Commit b02e3f7b authored by Steven Tamm's avatar Steven Tamm
Browse files

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.
parent 338fa84a
2005-11-11 David Reitter <david.reitter@gmail.com>
* 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.
2005-11-11 Kim F. Storm <storm@cua.dk>
 
* .gdbinit (pitx): Fix output format if n_overlay_strings > 0.
......
......@@ -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,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment