76 |
static char _alt_pressed = 0; |
static char _alt_pressed = 0; |
77 |
/* |
/* |
78 |
Keys used for the modifiers (you may set them with user preferences). |
Keys used for the modifiers (you may set them with user preferences). |
79 |
Note that the first and second key code for a modifier must be different. |
Note that the first and second key sym for a modifier must be different. |
80 |
Otherwise, the _*_pressed tracking will be confused. |
Otherwise, the _*_pressed tracking will be confused. |
81 |
*/ |
*/ |
82 |
static KeyCode _control_keycodes[2]; |
static KeySym _control_keysyms[2]; |
83 |
static KeyCode _command_keycodes[2]; |
static KeySym _command_keysyms[2]; |
84 |
static KeyCode _alt_keycodes[2]; |
static KeySym _alt_keysyms[2]; |
85 |
|
|
86 |
static BOOL _is_keyboard_initialized = NO; |
static BOOL _is_keyboard_initialized = NO; |
87 |
|
|
127 |
|
|
128 |
static void set_up_num_lock (void); |
static void set_up_num_lock (void); |
129 |
|
|
130 |
static inline int check_modifier (XEvent *xEvent, KeyCode key_code) |
// checks if given keycode is set in bit vector |
131 |
|
static inline int check_key (XEvent *xEvent, KeyCode key_code) |
132 |
{ |
{ |
133 |
return (xEvent->xkeymap.key_vector[key_code / 8] & (1 << (key_code % 8))); |
return (key_code == 0) ? |
134 |
|
0 : (xEvent->xkeymap.key_vector[key_code / 8] & (1 << (key_code % 8))); |
135 |
|
} |
136 |
|
|
137 |
|
// checks whether a GNUstep modifier is pressed when we're only able to check |
138 |
|
// whether X keycodes are pressed |
139 |
|
static int check_modifier (XEvent *xEvent, KeySym key_sym, |
140 |
|
XModifierKeymap *modmap) |
141 |
|
{ |
142 |
|
int m; |
143 |
|
int c; |
144 |
|
KeyCode key_code; |
145 |
|
|
146 |
|
// if key_sym is a modifier, check each of its keycodes |
147 |
|
for (m=0; m<8; m++) |
148 |
|
{ |
149 |
|
key_code = modmap->modifiermap[m * modmap->max_keypermod]; |
150 |
|
if ((key_code != 0) |
151 |
|
&& XKeycodeToKeysym(xEvent->xkeymap.display, key_code, 0) == key_sym) |
152 |
|
{ |
153 |
|
for (c=0; c<modmap->max_keypermod; c++) |
154 |
|
{ |
155 |
|
if (check_key(xEvent, |
156 |
|
modmap->modifiermap[m * modmap->max_keypermod + c])) |
157 |
|
return 1; |
158 |
|
} |
159 |
|
return 0; // no dice |
160 |
|
} |
161 |
|
} |
162 |
|
// wasn't a modifier; just check the first keycode for this keysym, |
163 |
|
// which ignores other possibilities but that's the best we can do |
164 |
|
// w/o XtKeysymToKeycodeList |
165 |
|
return check_key(xEvent, XKeysymToKeycode(xEvent->xkeymap.display, key_sym)); |
166 |
} |
} |
167 |
|
|
168 |
@implementation XGServer (EventOps) |
@implementation XGServer (EventOps) |
1009 |
// reports the state of the keyboard when pointer or |
// reports the state of the keyboard when pointer or |
1010 |
// focus enters a window |
// focus enters a window |
1011 |
case KeymapNotify: |
case KeymapNotify: |
1012 |
NSDebugLLog(@"NSEvent", @"%d KeymapNotify\n", |
{ |
1013 |
xEvent.xkeymap.window); |
XModifierKeymap *modmap = |
1014 |
// Check if control is pressed |
XGetModifierMapping(xEvent.xkeymap.display); |
1015 |
_control_pressed = 0; |
|
1016 |
if (_control_keycodes[0] |
if (_is_keyboard_initialized == NO) |
1017 |
&& check_modifier (&xEvent, _control_keycodes[0])) |
initialize_keyboard (); |
1018 |
{ |
|
1019 |
_control_pressed |= 1; |
NSDebugLLog(@"NSEvent", @"%d KeymapNotify\n", |
1020 |
} |
xEvent.xkeymap.window); |
1021 |
if (_control_keycodes[1] |
|
1022 |
&& check_modifier (&xEvent, _control_keycodes[1])) |
// Check if control is pressed |
1023 |
{ |
_control_pressed = 0; |
1024 |
_control_pressed |= 2; |
if ((_control_keysyms[0] != NoSymbol) |
1025 |
} |
&& check_modifier (&xEvent, _control_keysyms[0], modmap)) |
1026 |
// Check if command is pressed |
{ |
1027 |
_command_pressed = 0; |
_control_pressed |= 1; |
1028 |
if (_command_keycodes[0] |
} |
1029 |
&& check_modifier (&xEvent, _command_keycodes[0])) |
if ((_control_keysyms[1] != NoSymbol) |
1030 |
{ |
&& check_modifier (&xEvent, _control_keysyms[1], modmap)) |
1031 |
_command_pressed |= 1; |
{ |
1032 |
} |
_control_pressed |= 2; |
1033 |
if (_command_keycodes[1] |
} |
1034 |
&& check_modifier (&xEvent, _command_keycodes[1])) |
|
1035 |
{ |
// Check if command is pressed |
1036 |
_command_pressed |= 2; |
_command_pressed = 0; |
1037 |
} |
if ((_command_keysyms[0] != NoSymbol) |
1038 |
// Check if alt is pressed |
&& check_modifier (&xEvent, _command_keysyms[0], modmap)) |
1039 |
_alt_pressed = 0; |
{ |
1040 |
if (_alt_keycodes[0] |
_command_pressed |= 1; |
1041 |
&& check_modifier (&xEvent, _alt_keycodes[0])) |
} |
1042 |
{ |
if ((_command_keysyms[1] != NoSymbol) |
1043 |
_alt_pressed |= 1; |
&& check_modifier (&xEvent, _command_keysyms[1], modmap)) |
1044 |
} |
{ |
1045 |
if (_alt_keycodes[1] |
_command_pressed |= 2; |
1046 |
&& check_modifier (&xEvent, _alt_keycodes[1])) |
} |
1047 |
{ |
|
1048 |
_alt_pressed |= 2; |
// Check if alt is pressed |
1049 |
} |
_alt_pressed = 0; |
1050 |
|
if ((_alt_keysyms[0] != NoSymbol) |
1051 |
|
&& check_modifier (&xEvent, _alt_keysyms[0], modmap)) |
1052 |
|
{ |
1053 |
|
_alt_pressed |= 1; |
1054 |
|
} |
1055 |
|
if ((_alt_keysyms[1] != NoSymbol) |
1056 |
|
&& check_modifier (&xEvent, _alt_keysyms[1], modmap)) |
1057 |
|
{ |
1058 |
|
_alt_pressed |= 2; |
1059 |
|
} |
1060 |
|
XFreeModifiermap(modmap); |
1061 |
|
} |
1062 |
break; |
break; |
1063 |
|
|
1064 |
// when a window changes state from ummapped to |
// when a window changes state from ummapped to |
1395 |
} |
} |
1396 |
|
|
1397 |
|
|
1398 |
// Return the key_code corresponding to the user defaults string |
// Return the key_sym corresponding to the user defaults string given, |
1399 |
// Return 1 (which is an invalid keycode) if the user default |
// or fallback if no default is registered. |
1400 |
// is not set |
static KeySym |
1401 |
static KeyCode |
key_sym_from_defaults (Display *display, NSUserDefaults *defaults, |
1402 |
default_key_code (Display *display, NSUserDefaults *defaults, |
NSString *keyDefaultKey, KeySym fallback) |
|
NSString *aString) |
|
1403 |
{ |
{ |
1404 |
NSString *keySymString; |
NSString *keyDefaultName; |
1405 |
KeySym a_key_sym; |
KeySym key_sym; |
1406 |
|
|
1407 |
keySymString = [defaults stringForKey: aString]; |
keyDefaultName = [defaults stringForKey: keyDefaultKey]; |
1408 |
if (keySymString == nil) |
if (keyDefaultName == nil) |
1409 |
return 1; |
return fallback; |
1410 |
|
|
1411 |
a_key_sym = XStringToKeysym ([keySymString cString]); |
key_sym = XStringToKeysym ([keyDefaultName cString]); |
1412 |
if (a_key_sym == NoSymbol) |
if (key_sym == NoSymbol) |
1413 |
{ |
{ |
1414 |
// This is not necessarily an error. |
// This is not necessarily an error. |
1415 |
// If you want on purpose to disable a key, |
// If you want on purpose to disable a key, |
1416 |
// set its default to 'NoSymbol'. |
// set its default to 'NoSymbol'. |
1417 |
NSLog (@"KeySym %@ not found; disabling %@", keySymString, aString); |
NSLog (@"KeySym %@ not found; disabling %@", keyDefaultName, |
1418 |
return 0; |
keyDefaultKey); |
1419 |
} |
} |
1420 |
|
|
1421 |
return XKeysymToKeycode (display, a_key_sym); |
return key_sym; |
1422 |
} |
} |
1423 |
|
|
1424 |
// This function should be called before any keyboard event is dealed with. |
// This function should be called before any keyboard event is dealed with. |
1428 |
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; |
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; |
1429 |
Display *display = [XGServer currentXDisplay]; |
Display *display = [XGServer currentXDisplay]; |
1430 |
|
|
1431 |
|
// Below must be stored and checked as keysyms, not keycodes, since |
1432 |
|
// more than one keycode may be mapped t the same keysym |
1433 |
// Initialize Control |
// Initialize Control |
1434 |
_control_keycodes[0] = default_key_code (display, defaults, |
_control_keysyms[0] = key_sym_from_defaults(display, defaults, |
1435 |
@"GSFirstControlKey"); |
@"GSFirstControlKey", |
1436 |
if (_control_keycodes[0] == 1) // No User Default Set |
XK_Control_L); |
1437 |
_control_keycodes[0] = XKeysymToKeycode (display, XK_Control_L); |
|
1438 |
|
_control_keysyms[1] = key_sym_from_defaults(display, defaults, |
1439 |
_control_keycodes[1] = default_key_code (display, defaults, |
@"GSSecondControlKey", |
1440 |
@"GSSecondControlKey"); |
XK_Control_R); |
|
if (_control_keycodes[1] == 1) |
|
|
_control_keycodes[1] = XKeysymToKeycode (display, XK_Control_R); |
|
1441 |
|
|
1442 |
if (_control_keycodes[0] == _control_keycodes[1]) |
if (_control_keysyms[0] == _control_keysyms[1]) |
1443 |
_control_keycodes[1] = 0; |
_control_keysyms[1] = NoSymbol; |
1444 |
|
|
1445 |
// Initialize Command |
// Initialize Command |
1446 |
_command_keycodes[0] = default_key_code (display, defaults, |
_command_keysyms[0] = key_sym_from_defaults(display, defaults, |
1447 |
@"GSFirstCommandKey"); |
@"GSFirstCommandKey", |
1448 |
if (_command_keycodes[0] == 1) |
XK_Alt_L); |
1449 |
_command_keycodes[0] = XKeysymToKeycode (display, XK_Alt_L); |
|
1450 |
|
_command_keysyms[1] = key_sym_from_defaults(display, defaults, |
1451 |
_command_keycodes[1] = default_key_code (display, defaults, |
@"GSSecondCommandKey", |
1452 |
@"GSSecondCommandKey"); |
NoSymbol); |
|
if (_command_keycodes[1] == 1) |
|
|
_command_keycodes[1] = 0; |
|
1453 |
|
|
1454 |
if (_command_keycodes[0] == _command_keycodes[1]) |
if (_command_keysyms[0] == _command_keysyms[1]) |
1455 |
_command_keycodes[1] = 0; |
_command_keysyms[1] = NoSymbol; |
1456 |
|
|
1457 |
// Initialize Alt |
// Initialize Alt |
1458 |
_alt_keycodes[0] = default_key_code (display, defaults, |
_alt_keysyms[0] = key_sym_from_defaults(display, defaults, |
1459 |
@"GSFirstAlternateKey"); |
@"GSFirstAlternateKey", |
1460 |
if (_alt_keycodes[0] == 1) |
XK_Alt_R); |
1461 |
{ |
if (XKeysymToKeycode(display, _alt_keysyms[0]) == 0) |
1462 |
_alt_keycodes[0] = XKeysymToKeycode (display, XK_Alt_R); |
_alt_keysyms[0] = XK_Mode_switch; |
1463 |
if (_alt_keycodes[0] == 0) |
|
1464 |
_alt_keycodes[0] = XKeysymToKeycode (display, XK_Mode_switch); |
_alt_keysyms[1] = key_sym_from_defaults(display, defaults, |
1465 |
} |
@"GSecondAlternateKey", |
1466 |
_alt_keycodes[1] = default_key_code (display, defaults, |
NoSymbol); |
|
@"GSSecondAlternateKey"); |
|
|
if (_alt_keycodes[1] == 1) |
|
|
_alt_keycodes[1] = 0; |
|
1467 |
|
|
1468 |
if (_alt_keycodes[0] == _alt_keycodes[1]) |
if (_alt_keysyms[0] == _alt_keysyms[1]) |
1469 |
_alt_keycodes[1] = 0; |
_alt_keysyms[1] = NoSymbol; |
1470 |
|
|
1471 |
|
|
1472 |
set_up_num_lock (); |
set_up_num_lock (); |
1557 |
/* Process NSFlagsChanged events. We can't use a switch because we |
/* Process NSFlagsChanged events. We can't use a switch because we |
1558 |
are not comparing to constants. Make sure keyCode is not 0 since |
are not comparing to constants. Make sure keyCode is not 0 since |
1559 |
XIM events can potentially return 0 keyCodes. */ |
XIM events can potentially return 0 keyCodes. */ |
1560 |
keyCode = ((XKeyEvent *)xEvent)->keycode; |
keysym = XLookupKeysym((XKeyEvent *)xEvent, 0); |
1561 |
if (keyCode) |
if (keysym != NoSymbol) |
1562 |
{ |
{ |
1563 |
if (keyCode == _control_keycodes[0]) |
if (keysym == _control_keysyms[0]) |
1564 |
{ |
{ |
1565 |
control_key = 1; |
control_key = 1; |
1566 |
} |
} |
1567 |
else if (keyCode == _control_keycodes[1]) |
else if (keysym == _control_keysyms[1]) |
1568 |
{ |
{ |
1569 |
control_key = 2; |
control_key = 2; |
1570 |
} |
} |
1571 |
else if (keyCode == _command_keycodes[0]) |
else if (keysym == _command_keysyms[0]) |
1572 |
{ |
{ |
1573 |
command_key = 1; |
command_key = 1; |
1574 |
} |
} |
1575 |
else if (keyCode == _command_keycodes[1]) |
else if (keysym == _command_keysyms[1]) |
1576 |
{ |
{ |
1577 |
command_key = 2; |
command_key = 2; |
1578 |
} |
} |
1579 |
else if (keyCode == _alt_keycodes[0]) |
else if (keysym == _alt_keysyms[0]) |
1580 |
{ |
{ |
1581 |
alt_key = 1; |
alt_key = 1; |
1582 |
} |
} |
1583 |
else if (keyCode == _alt_keycodes[1]) |
else if (keysym == _alt_keysyms[1]) |
1584 |
{ |
{ |
1585 |
alt_key = 2; |
alt_key = 2; |
1586 |
} |
} |
1631 |
keysym: &keysym]; |
keysym: &keysym]; |
1632 |
|
|
1633 |
/* Process keycode */ |
/* Process keycode */ |
1634 |
|
keyCode = ((XKeyEvent *)xEvent)->keycode; |
1635 |
//ximKeyCode = XKeysymToKeycode([XGServer currentXDisplay],keysym); |
//ximKeyCode = XKeysymToKeycode([XGServer currentXDisplay],keysym); |
1636 |
|
|
1637 |
/* Add NSNumericPadKeyMask if the key is in the KeyPad */ |
/* Add NSNumericPadKeyMask if the key is in the KeyPad */ |