1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2000 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
37 #include "gdkprivate-x11.h"
38 #include "gdkinternals.h"
39 #include "gdkkeysyms.h"
43 guint _gdk_keymap_serial = 0;
45 static gint min_keycode = 0;
46 static gint max_keycode = 0;
49 update_keyrange (void)
52 XDisplayKeycodes (gdk_display, &min_keycode, &max_keycode);
56 #include <X11/XKBlib.h>
58 gboolean _gdk_use_xkb = FALSE;
59 gint _gdk_xkb_event_type;
60 static XkbDescPtr xkb_desc = NULL;
65 static guint current_serial = 0;
71 xkb_desc = XkbGetMap (gdk_display, XkbKeySymsMask, XkbUseCoreKbd);
73 g_error ("Failed to get keymap");
75 XkbGetNames (gdk_display, XkbGroupNamesMask, xkb_desc);
77 else if (current_serial != _gdk_keymap_serial)
79 XkbGetUpdatedMap (gdk_display, XkbKeySymsMask, xkb_desc);
80 XkbGetNames (gdk_display, XkbGroupNamesMask, xkb_desc);
83 current_serial = _gdk_keymap_serial;
89 /* Whether we were able to turn on detectable-autorepeat using
90 * XkbSetDetectableAutorepeat. If FALSE, we'll fall back
91 * to checking the next event with XPending().
93 gboolean _gdk_have_xkb_autorepeat = FALSE;
95 static KeySym* keymap = NULL;
96 static gint keysyms_per_keycode = 0;
97 static XModifierKeymap* mod_keymap = NULL;
98 static GdkModifierType group_switch_mask = 0;
99 static PangoDirection current_direction;
100 static gboolean have_direction = FALSE;
101 static GdkKeymap *default_keymap = NULL;
104 * gdk_keymap_get_default:
106 * Gets the #GdkKeymap for the default display.
108 * Return value: the default keymap
111 gdk_keymap_get_default (void)
113 if (default_keymap == NULL)
114 default_keymap = g_object_new (gdk_keymap_get_type (), NULL);
116 return default_keymap;
120 update_keymaps (void)
122 static guint current_serial = 0;
125 g_assert (!_gdk_use_xkb);
128 if (keymap == NULL ||
129 current_serial != _gdk_keymap_serial)
134 current_serial = _gdk_keymap_serial;
142 XFreeModifiermap (mod_keymap);
144 keymap = XGetKeyboardMapping (gdk_display, min_keycode,
145 max_keycode - min_keycode,
146 &keysyms_per_keycode);
148 mod_keymap = XGetModifierMapping (gdk_display);
151 group_switch_mask = 0;
153 /* there are 8 modifiers, and the first 3 are shift, shift lock,
156 map_size = 8 * mod_keymap->max_keypermod;
157 i = 3 * mod_keymap->max_keypermod;
160 /* get the key code at this point in the map,
161 * see if its keysym is GDK_Mode_switch, if so
162 * we have the mode key
164 gint keycode = mod_keymap->modifiermap[i];
166 if (keycode >= min_keycode &&
167 keycode <= max_keycode)
170 KeySym *syms = keymap + (keycode - min_keycode) * keysyms_per_keycode;
171 while (j < keysyms_per_keycode)
173 if (syms[j] == GDK_Mode_switch)
175 /* This modifier swaps groups */
177 /* GDK_MOD1_MASK is 1 << 3 for example, i.e. the
178 * fourth modifier, i / keyspermod is the modifier
182 group_switch_mask |= (1 << ( i / mod_keymap->max_keypermod));
204 static PangoDirection
207 XkbDescRec *xkb = get_xkb ();
209 XkbStateRec state_rec;
210 PangoDirection result;
212 XkbGetState (gdk_display, XkbUseCoreKbd, &state_rec);
214 if (xkb->names->groups[state_rec.locked_group] == None)
215 result = PANGO_DIRECTION_LTR;
218 name = gdk_atom_name (xkb->names->groups[state_rec.locked_group]);
219 if (g_strcasecmp (name, "arabic") == 0 ||
220 g_strcasecmp (name, "hebrew") == 0 ||
221 g_strcasecmp (name, "israelian") == 0)
222 result = PANGO_DIRECTION_RTL;
224 result = PANGO_DIRECTION_LTR;
232 _gdk_keymap_state_changed (void)
236 PangoDirection new_direction = get_direction ();
238 if (!have_direction || new_direction != current_direction)
240 have_direction = TRUE;
241 current_direction = new_direction;
242 g_signal_emit_by_name (G_OBJECT (default_keymap), "direction_changed");
246 #endif /* HAVE_XKB */
249 gdk_keymap_get_direction (GdkKeymap *keymap)
256 current_direction = get_direction ();
257 have_direction = TRUE;
260 return current_direction;
263 #endif /* HAVE_XKB */
264 return PANGO_DIRECTION_LTR;
268 * gdk_keymap_get_entries_for_keyval:
269 * @keymap: a #GdkKeymap, or %NULL to use the default keymap
270 * @keyval: a keyval, such as %GDK_a, %GDK_Up, %GDK_Return, etc.
271 * @keys: return location for an array of #GdkKeymapKey
272 * @n_keys: return location for number of elements in returned array
274 * Obtains a list of keycode/group/level combinations that will
275 * generate @keyval. Groups and levels are two kinds of keyboard mode;
276 * in general, the level determines whether the top or bottom symbol
277 * on a key is used, and the group determines whether the left or
278 * right symbol is used. On US keyboards, the shift key changes the
279 * keyboard level, and there are no groups. A group switch key might
280 * convert a keyboard between Hebrew to English modes, for example.
281 * #GdkEventKey contains a %group field that indicates the active
282 * keyboard group. The level is computed from the modifier mask.
283 * The returned array should be freed
286 * Return value: %TRUE if keys were found and returned
289 gdk_keymap_get_entries_for_keyval (GdkKeymap *keymap,
296 g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
297 g_return_val_if_fail (keys != NULL, FALSE);
298 g_return_val_if_fail (n_keys != NULL, FALSE);
299 g_return_val_if_fail (keyval != 0, FALSE);
301 retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
306 /* See sec 15.3.4 in XKB docs */
308 XkbDescRec *xkb = get_xkb ();
311 keycode = min_keycode;
313 while (keycode <= max_keycode)
315 gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode); /* "key width" */
318 gint total_syms = XkbKeyNumSyms (xkb, keycode);
322 /* entry is an array with all syms for group 0, all
323 * syms for group 1, etc. and for each group the
324 * shift level syms are in order
326 entry = XkbKeySymsPtr (xkb, keycode);
328 while (i < total_syms)
330 /* check out our cool loop invariant */
331 g_assert (i == (group * max_shift_levels + level));
333 if (entry[i] == keyval)
338 key.keycode = keycode;
342 g_array_append_val (retval, key);
344 g_assert (XkbKeySymEntry (xkb, keycode, level, group) == keyval);
349 if (level == max_shift_levels)
364 const KeySym *map = get_keymap ();
367 keycode = min_keycode;
368 while (keycode < max_keycode)
370 const KeySym *syms = map + (keycode - min_keycode) * keysyms_per_keycode;
373 while (i < keysyms_per_keycode)
375 if (syms[i] == keyval)
380 key.keycode = keycode;
382 /* The "classic" non-XKB keymap has 2 levels per group */
386 g_array_append_val (retval, key);
398 *keys = (GdkKeymapKey*) retval->data;
399 *n_keys = retval->len;
407 g_array_free (retval, retval->len > 0 ? FALSE : TRUE);
413 * gdk_keymap_get_entries_for_keycode:
414 * @keymap: a #GdkKeymap or %NULL to use the default keymap
415 * @hardware_keycode: a keycode
416 * @keys: return location for array of #GdkKeymapKey, or NULL
417 * @keyvals: return location for array of keyvals, or NULL
418 * @n_entries: length of @keys and @keyvals
420 * Returns the keyvals bound to @hardware_keycode.
421 * The Nth #GdkKeymapKey in @keys is bound to the Nth
422 * keyval in @keyvals. Free the returned arrays with g_free().
423 * When a keycode is pressed by the user, the keyval from
424 * this list of entries is selected by considering the effective
425 * keyboard group and level. See gdk_keymap_translate_keyboard_state().
427 * Returns: %TRUE if there were any entries
430 gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap,
431 guint hardware_keycode,
437 GArray *keyval_array;
439 g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
440 g_return_val_if_fail (n_entries != NULL, FALSE);
444 if (hardware_keycode < min_keycode ||
445 hardware_keycode > max_keycode)
457 key_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
462 keyval_array = g_array_new (FALSE, FALSE, sizeof (guint));
469 /* See sec 15.3.4 in XKB docs */
471 XkbDescRec *xkb = get_xkb ();
472 gint max_shift_levels;
479 max_shift_levels = XkbKeyGroupsWidth (xkb, hardware_keycode); /* "key width" */
480 total_syms = XkbKeyNumSyms (xkb, hardware_keycode);
482 /* entry is an array with all syms for group 0, all
483 * syms for group 1, etc. and for each group the
484 * shift level syms are in order
486 entry = XkbKeySymsPtr (xkb, hardware_keycode);
488 while (i < total_syms)
490 /* check out our cool loop invariant */
491 g_assert (i == (group * max_shift_levels + level));
497 key.keycode = hardware_keycode;
501 g_array_append_val (key_array, key);
505 g_array_append_val (keyval_array, entry[i]);
509 if (level == max_shift_levels)
521 const KeySym *map = get_keymap ();
525 syms = map + (hardware_keycode - min_keycode) * keysyms_per_keycode;
527 while (i < keysyms_per_keycode)
533 key.keycode = hardware_keycode;
535 /* The "classic" non-XKB keymap has 2 levels per group */
539 g_array_append_val (key_array, key);
543 g_array_append_val (keyval_array, syms[i]);
549 if ((key_array && key_array->len > 0) ||
550 (keyval_array && keyval_array->len > 0))
553 *keys = (GdkKeymapKey*) key_array->data;
556 *keyvals = (guint*) keyval_array->data;
559 *n_entries = key_array->len;
561 *n_entries = keyval_array->len;
575 g_array_free (key_array, key_array->len > 0 ? FALSE : TRUE);
577 g_array_free (keyval_array, keyval_array->len > 0 ? FALSE : TRUE);
579 return *n_entries > 0;
584 * gdk_keymap_lookup_key:
585 * @keymap: a #GdkKeymap or %NULL to use the default keymap
586 * @key: a #GdkKeymapKey with keycode, group, and level initialized
588 * Looks up the keyval mapped to a keycode/group/level triplet.
589 * If no keyval is bound to @key, returns 0. For normal user input,
590 * you want to use gdk_keymap_translate_keyboard_state() instead of
591 * this function, since the effective group/level may not be
592 * the same as the current keyboard state.
594 * Return value: a keyval, or 0 if none was mapped to the given @key
597 gdk_keymap_lookup_key (GdkKeymap *keymap,
598 const GdkKeymapKey *key)
600 g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), 0);
601 g_return_val_if_fail (key != NULL, 0);
602 g_return_val_if_fail (key->group < 4, 0);
607 XkbDescRec *xkb = get_xkb ();
609 return XkbKeySymEntry (xkb, key->keycode, key->level, key->group);
616 return XKeycodeToKeysym (gdk_display, key->keycode,
617 key->group * keysyms_per_keycode + key->level);
622 /* This is copied straight from XFree86 Xlib, because I needed to
623 * add the group and level return. It's unchanged for ease of
624 * diff against the Xlib sources; don't reformat it.
627 MyEnhancedXkbTranslateKeyCode(register XkbDescPtr xkb,
629 register unsigned int mods,
630 unsigned int * mods_rtrn,
631 KeySym * keysym_rtrn,
632 unsigned int * group_rtrn,
633 unsigned int * level_rtrn)
637 unsigned preserve,effectiveGroup;
643 nKeyGroups= XkbKeyNumGroups(xkb,key);
644 if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) {
645 if (keysym_rtrn!=NULL)
646 *keysym_rtrn = NoSymbol;
650 syms = XkbKeySymsPtr(xkb,key);
652 /* find the offset of the effective group */
654 effectiveGroup= XkbGroupForCoreState(mods);
655 if ( effectiveGroup>=nKeyGroups ) {
656 unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
657 switch (XkbOutOfRangeGroupAction(groupInfo)) {
659 effectiveGroup %= nKeyGroups;
661 case XkbClampIntoRange:
662 effectiveGroup = nKeyGroups-1;
664 case XkbRedirectIntoRange:
665 effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
666 if (effectiveGroup>=nKeyGroups)
671 col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
672 type = XkbKeyKeyType(xkb,key,effectiveGroup);
675 if (type->map) { /* find the column (shift level) within the group */
677 register XkbKTMapEntryPtr entry;
678 for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
679 if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) {
682 preserve= type->preserve[i].mask;
684 /* ---- Begin stuff GDK adds to the original Xlib version ---- */
687 *level_rtrn = entry->level;
689 /* ---- End stuff GDK adds to the original Xlib version ---- */
696 if (keysym_rtrn!=NULL)
697 *keysym_rtrn= syms[col];
699 *mods_rtrn= type->mods.mask&(~preserve);
701 /* ---- Begin stuff GDK comments out of the original Xlib version ---- */
702 /* This is commented out because xkb_info is a private struct */
705 /* The Motif VTS doesn't get the help callback called if help
706 * is bound to Shift+<whatever>, and it appears as though it
707 * is XkbTranslateKeyCode that is causing the problem. The
708 * core X version of XTranslateKey always OR's in ShiftMask
709 * and LockMask for mods_rtrn, so this "fix" keeps this behavior
710 * and solves the VTS problem.
712 if ((xkb->dpy)&&(xkb->dpy->xkb_info)&&
713 (xkb->dpy->xkb_info->xlib_ctrls&XkbLC_AlwaysConsumeShiftAndLock)) { *mods_rtrn|= (ShiftMask|LockMask);
717 /* ---- End stuff GDK comments out of the original Xlib version ---- */
720 /* ---- Begin stuff GDK adds to the original Xlib version ---- */
723 *group_rtrn = effectiveGroup;
725 /* ---- End stuff GDK adds to the original Xlib version ---- */
727 return (syms[col]!=NoSymbol);
729 #endif /* HAVE_XKB */
732 * gdk_keymap_translate_keyboard_state:
733 * @keymap: a #GdkKeymap, or %NULL to use the default
734 * @hardware_keycode: a keycode
735 * @state: a modifier state
736 * @group: active keyboard group
737 * @keyval: return location for keyval
738 * @effective_group: return location for effective group
739 * @level: return location for level
740 * @unused_modifiers: return location for modifiers that didn't affect the group or level
743 * Translates the contents of a #GdkEventKey into a keyval, effective
744 * group, and level. Modifiers that didn't affect the translation and
745 * are thus available for application use are returned in
746 * @unused_modifiers. See gdk_keyval_get_keys() for an explanation of
747 * groups and levels. The @effective_group is the group that was
748 * actually used for the translation; some keys such as Enter are not
749 * affected by the active keyboard group. The @level is derived from
750 * @state. For convenience, #GdkEventKey already contains the translated
751 * keyval, so this function isn't as useful as you might think.
753 * Return value: %TRUE if there was a keyval bound to the keycode/state/group
756 gdk_keymap_translate_keyboard_state (GdkKeymap *keymap,
757 guint hardware_keycode,
758 GdkModifierType state,
761 gint *effective_group,
763 GdkModifierType *unused_modifiers)
765 KeySym tmp_keyval = NoSymbol;
767 g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
768 g_return_val_if_fail (group < 4, FALSE);
773 *effective_group = 0;
776 if (unused_modifiers)
777 *unused_modifiers = state;
781 if (hardware_keycode < min_keycode ||
782 hardware_keycode > max_keycode)
788 XkbDescRec *xkb = get_xkb ();
790 /* replace bits 13 and 14 with the provided group */
791 state &= ~(1 << 13 | 1 << 14);
792 state |= group << 13;
794 MyEnhancedXkbTranslateKeyCode (xkb,
803 *keyval = tmp_keyval;
812 if ((state & GDK_SHIFT_MASK) &&
813 (state & GDK_LOCK_MASK))
814 shift_level = 0; /* shift disables shift lock */
815 else if ((state & GDK_SHIFT_MASK) ||
816 (state & GDK_LOCK_MASK))
821 tmp_keyval = XKeycodeToKeysym (gdk_display, hardware_keycode,
822 group * keysyms_per_keycode + shift_level);
825 *keyval = tmp_keyval;
827 if (unused_modifiers)
829 *unused_modifiers = state;
830 *unused_modifiers &= ~(GDK_SHIFT_MASK | GDK_LOCK_MASK | group_switch_mask);
834 *effective_group = (state & group_switch_mask) ? 1 : 0;
837 *level = shift_level;
840 return tmp_keyval != NoSymbol;
844 /* Key handling not part of the keymap */
847 gdk_keyval_name (guint keyval)
849 return XKeysymToString (keyval);
853 gdk_keyval_from_name (const gchar *keyval_name)
855 g_return_val_if_fail (keyval_name != NULL, 0);
857 return XStringToKeysym (keyval_name);
860 #ifdef HAVE_XCONVERTCASE
862 gdk_keyval_convert_case (guint symbol,
870 XConvertCase (symbol, &xlower, &xupper);
877 #endif /* HAVE_XCONVERTCASE */