X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/f9e65eb300c487a85de743edc0bafd6434d6db5e..6858afd0c4acb9a214231f50aeab39cbcc5b3f17:/src/macterm.c diff --git a/src/macterm.c b/src/macterm.c index 510269c8ca..93f3e73472 100644 --- a/src/macterm.c +++ b/src/macterm.c @@ -1,5 +1,5 @@ /* Implementation of GUI terminal on the Mac OS. - Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -35,29 +35,6 @@ Boston, MA 02111-1307, USA. */ #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 -#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. */ @@ -132,6 +109,10 @@ static int any_help_event_p; int x_autoselect_window_p; +/* Non-zero means make use of UNDERLINE_POSITION font properties. */ + +int x_use_underline_position_properties; + /* Non-zero means draw block and hollow cursor as wide as the glyph under it. For example, if a block cursor is over a tab, it will be drawn as wide as that tab on the display. */ @@ -249,8 +230,6 @@ extern Lisp_Object Vcommand_line_args, Vsystem_name; 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. */ @@ -263,8 +242,6 @@ static Lisp_Object Qvendor_specific_keysyms; extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *)); #endif -extern Lisp_Object x_icon_type P_ ((struct frame *)); - extern int inhibit_window_system; #if __MRC__ @@ -303,9 +280,10 @@ static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); 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_clip_to_row P_ ((struct window *, struct glyph_row *, - GC, 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 *)); static void x_update_window_begin P_ ((struct window *)); @@ -317,7 +295,6 @@ void deactivate_scroll_bars (FRAME_PTR); static int is_emacs_window (WindowPtr); extern int image_ascent (struct image *, struct face *); -void x_set_offset (struct frame *, int, int, int); int x_bitmap_icon (struct frame *, Lisp_Object); void x_make_frame_visible (struct frame *); @@ -329,15 +306,12 @@ extern void set_frame_menubar (FRAME_PTR, int, int); /* 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); } @@ -349,9 +323,9 @@ mac_set_forecolor (unsigned long color) { 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); } @@ -365,9 +339,9 @@ mac_set_backcolor (unsigned long 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); } @@ -403,6 +377,23 @@ XDrawLine (display, w, gc, x1, y1, x2, y2) 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 @@ -469,15 +460,21 @@ XClearWindow (display, w) /* 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 @@ -485,19 +482,16 @@ mac_draw_bitmap (display, w, gc, x, y, bitmap) #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 */ } @@ -540,6 +534,23 @@ mac_reset_clipping (display, w) } +/* 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 @@ -548,18 +559,19 @@ mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h) 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); } @@ -572,6 +584,67 @@ mac_free_bitmap (bitmap) 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 @@ -597,6 +670,26 @@ XFillRectangle (display, w, gc, x, y, width, height) } +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 @@ -632,20 +725,15 @@ mac_draw_rectangle_to_pixmap (display, p, gc, x, y, width, height) 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)); } @@ -760,23 +848,66 @@ mac_copy_area (display, src, dest, gc, src_x, src_y, width, height, dest_x, 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)); } @@ -811,7 +942,6 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y) { #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); @@ -822,8 +952,10 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y) 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); @@ -866,25 +998,67 @@ static void 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_x + width, src_y + height); + SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); + + 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; - SetRect (&src_r, src_x, src_y, src_right, src_bottom); - SetRect (&dest_r, dest_x, dest_y, dest_x + w, dest_y + h); + 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); - CopyBits ((BitMap *) &src, (BitMap *) &dest, &src_r, &dest_r, srcCopy, 0); + 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)); } @@ -941,7 +1115,7 @@ XGetGCValues (void* ignore, XGCValues *gc, /* Mac replacement for XSetForeground. */ -static void +void XSetForeground (display, gc, color) Display *display; GC gc; @@ -1145,6 +1319,9 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p) output_cursor.x, output_cursor.y); x_draw_vertical_border (w); + + draw_window_fringes (w); + UNBLOCK_INPUT; } @@ -1241,11 +1418,7 @@ x_after_update_window_line (desired_row) 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 @@ -1272,7 +1445,7 @@ x_after_update_window_line (desired_row) XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), 0, y, width, height, 0); XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), - f->output_data.mac->pixel_width - width, y, + FRAME_PIXEL_WIDTH (f) - width, y, width, height, 0); UNBLOCK_INPUT; @@ -1297,11 +1470,26 @@ x_draw_fringe_bitmap (w, row, p) 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, 1); + 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; @@ -1327,18 +1515,18 @@ x_draw_fringe_bitmap (w, row, p) #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); @@ -2119,6 +2307,21 @@ x_copy_dpy_color (dpy, cmap, pixel) #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 @@ -2134,12 +2337,42 @@ mac_alloc_lighter_color (f, color, factor, delta) 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)))), @@ -2184,7 +2417,8 @@ x_setup_relief_color (f, relief, factor, delta, default_pixel) /* 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; @@ -2214,6 +2448,10 @@ x_setup_relief_colors (s) 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; @@ -2247,9 +2485,11 @@ static void 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; @@ -2257,41 +2497,41 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, 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); } @@ -2306,7 +2546,7 @@ static void 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; @@ -2316,21 +2556,21 @@ x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, /* 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); } @@ -2351,9 +2591,10 @@ x_draw_glyph_string_box (s) if (s->row->full_width_p && !s->w->pseudo_window_p) { - last_x += FRAME_X_RIGHT_FRINGE_WIDTH (s->f); - if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f)) - last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f); + last_x += WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s->w); + if (s->area != RIGHT_MARGIN_AREA + || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w)) + last_x += WINDOW_RIGHT_FRINGE_WIDTH (s->w); } /* The glyph that may have a right box line. */ @@ -2364,9 +2605,9 @@ x_draw_glyph_string_box (s) 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; @@ -2417,39 +2658,36 @@ x_draw_image_foreground (s) 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 @@ -2473,7 +2711,6 @@ x_draw_image_foreground (s) } - /* Draw a relief around the image glyph string S. */ static void @@ -2546,30 +2783,12 @@ x_draw_image_foreground_1 (s, pixmap) 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); @@ -2584,15 +2803,16 @@ x_draw_image_foreground_1 (s, pixmap) { 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); } @@ -2625,7 +2845,7 @@ x_draw_glyph_string_bg_rect (s, x, y, w, h) | s->face->box | | +------------------------- - | | s->img->vmargin + | | s->img->margin | | | | +------------------- | | | the image @@ -2644,6 +2864,7 @@ x_draw_image_glyph_string (s) 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. */ @@ -2651,9 +2872,7 @@ x_draw_image_glyph_string (s) 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) { @@ -2663,25 +2882,21 @@ x_draw_image_glyph_string (s) 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. */ @@ -2691,18 +2906,19 @@ x_draw_image_glyph_string (s) 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; @@ -2714,7 +2930,7 @@ x_draw_image_glyph_string (s) 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); } @@ -2743,7 +2959,7 @@ x_draw_stretch_glyph_string (s) { /* If `x-stretch-block-cursor' is nil, don't draw a block cursor as wide as the stretch glyph. */ - int width = min (CANON_X_UNIT (s->f), s->background_width); + int width = min (FRAME_COLUMN_WIDTH (s->f), s->background_width); /* Draw cursor. */ x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height); @@ -2751,10 +2967,10 @@ x_draw_stretch_glyph_string (s) /* 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)) @@ -2814,7 +3030,6 @@ x_draw_glyph_string (s) 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. */ @@ -2851,7 +3066,7 @@ x_draw_glyph_string (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; @@ -2928,9 +3143,9 @@ x_draw_glyph_string (s) } } - /* 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. */ @@ -2950,7 +3165,6 @@ mac_shift_glyphs_for_insert (f, x, y, width, height, shift_by) x + shift_by, y); } - /* Delete N glyphs at the nominal cursor position. Not implemented for X frames. */ @@ -3005,6 +3219,7 @@ x_clear_frame () #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. */ @@ -3108,7 +3323,7 @@ XTring_bell () 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; { @@ -3144,10 +3359,8 @@ x_scroll_run (w, run) /* 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); - width += FRAME_X_FRINGE_WIDTH (f); - x -= FRAME_X_LEFT_FRINGE_WIDTH (f); from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y); to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y); @@ -3234,7 +3447,7 @@ x_new_focus_frame (dpyinfo, frame) selected_frame = frame; XSETFRAME (XWINDOW (selected_frame->selected_window)->frame, selected_frame); - Fselect_window (selected_frame->selected_window); + Fselect_window (selected_frame->selected_window, Qnil); choose_minibuf_frame (); #endif /* ! 0 */ @@ -3268,8 +3481,6 @@ static void XTframe_rehighlight (frame) struct frame *frame; { - - x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame)); } @@ -3464,107 +3675,6 @@ x_get_keysym_name (keysym) /* Mouse clicks and mouse movement. Rah. */ -/* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph - co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the - glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do - not force the value into range. */ - -void -pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip) - FRAME_PTR f; - register int pix_x, pix_y; - register int *x, *y; - Rect *bounds; - int noclip; -{ - /* Support tty mode: if Vwindow_system is nil, behave correctly. */ - if (NILP (Vwindow_system)) - { - *x = pix_x; - *y = pix_y; - return; - } - - /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down - even for negative values. */ - if (pix_x < 0) - pix_x -= FONT_WIDTH (FRAME_FONT (f)) - 1; - if (pix_y < 0) - pix_y -= (f)->output_data.mac->line_height - 1; - - pix_x = PIXEL_TO_CHAR_COL (f, pix_x); - pix_y = PIXEL_TO_CHAR_ROW (f, pix_y); - - if (bounds) - { - bounds->left = CHAR_TO_PIXEL_COL (f, pix_x); - bounds->top = CHAR_TO_PIXEL_ROW (f, pix_y); - bounds->right = bounds->left + FONT_WIDTH (FRAME_FONT (f)) - 1; - bounds->bottom = bounds->top + f->output_data.mac->line_height - 1; - } - - if (!noclip) - { - if (pix_x < 0) - pix_x = 0; - else if (pix_x > FRAME_WINDOW_WIDTH (f)) - pix_x = FRAME_WINDOW_WIDTH (f); - - if (pix_y < 0) - pix_y = 0; - else if (pix_y > f->height) - pix_y = f->height; - } - - *x = pix_x; - *y = pix_y; -} - - -/* Given HPOS/VPOS in the current matrix of W, return corresponding - frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we - can't tell the positions because W's display is not up to date, - return 0. */ - -int -glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y) - struct window *w; - int hpos, vpos; - int *frame_x, *frame_y; -{ - int success_p; - - xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w); - xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h); - - if (display_completed) - { - struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos); - struct glyph *glyph = row->glyphs[TEXT_AREA]; - struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]); - - *frame_y = row->y; - *frame_x = row->x; - while (glyph < end) - { - *frame_x += glyph->pixel_width; - ++glyph; - } - - success_p = 1; - } - else - { - *frame_y = *frame_x = 0; - success_p = 0; - } - - *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, *frame_y); - *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, *frame_x); - return success_p; -} - - /* Prepare a mouse-event in *RESULT for placement in the input queue. If the event is a button press, then note that we have grabbed @@ -3691,15 +3801,14 @@ glyph_rect (f, x, y, rect) { Lisp_Object window; - window = window_from_coordinates (f, x, y, 0, 0); + window = window_from_coordinates (f, x, y, 0, &x, &y, 0); + if (!NILP (window)) { struct window *w = XWINDOW (window); struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); struct glyph_row *end = r + w->current_matrix->nrows - 1; - frame_to_window_pixel_xy (w, &x, &y); - for (; r < end && r->enabled_p; ++r) if (r->y <= y && r->y + r->height > y) { @@ -3714,7 +3823,10 @@ glyph_rect (f, x, y, rect) if (x < r->x) { /* x is to the left of the first glyph in the row. */ - rect->left = XINT (w->left); + /* Shouldn't this be a pixel value? + WINDOW_LEFT_EDGE_X (w) seems to be the right value. + ++KFS */ + rect->left = WINDOW_LEFT_EDGE_COL (w); rect->right = WINDOW_TO_FRAME_PIXEL_X (w, r->x); return 1; } @@ -3730,7 +3842,10 @@ glyph_rect (f, x, y, rect) /* x is to the right of the last glyph in the row. */ rect->left = WINDOW_TO_FRAME_PIXEL_X (w, gx); - rect->right = XINT (w->left) + XINT (w->width); + /* Shouldn't this be a pixel value? + WINDOW_RIGHT_EDGE_X (w) seems to be the right value. + ++KFS */ + rect->right = WINDOW_RIGHT_EDGE_COL (w); return 1; } } @@ -3752,7 +3867,7 @@ remember_mouse_glyph (f1, gx, gy) int width = FRAME_SMALLEST_CHAR_WIDTH (f1); int height = FRAME_SMALLEST_FONT_HEIGHT (f1); - /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to + /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down even for negative values. */ if (gx < 0) gx -= width - 1; @@ -4038,35 +4153,30 @@ XTset_vertical_scroll_bar (w, portion, whole, position) struct frame *f = XFRAME (w->frame); struct scroll_bar *bar; int top, height, left, sb_left, width, sb_width, disp_top, disp_height; - int window_x, window_y, window_width, window_height; + int window_y, window_height; /* Get window dimensions. */ - window_box (w, -1, &window_x, &window_y, &window_width, &window_height); + window_box (w, -1, 0, &window_y, 0, &window_height); top = window_y; #ifdef MAC_OSX width = 16; #else - width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f); + width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f); #endif height = window_height; /* Compute the left edge of the scroll bar area. */ - if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) - left = XINT (w->left) + XINT (w->width) - FRAME_SCROLL_BAR_COLS (f); - else - left = XFASTINT (w->left); - left *= CANON_X_UNIT (f); - left += FRAME_INTERNAL_BORDER_WIDTH (f); + left = WINDOW_SCROLL_BAR_AREA_X (w); /* Compute the width of the scroll bar which might be less than the width of the area reserved for the scroll bar. */ - if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0) - sb_width = FRAME_SCROLL_BAR_PIXEL_WIDTH (f); + if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) > 0) + sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w); else sb_width = width; /* Compute the left edge of the scroll bar. */ - if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) + if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)) sb_left = left + width - sb_width - (width - sb_width) / 2; else sb_left = left + (width - sb_width) / 2; @@ -4079,13 +4189,13 @@ XTset_vertical_scroll_bar (w, portion, whole, position) disp_top = -1; disp_height++; } - else if (disp_top == PIXEL_HEIGHT (f) - 16) + else if (disp_top == FRAME_PIXEL_HEIGHT (f) - 16) { disp_top++; disp_height--; } - if (sb_left + sb_width == PIXEL_WIDTH (f)) + if (sb_left + sb_width == FRAME_PIXEL_WIDTH (f)) sb_left++; /* Does the scroll bar exist yet? */ @@ -4121,12 +4231,12 @@ XTset_vertical_scroll_bar (w, portion, whole, position) wide as the area reserved for it . This makes sure a previous mode line display is cleared after C-x 2 C-x 1, for example. */ - int area_width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f); + int area_width = WINDOW_SCROLL_BAR_AREA_WIDTH (w); XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), left, top, area_width, height, 0); #if 0 - if (sb_left + sb_width >= PIXEL_WIDTH (f)) + if (sb_left + sb_width >= FRAME_PIXEL_WIDTH (f)) XClearArea (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), sb_left - 1, top, 1, height, 0); #endif @@ -4469,25 +4579,22 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time) /* Set clipping for output in glyph row ROW. W is the window in which we operate. GC is the graphics context to set clipping in. - WHOLE_LINE_P non-zero means include the areas used for truncation - mark display and alike in the clipping rectangle. ROW may be a text row or, e.g., a mode line. Text rows must be clipped to the interior of the window dedicated to text display, mode lines must be clipped to the whole window. */ static void -x_clip_to_row (w, row, gc, whole_line_p) +x_clip_to_row (w, row, gc) struct window *w; struct glyph_row *row; GC gc; - int whole_line_p; { struct frame *f = XFRAME (WINDOW_FRAME (w)); Rect clip_rect; - int window_x, window_y, window_width, window_height; + int window_y, window_width; - window_box (w, -1, &window_x, &window_y, &window_width, &window_height); + window_box (w, -1, 0, &window_y, &window_width, 0); clip_rect.left = WINDOW_TO_FRAME_PIXEL_X (w, 0); clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); @@ -4495,14 +4602,6 @@ x_clip_to_row (w, row, gc, whole_line_p) clip_rect.right = clip_rect.left + window_width; clip_rect.bottom = clip_rect.top + row->visible_height; - /* If clipping to the whole line, including trunc marks, extend - the rectangle to the left and increase its width. */ - if (whole_line_p) - { - clip_rect.left -= FRAME_X_LEFT_FRINGE_WIDTH (f); - clip_rect.right += FRAME_X_FRINGE_WIDTH (f); - } - mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), &clip_rect); } @@ -4522,13 +4621,6 @@ x_draw_hollow_cursor (w, row) 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); @@ -4542,7 +4634,21 @@ x_draw_hollow_cursor (w, row) wd = cursor_glyph->pixel_width - 1; if (cursor_glyph->type == STRETCH_GLYPH && !x_stretch_cursor_p) - wd = min (CANON_X_UNIT (f), wd); + 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. */ @@ -4555,7 +4661,7 @@ x_draw_hollow_cursor (w, row) gc = dpyinfo->scratch_cursor_gc; /* Set clipping, draw the rectangle, and reset clipping again. */ - x_clip_to_row (w, row, gc, 0); + x_clip_to_row (w, row, gc); mac_draw_rectangle (dpy, FRAME_MAC_WINDOW (f), gc, x, y, wd, h); mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); } @@ -4569,35 +4675,49 @@ x_draw_hollow_cursor (w, row) --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); @@ -4609,14 +4729,24 @@ x_draw_bar_cursor (w, row, width) if (width < 0) width = FRAME_CURSOR_WIDTH (f); + width = min (cursor_glyph->pixel_width, width); + + w->phys_cursor_width = width; + x_clip_to_row (w, row, gc); + + 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); - x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); - x_clip_to_row (w, row, gc, 0); - XFillRectangle (dpy, window, gc, - x, - WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), - min (cursor_glyph->pixel_width, width), - row->height); mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); } } @@ -4648,19 +4778,26 @@ mac_clear_frame_area (f, x, y, width, height) /* RIF: Draw cursor on window W. */ static void -mac_draw_window_cursor (w, glyph_row, on, x, y, new_cursor_type, new_cursor_width) +mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, active_p) struct window *w; struct glyph_row *glyph_row; - int on, x, y; - int new_cursor_type, new_cursor_width; + int x, y; + int cursor_type, cursor_width; + int on_p, active_p; { - if (on) + if (on_p) { - w->phys_cursor_type = new_cursor_type; - w->phys_cursor_width = new_cursor_width; + w->phys_cursor_type = cursor_type; w->phys_cursor_on_p = 1; - switch (new_cursor_type) + 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: x_draw_hollow_cursor (w, glyph_row); @@ -4670,13 +4807,16 @@ mac_draw_window_cursor (w, glyph_row, on, x, y, new_cursor_type, new_cursor_widt 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, new_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: @@ -4784,36 +4924,37 @@ x_new_font (f, fontname) FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset; FRAME_FONTSET (f) = -1; + FRAME_COLUMN_WIDTH (f) = FONT_WIDTH (FRAME_FONT (f)); + FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (FRAME_FONT (f)); + + compute_fringe_widths (f, 1); + /* Compute the scroll bar width in character columns. */ - if (f->scroll_bar_pixel_width > 0) + if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0) { - int wid = FONT_WIDTH (FRAME_FONT (f)); - f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid; + int wid = FRAME_COLUMN_WIDTH (f); + FRAME_CONFIG_SCROLL_BAR_COLS (f) + = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid-1) / wid; } else { - int wid = FONT_WIDTH (FRAME_FONT (f)); - f->scroll_bar_cols = (14 + wid - 1) / wid; + int wid = FRAME_COLUMN_WIDTH (f); + FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid; } /* Now make the frame display the given font. */ if (FRAME_MAC_WINDOW (f) != 0) { XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->normal_gc, - f->output_data.mac->font); + FRAME_FONT (f)); XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->reverse_gc, - f->output_data.mac->font); + FRAME_FONT (f)); XSetFont (FRAME_MAC_DISPLAY (f), f->output_data.mac->cursor_gc, - f->output_data.mac->font); + FRAME_FONT (f)); - frame_update_line_height (f); if (NILP (tip_frame) || XFRAME (tip_frame) != f) - x_set_window_size (f, 0, f->width, f->height); + x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); } - else - /* If we are setting a new frame's font for the first time, - there are no faces yet, so this font's height is the line height. */ - f->output_data.mac->line_height = FONT_HEIGHT (FRAME_FONT (f)); return build_string (fontp->full_name); } @@ -4875,7 +5016,7 @@ x_calc_absolute_position (f) struct frame *f; { Point pt; - int flags = f->output_data.mac->size_hint_flags; + int flags = f->size_hint_flags; pt.h = pt.v = 0; @@ -4909,20 +5050,20 @@ x_calc_absolute_position (f) /* Treat negative positions as relative to the leftmost bottommost position that fits on the screen. */ if (flags & XNegative) - f->output_data.mac->left_pos = (FRAME_MAC_DISPLAY_INFO (f)->width - - 2 * f->output_data.mac->border_width - pt.h - - PIXEL_WIDTH (f) - + f->output_data.mac->left_pos); + f->left_pos = (FRAME_MAC_DISPLAY_INFO (f)->width + - 2 * f->border_width - pt.h + - FRAME_PIXEL_WIDTH (f) + + f->left_pos); /* NTEMACS_TODO: Subtract menubar height? */ if (flags & YNegative) - f->output_data.mac->top_pos = (FRAME_MAC_DISPLAY_INFO (f)->height - - 2 * f->output_data.mac->border_width - pt.v - - PIXEL_HEIGHT (f) - + f->output_data.mac->top_pos); + f->top_pos = (FRAME_MAC_DISPLAY_INFO (f)->height + - 2 * f->border_width - pt.v + - FRAME_PIXEL_HEIGHT (f) + + f->top_pos); /* The left_pos and top_pos are now relative to the top and left screen edges, so the flags should correspond. */ - f->output_data.mac->size_hint_flags &= ~ (XNegative | YNegative); + f->size_hint_flags &= ~ (XNegative | YNegative); } /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position, @@ -4941,22 +5082,22 @@ x_set_offset (f, xoff, yoff, change_gravity) if (change_gravity > 0) { - f->output_data.mac->top_pos = yoff; - f->output_data.mac->left_pos = xoff; - f->output_data.mac->size_hint_flags &= ~ (XNegative | YNegative); + f->top_pos = yoff; + f->left_pos = xoff; + f->size_hint_flags &= ~ (XNegative | YNegative); if (xoff < 0) - f->output_data.mac->size_hint_flags |= XNegative; + f->size_hint_flags |= XNegative; if (yoff < 0) - f->output_data.mac->size_hint_flags |= YNegative; - f->output_data.mac->win_gravity = NorthWestGravity; + f->size_hint_flags |= YNegative; + f->win_gravity = NorthWestGravity; } x_calc_absolute_position (f); BLOCK_INPUT; x_wm_set_size_hint (f, (long) 0, 0); - modified_left = f->output_data.mac->left_pos; - modified_top = f->output_data.mac->top_pos; + modified_left = f->left_pos; + modified_top = f->top_pos; MoveWindow (f->output_data.mac->mWP, modified_left + 6, modified_top + 42, false); @@ -4980,17 +5121,15 @@ x_set_window_size (f, change_gravity, cols, rows) BLOCK_INPUT; check_frame_size (f, &rows, &cols); - f->output_data.mac->vertical_scroll_bar_extra - = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f) - ? 0 - : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.mac->font))); + f->scroll_bar_actual_width + = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f); compute_fringe_widths (f, 0); - pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols); - pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows); + pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols); + pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows); - f->output_data.mac->win_gravity = NorthWestGravity; + f->win_gravity = NorthWestGravity; x_wm_set_size_hint (f, (long) 0, 0); SizeWindow (FRAME_MAC_WINDOW (f), pixelwidth, pixelheight, 0); @@ -5009,8 +5148,8 @@ x_set_window_size (f, change_gravity, cols, rows) We pass 1 for DELAY since we can't run Lisp code inside of a BLOCK_INPUT. */ change_frame_size (f, rows, cols, 0, 1, 0); - PIXEL_WIDTH (f) = pixelwidth; - PIXEL_HEIGHT (f) = pixelheight; + FRAME_PIXEL_WIDTH (f) = pixelwidth; + FRAME_PIXEL_HEIGHT (f) = pixelheight; /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to receive in the ConfigureNotify event; if we get what we asked @@ -5043,14 +5182,14 @@ x_set_mouse_position (f, x, y) { int pix_x, pix_y; - pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->output_data.mac->font) / 2; - pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.mac->line_height / 2; + pix_x = FRAME_COL_TO_PIXEL_X (f, x) + FRAME_COLUMN_WIDTH (f) / 2; + pix_y = FRAME_LINE_TO_PIXEL_Y (f, y) + FRAME_LINE_HEIGHT (f) / 2; if (pix_x < 0) pix_x = 0; - if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f); + if (pix_x > FRAME_PIXEL_WIDTH (f)) pix_x = FRAME_PIXEL_WIDTH (f); if (pix_y < 0) pix_y = 0; - if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f); + if (pix_y > FRAME_PIXEL_HEIGHT (f)) pix_y = FRAME_PIXEL_HEIGHT (f); x_set_mouse_pixel_position (f, pix_x, pix_y); } @@ -5149,8 +5288,7 @@ x_make_frame_visible (f) before the window gets really visible. */ if (! FRAME_ICONIFIED_P (f) && ! f->output_data.mac->asked_for_visible) - x_set_offset (f, f->output_data.mac->left_pos, - f->output_data.mac->top_pos, 0); + x_set_offset (f, f->left_pos, f->top_pos, 0); f->output_data.mac->asked_for_visible = 1; @@ -5203,6 +5341,8 @@ x_make_frame_visible (f) FRAME_SAMPLE_VISIBILITY (f); } } +#else + UNBLOCK_INPUT; #endif /* MAC_TODO */ } @@ -5259,10 +5399,10 @@ x_iconify_frame (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); @@ -5272,10 +5412,15 @@ x_destroy_window (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) @@ -5283,8 +5428,6 @@ x_destroy_window (f) 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 @@ -5298,6 +5441,21 @@ x_destroy_window (f) 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--; +} + /* Setting window manager hints. */ @@ -5327,8 +5485,8 @@ x_wm_set_size_hint (f, flags, user_position) /* Setting PMaxSize caused various problems. */ size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */; - size_hints.x = f->output_data.x->left_pos; - size_hints.y = f->output_data.x->top_pos; + size_hints.x = f->left_pos; + size_hints.y = f->top_pos; #ifdef USE_X_TOOLKIT XtSetArg (al[ac], XtNwidth, &widget_width); ac++; @@ -5337,16 +5495,16 @@ x_wm_set_size_hint (f, flags, user_position) size_hints.height = widget_height; size_hints.width = widget_width; #else /* not USE_X_TOOLKIT */ - size_hints.height = PIXEL_HEIGHT (f); - size_hints.width = PIXEL_WIDTH (f); + size_hints.height = FRAME_PIXEL_HEIGHT (f); + size_hints.width = FRAME_PIXEL_WIDTH (f); #endif /* not USE_X_TOOLKIT */ - size_hints.width_inc = FONT_WIDTH (f->output_data.x->font); - size_hints.height_inc = f->output_data.x->line_height; + size_hints.width_inc = FRAME_COLUMN_WIDTH (f); + size_hints.height_inc = FRAME_LINE_HEIGHT (f); size_hints.max_width - = FRAME_X_DISPLAY_INFO (f)->width - CHAR_TO_PIXEL_WIDTH (f, 0); + = FRAME_X_DISPLAY_INFO (f)->width - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); size_hints.max_height - = FRAME_X_DISPLAY_INFO (f)->height - CHAR_TO_PIXEL_HEIGHT (f, 0); + = FRAME_X_DISPLAY_INFO (f)->height - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); /* Calculate the base and minimum sizes. @@ -5357,8 +5515,8 @@ x_wm_set_size_hint (f, flags, user_position) int base_width, base_height; int min_rows = 0, min_cols = 0; - base_width = CHAR_TO_PIXEL_WIDTH (f, 0); - base_height = CHAR_TO_PIXEL_HEIGHT (f, 0); + base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0); + base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0); check_frame_size (f, &min_rows, &min_cols); @@ -5433,7 +5591,7 @@ x_wm_set_size_hint (f, flags, user_position) #endif #ifdef PWinGravity - size_hints.win_gravity = f->output_data.x->win_gravity; + size_hints.win_gravity = f->win_gravity; size_hints.flags |= PWinGravity; if (user_position) @@ -5564,6 +5722,7 @@ char **font_name_table = NULL; 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) @@ -5643,13 +5802,53 @@ mac_font_match (char *mf, char *xf) && 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) { @@ -5708,6 +5907,8 @@ static void 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, ""); @@ -5717,13 +5918,29 @@ x_font_name_to_mac_font_name (char *xf, char *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'; + } } @@ -5787,36 +6004,45 @@ init_font_name_table () 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. */ @@ -5858,6 +6084,7 @@ init_font_name_table () TextFont (fontnum); scriptcode = FontToScript (fontnum); + decode_mac_font_name (name, sizeof (name), scriptcode); do { HLock (font_handle); @@ -5892,9 +6119,9 @@ init_font_name_table () 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++] @@ -5921,10 +6148,150 @@ init_font_name_table () } +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 - calling mac_font_pattern_match (slow). */ + calling mac_font_pattern_match (slow). Return as many matching + fonts as possible if MAXNAMES = -1. */ Lisp_Object x_list_fonts (struct frame *f, @@ -5932,11 +6299,7 @@ x_list_fonts (struct frame *f, 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. */ @@ -5955,27 +6318,10 @@ x_list_fonts (struct frame *f, } } - 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 (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, @@ -6135,14 +6481,12 @@ XLoadQueryFont (Display *dpy, char *fontname) name = fontname; else { - for (i = 0; i < font_name_count; i++) - if (mac_font_pattern_match (font_name_table[i], fontname)) - break; - - if (i >= font_name_count) - return NULL; + Lisp_Object matched_fonts; - 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 */ @@ -6264,7 +6608,8 @@ XLoadQueryFont (Display *dpy, char *fontname) 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); } } } @@ -6353,6 +6698,7 @@ x_load_font (f, fontname, size) /* 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); @@ -6486,81 +6832,6 @@ x_find_ccl_program (fontp) -/*********************************************************************** - 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 @@ -6622,12 +6893,19 @@ static long app_sleep_time = WNE_SLEEP_AT_RESUME; 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. */ @@ -6700,6 +6978,20 @@ mac_to_emacs_modifiers (EventModifiers mods) 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. */ @@ -6709,6 +7001,11 @@ mac_event_to_emacs_modifiers (EventRef eventRef) 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); } @@ -6723,7 +7020,14 @@ mac_get_mouse_btn (EventRef ref) 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: @@ -6832,8 +7136,8 @@ do_check_ram_size (void) 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); @@ -7114,8 +7418,8 @@ do_grow_window (WindowPtr w, EventRecord *e) /* see if it really changed size */ if (grow_size != 0) { - rows = PIXEL_TO_CHAR_HEIGHT (f, HiWord (grow_size)); - columns = PIXEL_TO_CHAR_WIDTH (f, LoWord (grow_size)); + rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, HiWord (grow_size)); + columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, LoWord (grow_size)); x_set_window_size (f, 0, columns, rows); } @@ -7167,7 +7471,7 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out) InsetRect (&zoom_rect, 8, 4); /* not too tight */ zoom_rect.right = zoom_rect.left - + CHAR_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS); + + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS); SetWindowStandardState (w, &zoom_rect); } @@ -7189,7 +7493,7 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out) InsetRect (&zoom_rect, 8, 4); /* not too tight */ zoom_rect.right = zoom_rect.left - + CHAR_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS); + + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, DEFAULT_NUM_COLS); (**((WStateDataHandle) ((WindowPeek) w)->dataHandle)).stdState = zoom_rect; @@ -7204,8 +7508,8 @@ do_zoom_window (WindowPtr w, int zoom_in_or_out) #else port_rect = w->portRect; #endif - rows = PIXEL_TO_CHAR_HEIGHT (f, port_rect.bottom - port_rect.top); - columns = PIXEL_TO_CHAR_WIDTH (f, port_rect.right - port_rect.left); + rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, port_rect.bottom - port_rect.top); + columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, port_rect.right - port_rect.left); x_set_window_size (mwp->mFP, 0, columns, rows); SetPort (save_port); @@ -7632,7 +7936,9 @@ main (void) do_get_menus (); +#ifndef USE_LSB_TAG do_check_ram_size (); +#endif init_emacs_passwd_dir (); @@ -7710,8 +8016,9 @@ keycode_to_xkeysym (int keyCode, int *xKeySym) /* 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; @@ -7736,9 +8043,6 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) /* 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 @@ -7757,7 +8061,9 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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))) @@ -7795,16 +8101,17 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) GetEventParameter(eventRef, kEventParamMouseLocation, typeQDPoint, NULL, sizeof (Point), NULL, &point); - bufp->kind = MOUSE_WHEEL_EVENT; - bufp->code = delta; - bufp->modifiers = mac_event_to_emacs_modifiers(eventRef); + 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 ()); @@ -7853,28 +8160,27 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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; } @@ -7883,14 +8189,14 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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: @@ -7920,13 +8226,13 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) #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 @@ -7938,7 +8244,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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) { @@ -7954,43 +8260,61 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) } 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 */ @@ -7999,17 +8323,19 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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: @@ -8068,8 +8394,8 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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 { @@ -8088,12 +8414,12 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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; } } @@ -8104,7 +8430,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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; @@ -8133,7 +8459,7 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) if (the_err == noErr) { - unsigned char ch = bufp->code; + unsigned char ch = inev.code; ByteCount actual_input_length, actual_output_length; unsigned char outch; @@ -8144,25 +8470,23 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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: @@ -8190,21 +8514,21 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) 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. @@ -8221,8 +8545,6 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) #else /* not TARGET_API_MAC_CARBON */ InvalRect (&(wp->portRect)); #endif /* not TARGET_API_MAC_CARBON */ - - count++; } default: break; @@ -8291,8 +8613,13 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected) } } - UNBLOCK_INPUT; + if (inev.kind != NO_EVENT) + { + kbd_buffer_store_event_hold (&inev, hold_quit); + count++; + } + UNBLOCK_INPUT; return count; } @@ -8354,7 +8681,7 @@ NewMacWindow (FRAME_PTR fp) mwp->fontset = -1; - SizeWindow (mwp->mWP, mwp->pixel_width, mwp->pixel_height, false); + SizeWindow (mwp->mWP, FRAME_PIXEL_WIDTH (fp), FRAME_PIXEL_HEIGHT (fp), false); ShowWindow (mwp->mWP); } @@ -8363,9 +8690,6 @@ NewMacWindow (FRAME_PTR fp) 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); @@ -8375,23 +8699,23 @@ make_mac_frame (struct frame *f) f->output_data.mac->mouse_pixel = 0xff00ff; f->output_data.mac->cursor_foreground_pixel = 0x0000ff; - f->output_data.mac->fontset = -1; + FRAME_FONTSET (f) = -1; f->output_data.mac->scroll_bar_foreground_pixel = -1; f->output_data.mac->scroll_bar_background_pixel = -1; - f->output_data.mac->left_pos = 4; - f->output_data.mac->top_pos = 4; - f->output_data.mac->border_width = 0; f->output_data.mac->explicit_parent = 0; + f->left_pos = 4; + f->top_pos = 4; + f->border_width = 0; - f->output_data.mac->internal_border_width = 0; + f->internal_border_width = 0; f->output_method = output_mac; f->auto_raise = 1; f->auto_lower = 1; - f->new_width = 0; - f->new_height = 0; + f->new_text_cols = 0; + f->new_text_lines = 0; } void @@ -8405,14 +8729,17 @@ make_mac_terminal_frame (struct frame *f) f->output_data.mac = (struct mac_output *) xmalloc (sizeof (struct mac_output)); bzero (f->output_data.mac, sizeof (struct mac_output)); - f->output_data.mac->fontset = -1; + FRAME_FONTSET (f) = -1; f->output_data.mac->scroll_bar_foreground_pixel = -1; f->output_data.mac->scroll_bar_background_pixel = -1; XSETFRAME (FRAME_KBOARD (f)->Vdefault_minibuffer_frame, f); - f->width = 96; - f->height = 4; + 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); @@ -8437,74 +8764,6 @@ make_mac_terminal_frame (struct frame *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 @@ -8537,12 +8796,16 @@ mac_initialize_display_info () 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; @@ -8674,34 +8937,48 @@ quit_char_comp (EventRef inEvent, void *inCompData) } void -mac_check_for_quit_char() +mac_check_for_quit_char () { EventRef event; - /* If windows are not initialized, return immediately (keep it bouncin')*/ + static EMACS_TIME last_check_time = { 0, 0 }; + static EMACS_TIME one_second = { 1, 0 }; + EMACS_TIME now, t; + + /* If windows are not initialized, return immediately (keep it bouncin'). */ if (!mac_quit_char_modifiers) return; + /* Don't check if last check is less than a second ago. */ + EMACS_GET_TIME (now); + EMACS_SUB_TIME (t, now, last_check_time); + if (EMACS_TIME_LT (t, one_second)) + return; + last_check_time = now; + /* Redetermine modifiers because they are based on lisp variables */ - mac_determine_quit_char_modifiers(); + mac_determine_quit_char_modifiers (); /* Fill the queue with events */ ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &event); - event = FindSpecificEventInQueue (GetMainEventQueue(), quit_char_comp, NULL); + event = FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp, + NULL); if (event) { struct input_event e; - struct mac_output *mwp = (mac_output*) GetWRefCon (FrontNonFloatingWindow ()); + struct mac_output *mwp = + (mac_output *) GetWRefCon (FrontNonFloatingWindow ()); /* Use an input_event to emulate what the interrupt handler does. */ + EVENT_INIT (e); e.kind = ASCII_KEYSTROKE_EVENT; e.code = quit_char; e.arg = NULL; e.modifiers = NULL; - e.timestamp = EventTimeToTicks(GetEventTime(event))*(1000/60); - XSETFRAME(e.frame_or_window, mwp->mFP); + e.timestamp = EventTimeToTicks (GetEventTime (event)) * (1000/60); + XSETFRAME (e.frame_or_window, mwp->mFP); /* Remove event from queue to prevent looping. */ - RemoveEventFromQueue(GetMainEventQueue(), event); - ReleaseEvent(event); - kbd_buffer_store_event(&e); + RemoveEventFromQueue (GetMainEventQueue (), event); + ReleaseEvent (event); + kbd_buffer_store_event (&e); } } @@ -8709,8 +8986,11 @@ mac_check_for_quit_char() /* Set up use of X before we make the first connection. */ +extern frame_parm_handler mac_frame_parm_handlers[]; + static struct redisplay_interface x_redisplay_interface = { + mac_frame_parm_handlers, x_produce_glyphs, x_write_glyphs, x_insert_glyphs, @@ -8726,6 +9006,8 @@ static struct redisplay_interface x_redisplay_interface = 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 */ @@ -8733,6 +9015,7 @@ static struct redisplay_interface x_redisplay_interface = mac_define_frame_cursor, mac_clear_frame_area, mac_draw_window_cursor, + mac_draw_vertical_window_border, mac_shift_glyphs_for_insert }; @@ -8761,12 +9044,13 @@ mac_initialize () redeem_scroll_bar_hook = XTredeem_scroll_bar; judge_scroll_bars_hook = XTjudge_scroll_bars; - scroll_region_ok = 1; /* we'll scroll partial frames */ - char_ins_del_ok = 1; - line_ins_del_ok = 1; /* we'll just blt 'em */ - fast_clear_end_of_line = 1; /* X does this well */ - memory_below_frame = 0; /* we don't remember what scrolls - off the bottom */ + TTY_SCROLL_REGION_OK (CURTTY ()) = 1; /* we'll scroll partial frames */ + TTY_CHAR_INS_DEL_OK (CURTTY ()) = 1; + TTY_LINE_INS_DEL_OK (CURTTY ()) = 1; /* we'll just blt 'em */ + TTY_FAST_CLEAR_END_OF_LINE (CURTTY ()) = 1; /* X does this well */ + TTY_MEMORY_BELOW_FRAME (CURTTY ()) = 0; /* we don't remember what + scrolls off the + bottom */ baud_rate = 19200; x_noop_count = 0; @@ -8843,6 +9127,9 @@ syms_of_macterm () Fprovide (intern ("mac-carbon"), Qnil); + staticpro (&Qreverse); + Qreverse = intern ("reverse"); + staticpro (&x_display_name_list); x_display_name_list = Qnil; @@ -8858,6 +9145,18 @@ syms_of_macterm () 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; @@ -8866,6 +9165,14 @@ syms_of_macterm () doc: /* If not nil, Emacs uses toolkit scroll bars. */); Vx_toolkit_scroll_bars = Qt; + DEFVAR_BOOL ("x-use-underline-position-properties", + &x_use_underline_position_properties, + doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties. +nil means ignore them. If you encounter fonts with bogus +UNDERLINE_POSITION font properties, for example 7x13 on XFree prior +to 4.1, set this to nil. */); + x_use_underline_position_properties = 0; + staticpro (&last_mouse_motion_frame); last_mouse_motion_frame = Qnil; @@ -8879,6 +9186,17 @@ Otherwise the option key is used. */); 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 @@ -8912,3 +9230,6 @@ command, this enables the Mac keyboard to be used to enter non-ASCII characters directly. */); mac_keyboard_text_encoding = kTextEncodingMacRoman; } + +/* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b + (do not change this comment) */