aboutsummaryrefslogtreecommitdiffstats
path: root/src/macterm.c
diff options
context:
space:
mode:
authorSteven Tamm2005-11-11 16:33:44 +0000
committerSteven Tamm2005-11-11 16:33:44 +0000
commitb02e3f7ba66a48d30c8ebd5be03ff75c156564b0 (patch)
tree0496bdae8604b899bf9608449338e250996dca1a /src/macterm.c
parent338fa84a5ec5c280b7bbd19d1cac7b1268579789 (diff)
downloademacs-b02e3f7ba66a48d30c8ebd5be03ff75c156564b0.tar.gz
emacs-b02e3f7ba66a48d30c8ebd5be03ff75c156564b0.zip
macterm.c (backtranslate_modified_keycode): New function to
mask modifiers off of keycodes for use in modifier mapping. (mac_determine_quit_char_modifiers): Remove mac-reverse-ctrl-meta and replace it with more flexible system mapping mac modifier keys to emacs modifier keys. (convert_fn_keycode): Map Fn-keys to their original keycode using a table (english keyboard only). (syms_of_macterm): Define mac-control-modifier, mac-command-modifier, mac-function-modifier. Define meta and ctrl for use as modifiers.
Diffstat (limited to 'src/macterm.c')
-rw-r--r--src/macterm.c311
1 files changed, 226 insertions, 85 deletions
diff --git a/src/macterm.c b/src/macterm.c
index cc5625bd324..95d6dfa9fff 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -86,15 +86,7 @@ Boston, MA 02110-1301, USA. */
86#include "intervals.h" 86#include "intervals.h"
87#include "atimer.h" 87#include "atimer.h"
88#include "keymap.h" 88#include "keymap.h"
89 89
90/* Set of macros that handle mapping of Mac modifier keys to emacs. */
91#define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
92 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
93#define macShiftKey (shiftKey)
94#define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
95 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
96 : controlKey)
97#define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
98 90
99 91
100/* Non-nil means Emacs uses toolkit scroll bars. */ 92/* Non-nil means Emacs uses toolkit scroll bars. */
@@ -207,7 +199,8 @@ extern EMACS_INT extra_keyboard_modifiers;
207 199
208/* The keysyms to use for the various modifiers. */ 200/* The keysyms to use for the various modifiers. */
209 201
210static Lisp_Object Qalt, Qhyper, Qsuper, Qmodifier_value; 202static Lisp_Object Qalt, Qhyper, Qsuper, Qctrl,
203 Qmeta, Qmodifier_value;
211 204
212extern int inhibit_window_system; 205extern int inhibit_window_system;
213 206
@@ -7920,14 +7913,18 @@ x_find_ccl_program (fontp)
7920/* Contains the string "reverse", which is a constant for mouse button emu.*/ 7913/* Contains the string "reverse", which is a constant for mouse button emu.*/
7921Lisp_Object Qreverse; 7914Lisp_Object Qreverse;
7922 7915
7923/* True if using command key as meta key. */
7924Lisp_Object Vmac_command_key_is_meta;
7925 7916
7926/* Modifier associated with the option key, or nil for normal behavior. */ 7917/* Modifier associated with the control key, or nil to ignore. */
7918Lisp_Object Vmac_control_modifier;
7919
7920/* Modifier associated with the option key, or nil to ignore. */
7927Lisp_Object Vmac_option_modifier; 7921Lisp_Object Vmac_option_modifier;
7928 7922
7929/* True if the ctrl and meta keys should be reversed. */ 7923/* Modifier associated with the command key, or nil to ignore. */
7930Lisp_Object Vmac_reverse_ctrl_meta; 7924Lisp_Object Vmac_command_modifier;
7925
7926/* Modifier associated with the function key, or nil to ignore. */
7927Lisp_Object Vmac_function_modifier;
7931 7928
7932/* True if the option and command modifiers should be used to emulate 7929/* True if the option and command modifiers should be used to emulate
7933 a three button mouse */ 7930 a three button mouse */
@@ -8001,20 +7998,44 @@ mac_to_emacs_modifiers (EventModifiers mods)
8001#endif 7998#endif
8002{ 7999{
8003 unsigned int result = 0; 8000 unsigned int result = 0;
8004 if (mods & macShiftKey) 8001 if (mods & shiftKey)
8005 result |= shift_modifier; 8002 result |= shift_modifier;
8006 if (mods & macCtrlKey) 8003
8007 result |= ctrl_modifier; 8004
8008 if (mods & macMetaKey) 8005
8009 result |= meta_modifier; 8006 /* Deactivated to simplify configuration:
8010 if (NILP (Vmac_command_key_is_meta) && (mods & macAltKey)) 8007 if Vmac_option_modifier is non-NIL, we fully process the Option
8011 result |= alt_modifier; 8008 key. Otherwise, we only process it if an additional Ctrl or Command
8009 is pressed. That way the system may convert the character to a
8010 composed one.
8011 if ((mods & optionKey) &&
8012 (( !NILP(Vmac_option_modifier) ||
8013 ((mods & cmdKey) || (mods & controlKey))))) */
8014
8012 if (!NILP (Vmac_option_modifier) && (mods & optionKey)) { 8015 if (!NILP (Vmac_option_modifier) && (mods & optionKey)) {
8013 Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value); 8016 Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value);
8014 if (!NILP(val)) 8017 if (INTEGERP(val))
8015 result |= XUINT(val); 8018 result |= XUINT(val);
8016 } 8019 }
8020 if (!NILP (Vmac_command_modifier) && (mods & cmdKey)) {
8021 Lisp_Object val = Fget(Vmac_command_modifier, Qmodifier_value);
8022 if (INTEGERP(val))
8023 result |= XUINT(val);
8024 }
8025 if (!NILP (Vmac_control_modifier) && (mods & controlKey)) {
8026 Lisp_Object val = Fget(Vmac_control_modifier, Qmodifier_value);
8027 if (INTEGERP(val))
8028 result |= XUINT(val);
8029 }
8017 8030
8031#ifdef MAC_OSX
8032 if (!NILP (Vmac_function_modifier) && (mods & kEventKeyModifierFnMask)) {
8033 Lisp_Object val = Fget(Vmac_function_modifier, Qmodifier_value);
8034 if (INTEGERP(val))
8035 result |= XUINT(val);
8036 }
8037#endif
8038
8018 return result; 8039 return result;
8019} 8040}
8020 8041
@@ -8035,7 +8056,7 @@ mac_get_emulated_btn ( UInt32 modifiers )
8035#if USE_CARBON_EVENTS 8056#if USE_CARBON_EVENTS
8036/* Obtains the event modifiers from the event ref and then calls 8057/* Obtains the event modifiers from the event ref and then calls
8037 mac_to_emacs_modifiers. */ 8058 mac_to_emacs_modifiers. */
8038static int 8059static UInt32
8039mac_event_to_emacs_modifiers (EventRef eventRef) 8060mac_event_to_emacs_modifiers (EventRef eventRef)
8040{ 8061{
8041 UInt32 mods = 0; 8062 UInt32 mods = 0;
@@ -9385,13 +9406,129 @@ static unsigned char keycode_to_xkeysym_table[] = {
9385 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0 9406 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
9386}; 9407};
9387 9408
9388static int 9409
9410static int
9389keycode_to_xkeysym (int keyCode, int *xKeySym) 9411keycode_to_xkeysym (int keyCode, int *xKeySym)
9390{ 9412{
9391 *xKeySym = keycode_to_xkeysym_table [keyCode & 0x7f]; 9413 *xKeySym = keycode_to_xkeysym_table [keyCode & 0x7f];
9392 return *xKeySym != 0; 9414 return *xKeySym != 0;
9393} 9415}
9394 9416
9417static unsigned char fn_keycode_to_xkeysym_table[] = {
9418 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9419 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9420 /*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9421
9422 /*0x30*/ 0, 0, 0, 0,
9423 /*0x34*/ 0, 0, 0, 0,
9424 /*0x38*/ 0, 0, 0, 0,
9425 /*0x3C*/ 0, 0, 0, 0,
9426
9427 /*0x40*/ 0, 0x2e /*kp-. = .*/, 0, 0x50 /*kp-* = 'p'*/,
9428 /*0x44*/ 0, '/' /*kp-+*/, 0, 0,
9429 /*0x48*/ 0, 0, 0, 0x30 /*kp-/ = '0'*/,
9430 /*0x4C*/ 0, 0, 0x3b /*kp-- = ';'*/, 0,
9431
9432 /*0x50*/ 0, 0x2d /*kp-= = '-'*/, 0x6d /*kp-0 = 'm'*/, 0x6a /*kp-1 = 'j'*/,
9433 /*0x54*/ 0x6b /*kp-2 = 'k'*/, 0x6c /*kp-3 = 'l'*/, 'u' /*kp-4*/, 'i' /*kp-5*/,
9434 /*0x58*/ 'o' /*kp-6*/, '7' /*kp-7*/, 0, '8' /*kp-8*/,
9435 /*0x5C*/ '9' /*kp-9*/, 0, 0, 0,
9436
9437 /*0x60*/ 0, 0, 0, 0,
9438 /*0x64*/ 0, 0, 0, 0,
9439 /*0x68*/ 0, 0, 0, 0,
9440 /*0x6C*/ 0, 0, 0, 0,
9441
9442 /*0x70*/ 0, 0, 0, 0,
9443 /*0x74*/ 0, 0, 0, 0,
9444 /*0x78*/ 0, 0, 0, 0,
9445 /*0x7C*/ 0, 0, 0, 0
9446};
9447static int
9448convert_fn_keycode (EventRef eventRef, int keyCode, int *newCode)
9449{
9450#ifdef MAC_OSX
9451 /* Use the special map to translate keys when function modifier is
9452 to be caught. KeyTranslate can't be used in that case.
9453 We can't detect the function key using the input_event.modifiers,
9454 because this uses the high word of an UInt32. Therefore,
9455 we'll just read it out of the original eventRef.
9456 */
9457
9458
9459 /* TODO / known issues
9460
9461 - Fn-Shift-j is regonized as Fn-j and not Fn-J.
9462 The above table always translates to lower characters. We need to use
9463 the KCHR keyboard resource (KeyTranslate() ) to map k->K and 8->*.
9464
9465 - The table is meant for English language keyboards, and it will work
9466 for many others with the exception of key combinations like Fn-ö on
9467 a German keyboard, which is currently mapped to Fn-;.
9468 How to solve this without keeping separate tables for all keyboards
9469 around? KeyTranslate isn't of much help here, as it only takes a 16-bit
9470 value for keycode with the modifiers in he high byte, i.e. no room for the
9471 Fn modifier. That's why we need the table.
9472
9473 */
9474
9475 UInt32 mods = 0;
9476 if (!NILP(Vmac_function_modifier))
9477 {
9478 GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
9479 sizeof (UInt32), NULL, &mods);
9480 if (mods & kEventKeyModifierFnMask)
9481 { *newCode = fn_keycode_to_xkeysym_table [keyCode & 0x7f];
9482
9483 return (*newCode != 0);
9484 }
9485 }
9486#endif
9487 return false;
9488}
9489
9490static int
9491backtranslate_modified_keycode(int mods, int keycode, int def)
9492{
9493 if (mods &
9494 (controlKey |
9495 (NILP (Vmac_option_modifier) ? 0 : optionKey) |
9496 cmdKey))
9497 {
9498 /* This code comes from Keyboard Resource,
9499 Appendix C of IM - Text. This is necessary
9500 since shift is ignored in KCHR table
9501 translation when option or command is pressed.
9502 It also does not translate correctly
9503 control-shift chars like C-% so mask off shift
9504 here also.
9505
9506 Not done for combinations with the option key (alt)
9507 unless it is to be caught by Emacs: this is
9508 to preserve key combinations translated by the OS
9509 such as Alt-3.
9510 */
9511 /* mask off option and command */
9512 int new_modifiers = mods & 0xe600;
9513 /* set high byte of keycode to modifier high byte*/
9514 int new_keycode = keycode | new_modifiers;
9515 Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
9516 unsigned long some_state = 0;
9517 return (int) KeyTranslate (kchr_ptr, new_keycode,
9518 &some_state) & 0xff;
9519 /* TO DO: Recognize two separate resulting characters, "for
9520 example, when the user presses Option-E followed by N, you
9521 can map this through the KeyTranslate function using the
9522 U.S. 'KCHR' resource to produce ´n, which KeyTranslate
9523 returns as two characters in the bytes labeled Character code
9524 1 and Character code 2." (from Carbon API doc) */
9525
9526 }
9527 else
9528 return def;
9529}
9530
9531
9395#if !USE_CARBON_EVENTS 9532#if !USE_CARBON_EVENTS
9396static RgnHandle mouse_region = NULL; 9533static RgnHandle mouse_region = NULL;
9397 9534
@@ -9936,8 +10073,7 @@ XTread_socket (sd, expected, hold_quit)
9936 || !(er.modifiers & cmdKey)) 10073 || !(er.modifiers & cmdKey))
9937 && (!NILP (Vmac_pass_control_to_system) 10074 && (!NILP (Vmac_pass_control_to_system)
9938 || !(er.modifiers & controlKey)) 10075 || !(er.modifiers & controlKey))
9939 && (!NILP (Vmac_command_key_is_meta) 10076 && (NILP (Vmac_option_modifier)
9940 && NILP (Vmac_option_modifier)
9941 || !(er.modifiers & optionKey))) 10077 || !(er.modifiers & optionKey)))
9942 if (SendEventToEventTarget (eventRef, toolbox_dispatcher) 10078 if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
9943 != eventNotHandledErr) 10079 != eventNotHandledErr)
@@ -9981,49 +10117,36 @@ XTread_socket (sd, expected, hold_quit)
9981 dpyinfo->mouse_face_hidden = 1; 10117 dpyinfo->mouse_face_hidden = 1;
9982 } 10118 }
9983 10119
9984 if (keycode_to_xkeysym (keycode, &xkeysym)) 10120 /* translate the keycode back to determine the original key */
9985 { 10121 /* Convert key code if function key is pressed.
9986 inev.code = 0xff00 | xkeysym; 10122 Otherwise, if non-ASCII-event, take care of that
9987 inev.kind = NON_ASCII_KEYSTROKE_EVENT; 10123 without re-translating the key code. */
9988 } 10124#if USE_CARBON_EVENTS
9989 else 10125 if (convert_fn_keycode (eventRef, keycode, &xkeysym))
9990 { 10126 {
9991 if (er.modifiers & (controlKey | 10127 inev.code = xkeysym;
9992 (NILP (Vmac_command_key_is_meta) ? optionKey 10128 /* this doesn't work - tried to add shift modifiers */
9993 : cmdKey))) 10129 inev.code =
9994 { 10130 backtranslate_modified_keycode(er.modifiers & (~0x2200),
9995 /* This code comes from Keyboard Resource, 10131 xkeysym | 0x80, xkeysym);
9996 Appendix C of IM - Text. This is necessary
9997 since shift is ignored in KCHR table
9998 translation when option or command is pressed.
9999 It also does not translate correctly
10000 control-shift chars like C-% so mask off shift
10001 here also */
10002 int new_modifiers = er.modifiers & 0xe600;
10003 /* mask off option and command */
10004 int new_keycode = keycode | new_modifiers;
10005 Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
10006 unsigned long some_state = 0;
10007 inev.code = KeyTranslate (kchr_ptr, new_keycode,
10008 &some_state) & 0xff;
10009 }
10010 else if (!NILP (Vmac_option_modifier)
10011 && (er.modifiers & optionKey))
10012 {
10013 /* When using the option key as an emacs modifier,
10014 convert the pressed key code back to one
10015 without the Mac option modifier applied. */
10016 int new_modifiers = er.modifiers & ~optionKey;
10017 int new_keycode = keycode | new_modifiers;
10018 Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
10019 unsigned long some_state = 0;
10020 inev.code = KeyTranslate (kchr_ptr, new_keycode,
10021 &some_state) & 0xff;
10022 }
10023 else
10024 inev.code = er.message & charCodeMask;
10025 inev.kind = ASCII_KEYSTROKE_EVENT; 10132 inev.kind = ASCII_KEYSTROKE_EVENT;
10026 } 10133 }
10134 else
10135#endif
10136 if (keycode_to_xkeysym (keycode, &xkeysym))
10137 {
10138 inev.code = 0xff00 | xkeysym;
10139 inev.kind = NON_ASCII_KEYSTROKE_EVENT;
10140 }
10141 else
10142 {
10143
10144 inev.code =
10145 backtranslate_modified_keycode(er.modifiers, keycode,
10146 er.message & charCodeMask);
10147 inev.kind = ASCII_KEYSTROKE_EVENT;
10148
10149 }
10027 } 10150 }
10028 10151
10029#if USE_CARBON_EVENTS 10152#if USE_CARBON_EVENTS
@@ -10463,10 +10586,9 @@ mac_determine_quit_char_modifiers()
10463 10586
10464 /* Map modifiers */ 10587 /* Map modifiers */
10465 mac_quit_char_modifiers = 0; 10588 mac_quit_char_modifiers = 0;
10466 if (qc_modifiers & ctrl_modifier) mac_quit_char_modifiers |= macCtrlKey; 10589 if (qc_modifiers & ctrl_modifier) mac_quit_char_modifiers |= controlKey;
10467 if (qc_modifiers & shift_modifier) mac_quit_char_modifiers |= macShiftKey; 10590 if (qc_modifiers & shift_modifier) mac_quit_char_modifiers |= shiftKey;
10468 if (qc_modifiers & meta_modifier) mac_quit_char_modifiers |= macMetaKey; 10591 if (qc_modifiers & alt_modifier) mac_quit_char_modifiers |= optionKey;
10469 if (qc_modifiers & alt_modifier) mac_quit_char_modifiers |= macAltKey;
10470} 10592}
10471 10593
10472static void 10594static void
@@ -10623,6 +10745,10 @@ syms_of_macterm ()
10623#endif 10745#endif
10624 10746
10625 Qmodifier_value = intern ("modifier-value"); 10747 Qmodifier_value = intern ("modifier-value");
10748 Qctrl = intern ("ctrl");
10749 Fput (Qctrl, Qmodifier_value, make_number (ctrl_modifier));
10750 Qmeta = intern ("meta");
10751 Fput (Qmeta, Qmodifier_value, make_number (meta_modifier));
10626 Qalt = intern ("alt"); 10752 Qalt = intern ("alt");
10627 Fput (Qalt, Qmodifier_value, make_number (alt_modifier)); 10753 Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
10628 Qhyper = intern ("hyper"); 10754 Qhyper = intern ("hyper");
@@ -10674,22 +10800,37 @@ syms_of_macterm ()
10674 10800
10675 staticpro (&last_mouse_motion_frame); 10801 staticpro (&last_mouse_motion_frame);
10676 last_mouse_motion_frame = Qnil; 10802 last_mouse_motion_frame = Qnil;
10803
10804
10677 10805
10678 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta, 10806/* Variables to configure modifier key assignment. */
10679 doc: /* Non-nil means that the command key is used as the Emacs meta key. 10807
10680Otherwise the option key is used. */); 10808 DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier,
10681 Vmac_command_key_is_meta = Qt; 10809 doc: /* Modifier key assumed when the Mac control key is pressed.
10810The value can be `alt', `ctrl', `hyper', or `super' for the respective
10811modifier. The default is `ctrl'. */);
10812 Vmac_control_modifier = Qctrl;
10682 10813
10683 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier, 10814 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier,
10684 doc: /* Modifier to use for the Mac alt/option key. The value can 10815 doc: /* Modifier key assumed when the Mac alt/option key is pressed.
10685be alt, hyper, or super for the respective modifier. If the value is 10816The value can be `alt', `ctrl', `hyper', or `super' for the respective
10686nil then the key will act as the normal Mac option modifier. */); 10817modifier. If the value is nil then the key will act as the normal
10818Mac control modifier, and the option key can be used to compose
10819characters depending on the chosen Mac keyboard setting. */);
10687 Vmac_option_modifier = Qnil; 10820 Vmac_option_modifier = Qnil;
10688 10821
10689 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta, 10822 DEFVAR_LISP ("mac-command-modifier", &Vmac_command_modifier,
10690 doc: /* Non-nil means that the control and meta keys are reversed. This is 10823 doc: /* Modifier key assumed when the Mac command key is pressed.
10691useful for non-standard keyboard layouts. */); 10824The value can be `alt', `ctrl', `hyper', or `super' for the respective
10692 Vmac_reverse_ctrl_meta = Qnil; 10825modifier. The default is `meta'. */);
10826 Vmac_command_modifier = Qmeta;
10827
10828 DEFVAR_LISP ("mac-function-modifier", &Vmac_function_modifier,
10829 doc: /* Modifier key assumed when the Mac function key is pressed.
10830The value can be `alt', `ctrl', `hyper', or `super' for the respective
10831modifier. Note that remapping the function key may lead to unexpected
10832results for some keys on non-US/GB keyboards. */);
10833 Vmac_function_modifier = Qnil;
10693 10834
10694 DEFVAR_LISP ("mac-emulate-three-button-mouse", 10835 DEFVAR_LISP ("mac-emulate-three-button-mouse",
10695 &Vmac_emulate_three_button_mouse, 10836 &Vmac_emulate_three_button_mouse,