* Free modifier key assignment (OS X) @ 2005-09-25 20:34 David Reitter 2005-09-26 13:18 ` Stefan Monnier 2005-09-27 3:45 ` YAMAMOTO Mitsuharu 0 siblings, 2 replies; 10+ messages in thread From: David Reitter @ 2005-09-25 20:34 UTC (permalink / raw) [-- Attachment #1.1.1: Type: text/plain, Size: 895 bytes --] Here is the latest version of mac-modifier-keys patch, which allows people to freely assign modifier keys on their keyboard to Emacs modifiers. The current solution is overly complicated and doesn't allow certain combinations of settings such as Command->Hyper (while saying Option- >Meta). The reasoning behind it is described here. http://lists.gnu.org/archive/html/emacs-devel/2005-05/msg00661.html Note that any xmodmap solution people may think of will not work on OS X when using Carbon - OS X doesn't normally use X11 for its graphics output. I would like to recommend applying this now before the release is readied, because otherwise one will have to change customization options that get documented in the release. The present patch allows for longer-term stability. (It is backwards-compatible to cater for the many people who've been installing CVS Emacs.) [-- Attachment #1.1.2: mac-modifier-keys.patch --] [-- Type: application/octet-stream, Size: 16644 bytes --] Index: src/macterm.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/macterm.c,v retrieving revision 1.123 diff -c -r1.123 macterm.c *** src/macterm.c 14 Jul 2005 09:23:24 -0000 1.123 --- src/macterm.c 15 Jul 2005 23:15:49 -0000 *************** *** 86,99 **** #include "atimer.h" #include "keymap.h" ! /* Set of macros that handle mapping of Mac modifier keys to emacs. */ ! #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \ ! (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey)) #define macShiftKey (shiftKey) ! #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \ ! (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \ ! : controlKey) ! #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey) \f /* Non-nil means Emacs uses toolkit scroll bars. */ --- 86,118 ---- #include "atimer.h" #include "keymap.h" ! /* Set of macros that handle mapping of Mac modifier keys to emacs. ! If any of the newer-style mac_*_modifier variables is set, these ! macros are basically out of function. ! */ ! ! #define macOldModifierSetting ( NILP(Vmac_control_modifier) && \ ! NILP(Vmac_option_modifier) && \ ! NILP(Vmac_command_modifier) ) ! ! #define macCtrlKey (macOldModifierSetting ? \ ! (NILP(Vmac_reverse_ctrl_meta) ? controlKey : \ ! (NILP(Vmac_command_key_is_meta) ? \ ! optionKey : cmdKey)) : \ ! controlKey) #define macShiftKey (shiftKey) ! ! #define macMetaKey (macOldModifierSetting ? \ ! (NILP(Vmac_reverse_ctrl_meta) ? \ ! (NILP(Vmac_command_key_is_meta) ? optionKey : \ ! cmdKey) : controlKey) : \ ! (cmdKey | controlKey | optionKey)) ! ! #define macAltKey (macOldModifierSetting ? \ ! (NILP(Vmac_command_key_is_meta) ? \ ! cmdKey : optionKey) : optionKey) ! ! #define macCmdKey (cmdKey) \f /* Non-nil means Emacs uses toolkit scroll bars. */ *************** *** 205,211 **** /* The keysyms to use for the various modifiers. */ ! static Lisp_Object Qalt, Qhyper, Qsuper, Qmodifier_value; extern int inhibit_window_system; --- 224,230 ---- /* The keysyms to use for the various modifiers. */ ! static Lisp_Object Qalt, Qhyper, Qsuper, Qctrl, Qmeta, Qmodifier_value; extern int inhibit_window_system; *************** *** 7321,7333 **** /* Contains the string "reverse", which is a constant for mouse button emu.*/ Lisp_Object Qreverse; ! /* True if using command key as meta key. */ Lisp_Object Vmac_command_key_is_meta; /* Modifier associated with the option key, or nil for normal behavior. */ Lisp_Object Vmac_option_modifier; ! /* True if the ctrl and meta keys should be reversed. */ Lisp_Object Vmac_reverse_ctrl_meta; /* True if the option and command modifiers should be used to emulate --- 7340,7360 ---- /* Contains the string "reverse", which is a constant for mouse button emu.*/ Lisp_Object Qreverse; ! /* True if using command key as meta key. ! Deprecated; only use if macOldModifierSetting evaluates to true. */ Lisp_Object Vmac_command_key_is_meta; + /* Modifier associated with the control key, or nil for normal behavior. */ + Lisp_Object Vmac_control_modifier; + /* Modifier associated with the option key, or nil for normal behavior. */ Lisp_Object Vmac_option_modifier; ! /* Modifier associated with the command key, or nil for normal behavior. */ ! Lisp_Object Vmac_command_modifier; ! ! /* True if the ctrl and meta keys should be reversed. ! Deprecated; only use if macOldModifierSetting evaluates to true. */ Lisp_Object Vmac_reverse_ctrl_meta; /* True if the option and command modifiers should be used to emulate *************** *** 7347,7352 **** --- 7374,7386 ---- for processing before Emacs sees it. */ Lisp_Object Vmac_pass_control_to_system; + /* If non-nil, the Mac \"Option\" key can be used to compose + characters as handled by the system and depending on the + keyboard layout chosen. Only if the Mac \"Command\" or \"Ctrl\" key + is depressed at the same time, Emacs evaluates the combination using + whatever modifier is set in mac-option-modifier. */ + Lisp_Object Vmac_pass_option_to_system; + /* Points to the variable `inev' in the function XTread_socket. It is used for passing an input event to the function back from Carbon/Apple event handlers. */ *************** *** 7404,7420 **** unsigned int result = 0; if (mods & macShiftKey) result |= shift_modifier; ! if (mods & macCtrlKey) ! result |= ctrl_modifier; ! if (mods & macMetaKey) ! result |= meta_modifier; ! if (NILP (Vmac_command_key_is_meta) && (mods & macAltKey)) ! result |= alt_modifier; ! if (!NILP (Vmac_option_modifier) && (mods & optionKey)) { ! Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value); ! if (!NILP(val)) result |= XUINT(val); ! } return result; } --- 7438,7512 ---- unsigned int result = 0; if (mods & macShiftKey) result |= shift_modifier; ! ! if (macOldModifierSetting) /* compatibility with old-style modifier keys */ ! { ! if (mods & macCtrlKey) ! result |= ctrl_modifier; ! if (mods & macMetaKey) ! result |= meta_modifier; ! ! if ( ( NILP(Vmac_pass_option_to_system) || ! ( /* only for ctrl/cmd combos if option is handled by system */ ! (mods & cmdKey) || (mods & controlKey) ! ) ! ) && ! !NILP (Vmac_command_key_is_meta) && ! (mods & macAltKey) ! ) ! result |= alt_modifier; ! } else ! { ! /* new-style modifier keys */ ! ! /* if Vmac_pass_option_to_system is NIL, we fully process the Option ! key. Otherwise, we only process it if an additional Ctrl or Command ! is pressed. That way the system may convert the character to a ! composed one. ! */ ! ! if ( ! (mods & optionKey) && ! ( ! ( NILP(Vmac_pass_option_to_system) || ! ( ! (mods & cmdKey) || (mods & controlKey) ! ) ! ) ! ) ! ) ! { ! if (!NILP (Vmac_option_modifier)) { ! Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value); ! if (!NILP(val)) ! result |= XUINT(val); ! } else { /* default behavior if modifier variable is set to nil: ! do NOT assume alt modifier, because the OS already ! sends a modified key (e.g. option-l -> @ ! on German keyboard) */ ! ! result |= alt_modifier; ! } ! ! } ! if (!NILP (Vmac_command_modifier) && (mods & cmdKey)) { ! Lisp_Object val = Fget(Vmac_command_modifier, Qmodifier_value); ! if (!NILP(val)) result |= XUINT(val); ! } else { /* default behavior if modifier variable is not set: ! assign hyper*/ ! if (mods & macCmdKey) ! result |= hyper_modifier; ! } ! if (!NILP (Vmac_control_modifier) && (mods & controlKey)) { ! Lisp_Object val = Fget(Vmac_control_modifier, Qmodifier_value); ! if (!NILP(val)) ! result |= XUINT(val); ! } else { /* default behavior if modifier variable is not set */ ! if (mods & macCtrlKey) ! result |= ctrl_modifier; ! } ! } return result; } *************** *** 9326,9334 **** || !(er.modifiers & cmdKey)) && (!NILP (Vmac_pass_control_to_system) || !(er.modifiers & controlKey)) ! && (!NILP (Vmac_command_key_is_meta) ! && NILP (Vmac_option_modifier) ! || !(er.modifiers & optionKey))) if (SendEventToEventTarget (eventRef, toolbox_dispatcher) != eventNotHandledErr) break; --- 9418,9431 ---- || !(er.modifiers & cmdKey)) && (!NILP (Vmac_pass_control_to_system) || !(er.modifiers & controlKey)) ! && (!NILP (Vmac_pass_option_to_system) ! || (macOldModifierSetting ? ! ((!NILP (Vmac_command_key_is_meta) ! && NILP (Vmac_option_modifier) ! || !(er.modifiers & optionKey))) ! : !(er.modifiers & optionKey)) ! ) ! ) if (SendEventToEventTarget (eventRef, toolbox_dispatcher) != eventNotHandledErr) break; *************** *** 9377,9386 **** inev.kind = NON_ASCII_KEYSTROKE_EVENT; } else ! { ! if (er.modifiers & (controlKey | ! (NILP (Vmac_command_key_is_meta) ? optionKey ! : cmdKey))) { /* This code comes from Keyboard Resource, Appendix C of IM - Text. This is necessary --- 9474,9492 ---- inev.kind = NON_ASCII_KEYSTROKE_EVENT; } else ! { ! if (er.modifiers & (controlKey | ! (NILP (Vmac_pass_option_to_system) ? optionKey : 0) | ! ( ! (macOldModifierSetting ? ! (NILP (Vmac_command_key_is_meta) ? ! optionKey : cmdKey ! ) ! : cmdKey ! ) ! ) ! ) ! ) { /* This code comes from Keyboard Resource, Appendix C of IM - Text. This is necessary *************** *** 9388,9394 **** translation when option or command is pressed. It also does not translate correctly control-shift chars like C-% so mask off shift ! here also */ int new_modifiers = er.modifiers & 0xe600; /* mask off option and command */ int new_keycode = keycode | new_modifiers; --- 9494,9507 ---- translation when option or command is pressed. It also does not translate correctly control-shift chars like C-% so mask off shift ! here also. ! ! For combinations with the option key (alt), this is only ! done if either command or control are used additionally, ! in which case this isn't handled ! or if mac-pass-option-to-system is nil -- in order ! to preserve key combinations translated by the OS, such as Alt-3. ! */ int new_modifiers = er.modifiers & 0xe600; /* mask off option and command */ int new_keycode = keycode | new_modifiers; *************** *** 9397,9415 **** inev.code = KeyTranslate (kchr_ptr, new_keycode, &some_state) & 0xff; } - else if (!NILP (Vmac_option_modifier) - && (er.modifiers & optionKey)) - { - /* When using the option key as an emacs modifier, - convert the pressed key code back to one - without the Mac option modifier applied. */ - int new_modifiers = er.modifiers & ~optionKey; - int new_keycode = keycode | new_modifiers; - Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache); - unsigned long some_state = 0; - inev.code = KeyTranslate (kchr_ptr, new_keycode, - &some_state) & 0xff; - } else inev.code = er.message & charCodeMask; inev.kind = ASCII_KEYSTROKE_EVENT; --- 9510,9515 ---- *************** *** 10029,10034 **** --- 10129,10138 ---- #if TARGET_API_MAC_CARBON init_required_apple_events (); + Qctrl = intern ("ctrl"); + Fput (Qctrl, Qmodifier_value, make_number (ctrl_modifier)); + Qmeta = intern ("meta"); + Fput (Qmeta, Qmodifier_value, make_number (meta_modifier)); #if USE_CARBON_EVENTS #ifdef MAC_OSX init_service_handler (); *************** *** 10079,10084 **** --- 10183,10191 ---- #ifdef MAC_OSX Fprovide (intern ("mac-carbon"), Qnil); #endif + /* Deprecated variables to configure modifier key assignment. + Retained for backward-compatibility. */ + staticpro (&Qreverse); Qreverse = intern ("reverse"); *************** *** 10105,10123 **** DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta, doc: /* Non-nil means that the command key is used as the Emacs meta key. ! Otherwise the option key is used. */); Vmac_command_key_is_meta = Qt; DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier, doc: /* Modifier to use for the Mac alt/option key. The value can be alt, hyper, or super for the respective modifier. If the value is ! nil then the key will act as the normal Mac option modifier. */); Vmac_option_modifier = Qnil; ! DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta, ! doc: /* Non-nil means that the control and meta keys are reversed. This is ! useful for non-standard keyboard layouts. */); ! Vmac_reverse_ctrl_meta = Qnil; DEFVAR_LISP ("mac-emulate-three-button-mouse", &Vmac_emulate_three_button_mouse, --- 10212,10267 ---- DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta, doc: /* Non-nil means that the command key is used as the Emacs meta key. ! Otherwise the option key is used. This variable is DEPRECATED. ! It is only in effect if all of the variables mac-*-modifier are nil. */); Vmac_command_key_is_meta = Qt; + + DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta, + doc: /* Non-nil means that the control and meta keys are reversed. This is + useful for non-standard keyboard layouts. This variable is DEPRECATED. + Backwards-compatibility: It is only in effect if none of the variables + mac-{command|control|option}-modifier is non-nil. */); + Vmac_reverse_ctrl_meta = Qnil; + + + /* Variables to configure modifier key assignment. */ + + DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier, + doc: /* Modifier to use for the Mac control key. The value can + be alt, hyper, or super for the respective modifier. If the value is + nil then the key will act as the normal Mac control modifier. + Backwards-compatibility: If all values of + mac-{command|control|option}-modifier are nil, the deprecated + default assignment determined by mac-command-key-is-meta and + mac-reverse-ctrl-meta is used. */); + Vmac_control_modifier = Qnil; DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier, doc: /* Modifier to use for the Mac alt/option key. The value can be alt, hyper, or super for the respective modifier. If the value is ! nil then the key will act as the normal Mac option modifier, and the option ! key can be used to compose characters depending on the chosen Mac keyboard ! setting. ! Note that mac-pass-option-to-system takes precedence over this setting. If ! mac-pass-option-to-system is non-nil, simple key combinations with Option ! will be handled by the system in order to produce characters, and only ! combinations in conjunction with Command or Control will let Emacs see ! the modifier that is assigned to the Option key. ! Backwards-compatibility: If all values of ! mac-{command|control|option}-modifier are nil, the deprecated default ! assignment determined by mac-command-key-is-meta and ! mac-reverse-ctrl-meta is used. */); Vmac_option_modifier = Qnil; ! DEFVAR_LISP ("mac-command-modifier", &Vmac_command_modifier, ! doc: /* Modifier to use for the Mac command key. The value can ! be alt, hyper, or super for the respective modifier. If the value is ! nil then the key will act as the Emacs 'hyper' modifier. ! Backwards-compatibility: If all values of ! mac-{command|control|option}-modifier are nil, the deprecated ! default assignment determined by mac-command-key-is-meta and ! mac-reverse-ctrl-meta is used. */); ! Vmac_command_modifier = Qnil; DEFVAR_LISP ("mac-emulate-three-button-mouse", &Vmac_emulate_three_button_mouse, *************** *** 10146,10151 **** --- 10290,10303 ---- doc: /* If non-nil, the Mac \"Control\" key is passed on to the Mac Toolbox for processing before Emacs sees it. */); Vmac_pass_control_to_system = Qt; + + DEFVAR_LISP ("mac-pass-option-to-system", &Vmac_pass_option_to_system, + doc: /* If non-nil, the Mac \"Option\" key can be used to compose + characters as handled by the system and depending on the + keyboard layout chosen. Only if the Mac \"Command\" or \"Ctrl\" key + is depressed at the same time, Emacs evaluates the combination using + whatever modifier is set in mac-option-modifier. */); + Vmac_pass_option_to_system = Qt; #endif [-- Attachment #1.2: smime.p7s --] [-- Type: application/pkcs7-signature, Size: 2400 bytes --] [-- Attachment #2: Type: text/plain, Size: 142 bytes --] _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Free modifier key assignment (OS X) 2005-09-25 20:34 Free modifier key assignment (OS X) David Reitter @ 2005-09-26 13:18 ` Stefan Monnier 2005-09-27 3:45 ` YAMAMOTO Mitsuharu 1 sibling, 0 replies; 10+ messages in thread From: Stefan Monnier @ 2005-09-26 13:18 UTC (permalink / raw) Cc: Emacs-Devel ' > Here is the latest version of mac-modifier-keys patch, which allows people > to freely assign modifier keys on their keyboard to Emacs modifiers. I haven't looked at this code either, but here even more, the functionality would be *very* welcome (the problem with modifiers (with both X11 and Carbon) is endemic under Mac OS X). Stefan ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Free modifier key assignment (OS X) 2005-09-25 20:34 Free modifier key assignment (OS X) David Reitter 2005-09-26 13:18 ` Stefan Monnier @ 2005-09-27 3:45 ` YAMAMOTO Mitsuharu 2005-09-27 10:01 ` David Reitter 2005-12-13 3:26 ` Carbon port: M-§ not recognized (Italian keyboards) YAMAMOTO Mitsuharu 1 sibling, 2 replies; 10+ messages in thread From: YAMAMOTO Mitsuharu @ 2005-09-27 3:45 UTC (permalink / raw) Cc: emacs-devel >>>>> On Sun, 25 Sep 2005 21:34:18 +0100, David Reitter <david.reitter@gmail.com> said: > Here is the latest version of mac-modifier-keys patch, which allows > people to freely assign modifier keys on their keyboard to Emacs > modifiers. Let me make a few comments. * Please follow the convention written in the "Tips for Documentation Strings" node in the Emacs Lisp info. Yes, the existing one is really bad in this sense. * I think the following kind of indentation is not used in Emacs sources unless preprocessor directives intervene. ! if ( ! (mods & optionKey) && ! ( ! ( NILP(Vmac_pass_option_to_system) || * I'd prefer a simple principle especially for the option key handling. I'm anxious that too complicated one might become an obstacle when adding Unicode input support or TSM support. A simple one would be useful not only for the maintenance of code but also for users to understand. How about the following one? A Mac modifier key is passed to the system if it isn't mapped to any Emacs modifiers or the user requests that by setting mac-pass-{control,command}-to-system to non-nil. If the system didn't intercept the keyboard input, we obtain keycode using KeyTranslate after stripping off all the Mac modifier keys that are mapped to some Emacs modifiers. In particular, the option key works as the real option key if and only if it isn't mapped to any Emacs modifiers. (I.e., don't introduce the variable `mac-pass-option-to-system'.) Then the conditionals becomes much simpler. Note that this code is based on the current definition of macCtrlKey/macMetaKey/macAltKey. case autoKey: { int keycode = (er.message & keyCodeMask) >> 8; int xkeysym; EventModifiers modifiers; /* Obtain Mac modifier keys that are pressed and to be mapped to Emacs modifiers. */ modifiers = macCtrlKey | macMetaKey | macAltKey; if (!NILP (Vmac_option_modifier)) modifiers |= optionKey; modifiers &= er.modifiers; #if USE_CARBON_EVENTS && defined (MAC_OSX) /* 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 (!((NILP (Vmac_pass_command_to_system) && (modifiers & cmdKey)) || (NILP (Vmac_pass_control_to_system) && (modifiers & controlKey)) || (modifiers & optionKey))) if (SendEventToEventTarget (eventRef, toolbox_dispatcher) != eventNotHandledErr) break; #endif ... if (keycode_to_xkeysym (keycode, &xkeysym)) { inev.code = 0xff00 | xkeysym; inev.kind = NON_ASCII_KEYSTROKE_EVENT; } else { if (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 */ EventModifiers new_modifiers = er.modifiers & ~modifiers; /* mask off modifiers */ UInt16 new_keycode = keycode | new_modifiers & 0xff00; Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache); UInt32 some_state = 0; inev.code = KeyTranslate (kchr_ptr, new_keycode, &some_state) & 0xff; } else inev.code = er.message & charCodeMask; inev.kind = ASCII_KEYSTROKE_EVENT; } YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Free modifier key assignment (OS X) 2005-09-27 3:45 ` YAMAMOTO Mitsuharu @ 2005-09-27 10:01 ` David Reitter 2005-09-28 8:28 ` YAMAMOTO Mitsuharu 2005-12-13 3:26 ` Carbon port: M-§ not recognized (Italian keyboards) YAMAMOTO Mitsuharu 1 sibling, 1 reply; 10+ messages in thread From: David Reitter @ 2005-09-27 10:01 UTC (permalink / raw) On 27 Sep 2005, at 04:45, YAMAMOTO Mitsuharu wrote: > > In particular, the option key works as the real option key if and > only if it isn't mapped to any Emacs modifiers. (I.e., don't > introduce the variable `mac-pass-option-to-system'.) > > Then the conditionals becomes much simpler. Note that this code is > based on the current definition of macCtrlKey/macMetaKey/macAltKey. I like this. Can we drop support for mac-command-key-is-meta, mac-pass-command-to- system, mac-reverse-ctrl-meta? I understand these variables haven't appeared in any release yet. It would be good to get this right before committing to them in the upcoming release. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Free modifier key assignment (OS X) 2005-09-27 10:01 ` David Reitter @ 2005-09-28 8:28 ` YAMAMOTO Mitsuharu 2006-05-20 8:26 ` YAMAMOTO Mitsuharu 0 siblings, 1 reply; 10+ messages in thread From: YAMAMOTO Mitsuharu @ 2005-09-28 8:28 UTC (permalink / raw) >>>>> On Tue, 27 Sep 2005 11:01:21 +0100, David Reitter <david.reitter@gmail.com> said: > Can we drop support for mac-command-key-is-meta, > mac-pass-command-to-system, mac-reverse-ctrl-meta? I think that would be desirable for mac-command-key-is-meta and mac-reverse-ctrl-meta, but not for mac-pass-command-to-system. > I understand these variables haven't appeared in any release yet. It > would be good to get this right before committing to them in the > upcoming release. Actually, we have the variable mac-command-key-is-meta in the official Emacs 21 (for Mac OS Classic, of course). But I think the impact of removal would be small. Some description in etc/NEWS would be needed, though. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Free modifier key assignment (OS X) 2005-09-28 8:28 ` YAMAMOTO Mitsuharu @ 2006-05-20 8:26 ` YAMAMOTO Mitsuharu 0 siblings, 0 replies; 10+ messages in thread From: YAMAMOTO Mitsuharu @ 2006-05-20 8:26 UTC (permalink / raw) 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 mituharu@math.s.chiba-u.ac.jp 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: ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Carbon port: M-§ not recognized (Italian keyboards) 2005-09-27 3:45 ` YAMAMOTO Mitsuharu 2005-09-27 10:01 ` David Reitter @ 2005-12-13 3:26 ` YAMAMOTO Mitsuharu 1 sibling, 0 replies; 10+ messages in thread From: YAMAMOTO Mitsuharu @ 2005-12-13 3:26 UTC (permalink / raw) Cc: emacs-devel >>>>> On Sun, 11 Dec 2005 17:33:02 +0000, David Reitter <david.reitter@gmail.com> said: > suggesting that something goes wrong with back-translating the > keycode in macterm.c. Does anyone have a good suggestion about the > underlying cause of this? By the way, I noticed that the current backtranslate_modified_keycode does not work as I suggested in http://lists.gnu.org/archive/html/emacs-devel/2005-09/msg00736.html : >>>>> On Tue, 27 Sep 2005 12:45:22 +0900, YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> said: > If the system didn't intercept the keyboard input, we obtain > keycode using KeyTranslate after stripping off all the Mac > modifier keys that are mapped to some Emacs modifiers. Even if mac-option-modifier is nil, the current code strips off the option key bit. So control-shift-alt-7 does not generate C-\ with Finnish keyboards, for example. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 10+ messages in thread
* Carbon port: M-§ not recognized (Italian keyboards) @ 2005-12-11 17:33 David Reitter 2005-12-12 2:41 ` YAMAMOTO Mitsuharu 0 siblings, 1 reply; 10+ messages in thread From: David Reitter @ 2005-12-11 17:33 UTC (permalink / raw) It seems like M-§ isn't recognized as such on Italian keyboards in the Mac (Carbon) port. define-key for this sequence doesn't show an effect, and the error message is M-¤ is undefined suggesting that something goes wrong with back-translating the keycode in macterm.c. Does anyone have a good suggestion about the underlying cause of this? Note that this is with (setq mac-option-modifier 'meta). Option-§ is - by default - bound to @ under OS X, so getting that key to work properly would bear some significance, because people might want to manually bind this key to something like (insert "@").] (Apart from that, "\M-(" gives me a nice "\250", while "\M-§" gives me just "§". I assume this has traditional reasons.) ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Carbon port: M-§ not recognized (Italian keyboards) 2005-12-11 17:33 David Reitter @ 2005-12-12 2:41 ` YAMAMOTO Mitsuharu 2006-01-17 0:26 ` David Reitter 0 siblings, 1 reply; 10+ messages in thread From: YAMAMOTO Mitsuharu @ 2005-12-12 2:41 UTC (permalink / raw) Cc: emacs-devel >>>>> On Sun, 11 Dec 2005 17:33:02 +0000, David Reitter <david.reitter@gmail.com> said: > It seems like M-§ isn't recognized as such on Italian keyboards in > the Mac (Carbon) port. define-key for this sequence doesn't show an > effect, and the error message is > M-¤ is undefined > suggesting that something goes wrong with back-translating the > keycode in macterm.c. Does anyone have a good suggestion about the > underlying cause of this? The code of ¤(0xA4) corresponds to that of § in mac-roman encoding. So it seems that back-translation itself does work, but encoded-kbd-mode does not translate a key input with modifiers. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Carbon port: M-§ not recognized (Italian keyboards) 2005-12-12 2:41 ` YAMAMOTO Mitsuharu @ 2006-01-17 0:26 ` David Reitter 0 siblings, 0 replies; 10+ messages in thread From: David Reitter @ 2006-01-17 0:26 UTC (permalink / raw) Cc: emacs-devel On 12 Dec 2005, at 02:41, YAMAMOTO Mitsuharu wrote: > >> M-¤ is undefined > >> suggesting that something goes wrong with back-translating the >> keycode in macterm.c. Does anyone have a good suggestion about the >> underlying cause of this? > > The code of ¤(0xA4) corresponds to that of § in mac-roman encoding. > So it seems that back-translation itself does work, but > encoded-kbd-mode does not translate a key input with modifiers. "\M-°" (French keyboard where a - and = are on a US one) exhibits similar behavior. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2006-05-20 8:26 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-09-25 20:34 Free modifier key assignment (OS X) David Reitter 2005-09-26 13:18 ` Stefan Monnier 2005-09-27 3:45 ` YAMAMOTO Mitsuharu 2005-09-27 10:01 ` David Reitter 2005-09-28 8:28 ` YAMAMOTO Mitsuharu 2006-05-20 8:26 ` YAMAMOTO Mitsuharu 2005-12-13 3:26 ` Carbon port: M-§ not recognized (Italian keyboards) YAMAMOTO Mitsuharu -- strict thread matches above, loose matches on Subject: below -- 2005-12-11 17:33 David Reitter 2005-12-12 2:41 ` YAMAMOTO Mitsuharu 2006-01-17 0:26 ` David Reitter
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).