aboutsummaryrefslogtreecommitdiffstats
path: root/src/macterm.c
diff options
context:
space:
mode:
authorSteven Tamm <[email protected]>2005-11-11 16:33:44 +0000
committerSteven Tamm <[email protected]>2005-11-11 16:33:44 +0000
commitb02e3f7ba66a48d30c8ebd5be03ff75c156564b0 (patch)
tree0496bdae8604b899bf9608449338e250996dca1a /src/macterm.c
parent338fa84a5ec5c280b7bbd19d1cac7b1268579789 (diff)
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 cc5625bd32..95d6dfa9ff 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -86,15 +86,7 @@ Boston, MA 02110-1301, USA. */
#include "intervals.h"
#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)
+
/* Non-nil means Emacs uses toolkit scroll bars. */
@@ -207,7 +199,8 @@ extern EMACS_INT extra_keyboard_modifiers;
/* The keysyms to use for the various modifiers. */
-static Lisp_Object Qalt, Qhyper, Qsuper, Qmodifier_value;
+static Lisp_Object Qalt, Qhyper, Qsuper, Qctrl,
+ Qmeta, Qmodifier_value;
extern int inhibit_window_system;
@@ -7920,14 +7913,18 @@ x_find_ccl_program (fontp)
/* 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. */
+/* Modifier associated with the control key, or nil to ignore. */
+Lisp_Object Vmac_control_modifier;
+
+/* Modifier associated with the option key, or nil to ignore. */
Lisp_Object Vmac_option_modifier;
-/* True if the ctrl and meta keys should be reversed. */
-Lisp_Object Vmac_reverse_ctrl_meta;
+/* Modifier associated with the command key, or nil to ignore. */
+Lisp_Object Vmac_command_modifier;
+
+/* Modifier associated with the function key, or nil to ignore. */
+Lisp_Object Vmac_function_modifier;
/* True if the option and command modifiers should be used to emulate
a three button mouse */
@@ -8001,20 +7998,44 @@ mac_to_emacs_modifiers (EventModifiers mods)
#endif
{
unsigned int result = 0;
- if (mods & macShiftKey)
+ if (mods & shiftKey)
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;
+
+
+
+ /* Deactivated to simplify configuration:
+ if Vmac_option_modifier is non-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_option_modifier) ||
+ ((mods & cmdKey) || (mods & controlKey))))) */
+
if (!NILP (Vmac_option_modifier) && (mods & optionKey)) {
- Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value);
- if (!NILP(val))
- result |= XUINT(val);
+ Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value);
+ if (INTEGERP(val))
+ result |= XUINT(val);
}
+ if (!NILP (Vmac_command_modifier) && (mods & cmdKey)) {
+ Lisp_Object val = Fget(Vmac_command_modifier, Qmodifier_value);
+ if (INTEGERP(val))
+ result |= XUINT(val);
+ }
+ if (!NILP (Vmac_control_modifier) && (mods & controlKey)) {
+ Lisp_Object val = Fget(Vmac_control_modifier, Qmodifier_value);
+ if (INTEGERP(val))
+ result |= XUINT(val);
+ }
+#ifdef MAC_OSX
+ if (!NILP (Vmac_function_modifier) && (mods & kEventKeyModifierFnMask)) {
+ Lisp_Object val = Fget(Vmac_function_modifier, Qmodifier_value);
+ if (INTEGERP(val))
+ result |= XUINT(val);
+ }
+#endif
+
return result;
}
@@ -8035,7 +8056,7 @@ mac_get_emulated_btn ( UInt32 modifiers )
#if USE_CARBON_EVENTS
/* Obtains the event modifiers from the event ref and then calls
mac_to_emacs_modifiers. */
-static int
+static UInt32
mac_event_to_emacs_modifiers (EventRef eventRef)
{
UInt32 mods = 0;
@@ -9385,13 +9406,129 @@ static unsigned char keycode_to_xkeysym_table[] = {
/*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
};
-static int
+
+static int
keycode_to_xkeysym (int keyCode, int *xKeySym)
{
*xKeySym = keycode_to_xkeysym_table [keyCode & 0x7f];
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,
+
+ /*0x30*/ 0, 0, 0, 0,
+ /*0x34*/ 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,
+
+ /*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
+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.
+
+ */
+
+ UInt32 mods = 0;
+ if (!NILP(Vmac_function_modifier))
+ {
+ GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, NULL,
+ sizeof (UInt32), NULL, &mods);
+ if (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)
+{
+ if (mods &
+ (controlKey |
+ (NILP (Vmac_option_modifier) ? 0 : optionKey) |
+ cmdKey))
+ {
+ /* 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 option and command */
+ int new_modifiers = mods & 0xe600;
+ /* 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;
@@ -9936,8 +10073,7 @@ XTread_socket (sd, expected, hold_quit)
|| !(er.modifiers & cmdKey))
&& (!NILP (Vmac_pass_control_to_system)
|| !(er.modifiers & controlKey))
- && (!NILP (Vmac_command_key_is_meta)
- && NILP (Vmac_option_modifier)
+ && (NILP (Vmac_option_modifier)
|| !(er.modifiers & optionKey)))
if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
!= eventNotHandledErr)
@@ -9981,49 +10117,36 @@ XTread_socket (sd, expected, hold_quit)
dpyinfo->mouse_face_hidden = 1;
}
- if (keycode_to_xkeysym (keycode, &xkeysym))
- {
- inev.code = 0xff00 | xkeysym;
- inev.kind = NON_ASCII_KEYSTROKE_EVENT;
- }
- else
+ /* 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))
{
- 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
- 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 */
- int new_modifiers = er.modifiers & 0xe600;
- /* mask off option and command */
- 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 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.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
@@ -10463,10 +10586,9 @@ mac_determine_quit_char_modifiers()
/* Map modifiers */
mac_quit_char_modifiers = 0;
- if (qc_modifiers & ctrl_modifier) mac_quit_char_modifiers |= macCtrlKey;
- if (qc_modifiers & shift_modifier) mac_quit_char_modifiers |= macShiftKey;
- if (qc_modifiers & meta_modifier) mac_quit_char_modifiers |= macMetaKey;
- if (qc_modifiers & alt_modifier) mac_quit_char_modifiers |= macAltKey;
+ if (qc_modifiers & ctrl_modifier) mac_quit_char_modifiers |= controlKey;
+ if (qc_modifiers & shift_modifier) mac_quit_char_modifiers |= shiftKey;
+ if (qc_modifiers & alt_modifier) mac_quit_char_modifiers |= optionKey;
}
static void
@@ -10623,6 +10745,10 @@ syms_of_macterm ()
#endif
Qmodifier_value = intern ("modifier-value");
+ Qctrl = intern ("ctrl");
+ Fput (Qctrl, Qmodifier_value, make_number (ctrl_modifier));
+ Qmeta = intern ("meta");
+ Fput (Qmeta, Qmodifier_value, make_number (meta_modifier));
Qalt = intern ("alt");
Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
Qhyper = intern ("hyper");
@@ -10674,22 +10800,37 @@ syms_of_macterm ()
staticpro (&last_mouse_motion_frame);
last_mouse_motion_frame = Qnil;
+
+
- 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;
+/* Variables to configure modifier key assignment. */
+
+ DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier,
+ doc: /* Modifier key assumed when the Mac control key is pressed.
+The value can be `alt', `ctrl', `hyper', or `super' for the respective
+modifier. The default is `ctrl'. */);
+ Vmac_control_modifier = Qctrl;
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. */);
+ doc: /* Modifier key assumed when the Mac alt/option key is pressed.
+The value can be `alt', `ctrl', `hyper', or `super' for the respective
+modifier. If the value is nil then the key will act as the normal
+Mac control modifier, and the option key can be used to compose
+characters depending on the chosen Mac keyboard setting. */);
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-command-modifier", &Vmac_command_modifier,
+ doc: /* Modifier key assumed when the Mac command key is pressed.
+The value can be `alt', `ctrl', `hyper', or `super' for the respective
+modifier. The default is `meta'. */);
+ Vmac_command_modifier = Qmeta;
+
+ DEFVAR_LISP ("mac-function-modifier", &Vmac_function_modifier,
+ doc: /* Modifier key assumed when the Mac function key is pressed.
+The value can be `alt', `ctrl', `hyper', or `super' for the respective
+modifier. Note that remapping the function key may lead to unexpected
+results for some keys on non-US/GB keyboards. */);
+ Vmac_function_modifier = Qnil;
DEFVAR_LISP ("mac-emulate-three-button-mouse",
&Vmac_emulate_three_button_mouse,