]> Pileus Git - ~andy/gtk/blob - gdk/gdkkeys.c
gdk: remove the GET_EFFECTIVE_KEYMAP() stuff from gdkkeys-x11.c
[~andy/gtk] / gdk / gdkkeys.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 2000 Red Hat, Inc.
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 /*
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/.
25  */
26
27 #include "config.h"
28
29 #include "gdkkeysyms.h"
30 #include "gdkkeysprivate.h"
31 #include "gdkdisplay.h"
32 #include "gdkdisplaymanagerprivate.h"
33
34
35 /**
36  * SECTION:keys
37  * @Short_description: Functions for manipulating keyboard codes
38  * @Title: Key Values
39  *
40  * Key values are the codes which are sent whenever a key is pressed or released.
41  * They appear in the #GdkEventKey.keyval field of the
42  * #GdkEventKey structure, which is passed to signal handlers for the
43  * #GtkWidget::key-press-event and #GtkWidget::key-release-event signals.
44  * The complete list of key values can be found in the
45  * <filename>&lt;gdk/gdkkeysyms.h&gt;</filename> header file.
46  *
47  * Key values are regularly updated from the upstream X.org X11 implementation,
48  * so new values are added regularly. They will be prefixed with GDK_KEY_ rather
49  * than XF86XK_ or XK_ (for older symbols).
50  *
51  * Key values can be converted into a string representation using
52  * gdk_keyval_name(). The reverse function, converting a string to a key value,
53  * is provided by gdk_keyval_from_name().
54  *
55  * The case of key values can be determined using gdk_keyval_is_upper() and
56  * gdk_keyval_is_lower(). Key values can be converted to upper or lower case
57  * using gdk_keyval_to_upper() and gdk_keyval_to_lower().
58  *
59  * When it makes sense, key values can be converted to and from
60  * Unicode characters with gdk_keyval_to_unicode() and gdk_unicode_to_keyval().
61  *
62  * <para id="key-group-explanation">
63  * One #GdkKeymap object exists for each user display. gdk_keymap_get_default()
64  * returns the #GdkKeymap for the default display; to obtain keymaps for other
65  * displays, use gdk_keymap_get_for_display(). A keymap
66  * is a mapping from #GdkKeymapKey to key values. You can think of a #GdkKeymapKey
67  * as a representation of a symbol printed on a physical keyboard key. That is, it
68  * contains three pieces of information. First, it contains the hardware keycode;
69  * this is an identifying number for a physical key. Second, it contains the
70  * <firstterm>level</firstterm> of the key. The level indicates which symbol on the
71  * key will be used, in a vertical direction. So on a standard US keyboard, the key
72  * with the number "1" on it also has the exclamation point ("!") character on
73  * it. The level indicates whether to use the "1" or the "!" symbol.  The letter
74  * keys are considered to have a lowercase letter at level 0, and an uppercase
75  * letter at level 1, though only the uppercase letter is printed.  Third, the
76  * #GdkKeymapKey contains a group; groups are not used on standard US keyboards,
77  * but are used in many other countries. On a keyboard with groups, there can be 3
78  * or 4 symbols printed on a single key. The group indicates movement in a
79  * horizontal direction. Usually groups are used for two different languages.  In
80  * group 0, a key might have two English characters, and in group 1 it might have
81  * two Hebrew characters. The Hebrew characters will be printed on the key next to
82  * the English characters.
83  * </para>
84  *
85  * In order to use a keymap to interpret a key event, it's necessary to first
86  * convert the keyboard state into an effective group and level. This is done via a
87  * set of rules that varies widely according to type of keyboard and user
88  * configuration. The function gdk_keymap_translate_keyboard_state() accepts a
89  * keyboard state -- consisting of hardware keycode pressed, active modifiers, and
90  * active group -- applies the appropriate rules, and returns the group/level to be
91  * used to index the keymap, along with the modifiers which did not affect the
92  * group and level. i.e. it returns "unconsumed modifiers." The keyboard group may
93  * differ from the effective group used for keymap lookups because some keys don't
94  * have multiple groups - e.g. the Enter key is always in group 0 regardless of
95  * keyboard state.
96  *
97  * Note that gdk_keymap_translate_keyboard_state() also returns the keyval, i.e. it
98  * goes ahead and performs the keymap lookup in addition to telling you which
99  * effective group/level values were used for the lookup. #GdkEventKey already
100  * contains this keyval, however, so you don't normally need to call
101  * gdk_keymap_translate_keyboard_state() just to get the keyval.
102  */
103
104
105 enum {
106   DIRECTION_CHANGED,
107   KEYS_CHANGED,
108   STATE_CHANGED,
109   LAST_SIGNAL
110 };
111
112
113 static GdkModifierType gdk_keymap_real_get_modifier_mask (GdkKeymap         *keymap,
114                                                           GdkModifierIntent  intent);
115
116
117 static guint signals[LAST_SIGNAL] = { 0 };
118
119 G_DEFINE_TYPE (GdkKeymap, gdk_keymap, G_TYPE_OBJECT)
120
121 static void
122 gdk_keymap_class_init (GdkKeymapClass *klass)
123 {
124   GObjectClass *object_class = G_OBJECT_CLASS (klass);
125
126   klass->get_modifier_mask = gdk_keymap_real_get_modifier_mask;
127
128   /**
129    * GdkKeymap::direction-changed:
130    * @keymap: the object on which the signal is emitted
131    *
132    * The ::direction-changed signal gets emitted when the direction of
133    * the keymap changes.
134    *
135    * Since: 2.0
136    */
137   signals[DIRECTION_CHANGED] =
138     g_signal_new ("direction-changed",
139                   G_OBJECT_CLASS_TYPE (object_class),
140                   G_SIGNAL_RUN_LAST,
141                   G_STRUCT_OFFSET (GdkKeymapClass, direction_changed),
142                   NULL, NULL,
143                   g_cclosure_marshal_VOID__VOID,
144                   G_TYPE_NONE,
145                   0);
146   /**
147    * GdkKeymap::keys-changed:
148    * @keymap: the object on which the signal is emitted
149    *
150    * The ::keys-changed signal is emitted when the mapping represented by
151    * @keymap changes.
152    *
153    * Since: 2.2
154    */
155   signals[KEYS_CHANGED] =
156     g_signal_new ("keys-changed",
157                   G_OBJECT_CLASS_TYPE (object_class),
158                   G_SIGNAL_RUN_LAST,
159                   G_STRUCT_OFFSET (GdkKeymapClass, keys_changed),
160                   NULL, NULL,
161                   g_cclosure_marshal_VOID__VOID,
162                   G_TYPE_NONE,
163                   0);
164
165   /**
166    * GdkKeymap::state-changed:
167    * @keymap: the object on which the signal is emitted
168    *
169    * The ::state-changed signal is emitted when the state of the
170    * keyboard changes, e.g when Caps Lock is turned on or off.
171    * See gdk_keymap_get_caps_lock_state().
172    *
173    * Since: 2.16
174    */
175   signals[STATE_CHANGED] =
176     g_signal_new ("state_changed",
177                   G_OBJECT_CLASS_TYPE (object_class),
178                   G_SIGNAL_RUN_LAST,
179                   G_STRUCT_OFFSET (GdkKeymapClass, state_changed),
180                   NULL, NULL,
181                   g_cclosure_marshal_VOID__VOID,
182                   G_TYPE_NONE,
183                   0);
184 }
185
186 static void
187 gdk_keymap_init (GdkKeymap *keymap)
188 {
189 }
190
191 /* Other key-handling stuff
192  */
193
194 /**
195  * gdk_keyval_convert_case:
196  * @symbol: a keyval
197  * @lower: (out): return location for lowercase version of @symbol
198  * @upper: (out): return location for uppercase version of @symbol
199  *
200  * Obtains the upper- and lower-case versions of the keyval @symbol.
201  * Examples of keyvals are #GDK_KEY_a, #GDK_KEY_Enter, #GDK_KEY_F1, etc.
202  */
203 void
204 gdk_keyval_convert_case (guint symbol,
205                          guint *lower,
206                          guint *upper)
207 {
208   GdkDisplayManager *manager = gdk_display_manager_get ();
209
210   GDK_DISPLAY_MANAGER_GET_CLASS (manager)->keyval_convert_case (manager, symbol, lower, upper);
211 }
212
213 /**
214  * gdk_keyval_to_upper:
215  * @keyval: a key value.
216  *
217  * Converts a key value to upper case, if applicable.
218  *
219  * Returns: the upper case form of @keyval, or @keyval itself if it is already
220  *   in upper case or it is not subject to case conversion.
221  */
222 guint
223 gdk_keyval_to_upper (guint keyval)
224 {
225   guint result;
226
227   gdk_keyval_convert_case (keyval, NULL, &result);
228
229   return result;
230 }
231
232 /**
233  * gdk_keyval_to_lower:
234  * @keyval: a key value.
235  *
236  * Converts a key value to lower case, if applicable.
237  *
238  * Returns: the lower case form of @keyval, or @keyval itself if it is already
239  *  in lower case or it is not subject to case conversion.
240  */
241 guint
242 gdk_keyval_to_lower (guint keyval)
243 {
244   guint result;
245
246   gdk_keyval_convert_case (keyval, &result, NULL);
247
248   return result;
249 }
250
251 /**
252  * gdk_keyval_is_upper:
253  * @keyval: a key value.
254  *
255  * Returns %TRUE if the given key value is in upper case.
256  *
257  * Returns: %TRUE if @keyval is in upper case, or if @keyval is not subject to
258  *  case conversion.
259  */
260 gboolean
261 gdk_keyval_is_upper (guint keyval)
262 {
263   if (keyval)
264     {
265       guint upper_val = 0;
266
267       gdk_keyval_convert_case (keyval, NULL, &upper_val);
268       return upper_val == keyval;
269     }
270   return FALSE;
271 }
272
273 /**
274  * gdk_keyval_is_lower:
275  * @keyval: a key value.
276  *
277  * Returns %TRUE if the given key value is in lower case.
278  *
279  * Returns: %TRUE if @keyval is in lower case, or if @keyval is not
280  *   subject to case conversion.
281  */
282 gboolean
283 gdk_keyval_is_lower (guint keyval)
284 {
285   if (keyval)
286     {
287       guint lower_val = 0;
288
289       gdk_keyval_convert_case (keyval, &lower_val, NULL);
290       return lower_val == keyval;
291     }
292   return FALSE;
293 }
294
295 /**
296  * gdk_keymap_get_default:
297  *
298  * Returns the #GdkKeymap attached to the default display.
299  *
300  * Returns: (transfer none): the #GdkKeymap attached to the default display.
301  */
302 GdkKeymap*
303 gdk_keymap_get_default (void)
304 {
305   return gdk_keymap_get_for_display (gdk_display_get_default ());
306 }
307
308 /**
309  * gdk_keymap_get_direction:
310  * @keymap: a #GdkKeymap
311  *
312  * Returns the direction of effective layout of the keymap.
313  *
314  * Returns: %PANGO_DIRECTION_LTR or %PANGO_DIRECTION_RTL
315  *   if it can determine the direction. %PANGO_DIRECTION_NEUTRAL
316  *   otherwise.
317  **/
318 PangoDirection
319 gdk_keymap_get_direction (GdkKeymap *keymap)
320 {
321   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), PANGO_DIRECTION_LTR);
322
323   return GDK_KEYMAP_GET_CLASS (keymap)->get_direction (keymap);
324 }
325
326 /**
327  * gdk_keymap_have_bidi_layouts:
328  * @keymap: a #GdkKeymap
329  *
330  * Determines if keyboard layouts for both right-to-left and left-to-right
331  * languages are in use.
332  *
333  * Returns: %TRUE if there are layouts in both directions, %FALSE otherwise
334  *
335  * Since: 2.12
336  **/
337 gboolean
338 gdk_keymap_have_bidi_layouts (GdkKeymap *keymap)
339 {
340   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), FALSE);
341
342   return GDK_KEYMAP_GET_CLASS (keymap)->have_bidi_layouts (keymap);
343 }
344
345 /**
346  * gdk_keymap_get_caps_lock_state:
347  * @keymap: a #GdkKeymap
348  *
349  * Returns whether the Caps Lock modifer is locked.
350  *
351  * Returns: %TRUE if Caps Lock is on
352  *
353  * Since: 2.16
354  */
355 gboolean
356 gdk_keymap_get_caps_lock_state (GdkKeymap *keymap)
357 {
358   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), FALSE);
359
360   return GDK_KEYMAP_GET_CLASS (keymap)->get_caps_lock_state (keymap);
361 }
362
363 /**
364  * gdk_keymap_get_num_lock_state:
365  * @keymap: a #GdkKeymap
366  *
367  * Returns whether the Num Lock modifer is locked.
368  *
369  * Returns: %TRUE if Num Lock is on
370  *
371  * Since: 3.0
372  */
373 gboolean
374 gdk_keymap_get_num_lock_state (GdkKeymap *keymap)
375 {
376   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), FALSE);
377
378   return GDK_KEYMAP_GET_CLASS (keymap)->get_num_lock_state (keymap);
379 }
380
381 /**
382  * gdk_keymap_get_entries_for_keyval:
383  * @keymap: a #GdkKeymap
384  * @keyval: a keyval, such as %GDK_a, %GDK_Up, %GDK_Return, etc.
385  * @keys: (out) (array length=n_keys) (transfer full): return location
386  *     for an array of #GdkKeymapKey
387  * @n_keys: return location for number of elements in returned array
388  *
389  * Obtains a list of keycode/group/level combinations that will
390  * generate @keyval. Groups and levels are two kinds of keyboard mode;
391  * in general, the level determines whether the top or bottom symbol
392  * on a key is used, and the group determines whether the left or
393  * right symbol is used. On US keyboards, the shift key changes the
394  * keyboard level, and there are no groups. A group switch key might
395  * convert a keyboard between Hebrew to English modes, for example.
396  * #GdkEventKey contains a %group field that indicates the active
397  * keyboard group. The level is computed from the modifier mask.
398  * The returned array should be freed
399  * with g_free().
400  *
401  * Return value: %TRUE if keys were found and returned
402  **/
403 gboolean
404 gdk_keymap_get_entries_for_keyval (GdkKeymap     *keymap,
405                                    guint          keyval,
406                                    GdkKeymapKey **keys,
407                                    gint          *n_keys)
408 {
409   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), FALSE);
410   g_return_val_if_fail (keys != NULL, FALSE);
411   g_return_val_if_fail (n_keys != NULL, FALSE);
412   g_return_val_if_fail (keyval != 0, FALSE);
413
414   return GDK_KEYMAP_GET_CLASS (keymap)->get_entries_for_keyval (keymap, keyval,
415                                                                 keys, n_keys);
416 }
417
418 /**
419  * gdk_keymap_get_entries_for_keycode:
420  * @keymap: a #GdkKeymap
421  * @hardware_keycode: a keycode
422  * @keys: (out) (array length=n_entries) (transfer full): return
423  *     location for array of #GdkKeymapKey, or %NULL
424  * @keyvals: (out) (array length=n_entries) (transfer full): return
425  *     location for array of keyvals, or %NULL
426  * @n_entries: length of @keys and @keyvals
427  *
428  * Returns the keyvals bound to @hardware_keycode.
429  * The Nth #GdkKeymapKey in @keys is bound to the Nth
430  * keyval in @keyvals. Free the returned arrays with g_free().
431  * When a keycode is pressed by the user, the keyval from
432  * this list of entries is selected by considering the effective
433  * keyboard group and level. See gdk_keymap_translate_keyboard_state().
434  *
435  * Returns: %TRUE if there were any entries
436  **/
437 gboolean
438 gdk_keymap_get_entries_for_keycode (GdkKeymap     *keymap,
439                                     guint          hardware_keycode,
440                                     GdkKeymapKey **keys,
441                                     guint        **keyvals,
442                                     gint          *n_entries)
443 {
444   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), FALSE);
445   g_return_val_if_fail (n_entries != NULL, FALSE);
446
447   return GDK_KEYMAP_GET_CLASS (keymap)->get_entries_for_keycode (keymap, hardware_keycode,
448                                                                  keys, keyvals, n_entries);
449 }
450
451 /**
452  * gdk_keymap_lookup_key:
453  * @keymap: a #GdkKeymap
454  * @key: a #GdkKeymapKey with keycode, group, and level initialized
455  *
456  * Looks up the keyval mapped to a keycode/group/level triplet.
457  * If no keyval is bound to @key, returns 0. For normal user input,
458  * you want to use gdk_keymap_translate_keyboard_state() instead of
459  * this function, since the effective group/level may not be
460  * the same as the current keyboard state.
461  *
462  * Return value: a keyval, or 0 if none was mapped to the given @key
463  **/
464 guint
465 gdk_keymap_lookup_key (GdkKeymap          *keymap,
466                        const GdkKeymapKey *key)
467 {
468   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), 0);
469   g_return_val_if_fail (key != NULL, 0);
470
471   return GDK_KEYMAP_GET_CLASS (keymap)->lookup_key (keymap, key);
472 }
473
474 /**
475  * gdk_keymap_translate_keyboard_state:
476  * @keymap: a #GdkKeymap
477  * @hardware_keycode: a keycode
478  * @state: a modifier state
479  * @group: active keyboard group
480  * @keyval: (out) (allow-none): return location for keyval, or %NULL
481  * @effective_group: (out) (allow-none): return location for effective
482  *     group, or %NULL
483  * @level: (out) (allow-none): return location for level, or %NULL
484  * @consumed_modifiers: (out) (allow-none): return location for modifiers
485  *     that were used to determine the group or level, or %NULL
486  *
487  * Translates the contents of a #GdkEventKey into a keyval, effective
488  * group, and level. Modifiers that affected the translation and
489  * are thus unavailable for application use are returned in
490  * @consumed_modifiers.
491  * See <xref linkend="key-group-explanation"/> for an explanation of
492  * groups and levels. The @effective_group is the group that was
493  * actually used for the translation; some keys such as Enter are not
494  * affected by the active keyboard group. The @level is derived from
495  * @state. For convenience, #GdkEventKey already contains the translated
496  * keyval, so this function isn't as useful as you might think.
497  *
498  * <note><para>
499  * @consumed_modifiers gives modifiers that should be masked out
500  * from @state when comparing this key press to a hot key. For
501  * instance, on a US keyboard, the <literal>plus</literal>
502  * symbol is shifted, so when comparing a key press to a
503  * <literal>&lt;Control&gt;plus</literal> accelerator &lt;Shift&gt; should
504  * be masked out.
505  * </para>
506  * <informalexample><programlisting>
507  * &sol;* We want to ignore irrelevant modifiers like ScrollLock *&sol;
508  * &num;define ALL_ACCELS_MASK (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK)
509  * gdk_keymap_translate_keyboard_state (keymap, event->hardware_keycode,
510  *                                      event->state, event->group,
511  *                                      &amp;keyval, NULL, NULL, &amp;consumed);
512  * if (keyval == GDK_PLUS &&
513  *     (event->state &amp; ~consumed &amp; ALL_ACCELS_MASK) == GDK_CONTROL_MASK)
514  *   &sol;* Control was pressed *&sol;
515  * </programlisting></informalexample>
516  * <para>
517  * An older interpretation @consumed_modifiers was that it contained
518  * all modifiers that might affect the translation of the key;
519  * this allowed accelerators to be stored with irrelevant consumed
520  * modifiers, by doing:</para>
521  * <informalexample><programlisting>
522  * &sol;* XXX Don't do this XXX *&sol;
523  * if (keyval == accel_keyval &&
524  *     (event->state &amp; ~consumed &amp; ALL_ACCELS_MASK) == (accel_mods &amp; ~consumed))
525  *   &sol;* Accelerator was pressed *&sol;
526  * </programlisting></informalexample>
527  * <para>
528  * However, this did not work if multi-modifier combinations were
529  * used in the keymap, since, for instance, <literal>&lt;Control&gt;</literal>
530  * would be masked out even if only <literal>&lt;Control&gt;&lt;Alt&gt;</literal>
531  * was used in the keymap. To support this usage as well as well as
532  * possible, all <emphasis>single modifier</emphasis> combinations
533  * that could affect the key for any combination of modifiers will
534  * be returned in @consumed_modifiers; multi-modifier combinations
535  * are returned only when actually found in @state. When you store
536  * accelerators, you should always store them with consumed modifiers
537  * removed. Store <literal>&lt;Control&gt;plus</literal>,
538  * not <literal>&lt;Control&gt;&lt;Shift&gt;plus</literal>,
539  * </para></note>
540  *
541  * Return value: %TRUE if there was a keyval bound to the keycode/state/group
542  **/
543 gboolean
544 gdk_keymap_translate_keyboard_state (GdkKeymap       *keymap,
545                                      guint            hardware_keycode,
546                                      GdkModifierType  state,
547                                      gint             group,
548                                      guint           *keyval,
549                                      gint            *effective_group,
550                                      gint            *level,
551                                      GdkModifierType *consumed_modifiers)
552 {
553   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), FALSE);
554
555   return GDK_KEYMAP_GET_CLASS (keymap)->translate_keyboard_state (keymap,
556                                                                   hardware_keycode,
557                                                                   state,
558                                                                   group,
559                                                                   keyval,
560                                                                   effective_group,
561                                                                   level,
562                                                                   consumed_modifiers);
563 }
564
565 /**
566  * gdk_keymap_add_virtual_modifiers:
567  * @keymap: a #GdkKeymap
568  * @state: (out): pointer to the modifier mask to change
569  *
570  * Adds virtual modifiers (i.e. Super, Hyper and Meta) which correspond
571  * to the real modifiers (i.e Mod2, Mod3, ...) in @modifiers.
572  * are set in @state to their non-virtual counterparts (i.e. Mod2,
573  * Mod3,...) and set the corresponding bits in @state.
574  *
575  * GDK already does this before delivering key events, but for
576  * compatibility reasons, it only sets the first virtual modifier
577  * it finds, whereas this function sets all matching virtual modifiers.
578  *
579  * This function is useful when matching key events against
580  * accelerators.
581  *
582  * Since: 2.20
583  */
584 void
585 gdk_keymap_add_virtual_modifiers (GdkKeymap       *keymap,
586                                   GdkModifierType *state)
587 {
588   g_return_if_fail (GDK_IS_KEYMAP (keymap));
589
590   GDK_KEYMAP_GET_CLASS (keymap)->add_virtual_modifiers (keymap, state);
591 }
592
593 /**
594  * gdk_keymap_map_virtual_modifiers:
595  * @keymap: a #GdkKeymap
596  * @state: (out): pointer to the modifier state to map
597  *
598  * Maps the virtual modifiers (i.e. Super, Hyper and Meta) which
599  * are set in @state to their non-virtual counterparts (i.e. Mod2,
600  * Mod3,...) and set the corresponding bits in @state.
601  *
602  * This function is useful when matching key events against
603  * accelerators.
604  *
605  * Returns: %TRUE if no virtual modifiers were mapped to the
606  *     same non-virtual modifier. Note that %FALSE is also returned
607  *     if a virtual modifier is mapped to a non-virtual modifier that
608  *     was already set in @state.
609  *
610  * Since: 2.20
611  */
612 gboolean
613 gdk_keymap_map_virtual_modifiers (GdkKeymap       *keymap,
614                                   GdkModifierType *state)
615 {
616   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), FALSE);
617
618   return GDK_KEYMAP_GET_CLASS(keymap)->map_virtual_modifiers (keymap, state);
619 }
620
621 static GdkModifierType
622 gdk_keymap_real_get_modifier_mask (GdkKeymap         *keymap,
623                                    GdkModifierIntent  intent)
624 {
625   switch (intent)
626     {
627     case GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR:
628       return GDK_CONTROL_MASK;
629
630     case GDK_MODIFIER_INTENT_CONTEXT_MENU:
631       return 0;
632
633     case GDK_MODIFIER_INTENT_EXTEND_SELECTION:
634       return GDK_SHIFT_MASK;
635
636     case GDK_MODIFIER_INTENT_MODIFY_SELECTION:
637       return GDK_CONTROL_MASK;
638
639     case GDK_MODIFIER_INTENT_NO_TEXT_INPUT:
640       return GDK_MOD1_MASK | GDK_CONTROL_MASK;
641
642     case GDK_MODIFIER_INTENT_SHIFT_GROUP:
643       return 0;
644
645     default:
646       g_return_val_if_reached (0);
647     }
648 }
649
650 /**
651  * gdk_keymap_get_modifier_mask:
652  * @keymap: a #GdkKeymap
653  * @intent: the use case for the modifier mask
654  *
655  * Returns the modifier mask the @keymap's windowing system backend
656  * uses for a particular purpose.
657  *
658  * Note that this function always returns real hardware modifiers, not
659  * virtual ones (e.g. it will return #GDK_MOD1_MASK rather than
660  * #GDK_META_MASK if the backend maps MOD1 to META), so there are use
661  * cases where the return value of this function has to be transformed
662  * by gdk_keymap_add_virtual_modifiers() in order to contain the
663  * expected result.
664  *
665  * Returns: the modifier mask used for @intent.
666  *
667  * Since: 3.4
668  **/
669 GdkModifierType
670 gdk_keymap_get_modifier_mask (GdkKeymap         *keymap,
671                               GdkModifierIntent  intent)
672 {
673   g_return_val_if_fail (GDK_IS_KEYMAP (keymap), 0);
674
675   return GDK_KEYMAP_GET_CLASS (keymap)->get_modifier_mask (keymap, intent);
676 }
677
678
679 /**
680  * gdk_keyval_name:
681  * @keyval: a key value
682  *
683  * Converts a key value into a symbolic name.
684  *
685  * The names are the same as those in the
686  * <filename>&lt;gdk/gdkkeysyms.h&gt;</filename> header file
687  * but without the leading "GDK_KEY_".
688  *
689  * Return value: (transfer none): a string containing the name of the key,
690  *     or %NULL if @keyval is not a valid key. The string should not be
691  *     modified.
692  */
693 gchar *
694 gdk_keyval_name (guint keyval)
695 {
696   GdkDisplayManager *manager = gdk_display_manager_get ();
697
698   return GDK_DISPLAY_MANAGER_GET_CLASS (manager)->get_keyval_name (manager,
699                                                                    keyval);
700 }
701
702 /**
703  * gdk_keyval_from_name:
704  * @keyval_name: a key name
705  *
706  * Converts a key name to a key value.
707  *
708  * The names are the same as those in the
709  * <filename>&lt;gdk/gdkkeysyms.h&gt;</filename> header file
710  * but without the leading "GDK_KEY_".
711  *
712  * Returns: the corresponding key value, or %GDK_KEY_VoidSymbol
713  *     if the key name is not a valid key
714  */
715 guint
716 gdk_keyval_from_name (const gchar *keyval_name)
717 {
718   GdkDisplayManager *manager = gdk_display_manager_get ();
719
720   return GDK_DISPLAY_MANAGER_GET_CLASS (manager)->lookup_keyval (manager,
721                                                                  keyval_name);
722 }
723
724 void
725 _gdk_display_manager_real_keyval_convert_case (GdkDisplayManager *manager,
726                                                guint              symbol,
727                                                guint             *lower,
728                                                guint             *upper)
729 {
730   guint xlower = symbol;
731   guint xupper = symbol;
732
733   /* Check for directly encoded 24-bit UCS characters: */
734   if ((symbol & 0xff000000) == 0x01000000)
735     {
736       if (lower)
737         *lower = gdk_unicode_to_keyval (g_unichar_tolower (symbol & 0x00ffffff));
738       if (upper)
739         *upper = gdk_unicode_to_keyval (g_unichar_toupper (symbol & 0x00ffffff));
740       return;
741     }
742
743   switch (symbol >> 8)
744     {
745     case 0: /* Latin 1 */
746       if ((symbol >= GDK_KEY_A) && (symbol <= GDK_KEY_Z))
747         xlower += (GDK_KEY_a - GDK_KEY_A);
748       else if ((symbol >= GDK_KEY_a) && (symbol <= GDK_KEY_z))
749         xupper -= (GDK_KEY_a - GDK_KEY_A);
750       else if ((symbol >= GDK_KEY_Agrave) && (symbol <= GDK_KEY_Odiaeresis))
751         xlower += (GDK_KEY_agrave - GDK_KEY_Agrave);
752       else if ((symbol >= GDK_KEY_agrave) && (symbol <= GDK_KEY_odiaeresis))
753         xupper -= (GDK_KEY_agrave - GDK_KEY_Agrave);
754       else if ((symbol >= GDK_KEY_Ooblique) && (symbol <= GDK_KEY_Thorn))
755         xlower += (GDK_KEY_oslash - GDK_KEY_Ooblique);
756       else if ((symbol >= GDK_KEY_oslash) && (symbol <= GDK_KEY_thorn))
757         xupper -= (GDK_KEY_oslash - GDK_KEY_Ooblique);
758       break;
759
760     case 1: /* Latin 2 */
761       /* Assume the KeySym is a legal value (ignore discontinuities) */
762       if (symbol == GDK_KEY_Aogonek)
763         xlower = GDK_KEY_aogonek;
764       else if (symbol >= GDK_KEY_Lstroke && symbol <= GDK_KEY_Sacute)
765         xlower += (GDK_KEY_lstroke - GDK_KEY_Lstroke);
766       else if (symbol >= GDK_KEY_Scaron && symbol <= GDK_KEY_Zacute)
767         xlower += (GDK_KEY_scaron - GDK_KEY_Scaron);
768       else if (symbol >= GDK_KEY_Zcaron && symbol <= GDK_KEY_Zabovedot)
769         xlower += (GDK_KEY_zcaron - GDK_KEY_Zcaron);
770       else if (symbol == GDK_KEY_aogonek)
771         xupper = GDK_KEY_Aogonek;
772       else if (symbol >= GDK_KEY_lstroke && symbol <= GDK_KEY_sacute)
773         xupper -= (GDK_KEY_lstroke - GDK_KEY_Lstroke);
774       else if (symbol >= GDK_KEY_scaron && symbol <= GDK_KEY_zacute)
775         xupper -= (GDK_KEY_scaron - GDK_KEY_Scaron);
776       else if (symbol >= GDK_KEY_zcaron && symbol <= GDK_KEY_zabovedot)
777         xupper -= (GDK_KEY_zcaron - GDK_KEY_Zcaron);
778       else if (symbol >= GDK_KEY_Racute && symbol <= GDK_KEY_Tcedilla)
779         xlower += (GDK_KEY_racute - GDK_KEY_Racute);
780       else if (symbol >= GDK_KEY_racute && symbol <= GDK_KEY_tcedilla)
781         xupper -= (GDK_KEY_racute - GDK_KEY_Racute);
782       break;
783
784     case 2: /* Latin 3 */
785       /* Assume the KeySym is a legal value (ignore discontinuities) */
786       if (symbol >= GDK_KEY_Hstroke && symbol <= GDK_KEY_Hcircumflex)
787         xlower += (GDK_KEY_hstroke - GDK_KEY_Hstroke);
788       else if (symbol >= GDK_KEY_Gbreve && symbol <= GDK_KEY_Jcircumflex)
789         xlower += (GDK_KEY_gbreve - GDK_KEY_Gbreve);
790       else if (symbol >= GDK_KEY_hstroke && symbol <= GDK_KEY_hcircumflex)
791         xupper -= (GDK_KEY_hstroke - GDK_KEY_Hstroke);
792       else if (symbol >= GDK_KEY_gbreve && symbol <= GDK_KEY_jcircumflex)
793         xupper -= (GDK_KEY_gbreve - GDK_KEY_Gbreve);
794       else if (symbol >= GDK_KEY_Cabovedot && symbol <= GDK_KEY_Scircumflex)
795         xlower += (GDK_KEY_cabovedot - GDK_KEY_Cabovedot);
796       else if (symbol >= GDK_KEY_cabovedot && symbol <= GDK_KEY_scircumflex)
797         xupper -= (GDK_KEY_cabovedot - GDK_KEY_Cabovedot);
798       break;
799
800     case 3: /* Latin 4 */
801       /* Assume the KeySym is a legal value (ignore discontinuities) */
802       if (symbol >= GDK_KEY_Rcedilla && symbol <= GDK_KEY_Tslash)
803         xlower += (GDK_KEY_rcedilla - GDK_KEY_Rcedilla);
804       else if (symbol >= GDK_KEY_rcedilla && symbol <= GDK_KEY_tslash)
805         xupper -= (GDK_KEY_rcedilla - GDK_KEY_Rcedilla);
806       else if (symbol == GDK_KEY_ENG)
807         xlower = GDK_KEY_eng;
808       else if (symbol == GDK_KEY_eng)
809         xupper = GDK_KEY_ENG;
810       else if (symbol >= GDK_KEY_Amacron && symbol <= GDK_KEY_Umacron)
811         xlower += (GDK_KEY_amacron - GDK_KEY_Amacron);
812       else if (symbol >= GDK_KEY_amacron && symbol <= GDK_KEY_umacron)
813         xupper -= (GDK_KEY_amacron - GDK_KEY_Amacron);
814       break;
815
816     case 6: /* Cyrillic */
817       /* Assume the KeySym is a legal value (ignore discontinuities) */
818       if (symbol >= GDK_KEY_Serbian_DJE && symbol <= GDK_KEY_Serbian_DZE)
819         xlower -= (GDK_KEY_Serbian_DJE - GDK_KEY_Serbian_dje);
820       else if (symbol >= GDK_KEY_Serbian_dje && symbol <= GDK_KEY_Serbian_dze)
821         xupper += (GDK_KEY_Serbian_DJE - GDK_KEY_Serbian_dje);
822       else if (symbol >= GDK_KEY_Cyrillic_YU && symbol <= GDK_KEY_Cyrillic_HARDSIGN)
823         xlower -= (GDK_KEY_Cyrillic_YU - GDK_KEY_Cyrillic_yu);
824       else if (symbol >= GDK_KEY_Cyrillic_yu && symbol <= GDK_KEY_Cyrillic_hardsign)
825         xupper += (GDK_KEY_Cyrillic_YU - GDK_KEY_Cyrillic_yu);
826       break;
827
828     case 7: /* Greek */
829       /* Assume the KeySym is a legal value (ignore discontinuities) */
830       if (symbol >= GDK_KEY_Greek_ALPHAaccent && symbol <= GDK_KEY_Greek_OMEGAaccent)
831         xlower += (GDK_KEY_Greek_alphaaccent - GDK_KEY_Greek_ALPHAaccent);
832       else if (symbol >= GDK_KEY_Greek_alphaaccent && symbol <= GDK_KEY_Greek_omegaaccent &&
833                symbol != GDK_KEY_Greek_iotaaccentdieresis &&
834                symbol != GDK_KEY_Greek_upsilonaccentdieresis)
835         xupper -= (GDK_KEY_Greek_alphaaccent - GDK_KEY_Greek_ALPHAaccent);
836       else if (symbol >= GDK_KEY_Greek_ALPHA && symbol <= GDK_KEY_Greek_OMEGA)
837         xlower += (GDK_KEY_Greek_alpha - GDK_KEY_Greek_ALPHA);
838       else if (symbol >= GDK_KEY_Greek_alpha && symbol <= GDK_KEY_Greek_omega &&
839                symbol != GDK_KEY_Greek_finalsmallsigma)
840         xupper -= (GDK_KEY_Greek_alpha - GDK_KEY_Greek_ALPHA);
841       break;
842     }
843
844   if (lower)
845     *lower = xlower;
846   if (upper)
847     *upper = xupper;
848 }