/* Implementation of GUI terminal on the Mac OS.
Copyright (C) 2000, 2001, 2002, 2003, 2004,
- 2005, 2006 Free Software Foundation, Inc.
+ 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#define GC_BACK_COLOR(gc) (&(gc)->back_color)
#define GC_FONT(gc) ((gc)->xgcv.font)
#define FRAME_NORMAL_GC(f) ((f)->output_data.mac->normal_gc)
-#define CG_SET_FILL_COLOR(context, color) \
+
+#define CG_SET_FILL_COLOR(context, color) \
CGContextSetRGBFillColor (context, \
RED_FROM_ULONG (color) / 255.0f, \
GREEN_FROM_ULONG (color) / 255.0f, \
BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
-#define CG_SET_STROKE_COLOR(context, color) \
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ do { \
+ if (CGColorGetTypeID != NULL) \
+ CGContextSetFillColorWithColor (context, cg_color); \
+ else \
+ CG_SET_FILL_COLOR (context, color); \
+ } while (0)
+#else
+#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ CGContextSetFillColorWithColor (context, cg_color)
+#endif
+#else
+#define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ CG_SET_FILL_COLOR (context, color)
+#endif
+#define CG_SET_FILL_COLOR_WITH_GC_FOREGROUND(context, gc) \
+ CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground, \
+ (gc)->cg_fore_color)
+#define CG_SET_FILL_COLOR_WITH_GC_BACKGROUND(context, gc) \
+ CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.background, \
+ (gc)->cg_back_color)
+
+
+#define CG_SET_STROKE_COLOR(context, color) \
CGContextSetRGBStrokeColor (context, \
RED_FROM_ULONG (color) / 255.0f, \
GREEN_FROM_ULONG (color) / 255.0f, \
BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ do { \
+ if (CGColorGetTypeID != NULL) \
+ CGContextSetStrokeColorWithColor (context, cg_color); \
+ else \
+ CG_SET_STROKE_COLOR (context, color); \
+ } while (0)
+#else
+#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ CGContextSetStrokeColorWithColor (context, cg_color)
+#endif
+#else
+#define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
+ CG_SET_STROKE_COLOR (context, color)
+#endif
+#define CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND(context, gc) \
+ CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground, \
+ (gc)->cg_fore_color)
+
#if USE_CG_DRAWING
#define FRAME_CG_CONTEXT(f) ((f)->output_data.mac->cg_context)
static int max_fringe_bmp = 0;
static CGImageRef *fringe_bmp = 0;
+static CGColorSpaceRef mac_cg_color_space_rgb;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+static CGColorRef mac_cg_color_black;
+#endif
+
+static void
+init_cg_color ()
+{
+ mac_cg_color_space_rgb = CGColorSpaceCreateDeviceRGB ();
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ /* Don't check the availability of CGColorCreate; this symbol is
+ defined even in Mac OS X 10.1. */
+ if (CGColorGetTypeID != NULL)
+#endif
+ {
+ float rgba[] = {0.0f, 0.0f, 0.0f, 1.0f};
+
+ mac_cg_color_black = CGColorCreate (mac_cg_color_space_rgb, rgba);
+ }
+#endif
+}
+
static CGContextRef
mac_begin_cg_clip (f, gc)
struct frame *f;
gy1 += 0.5f, gy2 += 0.5f;
context = mac_begin_cg_clip (f, gc);
- CG_SET_STROKE_COLOR (context, gc->xgcv.foreground);
+ CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
CGContextBeginPath (context);
CGContextMoveToPoint (context, gx1, gy1);
CGContextAddLineToPoint (context, gx2, gy2);
#endif
}
+/* Mac version of XDrawLine (to Pixmap). */
+
void
-mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2)
+XDrawLine (display, p, gc, x1, y1, x2, y2)
Display *display;
Pixmap p;
GC gc;
CGContextRef context;
context = mac_begin_cg_clip (f, gc);
- CG_SET_FILL_COLOR (context, gc->xgcv.background);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect (context, CGRectMake (x, y, width, height));
mac_end_cg_clip (f);
#else
GC gc = FRAME_NORMAL_GC (f);
context = mac_begin_cg_clip (f, NULL);
- CG_SET_FILL_COLOR (context, gc->xgcv.background);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect (context, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f),
FRAME_PIXEL_HEIGHT (f)));
mac_end_cg_clip (f);
context = mac_begin_cg_clip (f, gc);
if (!overlay_p)
{
- CG_SET_FILL_COLOR (context, gc->xgcv.background);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect (context, dest_rect);
}
CGContextClipToRect (context, dest_rect);
CGContextScaleCTM (context, 1, -1);
CGContextTranslateCTM (context, 0, -port_height);
if (CGImageIsMask (image))
- CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+ CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
CGContextDrawImage (context,
CGRectMake (dest_x - src_x,
port_height - (dest_y - src_y
CGContextRef context;
context = mac_begin_cg_clip (f, gc);
- CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+ CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
CGContextFillRect (context, CGRectMake (x, y, width, height));
mac_end_cg_clip (f);
#else
CGContextRef context;
context = mac_begin_cg_clip (f, gc);
- CG_SET_STROKE_COLOR (context, gc->xgcv.foreground);
+ CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc);
CGContextStrokeRect (context,
CGRectMake (x + 0.5f, y + 0.5f, width, height));
mac_end_cg_clip (f);
#endif
if (bg_width)
{
- CG_SET_FILL_COLOR (context, gc->xgcv.background);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect
(context,
CGRectMake (x, y - FONT_BASE (GC_FONT (gc)),
#if !USE_CG_DRAWING
}
#endif
- CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+ CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
err = ATSUSetLayoutControls (text_layout,
sizeof (tags) / sizeof (tags[0]),
tags, sizes, values);
UniChar ch = c;
err = atsu_get_text_layout_with_text_ptr (&ch, 1, style, &text_layout);
- if (err == noErr)
+ if (err == noErr
+ && (font_ascent_return || font_descent_return || overall_return))
{
ATSTrapezoid glyph_bounds;
#endif
if (bg_width)
{
- CG_SET_FILL_COLOR (context, gc->xgcv.background);
+ CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context, gc);
CGContextFillRect
(context,
CGRectMake (gx, y - FONT_BASE (GC_FONT (gc)),
#if !USE_CG_DRAWING
}
#endif
- CG_SET_FILL_COLOR (context, gc->xgcv.foreground);
+ CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context, gc);
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);
- if (overstrike_p)
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CGContextShowGlyphsWithAdvances != NULL)
+#endif
{
- CGContextSetTextPosition (context, gx + 1.0f, gy);
+ CGContextSetTextPosition (context, gx, gy);
CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars);
+ if (overstrike_p)
+ {
+ CGContextSetTextPosition (context, gx + 1.0f, gy);
+ CGContextShowGlyphsWithAdvances (context, glyphs, advances, nchars);
+ }
}
-#else
- for (i = 0; i < nchars; i++)
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ else
+#endif
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
{
- CGContextShowGlyphsAtPoint (context, gx, gy, glyphs + i, 1);
- if (overstrike_p)
- CGContextShowGlyphsAtPoint (context, gx + 1.0f, gy, glyphs + i, 1);
- gx += advances[i].width;
+ for (i = 0; i < nchars; i++)
+ {
+ CGContextShowGlyphsAtPoint (context, gx, gy, glyphs + i, 1);
+ if (overstrike_p)
+ CGContextShowGlyphsAtPoint (context, gx + 1.0f, gy, glyphs + i, 1);
+ gx += advances[i].width;
+ }
}
#endif
#if USE_CG_DRAWING
/* Mac replacement for XCreateGC. */
GC
-XCreateGC (display, window, mask, xgcv)
+XCreateGC (display, d, mask, xgcv)
Display *display;
- Window window;
+ void *d;
unsigned long mask;
XGCValues *xgcv;
{
GC gc = xmalloc (sizeof (*gc));
bzero (gc, sizeof (*gc));
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CGColorGetTypeID != NULL)
+#endif
+ {
+ gc->cg_fore_color = gc->cg_back_color = mac_cg_color_black;
+ CGColorRetain (gc->cg_fore_color);
+ CGColorRetain (gc->cg_back_color);
+ }
+#endif
XChangeGC (display, gc, mask, xgcv);
return gc;
{
if (gc->clip_region)
DisposeRgn (gc->clip_region);
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CGColorGetTypeID != NULL)
+#endif
+ {
+ CGColorRelease (gc->cg_fore_color);
+ CGColorRelease (gc->cg_back_color);
+ }
+#endif
xfree (gc);
}
gc->fore_color.red = RED16_FROM_ULONG (color);
gc->fore_color.green = GREEN16_FROM_ULONG (color);
gc->fore_color.blue = BLUE16_FROM_ULONG (color);
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CGColorGetTypeID != NULL)
+#endif
+ {
+ CGColorRelease (gc->cg_fore_color);
+ if (color == 0)
+ {
+ gc->cg_fore_color = mac_cg_color_black;
+ CGColorRetain (gc->cg_fore_color);
+ }
+ else
+ {
+ float rgba[4];
+
+ rgba[0] = gc->fore_color.red / 65535.0f;
+ rgba[1] = gc->fore_color.green / 65535.0f;
+ rgba[2] = gc->fore_color.blue / 65535.0f;
+ rgba[3] = 1.0f;
+ gc->cg_fore_color = CGColorCreate (mac_cg_color_space_rgb, rgba);
+ }
+ }
+#endif
}
}
gc->back_color.red = RED16_FROM_ULONG (color);
gc->back_color.green = GREEN16_FROM_ULONG (color);
gc->back_color.blue = BLUE16_FROM_ULONG (color);
+#if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ if (CGColorGetTypeID != NULL)
+#endif
+ {
+ CGColorRelease (gc->cg_back_color);
+ if (color == 0)
+ {
+ gc->cg_back_color = mac_cg_color_black;
+ CGColorRetain (gc->cg_back_color);
+ }
+ else
+ {
+ float rgba[4];
+
+ rgba[0] = gc->back_color.red / 65535.0f;
+ rgba[1] = gc->back_color.green / 65535.0f;
+ rgba[2] = gc->back_color.blue / 65535.0f;
+ rgba[3] = 1.0f;
+ gc->cg_back_color = CGColorCreate (mac_cg_color_space_rgb, rgba);
+ }
+ }
+#endif
}
}
if (wp != tip_window)
remove_window_handler (wp);
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
DisposeWindow (wp);
if (wp == tip_window)
/* Neither WaitNextEvent nor ReceiveNextEvent receives `window
static Lisp_Object atsu_font_id_hash;
/* Alist linking Font Manager style to face attributes. */
static Lisp_Object fm_style_face_attributes_alist;
-static Lisp_Object Vmac_atsu_font_table;
extern Lisp_Object QCfamily, QCweight, QCslant, Qnormal, Qbold, Qitalic;
#endif
}
#if USE_ATSUI
+static FMFontStyle
+fm_get_style_from_font (font)
+ FMFont font;
+{
+ OSStatus err;
+ FMFontStyle style = normal;
+ ByteCount len;
+ UInt16 mac_style;
+ FMFontFamily font_family;
+#define FONT_HEADER_MAC_STYLE_OFFSET (4*4 + 2*2 + 8*2 + 2*4)
+
+ /* FMGetFontFamilyInstanceFromFont returns `normal' as the style of
+ some font (e.g., Optima) even if it is `bold'. */
+ err = FMGetFontTable (font, 'head', FONT_HEADER_MAC_STYLE_OFFSET,
+ sizeof (mac_style), &mac_style, &len);
+ if (err == noErr
+ && len >= FONT_HEADER_MAC_STYLE_OFFSET + sizeof (mac_style))
+ style = EndianU16_BtoN (mac_style);
+ else
+ FMGetFontFamilyInstanceFromFont (font, &font_family, &style);
+
+ return style;
+}
+
+static ATSUFontID
+atsu_find_font_from_family_name (family)
+ const char *family;
+{
+ struct Lisp_Hash_Table *h = XHASH_TABLE (atsu_font_id_hash);
+ unsigned hash_code;
+ int i;
+ Lisp_Object rest, best;
+ FMFontStyle min_style, style;
+
+ i = hash_lookup (h, make_unibyte_string (family, strlen (family)),
+ &hash_code);
+ if (i < 0)
+ return kATSUInvalidFontID;
+
+ rest = HASH_VALUE (h, i);
+ if (INTEGERP (rest) || (CONSP (rest) && INTEGERP (XCDR (rest))))
+ return cons_to_long (rest);
+
+ rest = Fnreverse (rest);
+ best = XCAR (rest);
+ rest = XCDR (rest);
+ if (!NILP (rest)
+ && (min_style = fm_get_style_from_font (cons_to_long (best))) != normal)
+ do
+ {
+ style = fm_get_style_from_font (cons_to_long (XCAR (rest)));
+ if (style < min_style)
+ {
+ best = XCAR (rest);
+ if (style == normal)
+ break;
+ else
+ min_style = style;
+ }
+ rest = XCDR (rest);
+ }
+ while (!NILP (rest));
+
+ HASH_VALUE (h, i) = best;
+ return cons_to_long (best);
+}
+
static Lisp_Object
fm_style_to_face_attributes (fm_style)
FMFontStyle fm_style;
return tem;
}
+
+static Lisp_Object
+atsu_find_font_family_name (font_id)
+ ATSUFontID font_id;
+{
+ OSStatus err;
+ ByteCount len;
+ Lisp_Object family = Qnil;
+
+ err = ATSUFindFontName (font_id, kFontFamilyName,
+ kFontMacintoshPlatform, kFontNoScript,
+ kFontNoLanguage, 0, NULL, &len, NULL);
+ if (err == noErr)
+ {
+ family = make_uninit_string (len);
+ err = ATSUFindFontName (font_id, kFontFamilyName,
+ kFontMacintoshPlatform, kFontNoScript,
+ kFontNoLanguage, len, SDATA (family),
+ NULL, NULL);
+ }
+ if (err == noErr)
+ decode_mac_font_name (SDATA (family), len + 1, Qnil);
+
+ return family;
+}
+
+Lisp_Object
+mac_atsu_font_face_attributes (font_id)
+ ATSUFontID font_id;
+{
+ Lisp_Object family, style_attrs;
+
+ family = atsu_find_font_family_name (font_id);
+ if (NILP (family))
+ return Qnil;
+ style_attrs = fm_style_to_face_attributes (fm_get_style_from_font (font_id));
+ return Fcons (QCfamily, Fcons (family, style_attrs));
+}
#endif
/* Sets up the table font_name_table to contain the list of all fonts
unsigned hash_code;
ItemCount nfonts, i;
ATSUFontID *font_ids = NULL;
- Ptr name;
- ByteCount name_len;
- Lisp_Object family;
+ Lisp_Object prev_family = Qnil;
+ int j;
atsu_font_id_hash =
make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
if (err == noErr)
for (i = 0; i < nfonts; i++)
{
- err = ATSUFindFontName (font_ids[i], kFontFamilyName,
- kFontMacintoshPlatform, kFontNoScript,
- kFontNoLanguage, 0, NULL, &name_len, NULL);
- if (err != noErr)
+ Lisp_Object family;
+
+ family = atsu_find_font_family_name (font_ids[i]);
+ if (NILP (family) || SREF (family, 0) == '.')
continue;
- name = xmalloc (name_len + 1);
- name[name_len] = '\0';
- err = ATSUFindFontName (font_ids[i], kFontFamilyName,
- kFontMacintoshPlatform, kFontNoScript,
- kFontNoLanguage, name_len, name,
- NULL, NULL);
- if (err == noErr)
+ if (!NILP (Fequal (prev_family, family)))
+ family = prev_family;
+ else
+ j = hash_lookup (h, family, &hash_code);
+ if (j < 0)
{
- FMFontFamily ff;
- FMFontStyle style = normal;
-
- decode_mac_font_name (name, name_len + 1, Qnil);
- family = make_unibyte_string (name, name_len);
- FMGetFontFamilyInstanceFromFont (font_ids[i], &ff, &style);
- Fputhash ((font_ids[i] > MOST_POSITIVE_FIXNUM
- ? make_float (font_ids[i])
- : make_number (font_ids[i])),
- Fcons (QCfamily,
- Fcons (family,
- fm_style_to_face_attributes (style))),
- Vmac_atsu_font_table);
- if (*name != '.'
- && hash_lookup (h, family, &hash_code) < 0)
- {
- add_mac_font_name (name, 0, normal, "iso10646-1");
- hash_put (h, family, long_to_cons (font_ids[i]),
- hash_code);
- }
+ add_mac_font_name (SDATA (family), 0, normal, "iso10646-1");
+ j = hash_put (h, family, Fcons (long_to_cons (font_ids[i]),
+ Qnil), hash_code);
}
- xfree (name);
+ else if (EQ (prev_family, family))
+ HASH_VALUE (h, j) = Fcons (long_to_cons (font_ids[i]),
+ HASH_VALUE (h, j));
+ prev_family = family;
}
if (font_ids)
xfree (font_ids);
{kAllTypographicFeaturesType, kDiacriticsType};
static const ATSUFontFeatureSelector selectors[] =
{kAllTypeFeaturesOffSelector, kDecomposeDiacriticsSelector};
- Lisp_Object font_id_cons;
FMFontStyle style;
- font_id_cons = Fgethash (make_unibyte_string (family, strlen (family)),
- atsu_font_id_hash, Qnil);
- if (NILP (font_id_cons))
- return NULL;
- font_id = cons_to_long (font_id_cons);
+ font_id = atsu_find_font_from_family_name (family);
+ if (font_id == kATSUInvalidFontID)
+ return;
size_fixed = Long2Fix (size);
bold_p = (fontface & bold) != 0;
italic_p = (fontface & italic) != 0;
continue;
else if (c == 0x7f)
{
- c = 0x9f;
- continue;
+#if USE_CG_TEXT_DRAWING
+ if (font->cg_glyphs)
+ {
+ c = 0x9f;
+ pcm = NULL;
+ continue;
+ }
+#endif
+ break;
}
- mac_query_char_extents (font->mac_style, c, NULL, NULL, pcm + c,
+ mac_query_char_extents (font->mac_style, c, NULL, NULL,
+ pcm ? pcm + c : NULL,
#if USE_CG_TEXT_DRAWING
(font->cg_glyphs ? font->cg_glyphs + c
: NULL)
font->cg_font = NULL;
xfree (font->cg_glyphs);
font->cg_glyphs = NULL;
+ if (pcm == NULL)
+ break;
}
#endif
}
else
#endif
{
+ OSStatus err;
FontInfo the_fontinfo;
int is_two_byte_font;
sizeof (XCharStruct) * (0xff - 0x20 + 1));
space_bounds = font->bounds.per_char;
- mac_query_char_extents (NULL, 0x20, &font->ascent, &font->descent,
- space_bounds, NULL);
+ err = mac_query_char_extents (NULL, 0x20, &font->ascent,
+ &font->descent, space_bounds, NULL);
+ if (err != noErr || space_bounds->width <= 0)
+ {
+ mac_unload_font (&one_mac_display_info, font);
+ return NULL;
+ }
for (c = 0x21, pcm = space_bounds + 1; c <= 0xff; c++, pcm++)
mac_query_char_extents (NULL, c, NULL, NULL, pcm, NULL);
extern OSErr init_coercion_handler P_ ((void));
/* Drag and Drop */
-OSErr install_drag_handler P_ ((WindowRef));
-void remove_drag_handler P_ ((WindowRef));
+extern OSErr install_drag_handler P_ ((WindowRef));
+extern void remove_drag_handler P_ ((WindowRef));
+
+/* Showing help echo string during menu tracking */
+extern OSStatus install_menu_target_item_handler P_ ((WindowPtr));
#if USE_CARBON_EVENTS
#ifdef MAC_OSX
extern void init_service_handler ();
static Lisp_Object Qservice, Qpaste, Qperform;
#endif
+
/* Window Event Handler */
static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
EventRef, void *);
};
#endif /* MAC_OSX */
-static unsigned int
+static int
#if USE_CARBON_EVENTS
mac_to_emacs_modifiers (UInt32 mods)
#else
return result;
}
+static UInt32
+mac_mapped_modifiers (modifiers)
+ UInt32 modifiers;
+{
+ UInt32 mapped_modifiers_all =
+ (NILP (Vmac_control_modifier) ? 0 : controlKey)
+ | (NILP (Vmac_option_modifier) ? 0 : optionKey)
+ | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
+
+#ifdef MAC_OSX
+ mapped_modifiers_all |=
+ (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
+#endif
+
+ return mapped_modifiers_all & modifiers;
+}
+
static int
mac_get_emulated_btn ( UInt32 modifiers )
{
return result;
}
+#if TARGET_API_MAC_CARBON
+/***** Code to handle C-g testing *****/
+extern int quit_char;
+extern int make_ctrl_char P_ ((int));
+
+int
+mac_quit_char_key_p (modifiers, key_code)
+ UInt32 modifiers, key_code;
+{
+ UInt32 char_code;
+ unsigned long some_state = 0;
+ Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
+ int c, emacs_modifiers;
+
+ /* Mask off modifier keys that are mapped to some Emacs modifiers. */
+ key_code |= (modifiers & ~(mac_mapped_modifiers (modifiers)));
+ char_code = KeyTranslate (kchr_ptr, key_code, &some_state);
+ if (char_code & ~0xff)
+ return 0;
+
+ emacs_modifiers = mac_to_emacs_modifiers (modifiers);
+ if (emacs_modifiers & ctrl_modifier)
+ c = make_ctrl_char (char_code);
+
+ c |= (emacs_modifiers
+ & (meta_modifier | alt_modifier
+ | hyper_modifier | super_modifier));
+
+ return c == quit_char;
+}
+#endif
+
#if USE_CARBON_EVENTS
/* Obtains the event modifiers from the event ref and then calls
mac_to_emacs_modifiers. */
-static UInt32
+static int
mac_event_to_emacs_modifiers (EventRef eventRef)
{
UInt32 mods = 0;
GetPortVisibleRegion (GetWindowPort (win), region);
GetRegionBounds (region, &r);
expose_frame (f, r.left, r.top, r.right - r.left, r.bottom - r.top);
+#if USE_CG_DRAWING
+ mac_prepare_for_quickdraw (f);
+#endif
UpdateControls (win, region);
DisposeRgn (region);
#else
{
mac_store_apple_event (class_key, id_key, &apple_event);
AEDisposeDesc (&apple_event);
- /* Post a harmless event so as to wake up from
- ReceiveNextEvent. */
- mac_post_mouse_moved_event ();
+ mac_wakeup_from_rne ();
}
}
}
err = GetEventParameter (kbd_event, kEventParamKeyModifiers,
typeUInt32, NULL,
sizeof (UInt32), NULL, &modifiers);
- if (err == noErr)
- {
- mapped_modifiers =
- (NILP (Vmac_control_modifier) ? 0 : controlKey)
- | (NILP (Vmac_option_modifier) ? 0 : optionKey)
- | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
-#ifdef MAC_OSX
- mapped_modifiers |=
- (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
-#endif
- if (modifiers & mapped_modifiers)
- /* There're mapped modifier keys. Process it in
- XTread_socket. */
- return eventNotHandledErr;
- }
+ if (err == noErr && mac_mapped_modifiers (modifiers))
+ /* There're mapped modifier keys. Process it in
+ XTread_socket. */
+ return eventNotHandledErr;
if (err == noErr)
err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
typeUnicodeText, NULL, 0, &actual_size,
#endif
if (err == noErr)
err = install_drag_handler (window);
+ if (err == noErr)
+ err = install_menu_target_item_handler (window);
return err;
}
#if __MWERKS__
/* set creator and type for files created by MSL */
- _fcreator = 'EMAx';
+ _fcreator = MAC_EMACS_CREATOR_CODE;
_ftype = 'TEXT';
#endif
#else
FrontWindow ()
#endif
- != window_ptr)
+ != window_ptr
+ || (mac_window_to_frame (window_ptr)
+ != dpyinfo->x_focus_frame))
SelectWindow (window_ptr);
else
{
SInt16 current_key_script;
UInt32 modifiers = er.modifiers, mapped_modifiers;
- mapped_modifiers =
- (NILP (Vmac_control_modifier) ? 0 : controlKey)
- | (NILP (Vmac_option_modifier) ? 0 : optionKey)
- | (NILP (Vmac_command_modifier) ? 0 : cmdKey);
-
#if USE_CARBON_EVENTS && defined (MAC_OSX)
- mapped_modifiers |=
- (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask);
-
GetEventParameter (eventRef, kEventParamKeyModifiers,
typeUInt32, NULL,
sizeof (UInt32), NULL, &modifiers);
#endif
- mapped_modifiers &= modifiers;
+ mapped_modifiers = mac_mapped_modifiers (modifiers);
#if USE_CARBON_EVENTS && (defined (MAC_OSX) || USE_MAC_TSM)
/* When using Carbon Events, we need to pass raw keyboard
\f
#ifdef MAC_OSX
-void
-mac_check_bundle()
-{
- extern int inhibit_window_system;
- extern int noninteractive;
- CFBundleRef appsBundle;
-
- /* No need to test if already -nw*/
- if (inhibit_window_system || noninteractive)
- return;
-
- appsBundle = CFBundleGetMainBundle();
- if (appsBundle != NULL)
- {
- CFStringRef cfBI = CFSTR("CFBundleIdentifier");
- CFTypeRef res = CFBundleGetValueForInfoDictionaryKey(appsBundle, cfBI);
- /* We found the bundle identifier, now we know we are valid. */
- if (res != NULL)
- {
- CFRelease(res);
- return;
- }
- }
- /* MAC_TODO: Have this start the bundled executable */
-
- /* For now, prevent the fatal error by bringing it up in the terminal */
- inhibit_window_system = 1;
-}
-
void
MakeMeTheFrontProcess ()
{
if (err == noErr)
(void) SetFrontProcess (&psn);
}
-
-/***** Code to handle C-g testing *****/
-
-/* Contains the Mac modifier formed from quit_char */
-int mac_quit_char_modifiers = 0;
-int mac_quit_char_keycode;
-extern int quit_char;
-
-static void
-mac_determine_quit_char_modifiers()
-{
- /* Todo: Determine modifiers from quit_char. */
- UInt32 qc_modifiers = ctrl_modifier;
-
- /* Map modifiers */
- mac_quit_char_modifiers = 0;
- 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
-init_quit_char_handler ()
-{
- /* TODO: Let this support keys other the 'g' */
- mac_quit_char_keycode = 5;
- /* Look at <architecture/adb_kb_map.h> for details */
- /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
-
- mac_determine_quit_char_modifiers();
-}
#endif /* MAC_OSX */
static void
#if USE_CARBON_EVENTS
#ifdef MAC_OSX
init_service_handler ();
-
- init_quit_char_handler ();
#endif /* MAC_OSX */
init_command_handler ();
#endif
#if USE_CG_DRAWING
+ init_cg_color ();
+
mac_init_fringe ();
#endif
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
+A value of 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.
DEFVAR_BOOL ("x-underline-at-descent-line",
&x_underline_at_descent_line,
doc: /* *Non-nil means to draw the underline at the same place as the descent line.
-nil means to draw the underline according to the value of the variable
-`x-use-underline-position-properties', which is usually at the baseline
-level. The default value is nil. */);
+A value of nil means to draw the underline according to the value of the
+variable `x-use-underline-position-properties', which is usually at the
+baseline level. The default value is nil. */);
x_underline_at_descent_line = 0;
DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
&Vmac_emulate_three_button_mouse,
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.
+A value of 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.
Fcons (list3 (build_string ("mac-roman"),
make_number (smRoman), Qnil), Qnil);
-#if USE_ATSUI
- DEFVAR_LISP ("mac-atsu-font-table", &Vmac_atsu_font_table,
- doc: /* Hash table of ATSU font IDs vs plist of attributes and values. */);
- Vmac_atsu_font_table =
- make_hash_table (Qeql, make_number (DEFAULT_HASH_SIZE),
- make_float (DEFAULT_REHASH_SIZE),
- make_float (DEFAULT_REHASH_THRESHOLD),
- Qnil, Qnil, Qnil);
-#endif
#if USE_MAC_TSM
DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay,
doc: /* Overlay used to display Mac TSM active input area. */);