📄 gdkkeys-x11.c
字号:
else#endif { const KeySym *map = get_keymap (keymap_x11); const KeySym *syms = map + (key->keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode; return get_symbol (syms, keymap_x11, key->group, key->level); }}#ifdef HAVE_XKB/* This is copied straight from XFree86 Xlib, to: * - add the group and level return. * - change the interpretation of mods_rtrn as described * in the docs for gdk_keymap_translate_keyboard_state() * It's unchanged for ease of diff against the Xlib sources; don't * reformat it. */static BoolMyEnhancedXkbTranslateKeyCode(register XkbDescPtr xkb, KeyCode key, register unsigned int mods, unsigned int * mods_rtrn, KeySym * keysym_rtrn, unsigned int * group_rtrn, unsigned int * level_rtrn){ XkbKeyTypeRec *type; int col,nKeyGroups; unsigned preserve,effectiveGroup; KeySym *syms; if (mods_rtrn!=NULL) *mods_rtrn = 0; nKeyGroups= XkbKeyNumGroups(xkb,key); if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) { if (keysym_rtrn!=NULL) *keysym_rtrn = NoSymbol; return False; } syms = XkbKeySymsPtr(xkb,key); /* find the offset of the effective group */ col = 0; effectiveGroup= XkbGroupForCoreState(mods); if ( effectiveGroup>=nKeyGroups ) { unsigned groupInfo= XkbKeyGroupInfo(xkb,key); switch (XkbOutOfRangeGroupAction(groupInfo)) { default: effectiveGroup %= nKeyGroups; break; case XkbClampIntoRange: effectiveGroup = nKeyGroups-1; break; case XkbRedirectIntoRange: effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo); if (effectiveGroup>=nKeyGroups) effectiveGroup= 0; break; } } col= effectiveGroup*XkbKeyGroupsWidth(xkb,key); type = XkbKeyKeyType(xkb,key,effectiveGroup); preserve= 0; if (type->map) { /* find the column (shift level) within the group */ register int i; register XkbKTMapEntryPtr entry; /* ---- Begin section modified for GDK ---- */ int found = 0; for (i=0,entry=type->map;i<type->map_count;i++,entry++) { if (mods_rtrn) { int bits = 0; unsigned long tmp = entry->mods.mask; while (tmp) { if ((tmp & 1) == 1) bits++; tmp >>= 1; } /* We always add one-modifiers levels to mods_rtrn since * they can't wipe out bits in the state unless the * level would be triggered. But return other modifiers * */ if (bits == 1 || (mods&type->mods.mask)==entry->mods.mask) *mods_rtrn |= entry->mods.mask; } if (!found&&entry->active&&((mods&type->mods.mask)==entry->mods.mask)) { col+= entry->level; if (type->preserve) preserve= type->preserve[i].mask; if (level_rtrn) *level_rtrn = entry->level; found = 1; } } /* ---- End section modified for GDK ---- */ } if (keysym_rtrn!=NULL) *keysym_rtrn= syms[col]; if (mods_rtrn) { /* ---- Begin section modified for GDK ---- */ *mods_rtrn &= ~preserve; /* ---- End section modified for GDK ---- */ /* ---- Begin stuff GDK comments out of the original Xlib version ---- */ /* This is commented out because xkb_info is a private struct */#if 0 /* The Motif VTS doesn't get the help callback called if help * is bound to Shift+<whatever>, and it appears as though it * is XkbTranslateKeyCode that is causing the problem. The * core X version of XTranslateKey always OR's in ShiftMask * and LockMask for mods_rtrn, so this "fix" keeps this behavior * and solves the VTS problem. */ if ((xkb->dpy)&&(xkb->dpy->xkb_info)&& (xkb->dpy->xkb_info->xlib_ctrls&XkbLC_AlwaysConsumeShiftAndLock)) { *mods_rtrn|= (ShiftMask|LockMask); }#endif /* ---- End stuff GDK comments out of the original Xlib version ---- */ } /* ---- Begin stuff GDK adds to the original Xlib version ---- */ if (group_rtrn) *group_rtrn = effectiveGroup; /* ---- End stuff GDK adds to the original Xlib version ---- */ return (syms[col]!=NoSymbol);}#endif /* HAVE_XKB *//* Translates from keycode/state to keysymbol using the traditional interpretation * of the keyboard map. See section 12.7 of the Xlib reference manual */static guinttranslate_keysym (GdkKeymapX11 *keymap_x11, guint hardware_keycode, gint group, GdkModifierType state, guint *effective_group, guint *effective_level){ const KeySym *map = get_keymap (keymap_x11); const KeySym *syms = map + (hardware_keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;#define SYM(k,g,l) get_symbol (syms, k,g,l) GdkModifierType shift_modifiers; gint shift_level; guint tmp_keyval; gint num_lock_index; shift_modifiers = GDK_SHIFT_MASK; if (keymap_x11->lock_keysym == GDK_Shift_Lock) shift_modifiers |= GDK_LOCK_MASK; /* Fall back to the first group if the passed in group is empty */ if (!(SYM (keymap_x11, group, 0) || SYM (keymap_x11, group, 1)) && (SYM (keymap_x11, 0, 0) || SYM (keymap_x11, 0, 1))) group = 0; /* Hack: On Sun, the Num Lock modifier uses the third element in the * keysym array, and Mode_Switch does not apply for a keypad key. */ if (keymap_x11->sun_keypad) { num_lock_index = 2; if (group != 0) { gint i; for (i = 0; i < keymap_x11->keysyms_per_keycode; i++) if (KEYSYM_IS_KEYPAD (SYM (keymap_x11, 0, i))) group = 0; } } else num_lock_index = 1; if ((state & keymap_x11->num_lock_mask) && KEYSYM_IS_KEYPAD (SYM (keymap_x11, group, num_lock_index))) { /* Shift, Shift_Lock cancel Num_Lock */ shift_level = (state & shift_modifiers) ? 0 : num_lock_index; if (!SYM (keymap_x11, group, shift_level) && SYM (keymap_x11, group, 0)) shift_level = 0; tmp_keyval = SYM (keymap_x11, group, shift_level); } else { /* Fall back to the first level if no symbol for the level * we were passed. */ shift_level = (state & shift_modifiers) ? 1 : 0; if (!SYM (keymap_x11, group, shift_level) && SYM (keymap_x11, group, 0)) shift_level = 0; tmp_keyval = SYM (keymap_x11, group, shift_level); if (keymap_x11->lock_keysym == GDK_Caps_Lock && (state & GDK_LOCK_MASK) != 0) { guint upper = gdk_keyval_to_upper (tmp_keyval); if (upper != tmp_keyval) tmp_keyval = upper; } } if (effective_group) *effective_group = group; if (effective_level) *effective_level = shift_level; return tmp_keyval; #undef SYM}/** * gdk_keymap_translate_keyboard_state: * @keymap: a #GdkKeymap, or %NULL to use the default * @hardware_keycode: a keycode * @state: a modifier state * @group: active keyboard group * @keyval: return location for keyval * @effective_group: return location for effective group * @level: return location for level * @consumed_modifiers: return location for modifiers that were used to determine the group or level * * * Translates the contents of a #GdkEventKey into a keyval, effective * group, and level. Modifiers that affected the translation and * are thus unavailable for application use are returned in * @consumed_modifiers. See gdk_keyval_get_keys() for an explanation of * groups and levels. The @effective_group is the group that was * actually used for the translation; some keys such as Enter are not * affected by the active keyboard group. The @level is derived from * @state. For convenience, #GdkEventKey already contains the translated * keyval, so this function isn't as useful as you might think. * * <note><para> * @consumed_modifiers gives modifiers that should be masked out * from @state when comparing this key press to a hot key. For * instance, on a US keyboard, the <literal>plus</literal> * symbol is shifted, so when comparing a key press to a * <literal><Control>plus</literal> accelerator <Shift> should * be masked out. * </para> * <informalexample><programlisting> * /* We want to ignore irrelevant modifiers like ScrollLock */ * #define ALL_ACCELS_MASK (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK) * gdk_keymap_translate_keyboard_state (keymap, event->hardware_keycode, * event->state, event->group, * &keyval, NULL, NULL, &consumed); * if (keyval == GDK_PLUS && * (event->state & ~consumed & ALL_ACCELS_MASK) == GDK_CONTROL_MASK) * /* Control was pressed */ * </programlisting></informalexample> * <para> * An older interpretation @consumed_modifiers was that it contained * all modifiers that might affect the translation of the key; * this allowed accelerators to be stored with irrelevant consumed * modifiers, by doing:</para> * <informalexample><programlisting> * /* XXX Don't do this XXX */ * if (keyval == accel_keyval && * (event->state & ~consumed & ALL_ACCELS_MASK) == (accel_mods & ~consumed)) * /* Accelerator was pressed */ * </programlisting></informalexample> * <para> * However, this did not work if multi-modifier combinations were * used in the keymap, since, for instance, <literal><Control></literal> * would be masked out even if only <literal><Control><Alt></literal> * was used in the keymap. To support this usage as well as well as * possible, all <emphasis>single modifier</emphasis> combinations * that could affect the key for any combination of modifiers will * be returned in @consumed_modifiers; multi-modifier combinations * are returned only when actually found in @state. When you store * accelerators, you should always store them with consumed modifiers * removed. Store <literal><Control>plus</literal>, * not <literal><Control><Shift>plus</literal>, * </para></note> * * Return value: %TRUE if there was a keyval bound to the keycode/state/group **/gbooleangdk_keymap_translate_keyboard_state (GdkKeymap *keymap, guint hardware_keycode, GdkModifierType state, gint group, guint *keyval, gint *effective_group, gint *level, GdkModifierType *consumed_modifiers){ GdkKeymapX11 *keymap_x11; KeySym tmp_keyval = NoSymbol; guint tmp_modifiers; g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE); g_return_val_if_fail (group < 4, FALSE); keymap = GET_EFFECTIVE_KEYMAP (keymap); keymap_x11 = GDK_KEYMAP_X11 (keymap); if (keyval) *keyval = NoSymbol; if (effective_group) *effective_group = 0; if (level) *level = 0; if (consumed_modifiers) *consumed_modifiers = 0; update_keyrange (keymap_x11); if (hardware_keycode < keymap_x11->min_keycode || hardware_keycode > keymap_x11->max_keycode) return FALSE; #ifdef HAVE_XKB if (KEYMAP_USE_XKB (keymap)) { XkbDescRec *xkb = get_xkb (keymap_x11); /* replace bits 13 and 14 with the provided group */ state &= ~(1 << 13 | 1 << 14); state |= group << 13; MyEnhancedXkbTranslateKeyCode (xkb, hardware_keycode, state, &tmp_modifiers, &tmp_keyval, effective_group, level); if (state & ~tmp_modifiers & LockMask) tmp_keyval = gdk_keyval_to_upper (tmp_keyval); /* We need to augment the consumed modifiers with LockMask, since * we handle that ourselves, and also with the group bits */ tmp_modifiers |= LockMask | 1 << 13 | 1 << 14; } else#endif { GdkModifierType bit; tmp_modifiers = 0; /* We see what modifiers matter by trying the translation with * and without each possible modifier */ for (bit = GDK_SHIFT_MASK; bit < GDK_BUTTON1_MASK; bit <<= 1) { /* Handling of the group here is a bit funky; a traditional * X keyboard map can have more than two groups, but no way * of accessing the extra groups is defined. We allow a * caller to pass in any group to this function, but we * only can represent switching between group 0 and 1 in * consumed modifiers. */ if (translate_keysym (keymap_x11, hardware_keycode, (bit == keymap_x11->group_switch_mask) ? 0 : group, state & ~bit, NULL, NULL) != translate_keysym (keymap_x11, hardware_keycode, (bit == keymap_x11->group_switch_mask) ? 1 : group, state | bit, NULL, NULL)) tmp_modifiers |= bit; } tmp_keyval = translate_keysym (keymap_x11, hardware_keycode, group, state, level, effective_group); } if (consumed_modifiers) *consumed_modifiers = tmp_modifiers; if (keyval) *keyval = tmp_keyval; return tmp_keyval != NoSymbol;}/* Key handling not part of the keymap */gchar*gdk_keyval_name (guint keyval){ switch (keyval) { case GDK_Page_Up: return "Page_Up"; case GDK_Page_Down: return "Page_Down"; case GDK_KP_Page_Up: return "KP_Page_Up"; case GDK_KP_Page_Down: return "KP_Page_Down"; } return XKeysymToString (keyval);}guintgdk_keyval_from_name (const gchar *keyval_name){ g_return_val_if_fail (keyval_name != NULL, 0); return XStringToKeysym (keyval_name);}#ifdef HAVE_XCONVERTCASEvoidgdk_keyval_convert_case (guint symbol, guint *lower, guint *upper){ KeySym xlower = 0; KeySym xupper = 0; /* Check for directly encoded 24-bit UCS characters: */ if ((symbol & 0xff000000) == 0x01000000) { if (lower) *lower = gdk_unicode_to_keyval (g_unichar_tolower (symbol & 0x00ffffff)); if (upper) *upper = gdk_unicode_to_keyval (g_unichar_toupper (symbol & 0x00ffffff)); return; } if (symbol) XConvertCase (symbol, &xlower, &xupper); if (lower) *lower = xlower; if (upper) *upper = xupper;} #endif /* HAVE_XCONVERTCASE */gint_gdk_x11_get_group_for_state (GdkDisplay *display, GdkModifierType state){ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display); #ifdef HAVE_XKB if (display_x11->use_xkb) { return XkbGroupForCoreState (state); } else#endif { GdkKeymapX11 *keymap_impl = GDK_KEYMAP_X11 (gdk_keymap_get_for_display (display)); update_keymaps (keymap_impl); return (state & keymap_impl->group_switch_mask) ? 1 : 0; }}#define __GDK_KEYS_X11_C__#include "gdkaliasdef.c"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -