Mercurial > emacs
diff src/macterm.c @ 90261:7beb78bc1f8e
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-97
Merge from emacs--cvs-trunk--0
Patches applied:
* emacs--cvs-trunk--0 (patch 616-696)
- Add lisp/mh-e/.arch-inventory
- Update from CVS
- Merge from gnus--rel--5.10
- Update from CVS: lisp/smerge-mode.el: Add 'tools' to file keywords.
- lisp/gnus/ChangeLog: Remove duplicate entry
* gnus--rel--5.10 (patch 147-181)
- Update from CVS
- Merge from emacs--cvs-trunk--0
- Update from CVS: lisp/mml.el (mml-preview): Doc fix.
- Update from CVS: texi/message.texi: Fix default values.
- Update from CVS: texi/gnus.texi (RSS): Addition.
author | Miles Bader <miles@gnu.org> |
---|---|
date | Mon, 16 Jan 2006 08:37:27 +0000 |
parents | 0ca0d9181b5e d88b44855af3 |
children | c5406394f567 |
line wrap: on
line diff
--- a/src/macterm.c Mon Jan 16 06:59:21 2006 +0000 +++ b/src/macterm.c Mon Jan 16 08:37:27 2006 +0000 @@ -68,7 +68,6 @@ #include <errno.h> #include <setjmp.h> #include <sys/stat.h> -#include <sys/param.h> #include "charset.h" #include "coding.h" @@ -89,22 +88,15 @@ #include "character.h" #include "ccl.h" -/* Set of macros that handle mapping of Mac modifier keys to emacs. */ -#define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \ - (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey)) -#define macShiftKey (shiftKey) -#define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \ - (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \ - : controlKey) -#define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey) /* Non-nil means Emacs uses toolkit scroll bars. */ Lisp_Object Vx_toolkit_scroll_bars; -/* If Non-nil, the text will be rendered using Core Graphics text rendering which may anti-alias the text. */ -Lisp_Object Vmac_use_core_graphics; +/* If non-zero, the text will be rendered using Core Graphics text + rendering which may anti-alias the text. */ +int mac_use_core_graphics; /* Non-zero means that a HELP_EVENT has been generated since Emacs @@ -115,6 +107,10 @@ /* Last window where we saw the mouse. Used by mouse-autoselect-window. */ static Lisp_Object last_window; +/* Non-zero means make use of UNDERLINE_POSITION font properties. + (Not yet supported.) */ +int x_use_underline_position_properties; + /* This is a chain of structures for all the X displays currently in use. */ @@ -167,6 +163,7 @@ /* Where the mouse was last time we reported a mouse event. */ static Rect last_mouse_glyph; +static FRAME_PTR last_mouse_glyph_frame; /* The scroll bar in which the last X motion event occurred. @@ -208,7 +205,7 @@ /* The keysyms to use for the various modifiers. */ -static Lisp_Object Qalt, Qhyper, Qsuper, Qmodifier_value; +static Lisp_Object Qalt, Qhyper, Qsuper, Qcontrol, Qmeta, Qmodifier_value; extern int inhibit_window_system; @@ -263,7 +260,7 @@ unsigned long *)); static int is_emacs_window P_ ((WindowPtr)); - +static XCharStruct *mac_per_char_metric P_ ((XFontStruct *, XChar2b *, int)); static void XSetFont P_ ((Display *, GC, XFontStruct *)); /* Defined in macmenu.h. */ @@ -630,7 +627,8 @@ ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)}; static ATSLineLayoutOptions line_layout = #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 - kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics + kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics + | kATSLineUseQDRendering #else kATSLineIsDisplayOnly | kATSLineFractDisable #endif @@ -695,7 +693,7 @@ { #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 UInt32 textFlags, savedFlags; - if (!NILP(Vmac_use_core_graphics)) { + if (mac_use_core_graphics) { textFlags = kQDUseCGTextRendering; savedFlags = SwapQDTextFlags(textFlags); } @@ -718,10 +716,10 @@ #ifndef WORDS_BIG_ENDIAN { int i; - Unichar *text = (Unichar *)buf; + UniChar *text = (UniChar *)buf; for (i = 0; i < nchars; i++) - text[i] = buf[2*i] << 8 | buf[2*i+1]; + text[i] = EndianU16_BtoN (text[i]); } #endif err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf, @@ -731,7 +729,7 @@ if (err == noErr) { #ifdef MAC_OSX - if (NILP (Vmac_use_core_graphics)) + if (!mac_use_core_graphics) { #endif mac_begin_clip (GC_CLIP_REGION (gc)); @@ -775,11 +773,18 @@ ATSUDrawText (text_layout, kATSUFromTextBeginning, kATSUToTextEnd, Long2Fix (x), Long2Fix (port_height - y)); + CGContextSynchronize (context); + QDEndCGContext (port, &context); +#if 0 + /* This doesn't work on Mac OS X 10.1. */ ATSUClearLayoutControls (text_layout, sizeof (tags) / sizeof (tags[0]), tags); - CGContextSynchronize (context); - QDEndCGContext (port, &context); +#else + ATSUSetLayoutControls (text_layout, + sizeof (tags) / sizeof (tags[0]), + tags, sizes, values); +#endif } #endif } @@ -803,7 +808,7 @@ if (mode != srcOr) RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f))); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 - if (!NILP(Vmac_use_core_graphics)) + if (mac_use_core_graphics) SwapQDTextFlags(savedFlags); #endif } @@ -865,6 +870,244 @@ } +/* Mac replacement for XQueryTextExtents, but takes a character. If + STYLE is NULL, measurement is done by QuickDraw Text routines for + the font of the current graphics port. If CG_GLYPH is not NULL, + *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained. */ + +static OSErr +mac_query_char_extents (style, c, + font_ascent_return, font_descent_return, + overall_return, cg_glyph) +#if USE_ATSUI + ATSUStyle style; +#else + void *style; +#endif + int c; + int *font_ascent_return, *font_descent_return; + XCharStruct *overall_return; +#if USE_CG_TEXT_DRAWING + CGGlyph *cg_glyph; +#else + void *cg_glyph; +#endif +{ + OSErr err = noErr; + int width; + Rect char_bounds; + +#if USE_ATSUI + if (style) + { + ATSUTextLayout text_layout; + UniChar ch = c; + + err = atsu_get_text_layout_with_text_ptr (&ch, 1, style, &text_layout); + if (err == noErr) + { + ATSTrapezoid glyph_bounds; + + err = ATSUGetGlyphBounds (text_layout, 0, 0, + kATSUFromTextBeginning, kATSUToTextEnd, +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 + kATSUseFractionalOrigins, +#else + kATSUseDeviceOrigins, +#endif + 1, &glyph_bounds, NULL); + if (err == noErr) + { + xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x + == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); + + width = Fix2Long (glyph_bounds.upperRight.x + - glyph_bounds.upperLeft.x); + if (font_ascent_return) + *font_ascent_return = -Fix2Long (glyph_bounds.upperLeft.y); + if (font_descent_return) + *font_descent_return = Fix2Long (glyph_bounds.lowerLeft.y); + } + } + if (err == noErr && overall_return) + { + err = ATSUMeasureTextImage (text_layout, + kATSUFromTextBeginning, kATSUToTextEnd, + 0, 0, &char_bounds); + if (err == noErr) + STORE_XCHARSTRUCT (*overall_return, width, char_bounds); +#if USE_CG_TEXT_DRAWING + if (err == noErr && cg_glyph) + { + OSErr err1; + ATSUGlyphInfoArray glyph_info_array; + ByteCount count = sizeof (ATSUGlyphInfoArray); + + err1 = ATSUMatchFontsToText (text_layout, kATSUFromTextBeginning, + kATSUToTextEnd, NULL, NULL, NULL); + if (err1 == noErr) + err1 = ATSUGetGlyphInfo (text_layout, kATSUFromTextBeginning, + kATSUToTextEnd, &count, + &glyph_info_array); + if (err1 == noErr) + { + xassert (glyph_info_array.glyphs[0].glyphID); + *cg_glyph = glyph_info_array.glyphs[0].glyphID; + } + else + *cg_glyph = 0; + } +#endif + } + } + else +#endif + { + if (font_ascent_return || font_descent_return) + { + FontInfo font_info; + + GetFontInfo (&font_info); + if (font_ascent_return) + *font_ascent_return = font_info.ascent; + if (font_descent_return) + *font_descent_return = font_info.descent; + } + if (overall_return) + { + char ch = c; + + width = CharWidth (ch); + QDTextBounds (1, &ch, &char_bounds); + STORE_XCHARSTRUCT (*overall_return, width, char_bounds); + } + } + + return err; +} + + +/* Mac replacement for XTextExtents16. Only sets horizontal metrics. */ + +static int +mac_text_extents_16 (font_struct, string, nchars, overall_return) + XFontStruct *font_struct; + XChar2b *string; + int nchars; + XCharStruct *overall_return; +{ + int i; + short width = 0, lbearing = 0, rbearing = 0; + XCharStruct *pcm; + + for (i = 0; i < nchars; i++) + { + pcm = mac_per_char_metric (font_struct, string, 0); + if (pcm == NULL) + width += FONT_WIDTH (font_struct); + else + { + lbearing = min (lbearing, width + pcm->lbearing); + rbearing = max (rbearing, width + pcm->rbearing); + width += pcm->width; + } + string++; + } + + overall_return->lbearing = lbearing; + overall_return->rbearing = rbearing; + overall_return->width = width; + + /* What's the meaning of the return value of XTextExtents16? */ +} + + +#if USE_CG_TEXT_DRAWING +static int cg_text_anti_aliasing_threshold = 8; + +static void +init_cg_text_anti_aliasing_threshold () +{ + Lisp_Object val = + Fmac_get_preference (build_string ("AppleAntiAliasingThreshold"), + Qnil, Qnil, Qnil); + + if (INTEGERP (val)) + cg_text_anti_aliasing_threshold = XINT (val); +} + +static int +mac_draw_string_cg (f, gc, x, y, buf, nchars) + struct frame *f; + GC gc; + int x, y; + XChar2b *buf; + int nchars; +{ + CGrafPtr port; + float port_height, gx, gy; + int i; + CGContextRef context; + CGGlyph *glyphs; + CGSize *advances; + + if (!mac_use_core_graphics || GC_FONT (gc)->cg_font == NULL) + return 0; + + port = GetWindowPort (FRAME_MAC_WINDOW (f)); + port_height = FRAME_PIXEL_HEIGHT (f); + gx = x; + gy = port_height - y; + glyphs = (CGGlyph *)buf; + advances = xmalloc (sizeof (CGSize) * nchars); + for (i = 0; i < nchars; i++) + { + XCharStruct *pcm = mac_per_char_metric (GC_FONT (gc), buf, 0); + + advances[i].width = pcm->width; + advances[i].height = 0; + glyphs[i] = GC_FONT (gc)->cg_glyphs[buf->byte2]; + buf++; + } + + QDBeginCGContext (port, &context); + if (gc->n_clip_rects) + { + CGContextTranslateCTM (context, 0, port_height); + CGContextScaleCTM (context, 1, -1); + CGContextClipToRects (context, gc->clip_rects, gc->n_clip_rects); + CGContextScaleCTM (context, 1, -1); + CGContextTranslateCTM (context, 0, -port_height); + } + CGContextSetRGBFillColor (context, + RED_FROM_ULONG (gc->xgcv.foreground) / 255.0, + GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0, + BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0, + 1.0); + CGContextSetFont (context, GC_FONT (gc)->cg_font); + CGContextSetFontSize (context, GC_FONT (gc)->mac_fontsize); + if (GC_FONT (gc)->mac_fontsize <= cg_text_anti_aliasing_threshold) + CGContextSetShouldAntialias (context, false); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + CGContextSetTextPosition (context, gx, gy); + CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars); +#else + for (i = 0; i < nchars; i++) + { + CGContextShowGlyphsAtPoint (context, gx, gy, glyphs + i, 1); + gx += advances[i].width; + } +#endif + CGContextSynchronize (context); + QDEndCGContext (port, &context); + + xfree (advances); + + return 1; +} +#endif + + /* Mac replacement for XCopyArea: dest must be window. */ static void @@ -1636,59 +1879,32 @@ #if USE_ATSUI if (font->mac_style) { - if (char2b->byte1 >= font->min_byte1 - && char2b->byte1 <= font->max_byte1 - && char2b->byte2 >= font->min_char_or_byte2 - && char2b->byte2 <= font->max_char_or_byte2) + XCharStructRow **row = font->bounds.rows + char2b->byte1; + + if (*row == NULL) { - pcm = (font->per_char - + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) - * (char2b->byte1 - font->min_byte1)) - + (char2b->byte2 - font->min_char_or_byte2)); + *row = xmalloc (sizeof (XCharStructRow)); + if (*row) + bzero (*row, sizeof (XCharStructRow)); } - - if (pcm && !pcm->valid_p) + if (*row) { - OSErr err; - ATSUTextLayout text_layout; - UniChar c; - int char_width; - ATSTrapezoid glyph_bounds; - Rect char_bounds; - - c = (char2b->byte1 << 8) + char2b->byte2; - BLOCK_INPUT; - err = atsu_get_text_layout_with_text_ptr (&c, 1, - font->mac_style, - &text_layout); - if (err == noErr) - err = ATSUMeasureTextImage (text_layout, - kATSUFromTextBeginning, kATSUToTextEnd, - 0, 0, &char_bounds); - - if (err == noErr) - err = ATSUGetGlyphBounds (text_layout, 0, 0, - kATSUFromTextBeginning, kATSUToTextEnd, - kATSUseFractionalOrigins, 1, - &glyph_bounds, NULL); - UNBLOCK_INPUT; - if (err != noErr) - pcm = NULL; - else + pcm = (*row)->per_char + char2b->byte2; + if (!XCHARSTRUCTROW_CHAR_VALID_P (*row, char2b->byte2)) { - xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x - == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); - - char_width = Fix2Long (glyph_bounds.upperRight.x - - glyph_bounds.upperLeft.x); - STORE_XCHARSTRUCT (*pcm, char_width, char_bounds); + BLOCK_INPUT; + mac_query_char_extents (font->mac_style, + (char2b->byte1 << 8) + char2b->byte2, + NULL, NULL, pcm, NULL); + UNBLOCK_INPUT; + XCHARSTRUCTROW_SET_CHAR_VALID (*row, char2b->byte2); } } } else { #endif - if (font->per_char != NULL) + if (font->bounds.per_char != NULL) { if (font->min_byte1 == 0 && font->max_byte1 == 0) { @@ -1701,7 +1917,8 @@ if (char2b->byte1 == 0 && char2b->byte2 >= font->min_char_or_byte2 && char2b->byte2 <= font->max_char_or_byte2) - pcm = font->per_char + char2b->byte2 - font->min_char_or_byte2; + pcm = font->bounds.per_char + + (char2b->byte2 - font->min_char_or_byte2); } else { @@ -1723,7 +1940,7 @@ && char2b->byte2 >= font->min_char_or_byte2 && char2b->byte2 <= font->max_char_or_byte2) { - pcm = (font->per_char + pcm = (font->bounds.per_char + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) * (char2b->byte1 - font->min_byte1)) + (char2b->byte2 - font->min_char_or_byte2)); @@ -2064,67 +2281,32 @@ { if (s->cmp == NULL && s->first_glyph->type == CHAR_GLYPH) - { - Rect r; - MacFontStruct *font = s->font; - + if (!s->two_byte_p #if USE_ATSUI - if (font->mac_style) - { - OSErr err; - ATSUTextLayout text_layout; - UniChar *buf; - int i; - - SetRect (&r, 0, 0, 0, 0); - buf = xmalloc (sizeof (UniChar) * s->nchars); - if (buf) - { - for (i = 0; i < s->nchars; i++) - buf[i] = (s->char2b[i].byte1 << 8) + s->char2b[i].byte2; - - err = atsu_get_text_layout_with_text_ptr (buf, s->nchars, - font->mac_style, - &text_layout); - if (err == noErr) - err = ATSUMeasureTextImage (text_layout, - kATSUFromTextBeginning, - kATSUToTextEnd, - 0, 0, &r); - xfree (buf); - } - } - else - { -#endif - TextFont (font->mac_fontnum); - TextSize (font->mac_fontsize); - TextFace (font->mac_fontface); - - if (s->two_byte_p) + || s->font->mac_style +#endif + ) + { + XCharStruct cs; + + mac_text_extents_16 (s->font, s->char2b, s->nchars, &cs); + s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0; + s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0; + } + else + { + Rect r; + MacFontStruct *font = s->font; + + TextFont (font->mac_fontnum); + TextSize (font->mac_fontsize); + TextFace (font->mac_fontface); + QDTextBounds (s->nchars * 2, (char *)s->char2b, &r); - else - { - int i; - char *buf = xmalloc (s->nchars); - - if (buf == NULL) - SetRect (&r, 0, 0, 0, 0); - else - { - for (i = 0; i < s->nchars; ++i) - buf[i] = s->char2b[i].byte2; - QDTextBounds (s->nchars, buf, &r); - xfree (buf); - } - } -#if USE_ATSUI - } -#endif - - s->right_overhang = r.right > s->width ? r.right - s->width : 0; - s->left_overhang = r.left < 0 ? -r.left : 0; - } + + s->right_overhang = r.right > s->width ? r.right - s->width : 0; + s->left_overhang = r.left < 0 ? -r.left : 0; + } } @@ -2255,6 +2437,13 @@ || GC_FONT (s->gc)->mac_style #endif ) +#if USE_CG_TEXT_DRAWING + if (!s->two_byte_p + && mac_draw_string_cg (s->f, s->gc, x, s->ybase - boff, + s->char2b, s->nchars)) + ; + else +#endif mac_draw_string_16 (s->f, s->gc, x, s->ybase - boff, s->char2b, s->nchars); else @@ -3912,13 +4101,15 @@ return 1; } /* Has the mouse moved off the glyph it was on at the last sighting? */ - if (!PtInRect (*pos, &last_mouse_glyph)) + if (frame != last_mouse_glyph_frame + || !PtInRect (*pos, &last_mouse_glyph)) { frame->mouse_moved = 1; last_mouse_scroll_bar = Qnil; note_mouse_highlight (frame, pos->h, pos->v); /* Remember which glyph we're now on. */ remember_mouse_glyph (frame, pos->h, pos->v, &last_mouse_glyph); + last_mouse_glyph_frame = frame; return 1; } @@ -4023,6 +4214,7 @@ GetMouse (&mouse_pos); remember_mouse_glyph (f1, mouse_pos.h, mouse_pos.v, &last_mouse_glyph); + last_mouse_glyph_frame = f1; *bar_window = Qnil; *part = 0; @@ -6591,7 +6783,7 @@ sprintf (xf, "%s-%c-normal--%d-%d-%d-%d-m-%d-%s", style & bold ? "bold" : "medium", style & italic ? 'i' : 'r', - size, size * 10, size ? 75 : 0, size ? 75 : 0, size * 10, charset); + size, size * 10, size ? 72 : 0, size ? 72 : 0, size * 10, charset); result = xmalloc (strlen (foundry) + strlen (family) + strlen (xf) + 3 + 1); sprintf (result, "-%s-%s-%s", foundry, family, xf); @@ -6717,6 +6909,9 @@ text_encoding_info_alist = create_text_encoding_info_alist (); #if USE_ATSUI +#if USE_CG_TEXT_DRAWING + init_cg_text_anti_aliasing_threshold (); +#endif if (!NILP (assq_no_quit (make_number (kTextEncodingMacUnicode), text_encoding_info_alist))) { @@ -7080,7 +7275,7 @@ continue; memcpy (scaled, font_name_table[i], former_len); sprintf (scaled + former_len, - "-%d-%d-75-75-m-%d-%s", + "-%d-%d-72-72-m-%d-%s", scl_val[XLFD_SCL_PIXEL_SIZE], scl_val[XLFD_SCL_POINT_SIZE], scl_val[XLFD_SCL_AVGWIDTH], @@ -7286,12 +7481,13 @@ static MacFontStruct * XLoadQueryFont (Display *dpy, char *fontname) { - int i, size, char_width; + int size; char *name; Str255 family; Str31 charset; SInt16 fontnum; #if USE_ATSUI + static ATSUFontID font_id; ATSUStyle mac_style = NULL; #endif Style fontface; @@ -7302,6 +7498,7 @@ short scriptcode; #endif MacFontStruct *font; + XCharStruct *space_bounds = NULL, *pcm; if (is_fully_specified_xlfd (fontname)) name = fontname; @@ -7326,13 +7523,14 @@ kATSUQDBoldfaceTag, kATSUQDItalicTag}; ByteCount sizes[] = {sizeof (ATSUFontID), sizeof (Fixed), sizeof (Boolean), sizeof (Boolean)}; - static ATSUFontID font_id; static Fixed size_fixed; static Boolean bold_p, italic_p; ATSUAttributeValuePtr values[] = {&font_id, &size_fixed, &bold_p, &italic_p}; - ATSUFontFeatureType types[] = {kAllTypographicFeaturesType}; - ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector}; + ATSUFontFeatureType types[] = {kAllTypographicFeaturesType, + kDiacriticsType}; + ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector, + kDecomposeDiacriticsSelector}; Lisp_Object font_id_cons; font_id_cons = Fgethash (make_unibyte_string (family, strlen (family)), @@ -7380,6 +7578,10 @@ font->mac_scriptcode = scriptcode; #if USE_ATSUI font->mac_style = mac_style; +#if USE_CG_TEXT_DRAWING + font->cg_font = NULL; + font->cg_glyphs = NULL; +#endif #endif /* Apple Japanese (SJIS) font is listed as both @@ -7395,83 +7597,103 @@ if (font->mac_style) { OSErr err; - ATSUTextLayout text_layout; - UniChar c = 0x20; - Rect char_bounds, min_bounds, max_bounds; - int min_width, max_width; - ATSTrapezoid glyph_bounds; - - font->per_char = xmalloc (sizeof (XCharStruct) * 0x10000); - if (font->per_char == NULL) + UniChar c; + + font->min_byte1 = 0; + font->max_byte1 = 0xff; + font->min_char_or_byte2 = 0; + font->max_char_or_byte2 = 0xff; + + font->bounds.rows = xmalloc (sizeof (XCharStructRow *) * 0x100); + if (font->bounds.rows == NULL) + { + mac_unload_font (&one_mac_display_info, font); + return NULL; + } + bzero (font->bounds.rows, sizeof (XCharStructRow *) * 0x100); + font->bounds.rows[0] = xmalloc (sizeof (XCharStructRow)); + if (font->bounds.rows[0] == NULL) { mac_unload_font (&one_mac_display_info, font); return NULL; } - bzero (font->per_char, sizeof (XCharStruct) * 0x10000); - - err = atsu_get_text_layout_with_text_ptr (&c, 1, - font->mac_style, - &text_layout); + bzero (font->bounds.rows[0], sizeof (XCharStructRow)); + +#if USE_CG_TEXT_DRAWING + { + FMFontFamily font_family; + FMFontStyle style; + ATSFontRef ats_font; + + err = FMGetFontFamilyInstanceFromFont (font_id, &font_family, &style); + if (err == noErr) + err = FMGetFontFromFontFamilyInstance (font_family, fontface, + &font_id, &style); + /* Use CG text drawing if italic/bold is not synthesized. */ + if (err == noErr && style == fontface) + { + ats_font = FMGetATSFontRefFromFont (font_id); + font->cg_font = CGFontCreateWithPlatformFont (&ats_font); + } + } + + if (font->cg_font) + font->cg_glyphs = xmalloc (sizeof (CGGlyph) * 0x100); + if (font->cg_glyphs) + bzero (font->cg_glyphs, sizeof (CGGlyph) * 0x100); +#endif + space_bounds = font->bounds.rows[0]->per_char + 0x20; + err = mac_query_char_extents (font->mac_style, 0x20, + &font->ascent, &font->descent, + space_bounds, +#if USE_CG_TEXT_DRAWING + (font->cg_glyphs ? font->cg_glyphs + 0x20 + : NULL) +#else + NULL +#endif + ); if (err != noErr) { mac_unload_font (&one_mac_display_info, font); return NULL; } - - for (c = 0x20; c <= 0x7e; c++) + XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], 0x20); + + pcm = font->bounds.rows[0]->per_char; + for (c = 0x21; c <= 0xff; c++) { - err = ATSUClearLayoutCache (text_layout, kATSUFromTextBeginning); - if (err == noErr) - err = ATSUMeasureTextImage (text_layout, - kATSUFromTextBeginning, kATSUToTextEnd, - 0, 0, &char_bounds); - if (err == noErr) - err = ATSUGetGlyphBounds (text_layout, 0, 0, - kATSUFromTextBeginning, kATSUToTextEnd, - kATSUseFractionalOrigins, 1, - &glyph_bounds, NULL); - if (err == noErr) + if (c == 0xad) + /* Soft hyphen is not supported in ATSUI. */ + continue; + else if (c == 0x7f) { - xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x - == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); - - char_width = Fix2Long (glyph_bounds.upperRight.x - - glyph_bounds.upperLeft.x); - STORE_XCHARSTRUCT (font->per_char[c], - char_width, char_bounds); - if (c == 0x20) - { - min_width = max_width = char_width; - min_bounds = max_bounds = char_bounds; - font->ascent = -Fix2Long (glyph_bounds.upperLeft.y); - font->descent = Fix2Long (glyph_bounds.lowerLeft.y); - } - else - { - if (char_width > 0) - { - min_width = min (min_width, char_width); - max_width = max (max_width, char_width); - } - if (!EmptyRect (&char_bounds)) - { - SetRect (&min_bounds, - max (min_bounds.left, char_bounds.left), - max (min_bounds.top, char_bounds.top), - min (min_bounds.right, char_bounds.right), - min (min_bounds.bottom, char_bounds.bottom)); - UnionRect (&max_bounds, &char_bounds, &max_bounds); - } - } + c = 0x9f; + continue; } + + mac_query_char_extents (font->mac_style, c, NULL, NULL, pcm + c, +#if USE_CG_TEXT_DRAWING + (font->cg_glyphs ? font->cg_glyphs + c + : NULL) +#else + NULL +#endif + ); + XCHARSTRUCTROW_SET_CHAR_VALID (font->bounds.rows[0], c); + +#if USE_CG_TEXT_DRAWING + if (font->cg_glyphs && font->cg_glyphs[c] == 0) + { + /* Don't use CG text drawing if font substitution occurs in + ASCII or Latin-1 characters. */ + CGFontRelease (font->cg_font); + font->cg_font = NULL; + xfree (font->cg_glyphs); + font->cg_glyphs = NULL; + } +#endif } - STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds); - STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds); - - font->min_byte1 = 0; - font->max_byte1 = 0xff; - font->min_char_or_byte2 = 0; - font->max_char_or_byte2 = 0xff; } else #endif @@ -7510,6 +7732,8 @@ if (is_two_byte_font) { + int char_width; + font->min_byte1 = 0xa1; font->max_byte1 = 0xfe; font->min_char_or_byte2 = 0xa1; @@ -7538,21 +7762,8 @@ char_width = StringWidth("\p\xa1\xa1"); break; } - } - else - { - font->min_byte1 = font->max_byte1 = 0; - font->min_char_or_byte2 = 0x20; - font->max_char_or_byte2 = 0xff; - - /* Do this instead of use the_fontinfo.widMax, which - incorrectly returns 15 for 12-point Monaco! */ - char_width = CharWidth ('m'); - } - - if (is_two_byte_font) - { - font->per_char = NULL; + + font->bounds.per_char = NULL; if (fontface & italic) font->max_bounds.rbearing = char_width + 1; @@ -7567,49 +7778,28 @@ } else { - int c, min_width, max_width; - Rect char_bounds, min_bounds, max_bounds; - char ch; - - font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); - bzero (font->per_char, sizeof (XCharStruct) * (0xff - 0x20 + 1)); - - min_width = max_width = char_width; - SetRect (&min_bounds, -32767, -32767, 32767, 32767); - SetRect (&max_bounds, 0, 0, 0, 0); - for (c = 0x20; c <= 0xff; c++) + int c; + + font->min_byte1 = font->max_byte1 = 0; + font->min_char_or_byte2 = 0x20; + font->max_char_or_byte2 = 0xff; + + font->bounds.per_char = + xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); + if (font->bounds.per_char == NULL) { - ch = c; - char_width = CharWidth (ch); - QDTextBounds (1, &ch, &char_bounds); - STORE_XCHARSTRUCT (font->per_char[c - 0x20], - char_width, char_bounds); - /* Some Japanese fonts (in SJIS encoding) return 0 as - the character width of 0x7f. */ - if (char_width > 0) - { - min_width = min (min_width, char_width); - max_width = max (max_width, char_width); - } - if (!EmptyRect (&char_bounds)) - { - SetRect (&min_bounds, - max (min_bounds.left, char_bounds.left), - max (min_bounds.top, char_bounds.top), - min (min_bounds.right, char_bounds.right), - min (min_bounds.bottom, char_bounds.bottom)); - UnionRect (&max_bounds, &char_bounds, &max_bounds); - } + mac_unload_font (&one_mac_display_info, font); + return NULL; } - STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds); - STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds); - if (min_width == max_width - && max_bounds.left >= 0 && max_bounds.right <= max_width) - { - /* Fixed width and no overhangs. */ - xfree (font->per_char); - font->per_char = NULL; - } + bzero (font->bounds.per_char, + sizeof (XCharStruct) * (0xff - 0x20 + 1)); + + space_bounds = font->bounds.per_char; + mac_query_char_extents (NULL, 0x20, &font->ascent, &font->descent, + space_bounds, NULL); + + for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++) + mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL); } /* Restore previous font number, size and face. */ @@ -7618,6 +7808,55 @@ TextFace (old_fontface); } + if (space_bounds) + { + int c; + + font->min_bounds = font->max_bounds = *space_bounds; + for (c = 0x21, pcm = space_bounds + 1; c <= 0x7f; c++, pcm++) + if (pcm->width > 0) + { + font->min_bounds.lbearing = min (font->min_bounds.lbearing, + pcm->lbearing); + font->min_bounds.rbearing = min (font->min_bounds.rbearing, + pcm->rbearing); + font->min_bounds.width = min (font->min_bounds.width, + pcm->width); + font->min_bounds.ascent = min (font->min_bounds.ascent, + pcm->ascent); + + font->max_bounds.lbearing = max (font->max_bounds.lbearing, + pcm->lbearing); + font->max_bounds.rbearing = max (font->max_bounds.rbearing, + pcm->rbearing); + font->max_bounds.width = max (font->max_bounds.width, + pcm->width); + font->max_bounds.ascent = max (font->max_bounds.ascent, + pcm->ascent); + } + if ( +#if USE_ATSUI + font->mac_style == NULL && +#endif + font->max_bounds.width == font->min_bounds.width + && font->min_bounds.lbearing >= 0 + && font->max_bounds.rbearing <= font->max_bounds.width) + { + /* Fixed width and no overhangs. */ + xfree (font->bounds.per_char); + font->bounds.per_char = NULL; + } + } + +#if !defined (MAC_OS8) || USE_ATSUI + /* AppKit and WebKit do some adjustment to the heights of Courier, + Helvetica, and Times. This only works on the environments where + the XDrawImageString counterpart is never used. */ + if (strcmp (family, "courier") == 0 || strcmp (family, "helvetica") == 0 + || strcmp (family, "times") == 0) + font->ascent += (font->ascent + font->descent) * .15 + 0.5; +#endif + return font; } @@ -7628,11 +7867,26 @@ XFontStruct *font; { xfree (font->full_name); - if (font->per_char) - xfree (font->per_char); #if USE_ATSUI if (font->mac_style) - ATSUDisposeStyle (font->mac_style); + { + int i; + + for (i = font->min_byte1; i <= font->max_byte1; i++) + if (font->bounds.rows[i]) + xfree (font->bounds.rows[i]); + xfree (font->bounds.rows); + ATSUDisposeStyle (font->mac_style); + } + else +#endif + if (font->bounds.per_char) + xfree (font->bounds.per_char); +#if USE_CG_TEXT_DRAWING + if (font->cg_font) + CGFontRelease (font->cg_font); + if (font->cg_glyphs) + xfree (font->cg_glyphs); #endif xfree (font); } @@ -7922,31 +8176,35 @@ /* 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; - -/* Modifier associated with the option key, or nil for normal behavior. */ + +/* Modifier associated with the control key, or nil to ignore. */ +Lisp_Object Vmac_control_modifier; + +/* Modifier associated with the option key, or nil to ignore. */ Lisp_Object Vmac_option_modifier; -/* True if the ctrl and meta keys should be reversed. */ -Lisp_Object Vmac_reverse_ctrl_meta; +/* Modifier associated with the command key, or nil to ignore. */ +Lisp_Object Vmac_command_modifier; + +/* Modifier associated with the function key, or nil to ignore. */ +Lisp_Object Vmac_function_modifier; /* 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 +/* Non-zero if the mouse wheel button (i.e. button 4) should map to mouse-2, instead of mouse-3. */ -Lisp_Object Vmac_wheel_button_is_mouse_2; - -/* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox +int mac_wheel_button_is_mouse_2; + +/* If non-zero, the Mac "Command" key is passed on to the Mac Toolbox for processing before Emacs sees it. */ -Lisp_Object Vmac_pass_command_to_system; - -/* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox +int mac_pass_command_to_system; + +/* If non-zero, the Mac "Control" key is passed on to the Mac Toolbox for processing before Emacs sees it. */ -Lisp_Object Vmac_pass_control_to_system; +int mac_pass_control_to_system; #endif /* Points to the variable `inev' in the function XTread_socket. It is @@ -7954,20 +8212,19 @@ Carbon/Apple event handlers. */ static struct input_event *read_socket_inev = NULL; -/* Set in term/mac-win.el to indicate that event loop can now generate - drag and drop events. */ -Lisp_Object Qmac_ready_for_drag_n_drop; - Point saved_menu_event_location; /* Apple Events */ -static void init_required_apple_events (void); -static pascal OSErr -do_ae_open_application (const AppleEvent *, AppleEvent *, long); -static pascal OSErr -do_ae_print_documents (const AppleEvent *, AppleEvent *, long); -static pascal OSErr do_ae_open_documents (AppleEvent *, AppleEvent *, long); -static pascal OSErr do_ae_quit_application (AppleEvent *, AppleEvent *, long); +#if USE_CARBON_EVENTS +static Lisp_Object Qhicommand; +#endif +extern int mac_ready_for_apple_events; +extern Lisp_Object Qundefined; +extern void init_apple_event_handler P_ ((void)); +extern void mac_find_apple_event_spec P_ ((AEEventClass, AEEventID, + Lisp_Object *, Lisp_Object *, + Lisp_Object *)); +extern OSErr init_coercion_handler P_ ((void)); #if TARGET_API_MAC_CARBON /* Drag and Drop */ @@ -7977,11 +8234,10 @@ static DragReceiveHandlerUPP mac_do_receive_dragUPP = NULL; #endif -static Lisp_Object Qapplication, Qabout; #if USE_CARBON_EVENTS #ifdef MAC_OSX extern void init_service_handler (); -static Lisp_Object Qpreferences, Qservices, Qpaste, Qperform; +static Lisp_Object Qservices, Qpaste, Qperform; #endif /* Window Event Handler */ static pascal OSStatus mac_handle_window_event (EventHandlerCallRef, @@ -8003,19 +8259,41 @@ #endif { unsigned int result = 0; - if (mods & macShiftKey) + if (mods & shiftKey) result |= shift_modifier; - if (mods & macCtrlKey) - result |= ctrl_modifier; - if (mods & macMetaKey) - result |= meta_modifier; - if (NILP (Vmac_command_key_is_meta) && (mods & macAltKey)) - result |= alt_modifier; + + /* Deactivated to simplify configuration: + if Vmac_option_modifier is non-NIL, we fully process the Option + key. Otherwise, we only process it if an additional Ctrl or Command + is pressed. That way the system may convert the character to a + composed one. + if ((mods & optionKey) && + (( !NILP(Vmac_option_modifier) || + ((mods & cmdKey) || (mods & controlKey))))) */ + if (!NILP (Vmac_option_modifier) && (mods & optionKey)) { - Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value); - if (!NILP(val)) - result |= XUINT(val); + Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value); + if (INTEGERP(val)) + result |= XUINT(val); + } + if (!NILP (Vmac_command_modifier) && (mods & cmdKey)) { + Lisp_Object val = Fget(Vmac_command_modifier, Qmodifier_value); + if (INTEGERP(val)) + result |= XUINT(val); } + if (!NILP (Vmac_control_modifier) && (mods & controlKey)) { + Lisp_Object val = Fget(Vmac_control_modifier, Qmodifier_value); + if (INTEGERP(val)) + result |= XUINT(val); + } + +#ifdef MAC_OSX + if (!NILP (Vmac_function_modifier) && (mods & kEventKeyModifierFnMask)) { + Lisp_Object val = Fget(Vmac_function_modifier, Qmodifier_value); + if (INTEGERP(val)) + result |= XUINT(val); + } +#endif return result; } @@ -8037,7 +8315,7 @@ #if USE_CARBON_EVENTS /* Obtains the event modifiers from the event ref and then calls mac_to_emacs_modifiers. */ -static int +static UInt32 mac_event_to_emacs_modifiers (EventRef eventRef) { UInt32 mods = 0; @@ -8071,10 +8349,10 @@ return mac_get_emulated_btn(mods); } case kEventMouseButtonSecondary: - return NILP (Vmac_wheel_button_is_mouse_2) ? 1 : 2; + return mac_wheel_button_is_mouse_2 ? 2 : 1; case kEventMouseButtonTertiary: case 4: /* 4 is the number for the mouse wheel button */ - return NILP (Vmac_wheel_button_is_mouse_2) ? 2 : 1; + return mac_wheel_button_is_mouse_2 ? 1 : 2; default: return 0; } @@ -8502,179 +8780,49 @@ x_real_positions (f, &f->left_pos, &f->top_pos); } -/* Intialize AppleEvent dispatcher table for the required events. */ -void -init_required_apple_events () -{ - OSErr err; - long result; - - /* Make sure we have apple events before starting. */ - err = Gestalt (gestaltAppleEventsAttr, &result); - if (err != noErr) - abort (); - - if (!(result & (1 << gestaltAppleEventsPresent))) - abort (); - -#if TARGET_API_MAC_CARBON - err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, - NewAEEventHandlerUPP - ((AEEventHandlerProcPtr) do_ae_open_application), - 0L, false); -#else - err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, - NewAEEventHandlerProc - ((AEEventHandlerProcPtr) do_ae_open_application), - 0L, false); -#endif - if (err != noErr) - abort (); - -#if TARGET_API_MAC_CARBON - err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, - NewAEEventHandlerUPP - ((AEEventHandlerProcPtr) do_ae_open_documents), - 0L, false); -#else - err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, - NewAEEventHandlerProc - ((AEEventHandlerProcPtr) do_ae_open_documents), - 0L, false); -#endif - if (err != noErr) - abort (); - -#if TARGET_API_MAC_CARBON - err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, - NewAEEventHandlerUPP - ((AEEventHandlerProcPtr) do_ae_print_documents), - 0L, false); -#else - err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, - NewAEEventHandlerProc - ((AEEventHandlerProcPtr) do_ae_print_documents), - 0L, false); -#endif - if (err != noErr) - abort (); - -#if TARGET_API_MAC_CARBON - err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, - NewAEEventHandlerUPP - ((AEEventHandlerProcPtr) do_ae_quit_application), - 0L, false); -#else - err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, - NewAEEventHandlerProc - ((AEEventHandlerProcPtr) do_ae_quit_application), - 0L, false); -#endif - if (err != noErr) - abort (); -} - -void -mac_store_application_menu_event (event) -#if USE_CARBON_EVENTS - EventRef event; -#else - UInt32 event; -#endif -{ +OSErr +mac_store_apple_event (class, id, desc) + Lisp_Object class, id; + const AEDesc *desc; +{ + OSErr err = noErr; struct input_event buf; - Lisp_Object frame, entry; - - EVENT_INIT (buf); - - XSETFRAME (frame, mac_focus_frame (&one_mac_display_info)); - buf.kind = MENU_BAR_EVENT; - buf.frame_or_window = frame; - buf.arg = frame; - kbd_buffer_store_event (&buf); - - buf.arg = Qapplication; - kbd_buffer_store_event (&buf); - -#if USE_CARBON_EVENTS - switch (GetEventClass (event)) - { -#ifdef MAC_OSX - case kEventClassService: - buf.arg = Qservices; + AEDesc *desc_copy; + + desc_copy = xmalloc (sizeof (AEDesc)); + if (desc_copy == NULL) + err = memFullErr; + else + err = AEDuplicateDesc (desc, desc_copy); + if (err == noErr) + { + EVENT_INIT (buf); + + buf.kind = MAC_APPLE_EVENT; + buf.x = class; + buf.y = id; + buf.code = (int)desc_copy; + XSETFRAME (buf.frame_or_window, + mac_focus_frame (&one_mac_display_info)); + buf.arg = Qnil; kbd_buffer_store_event (&buf); - switch (GetEventKind (event)) - { - case kEventServicePaste: - entry = Qpaste; - break; - - case kEventServicePerform: - { - OSErr err; - CFStringRef message; - - err = GetEventParameter (event, kEventParamServiceMessageName, - typeCFStringRef, NULL, - sizeof (CFStringRef), NULL, &message); - buf.arg = Qperform; - kbd_buffer_store_event (&buf); - if (err == noErr && message) - entry = intern (SDATA (cfstring_to_lisp (message))); - else - entry = Qnil; - } - break; - - default: - abort (); - } - break; -#endif /* MAC_OSX */ - case kEventClassCommand: - { - HICommand command; - - GetEventParameter(event, kEventParamDirectObject, typeHICommand, - NULL, sizeof (HICommand), NULL, &command); - switch (command.commandID) - { - case kHICommandAbout: - entry = Qabout; - break; -#ifdef MAC_OSX - case kHICommandPreferences: - entry = Qpreferences; - break; -#endif /* MAC_OSX */ - case kHICommandQuit: - entry = Qquit; - break; - default: - abort (); - } - } - break; - - default: - abort (); - } -#else /* USE_CARBON_EVENTS */ - switch (event) - { - case kHICommandAbout: - entry = Qabout; - break; - case kHICommandQuit: - entry = Qquit; - break; - default: - abort (); - } -#endif - - buf.arg = entry; - kbd_buffer_store_event (&buf); + } + + return err; +} + +Lisp_Object +mac_make_lispy_event_code (code) + int code; +{ + AEDesc *desc = (AEDesc *)code; + Lisp_Object obj; + + obj = mac_aedesc_to_lisp (desc); + AEDisposeDesc (desc); + xfree (desc); + + return obj; } #if USE_CARBON_EVENTS @@ -8684,28 +8832,47 @@ EventRef event; void *data; { + OSStatus result; + OSErr err; HICommand command; - OSErr result; - - GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, - sizeof (HICommand), NULL, &command); - - switch (command.commandID) - { - case kHICommandAbout: -#ifdef MAC_OSX - case kHICommandPreferences: -#endif /* MAC_OSX */ - result = CallNextEventHandler (next_handler, event); - if (result != eventNotHandledErr) - return result; - - mac_store_application_menu_event (event); - return noErr; - - default: - break; - } + Lisp_Object class_key, id_key, binding; + + result = CallNextEventHandler (next_handler, event); + if (result != eventNotHandledErr) + return result; + + GetEventParameter (event, kEventParamDirectObject, typeHICommand, NULL, + sizeof (HICommand), NULL, &command); + + if (command.commandID == 0) + return eventNotHandledErr; + + /* A HICommand event is mapped to an Apple event whose event class + symbol is `hicommand' and event ID is its command ID. */ + class_key = Qhicommand; + mac_find_apple_event_spec (0, command.commandID, + &class_key, &id_key, &binding); + if (!NILP (binding) && !EQ (binding, Qundefined)) + if (INTEGERP (binding)) + return XINT (binding); + else + { + AppleEvent apple_event; + UInt32 modifiers; + static EventParamName names[] = {kEventParamDirectObject, + kEventParamKeyModifiers}; + static EventParamType types[] = {typeHICommand, + typeUInt32}; + err = create_apple_event_from_event_ref (event, 2, names, types, + &apple_event); + if (err == noErr) + { + err = mac_store_apple_event (class_key, id_key, &apple_event); + AEDisposeDesc (&apple_event); + } + if (err == noErr) + return noErr; + } return eventNotHandledErr; } @@ -8867,6 +9034,50 @@ return eventNotHandledErr; } + +#ifdef MAC_OSX +OSErr +mac_store_services_event (event) + EventRef event; +{ + OSErr err; + AppleEvent apple_event; + Lisp_Object id_key; + + switch (GetEventKind (event)) + { + case kEventServicePaste: + id_key = Qpaste; + err = create_apple_event_from_event_ref (event, 0, NULL, NULL, + &apple_event); + break; + + case kEventServicePerform: + { + static EventParamName names[] = {kEventParamServiceMessageName, + kEventParamServiceUserData}; + static EventParamType types[] = {typeCFStringRef, + typeCFStringRef}; + + id_key = Qperform; + err = create_apple_event_from_event_ref (event, 2, names, types, + &apple_event); + } + break; + + default: + abort (); + } + + if (err == noErr) + { + err = mac_store_apple_event (Qservices, id_key, &apple_event); + AEDisposeDesc (&apple_event); + } + + return err; +} +#endif /* MAC_OSX */ #endif /* USE_CARBON_EVENTS */ @@ -8925,159 +9136,6 @@ #endif } -/* Open Application Apple Event */ -static pascal OSErr -do_ae_open_application(const AppleEvent *pae, AppleEvent *preply, long prefcon) -{ - return noErr; -} - - -/* Called when we receive an AppleEvent with an ID of - "kAEOpenDocuments". This routine gets the direct parameter, - extracts the FSSpecs in it, and puts their names on a list. */ -#pragma options align=mac68k -typedef struct SelectionRange { - short unused1; // 0 (not used) - short lineNum; // line to select (<0 to specify range) - long startRange; // start of selection range (if line < 0) - long endRange; // end of selection range (if line < 0) - long unused2; // 0 (not used) - long theDate; // modification date/time -} SelectionRange; -#pragma options align=reset - -static pascal OSErr -do_ae_open_documents(AppleEvent *message, AppleEvent *reply, long refcon) -{ - OSErr err, err2; - AEDesc the_desc; - AEKeyword keyword; - DescType actual_type; - Size actual_size; - SelectionRange position; - Lisp_Object file_list = Qnil; - - xassert (read_socket_inev); - - err = AEGetParamDesc (message, keyDirectObject, typeAEList, &the_desc); - if (err != noErr) - goto descriptor_error_exit; - - err = AEGetParamPtr (message, keyAEPosition, typeChar, &actual_type, &position, sizeof(SelectionRange), &actual_size); - if (err == noErr) - file_list = Fcons (list3 (make_number (position.lineNum + 1), - make_number (position.startRange + 1), - make_number (position.endRange + 1)), - file_list); - - /* Check to see that we got all of the required parameters from the - event descriptor. For an 'odoc' event this should just be the - file list. */ - err = AEGetAttributePtr(message, keyMissedKeywordAttr, typeWildCard, - &actual_type, (Ptr) &keyword, - sizeof (keyword), &actual_size); - /* No error means that we found some unused parameters. - errAEDescNotFound means that there are no more parameters. If we - get an error code other than that, flag it. */ - if ((err == noErr) || (err != errAEDescNotFound)) - { - err = errAEEventNotHandled; - goto error_exit; - } - err = noErr; - - /* Got all the parameters we need. Now, go through the direct - object list and parse it up. */ - { - long num_files_to_open; - - err = AECountItems (&the_desc, &num_files_to_open); - if (err == noErr) - { - int i; - - /* AE file list is one based so just use that for indexing here. */ - for (i = 1; i <= num_files_to_open; i++) - { - char unix_path_name[MAXPATHLEN]; -#ifdef MAC_OSX - FSRef fref; - - err = AEGetNthPtr (&the_desc, i, typeFSRef, &keyword, - &actual_type, &fref, sizeof (FSRef), - &actual_size); - if (err != noErr || actual_type != typeFSRef) - continue; - - if (FSRefMakePath (&fref, unix_path_name, sizeof (unix_path_name)) - == noErr) -#else - FSSpec fs; - - err = AEGetNthPtr(&the_desc, i, typeFSS, &keyword, &actual_type, - (Ptr) &fs, sizeof (fs), &actual_size); - if (err != noErr) continue; - - if (fsspec_to_posix_pathname (&fs, unix_path_name, - sizeof (unix_path_name) - 1) == noErr) -#endif - /* x-dnd functions expect undecoded filenames. */ - file_list = Fcons (make_unibyte_string (unix_path_name, - strlen (unix_path_name)), - file_list); - } - } - - /* Build a DRAG_N_DROP_EVENT type event as is done in - constuct_drag_n_drop in w32term.c. */ - if (!NILP (file_list)) - { - struct frame *f = mac_focus_frame (&one_mac_display_info); - WindowPtr wp; - Lisp_Object frame; - - read_socket_inev->kind = DRAG_N_DROP_EVENT; - read_socket_inev->code = 0; - read_socket_inev->modifiers = 0; - - XSETINT (read_socket_inev->x, 0); - XSETINT (read_socket_inev->y, 0); - - XSETFRAME (frame, f); - read_socket_inev->frame_or_window = Fcons (frame, file_list); - -#if 0 - /* Regardless of whether Emacs was suspended or in the - foreground, ask it to redraw its entire screen. Otherwise - parts of the screen can be left in an inconsistent - state. */ - wp = FRAME_MAC_WINDOW (f); - if (wp) -#if TARGET_API_MAC_CARBON - { - Rect r; - - GetWindowPortBounds (wp, &r); - InvalWindowRect (wp, &r); - } -#else /* not TARGET_API_MAC_CARBON */ - InvalRect (&(wp->portRect)); -#endif /* not TARGET_API_MAC_CARBON */ -#endif - } - } - -error_exit: - /* Nuke the coerced file list in any case */ - err2 = AEDisposeDesc(&the_desc); - -descriptor_error_exit: - /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */ - return err; -} - - #if TARGET_API_MAC_CARBON static pascal OSErr mac_do_track_drag (DragTrackingMessage message, WindowPtr window, @@ -9173,25 +9231,25 @@ result = GetFlavorFlags (theDrag, theItem, flavorTypeHFS, &theFlags); if (result == noErr) { -#ifdef MAC_OSX - FSRef fref; -#endif - char unix_path_name[MAXPATHLEN]; - - GetFlavorData (theDrag, theItem, flavorTypeHFS, &data, &size, 0L); -#ifdef MAC_OSX - /* Use Carbon routines, otherwise it converts the file name - to /Macintosh HD/..., which is not correct. */ - FSpMakeFSRef (&data.fileSpec, &fref); - if (! FSRefMakePath (&fref, unix_path_name, sizeof (unix_path_name))); -#else - if (fsspec_to_posix_pathname (&data.fileSpec, unix_path_name, - sizeof (unix_path_name) - 1) == noErr) -#endif - /* x-dnd functions expect undecoded filenames. */ - file_list = Fcons (make_unibyte_string (unix_path_name, - strlen (unix_path_name)), - file_list); + OSErr err; + AEDesc desc; + + err = GetFlavorData (theDrag, theItem, flavorTypeHFS, + &data, &size, 0L); + if (err == noErr) + err = AECoercePtr (typeFSS, &data.fileSpec, sizeof (FSSpec), + TYPE_FILE_NAME, &desc); + if (err == noErr) + { + Lisp_Object file; + + /* x-dnd functions expect undecoded filenames. */ + file = make_uninit_string (AEGetDescDataSize (&desc)); + err = AEGetDescData (&desc, SDATA (file), SBYTES (file)); + if (err == noErr) + file_list = Fcons (file, file_list); + AEDisposeDesc (&desc); + } } } /* If there are items in the list, construct an event and post it to @@ -9213,8 +9271,8 @@ XSETINT (event.x, mouse.h); XSETINT (event.y, mouse.v); XSETFRAME (frame, f); - event.frame_or_window = Fcons (frame, file_list); - event.arg = Qnil; + event.frame_or_window = frame; + event.arg = file_list; /* Post to the interrupt queue */ kbd_buffer_store_event (&event); /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */ @@ -9232,44 +9290,6 @@ #endif -/* Print Document Apple Event */ -static pascal OSErr -do_ae_print_documents (const AppleEvent *pAE, AppleEvent *reply, long refcon) -{ - return errAEEventNotHandled; -} - - -static pascal OSErr -do_ae_quit_application (AppleEvent* message, AppleEvent *reply, long refcon) -{ -#if USE_CARBON_EVENTS - OSErr err; - EventRef event = NULL; - static const HICommand quit_command = {kEventAttributeNone, kHICommandQuit}; - - err = CreateEvent (NULL, kEventClassCommand, kEventCommandProcess, 0, - kEventAttributeUserEvent, &event); - if (err == noErr) - err = SetEventParameter (event, kEventParamDirectObject, typeHICommand, - sizeof (HICommand), &quit_command); - if (err == noErr) - mac_store_application_menu_event (event); - if (event) - ReleaseEvent (event); - - if (err == noErr) - return noErr; - else - return errAEEventNotHandled; -#else - mac_store_application_menu_event (kHICommandQuit); - - return noErr; -#endif -} - - #if __profile__ void profiler_exit_proc () @@ -9321,9 +9341,11 @@ init_environ (); + init_coercion_handler (); + initialize_applescript (); - init_required_apple_events (); + init_apple_event_handler (); { char **argv; @@ -9387,6 +9409,7 @@ /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0 }; + static int keycode_to_xkeysym (int keyCode, int *xKeySym) { @@ -9394,6 +9417,124 @@ return *xKeySym != 0; } +static unsigned char fn_keycode_to_xkeysym_table[] = { + /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /*0x30*/ 0, 0, 0, 0, + /*0x34*/ 0, 0, 0, 0, + /*0x38*/ 0, 0, 0, 0, + /*0x3C*/ 0, 0, 0, 0, + + /*0x40*/ 0, 0x2e /*kp-. = .*/, 0, 0x50 /*kp-* = 'p'*/, + /*0x44*/ 0, '/' /*kp-+*/, 0, 0, + /*0x48*/ 0, 0, 0, 0x30 /*kp-/ = '0'*/, + /*0x4C*/ 0, 0, 0x3b /*kp-- = ';'*/, 0, + + /*0x50*/ 0, 0x2d /*kp-= = '-'*/, 0x6d /*kp-0 = 'm'*/, 0x6a /*kp-1 = 'j'*/, + /*0x54*/ 0x6b /*kp-2 = 'k'*/, 0x6c /*kp-3 = 'l'*/, 'u' /*kp-4*/, 'i' /*kp-5*/, + /*0x58*/ 'o' /*kp-6*/, '7' /*kp-7*/, 0, '8' /*kp-8*/, + /*0x5C*/ '9' /*kp-9*/, 0, 0, 0, + + /*0x60*/ 0, 0, 0, 0, + /*0x64*/ 0, 0, 0, 0, + /*0x68*/ 0, 0, 0, 0, + /*0x6C*/ 0, 0, 0, 0, + + /*0x70*/ 0, 0, 0, 0, + /*0x74*/ 0, 0, 0, 0, + /*0x78*/ 0, 0, 0, 0, + /*0x7C*/ 0, 0, 0, 0 +}; +static int +convert_fn_keycode (EventRef eventRef, int keyCode, int *newCode) +{ +#ifdef MAC_OSX + /* Use the special map to translate keys when function modifier is + to be caught. KeyTranslate can't be used in that case. + We can't detect the function key using the input_event.modifiers, + because this uses the high word of an UInt32. Therefore, + we'll just read it out of the original eventRef. + */ + + + /* TODO / known issues + + - Fn-Shift-j is regonized as Fn-j and not Fn-J. + The above table always translates to lower characters. We need to use + the KCHR keyboard resource (KeyTranslate() ) to map k->K and 8->*. + + - The table is meant for English language keyboards, and it will work + for many others with the exception of key combinations like Fn-ö on + a German keyboard, which is currently mapped to Fn-;. + How to solve this without keeping separate tables for all keyboards + around? KeyTranslate isn't of much help here, as it only takes a 16-bit + value for keycode with the modifiers in he high byte, i.e. no room for the + Fn modifier. That's why we need the table. + + */ + + UInt32 mods = 0; + if (!NILP(Vmac_function_modifier)) + { + GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL, + sizeof (UInt32), NULL, &mods); + if (mods & kEventKeyModifierFnMask) + { *newCode = fn_keycode_to_xkeysym_table [keyCode & 0x7f]; + + return (*newCode != 0); + } + } +#endif + return false; +} + +static int +backtranslate_modified_keycode(int mods, int keycode, int def) +{ + EventModifiers mapped_modifiers = + (NILP (Vmac_control_modifier) ? 0 : controlKey) + | (NILP (Vmac_option_modifier) ? 0 : optionKey) + | (NILP (Vmac_command_modifier) ? 0 : cmdKey); + + if (mods & mapped_modifiers) + { + /* This code comes from Keyboard Resource, + Appendix C of IM - Text. This is necessary + since shift is ignored in KCHR table + translation when option or command is pressed. + It also does not translate correctly + control-shift chars like C-% so mask off shift + here also. + + Not done for combinations with the option key (alt) + unless it is to be caught by Emacs: this is + to preserve key combinations translated by the OS + such as Alt-3. + */ + /* Mask off modifier keys that are mapped to some Emacs + modifiers. */ + int new_modifiers = mods & ~mapped_modifiers; + /* set high byte of keycode to modifier high byte*/ + int new_keycode = keycode | new_modifiers; + Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache); + unsigned long some_state = 0; + return (int) KeyTranslate (kchr_ptr, new_keycode, + &some_state) & 0xff; + /* TO DO: Recognize two separate resulting characters, "for + example, when the user presses Option-E followed by N, you + can map this through the KeyTranslate function using the + U.S. 'KCHR' resource to produce ´n, which KeyTranslate + returns as two characters in the bytes labeled Character code + 1 and Character code 2." (from Carbon API doc) */ + + } + else + return def; +} + + #if !USE_CARBON_EVENTS static RgnHandle mouse_region = NULL; @@ -9411,7 +9552,7 @@ mouse_region = NewRgn (); event_mask = everyEvent; - if (NILP (Fboundp (Qmac_ready_for_drag_n_drop))) + if (!mac_ready_for_apple_events) event_mask -= highLevelEventMask; current_tick = TickCount (); @@ -9522,6 +9663,7 @@ != eventNotHandledErr) break; #endif + last_mouse_glyph_frame = 0; if (dpyinfo->grabbed && last_mouse_frame && FRAME_LIVE_P (last_mouse_frame)) @@ -9933,12 +10075,11 @@ will pass back noErr, otherwise it will pass back "eventNotHandledErr" and we can process it normally. */ - if ((!NILP (Vmac_pass_command_to_system) + if ((mac_pass_command_to_system || !(er.modifiers & cmdKey)) - && (!NILP (Vmac_pass_control_to_system) + && (mac_pass_control_to_system || !(er.modifiers & controlKey)) - && (!NILP (Vmac_command_key_is_meta) - && NILP (Vmac_option_modifier) + && (NILP (Vmac_option_modifier) || !(er.modifiers & optionKey))) if (SendEventToEventTarget (eventRef, toolbox_dispatcher) != eventNotHandledErr) @@ -9982,49 +10123,34 @@ dpyinfo->mouse_face_hidden = 1; } - if (keycode_to_xkeysym (keycode, &xkeysym)) + /* translate the keycode back to determine the original key */ + /* Convert key code if function key is pressed. + Otherwise, if non-ASCII-event, take care of that + without re-translating the key code. */ +#if USE_CARBON_EVENTS + if (convert_fn_keycode (eventRef, keycode, &xkeysym)) { - inev.code = 0xff00 | xkeysym; - inev.kind = NON_ASCII_KEYSTROKE_EVENT; + inev.code = xkeysym; + /* this doesn't work - tried to add shift modifiers */ + inev.code = + backtranslate_modified_keycode(er.modifiers & (~0x2200), + xkeysym | 0x80, xkeysym); + inev.kind = ASCII_KEYSTROKE_EVENT; } else - { - if (er.modifiers & (controlKey | - (NILP (Vmac_command_key_is_meta) ? optionKey - : cmdKey))) - { - /* This code comes from Keyboard Resource, - Appendix C of IM - Text. This is necessary - since shift is ignored in KCHR table - translation when option or command is pressed. - It also does not translate correctly - control-shift chars like C-% so mask off shift - here also */ - int new_modifiers = er.modifiers & 0xe600; - /* mask off option and command */ - int new_keycode = keycode | new_modifiers; - Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache); - unsigned long some_state = 0; - inev.code = KeyTranslate (kchr_ptr, new_keycode, - &some_state) & 0xff; - } - else if (!NILP (Vmac_option_modifier) - && (er.modifiers & optionKey)) - { - /* When using the option key as an emacs modifier, - convert the pressed key code back to one - without the Mac option modifier applied. */ - int new_modifiers = er.modifiers & ~optionKey; - int new_keycode = keycode | new_modifiers; - Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache); - unsigned long some_state = 0; - inev.code = KeyTranslate (kchr_ptr, new_keycode, - &some_state) & 0xff; - } - else - inev.code = er.message & charCodeMask; - inev.kind = ASCII_KEYSTROKE_EVENT; - } +#endif + if (keycode_to_xkeysym (keycode, &xkeysym)) + { + inev.code = 0xff00 | xkeysym; + inev.kind = NON_ASCII_KEYSTROKE_EVENT; + } + else + { + inev.code = + backtranslate_modified_keycode(er.modifiers, keycode, + er.message & charCodeMask); + inev.kind = ASCII_KEYSTROKE_EVENT; + } } #if USE_CARBON_EVENTS @@ -10251,8 +10377,8 @@ main_device_handle = LMGetMainDevice(); dpyinfo->reference_count = 0; - dpyinfo->resx = 75.0; - dpyinfo->resy = 75.0; + dpyinfo->resx = 72.0; + dpyinfo->resy = 72.0; dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType); #ifdef MAC_OSX /* HasDepth returns true if it is possible to have a 32 bit display, @@ -10464,10 +10590,9 @@ /* Map modifiers */ mac_quit_char_modifiers = 0; - if (qc_modifiers & ctrl_modifier) mac_quit_char_modifiers |= macCtrlKey; - if (qc_modifiers & shift_modifier) mac_quit_char_modifiers |= macShiftKey; - if (qc_modifiers & meta_modifier) mac_quit_char_modifiers |= macMetaKey; - if (qc_modifiers & alt_modifier) mac_quit_char_modifiers |= macAltKey; + if (qc_modifiers & ctrl_modifier) mac_quit_char_modifiers |= controlKey; + if (qc_modifiers & shift_modifier) mac_quit_char_modifiers |= shiftKey; + if (qc_modifiers & alt_modifier) mac_quit_char_modifiers |= optionKey; } static void @@ -10592,7 +10717,6 @@ BLOCK_INPUT; #if TARGET_API_MAC_CARBON - init_required_apple_events (); #if USE_CARBON_EVENTS #ifdef MAC_OSX @@ -10607,6 +10731,10 @@ #endif /* USE_CARBON_EVENTS */ #ifdef MAC_OSX + init_coercion_handler (); + + init_apple_event_handler (); + if (!inhibit_window_system) MakeMeTheFrontProcess (); #endif @@ -10623,23 +10751,28 @@ x_error_message_string = Qnil; #endif + Qcontrol = intern ("control"); staticpro (&Qcontrol); + Qmeta = intern ("meta"); staticpro (&Qmeta); + Qalt = intern ("alt"); staticpro (&Qalt); + Qhyper = intern ("hyper"); staticpro (&Qhyper); + Qsuper = intern ("super"); staticpro (&Qsuper); Qmodifier_value = intern ("modifier-value"); - Qalt = intern ("alt"); - Fput (Qalt, Qmodifier_value, make_number (alt_modifier)); - Qhyper = intern ("hyper"); - Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier)); - Qsuper = intern ("super"); - Fput (Qsuper, Qmodifier_value, make_number (super_modifier)); - - Qapplication = intern ("application"); staticpro (&Qapplication); - Qabout = intern ("about"); staticpro (&Qabout); - -#if USE_CARBON_EVENTS && defined (MAC_OSX) - Qpreferences = intern ("preferences"); staticpro (&Qpreferences); + staticpro (&Qmodifier_value); + + Fput (Qcontrol, Qmodifier_value, make_number (ctrl_modifier)); + Fput (Qmeta, Qmodifier_value, make_number (meta_modifier)); + Fput (Qalt, Qmodifier_value, make_number (alt_modifier)); + Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier)); + Fput (Qsuper, Qmodifier_value, make_number (super_modifier)); + +#if USE_CARBON_EVENTS + Qhicommand = intern ("hicommand"); staticpro (&Qhicommand); +#ifdef MAC_OSX Qservices = intern ("services"); staticpro (&Qservices); Qpaste = intern ("paste"); staticpro (&Qpaste); Qperform = intern ("perform"); staticpro (&Qperform); #endif +#endif #ifdef MAC_OSX Fprovide (intern ("mac-carbon"), Qnil); @@ -10648,9 +10781,6 @@ staticpro (&Qreverse); Qreverse = intern ("reverse"); - staticpro (&Qmac_ready_for_drag_n_drop); - Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); - staticpro (&x_display_name_list); x_display_name_list = Qnil; @@ -10665,6 +10795,18 @@ atsu_font_id_hash = Qnil; #endif + /* We don't yet support this, but defining this here avoids whining + from cus-start.el and other places, like "M-x set-variable". */ + 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. + +NOTE: Not supported on Mac yet. */); + x_use_underline_position_properties = 0; + DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, doc: /* If not nil, Emacs uses toolkit scroll bars. */); #ifdef USE_TOOLKIT_SCROLL_BARS @@ -10676,70 +10818,83 @@ staticpro (&last_mouse_motion_frame); last_mouse_motion_frame = Qnil; - DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta, - doc: /* Non-nil means that the command key is used as the Emacs meta key. -Otherwise the option key is used. */); - Vmac_command_key_is_meta = Qt; +/* Variables to configure modifier key assignment. */ + + DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier, + doc: /* *Modifier key assumed when the Mac control key is pressed. +The value can be `control', `meta', `alt', `hyper', or `super' for the +respective modifier. The default is `control'. */); + Vmac_control_modifier = Qcontrol; DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier, - doc: /* Modifier to use for the Mac alt/option key. The value can -be alt, hyper, or super for the respective modifier. If the value is -nil then the key will act as the normal Mac option modifier. */); + doc: /* *Modifier key assumed when the Mac alt/option key is pressed. +The value can be `control', `meta', `alt', `hyper', or `super' for the +respective modifier. If the value is nil then the key will act as the +normal Mac control modifier, and the option key can be used to compose +characters depending on the chosen Mac keyboard setting. */); Vmac_option_modifier = Qnil; - DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta, - doc: /* Non-nil means that the control and meta keys are reversed. This is -useful for non-standard keyboard layouts. */); - Vmac_reverse_ctrl_meta = Qnil; + DEFVAR_LISP ("mac-command-modifier", &Vmac_command_modifier, + doc: /* *Modifier key assumed when the Mac command key is pressed. +The value can be `control', `meta', `alt', `hyper', or `super' for the +respective modifier. The default is `meta'. */); + Vmac_command_modifier = Qmeta; + + DEFVAR_LISP ("mac-function-modifier", &Vmac_function_modifier, + doc: /* *Modifier key assumed when the Mac function key is pressed. +The value can be `control', `meta', `alt', `hyper', or `super' for the +respective modifier. Note that remapping the function key may lead to +unexpected results for some keys on non-US/GB keyboards. */); + Vmac_function_modifier = 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 option-key will register for mouse-3 -and the command-key will register for mouse-2. nil means that -no emulation should be done and the modifiers should be placed -on the mouse-1 event. */); + doc: /* *Specify a way of three button mouse emulation. +The value can be nil, t, or the symbol `reverse'. +nil means that no emulation should be done and the modifiers should be +placed on the mouse-1 event. +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. +The symbol `reverse' means that the option-key will register for +mouse-3 and the command-key will register for mouse-2. */); 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 -the right click will be mouse-3. -Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/); - Vmac_wheel_button_is_mouse_2 = Qt; - - DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system, - doc: /* If non-nil, the Mac \"Command\" key is passed on to the Mac -Toolbox for processing before Emacs sees it. */); - Vmac_pass_command_to_system = Qt; - - DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system, - doc: /* If non-nil, the Mac \"Control\" key is passed on to the Mac -Toolbox for processing before Emacs sees it. */); - Vmac_pass_control_to_system = Qt; - -#endif - - DEFVAR_LISP ("mac-allow-anti-aliasing", &Vmac_use_core_graphics, - doc: /* If non-nil, allow anti-aliasing. + DEFVAR_BOOL ("mac-wheel-button-is-mouse-2", &mac_wheel_button_is_mouse_2, + doc: /* *Non-nil if the wheel button is mouse-2 and the right click mouse-3. +Otherwise, the right click will be treated as mouse-2 and the wheel +button will be mouse-3. */); + mac_wheel_button_is_mouse_2 = 1; + + DEFVAR_BOOL ("mac-pass-command-to-system", &mac_pass_command_to_system, + doc: /* *Non-nil if command key presses are passed on to the Mac Toolbox. */); + mac_pass_command_to_system = 1; + + DEFVAR_BOOL ("mac-pass-control-to-system", &mac_pass_control_to_system, + doc: /* *Non-nil if control key presses are passed on to the Mac Toolbox. */); + mac_pass_control_to_system = 1; + +#endif + + DEFVAR_BOOL ("mac-allow-anti-aliasing", &mac_use_core_graphics, + doc: /* *If non-nil, allow anti-aliasing. The text will be rendered using Core Graphics text rendering which may anti-alias the text. */); - Vmac_use_core_graphics = Qnil; + mac_use_core_graphics = 0; /* Register an entry for `mac-roman' so that it can be used when creating the terminal frame on Mac OS 9 before loading term/mac-win.elc. */ DEFVAR_LISP ("mac-charset-info-alist", &Vmac_charset_info_alist, - doc: /* Alist linking Emacs character sets to Mac text encoding and Emacs coding system. + doc: /* Alist of Emacs character sets vs text encodings and coding systems. Each entry should be of the form: (CHARSET-NAME TEXT-ENCODING CODING-SYSTEM) where CHARSET-NAME is a string used in font names to identify the -charset, TEXT-ENCODING is a TextEncodingBase value, and CODING_SYSTEM -is a coding system corresponding to TEXT-ENCODING. */); +charset, TEXT-ENCODING is a TextEncodingBase value in Mac, and +CODING_SYSTEM is a coding system corresponding to TEXT-ENCODING. */); Vmac_charset_info_alist = Fcons (list3 (build_string ("mac-roman"), make_number (smRoman), Qnil), Qnil);