43
143
#include <X11/extensions/XTest.h>
146
#include <X11/XKBlib.h>
46
149
#include "vino-util.h"
48
/* See <X11/keysymdef.h> - "Latin 1: Byte 3 and 4 = 0"
50
#define VINO_IS_LATIN1_KEYSYM(k) ((k) != NoSymbol && ((k) & 0xffffff00) == 0)
52
151
#define VINO_IS_MODIFIER_KEYSYM(k) (((k) >= XK_Shift_L && (k) <= XK_Hyper_R) || \
152
(k) == XK_Num_Lock || \
53
153
(k) == XK_Mode_switch || \
54
154
(k) == XK_ISO_Level3_Shift)
156
#define VINO_IS_KEYPAD_KEYSYM(k) ((k) >= XK_KP_Space && (k) <= XK_KP_Equal)
58
VINO_LEFT_SHIFT = 1 << 0,
59
VINO_RIGHT_SHIFT = 1 << 1,
160
VINO_LEFT_SHIFT = 1 << 0,
161
VINO_RIGHT_SHIFT = 1 << 1,
162
VINO_LEFT_CONTROL = 1 << 2,
163
VINO_RIGHT_ALT = 1 << 3,
164
VINO_ALT_GR = 1 << 4,
165
VINO_NUM_LOCK = 1 << 5
61
166
} VinoModifierState;
63
#define VINO_LEFT_OR_RIGHT_SHIFT (VINO_LEFT_SHIFT | VINO_RIGHT_SHIFT)
69
VinoModifierState modifier_state;
70
guint8 modifiers [0x100];
71
KeyCode keycodes [0x100];
72
KeyCode left_shift_keycode;
73
KeyCode right_shift_keycode;
74
KeyCode alt_gr_keycode;
76
guint n_pointer_buttons;
78
guint initialized : 1;
79
guint xtest_supported : 1;
170
VINO_LEVEL_PLAIN = 0,
171
VINO_LEVEL_SHIFT = 1,
172
VINO_LEVEL_ALTGR = 2,
173
VINO_LEVEL_SHIFT_ALTGR = 3,
174
VINO_LEVEL_NUM_LOCK = 4
177
#define VINO_NUM_LEVELS 4 /* NumLock is special and doesn't count */
178
#define VINO_NUM_GROUPS 4
180
#define VINO_LEVEL(state) ((((state) & (VINO_LEFT_SHIFT | VINO_RIGHT_SHIFT)) ? VINO_LEVEL_SHIFT : 0) | \
181
(((state) & VINO_ALT_GR) ? VINO_LEVEL_ALTGR : 0) | \
182
(((state) & VINO_NUM_LOCK) ? VINO_LEVEL_NUM_LOCK : 0))
184
#define VINO_LEVEL_IS_SHIFT(level) (level & VINO_LEVEL_SHIFT)
185
#define VINO_LEVEL_IS_ALTGR(level) (level & VINO_LEVEL_ALTGR)
186
#define VINO_LEVEL_IS_NUM_LOCK(level) (level & VINO_LEVEL_NUM_LOCK)
198
VinoModifierState modifier_state;
203
GHashTable *keybindings;
204
GHashTable *decompositions;
205
KeyCode left_shift_keycode;
206
KeyCode right_shift_keycode;
207
KeyCode left_control_keycode;
208
KeyCode alt_gr_keycode;
209
KeyCode num_lock_keycode;
211
KeySym alt_gr_keysym;
219
guint initialized : 1;
220
guint xtest_supported : 1;
221
guint xkb_supported : 1;
222
guint n_pointer_buttons;
82
225
/* Data is per-display, but we only handle a single display.
84
227
static VinoInputData global_input_data = { 0, };
86
/* Set up a keysym -> keycode + modifier mapping.
88
* RFB transmits the KeySym for a keypress, but we may only inject
89
* keycodes using XTest. Thus, we must ensure that the modifier
90
* state is such that the keycode we inject maps to the KeySym
91
* we received from the client.
233
guint32 decomposed[3];
234
} decompositions[] = {
235
{ XK_Cabovedot, { XK_dead_abovedot, 'C', 0 } },
236
{ XK_Eabovedot, { XK_dead_abovedot, 'E', 0 } },
237
{ XK_Gabovedot, { XK_dead_abovedot, 'G', 0 } },
238
{ XK_Iabovedot, { XK_dead_abovedot, 'I', 0 } },
239
{ XK_Zabovedot, { XK_dead_abovedot, 'Z', 0 } },
240
{ XK_cabovedot, { XK_dead_abovedot, 'c', 0 } },
241
{ XK_eabovedot, { XK_dead_abovedot, 'e', 0 } },
242
{ XK_gabovedot, { XK_dead_abovedot, 'g', 0 } },
243
{ XK_idotless, { XK_dead_abovedot, 'i', 0 } },
244
{ XK_zabovedot, { XK_dead_abovedot, 'z', 0 } },
245
{ XK_abovedot, { XK_dead_abovedot, XK_dead_abovedot, 0 } },
247
{ XK_Aring, { XK_dead_abovering, 'A', 0 } },
248
{ XK_Uring, { XK_dead_abovering, 'U', 0 } },
249
{ XK_aring, { XK_dead_abovering, 'a', 0 } },
250
{ XK_uring, { XK_dead_abovering, 'u', 0 } },
251
{ XK_degree, { XK_dead_abovering, XK_dead_abovering, 0 } },
253
{ XK_Aacute, { XK_dead_acute, 'A', 0 } },
254
{ XK_Cacute, { XK_dead_acute, 'C', 0 } },
255
{ XK_Eacute, { XK_dead_acute, 'E', 0 } },
256
{ XK_Iacute, { XK_dead_acute, 'I', 0 } },
257
{ XK_Lacute, { XK_dead_acute, 'L', 0 } },
258
{ XK_Nacute, { XK_dead_acute, 'N', 0 } },
259
{ XK_Oacute, { XK_dead_acute, 'O', 0 } },
260
{ XK_Racute, { XK_dead_acute, 'R', 0 } },
261
{ XK_Sacute, { XK_dead_acute, 'S', 0 } },
262
{ XK_Uacute, { XK_dead_acute, 'U', 0 } },
263
{ XK_Yacute, { XK_dead_acute, 'Y', 0 } },
264
{ XK_Zacute, { XK_dead_acute, 'Z', 0 } },
265
{ XK_aacute, { XK_dead_acute, 'a', 0 } },
266
{ XK_cacute, { XK_dead_acute, 'c', 0 } },
267
{ XK_eacute, { XK_dead_acute, 'e', 0 } },
268
{ XK_iacute, { XK_dead_acute, 'i', 0 } },
269
{ XK_lacute, { XK_dead_acute, 'l', 0 } },
270
{ XK_nacute, { XK_dead_acute, 'n', 0 } },
271
{ XK_oacute, { XK_dead_acute, 'o', 0 } },
272
{ XK_racute, { XK_dead_acute, 'r', 0 } },
273
{ XK_sacute, { XK_dead_acute, 's', 0 } },
274
{ XK_uacute, { XK_dead_acute, 'u', 0 } },
275
{ XK_yacute, { XK_dead_acute, 'y', 0 } },
276
{ XK_zacute, { XK_dead_acute, 'z', 0 } },
277
{ XK_acute, { XK_dead_acute, XK_dead_acute, 0 } },
279
{ XK_Abreve, { XK_dead_breve, 'A', 0 } },
280
{ XK_Gbreve, { XK_dead_breve, 'G', 0 } },
281
{ XK_Ubreve, { XK_dead_breve, 'U', 0 } },
282
{ XK_abreve, { XK_dead_breve, 'a', 0 } },
283
{ XK_gbreve, { XK_dead_breve, 'g', 0 } },
284
{ XK_ubreve, { XK_dead_breve, 'u', 0 } },
285
{ XK_breve, { XK_dead_breve, XK_dead_breve, 0 } },
287
{ XK_Ccaron, { XK_dead_caron, 'C', 0 } },
288
{ XK_Dcaron, { XK_dead_caron, 'D', 0 } },
289
{ XK_Ecaron, { XK_dead_caron, 'E', 0 } },
290
{ XK_Lcaron, { XK_dead_caron, 'L', 0 } },
291
{ XK_Ncaron, { XK_dead_caron, 'N', 0 } },
292
{ XK_Rcaron, { XK_dead_caron, 'R', 0 } },
293
{ XK_Scaron, { XK_dead_caron, 'S', 0 } },
294
{ XK_Tcaron, { XK_dead_caron, 'T', 0 } },
295
{ XK_Zcaron, { XK_dead_caron, 'Z', 0 } },
296
{ XK_ccaron, { XK_dead_caron, 'c', 0 } },
297
{ XK_dcaron, { XK_dead_caron, 'd', 0 } },
298
{ XK_ecaron, { XK_dead_caron, 'e', 0 } },
299
{ XK_lcaron, { XK_dead_caron, 'l', 0 } },
300
{ XK_ncaron, { XK_dead_caron, 'n', 0 } },
301
{ XK_rcaron, { XK_dead_caron, 'r', 0 } },
302
{ XK_scaron, { XK_dead_caron, 's', 0 } },
303
{ XK_tcaron, { XK_dead_caron, 't', 0 } },
304
{ XK_zcaron, { XK_dead_caron, 'z', 0 } },
305
{ XK_caron, { XK_dead_caron, XK_dead_caron, 0 } },
307
{ XK_Ccedilla, { XK_dead_cedilla, 'C', 0 } },
308
{ XK_Gcedilla, { XK_dead_cedilla, 'G', 0 } },
309
{ XK_Kcedilla, { XK_dead_cedilla, 'K', 0 } },
310
{ XK_Lcedilla, { XK_dead_cedilla, 'L', 0 } },
311
{ XK_Ncedilla, { XK_dead_cedilla, 'N', 0 } },
312
{ XK_Rcedilla, { XK_dead_cedilla, 'R', 0 } },
313
{ XK_Scedilla, { XK_dead_cedilla, 'S', 0 } },
314
{ XK_Tcedilla, { XK_dead_cedilla, 'T', 0 } },
315
{ XK_ccedilla, { XK_dead_cedilla, 'c', 0 } },
316
{ XK_gcedilla, { XK_dead_cedilla, 'g', 0 } },
317
{ XK_kcedilla, { XK_dead_cedilla, 'k', 0 } },
318
{ XK_lcedilla, { XK_dead_cedilla, 'l', 0 } },
319
{ XK_ncedilla, { XK_dead_cedilla, 'n', 0 } },
320
{ XK_rcedilla, { XK_dead_cedilla, 'r', 0 } },
321
{ XK_scedilla, { XK_dead_cedilla, 's', 0 } },
322
{ XK_tcedilla, { XK_dead_cedilla, 't', 0 } },
323
{ XK_cedilla, { XK_dead_cedilla, XK_dead_cedilla, 0 } },
325
{ XK_Acircumflex, { XK_dead_circumflex, 'A', 0 } },
326
{ XK_Ccircumflex, { XK_dead_circumflex, 'C', 0 } },
327
{ XK_Ecircumflex, { XK_dead_circumflex, 'E', 0 } },
328
{ XK_Gcircumflex, { XK_dead_circumflex, 'G', 0 } },
329
{ XK_Hcircumflex, { XK_dead_circumflex, 'H', 0 } },
330
{ XK_Icircumflex, { XK_dead_circumflex, 'I', 0 } },
331
{ XK_Jcircumflex, { XK_dead_circumflex, 'J', 0 } },
332
{ XK_Ocircumflex, { XK_dead_circumflex, 'O', 0 } },
333
{ XK_Scircumflex, { XK_dead_circumflex, 'S', 0 } },
334
{ XK_Ucircumflex, { XK_dead_circumflex, 'U', 0 } },
335
{ XK_acircumflex, { XK_dead_circumflex, 'a', 0 } },
336
{ XK_ccircumflex, { XK_dead_circumflex, 'c', 0 } },
337
{ XK_ecircumflex, { XK_dead_circumflex, 'e', 0 } },
338
{ XK_gcircumflex, { XK_dead_circumflex, 'g', 0 } },
339
{ XK_hcircumflex, { XK_dead_circumflex, 'h', 0 } },
340
{ XK_icircumflex, { XK_dead_circumflex, 'i', 0 } },
341
{ XK_jcircumflex, { XK_dead_circumflex, 'j', 0 } },
342
{ XK_ocircumflex, { XK_dead_circumflex, 'o', 0 } },
343
{ XK_scircumflex, { XK_dead_circumflex, 's', 0 } },
344
{ XK_ucircumflex, { XK_dead_circumflex, 'u', 0 } },
345
{ XK_asciicircum, { XK_dead_circumflex, XK_dead_circumflex, 0 } },
347
{ XK_Adiaeresis, { XK_dead_diaeresis, 'A', 0 } },
348
{ XK_Ediaeresis, { XK_dead_diaeresis, 'E', 0 } },
349
{ XK_Idiaeresis, { XK_dead_diaeresis, 'I', 0 } },
350
{ XK_Odiaeresis, { XK_dead_diaeresis, 'O', 0 } },
351
{ XK_Udiaeresis, { XK_dead_diaeresis, 'U', 0 } },
352
{ XK_adiaeresis, { XK_dead_diaeresis, 'a', 0 } },
353
{ XK_ediaeresis, { XK_dead_diaeresis, 'e', 0 } },
354
{ XK_idiaeresis, { XK_dead_diaeresis, 'i', 0 } },
355
{ XK_odiaeresis, { XK_dead_diaeresis, 'o', 0 } },
356
{ XK_udiaeresis, { XK_dead_diaeresis, 'u', 0 } },
357
{ XK_ydiaeresis, { XK_dead_diaeresis, 'y', 0 } },
358
{ XK_diaeresis, { XK_dead_diaeresis, XK_dead_diaeresis, 0 } },
360
{ XK_Odoubleacute, { XK_dead_doubleacute, 'O', 0 } },
361
{ XK_Udoubleacute, { XK_dead_doubleacute, 'U', 0 } },
362
{ XK_odoubleacute, { XK_dead_doubleacute, 'o', 0 } },
363
{ XK_udoubleacute, { XK_dead_doubleacute, 'u', 0 } },
364
{ XK_doubleacute, { XK_dead_doubleacute, XK_dead_doubleacute, 0 } },
366
{ XK_Agrave, { XK_dead_grave, 'A', 0 } },
367
{ XK_Egrave, { XK_dead_grave, 'E', 0 } },
368
{ XK_Igrave, { XK_dead_grave, 'I', 0 } },
369
{ XK_Ograve, { XK_dead_grave, 'O', 0 } },
370
{ XK_Ugrave, { XK_dead_grave, 'U', 0 } },
371
{ XK_agrave, { XK_dead_grave, 'a', 0 } },
372
{ XK_egrave, { XK_dead_grave, 'e', 0 } },
373
{ XK_igrave, { XK_dead_grave, 'i', 0 } },
374
{ XK_ograve, { XK_dead_grave, 'o', 0 } },
375
{ XK_ugrave, { XK_dead_grave, 'u', 0 } },
376
{ XK_grave, { XK_dead_grave, XK_dead_grave, 0 } },
378
{ XK_Amacron, { XK_dead_macron, 'A', 0 } },
379
{ XK_Emacron, { XK_dead_macron, 'E', 0 } },
380
{ XK_Imacron, { XK_dead_macron, 'I', 0 } },
381
{ XK_Omacron, { XK_dead_macron, 'O', 0 } },
382
{ XK_Umacron, { XK_dead_macron, 'U', 0 } },
383
{ XK_amacron, { XK_dead_macron, 'a', 0 } },
384
{ XK_emacron, { XK_dead_macron, 'e', 0 } },
385
{ XK_imacron, { XK_dead_macron, 'i', 0 } },
386
{ XK_omacron, { XK_dead_macron, 'o', 0 } },
387
{ XK_umacron, { XK_dead_macron, 'u', 0 } },
388
{ XK_macron, { XK_dead_macron, XK_dead_macron, 0 } },
390
{ XK_Aogonek, { XK_dead_ogonek, 'A', 0 } },
391
{ XK_Eogonek, { XK_dead_ogonek, 'E', 0 } },
392
{ XK_Iogonek, { XK_dead_ogonek, 'I', 0 } },
393
{ XK_Uogonek, { XK_dead_ogonek, 'U', 0 } },
394
{ XK_aogonek, { XK_dead_ogonek, 'a', 0 } },
395
{ XK_eogonek, { XK_dead_ogonek, 'e', 0 } },
396
{ XK_iogonek, { XK_dead_ogonek, 'i', 0 } },
397
{ XK_uogonek, { XK_dead_ogonek, 'u', 0 } },
398
{ XK_ogonek, { XK_dead_ogonek, XK_dead_ogonek, 0 } },
400
{ XK_Atilde, { XK_dead_tilde, 'A', 0 } },
401
{ XK_Itilde, { XK_dead_tilde, 'I', 0 } },
402
{ XK_Ntilde, { XK_dead_tilde, 'N', 0 } },
403
{ XK_Otilde, { XK_dead_tilde, 'O', 0 } },
404
{ XK_Utilde, { XK_dead_tilde, 'U', 0 } },
405
{ XK_atilde, { XK_dead_tilde, 'a', 0 } },
406
{ XK_itilde, { XK_dead_tilde, 'i', 0 } },
407
{ XK_ntilde, { XK_dead_tilde, 'n', 0 } },
408
{ XK_otilde, { XK_dead_tilde, 'o', 0 } },
409
{ XK_utilde, { XK_dead_tilde, 'u', 0 } },
410
{ XK_asciitilde, { XK_dead_tilde, XK_dead_tilde, 0 } },
412
{ XK_Greek_ALPHAaccent, { XK_dead_acute, XK_Greek_ALPHA, 0 } },
413
{ XK_Greek_EPSILONaccent, { XK_dead_acute, XK_Greek_EPSILON, 0 } },
414
{ XK_Greek_ETAaccent, { XK_dead_acute, XK_Greek_ETA, 0 } },
415
{ XK_Greek_IOTAaccent, { XK_dead_acute, XK_Greek_IOTA, 0 } },
416
{ XK_Greek_OMICRONaccent, { XK_dead_acute, XK_Greek_OMICRON, 0 } },
417
{ XK_Greek_UPSILONaccent, { XK_dead_acute, XK_Greek_UPSILON, 0 } },
418
{ XK_Greek_OMEGAaccent, { XK_dead_acute, XK_Greek_OMEGA, 0 } },
419
{ XK_Greek_alphaaccent, { XK_dead_acute, XK_Greek_alpha, 0 } },
420
{ XK_Greek_epsilonaccent, { XK_dead_acute, XK_Greek_epsilon, 0 } },
421
{ XK_Greek_etaaccent, { XK_dead_acute, XK_Greek_eta, 0 } },
422
{ XK_Greek_iotaaccent, { XK_dead_acute, XK_Greek_iota, 0 } },
423
{ XK_Greek_omicronaccent, { XK_dead_acute, XK_Greek_omicron, 0 } },
424
{ XK_Greek_upsilonaccent, { XK_dead_acute, XK_Greek_upsilon, 0 } },
425
{ XK_Greek_omegaaccent, { XK_dead_acute, XK_Greek_omega, 0 } },
427
{ XK_Greek_IOTAdieresis, { XK_dead_diaeresis, XK_Greek_IOTA, 0 } },
428
{ XK_Greek_UPSILONdieresis, { XK_dead_diaeresis, XK_Greek_UPSILON, 0 } },
429
{ XK_Greek_iotadieresis, { XK_dead_diaeresis, XK_Greek_iota, 0 } },
430
{ XK_Greek_upsilondieresis, { XK_dead_diaeresis, XK_Greek_upsilon, 0 } },
432
{ XK_Greek_iotaaccentdieresis, { XK_dead_acute, XK_dead_diaeresis, XK_Greek_iota } },
433
{ XK_Greek_upsilonaccentdieresis, { XK_dead_acute, XK_dead_diaeresis, XK_Greek_upsilon } }
435
static const int num_decompositions = G_N_ELEMENTS (decompositions);
437
static void vino_input_initialize_keycodes (Display *xdisplay);
95
vino_input_initialize_keycodes (GdkDisplay *display)
440
vino_input_initialize_keycodes_core (Display *xdisplay)
98
442
int min_keycodes, max_keycodes;
99
443
int keysyms_per_keycode;
102
xdisplay = GDK_DISPLAY_XDISPLAY (display);
104
memset (global_input_data.keycodes, 0, sizeof (global_input_data.keycodes));
105
memset (global_input_data.modifiers, -1, sizeof (global_input_data.modifiers));
445
int keycode, level, i;
446
XModifierKeymap *modmap;
448
global_input_data.alt_gr_keysym = XK_Mode_switch;
107
450
XDisplayKeycodes (xdisplay, &min_keycodes, &max_keycodes);
109
g_assert (min_keycodes >= 8);
110
g_assert (max_keycodes <= 255);
112
451
XGetKeyboardMapping (xdisplay, min_keycodes, 0, &keysyms_per_keycode);
453
/* We iterate by level first, then by keycode, to ensure that we
454
* find an unshifted match for each keysym, if possible.
456
for (level = 0; level < MAX (keysyms_per_keycode, VINO_NUM_LEVELS); level++)
458
for (keycode = min_keycodes; keycode < max_keycodes; keycode++)
460
VinoKeybinding *binding;
461
gboolean unmodifiable = FALSE;
463
sym = XKeycodeToKeysym (xdisplay, keycode, level);
467
if (g_hash_table_lookup (global_input_data.keybindings,
468
GUINT_TO_POINTER (sym)))
471
binding = g_new (VinoKeybinding, VINO_NUM_GROUPS);
472
g_hash_table_insert (global_input_data.keybindings,
473
GUINT_TO_POINTER (sym), binding);
475
/* There's only one group in plain X, so use "binding[0]". */
476
binding[0].keycode = keycode;
477
binding[0].keypad = VINO_IS_KEYPAD_KEYSYM (sym);
479
/* Check if this is a key like XK_uparrow that doesn't change
480
* when you press Shift/Alt-Gr.
482
if (level == VINO_LEVEL_PLAIN)
484
KeySym shiftsym, altgrsym;
486
shiftsym = XKeycodeToKeysym (xdisplay, keycode, VINO_LEVEL_SHIFT);
487
altgrsym = (keysyms_per_keycode <= VINO_LEVEL_ALTGR) ? NoSymbol :
488
XKeycodeToKeysym (xdisplay, keycode, VINO_LEVEL_ALTGR);
490
unmodifiable = (shiftsym == NoSymbol) && (altgrsym == NoSymbol);
494
binding[0].level = -1;
495
else if (binding[0].keypad && level == VINO_LEVEL_SHIFT)
496
binding[0].level = VINO_LEVEL_NUM_LOCK;
498
binding[0].level = level;
500
dprintf (INPUT, "\t0x%.2x (%s) -> key %d level %d\n", (guint)sym,
501
XKeysymToString (sym), keycode, level);
505
/* Find the modifier mask corresponding to NumLock */
506
keycode = XKeysymToKeycode (xdisplay, XK_Num_Lock);
507
modmap = XGetModifierMapping (xdisplay);
508
for (i = 0; i < 8 * modmap->max_keypermod; i++)
510
if (modmap->modifiermap[i] == keycode)
512
global_input_data.num_lock_mod = 1 << (i / modmap->max_keypermod);
516
XFreeModifiermap (modmap);
521
vino_input_initialize_keycodes_xkb (Display *xdisplay)
525
int levelmap[XkbMaxKeyTypes][VINO_NUM_LEVELS], kc, kt, level, group;
527
VinoKeybinding *binding;
530
global_input_data.alt_gr_keysym = XK_ISO_Level3_Shift;
532
xkb = XkbGetMap (xdisplay, XkbAllClientInfoMask, XkbUseCoreKbd);
533
g_assert (xkb != NULL);
535
LevelThreeMask = XkbKeysymToModifiers (xdisplay, XK_ISO_Level3_Shift);
537
/* XKB's levels don't map to VinoLevel, and in fact, may be
538
* different for different types of keys (eg, the second level on
539
* the function keys is Ctrl+Alt, not Shift). So we create
540
* "levelmap" to map VinoLevel values to keytype-specific levels.
542
for (kt = 0; kt < xkb->map->num_types; kt++)
548
levelmap[kt][VINO_LEVEL_PLAIN] = 0;
549
levelmap[kt][VINO_LEVEL_SHIFT] = -1;
550
levelmap[kt][VINO_LEVEL_ALTGR] = -1;
551
levelmap[kt][VINO_LEVEL_SHIFT_ALTGR] = -1;
553
type = &xkb->map->types[kt];
554
for (ktl = 0; ktl < type->map_count; ktl++)
556
if (!type->map[ktl].active)
559
mods = &type->map[ktl].mods;
560
if (mods->mask == ShiftMask)
561
levelmap[kt][VINO_LEVEL_SHIFT] = type->map[ktl].level;
562
else if (mods->mask == LevelThreeMask)
563
levelmap[kt][VINO_LEVEL_ALTGR] = type->map[ktl].level;
564
else if (mods->mask == (ShiftMask | LevelThreeMask))
565
levelmap[kt][VINO_LEVEL_SHIFT_ALTGR] = type->map[ktl].level;
568
if (levelmap[kt][VINO_LEVEL_SHIFT] == -1)
569
levelmap[kt][VINO_LEVEL_SHIFT] = levelmap[kt][VINO_LEVEL_PLAIN];
570
if (levelmap[kt][VINO_LEVEL_ALTGR] == -1)
571
levelmap[kt][VINO_LEVEL_ALTGR] = levelmap[kt][VINO_LEVEL_PLAIN];
572
if (levelmap[kt][VINO_LEVEL_SHIFT_ALTGR] == -1)
573
levelmap[kt][VINO_LEVEL_SHIFT_ALTGR] = levelmap[kt][VINO_LEVEL_SHIFT];
576
/* Now map out the keysyms. As in the core case, we iterate levels
577
* before keycodes, so our first match for a keysym in each group
578
* will be unshifted if possible.
580
for (group = 0; group < VINO_NUM_GROUPS; group++)
582
for (level = 0; level < VINO_NUM_LEVELS; level++)
584
for (kc = xkb->min_key_code; kc <= xkb->max_key_code; kc++)
588
ngroups = XkbKeyNumGroups (xkb, kc);
592
/* If the key has fewer groups than the keyboard as a
593
* whole does, figure out which of the key's groups
594
* ("kgroup") will end up being used when the keyboard
595
* as a whole is using group "group".
597
if (group >= ngroups)
599
if (xkb->map->key_sym_map[kc].group_info & XkbRedirectIntoRange)
601
else if (xkb->map->key_sym_map[kc].group_info & XkbClampIntoRange)
602
kgroup = ngroups - 1;
604
kgroup = group % ngroups;
609
kt = xkb->map->key_sym_map[kc].kt_index[kgroup];
610
sym = XkbKeySymEntry (xkb, kc, levelmap[kt][level], kgroup);
614
binding = g_hash_table_lookup (global_input_data.keybindings,
615
GUINT_TO_POINTER (sym));
618
binding = g_new0 (VinoKeybinding, VINO_NUM_GROUPS);
619
g_hash_table_insert (global_input_data.keybindings,
620
GUINT_TO_POINTER (sym), binding);
623
if (!binding[group].keycode)
625
binding[group].keycode = kc;
626
binding[group].keypad = (kt == XkbKeypadIndex);
627
if (xkb->map->types[kt].num_levels == 1)
628
binding[group].level = -1;
629
else if (binding[group].keypad && level == VINO_LEVEL_SHIFT)
630
binding[group].level = VINO_LEVEL_NUM_LOCK;
632
binding[group].level = level;
637
dprintf (INPUT, "\t0x%.2x (%s) -> key %d group %d level %d\n",
638
(guint)sym, XKeysymToString (sym), kc, group, level);
644
/* Figure out how switching between groups works; we only support
645
* XkbWrapIntoRange. (In theory, xkb->ctrls->group_info should equal
646
* XkbWrapIntoRange (ie, 0) when that's the case, but in practice
647
* there seems to be junk in the lower 4 bits, so we test for the
648
* absence of the other two flags instead.)
650
if (XkbGetControls (xdisplay, XkbGroupsWrapMask, xkb) == Success)
652
if (!(xkb->ctrls->groups_wrap & (XkbClampIntoRange | XkbRedirectIntoRange)))
654
dprintf (INPUT, "%d groups configured\n", xkb->ctrls->num_groups);
655
global_input_data.xkb_num_groups = xkb->ctrls->num_groups;
657
else if (xkb->ctrls->num_groups > 1)
659
dprintf (INPUT, "groups_wrap is not WrapIntoRange, can't use\n");
660
global_input_data.xkb_num_groups = -1;
664
/* Find NumLock modifier mask and get initial NumLock state */
665
global_input_data.num_lock_mod = XkbKeysymToModifiers (xdisplay, XK_Num_Lock);
666
if (XkbGetState (xdisplay, XkbUseCoreKbd, &state) == Success)
668
if (state.locked_mods & global_input_data.num_lock_mod)
669
global_input_data.modifier_state |= VINO_NUM_LOCK;
672
XkbFreeKeyboard (xkb, 0, True);
675
static GdkFilterReturn
676
xkb_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data)
678
VinoInputData *data = user_data;
679
XkbStateNotifyEvent *state;
681
if (((XEvent *)xevent)->type == data->xkb_event_type)
683
switch (((XkbAnyEvent *)xevent)->xkb_type)
686
state = (XkbStateNotifyEvent *)xevent;
688
if (state->changed & XkbGroupStateMask)
690
data->current_group = state->group;
691
dprintf (INPUT, "current_group -> %d\n", data->current_group);
693
if (state->changed & XkbModifierLockMask)
695
if (state->locked_mods & data->num_lock_mod)
696
data->modifier_state |= VINO_NUM_LOCK;
698
data->modifier_state &= ~VINO_NUM_LOCK;
699
dprintf (INPUT, "locked_mods -> %u, modifier_state -> %u\n",
700
state->locked_mods, data->modifier_state);
705
XkbRefreshKeyboardMapping ((XkbMapNotifyEvent *)xevent);
708
case XkbControlsNotify:
709
vino_input_initialize_keycodes (((XkbAnyEvent *)xevent)->display);
714
return GDK_FILTER_CONTINUE;
719
vino_input_initialize_keycodes (Display *xdisplay)
114
721
dprintf (INPUT, "Initializing keysym to keycode/modifier mapping\n");
116
for (keycode = min_keycodes; keycode < max_keycodes; keycode++)
120
for (modifier = 0; modifier < keysyms_per_keycode; modifier++)
122
guint32 keysym = XKeycodeToKeysym (xdisplay, keycode, modifier);
124
if (VINO_IS_LATIN1_KEYSYM (keysym))
126
global_input_data.keycodes [keysym] = keycode;
127
global_input_data.modifiers [keysym] = modifier;
129
dprintf (INPUT, "\t0x%.2x -> %d %d\n", keysym, keycode, modifier);
134
global_input_data.left_shift_keycode = XKeysymToKeycode (xdisplay, XK_Shift_L);
135
global_input_data.right_shift_keycode = XKeysymToKeycode (xdisplay, XK_Shift_R);
136
global_input_data.alt_gr_keycode = XKeysymToKeycode (xdisplay, XK_Mode_switch);
723
if (global_input_data.keybindings)
724
g_hash_table_destroy (global_input_data.keybindings);
725
global_input_data.keybindings =
726
g_hash_table_new_full (NULL, NULL, NULL, g_free);
729
if (global_input_data.xkb_supported)
730
vino_input_initialize_keycodes_xkb (xdisplay);
732
if (!global_input_data.xkb_supported)
733
vino_input_initialize_keycodes_core (xdisplay);
735
global_input_data.left_shift_keycode = XKeysymToKeycode (xdisplay, XK_Shift_L);
736
global_input_data.right_shift_keycode = XKeysymToKeycode (xdisplay, XK_Shift_R);
737
global_input_data.left_control_keycode = XKeysymToKeycode (xdisplay, XK_Control_L);
738
global_input_data.num_lock_keycode = XKeysymToKeycode (xdisplay, XK_Num_Lock);
739
global_input_data.alt_gr_keycode = XKeysymToKeycode (xdisplay, global_input_data.alt_gr_keysym);
138
741
#endif /* HAVE_XTEST */