[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Free modifier key assignment (OS X)
From: |
YAMAMOTO Mitsuharu |
Subject: |
Re: Free modifier key assignment (OS X) |
Date: |
Sat, 20 May 2006 17:26:09 +0900 |
User-agent: |
Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.6 (Marutamachi) APEL/10.6 Emacs/22.0.50 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI) |
I tried to tackle some issues about mapping the laptop `fn' key to an
Emacs modifier. (This functionality was originally provided by David
Reitter.)
/* 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.
*/
I think the first one is solved by the patch below, but I can't test
the second one. Could non-US keyboard users test if the patch below
works for you? Fn-ö may be recognized as H-\232 instead of H-ö on a
German keyboard even if you set (setq mac-function-modifier 'hyper),
but this is another issue
(http://lists.gnu.org/archive/html/emacs-pretest-bug/2006-05/msg00033.html).
YAMAMOTO Mitsuharu
address@hidden
Index: src/macterm.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/macterm.c,v
retrieving revision 1.172
diff -c -r1.172 macterm.c
*** src/macterm.c 20 May 2006 07:15:22 -0000 1.172
--- src/macterm.c 20 May 2006 07:57:56 -0000
***************
*** 9629,9635 ****
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,
--- 9629,9635 ----
return *xKeySym != 0;
}
! 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,9662 ****
/*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
--- 9639,9662 ----
/*0x38*/ 0, 0, 0, 0,
/*0x3C*/ 0, 0, 0, 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, 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, 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
***************
*** 9673,9682 ****
/* 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-;.
--- 9673,9679 ----
/* TODO / known issues
! !!!! NEED TO CHECK IF IT REALLY DOESN'T WORK WITH NON-US KEYBOARDS. !!!!!
- 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-;.
***************
*** 9693,9699 ****
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);
}
--- 9690,9696 ----
err = GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32,
NULL, sizeof (UInt32), NULL, &mods);
if (err == noErr && mods & kEventKeyModifierFnMask)
! { *newCode = fn_keycode_to_keycode_table [keyCode & 0x7f];
return (*newCode != 0);
}
***************
*** 9702,9751 ****
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;
--- 9699,9704 ----
***************
*** 10338,10343 ****
--- 10291,10299 ----
{
int keycode = (er.message & keyCodeMask) >> 8;
int xkeysym;
+ static SInt16 last_key_script = -1;
+ SInt16 current_key_script;
+ UInt32 modifiers = er.modifiers, mapped_modifiers;
#if USE_CARBON_EVENTS && defined (MAC_OSX)
/* When using Carbon Events, we need to pass raw keyboard
***************
*** 10358,10392 ****
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);
--- 10314,10319 ----
***************
*** 10398,10442 ****
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))
{
! 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
- #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);
#endif
! inev.modifiers |= (extra_keyboard_modifiers
! & (meta_modifier | alt_modifier
! | hyper_modifier | super_modifier));
! XSETFRAME (inev.frame_or_window, f);
break;
case kHighLevelEvent:
--- 10325,10484 ----
dpyinfo->mouse_face_hidden = 1;
}
! 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 USE_CARBON_EVENTS
! inev.modifiers = mac_event_to_emacs_modifiers (eventRef);
#else
! 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);
!
! #if USE_CARBON_EVENTS
! {
! int tmp_code;
!
! if (convert_fn_keycode (eventRef, keycode, &tmp_code))
! keycode = tmp_code;
! }
#endif
! if (keycode_to_xkeysym (keycode, &xkeysym))
! {
! inev.kind = NON_ASCII_KEYSTROKE_EVENT;
! inev.code = 0xff00 | xkeysym;
! break;
! }
!
! #if USE_CARBON_EVENTS
! GetEventParameter (eventRef, kEventParamKeyModifiers,
! typeUInt32, NULL,
! sizeof (UInt32), NULL, &modifiers);
! #endif
!
! mapped_modifiers =
! (NILP (Vmac_control_modifier) ? 0 : controlKey)
! | (NILP (Vmac_option_modifier) ? 0 : optionKey)
! | (NILP (Vmac_command_modifier) ? 0 : cmdKey)
! #ifdef MAC_OSX
! | (NILP (Vmac_function_modifier) ? 0 : kEventKeyModifierFnMask)
! #endif
! ;
!
! if (!(modifiers & mapped_modifiers))
! {
! inev.kind = ASCII_KEYSTROKE_EVENT;
! inev.code = er.message & charCodeMask;
! }
! else
! {
! /* 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, 0,
! &dead_key_state,
! 1, &actual_length, &code);
! if (status == noErr && actual_length == 1)
! {
! int charset_id, c1, c2;
!
! if (code < 0x80)
! {
! inev.kind = ASCII_KEYSTROKE_EVENT;
! inev.code = code;
! }
! else if (code < 0x100)
! {
! if (code < 0xA0)
! charset_id = CHARSET_8_BIT_CONTROL;
! else
! charset_id = charset_latin_iso8859_1;
! inev.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
! inev.code = MAKE_CHAR (charset_id, code, 0);
! }
! else
! {
! if (code < 0x2500)
! charset_id = charset_mule_unicode_0100_24ff,
! code -= 0x100;
! else if (code < 0xE000)
! charset_id = charset_mule_unicode_2500_33ff,
! code -= 0x2500;
! else
! charset_id = charset_mule_unicode_e000_ffff,
! code -= 0xE000;
! c1 = (code / 96) + 32, c2 = (code % 96) + 32;
! inev.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
! inev.code = MAKE_CHAR (charset_id, c1, c2);
! }
! }
! }
! #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;
! inev.code = (int) KeyTranslate (kchr_ptr, new_keycode,
! &some_state) & 0xff;
! inev.kind = ASCII_KEYSTROKE_EVENT;
! }
! }
! }
break;
case kHighLevelEvent:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: Free modifier key assignment (OS X),
YAMAMOTO Mitsuharu <=