/* Implementation of GUI terminal on the Mac OS.
- Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#endif
#ifdef MAC_OSX
-#undef mktime
-#undef DEBUG
-#undef free
-#undef malloc
-#undef realloc
-/* Macros max and min defined in lisp.h conflict with those in
- precompiled header Carbon.h. */
-#undef max
-#undef min
-#undef init_process
-#include <Carbon/Carbon.h>
-#undef free
-#define free unexec_free
-#undef malloc
-#define malloc unexec_malloc
-#undef realloc
-#define realloc unexec_realloc
-#undef min
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#undef max
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#undef init_process
-#define init_process emacs_init_process
/* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
obtain events from the event queue. If set to 0, WaitNextEvent is
used instead. */
extern Lisp_Object Vx_no_window_manager;
-extern Lisp_Object Qface, Qmouse_face;
-
extern int errno;
/* A mask of extra modifier bits to put into every keyboard char. */
static void XTframe_rehighlight P_ ((struct frame *));
static void x_frame_rehighlight P_ ((struct x_display_info *));
static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
-static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
+static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
+ enum text_cursor_kinds));
+
static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC));
static void x_flush P_ ((struct frame *f));
static void x_update_begin P_ ((struct frame *));
/* X display function emulation */
-static void
+void
XFreePixmap (display, pixmap)
- Display *display;
+ Display *display; /* not used */
Pixmap pixmap;
{
- PixMap *p = (PixMap *) pixmap;
-
- xfree (p->baseAddr);
- xfree (p);
+ DisposeGWorld (pixmap);
}
{
RGBColor fg_color;
- fg_color.red = RED_FROM_ULONG (color) * 256;
- fg_color.green = GREEN_FROM_ULONG (color) * 256;
- fg_color.blue = BLUE_FROM_ULONG (color) * 256;
+ fg_color.red = RED16_FROM_ULONG (color);
+ fg_color.green = GREEN16_FROM_ULONG (color);
+ fg_color.blue = BLUE16_FROM_ULONG (color);
RGBForeColor (&fg_color);
}
{
RGBColor bg_color;
- bg_color.red = RED_FROM_ULONG (color) * 256;
- bg_color.green = GREEN_FROM_ULONG (color) * 256;
- bg_color.blue = BLUE_FROM_ULONG (color) * 256;
+ bg_color.red = RED16_FROM_ULONG (color);
+ bg_color.green = GREEN16_FROM_ULONG (color);
+ bg_color.blue = BLUE16_FROM_ULONG (color);
RGBBackColor (&bg_color);
}
LineTo (x2, y2);
}
+void
+mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2)
+ Display *display;
+ Pixmap p;
+ GC gc;
+ int x1, y1, x2, y2;
+{
+ SetGWorld (p, NULL);
+
+ mac_set_colors (gc);
+
+ LockPixels (GetGWorldPixMap (p));
+ MoveTo (x1, y1);
+ LineTo (x2, y2);
+ UnlockPixels (GetGWorldPixMap (p));
+}
+
/* Mac version of XClearArea. */
void
/* Mac replacement for XCopyArea. */
static void
-mac_draw_bitmap (display, w, gc, x, y, bitmap)
+mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
Display *display;
WindowPtr w;
GC gc;
- int x, y;
- BitMap *bitmap;
+ int x, y, width, height;
+ unsigned short *bits;
+ int overlay_p;
{
+ BitMap bitmap;
Rect r;
+ bitmap.rowBytes = sizeof(unsigned short);
+ bitmap.baseAddr = (char *)bits;
+ SetRect (&(bitmap.bounds), 0, 0, width, height);
+
#if TARGET_API_MAC_CARBON
SetPort (GetWindowPort (w));
#else
#endif
mac_set_colors (gc);
- SetRect (&r, x, y, x + bitmap->bounds.right, y + bitmap->bounds.bottom);
+ SetRect (&r, x, y, x + width, y + height);
#if TARGET_API_MAC_CARBON
- {
- PixMapHandle pmh;
-
- LockPortBits (GetWindowPort (w));
- pmh = GetPortPixMap (GetWindowPort (w));
- CopyBits (bitmap, (BitMap *) *pmh, &(bitmap->bounds), &r, srcCopy, 0);
- UnlockPortBits (GetWindowPort (w));
- }
+ LockPortBits (GetWindowPort (w));
+ CopyBits (&bitmap, GetPortBitMapForCopyBits (GetWindowPort (w)),
+ &(bitmap.bounds), &r, overlay_p ? srcOr : srcCopy, 0);
+ UnlockPortBits (GetWindowPort (w));
#else /* not TARGET_API_MAC_CARBON */
- CopyBits (bitmap, &(w->portBits), &(bitmap->bounds), &r, srcCopy, 0);
+ CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r,
+ overlay_p ? srcOr : srcCopy, 0);
#endif /* not TARGET_API_MAC_CARBON */
}
}
+/* XBM bits seem to be backward within bytes compared with how
+ Mac does things. */
+static unsigned char
+reflect_byte (orig)
+ unsigned char orig;
+{
+ int i;
+ unsigned char reflected = 0x00;
+ for (i = 0; i < 8; i++)
+ {
+ if (orig & (0x01 << i))
+ reflected |= 0x80 >> i;
+ }
+ return reflected;
+}
+
+
/* Mac replacement for XCreateBitmapFromBitmapData. */
static void
char *bits;
int w, h;
{
- int bytes_per_row, i, j;
+ int i, j, w1;
+ char *p;
- bitmap->rowBytes = (w + 15) / 16 * 2; /* must be on word boundary */
+ w1 = (w + 7) / 8; /* nb of 8bits elt in X bitmap */
+ bitmap->rowBytes = ((w + 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
bitmap->baseAddr = xmalloc (bitmap->rowBytes * h);
- if (!bitmap->baseAddr)
- abort ();
-
bzero (bitmap->baseAddr, bitmap->rowBytes * h);
for (i = 0; i < h; i++)
- for (j = 0; j < w; j++)
- if (BitTst (bits, i * w + j))
- BitSet (bitmap->baseAddr, i * bitmap->rowBytes * 8 + j);
+ {
+ p = bitmap->baseAddr + i * bitmap->rowBytes;
+ for (j = 0; j < w1; j++)
+ *p++ = reflect_byte (*bits++);
+ }
SetRect (&(bitmap->bounds), 0, 0, w, h);
}
xfree (bitmap->baseAddr);
}
+
+Pixmap
+XCreatePixmap (display, w, width, height, depth)
+ Display *display; /* not used */
+ WindowPtr w;
+ unsigned int width, height;
+ unsigned int depth; /* not used */
+{
+ Pixmap pixmap;
+ Rect r;
+ QDErr err;
+
+#if TARGET_API_MAC_CARBON
+ SetPort (GetWindowPort (w));
+#else
+ SetPort (w);
+#endif
+
+ SetRect (&r, 0, 0, width, height);
+ err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0);
+ if (err != noErr)
+ return NULL;
+ return pixmap;
+}
+
+
+Pixmap
+XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
+ Display *display; /* not used */
+ WindowPtr w;
+ char *data;
+ unsigned int width, height;
+ unsigned long fg, bg;
+ unsigned int depth; /* not used */
+{
+ Pixmap pixmap;
+ BitMap bitmap;
+
+ pixmap = XCreatePixmap (display, w, width, height, depth);
+ if (pixmap == NULL)
+ return NULL;
+
+ SetGWorld (pixmap, NULL);
+ mac_create_bitmap_from_bitmap_data (&bitmap, data, width, height);
+ mac_set_forecolor (fg);
+ mac_set_backcolor (bg);
+ LockPixels (GetGWorldPixMap (pixmap));
+#if TARGET_API_MAC_CARBON
+ CopyBits (&bitmap, GetPortBitMapForCopyBits (pixmap),
+ &bitmap.bounds, &bitmap.bounds, srcCopy, 0);
+#else /* not TARGET_API_MAC_CARBON */
+ CopyBits (&bitmap, &(((GrafPtr)pixmap)->portBits),
+ &bitmap.bounds, &bitmap.bounds, srcCopy, 0);
+#endif /* not TARGET_API_MAC_CARBON */
+ UnlockPixels (GetGWorldPixMap (pixmap));
+ mac_free_bitmap (&bitmap);
+
+ return pixmap;
+}
+
+
/* Mac replacement for XFillRectangle. */
static void
}
+static void
+mac_fill_rectangle_to_pixmap (display, p, gc, x, y, width, height)
+ Display *display;
+ Pixmap p;
+ GC gc;
+ int x, y;
+ unsigned int width, height;
+{
+ Rect r;
+
+ SetGWorld (p, NULL);
+ mac_set_colors (gc);
+ SetRect (&r, x, y, x + width, y + height);
+
+ LockPixels (GetGWorldPixMap (p));
+ PaintRect (&r); /* using foreground color of gc */
+ UnlockPixels (GetGWorldPixMap (p));
+}
+
+
/* Mac replacement for XDrawRectangle: dest is a window. */
static void
int x, y;
unsigned int width, height;
{
-#if 0 /* MAC_TODO: draw a rectangle in a PixMap */
Rect r;
-#if TARGET_API_MAC_CARBON
- SetPort (GetWindowPort (w));
-#else
- SetPort (w);
-#endif
-
+ SetGWorld (p, NULL);
mac_set_colors (gc);
- SetRect (&r, x, y, x + width, y + height);
+ SetRect (&r, x, y, x + width + 1, y + height + 1);
+ LockPixels (GetGWorldPixMap (p));
FrameRect (&r); /* using foreground color of gc */
-#endif /* 0 */
+ UnlockPixels (GetGWorldPixMap (p));
}
SetPort (dest);
#endif
- mac_set_colors (gc);
-
SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
+ ForeColor (blackColor);
+ BackColor (whiteColor);
+
+ LockPixels (GetGWorldPixMap (src));
#if TARGET_API_MAC_CARBON
- {
- PixMapHandle pmh;
+ LockPortBits (GetWindowPort (dest));
+ CopyBits (GetPortBitMapForCopyBits (src),
+ GetPortBitMapForCopyBits (GetWindowPort (dest)),
+ &src_r, &dest_r, srcCopy, 0);
+ UnlockPortBits (GetWindowPort (dest));
+#else /* not TARGET_API_MAC_CARBON */
+ CopyBits (&(((GrafPtr)src)->portBits), &(dest->portBits),
+ &src_r, &dest_r, srcCopy, 0);
+#endif /* not TARGET_API_MAC_CARBON */
+ UnlockPixels (GetGWorldPixMap (src));
+}
- LockPortBits (GetWindowPort (dest));
- pmh = GetPortPixMap (GetWindowPort (dest));
- CopyBits ((BitMap *) &src, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0);
- UnlockPortBits (GetWindowPort (dest));
- }
+
+static void
+mac_copy_area_with_mask (display, src, mask, dest, gc, src_x, src_y,
+ width, height, dest_x, dest_y)
+ Display *display;
+ Pixmap src, mask;
+ WindowPtr dest;
+ GC gc;
+ int src_x, src_y;
+ unsigned int width, height;
+ int dest_x, dest_y;
+{
+ Rect src_r, dest_r;
+
+#if TARGET_API_MAC_CARBON
+ SetPort (GetWindowPort (dest));
+#else
+ SetPort (dest);
+#endif
+
+ SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
+ SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
+
+ ForeColor (blackColor);
+ BackColor (whiteColor);
+
+ LockPixels (GetGWorldPixMap (src));
+ LockPixels (GetGWorldPixMap (mask));
+#if TARGET_API_MAC_CARBON
+ LockPortBits (GetWindowPort (dest));
+ CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask),
+ GetPortBitMapForCopyBits (GetWindowPort (dest)),
+ &src_r, &src_r, &dest_r);
+ UnlockPortBits (GetWindowPort (dest));
#else /* not TARGET_API_MAC_CARBON */
- CopyBits ((BitMap *) &src, &(dest->portBits), &src_r, &dest_r, srcCopy, 0);
+ CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits),
+ &(dest->portBits), &src_r, &src_r, &dest_r);
#endif /* not TARGET_API_MAC_CARBON */
+ UnlockPixels (GetGWorldPixMap (mask));
+ UnlockPixels (GetGWorldPixMap (src));
}
{
#if TARGET_API_MAC_CARBON
Rect gw_r, src_r, dest_r;
- PixMapHandle pmh;
SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
BackColor (whiteColor);
LockPortBits (GetWindowPort (w));
- pmh = GetPortPixMap (GetWindowPort (w));
- CopyBits ((BitMap *) *pmh, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0);
+ {
+ const BitMap *bitmap = GetPortBitMapForCopyBits (GetWindowPort (w));
+ CopyBits (bitmap, bitmap, &src_r, &dest_r, srcCopy, 0);
+ }
UnlockPortBits (GetWindowPort (w));
mac_set_colors (gc);
mac_copy_area_to_pixmap (display, src, dest, gc, src_x, src_y, width, height,
dest_x, dest_y)
Display *display;
- Pixmap src;
- Pixmap dest;
+ Pixmap src, dest;
GC gc;
int src_x, src_y;
unsigned int width, height;
int dest_x, dest_y;
{
Rect src_r, dest_r;
- int src_right = ((PixMap *) src)->bounds.right;
- int src_bottom = ((PixMap *) src)->bounds.bottom;
- int w = src_right - src_x;
- int h = src_bottom - src_y;
- mac_set_colors (gc);
+ SetGWorld (dest, NULL);
+ ForeColor (blackColor);
+ BackColor (whiteColor);
- SetRect (&src_r, src_x, src_y, src_right, src_bottom);
- SetRect (&dest_r, dest_x, dest_y, dest_x + w, dest_y + h);
+ SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
+ SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
- CopyBits ((BitMap *) &src, (BitMap *) &dest, &src_r, &dest_r, srcCopy, 0);
+ LockPixels (GetGWorldPixMap (src));
+ LockPixels (GetGWorldPixMap (dest));
+#if TARGET_API_MAC_CARBON
+ CopyBits (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (dest),
+ &src_r, &dest_r, srcCopy, 0);
+#else /* not TARGET_API_MAC_CARBON */
+ CopyBits (&(((GrafPtr)src)->portBits), &(((GrafPtr)dest)->portBits),
+ &src_r, &dest_r, srcCopy, 0);
+#endif /* not TARGET_API_MAC_CARBON */
+ UnlockPixels (GetGWorldPixMap (dest));
+ UnlockPixels (GetGWorldPixMap (src));
+}
+
+
+static void
+mac_copy_area_with_mask_to_pixmap (display, src, mask, dest, gc, src_x, src_y,
+ width, height, dest_x, dest_y)
+ Display *display;
+ Pixmap src, mask, dest;
+ GC gc;
+ int src_x, src_y;
+ unsigned int width, height;
+ int dest_x, dest_y;
+{
+ Rect src_r, dest_r;
+
+ SetGWorld (dest, NULL);
+ ForeColor (blackColor);
+ BackColor (whiteColor);
+
+ SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
+ SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
+
+ LockPixels (GetGWorldPixMap (src));
+ LockPixels (GetGWorldPixMap (mask));
+ LockPixels (GetGWorldPixMap (dest));
+#if TARGET_API_MAC_CARBON
+ CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask),
+ GetPortBitMapForCopyBits (dest), &src_r, &src_r, &dest_r);
+#else /* not TARGET_API_MAC_CARBON */
+ CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits),
+ &(((GrafPtr)dest)->portBits), &src_r, &src_r, &dest_r);
+#endif /* not TARGET_API_MAC_CARBON */
+ UnlockPixels (GetGWorldPixMap (dest));
+ UnlockPixels (GetGWorldPixMap (mask));
+ UnlockPixels (GetGWorldPixMap (src));
}
/* Mac replacement for XSetForeground. */
-static void
+void
XSetForeground (display, gc, color)
Display *display;
GC gc;
output_cursor.x, output_cursor.y);
x_draw_vertical_border (w);
+
+ draw_window_fringes (w);
+
UNBLOCK_INPUT;
}
xassert (w);
if (!desired_row->mode_line_p && !w->pseudo_window_p)
- {
- BLOCK_INPUT;
- draw_row_fringe_bitmaps (w, desired_row);
- UNBLOCK_INPUT;
- }
+ desired_row->redraw_fringe_bitmaps_p = 1;
/* When a window has disappeared, make sure that no rest of
full-width rows stays visible in the internal border. Could
XGCValues gcv;
GC gc = f->output_data.mac->normal_gc;
struct face *face = p->face;
+ int rowY;
/* Must clip because of partially visible lines. */
- x_clip_to_row (w, row, gc);
+ rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+ if (p->y < rowY)
+ {
+ /* Adjust position of "bottom aligned" bitmap on partially
+ visible last row. */
+ int oldY = row->y;
+ int oldVH = row->visible_height;
+ row->visible_height = p->h;
+ row->y -= rowY - p->y;
+ x_clip_to_row (w, row, gc);
+ row->y = oldY;
+ row->visible_height = oldVH;
+ }
+ else
+ x_clip_to_row (w, row, gc);
- if (p->bx >= 0)
+ if (p->bx >= 0 && !p->overlay_p)
{
XGCValues gcv;
gcv.foreground = face->background;
#endif
}
- if (p->which != NO_FRINGE_BITMAP)
+ if (p->which)
{
- unsigned char *bits = fringe_bitmaps[p->which].bits + p->dh;
- BitMap bitmap;
+ unsigned short *bits = p->bits + p->dh;
- mac_create_bitmap_from_bitmap_data (&bitmap, bits, p->wd, p->h);
- gcv.foreground = face->foreground;
+ gcv.foreground = (p->cursor_p
+ ? (p->overlay_p ? face->background
+ : f->output_data.mac->cursor_pixel)
+ : face->foreground);
gcv.background = face->background;
- mac_draw_bitmap (display, window, &gcv, p->x, p->y, &bitmap);
-
- mac_free_bitmap (&bitmap);
+ mac_draw_bitmap (display, window, &gcv, p->x, p->y,
+ p->wd, p->h, bits, p->overlay_p);
}
mac_reset_clipping (display, window);
#endif /* MAC_TODO */
+
+/* Brightness beyond which a color won't have its highlight brightness
+ boosted.
+
+ Nominally, highlight colors for `3d' faces are calculated by
+ brightening an object's color by a constant scale factor, but this
+ doesn't yield good results for dark colors, so for colors who's
+ brightness is less than this value (on a scale of 0-255) have to
+ use an additional additive factor.
+
+ The value here is set so that the default menu-bar/mode-line color
+ (grey75) will not have its highlights changed at all. */
+#define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
+
+
/* Allocate a color which is lighter or darker than *COLOR by FACTOR
or DELTA. Try a color with RGB values multiplied by FACTOR first.
If this produces the same color as COLOR, try a color where all RGB
int delta;
{
unsigned long new;
+ long bright;
+
+ /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
+ delta /= 256;
/* Change RGB values by specified FACTOR. Avoid overflow! */
xassert (factor >= 0);
new = RGB_TO_ULONG (min (0xff, (int) (factor * RED_FROM_ULONG (*color))),
min (0xff, (int) (factor * GREEN_FROM_ULONG (*color))),
min (0xff, (int) (factor * BLUE_FROM_ULONG (*color))));
+
+ /* Calculate brightness of COLOR. */
+ bright = (2 * RED_FROM_ULONG (*color) + 3 * GREEN_FROM_ULONG (*color)
+ + BLUE_FROM_ULONG (*color)) / 6;
+
+ /* We only boost colors that are darker than
+ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
+ if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
+ /* Make an additive adjustment to NEW, because it's dark enough so
+ that scaling by FACTOR alone isn't enough. */
+ {
+ /* How far below the limit this color is (0 - 1, 1 being darker). */
+ double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
+ /* The additive adjustment. */
+ int min_delta = delta * dimness * factor / 2;
+
+ if (factor < 1)
+ new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color)) - min_delta)),
+ max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color)) - min_delta)),
+ max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color)) - min_delta)));
+ else
+ new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta + RED_FROM_ULONG (*color)))),
+ max (0, min (0xff, (int) (min_delta + GREEN_FROM_ULONG (*color)))),
+ max (0, min (0xff, (int) (min_delta + BLUE_FROM_ULONG (*color)))));
+ }
+
if (new == *color)
new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta + RED_FROM_ULONG (*color)))),
max (0, min (0xff, (int) (delta + GREEN_FROM_ULONG (*color)))),
/* Allocate new color. */
xgcv.foreground = default_pixel;
pixel = background;
- if (mac_alloc_lighter_color (f, &pixel, factor, delta))
+ if (dpyinfo->n_planes != 1
+ && mac_alloc_lighter_color (f, &pixel, factor, delta))
{
relief->allocated_p = 1;
xgcv.foreground = relief->pixel = pixel;
if (s->face->use_box_color_for_shadows_p)
color = s->face->box_color;
+ else if (s->first_glyph->type == IMAGE_GLYPH
+ && s->img->pixmap
+ && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
+ color = IMAGE_BACKGROUND (s->img, s->f, 0);
else
{
XGCValues xgcv;
x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
raised_p, left_p, right_p, clip_rect)
struct frame *f;
- int left_x, top_y, right_x, bottom_y, left_p, right_p, raised_p;
+ int left_x, top_y, right_x, bottom_y, width, left_p, right_p, raised_p;
Rect *clip_rect;
{
+ Display *dpy = FRAME_MAC_DISPLAY (f);
+ Window window = FRAME_MAC_WINDOW (f);
int i;
GC gc;
gc = f->output_data.mac->white_relief.gc;
else
gc = f->output_data.mac->black_relief.gc;
- mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), clip_rect);
+ mac_set_clip_rectangle (dpy, window, clip_rect);
/* Top. */
for (i = 0; i < width; ++i)
- XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc,
+ XDrawLine (dpy, window, gc,
left_x + i * left_p, top_y + i,
- right_x + 1 - i * right_p, top_y + i);
+ right_x - i * right_p, top_y + i);
/* Left. */
if (left_p)
for (i = 0; i < width; ++i)
- XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc,
+ XDrawLine (dpy, window, gc,
left_x + i, top_y + i, left_x + i, bottom_y - i);
- mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f));
+ mac_reset_clipping (dpy, window);
if (raised_p)
gc = f->output_data.mac->black_relief.gc;
else
gc = f->output_data.mac->white_relief.gc;
- mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f),
+ mac_set_clip_rectangle (dpy, window,
clip_rect);
/* Bottom. */
for (i = 0; i < width; ++i)
- XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc,
+ XDrawLine (dpy, window, gc,
left_x + i * left_p, bottom_y - i,
- right_x + 1 - i * right_p, bottom_y - i);
+ right_x - i * right_p, bottom_y - i);
/* Right. */
if (right_p)
for (i = 0; i < width; ++i)
- XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc,
- right_x - i, top_y + i + 1, right_x - i, bottom_y - i);
+ XDrawLine (dpy, window, gc,
+ right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1);
- mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f));
+ mac_reset_clipping (dpy, window);
}
x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
left_p, right_p, clip_rect)
struct glyph_string *s;
- int left_x, top_y, right_x, bottom_y, left_p, right_p;
+ int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
Rect *clip_rect;
{
XGCValues xgcv;
/* Top. */
XFillRectangle (s->display, s->window, &xgcv,
- left_x, top_y, right_x - left_x, width);
+ left_x, top_y, right_x - left_x + 1, width);
/* Left. */
if (left_p)
XFillRectangle (s->display, s->window, &xgcv,
- left_x, top_y, width, bottom_y - top_y);
+ left_x, top_y, width, bottom_y - top_y + 1);
/* Bottom. */
XFillRectangle (s->display, s->window, &xgcv,
- left_x, bottom_y - width, right_x - left_x, width);
+ left_x, bottom_y - width + 1, right_x - left_x + 1, width);
/* Right. */
if (right_p)
XFillRectangle (s->display, s->window, &xgcv,
- right_x - width, top_y, width, bottom_y - top_y);
+ right_x - width + 1, top_y, width, bottom_y - top_y + 1);
mac_reset_clipping (s->display, s->window);
}
width = abs (s->face->box_line_width);
raised_p = s->face->box == FACE_RAISED_BOX;
left_x = s->x;
- right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
- ? last_x - 1
- : min (last_x, s->x + s->background_width) - 1));
+ right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
+ ? last_x - 1
+ : min (last_x, s->x + s->background_width) - 1);
top_y = s->y;
bottom_y = top_y + s->height - 1;
if (s->img->pixmap)
{
-#if 0 /* MAC_TODO: image mask */
if (s->img->mask)
{
- /* We can't set both a clip mask and use XSetClipRectangles
- because the latter also sets a clip mask. We also can't
- trust on the shape extension to be available
- (XShapeCombineRegion). So, compute the rectangle to draw
- manually. */
- unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
- | GCFunction);
- XGCValues xgcv;
+ Rect nr;
XRectangle clip_rect, image_rect, r;
- xgcv.clip_mask = s->img->mask;
- xgcv.clip_x_origin = x;
- xgcv.clip_y_origin = y;
- xgcv.function = GXcopy;
- XChangeGC (s->display, s->gc, mask, &xgcv);
-
- get_glyph_string_clip_rect (s, &clip_rect);
+ get_glyph_string_clip_rect (s, &nr);
+ CONVERT_TO_XRECT (clip_rect, nr);
image_rect.x = x;
image_rect.y = y;
image_rect.width = s->img->width;
image_rect.height = s->img->height;
if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
- XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
- r.x - x, r.y - y, r.width, r.height, r.x, r.y);
+ mac_copy_area_with_mask (s->display, s->img->pixmap, s->img->mask,
+ s->window, s->gc, r.x - x, r.y - y,
+ r.width, r.height, r.x, r.y);
}
else
-#endif /* MAC_TODO */
{
- mac_copy_area (s->display, s->img->pixmap, s->window, s->gc,
- 0, 0, s->img->width, s->img->height, x, y);
+ Rect nr;
+ XRectangle clip_rect, image_rect, r;
+
+ get_glyph_string_clip_rect (s, &nr);
+ CONVERT_TO_XRECT (clip_rect, nr);
+ image_rect.x = x;
+ image_rect.y = y;
+ image_rect.width = s->img->width;
+ image_rect.height = s->img->height;
+ if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
+ mac_copy_area (s->display, s->img->pixmap, s->window, s->gc,
+ r.x - x, r.y - y, r.width, r.height, r.x, r.y);
/* When the image has a mask, we can expect that at
least part of a mouse highlight or a block cursor will
}
-
/* Draw a relief around the image glyph string S. */
static void
if (s->img->pixmap)
{
-#if 0 /* MAC_TODO: image mask */
if (s->img->mask)
- {
- /* We can't set both a clip mask and use XSetClipRectangles
- because the latter also sets a clip mask. We also can't
- trust on the shape extension to be available
- (XShapeCombineRegion). So, compute the rectangle to draw
- manually. */
- unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
- | GCFunction);
- XGCValues xgcv;
-
- xgcv.clip_mask = s->img->mask;
- xgcv.clip_x_origin = x;
- xgcv.clip_y_origin = y;
- xgcv.function = GXcopy;
- XChangeGC (s->display, s->gc, mask, &xgcv);
-
- XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
- 0, 0, s->img->width, s->img->height, x, y);
- XSetClipMask (s->display, s->gc, None);
- }
+ mac_copy_area_with_mask_to_pixmap (s->display, s->img->pixmap,
+ s->img->mask, pixmap, s->gc,
+ 0, 0, s->img->width, s->img->height,
+ x, y);
else
-#endif /* MAC_TODO */
{
mac_copy_area_to_pixmap (s->display, s->img->pixmap, pixmap, s->gc,
0, 0, s->img->width, s->img->height, x, y);
{
int r = s->img->relief;
if (r < 0) r = -r;
- mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x - r, y - r,
- s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+ mac_draw_rectangle (s->display, s->window, s->gc, x - r, y - r,
+ s->img->width + r*2 - 1,
+ s->img->height + r*2 - 1);
}
}
}
else
/* Draw a rectangle if image could not be loaded. */
mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y,
- s->img->width - 1, s->img->height - 1);
+ s->img->width - 1, s->img->height - 1);
}
| s->face->box
|
| +-------------------------
- | | s->img->vmargin
+ | | s->img->margin
| |
| | +-------------------
| | | the image
height = s->height - 2 * box_line_vwidth;
+
/* Fill background with face under the image. Do it only if row is
taller than image or if image has a clip mask to reduce
flickering. */
if (height > s->img->height
|| s->img->hmargin
|| s->img->vmargin
-#if 0 /* TODO: image mask */
|| s->img->mask
-#endif
|| s->img->pixmap == 0
|| s->width != s->background_width)
{
x = s->x;
y = s->y + box_line_vwidth;
-#if 0 /* TODO: image mask */
+
if (s->img->mask)
{
/* Create a pixmap as large as the glyph string. Fill it
with the background color. Copy the image to it, using
its mask. Copy the temporary pixmap to the display. */
- Screen *screen = FRAME_X_SCREEN (s->f);
- int depth = DefaultDepthOfScreen (screen);
+ int depth = one_mac_display_info.n_planes;
/* Create a pixmap as large as the glyph string. */
pixmap = XCreatePixmap (s->display, s->window,
s->background_width,
s->height, depth);
- /* Don't clip in the following because we're working on the
- pixmap. */
- XSetClipMask (s->display, s->gc, None);
-
/* Fill the pixmap with the background color/stipple. */
+#if 0 /* TODO: stipple */
if (s->stippled_p)
{
/* Fill background with a stipple pattern. */
XSetFillStyle (s->display, s->gc, FillSolid);
}
else
+#endif
{
XGCValues xgcv;
XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
&xgcv);
XSetForeground (s->display, s->gc, xgcv.background);
- XFillRectangle (s->display, pixmap, s->gc,
- 0, 0, s->background_width, s->height);
+ mac_fill_rectangle_to_pixmap (s->display, pixmap, s->gc,
+ 0, 0, s->background_width,
+ s->height);
XSetForeground (s->display, s->gc, xgcv.foreground);
}
}
else
-#endif
x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
s->background_filled_p = 1;
x_draw_image_foreground_1 (s, pixmap);
x_set_glyph_string_clipping (s);
mac_copy_area (s->display, pixmap, s->window, s->gc,
- 0, 0, s->background_width, s->height, s->x, s->y);
+ 0, 0, s->background_width, s->height, s->x, s->y);
mac_reset_clipping (s->display, s->window);
XFreePixmap (s->display, pixmap);
}
/* Clear rest using the GC of the original non-cursor face. */
if (width < s->background_width)
{
- GC gc = s->face->gc;
int x = s->x + width, y = s->y;
int w = s->background_width - width, h = s->height;
Rect r;
+ GC gc;
if (s->row->mouse_face_p
&& cursor_in_mouse_face_p (s->w))
x_set_glyph_string_gc (s->next);
x_set_glyph_string_clipping (s->next);
x_draw_glyph_string_background (s->next, 1);
-
}
/* Set up S->gc, set clipping and draw S. */
if (s->for_overlaps_p)
s->background_filled_p = 1;
else
- x_draw_glyph_string_background (s, 0);
+ x_draw_glyph_string_background (s, 0);
x_draw_glyph_string_foreground (s);
break;
}
}
- /* Draw relief. */
+ /* Draw relief if not yet drawn. */
if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
- x_draw_glyph_string_box (s);
+ x_draw_glyph_string_box (s);
}
/* Reset clipping. */
x + shift_by, y);
}
-
/* Delete N glyphs at the nominal cursor position. Not implemented
for X frames. */
#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
+
/* Subtract the `struct timeval' values X and Y, storing the result in
*RESULT. Return 1 if the difference is negative, otherwise 0. */
This, and those operations, are used only within an update
that is bounded by calls to x_update_begin and x_update_end. */
-void
+static void
XTset_terminal_window (n)
register int n;
{
/* Get frame-relative bounding box of the text display area of W,
without mode lines. Include in this box the left and right
- fringes of W. */
+ fringe of W. */
window_box (w, -1, &x, &y, &width, &height);
from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
XTframe_rehighlight (frame)
struct frame *frame;
{
-
-
x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
}
struct glyph *cursor_glyph;
GC gc;
- /* Compute frame-relative coordinates from window-relative
- coordinates. */
- x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- y = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
- + row->ascent - w->phys_cursor_ascent);
- h = row->height - 1;
-
/* Get the glyph the cursor is on. If we can't tell because
the current matrix is invalid or such, give up. */
cursor_glyph = get_phys_cursor_glyph (w);
if (cursor_glyph->type == STRETCH_GLYPH
&& !x_stretch_cursor_p)
wd = min (FRAME_COLUMN_WIDTH (f), wd);
+ w->phys_cursor_width = wd;
+
+ /* Compute frame-relative coordinates from window-relative
+ coordinates. */
+ x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+ y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
+
+ /* Compute the proper height and ascent of the rectangle, based
+ on the actual glyph. Using the full height of the row looks
+ bad when there are tall images on that row. */
+ h = max (FRAME_LINE_HEIGHT (f), cursor_glyph->ascent + cursor_glyph->descent);
+ if (h < row->height)
+ y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
+ h--;
/* The foreground of cursor_gc is typically the same as the normal
background color, which can cause the cursor box to be invisible. */
--gerd. */
static void
-x_draw_bar_cursor (w, row, width)
+x_draw_bar_cursor (w, row, width, kind)
struct window *w;
struct glyph_row *row;
int width;
+ enum text_cursor_kinds kind;
{
- /* If cursor hpos is out of bounds, don't draw garbage. This can
- happen in mini-buffer windows when switching between echo area
- glyphs and mini-buffer. */
- if (w->phys_cursor.hpos < row->used[TEXT_AREA])
+ struct frame *f = XFRAME (w->frame);
+ struct glyph *cursor_glyph;
+
+ /* If cursor is out of bounds, don't draw garbage. This can happen
+ in mini-buffer windows when switching between echo area glyphs
+ and mini-buffer. */
+ cursor_glyph = get_phys_cursor_glyph (w);
+ if (cursor_glyph == NULL)
+ return;
+
+ /* If on an image, draw like a normal cursor. That's usually better
+ visible than drawing a bar, esp. if the image is large so that
+ the bar might not be in the window. */
+ if (cursor_glyph->type == IMAGE_GLYPH)
{
- struct frame *f = XFRAME (w->frame);
- struct glyph *cursor_glyph;
- GC gc;
- int x;
- unsigned long mask;
+ struct glyph_row *row;
+ row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
+ draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
+ }
+ else
+ {
+ Display *dpy = FRAME_MAC_DISPLAY (f);
+ Window window = FRAME_MAC_WINDOW (f);
+ GC gc = FRAME_MAC_DISPLAY_INFO (f)->scratch_cursor_gc;
+ unsigned long mask = GCForeground | GCBackground;
+ struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
XGCValues xgcv;
- Display *dpy;
- Window window;
- cursor_glyph = get_phys_cursor_glyph (w);
- if (cursor_glyph == NULL)
- return;
-
- xgcv.background = f->output_data.mac->cursor_pixel;
- xgcv.foreground = f->output_data.mac->cursor_pixel;
- mask = GCForeground | GCBackground;
- dpy = FRAME_MAC_DISPLAY (f);
- window = FRAME_MAC_WINDOW (f);
- gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc;
+ /* If the glyph's background equals the color we normally draw
+ the bar cursor in, the bar cursor in its normal color is
+ invisible. Use the glyph's foreground color instead in this
+ case, on the assumption that the glyph's colors are chosen so
+ that the glyph is legible. */
+ if (face->background == f->output_data.mac->cursor_pixel)
+ xgcv.background = xgcv.foreground = face->foreground;
+ else
+ xgcv.background = xgcv.foreground = f->output_data.mac->cursor_pixel;
if (gc)
XChangeGC (dpy, gc, mask, &xgcv);
if (width < 0)
width = FRAME_CURSOR_WIDTH (f);
+ width = min (cursor_glyph->pixel_width, width);
- x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
+ w->phys_cursor_width = width;
x_clip_to_row (w, row, gc);
- XFillRectangle (dpy, window, gc,
- x,
- WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
- min (cursor_glyph->pixel_width, width),
- row->height);
+
+ if (kind == BAR_CURSOR)
+ XFillRectangle (dpy, window, gc,
+ WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
+ WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
+ width, row->height);
+ else
+ XFillRectangle (dpy, window, gc,
+ WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
+ WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
+ row->height - width),
+ cursor_glyph->pixel_width,
+ width);
+
mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f));
}
}
if (on_p)
{
w->phys_cursor_type = cursor_type;
- w->phys_cursor_width = cursor_width;
w->phys_cursor_on_p = 1;
+ if (glyph_row->exact_window_width_line_p
+ && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])
+ {
+ glyph_row->cursor_in_fringe_p = 1;
+ draw_fringe_bitmap (w, glyph_row, 0);
+ }
+ else
switch (cursor_type)
{
case HOLLOW_BOX_CURSOR:
draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
break;
- case HBAR_CURSOR:
- /* TODO. For now, just draw bar cursor. */
case BAR_CURSOR:
- x_draw_bar_cursor (w, glyph_row, cursor_width);
+ x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
+ break;
+
+ case HBAR_CURSOR:
+ x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
break;
case NO_CURSOR:
+ w->phys_cursor_width = 0;
break;
default:
FRAME_SAMPLE_VISIBILITY (f);
}
}
+#else
+ UNBLOCK_INPUT;
#endif /* MAC_TODO */
}
}
\f
-/* Destroy the X window of frame F. */
+/* Free X resources of frame F. */
void
-x_destroy_window (f)
+x_free_frame_resources (f)
struct frame *f;
{
struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
DisposeWindow (FRAME_MAC_WINDOW (f));
free_frame_menubar (f);
- free_frame_faces (f);
+
+ if (FRAME_FACE_CACHE (f))
+ free_frame_faces (f);
+
+ x_free_gcs (f);
xfree (f->output_data.mac);
- f->output_data.mac = 0;
+ f->output_data.mac = NULL;
+
if (f == dpyinfo->x_focus_frame)
dpyinfo->x_focus_frame = 0;
if (f == dpyinfo->x_focus_event_frame)
if (f == dpyinfo->x_highlight_frame)
dpyinfo->x_highlight_frame = 0;
- dpyinfo->reference_count--;
-
if (f == dpyinfo->mouse_face_mouse_frame)
{
dpyinfo->mouse_face_beg_row
UNBLOCK_INPUT;
}
+
+
+/* Destroy the X window of frame F. */
+
+void
+x_destroy_window (f)
+ struct frame *f;
+{
+ struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
+
+ x_free_frame_resources (f);
+
+ dpyinfo->reference_count--;
+}
+
\f
/* Setting window manager hints. */
int font_name_table_size = 0;
int font_name_count = 0;
+#if 0
/* compare two strings ignoring case */
static int
stricmp (const char *s, const char *t)
&& wildstrieq (m_charset, x_charset))
|| mac_font_pattern_match (mf, xf);
}
+#endif
+
+static Lisp_Object Qbig5, Qcn_gb, Qsjis, Qeuc_kr;
+
+static void
+decode_mac_font_name (char *name, int size, short scriptcode)
+{
+ Lisp_Object coding_system;
+ struct coding_system coding;
+ char *buf;
+
+ switch (scriptcode)
+ {
+ case smTradChinese:
+ coding_system = Qbig5;
+ break;
+ case smSimpChinese:
+ coding_system = Qcn_gb;
+ break;
+ case smJapanese:
+ coding_system = Qsjis;
+ break;
+ case smKorean:
+ coding_system = Qeuc_kr;
+ break;
+ default:
+ return;
+ }
+
+ setup_coding_system (coding_system, &coding);
+ coding.src_multibyte = 0;
+ coding.dst_multibyte = 1;
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+ coding.composing = COMPOSITION_DISABLED;
+ buf = (char *) alloca (size);
+
+ decode_coding (&coding, name, buf, strlen (name), size - 1);
+ bcopy (buf, name, coding.produced);
+ name[coding.produced] = '\0';
+}
static char *
mac_to_x_fontname (char *name, int size, Style style, short scriptcode)
{
char foundry[32], family[32], cs[32];
- char xf[255], *result, *p;
+ char xf[256], *result, *p;
if (sscanf (name, "%31[^-]-%31[^-]-%31s", foundry, family, cs) != 3)
{
x_font_name_to_mac_font_name (char *xf, char *mf)
{
char foundry[32], family[32], weight[20], slant[2], cs[32];
+ Lisp_Object coding_system = Qnil;
+ struct coding_system coding;
strcpy (mf, "");
foundry, family, weight, slant, cs) != 5)
return;
- if (strcmp (cs, "big5-0") == 0 || strcmp (cs, "gb2312.1980-0") == 0
- || strcmp (cs, "jisx0208.1983-sjis") == 0
- || strcmp (cs, "jisx0201.1976-0") == 0
- || strcmp (cs, "ksc5601.1989-0") == 0 || strcmp (cs, "mac-roman") == 0)
- strcpy(mf, family);
+ if (strcmp (cs, "big5-0") == 0)
+ coding_system = Qbig5;
+ else if (strcmp (cs, "gb2312.1980-0") == 0)
+ coding_system = Qcn_gb;
+ else if (strcmp (cs, "jisx0208.1983-sjis") == 0
+ || strcmp (cs, "jisx0201.1976-0") == 0)
+ coding_system = Qsjis;
+ else if (strcmp (cs, "ksc5601.1989-0") == 0)
+ coding_system = Qeuc_kr;
+ else if (strcmp (cs, "mac-roman") == 0)
+ strcpy (mf, family);
else
- sprintf(mf, "%s-%s-%s", foundry, family, cs);
+ sprintf (mf, "%s-%s-%s", foundry, family, cs);
+
+ if (!NILP (coding_system))
+ {
+ setup_coding_system (coding_system, &coding);
+ coding.src_multibyte = 1;
+ coding.dst_multibyte = 1;
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+ encode_coding (&coding, family, mf, strlen (family), sizeof (Str32) - 1);
+ mf[coding.produced] = '\0';
+ }
}
if (FMGetFontFamilyName (ff, name) != noErr)
break;
p2cstr (name);
+ if (*name == '.')
+ continue;
sc = FontToScript (ff);
+ decode_mac_font_name (name, sizeof (name), sc);
/* Point the instance iterator at the current font family. */
- if (FMResetFontFamilyInstanceIterator(ff, &ffii) != noErr)
+ if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr)
break;
while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
== noErr)
- if (size == 0)
- {
- add_font_name_table_entry (mac_to_x_fontname (name, size,
- style, sc));
- add_font_name_table_entry (mac_to_x_fontname (name, size,
- italic, sc));
- add_font_name_table_entry (mac_to_x_fontname (name, size,
- bold, sc));
- add_font_name_table_entry (mac_to_x_fontname (name, size,
- italic | bold,
- sc));
- }
- else
- {
+ {
+ /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
+ contained in Apple Japanese (SJIS) font. */
+ again:
+ if (size == 0)
+ {
+ add_font_name_table_entry (mac_to_x_fontname (name, size,
+ style, sc));
+ add_font_name_table_entry (mac_to_x_fontname (name, size,
+ italic, sc));
+ add_font_name_table_entry (mac_to_x_fontname (name, size,
+ bold, sc));
+ add_font_name_table_entry (mac_to_x_fontname (name, size,
+ italic | bold,
+ sc));
+ }
+ else
add_font_name_table_entry (mac_to_x_fontname (name, size,
style, sc));
- if (smJapanese == sc)
- add_font_name_table_entry (mac_to_x_fontname (name, size,
- style,
- -smJapanese));
- }
+ if (sc == smJapanese)
+ {
+ sc = -smJapanese;
+ goto again;
+ }
+ else if (sc == -smJapanese)
+ sc = smJapanese;
+ }
}
/* Dispose of the iterators. */
TextFont (fontnum);
scriptcode = FontToScript (fontnum);
+ decode_mac_font_name (name, sizeof (name), scriptcode);
do
{
HLock (font_handle);
assc_entry->fontSize,
assc_entry->fontStyle,
scriptcode);
- /* Both jisx0208.1983-sjis and
- jisx0201.1976-sjis parts are contained in
- Apple Japanese (SJIS) font. */
+ /* Both jisx0208.1983-sjis and jisx0201.1976-0
+ parts are contained in Apple Japanese (SJIS)
+ font. */
if (smJapanese == scriptcode)
{
font_name_table[font_name_count++]
}
+enum xlfd_scalable_field_index
+ {
+ XLFD_SCL_PIXEL_SIZE,
+ XLFD_SCL_POINT_SIZE,
+ XLFD_SCL_AVGWIDTH,
+ XLFD_SCL_LAST
+ };
+
+static int xlfd_scalable_fields[] =
+ {
+ 6, /* PIXEL_SIZE */
+ 7, /* POINT_SIZE */
+ 11, /* AVGWIDTH */
+ -1
+ };
+
+static Lisp_Object
+mac_do_list_fonts (pattern, maxnames)
+ char *pattern;
+ int maxnames;
+{
+ int i, n_fonts = 0;
+ Lisp_Object font_list = Qnil, pattern_regex, fontname;
+ char *regex = (char *) alloca (strlen (pattern) * 2 + 3);
+ char scaled[256];
+ char *ptr;
+ int scl_val[XLFD_SCL_LAST], *field, *val;
+
+ for (i = 0; i < XLFD_SCL_LAST; i++)
+ scl_val[i] = -1;
+
+ /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
+ POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
+ fonts are scaled according to the specified size. */
+ ptr = pattern;
+ i = 0;
+ field = xlfd_scalable_fields;
+ val = scl_val;
+ if (*ptr == '-')
+ do
+ {
+ ptr++;
+ if (i == *field)
+ {
+ if ('1' <= *ptr && *ptr <= '9')
+ {
+ *val = *ptr++ - '0';
+ while ('0' <= *ptr && *ptr <= '9' && *val < 10000)
+ *val = *val * 10 + *ptr++ - '0';
+ if (*ptr != '-')
+ *val = -1;
+ }
+ field++;
+ val++;
+ }
+ ptr = strchr (ptr, '-');
+ i++;
+ }
+ while (ptr && i < 14);
+
+ if (i == 14 && ptr == NULL)
+ {
+ if (scl_val[XLFD_SCL_POINT_SIZE] > 0)
+ {
+ scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_POINT_SIZE] / 10;
+ scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_POINT_SIZE];
+ }
+ else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0)
+ {
+ scl_val[XLFD_SCL_POINT_SIZE] =
+ scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_PIXEL_SIZE] * 10;
+ }
+ else if (scl_val[XLFD_SCL_AVGWIDTH] > 0)
+ {
+ scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_AVGWIDTH] / 10;
+ scl_val[XLFD_SCL_POINT_SIZE] = scl_val[XLFD_SCL_AVGWIDTH];
+ }
+ }
+ else
+ scl_val[XLFD_SCL_PIXEL_SIZE] = -1;
+
+ ptr = regex;
+ *ptr++ = '^';
+
+ /* Turn pattern into a regexp and do a regexp match. */
+ for (; *pattern; pattern++)
+ {
+ if (*pattern == '?')
+ *ptr++ = '.';
+ else if (*pattern == '*')
+ {
+ *ptr++ = '.';
+ *ptr++ = '*';
+ }
+ else
+ *ptr++ = tolower (*pattern);
+ }
+ *ptr = '$';
+ *(ptr + 1) = '\0';
+
+ pattern_regex = build_string (regex);
+
+ for (i = 0; i < font_name_count; i++)
+ {
+ fontname = build_string (font_name_table[i]);
+ if (fast_string_match (pattern_regex, fontname) >= 0)
+ {
+ font_list = Fcons (fontname, font_list);
+
+ n_fonts++;
+ if (maxnames > 0 && n_fonts >= maxnames)
+ break;
+ }
+ else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0
+ && (ptr = strstr (font_name_table[i], "-0-0-75-75-m-0-")))
+ {
+ int former_len = ptr - font_name_table[i];
+
+ memcpy (scaled, font_name_table[i], former_len);
+ sprintf (scaled + former_len,
+ "-%d-%d-75-75-m-%d-%s",
+ scl_val[XLFD_SCL_PIXEL_SIZE],
+ scl_val[XLFD_SCL_POINT_SIZE],
+ scl_val[XLFD_SCL_AVGWIDTH],
+ ptr + sizeof ("-0-0-75-75-m-0-") - 1);
+ fontname = build_string (scaled);
+ if (fast_string_match (pattern_regex, fontname) >= 0)
+ {
+ font_list = Fcons (fontname, font_list);
+
+ n_fonts++;
+ if (maxnames > 0 && n_fonts >= maxnames)
+ break;
+ }
+ }
+ }
+ return font_list;
+}
+
/* Return a list of at most MAXNAMES font specs matching the one in
PATTERN. Cache matching fonts for patterns in
dpyinfo->name_list_element to avoid looking them up again by
int size,
int maxnames)
{
- char *ptnstr;
Lisp_Object newlist = Qnil, tem, key;
- int n_fonts = 0;
- int i;
- struct gcpro gcpro1, gcpro2;
struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL;
if (font_name_table == NULL) /* Initialize when first used. */
}
}
- ptnstr = SDATA (pattern);
-
- GCPRO2 (pattern, newlist);
-
- /* Scan and matching bitmap fonts. */
- for (i = 0; i < font_name_count; i++)
- {
- if (mac_font_pattern_match (font_name_table[i], ptnstr))
- {
- newlist = Fcons (build_string (font_name_table[i]), newlist);
-
- n_fonts++;
- if (maxnames > 0 && n_fonts >= maxnames)
- break;
- }
- }
+ newlist = mac_do_list_fonts (SDATA (pattern), maxnames);
/* MAC_TODO: add code for matching outline fonts here */
- UNGCPRO;
-
if (dpyinfo)
{
XSETCDR (dpyinfo->name_list_element,
name = fontname;
else
{
- for (i = 0; i < font_name_count; i++)
- if (mac_font_pattern_match (font_name_table[i], fontname))
- break;
+ Lisp_Object matched_fonts;
- if (i >= font_name_count)
- return NULL;
-
- name = font_name_table[i];
+ matched_fonts = mac_do_list_fonts (fontname, 1);
+ if (NILP (matched_fonts))
+ return NULL;
+ name = SDATA (XCAR (matched_fonts));
}
GetPort (&port); /* save the current font number used */
for (c = 0x20; c <= 0xff; c++)
{
font->per_char[c - 0x20] = font->max_bounds;
- font->per_char[c - 0x20].width = CharWidth (c);
+ font->per_char[c - 0x20].width =
+ font->per_char[c - 0x20].rbearing = CharWidth (c);
}
}
}
/* Now fill in the slots of *FONTP. */
BLOCK_INPUT;
+ bzero (fontp, sizeof (*fontp));
fontp->font = font;
fontp->font_idx = i;
fontp->name = (char *) xmalloc (strlen (font->fontname) + 1);
\f
-/***********************************************************************
- Initialization
- ***********************************************************************/
-
-#ifdef USE_X_TOOLKIT
-static XrmOptionDescRec emacs_options[] = {
- {"-geometry", ".geometry", XrmoptionSepArg, NULL},
- {"-iconic", ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
-
- {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
- XrmoptionSepArg, NULL},
- {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
-
- {"-T", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
- {"-wn", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
- {"-title", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
- {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
- {"-in", "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
- {"-mc", "*pointerColor", XrmoptionSepArg, (XtPointer) NULL},
- {"-cr", "*cursorColor", XrmoptionSepArg, (XtPointer) NULL}
-};
-#endif /* USE_X_TOOLKIT */
-
-static int x_initialized;
-
-#ifdef MULTI_KBOARD
-/* Test whether two display-name strings agree up to the dot that separates
- the screen number from the server number. */
-static int
-same_x_server (name1, name2)
- char *name1, *name2;
-{
- int seen_colon = 0;
- unsigned char *system_name = SDATA (Vsystem_name);
- int system_name_length = strlen (system_name);
- int length_until_period = 0;
-
- while (system_name[length_until_period] != 0
- && system_name[length_until_period] != '.')
- length_until_period++;
-
- /* Treat `unix' like an empty host name. */
- if (! strncmp (name1, "unix:", 5))
- name1 += 4;
- if (! strncmp (name2, "unix:", 5))
- name2 += 4;
- /* Treat this host's name like an empty host name. */
- if (! strncmp (name1, system_name, system_name_length)
- && name1[system_name_length] == ':')
- name1 += system_name_length;
- if (! strncmp (name2, system_name, system_name_length)
- && name2[system_name_length] == ':')
- name2 += system_name_length;
- /* Treat this host's domainless name like an empty host name. */
- if (! strncmp (name1, system_name, length_until_period)
- && name1[length_until_period] == ':')
- name1 += length_until_period;
- if (! strncmp (name2, system_name, length_until_period)
- && name2[length_until_period] == ':')
- name2 += length_until_period;
-
- for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
- {
- if (*name1 == ':')
- seen_colon++;
- if (seen_colon && *name1 == '.')
- return 1;
- }
- return (seen_colon
- && (*name1 == '.' || *name1 == '\0')
- && (*name2 == '.' || *name2 == '\0'));
-}
-#endif
-
-
/* The Mac Event loop code */
#ifndef MAC_OSX
Boolean terminate_flag = false;
+/* Contains the string "reverse", which is a constant for mouse button emu.*/
+Lisp_Object Qreverse;
+
/* True if using command key as meta key. */
Lisp_Object Vmac_command_key_is_meta;
/* True if the ctrl and meta keys should be reversed. */
Lisp_Object Vmac_reverse_ctrl_meta;
+/* True if the option and command modifiers should be used to emulate
+ a three button mouse */
+Lisp_Object Vmac_emulate_three_button_mouse;
+
#if USE_CARBON_EVENTS
/* True if the mouse wheel button (i.e. button 4) should map to
mouse-2, instead of mouse-3. */
return result;
}
+static int
+mac_get_emulated_btn ( UInt32 modifiers )
+{
+ int result = 0;
+ if (Vmac_emulate_three_button_mouse != Qnil) {
+ int cmdIs3 = (Vmac_emulate_three_button_mouse != Qreverse);
+ if (modifiers & controlKey)
+ result = cmdIs3 ? 2 : 1;
+ else if (modifiers & optionKey)
+ result = cmdIs3 ? 1 : 2;
+ }
+ return result;
+}
+
#if USE_CARBON_EVENTS
/* Obtains the event modifiers from the event ref and then calls
mac_to_emacs_modifiers. */
UInt32 mods = 0;
GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
sizeof (UInt32), NULL, &mods);
+ if (Vmac_emulate_three_button_mouse != Qnil &&
+ GetEventClass(eventRef) == kEventClassMouse)
+ {
+ mods &= ~(optionKey & cmdKey);
+ }
return mac_to_emacs_modifiers (mods);
}
switch (result)
{
case kEventMouseButtonPrimary:
- return 0;
+ if (Vmac_emulate_three_button_mouse == Qnil)
+ return 0;
+ else {
+ UInt32 mods = 0;
+ GetEventParameter (ref, kEventParamKeyModifiers, typeUInt32, NULL,
+ sizeof (UInt32), NULL, &mods);
+ return mac_get_emulated_btn(mods);
+ }
case kEventMouseButtonSecondary:
return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2;
case kEventMouseButtonTertiary:
if (Gestalt (gestaltPhysicalRAMSize, &physical_ram_size) != noErr
|| Gestalt (gestaltLogicalRAMSize, &logical_ram_size) != noErr
- || physical_ram_size > 256 * 1024 * 1024
- || logical_ram_size > 256 * 1024 * 1024)
+ || physical_ram_size > (1 << VALBITS)
+ || logical_ram_size > (1 << VALBITS))
{
StopAlert (RAM_TOO_LARGE_ALERT_ID, NULL);
exit (1);
do_get_menus ();
+#ifndef USE_LSB_TAG
do_check_ram_size ();
+#endif
init_emacs_passwd_dir ();
/* Emacs calls this whenever it wants to read an input event from the
user. */
int
-XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
+XTread_socket (int sd, int expected, struct input_event *hold_quit)
{
+ struct input_event inev;
int count = 0;
#if USE_CARBON_EVENTS
OSStatus rneResult;
/* So people can tell when we have read the available input. */
input_signal_count++;
- if (numchars <= 0)
- abort ();
-
/* Don't poll for events to process (specifically updateEvt) if
window update currently already in progress. A call to redisplay
(in do_window_update) can be preempted by another call to
event to nil because keyboard.c protects incompletely processed
event from being garbage collected by placing them in the
kbd_buffer_gcpro vector. */
- bufp->arg = Qnil;
+ EVENT_INIT (inev);
+ inev.kind = NO_EVENT;
+ inev.arg = Qnil;
event_mask = everyEvent;
if (NILP (Fboundp (Qmac_ready_for_drag_n_drop)))
GetEventParameter(eventRef, kEventParamMouseLocation,
typeQDPoint, NULL, sizeof (Point),
NULL, &point);
- bufp->kind = WHEEL_EVENT;
- bufp->code = 0;
- bufp->modifiers = (mac_event_to_emacs_modifiers(eventRef)
- | ((delta < 0) ? down_modifier
- : up_modifier));
+ inev.kind = WHEEL_EVENT;
+ inev.code = 0;
+ inev.modifiers = (mac_event_to_emacs_modifiers(eventRef)
+ | ((delta < 0) ? down_modifier
+ : up_modifier));
SetPort (GetWindowPort (window_ptr));
GlobalToLocal (&point);
- XSETINT (bufp->x, point.h);
- XSETINT (bufp->y, point.v);
- XSETFRAME (bufp->frame_or_window, mwp->mFP);
- bufp->timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
- count++;
+ XSETINT (inev.x, point.h);
+ XSETINT (inev.y, point.v);
+ XSETFRAME (inev.frame_or_window, mwp->mFP);
+ inev.timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60);
}
else
SendEventToEventTarget (eventRef, GetEventDispatcherTarget ());
GlobalToLocal (&mouse_loc);
#if USE_CARBON_EVENTS
- bufp->code = mac_get_mouse_btn (eventRef);
+ inev.code = mac_get_mouse_btn (eventRef);
#else
- bufp->code = 0; /* only one mouse button */
+ inev.code = mac_get_emulate_btn (er.modifiers);
#endif
- bufp->kind = SCROLL_BAR_CLICK_EVENT;
- bufp->frame_or_window = tracked_scroll_bar->window;
- bufp->part = scroll_bar_handle;
+ inev.kind = SCROLL_BAR_CLICK_EVENT;
+ inev.frame_or_window = tracked_scroll_bar->window;
+ inev.part = scroll_bar_handle;
#if USE_CARBON_EVENTS
- bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+ inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
- bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+ inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
#endif
- bufp->modifiers |= up_modifier;
- bufp->timestamp = er.when * (1000 / 60);
+ inev.modifiers |= up_modifier;
+ inev.timestamp = er.when * (1000 / 60);
/* ticks to milliseconds */
- XSETINT (bufp->x, tracked_scroll_bar->left + 2);
- XSETINT (bufp->y, mouse_loc.v - 24);
+ XSETINT (inev.x, tracked_scroll_bar->left + 2);
+ XSETINT (inev.y, mouse_loc.v - 24);
tracked_scroll_bar->dragging = Qnil;
mouse_tracking_in_progress = mouse_tracking_none;
tracked_scroll_bar = NULL;
- count++;
break;
}
switch (part_code)
{
case inMenuBar:
- {
- struct frame *f = ((mac_output *)
- GetWRefCon (FrontWindow ()))->mFP;
- saved_menu_event_location = er.where;
- bufp->kind = MENU_BAR_ACTIVATE_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- count++;
- }
+ if (er.what == mouseDown)
+ {
+ struct frame *f = ((mac_output *)
+ GetWRefCon (FrontWindow ()))->mFP;
+ saved_menu_event_location = er.where;
+ inev.kind = MENU_BAR_ACTIVATE_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
+ }
break;
case inContent:
#endif
#if USE_CARBON_EVENTS
- bufp->code = mac_get_mouse_btn (eventRef);
+ inev.code = mac_get_mouse_btn (eventRef);
#else
- bufp->code = 0; /* only one mouse button */
+ inev.code = mac_get_emulate_btn (er.modifiers);
#endif
- XSETINT (bufp->x, mouse_loc.h);
- XSETINT (bufp->y, mouse_loc.v);
- bufp->timestamp = er.when * (1000 / 60);
+ XSETINT (inev.x, mouse_loc.h);
+ XSETINT (inev.y, mouse_loc.v);
+ inev.timestamp = er.when * (1000 / 60);
/* ticks to milliseconds */
#if TARGET_API_MAC_CARBON
struct scroll_bar *bar = (struct scroll_bar *)
GetControlReference (ch);
x_scroll_bar_handle_click (bar, control_part_code, &er,
- bufp);
+ &inev);
if (er.what == mouseDown
&& control_part_code == kControlIndicatorPart)
{
}
else
{
- bufp->kind = MOUSE_CLICK_EVENT;
- XSETFRAME (bufp->frame_or_window, mwp->mFP);
+ Lisp_Object window;
+
+ XSETFRAME (inev.frame_or_window, mwp->mFP);
if (er.what == mouseDown)
- mouse_tracking_in_progress
+ mouse_tracking_in_progress
= mouse_tracking_mouse_movement;
else
- mouse_tracking_in_progress = mouse_tracking_none;
- }
+ mouse_tracking_in_progress = mouse_tracking_none;
+ window = window_from_coordinates (mwp->mFP, inev.x, inev.y, 0, 0, 0, 1);
+
+ if (EQ (window, mwp->mFP->tool_bar_window))
+ {
+ if (er.what == mouseDown)
+ handle_tool_bar_click (mwp->mFP, inev.x, inev.y, 1, 0);
+ else
+ handle_tool_bar_click (mwp->mFP, inev.x, inev.y, 0,
+#if USE_CARBON_EVENTS
+ mac_event_to_emacs_modifiers (eventRef)
+#else
+ er.modifiers
+#endif
+ );
+ break;
+ }
+ else
+ inev.kind = MOUSE_CLICK_EVENT;
+ }
#if USE_CARBON_EVENTS
- bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+ inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
- bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+ inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
#endif
switch (er.what)
{
case mouseDown:
- bufp->modifiers |= down_modifier;
+ inev.modifiers |= down_modifier;
break;
case mouseUp:
- bufp->modifiers |= up_modifier;
+ inev.modifiers |= up_modifier;
break;
}
-
- count++;
}
break;
case inDrag:
#if TARGET_API_MAC_CARBON
- {
- BitMap bm;
-
- GetQDGlobalsScreenBits (&bm);
- DragWindow (window_ptr, er.where, &bm.bounds);
- }
+ if (er.what == mouseDown)
+ {
+ BitMap bm;
+
+ GetQDGlobalsScreenBits (&bm);
+ DragWindow (window_ptr, er.where, &bm.bounds);
+ }
#else /* not TARGET_API_MAC_CARBON */
DragWindow (window_ptr, er.where, &qd.screenBits.bounds);
#endif /* not TARGET_API_MAC_CARBON */
case inGoAway:
if (TrackGoAway (window_ptr, er.where))
{
- bufp->kind = DELETE_WINDOW_EVENT;
- XSETFRAME (bufp->frame_or_window,
+ inev.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (inev.frame_or_window,
((mac_output *) GetWRefCon (window_ptr))->mFP);
- count++;
}
break;
/* window resize handling added --ben */
case inGrow:
- do_grow_window(window_ptr, &er);
- break;
+ if (er.what == mouseDown)
+ {
+ do_grow_window(window_ptr, &er);
+ break;
+ }
/* window zoom handling added --ben */
case inZoomIn:
if (keycode_to_xkeysym (keycode, &xkeysym))
{
- bufp->code = 0xff00 | xkeysym;
- bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
+ inev.code = 0xff00 | xkeysym;
+ inev.kind = NON_ASCII_KEYSTROKE_EVENT;
}
else
{
int new_keycode = keycode | new_modifiers;
Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
unsigned long some_state = 0;
- bufp->code = KeyTranslate (kchr_ptr, new_keycode,
- &some_state) & 0xff;
+ inev.code = KeyTranslate (kchr_ptr, new_keycode,
+ &some_state) & 0xff;
}
else
- bufp->code = er.message & charCodeMask;
- bufp->kind = ASCII_KEYSTROKE_EVENT;
+ inev.code = er.message & charCodeMask;
+ inev.kind = ASCII_KEYSTROKE_EVENT;
}
}
Mac keyboard to be used to enter non-ASCII iso-latin-1
characters directly. */
if (mac_keyboard_text_encoding != kTextEncodingMacRoman
- && bufp->kind == ASCII_KEYSTROKE_EVENT && bufp->code >= 128)
+ && inev.kind == ASCII_KEYSTROKE_EVENT && inev.code >= 128)
{
static TECObjectRef converter = NULL;
OSStatus the_err = noErr;
if (the_err == noErr)
{
- unsigned char ch = bufp->code;
+ unsigned char ch = inev.code;
ByteCount actual_input_length, actual_output_length;
unsigned char outch;
if (convert_status == noErr
&& actual_input_length == 1
&& actual_output_length == 1)
- bufp->code = outch;
+ inev.code = outch;
}
}
#if USE_CARBON_EVENTS
- bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+ inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
- bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+ inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
#endif
{
mac_output *mwp
= (mac_output *) GetWRefCon (FrontNonFloatingWindow ());
- XSETFRAME (bufp->frame_or_window, mwp->mFP);
+ XSETFRAME (inev.frame_or_window, mwp->mFP);
}
- bufp->timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
-
- count++;
+ inev.timestamp = er.when * (1000 / 60); /* ticks to milliseconds */
break;
case kHighLevelEvent:
if (wp && is_emacs_window(wp))
f = ((mac_output *) GetWRefCon (wp))->mFP;
- bufp->kind = DRAG_N_DROP_EVENT;
- bufp->code = 0;
- bufp->timestamp = er.when * (1000 / 60);
+ inev.kind = DRAG_N_DROP_EVENT;
+ inev.code = 0;
+ inev.timestamp = er.when * (1000 / 60);
/* ticks to milliseconds */
#if USE_CARBON_EVENTS
- bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
+ inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
- bufp->modifiers = mac_to_emacs_modifiers (er.modifiers);
+ inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
#endif
- XSETINT (bufp->x, 0);
- XSETINT (bufp->y, 0);
+ XSETINT (inev.x, 0);
+ XSETINT (inev.y, 0);
XSETFRAME (frame, f);
- bufp->frame_or_window = Fcons (frame, drag_and_drop_file_list);
+ inev.frame_or_window = Fcons (frame, drag_and_drop_file_list);
/* Regardless of whether Emacs was suspended or in the
foreground, ask it to redraw its entire screen.
#else /* not TARGET_API_MAC_CARBON */
InvalRect (&(wp->portRect));
#endif /* not TARGET_API_MAC_CARBON */
-
- count++;
}
default:
break;
}
}
- UNBLOCK_INPUT;
+ if (inev.kind != NO_EVENT)
+ {
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ count++;
+ }
+ UNBLOCK_INPUT;
return count;
}
void
make_mac_frame (struct frame *f)
{
- FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
- FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
-
FRAME_DESIRED_CURSOR (f) = FILLED_BOX_CURSOR;
NewMacWindow(f);
FRAME_COLS (f) = 96;
FRAME_LINES (f) = 4;
+ FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
+ FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_right;
+
make_mac_frame (f);
x_make_gc (f);
Initialization
***********************************************************************/
-#ifdef USE_X_TOOLKIT
-static XrmOptionDescRec emacs_options[] = {
- {"-geometry", ".geometry", XrmoptionSepArg, NULL},
- {"-iconic", ".iconic", XrmoptionNoArg, (XtPointer) "yes"},
-
- {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
- XrmoptionSepArg, NULL},
- {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg, NULL},
-
- {"-T", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
- {"-wn", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
- {"-title", "*EmacsShell.title", XrmoptionSepArg, (XtPointer) NULL},
- {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
- {"-in", "*EmacsShell.iconName", XrmoptionSepArg, (XtPointer) NULL},
- {"-mc", "*pointerColor", XrmoptionSepArg, (XtPointer) NULL},
- {"-cr", "*cursorColor", XrmoptionSepArg, (XtPointer) NULL}
-};
-#endif /* USE_X_TOOLKIT */
-
-#ifdef MULTI_KBOARD
-/* Test whether two display-name strings agree up to the dot that separates
- the screen number from the server number. */
-static int
-same_x_server (name1, name2)
- char *name1, *name2;
-{
- int seen_colon = 0;
- unsigned char *system_name = SDATA (Vsystem_name);
- int system_name_length = strlen (system_name);
- int length_until_period = 0;
-
- while (system_name[length_until_period] != 0
- && system_name[length_until_period] != '.')
- length_until_period++;
-
- /* Treat `unix' like an empty host name. */
- if (! strncmp (name1, "unix:", 5))
- name1 += 4;
- if (! strncmp (name2, "unix:", 5))
- name2 += 4;
- /* Treat this host's name like an empty host name. */
- if (! strncmp (name1, system_name, system_name_length)
- && name1[system_name_length] == ':')
- name1 += system_name_length;
- if (! strncmp (name2, system_name, system_name_length)
- && name2[system_name_length] == ':')
- name2 += system_name_length;
- /* Treat this host's domainless name like an empty host name. */
- if (! strncmp (name1, system_name, length_until_period)
- && name1[length_until_period] == ':')
- name1 += length_until_period;
- if (! strncmp (name2, system_name, length_until_period)
- && name2[length_until_period] == ':')
- name2 += length_until_period;
-
- for (; *name1 != '\0' && *name1 == *name2; name1++, name2++)
- {
- if (*name1 == ':')
- seen_colon++;
- if (seen_colon && *name1 == '.')
- return 1;
- }
- return (seen_colon
- && (*name1 == '.' || *name1 == '\0')
- && (*name2 == '.' || *name2 == '\0'));
-}
-#endif
-
int mac_initialized = 0;
void
dpyinfo->reference_count = 0;
dpyinfo->resx = 75.0;
dpyinfo->resy = 75.0;
- dpyinfo->n_planes = 1;
- dpyinfo->n_cbits = 16;
+ dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
+ for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
+ if (HasDepth (main_device_handle, dpyinfo->n_planes,
+ gdDevType, dpyinfo->color_p))
+ break;
dpyinfo->height = (**main_device_handle).gdRect.bottom;
dpyinfo->width = (**main_device_handle).gdRect.right;
dpyinfo->grabbed = 0;
dpyinfo->root_window = NULL;
+ dpyinfo->image_cache = make_image_cache ();
dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
x_get_glyph_overhangs,
x_fix_overlapping_area,
x_draw_fringe_bitmap,
+ 0, /* define_fringe_bitmap */
+ 0, /* destroy_fringe_bitmap */
mac_per_char_metric,
mac_encode_char,
NULL, /* mac_compute_glyph_string_overhangs */
Fprovide (intern ("mac-carbon"), Qnil);
+ staticpro (&Qreverse);
+ Qreverse = intern ("reverse");
+
staticpro (&x_display_name_list);
x_display_name_list = Qnil;
Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop");
staticpro (&Qmac_ready_for_drag_n_drop);
+ Qbig5 = intern ("big5");
+ staticpro (&Qbig5);
+
+ Qcn_gb = intern ("cn-gb");
+ staticpro (&Qcn_gb);
+
+ Qsjis = intern ("sjis");
+ staticpro (&Qsjis);
+
+ Qeuc_kr = intern ("euc-kr");
+ staticpro (&Qeuc_kr);
+
DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p,
doc: /* *Non-nil means autoselect window with mouse pointer. */);
x_autoselect_window_p = 0;
useful for non-standard keyboard layouts. */);
Vmac_reverse_ctrl_meta = Qnil;
+ DEFVAR_LISP ("mac-emulate-three-button-mouse",
+ &Vmac_emulate_three_button_mouse,
+ doc: /* t means that when the option-key is held down while pressing the
+ mouse button, the click will register as mouse-2 and while the
+ command-key is held down, the click will register as mouse-3.
+ 'reverse means that the the option-key will register for mouse-3
+ and the command-key will register for mouse-2. nil means that
+ not emulation should be done and the modifiers should be placed
+ on the mouse-1 event. */);
+ Vmac_emulate_three_button_mouse = Qnil;
+
#if USE_CARBON_EVENTS
DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2,
doc: /* Non-nil means that the wheel button will be treated as mouse-2 and
characters directly. */);
mac_keyboard_text_encoding = kTextEncodingMacRoman;
}
+
+/* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
+ (do not change this comment) */