📄 gdkkeys-x11.c
字号:
group_atom = xkb->names->groups[group]; /* a group change? */ if (!keymap_x11->have_direction || keymap_x11->current_group_atom != group_atom) { gboolean cache_hit = FALSE; DirectionCacheEntry *cache = keymap_x11->group_direction_cache; PangoDirection direction = PANGO_DIRECTION_NEUTRAL; gint i; if (keymap_x11->have_direction) { /* lookup in cache */ for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++) { if (cache[i].group_atom == group_atom) { cache_hit = TRUE; cache[i].serial = keymap_x11->current_cache_serial++; /* freshen */ direction = cache[i].direction; group_atom = cache[i].group_atom; break; } } } else { /* initialize cache */ for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++) { cache[i].group_atom = 0; cache[i].serial = keymap_x11->current_cache_serial; } keymap_x11->current_cache_serial++; } /* insert in cache */ if (!cache_hit) { gint oldest = 0; direction = get_direction (xkb, group); /* remove the oldest entry */ for (i = 0; i < G_N_ELEMENTS (keymap_x11->group_direction_cache); i++) { if (cache[i].serial < cache[oldest].serial) oldest = i; } cache[oldest].group_atom = group_atom; cache[oldest].direction = direction; cache[oldest].serial = keymap_x11->current_cache_serial++; } keymap_x11->current_group_atom = group_atom; keymap_x11->have_direction = TRUE; keymap_x11->current_direction = direction; }}static void_gdk_keymap_direction_changed (GdkKeymapX11 *keymap_x11){ gboolean had_direction; PangoDirection direction; had_direction = keymap_x11->have_direction; direction = keymap_x11->current_direction; update_direction (keymap_x11); if (!had_direction || direction != keymap_x11->current_direction) g_signal_emit_by_name (keymap_x11, "direction_changed");}void_gdk_keymap_state_changed (GdkDisplay *display){ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); if (display_x11->keymap) { GdkKeymapX11 *keymap_x11 = GDK_KEYMAP_X11 (display_x11->keymap); _gdk_keymap_direction_changed (keymap_x11); }}#endif /* HAVE_XKB */void_gdk_keymap_keys_changed (GdkDisplay *display){ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); ++display_x11->keymap_serial; if (display_x11->keymap) g_signal_emit_by_name (display_x11->keymap, "keys_changed", 0);}PangoDirectiongdk_keymap_get_direction (GdkKeymap *keymap){ keymap = GET_EFFECTIVE_KEYMAP (keymap); #if HAVE_XKB if (KEYMAP_USE_XKB (keymap)) { GdkKeymapX11 *keymap_x11 = GDK_KEYMAP_X11 (keymap); if (!keymap_x11->have_direction) update_direction (keymap_x11); return keymap_x11->current_direction; } else#endif /* HAVE_XKB */ return PANGO_DIRECTION_NEUTRAL;}/** * gdk_keymap_get_entries_for_keyval: * @keymap: a #GdkKeymap, or %NULL to use the default keymap * @keyval: a keyval, such as %GDK_a, %GDK_Up, %GDK_Return, etc. * @keys: return location for an array of #GdkKeymapKey * @n_keys: return location for number of elements in returned array * * Obtains a list of keycode/group/level combinations that will * generate @keyval. Groups and levels are two kinds of keyboard mode; * in general, the level determines whether the top or bottom symbol * on a key is used, and the group determines whether the left or * right symbol is used. On US keyboards, the shift key changes the * keyboard level, and there are no groups. A group switch key might * convert a keyboard between Hebrew to English modes, for example. * #GdkEventKey contains a %group field that indicates the active * keyboard group. The level is computed from the modifier mask. * The returned array should be freed * with g_free(). * * Return value: %TRUE if keys were found and returned **/gbooleangdk_keymap_get_entries_for_keyval (GdkKeymap *keymap, guint keyval, GdkKeymapKey **keys, gint *n_keys){ GArray *retval; GdkKeymapX11 *keymap_x11; g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); g_return_val_if_fail (keys != NULL, FALSE); g_return_val_if_fail (n_keys != NULL, FALSE); g_return_val_if_fail (keyval != 0, FALSE); keymap = GET_EFFECTIVE_KEYMAP (keymap); keymap_x11 = GDK_KEYMAP_X11 (keymap); retval = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));#ifdef HAVE_XKB if (KEYMAP_USE_XKB (keymap)) { /* See sec 15.3.4 in XKB docs */ XkbDescRec *xkb = get_xkb (keymap_x11); gint keycode; keycode = keymap_x11->min_keycode; while (keycode <= keymap_x11->max_keycode) { gint max_shift_levels = XkbKeyGroupsWidth (xkb, keycode); /* "key width" */ gint group = 0; gint level = 0; gint total_syms = XkbKeyNumSyms (xkb, keycode); gint i = 0; KeySym *entry; /* entry is an array with all syms for group 0, all * syms for group 1, etc. and for each group the * shift level syms are in order */ entry = XkbKeySymsPtr (xkb, keycode); while (i < total_syms) { /* check out our cool loop invariant */ g_assert (i == (group * max_shift_levels + level)); if (entry[i] == keyval) { /* Found a match */ GdkKeymapKey key; key.keycode = keycode; key.group = group; key.level = level; g_array_append_val (retval, key); g_assert (XkbKeySymEntry (xkb, keycode, level, group) == keyval); } ++level; if (level == max_shift_levels) { level = 0; ++group; } ++i; } ++keycode; } } else#endif { const KeySym *map = get_keymap (keymap_x11); gint keycode; keycode = keymap_x11->min_keycode; while (keycode <= keymap_x11->max_keycode) { const KeySym *syms = map + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode; gint i = 0; while (i < keymap_x11->keysyms_per_keycode) { if (syms[i] == keyval) { /* found a match */ GdkKeymapKey key; key.keycode = keycode; /* The "classic" non-XKB keymap has 2 levels per group */ key.group = i / 2; key.level = i % 2; g_array_append_val (retval, key); } ++i; } ++keycode; } } if (retval->len > 0) { *keys = (GdkKeymapKey*) retval->data; *n_keys = retval->len; } else { *keys = NULL; *n_keys = 0; } g_array_free (retval, retval->len > 0 ? FALSE : TRUE); return *n_keys > 0;}/** * gdk_keymap_get_entries_for_keycode: * @keymap: a #GdkKeymap or %NULL to use the default keymap * @hardware_keycode: a keycode * @keys: return location for array of #GdkKeymapKey, or NULL * @keyvals: return location for array of keyvals, or NULL * @n_entries: length of @keys and @keyvals * * Returns the keyvals bound to @hardware_keycode. * The Nth #GdkKeymapKey in @keys is bound to the Nth * keyval in @keyvals. Free the returned arrays with g_free(). * When a keycode is pressed by the user, the keyval from * this list of entries is selected by considering the effective * keyboard group and level. See gdk_keymap_translate_keyboard_state(). * * Returns: %TRUE if there were any entries **/gbooleangdk_keymap_get_entries_for_keycode (GdkKeymap *keymap, guint hardware_keycode, GdkKeymapKey **keys, guint **keyvals, gint *n_entries){ GdkKeymapX11 *keymap_x11; GArray *key_array; GArray *keyval_array; g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); g_return_val_if_fail (n_entries != NULL, FALSE); keymap = GET_EFFECTIVE_KEYMAP (keymap); keymap_x11 = GDK_KEYMAP_X11 (keymap); update_keyrange (keymap_x11); if (hardware_keycode < keymap_x11->min_keycode || hardware_keycode > keymap_x11->max_keycode) { if (keys) *keys = NULL; if (keyvals) *keyvals = NULL; *n_entries = 0; return FALSE; } if (keys) key_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey)); else key_array = NULL; if (keyvals) keyval_array = g_array_new (FALSE, FALSE, sizeof (guint)); else keyval_array = NULL; #ifdef HAVE_XKB if (KEYMAP_USE_XKB (keymap)) { /* See sec 15.3.4 in XKB docs */ XkbDescRec *xkb = get_xkb (keymap_x11); gint max_shift_levels; gint group = 0; gint level = 0; gint total_syms; gint i = 0; KeySym *entry; max_shift_levels = XkbKeyGroupsWidth (xkb, hardware_keycode); /* "key width" */ total_syms = XkbKeyNumSyms (xkb, hardware_keycode); /* entry is an array with all syms for group 0, all * syms for group 1, etc. and for each group the * shift level syms are in order */ entry = XkbKeySymsPtr (xkb, hardware_keycode); while (i < total_syms) { /* check out our cool loop invariant */ g_assert (i == (group * max_shift_levels + level)); if (key_array) { GdkKeymapKey key; key.keycode = hardware_keycode; key.group = group; key.level = level; g_array_append_val (key_array, key); } if (keyval_array) g_array_append_val (keyval_array, entry[i]); ++level; if (level == max_shift_levels) { level = 0; ++group; } ++i; } } else#endif { const KeySym *map = get_keymap (keymap_x11); const KeySym *syms; gint i = 0; syms = map + (hardware_keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode; while (i < keymap_x11->keysyms_per_keycode) { if (key_array) { GdkKeymapKey key; key.keycode = hardware_keycode; /* The "classic" non-XKB keymap has 2 levels per group */ key.group = i / 2; key.level = i % 2; g_array_append_val (key_array, key); } if (keyval_array) g_array_append_val (keyval_array, syms[i]); ++i; } } if ((key_array && key_array->len > 0) || (keyval_array && keyval_array->len > 0)) { if (keys) *keys = (GdkKeymapKey*) key_array->data; if (keyvals) *keyvals = (guint*) keyval_array->data; if (key_array) *n_entries = key_array->len; else *n_entries = keyval_array->len; } else { if (keys) *keys = NULL; if (keyvals) *keyvals = NULL; *n_entries = 0; } if (key_array) g_array_free (key_array, key_array->len > 0 ? FALSE : TRUE); if (keyval_array) g_array_free (keyval_array, keyval_array->len > 0 ? FALSE : TRUE); return *n_entries > 0;}/** * gdk_keymap_lookup_key: * @keymap: a #GdkKeymap or %NULL to use the default keymap * @key: a #GdkKeymapKey with keycode, group, and level initialized * * Looks up the keyval mapped to a keycode/group/level triplet. * If no keyval is bound to @key, returns 0. For normal user input, * you want to use gdk_keymap_translate_keyboard_state() instead of * this function, since the effective group/level may not be * the same as the current keyboard state. * * Return value: a keyval, or 0 if none was mapped to the given @key **/guintgdk_keymap_lookup_key (GdkKeymap *keymap, const GdkKeymapKey *key){ GdkKeymapX11 *keymap_x11; g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), 0); g_return_val_if_fail (key != NULL, 0); g_return_val_if_fail (key->group < 4, 0); keymap = GET_EFFECTIVE_KEYMAP (keymap); keymap_x11 = GDK_KEYMAP_X11 (keymap); #ifdef HAVE_XKB if (KEYMAP_USE_XKB (keymap)) { XkbDescRec *xkb = get_xkb (keymap_x11); return XkbKeySymEntry (xkb, key->keycode, key->level, key->group); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -