(fn_keycode_to_xkeysym_table, convert_fn_keycode): Remove.

(fn_keycode_to_keycode_table) [MAC_OSX]: New variable.
(mac_set_unicode_keystroke_event) [TARGET_API_MAC_CARBON]: New function.
(XTread_socket) [TARGET_API_MAC_CARBON]: Use it.
(XTread_socket) [MAC_OSX]: Try 'uchr' Unicode keyboard-layout
resource to backtranslate key with modifiers.
(XTread_socket): Don't set read_socket_inev around AEProcessAppleEvent.
This commit is contained in:
YAMAMOTO Mitsuharu 2006-05-23 08:12:13 +00:00
parent b12d1537e7
commit b8c6940eaf
2 changed files with 226 additions and 170 deletions

View file

@ -1,3 +1,13 @@
2006-05-23 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
* macterm.c (fn_keycode_to_xkeysym_table, convert_fn_keycode): Remove.
(fn_keycode_to_keycode_table) [MAC_OSX]: New variable.
(mac_set_unicode_keystroke_event) [TARGET_API_MAC_CARBON]: New function.
(XTread_socket) [TARGET_API_MAC_CARBON]: Use it.
(XTread_socket) [MAC_OSX]: Try 'uchr' Unicode keyboard-layout
resource to backtranslate key with modifiers.
(XTread_socket): Don't set read_socket_inev around AEProcessAppleEvent.
2006-05-23 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
* xterm.c: Remove declarations already in xterm.h
@ -147,7 +157,7 @@
[MAC_OS] (gif_load): Emulate Graphic Control Extension block.
* macfns.c (x_to_mac_color): Fix shift amount change.
[USE_MAC_FONT_PANEL] (mac_set_font): Use x_get_focus_frame.
(mac_set_font) [USE_MAC_FONT_PANEL]: Use x_get_focus_frame.
[USE_MAC_FONT_PANEL] (Fmac_set_font_panel_visibility): Doc fix.
* macselect.c (Vmac_service_selection) [MAC_OSX]: Rename from

View file

@ -9629,7 +9629,12 @@ keycode_to_xkeysym (int keyCode, int *xKeySym)
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. */
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,
@ -9639,113 +9644,27 @@ static unsigned char fn_keycode_to_xkeysym_table[] = {
/*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,
/*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,
/*0x70*/ 0, 0, 0, 0x7b /*home -> left*/,
/*0x74*/ 0x7e /*pgup -> up*/, 0x33 /*delete -> backspace*/, 0, 0x7c /*end -> right*/,
/*0x78*/ 0, 0x7d /*pgdown -> down*/, 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.
*/
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;
@ -9819,6 +9738,44 @@ mac_post_mouse_moved_event ()
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
@ -10338,55 +10295,39 @@ XTread_socket (sd, expected, hold_quit)
{
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);
/* When using Carbon Events, we need to pass raw keyboard
events to the TSM ourselves. If TSM handles it, it
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 (!(modifiers
& mapped_modifiers
& ~(mac_pass_command_to_system ? cmdKey : 0)
& ~(mac_pass_control_to_system ? controlKey : 0)))
if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
!= eventNotHandledErr)
break;
break;
#endif
if (er.what == keyUp)
break;
#if 0
if (dpyinfo->x_focus_frame == NULL)
{
/* Beep if keyboard input occurs when all the frames
are invisible. */
SysBeep (1);
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;
}
ObscureCursor ();
f = mac_focus_frame (dpyinfo);
@ -10398,51 +10339,156 @@ XTread_socket (sd, expected, hold_quit)
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
#ifdef MAC_OSX
if (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.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 (keycode_to_xkeysym (keycode, &xkeysym))
{
inev.kind = NON_ASCII_KEYSTROKE_EVENT;
inev.code = 0xff00 | xkeysym;
}
else if (modifiers & 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;
}
#if USE_CARBON_EVENTS
inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
inev.modifiers = mac_to_emacs_modifiers (er.modifiers);
#endif
inev.modifiers |= (extra_keyboard_modifiers
& (meta_modifier | alt_modifier
| hyper_modifier | super_modifier));
XSETFRAME (inev.frame_or_window, f);
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
}
break;
case kHighLevelEvent:
read_socket_inev = &inev;
AEProcessAppleEvent (&er);
read_socket_inev = NULL;
break;
default: