#include "intervals.h"
#include "atimer.h"
#include "keymap.h"
+#include "character.h"
+#include "ccl.h"
\f
/* Function prototypes of this page. */
static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *));
-static int mac_encode_char P_ ((int, XChar2b *, struct font_info *, int *));
+static int mac_encode_char P_ ((int, XChar2b *, struct font_info *,
+ struct charset *, int *));
static void
the two-byte form of C. Encoding is returned in *CHAR2B. */
static int
-mac_encode_char (c, char2b, font_info, two_byte_p)
+mac_encode_char (c, char2b, font_info, charset, two_byte_p)
int c;
XChar2b *char2b;
struct font_info *font_info;
+ struct charset *charset;
int *two_byte_p;
{
- int charset = CHAR_CHARSET (c);
XFontStruct *font = font_info->font;
/* FONT_INFO may define a scheme by which to encode byte1 and byte2.
check_ccl_update (ccl);
if (CHARSET_DIMENSION (charset) == 1)
{
- ccl->reg[0] = charset;
- ccl->reg[1] = char2b->byte2;
+ ccl->reg[0] = CHARSET_ID (charset);
+ ccl->reg[1] = XCHAR2B_BYTE2 (char2b);
ccl->reg[2] = -1;
}
else
{
- ccl->reg[0] = charset;
- ccl->reg[1] = char2b->byte1;
- ccl->reg[2] = char2b->byte2;
+ ccl->reg[0] = CHARSET_ID (charset);
+ ccl->reg[1] = XCHAR2B_BYTE1 (char2b);
+ ccl->reg[2] = XCHAR2B_BYTE2 (char2b);
}
- ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
+ ccl_driver (ccl, NULL, NULL, 0, 0, Qnil);
/* We assume that MSBs are appropriately set/reset by CCL
program. */
if (font->max_byte1 == 0) /* 1-byte font */
- char2b->byte1 = 0, char2b->byte2 = ccl->reg[1];
+ STORE_XCHAR2B (char2b, 0, ccl->reg[1]);
else
- char2b->byte1 = ccl->reg[1], char2b->byte2 = ccl->reg[2];
+ STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
}
- else if (font_info->encoding[charset])
+ else if (font_info->encoding_type)
{
/* Fixed encoding scheme. See fontset.h for the meaning of the
encoding numbers. */
- int enc = font_info->encoding[charset];
+ unsigned char enc = font_info->encoding_type;
if ((enc == 1 || enc == 2)
&& CHARSET_DIMENSION (charset) == 2)
char2b->byte2 |= 0x80;
if (enc == 4)
- {
- int sjis1, sjis2;
+ {
+ int code = (char2b->byte1 << 8) | char2b->byte2;
- ENCODE_SJIS (char2b->byte1, char2b->byte2, sjis1, sjis2);
- char2b->byte1 = sjis1;
- char2b->byte2 = sjis2;
- }
+ JIS_TO_SJIS (code);
+ STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
+ }
}
if (two_byte_p)
face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
if (s->first_glyph->type == CHAR_GLYPH)
- face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
+ face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
else
- face_id = FACE_FOR_CHAR (s->f, face, 0);
+ face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
s->face = FACE_FROM_ID (s->f, face_id);
PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
{
/* If `x-stretch-block-cursor' is nil, don't draw a block cursor
as wide as the stretch glyph. */
- int width = min (FRAME_COLUMN_WIDTH (s->f), s->background_width);
+ int width, background_width = s->background_width;
+ int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
/* Draw cursor. */
- x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
+ x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
/* Clear rest using the GC of the original non-cursor face. */
- if (width < s->background_width)
+ if (width < background_width)
{
- int x = s->x + width, y = s->y;
- int w = s->background_width - width, h = s->height;
+ int y = s->y;
+ int w = background_width - width, h = s->height;
Rect r;
GC gc;
+ x += width;
if (s->row->mouse_face_p
&& cursor_in_mouse_face_p (s->w))
{
}
}
else if (!s->background_filled_p)
- x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
- s->height);
+ {
+ int background_width = s->background_width;
+ int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ if (background_width > 0)
+ x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
+ }
s->background_filled_p = 1;
}
pending_autoraise_frame = dpyinfo->x_focus_frame;
else
pending_autoraise_frame = 0;
+
+#if USE_MAC_FONT_PANEL
+ if (frame)
+ mac_set_font_info_for_selection (frame, DEFAULT_FACE_ID, 0);
+#endif
}
x_frame_rehighlight (dpyinfo);
return;
/* Compute frame-relative coordinates for phys cursor. */
- x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+ get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
wd = w->phys_cursor_width;
/* The foreground of cursor_gc is typically the same as the normal
register char *fontname;
{
struct font_info *fontp
- = FS_LOAD_FONT (f, 0, fontname, -1);
+ = FS_LOAD_FONT (f, fontname);
if (!fontp)
return Qnil;
+ if (FRAME_FONT (f) == (XFontStruct *) (fontp->font))
+ /* This font is already set in frame F. There's nothing more to
+ do. */
+ return build_string (fontp->full_name);
+
FRAME_FONT (f) = (XFontStruct *) (fontp->font);
FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
FRAME_FONTSET (f) = -1;
return build_string (fontp->full_name);
}
+\f
+/* Give frame F the fontset named FONTSETNAME as its default fontset,
+ and return the full name of that fontset. FONTSETNAME may be a
+ wildcard pattern; in that case, we choose some fontset that fits
+ the pattern. FONTSETNAME may be a font name for ASCII characters;
+ in that case, we create a fontset from that font name.
-/* Give frame F the fontset named FONTSETNAME as its default font, and
- return the full name of that fontset. FONTSETNAME may be a wildcard
- pattern; in that case, we choose some fontset that fits the pattern.
- The return value shows which fontset we chose. */
+ The return value shows which fontset we chose.
+ If FONTSETNAME specifies the default fontset, return Qt.
+ If an ASCII font in the specified fontset can't be loaded, return
+ Qnil. */
Lisp_Object
x_new_fontset (f, fontsetname)
struct frame *f;
- char *fontsetname;
+ Lisp_Object fontsetname;
{
- int fontset = fs_query_fontset (build_string (fontsetname), 0);
+ int fontset = fs_query_fontset (fontsetname, 0);
Lisp_Object result;
- if (fontset < 0)
- return Qnil;
-
- if (FRAME_FONTSET (f) == fontset)
+ if (fontset > 0 && FRAME_FONTSET(f) == fontset)
/* This fontset is already set in frame F. There's nothing more
to do. */
return fontset_name (fontset);
+ else if (fontset == 0)
+ /* The default fontset can't be the default font. */
+ return Qt;
- result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
+ if (fontset > 0)
+ result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
+ else
+ result = x_new_font (f, SDATA (fontsetname));
if (!STRINGP (result))
/* Can't load ASCII font. */
return Qnil;
+ if (fontset < 0)
+ fontset = new_fontset_from_font_name (result);
+
/* Since x_new_font doesn't update any fontset information, do it now. */
FRAME_FONTSET (f) = fontset;
- return build_string (fontsetname);
+ return fontset_name (fontset);
}
\f
EVENT_INIT (buf);
buf.kind = DEICONIFY_EVENT;
XSETFRAME (buf.frame_or_window, f);
+ buf.arg = Qnil;
kbd_buffer_store_event (&buf);
}
else if (! NILP (Vframe_list) && ! NILP (XCDR (Vframe_list)))
EVENT_INIT (buf);
buf.kind = ICONIFY_EVENT;
XSETFRAME (buf.frame_or_window, f);
+ buf.arg = Qnil;
kbd_buffer_store_event (&buf);
}
f->output_data.mac = NULL;
if (f == dpyinfo->x_focus_frame)
- dpyinfo->x_focus_frame = 0;
+ {
+ dpyinfo->x_focus_frame = 0;
+#if USE_MAC_FONT_PANEL
+ mac_set_font_info_for_selection (NULL, DEFAULT_FACE_ID, 0);
+#endif
+ }
if (f == dpyinfo->x_focus_event_frame)
dpyinfo->x_focus_event_frame = 0;
if (f == dpyinfo->x_highlight_frame)
#if USE_ATSUI
/* Hash table linking font family names to ATSU font IDs. */
static Lisp_Object atsu_font_id_hash;
+static Lisp_Object Vmac_atsu_font_table;
+extern Lisp_Object QCfamily, QCweight, QCslant, Qnormal, Qbold, Qitalic;
#endif
/* Alist linking character set strings to Mac text encoding and Emacs
coding.src_multibyte = 0;
coding.dst_multibyte = 1;
coding.mode |= CODING_MODE_LAST_BLOCK;
- coding.composing = COMPOSITION_DISABLED;
- buf = (char *) alloca (size);
+ coding.dst_bytes = size;
+ coding.destination = (unsigned char *) alloca (coding.dst_bytes);
- decode_coding (&coding, name, buf, strlen (name), size - 1);
- bcopy (buf, name, coding.produced);
- name[coding.produced] = '\0';
+ decode_coding_c_string (&coding, name, strlen (name), Qnil);
+ bcopy (coding.destination, name, min (coding.produced, size));
+ name[min (coding.produced, size)] = '\0';
}
}
NULL, NULL);
if (err == noErr)
{
+ 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 (make_unibyte_string ((char *)(font_ids + i),
+ sizeof (ATSUFontID)),
+ Fcons (QCfamily,
+ list5 (family,
+ QCweight,
+ style & bold ? Qbold : Qnormal,
+ QCslant,
+ style & italic ? Qitalic : Qnormal)),
+ Vmac_atsu_font_table);
if (*name != '.'
&& hash_lookup (h, family, &hash_code) < 0)
{
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);
return NULL;
err = ATSUSetAttributes (mac_style, sizeof (tags) / sizeof (tags[0]),
tags, sizes, values);
- fontnum = -1;
+ if (err != noErr)
+ return NULL;
+ err = FMGetFontFamilyInstanceFromFont (font_id, &fontnum, &style);
+ if (err != noErr)
+ fontnum = -1;
scriptcode = kTextEncodingMacUnicode;
}
else
pcm_init (font->bounds.rows[0], 0x100);
#if USE_CG_TEXT_DRAWING
- {
- FMFontFamily font_family;
- FMFontStyle style;
- ATSFontRef ats_font;
+ if (fontnum != -1)
+ {
+ FMFontStyle style;
+ ATSFontRef ats_font;
- err = FMGetFontFamilyInstanceFromFont (font_id, &font_family, &style);
- if (err == noErr)
- err = FMGetFontFromFontFamilyInstance (font_family, fontface,
+ err = FMGetFontFromFontFamilyInstance (fontnum, 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);
- }
- }
+ /* 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)
{
bzero (fontp, sizeof (*fontp));
fontp->font = font;
fontp->font_idx = i;
+ fontp->charset = -1; /* fs_load_font sets it. */
fontp->name = (char *) xmalloc (strlen (fontname) + 1);
bcopy (fontname, fontp->name, strlen (fontname) + 1);
fontp->height = max_height;
}
+ /* MAC_TODO: The script encoding is irrelevant in unicode? */
/* The slot `encoding' specifies how to map a character
code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
(0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
2:0xA020..0xFF7F). For the moment, we don't know which charset
- uses this font. So, we set information in fontp->encoding[1]
+ uses this font. So, we set information in fontp->encoding_type
which is never used by any charset. If mapping can't be
decided, set FONT_ENCODING_NOT_DECIDED. */
if (font->mac_scriptcode == smJapanese)
- fontp->encoding[1] = 4;
+ fontp->encoding_type = 4;
else
{
- fontp->encoding[1]
+ fontp->encoding_type
= (font->max_byte1 == 0
/* 1-byte font */
? (font->min_char_or_byte2 < 0x80
}
}
+#if USE_MAC_FONT_PANEL
+/* Whether Font Panel has been shown before. The first call to font
+ panel functions (FPIsFontPanelVisible, SetFontInfoForSelection) is
+ slow. This variable is used for deferring such a call as much as
+ possible. */
+static int font_panel_shown_p = 0;
+
+int
+mac_font_panel_visible_p ()
+{
+ return font_panel_shown_p && FPIsFontPanelVisible ();
+}
+
+OSStatus
+mac_show_hide_font_panel ()
+{
+ font_panel_shown_p = 1;
+
+ return FPShowHideFontPanel ();
+}
+
+OSStatus
+mac_set_font_info_for_selection (f, face_id, c)
+ struct frame *f;
+ int face_id, c;
+{
+ OSStatus err;
+ EventTargetRef target = NULL;
+ XFontStruct *font = NULL;
+
+ if (!mac_font_panel_visible_p ())
+ return noErr;
+
+ if (f)
+ {
+ target = GetWindowEventTarget (FRAME_MAC_WINDOW (f));
+
+ if (FRAME_FACE_CACHE (f) && CHAR_VALID_P (c, 0))
+ {
+ struct face *face;
+
+ face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
+ face = FACE_FROM_ID (f, face_id);
+ font = face->font;
+ }
+ }
+
+ if (font == NULL)
+ err = SetFontInfoForSelection (kFontSelectionATSUIType, 0, NULL, target);
+ else
+ {
+ if (font->mac_fontnum != -1)
+ {
+ FontSelectionQDStyle qd_style;
+
+ qd_style.version = kFontSelectionQDStyleVersionZero;
+ qd_style.instance.fontFamily = font->mac_fontnum;
+ qd_style.instance.fontStyle = font->mac_fontface;
+ qd_style.size = font->mac_fontsize;
+ qd_style.hasColor = false;
+
+ err = SetFontInfoForSelection (kFontSelectionQDType,
+ 1, &qd_style, target);
+ }
+ else
+ err = SetFontInfoForSelection (kFontSelectionATSUIType,
+ 1, &font->mac_style, target);
+ }
+
+ return err;
+}
+#endif
\f
/* The Mac Event loop code */
/* Apple Events */
#if USE_CARBON_EVENTS
static Lisp_Object Qhicommand;
+#ifdef MAC_OSX
+extern Lisp_Object Qwindow;
+static Lisp_Object Qtoolbar_switch_mode;
+#endif
+#if USE_MAC_FONT_PANEL
+extern Lisp_Object Qfont;
+static Lisp_Object Qpanel_closed, Qselection;
+#endif
+#if USE_MAC_TSM
+static TSMDocumentID tsm_document_id;
+static Lisp_Object Qtext_input;
+static Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
+static Lisp_Object Vmac_ts_active_input_overlay;
+extern Lisp_Object Qbefore_string;
+#endif
#endif
extern int mac_ready_for_apple_events;
extern Lisp_Object Qundefined;
#if USE_CARBON_EVENTS
#ifdef MAC_OSX
extern void init_service_handler ();
-static Lisp_Object Qservices, Qpaste, Qperform;
+static Lisp_Object Qservice, Qpaste, Qperform;
#endif
/* Window Event Handler */
static pascal OSStatus mac_handle_window_event (EventHandlerCallRef,
static void
do_app_resume ()
{
- /* Window-activate events will do the job. */
+#if USE_MAC_TSM
+ ActivateTSMDocument (tsm_document_id);
+#endif
}
static void
do_app_suspend ()
{
- /* Window-deactivate events will do the job. */
+#if USE_MAC_TSM
+ DeactivateTSMDocument (tsm_document_id);
+#endif
}
}
#if TARGET_API_MAC_CARBON
+static OSStatus
+mac_store_event_ref_as_apple_event (class, id, class_key, id_key,
+ event, num_params, names, types)
+ AEEventClass class;
+ AEEventID id;
+ Lisp_Object class_key, id_key;
+ EventRef event;
+ UInt32 num_params;
+ EventParamName *names;
+ EventParamType *types;
+{
+ OSStatus err = eventNotHandledErr;
+ Lisp_Object binding;
+
+ mac_find_apple_event_spec (class, id, &class_key, &id_key, &binding);
+ if (!NILP (binding) && !EQ (binding, Qundefined))
+ {
+ if (INTEGERP (binding))
+ err = XINT (binding);
+ else
+ {
+ AppleEvent apple_event;
+ err = create_apple_event_from_event_ref (event, num_params,
+ names, types,
+ &apple_event);
+ if (err == noErr)
+ {
+ 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 ();
+ }
+ }
+ }
+
+ return err;
+}
+
void
mac_store_drag_event (window, mouse_pos, modifiers, desc)
WindowRef window;
{
OSStatus result, err;
HICommand command;
- Lisp_Object class_key, id_key, binding;
+ static EventParamName names[] = {kEventParamDirectObject,
+ kEventParamKeyModifiers};
+ static EventParamType types[] = {typeHICommand,
+ typeUInt32};
+ int num_params = sizeof (names) / sizeof (names[0]);
result = CallNextEventHandler (next_handler, event);
if (result != 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;
- 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)
- {
- mac_store_apple_event (class_key, id_key, &apple_event);
- AEDisposeDesc (&apple_event);
- return noErr;
- }
- }
- }
-
- return eventNotHandledErr;
+ err = mac_store_event_ref_as_apple_event (0, command.commandID,
+ Qhicommand, Qnil,
+ event, num_params, names, types);
+ return err == noErr ? noErr : eventNotHandledErr;
}
static OSErr
return noErr;
break;
+
+#ifdef MAC_OSX
+ case kEventWindowToolbarSwitchMode:
+ result = CallNextEventHandler (next_handler, event);
+ {
+ static EventParamName names[] = {kEventParamDirectObject,
+ kEventParamWindowMouseLocation,
+ kEventParamKeyModifiers,
+ kEventParamMouseButton,
+ kEventParamClickCount,
+ kEventParamMouseChord};
+ static EventParamType types[] = {typeWindowRef,
+ typeQDPoint,
+ typeUInt32,
+ typeMouseButton,
+ typeUInt32,
+ typeUInt32};
+ int num_params = sizeof (names) / sizeof (names[0]);
+
+ err = mac_store_event_ref_as_apple_event (0, 0,
+ Qwindow,
+ Qtoolbar_switch_mode,
+ event, num_params,
+ names, types);
+ }
+ return err == noErr ? noErr : result;
+#endif
+
+#if USE_MAC_TSM
+ case kEventWindowFocusAcquired:
+ result = CallNextEventHandler (next_handler, event);
+ err = ActivateTSMDocument (tsm_document_id);
+ return err == noErr ? noErr : result;
+
+ case kEventWindowFocusRelinquish:
+ result = CallNextEventHandler (next_handler, event);
+ err = DeactivateTSMDocument (tsm_document_id);
+ return err == noErr ? noErr : result;
+#endif
}
return eventNotHandledErr;
return eventNotHandledErr;
}
-#ifdef MAC_OSX
-OSErr
-mac_store_services_event (event)
+#if USE_MAC_FONT_PANEL
+static pascal OSStatus
+mac_handle_font_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
EventRef event;
+ void *data;
{
- OSErr err;
- AppleEvent apple_event;
+ OSStatus result, err;
Lisp_Object id_key;
+ int num_params;
+ EventParamName *names;
+ EventParamType *types;
+ static EventParamName names_sel[] = {kEventParamATSUFontID,
+ kEventParamATSUFontSize,
+ kEventParamFMFontFamily,
+ kEventParamFMFontSize,
+ kEventParamFontColor};
+ static EventParamType types_sel[] = {typeATSUFontID,
+ typeATSUSize,
+ typeFMFontFamily,
+ typeFMFontSize,
+ typeFontColor};
+
+ result = CallNextEventHandler (next_handler, event);
+ if (result != eventNotHandledErr)
+ return result;
switch (GetEventKind (event))
{
- case kEventServicePaste:
- id_key = Qpaste;
- err = create_apple_event_from_event_ref (event, 0, NULL, NULL,
- &apple_event);
+ case kEventFontPanelClosed:
+ id_key = Qpanel_closed;
+ num_params = 0;
+ names = NULL;
+ types = NULL;
break;
- case kEventServicePerform:
+ case kEventFontSelection:
+ id_key = Qselection;
+ num_params = sizeof (names_sel) / sizeof (names_sel[0]);
+ names = names_sel;
+ types = types_sel;
+ break;
+ }
+
+ err = mac_store_event_ref_as_apple_event (0, 0, Qfont, id_key,
+ event, num_params,
+ names, types);
+
+ return err == noErr ? noErr : eventNotHandledErr;
+}
+#endif
+
+#if USE_MAC_TSM
+static pascal OSStatus
+mac_handle_text_input_event (next_handler, event, data)
+ EventHandlerCallRef next_handler;
+ EventRef event;
+ void *data;
+{
+ OSStatus result, err = noErr;
+ Lisp_Object id_key = Qnil;
+ int num_params;
+ EventParamName *names;
+ EventParamType *types;
+ static UInt32 seqno_uaia = 0;
+ static EventParamName names_uaia[] =
+ {kEventParamTextInputSendComponentInstance,
+ kEventParamTextInputSendRefCon,
+ kEventParamTextInputSendSLRec,
+ kEventParamTextInputSendFixLen,
+ kEventParamTextInputSendText,
+ kEventParamTextInputSendUpdateRng,
+ kEventParamTextInputSendHiliteRng,
+ kEventParamTextInputSendClauseRng,
+ kEventParamTextInputSendPinRng,
+ kEventParamTextInputSendTextServiceEncoding,
+ kEventParamTextInputSendTextServiceMacEncoding,
+ EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER};
+ static EventParamType types_uaia[] =
+ {typeComponentInstance,
+ typeLongInteger,
+ typeIntlWritingCode,
+ typeLongInteger,
+ typeUnicodeText,
+ typeTextRangeArray,
+ typeTextRangeArray,
+ typeOffsetArray,
+ typeTextRange,
+ typeUInt32,
+ typeUInt32,
+ typeUInt32};
+ static EventParamName names_ufke[] =
+ {kEventParamTextInputSendComponentInstance,
+ kEventParamTextInputSendRefCon,
+ kEventParamTextInputSendSLRec,
+ kEventParamTextInputSendText};
+ static EventParamType types_ufke[] =
+ {typeComponentInstance,
+ typeLongInteger,
+ typeIntlWritingCode,
+ typeUnicodeText};
+
+ result = CallNextEventHandler (next_handler, event);
+
+ switch (GetEventKind (event))
+ {
+ case kEventTextInputUpdateActiveInputArea:
+ id_key = Qupdate_active_input_area;
+ num_params = sizeof (names_uaia) / sizeof (names_uaia[0]);
+ names = names_uaia;
+ types = types_uaia;
+ SetEventParameter (event, EVENT_PARAM_TEXT_INPUT_SEQUENCE_NUMBER,
+ typeUInt32, sizeof (UInt32), &seqno_uaia);
+ seqno_uaia++;
+ break;
+
+ case kEventTextInputUnicodeForKeyEvent:
{
- 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);
+ EventRef kbd_event;
+ UInt32 actual_size, modifiers, mapped_modifiers;
+ UniChar code;
+
+ err = GetEventParameter (event, kEventParamTextInputSendKeyboardEvent,
+ typeEventRef, NULL, sizeof (EventRef), NULL,
+ &kbd_event);
+ if (err == noErr)
+ 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)
+ err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
+ typeUnicodeText, NULL, 0, &actual_size,
+ NULL);
+ if (err == noErr)
+ {
+ if (actual_size == sizeof (UniChar))
+ err = GetEventParameter (kbd_event, kEventParamKeyUnicodes,
+ typeUnicodeText, NULL,
+ sizeof (UniChar), NULL, &code);
+ if (err == noErr && code < 0x80)
+ {
+ /* ASCII character. Process it in XTread_socket. */
+ if (read_socket_inev && code >= 0x20 && code <= 0x7e)
+ {
+ struct frame *f = mac_focus_frame (&one_mac_display_info);
+
+ read_socket_inev->kind = ASCII_KEYSTROKE_EVENT;
+ read_socket_inev->code = code;
+ read_socket_inev->modifiers =
+ (extra_keyboard_modifiers
+ & (meta_modifier | alt_modifier
+ | hyper_modifier | super_modifier));
+ XSETFRAME (read_socket_inev->frame_or_window, f);
+ }
+ return eventNotHandledErr;
+ }
+ }
+ }
+ /* Non-ASCII keystrokes without mapped modifiers are processed
+ at the Lisp level. */
+ id_key = Qunicode_for_key_event;
+ num_params = sizeof (names_ufke) / sizeof (names_ufke[0]);
+ names = names_ufke;
+ types = types_ufke;
+ break;
+
+ case kEventTextInputOffsetToPos:
+ {
+ struct frame *f;
+ struct window *w;
+ Point p;
+
+ if (!OVERLAYP (Vmac_ts_active_input_overlay))
+ return eventNotHandledErr;
+
+ /* Strictly speaking, this is not always correct because
+ previous events may change some states about display. */
+ if (NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
+ {
+ /* Active input area is displayed in the echo area. */
+ w = XWINDOW (echo_area_window);
+ f = WINDOW_XFRAME (w);
+ }
+ else
+ {
+ /* Active input area is displayed around the current point. */
+ f = SELECTED_FRAME ();
+ w = XWINDOW (f->selected_window);
+ }
+
+ p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
+ + WINDOW_LEFT_FRINGE_WIDTH (w));
+ p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
+ + FONT_BASE (FRAME_FONT (f)));
+ SetPortWindowPort (FRAME_MAC_WINDOW (f));
+ LocalToGlobal (&p);
+ err = SetEventParameter (event, kEventParamTextInputReplyPoint,
+ typeQDPoint, sizeof (typeQDPoint), &p);
}
break;
abort ();
}
- if (err == noErr)
+ if (!NILP (id_key))
+ err = mac_store_event_ref_as_apple_event (0, 0, Qtext_input, id_key,
+ event, num_params,
+ names, types);
+
+ return err == noErr ? noErr : result;
+}
+#endif
+
+#ifdef MAC_OSX
+OSStatus
+mac_store_service_event (event)
+ EventRef event;
+{
+ OSStatus err;
+ Lisp_Object id_key;
+ int num_params;
+ EventParamName *names;
+ EventParamType *types;
+ static EventParamName names_pfm[] = {kEventParamServiceMessageName,
+ kEventParamServiceUserData};
+ static EventParamType types_pfm[] = {typeCFStringRef,
+ typeCFStringRef};
+
+ switch (GetEventKind (event))
{
- mac_store_apple_event (Qservices, id_key, &apple_event);
- AEDisposeDesc (&apple_event);
+ case kEventServicePaste:
+ id_key = Qpaste;
+ num_params = 0;
+ names = NULL;
+ types = NULL;
+ break;
+
+ case kEventServicePerform:
+ id_key = Qperform;
+ num_params = sizeof (names_pfm) / sizeof (names_pfm[0]);
+ names = names_pfm;
+ types = types_pfm;
+ break;
+
+ default:
+ abort ();
}
+ err = mac_store_event_ref_as_apple_event (0, 0, Qservice, id_key,
+ event, num_params,
+ names, types);
+
return err;
}
#endif /* MAC_OSX */
{kEventClassWindow, kEventWindowShown},
{kEventClassWindow, kEventWindowHidden},
{kEventClassWindow, kEventWindowExpanded},
- {kEventClassWindow, kEventWindowCollapsed}};
+ {kEventClassWindow, kEventWindowCollapsed},
+#ifdef MAC_OSX
+ {kEventClassWindow, kEventWindowToolbarSwitchMode},
+#endif
+#if USE_MAC_TSM
+ {kEventClassWindow, kEventWindowFocusAcquired},
+ {kEventClassWindow, kEventWindowFocusRelinquish},
+#endif
+ };
EventTypeSpec specs_mouse[] = {{kEventClassMouse, kEventMouseWheelMoved}};
static EventHandlerUPP handle_window_eventUPP = NULL;
static EventHandlerUPP handle_mouse_eventUPP = NULL;
+#if USE_MAC_FONT_PANEL
+ EventTypeSpec specs_font[] = {{kEventClassFont, kEventFontPanelClosed},
+ {kEventClassFont, kEventFontSelection}};
+ static EventHandlerUPP handle_font_eventUPP = NULL;
+#endif
+#if USE_MAC_TSM
+ EventTypeSpec specs_text_input[] =
+ {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
+ {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
+ {kEventClassTextInput, kEventTextInputOffsetToPos}};
+ static EventHandlerUPP handle_text_input_eventUPP = NULL;
+#endif
if (handle_window_eventUPP == NULL)
handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event);
if (handle_mouse_eventUPP == NULL)
handle_mouse_eventUPP = NewEventHandlerUPP (mac_handle_mouse_event);
+#if USE_MAC_FONT_PANEL
+ if (handle_font_eventUPP == NULL)
+ handle_font_eventUPP = NewEventHandlerUPP (mac_handle_font_event);
+#endif
+#if USE_MAC_TSM
+ if (handle_text_input_eventUPP == NULL)
+ handle_text_input_eventUPP =
+ NewEventHandlerUPP (mac_handle_text_input_event);
+#endif
err = InstallWindowEventHandler (window, handle_window_eventUPP,
GetEventTypeCount (specs_window),
specs_window, NULL, NULL);
err = InstallWindowEventHandler (window, handle_mouse_eventUPP,
GetEventTypeCount (specs_mouse),
specs_mouse, NULL, NULL);
+#if USE_MAC_FONT_PANEL
+ if (err == noErr)
+ err = InstallWindowEventHandler (window, handle_font_eventUPP,
+ GetEventTypeCount (specs_font),
+ specs_font, NULL, NULL);
+#endif
+#if USE_MAC_TSM
+ if (err == noErr)
+ err = InstallWindowEventHandler (window, handle_text_input_eventUPP,
+ GetEventTypeCount (specs_text_input),
+ specs_text_input, window, NULL);
+#endif
#endif
if (err == noErr)
err = install_drag_handler (window);
/*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
/*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
- /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
+ /*0x68*/ 0, 0xca /*f13*/, 0xcd /*f16*/, 0xcb /*f14*/,
/*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
/*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
return *xKeySym != 0;
}
-static unsigned char fn_keycode_to_xkeysym_table[] = {
+#ifdef MAC_OSX
+/* Table for translating Mac keycode with the laptop `fn' key to that
+ without it. Destination symbols in comments are keys on US
+ keyboard, and they may not be the same on other types of keyboards.
+ If the destination is identical to the source (f1 ... f12), it
+ doesn't map `fn' key to a modifier. */
+static unsigned char fn_keycode_to_keycode_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,
/*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,
+ /*0x40*/ 0, 0x2f /*kp-. -> '.'*/, 0, 0x23 /*kp-* -> 'p'*/,
+ /*0x44*/ 0, 0x2c /*kp-+ -> '/'*/, 0, 0x16 /*clear -> '6'*/,
+ /*0x48*/ 0, 0, 0, 0x1d /*kp-/ -> '0'*/,
+ /*0x4C*/ 0x24 /*kp-enter -> return*/, 0, 0x29 /*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,
+ /*0x50*/ 0, 0x1b /*kp-= -> '-'*/, 0x2e /*kp-0 -> 'm'*/, 0x26 /*kp-1 -> 'j'*/,
+ /*0x54*/ 0x28 /*kp-2 -> 'k'*/, 0x25 /*kp-3 -> 'l'*/, 0x20 /*kp-4 -> 'u'*/, 0x22 /*kp-5 ->'i'*/,
+ /*0x58*/ 0x1f /*kp-6 -> 'o'*/, 0x1a /*kp-7 -> '7'*/, 0, 0x1c /*kp-8 -> '8'*/,
+ /*0x5C*/ 0x19 /*kp-9 -> '9'*/, 0, 0, 0,
- /*0x60*/ 0, 0, 0, 0,
- /*0x64*/ 0, 0, 0, 0,
+ /*0x60*/ 0x60 /*f5 = f5*/, 0x61 /*f6 = f6*/, 0x62 /*f7 = f7*/, 0x63 /*f3 = f3*/,
+ /*0x64*/ 0x64 /*f8 = f8*/, 0x65 /*f9 = f9*/, 0, 0x67 /*f11 = f11*/,
/*0x68*/ 0, 0, 0, 0,
- /*0x6C*/ 0, 0, 0, 0,
+ /*0x6C*/ 0, 0x6d /*f10 = f10*/, 0, 0x6f /*f12 = f12*/,
- /*0x70*/ 0, 0, 0, 0,
- /*0x74*/ 0, 0, 0, 0,
- /*0x78*/ 0, 0, 0, 0,
+ /*0x70*/ 0, 0, 0, 0x7b /*home -> left*/,
+ /*0x74*/ 0x7e /*pgup -> up*/, 0x33 /*delete -> backspace*/, 0x76 /*f4 = f4*/, 0x7c /*end -> right*/,
+ /*0x78*/ 0x78 /*f2 = f2*/, 0x7d /*pgdown -> down*/, 0x7a /*f1 = f1*/, 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.
-
- */
- OSStatus err;
- UInt32 mods = 0;
- if (!NILP(Vmac_function_modifier))
- {
- err = GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32,
- NULL, sizeof (UInt32), NULL, &mods);
- if (err != noErr && 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;
-}
-
+#endif /* MAC_OSX */
#if !USE_CARBON_EVENTS
static RgnHandle mouse_region = NULL;
return err;
}
+
+static void
+mac_set_unicode_keystroke_event (code, buf)
+ UniChar code;
+ struct input_event *buf;
+{
+ int charset_id, c1, c2;
+
+ if (code < 0x80)
+ {
+ buf->kind = ASCII_KEYSTROKE_EVENT;
+ buf->code = code;
+ }
+ else if (code < 0x100)
+ {
+ if (code < 0xA0)
+ charset_id = CHARSET_8_BIT_CONTROL;
+ else
+ charset_id = charset_latin_iso8859_1;
+ buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ buf->code = MAKE_CHAR (charset_id, code, 0);
+ }
+ else
+ {
+ if (code < 0x2500)
+ charset_id = charset_mule_unicode_0100_24ff,
+ code -= 0x100;
+ else if (code < 0x33FF)
+ charset_id = charset_mule_unicode_2500_33ff,
+ code -= 0x2500;
+ else if (code >= 0xE000)
+ charset_id = charset_mule_unicode_e000_ffff,
+ code -= 0xE000;
+ c1 = (code / 96) + 32, c2 = (code % 96) + 32;
+ buf->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ buf->code = MAKE_CHAR (charset_id, c1, c2);
+ }
+}
#endif
/* Emacs calls this whenever it wants to read an input event from the
struct frame *f;
unsigned long timestamp;
- /* It is necessary to set this (additional) argument slot of an
- event to nil because keyboard.c protects incompletely
- processed event from being garbage collected by placing them
- in the kbd_buffer_gcpro vector. */
EVENT_INIT (inev);
inev.kind = NO_EVENT;
inev.arg = Qnil;
break;
case inContent:
- if (window_ptr != FRAME_MAC_WINDOW (mac_focus_frame (dpyinfo)))
+ if (
+#if TARGET_API_MAC_CARBON
+ FrontNonFloatingWindow ()
+#else
+ FrontWindow ()
+#endif
+ != window_ptr)
SelectWindow (window_ptr);
else
{
break;
case keyDown:
+ case keyUp:
case autoKey:
{
int keycode = (er.message & keyCodeMask) >> 8;
int xkeysym;
+ static SInt16 last_key_script = -1;
+ 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;
#if USE_CARBON_EVENTS && defined (MAC_OSX)
/* When using Carbon Events, we need to pass raw keyboard
will pass back noErr, otherwise it will pass back
"eventNotHandledErr" and we can process it
normally. */
- if ((mac_pass_command_to_system
- || !(er.modifiers & cmdKey))
- && (mac_pass_control_to_system
- || !(er.modifiers & controlKey))
- && (NILP (Vmac_option_modifier)
- || !(er.modifiers & optionKey)))
- if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
- != eventNotHandledErr)
- break;
-#endif
-
-#if 0
- if (dpyinfo->x_focus_frame == NULL)
+ if (!(mapped_modifiers
+ & ~(mac_pass_command_to_system ? cmdKey : 0)
+ & ~(mac_pass_control_to_system ? controlKey : 0)))
{
- /* Beep if keyboard input occurs when all the frames
- are invisible. */
- SysBeep (1);
- break;
+ OSStatus err;
+
+ read_socket_inev = &inev;
+ err = SendEventToEventTarget (eventRef, toolbox_dispatcher);
+ read_socket_inev = NULL;
+ if (err != eventNotHandledErr)
+ break;
}
#endif
-
- {
- static SInt16 last_key_script = -1;
- SInt16 current_key_script = GetScriptManagerVariable (smKeyScript);
-
- if (last_key_script != current_key_script)
- {
- struct input_event event;
-
- EVENT_INIT (event);
- event.kind = LANGUAGE_CHANGE_EVENT;
- event.arg = Qnil;
- event.code = current_key_script;
- event.timestamp = timestamp;
- kbd_buffer_store_event (&event);
- count++;
- }
- last_key_script = current_key_script;
- }
+ if (er.what == keyUp)
+ break;
ObscureCursor ();
dpyinfo->mouse_face_hidden = 1;
}
- /* 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))
+ current_key_script = GetScriptManagerVariable (smKeyScript);
+ if (last_key_script != current_key_script)
{
- 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;
+ struct input_event event;
+
+ EVENT_INIT (event);
+ event.kind = LANGUAGE_CHANGE_EVENT;
+ event.arg = Qnil;
+ event.code = current_key_script;
+ event.timestamp = timestamp;
+ kbd_buffer_store_event (&event);
+ count++;
+ last_key_script = current_key_script;
}
- else
+
+#if USE_MAC_TSM
+ if (inev.kind != NO_EVENT)
+ break;
#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
- inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
-#else
- inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
+#ifdef MAC_OSX
+ if (mapped_modifiers & kEventKeyModifierFnMask
+ && keycode <= 0x7f
+ && fn_keycode_to_keycode_table[keycode])
+ keycode = fn_keycode_to_keycode_table[keycode];
+#endif
+ if (keycode_to_xkeysym (keycode, &xkeysym))
+ {
+ inev.kind = NON_ASCII_KEYSTROKE_EVENT;
+ inev.code = 0xff00 | xkeysym;
+#ifdef MAC_OSX
+ if (modifiers & kEventKeyModifierFnMask
+ && keycode <= 0x7f
+ && fn_keycode_to_keycode_table[keycode] == keycode)
+ modifiers &= ~kEventKeyModifierFnMask;
+#endif
+ }
+ else if (mapped_modifiers)
+ {
+ /* translate the keycode back to determine the
+ original key */
+#ifdef MAC_OSX
+ static SInt16 last_key_layout_id = 0;
+ static Handle uchr_handle = (Handle)-1;
+ SInt16 current_key_layout_id =
+ GetScriptVariable (current_key_script, smScriptKeys);
+
+ if (uchr_handle == (Handle)-1
+ || last_key_layout_id != current_key_layout_id)
+ {
+ uchr_handle = GetResource ('uchr', current_key_layout_id);
+ last_key_layout_id = current_key_layout_id;
+ }
+
+ if (uchr_handle)
+ {
+ OSStatus status;
+ UInt16 key_action = er.what - keyDown;
+ UInt32 modifier_key_state =
+ (modifiers & ~mapped_modifiers) >> 8;
+ UInt32 keyboard_type = LMGetKbdType ();
+ SInt32 dead_key_state = 0;
+ UniChar code;
+ UniCharCount actual_length;
+
+ status = UCKeyTranslate ((UCKeyboardLayout *)*uchr_handle,
+ keycode, key_action,
+ modifier_key_state,
+ keyboard_type,
+ kUCKeyTranslateNoDeadKeysMask,
+ &dead_key_state,
+ 1, &actual_length, &code);
+ if (status == noErr && actual_length == 1)
+ mac_set_unicode_keystroke_event (code, &inev);
+ }
+#endif /* MAC_OSX */
+
+ if (inev.kind == NO_EVENT)
+ {
+ /* 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. */
+ /* Mask off modifier keys that are mapped to some
+ Emacs modifiers. */
+ int new_modifiers = er.modifiers & ~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;
+ UInt32 new_char_code;
+
+ new_char_code = KeyTranslate (kchr_ptr, new_keycode,
+ &some_state);
+ if (new_char_code == 0)
+ /* Seems like a dead key. Append up-stroke. */
+ new_char_code = KeyTranslate (kchr_ptr,
+ new_keycode | 0x80,
+ &some_state);
+ if (new_char_code)
+ {
+ inev.kind = ASCII_KEYSTROKE_EVENT;
+ inev.code = new_char_code & 0xff;
+ }
+ }
+ }
+
+ if (inev.kind == NO_EVENT)
+ {
+ inev.kind = ASCII_KEYSTROKE_EVENT;
+ inev.code = er.message & charCodeMask;
+ }
+
+ inev.modifiers = mac_to_emacs_modifiers (modifiers);
+ inev.modifiers |= (extra_keyboard_modifiers
+ & (meta_modifier | alt_modifier
+ | hyper_modifier | super_modifier));
+ XSETFRAME (inev.frame_or_window, f);
+
+#if TARGET_API_MAC_CARBON
+ if (inev.kind == ASCII_KEYSTROKE_EVENT
+ && inev.code >= 0x80 && inev.modifiers)
+ {
+ OSStatus err;
+ TextEncoding encoding = kTextEncodingMacRoman;
+ TextToUnicodeInfo ttu_info;
+
+ UpgradeScriptInfoToTextEncoding (current_key_script,
+ kTextLanguageDontCare,
+ kTextRegionDontCare,
+ NULL, &encoding);
+ err = CreateTextToUnicodeInfoByEncoding (encoding, &ttu_info);
+ if (err == noErr)
+ {
+ UniChar code;
+ Str255 pstr;
+ ByteCount unicode_len;
+
+ pstr[0] = 1;
+ pstr[1] = inev.code;
+ err = ConvertFromPStringToUnicode (ttu_info, pstr,
+ sizeof (UniChar),
+ &unicode_len, &code);
+ if (err == noErr && unicode_len == sizeof (UniChar))
+ mac_set_unicode_keystroke_event (code, &inev);
+ DisposeTextToUnicodeInfo (&ttu_info);
+ }
+ }
#endif
- inev.modifiers |= (extra_keyboard_modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
- XSETFRAME (inev.frame_or_window, f);
+ }
break;
case kHighLevelEvent:
- read_socket_inev = &inev;
AEProcessAppleEvent (&er);
- read_socket_inev = NULL;
break;
default:
#endif
}
+#if USE_MAC_TSM
+static void
+init_tsm ()
+{
+ static InterfaceTypeList types = {kUnicodeDocument};
+
+ NewTSMDocument (sizeof (types) / sizeof (types[0]), types,
+ &tsm_document_id, 0);
+}
+#endif
/* Set up use of X before we make the first connection. */
init_command_handler ();
init_menu_bar ();
+
+#if USE_MAC_TSM
+ init_tsm ();
+#endif
#endif /* USE_CARBON_EVENTS */
#ifdef MAC_OSX
#if USE_CARBON_EVENTS
Qhicommand = intern ("hicommand"); staticpro (&Qhicommand);
#ifdef MAC_OSX
- Qservices = intern ("services"); staticpro (&Qservices);
+ Qtoolbar_switch_mode = intern ("toolbar-switch-mode");
+ staticpro (&Qtoolbar_switch_mode);
+#if USE_MAC_FONT_PANEL
+ Qpanel_closed = intern ("panel-closed"); staticpro (&Qpanel_closed);
+ Qselection = intern ("selection"); staticpro (&Qselection);
+#endif
+
+ Qservice = intern ("service"); staticpro (&Qservice);
Qpaste = intern ("paste"); staticpro (&Qpaste);
Qperform = intern ("perform"); staticpro (&Qperform);
#endif
+#if USE_MAC_TSM
+ Qtext_input = intern ("text-input"); staticpro (&Qtext_input);
+ Qupdate_active_input_area = intern ("update-active-input-area");
+ staticpro (&Qupdate_active_input_area);
+ Qunicode_for_key_event = intern ("unicode-for-key-event");
+ staticpro (&Qunicode_for_key_event);
+#endif
#endif
#ifdef MAC_OSX
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. */);
+ doc: /* If not nil, Emacs uses toolkit scroll bars. */);
#ifdef USE_TOOLKIT_SCROLL_BARS
Vx_toolkit_scroll_bars = Qt;
#else
#if USE_CARBON_EVENTS
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.
+ 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. */);
+ 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. */);
+ 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.
+ doc: /* *If non-nil, allow anti-aliasing.
The text will be rendered using Core Graphics text rendering which
may anti-alias the text. */);
#if USE_CG_DRAWING
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 of Emacs character sets vs text encodings and coding systems.
+ 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)
Vmac_charset_info_alist =
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.
+Each font ID is represented as a four-byte string in native byte
+order. */);
+ Vmac_atsu_font_table =
+ make_hash_table (Qequal, 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. */);
+ Vmac_ts_active_input_overlay = Qnil;
+#endif
}
/* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b