diff --git a/gdk/win32/gdkkeys-win32-impl.c b/gdk/win32/gdkkeys-win32-impl.c index f792c4e24b..a6124f943d 100644 --- a/gdk/win32/gdkkeys-win32-impl.c +++ b/gdk/win32/gdkkeys-win32-impl.c @@ -213,7 +213,7 @@ modbits_to_level (GdkWin32KeymapLayoutInfo *info, /* * vk_to_char_fuzzy: * - * For a given key and keystate, return the best-fit character and the + * For a given key and modifier state, return the best-fit character and the * modifiers used to produce it. Note that not all modifiers need to be used, * because some modifier combination aren't actually mapped in the keyboard * layout (for example the Ctrl key typically has no effect, unless used in @@ -221,26 +221,32 @@ modbits_to_level (GdkWin32KeymapLayoutInfo *info, * * 'Best-fit' means 'consume as many modifiers as possibe'. * - * For example (assuming a neutral keystate): + * For example (assuming a neutral lock state): * + * - a -> 'a', consumed_mod_bits: [] * - Shift + a -> 'A', consumed_mod_bits: [Shift] * - Ctrl + a -> 'a', consumed_mod_bits: [] * - Ctrl + Shift + a -> 'A', consumed_mod_bits: [Shift] * * If capslock is active, the result could be: * - * - Shift + a -> 'a', consumed_mod_bits: [Shift] + * - a -> 'A', consumed_mod_bits: [Shift] + * - Shift + a -> 'a', consumed_mod_bits: [] + * - Ctrl + a -> 'a', consumed_mod_bits: [] + * - Ctrl + Shift + a -> 'A', consumed_mod_bits: [Shift] * - * The caller can supply additional modifiers to be added to the - * keystate in `extra_mod_bits`. + * The held down modifiers are supplied in `mod_bits` as a bitmask of KBDSHIFT, + * KBDCTRL, KBDALT etc. + * + * The toggled modifiers are supplied in `lock_state` as a bitmask of CAPLOK and KANALOK. * * If the key combination results in a dead key, `is_dead` will be set to TRUE, * otherwise it will be set to FALSE. */ static WCHAR vk_to_char_fuzzy (GdkWin32KeymapLayoutInfo *info, - const BYTE keystate[256], - BYTE extra_mod_bits, + BYTE mod_bits, + BYTE lock_bits, BYTE *consumed_mod_bits, gboolean *is_dead, BYTE vk) @@ -282,18 +288,12 @@ vk_to_char_fuzzy (GdkWin32KeymapLayoutInfo *info, if (entry->VirtualKey == vk) { - BYTE modbits; WCHAR best_char = WCH_NONE; BYTE best_modifiers = 0; int best_score = -1; gboolean best_is_dead = FALSE; int level; - /* Add modbits of currently pressed keys. */ - modbits = keystate_to_modbits (info, keystate); - /* Add modbits supplied by caller. */ - modbits |= extra_mod_bits; - /* Take toggled keys into account. For example, capslock normally inverts the * state of KBDSHIFT (with some exceptions). */ @@ -302,27 +302,27 @@ vk_to_char_fuzzy (GdkWin32KeymapLayoutInfo *info, /* Ignore capslock if any modifiers other than shift are pressed. * E.g. on the German layout, CapsLock + AltGr + q is the same as * AltGr + q ('@'), but NOT the same as Shift + AltGr + q (not mapped). */ - !(modbits & ~KBDSHIFT) && - (keystate[VK_CAPITAL] & 0x01)) - modbits ^= KBDSHIFT; + !(mod_bits & ~KBDSHIFT) && + (lock_bits & CAPLOK)) + mod_bits ^= KBDSHIFT; /* Key supporting combination of capslock + altgr */ if ((entry->Attributes & CAPLOKALTGR) && - (modbits & KBDALTGR) && - (keystate[VK_CAPITAL] & 0x01)) - modbits ^= KBDSHIFT; + (mod_bits & KBDALTGR) && + (lock_bits & CAPLOK)) + mod_bits ^= KBDSHIFT; /* In the Swiss German layout, CapsLock + key is different from Shift + key * for some keys. For such keys, Capslock toggles the KBDCTRL bit. */ if ((entry->Attributes & SGCAPS) && - (keystate[VK_CAPITAL] & 0x01)) - modbits ^= KBDCTRL; + (lock_bits & CAPLOK)) + mod_bits ^= KBDCTRL; /* I'm not totally sure how kanalok behaves, for now I assume that there * aren't any special cases. */ if ((entry->Attributes & KANALOK) && - (keystate[VK_KANA] & 0x01)) - modbits ^= KBDKANA; + (lock_bits & KANALOK)) + mod_bits ^= KBDKANA; /* We try to find the entry with the most matching modifiers */ for (level = 0; level < n_levels; ++level) @@ -332,7 +332,7 @@ vk_to_char_fuzzy (GdkWin32KeymapLayoutInfo *info, WCHAR c; int score; - if (candidate_modbits & ~modbits) + if (candidate_modbits & ~mod_bits) continue; c = entry->wch[level]; @@ -349,7 +349,7 @@ vk_to_char_fuzzy (GdkWin32KeymapLayoutInfo *info, if (c == WCH_DEAD || c == WCH_LGTR || c == WCH_NONE) continue; - score = POPCOUNT (candidate_modbits & modbits); + score = POPCOUNT (candidate_modbits & mod_bits); if (score > best_score) { best_score = score; diff --git a/gdk/win32/gdkkeys-win32.c b/gdk/win32/gdkkeys-win32.c index 18a6752278..19bc721ce0 100644 --- a/gdk/win32/gdkkeys-win32.c +++ b/gdk/win32/gdkkeys-win32.c @@ -156,13 +156,13 @@ modbits_to_level (GdkWin32Keymap *keymap, static WCHAR vk_to_char_fuzzy (GdkWin32Keymap *keymap, GdkWin32KeymapLayoutInfo *info, - const BYTE keystate[256], - BYTE extra_mod_bits, + BYTE mod_bits, + BYTE lock_bits, BYTE *consumed_mod_bits, gboolean *is_dead, BYTE vk) { - return keymap->gdkwin32_keymap_impl->vk_to_char_fuzzy (info, keystate, extra_mod_bits, + return keymap->gdkwin32_keymap_impl->vk_to_char_fuzzy (info, mod_bits, lock_bits, consumed_mod_bits, is_dead, vk); } @@ -347,8 +347,8 @@ static guint vk_and_mod_bits_to_gdk_keysym (GdkWin32Keymap *keymap, GdkWin32KeymapLayoutInfo *info, guint vk, - const BYTE keystate[256], BYTE mod_bits, + BYTE lock_bits, BYTE *consumed_mod_bits) { @@ -384,7 +384,7 @@ vk_and_mod_bits_to_gdk_keysym (GdkWin32Keymap *keymap, } /* Handle regular keys (including dead keys) */ - c = vk_to_char_fuzzy (keymap, info, keystate, mod_bits, + c = vk_to_char_fuzzy (keymap, info, mod_bits, lock_bits, consumed_mod_bits, &is_dead, vk); if (c == WCH_NONE) @@ -497,26 +497,6 @@ gdk_mod_mask_to_mod_bits (GdkModifierType mod_mask) return result; } -static void -get_lock_state (BYTE lock_state[256]) -{ - static const guint mode_keys[] = - { - VK_CAPITAL, - VK_KANA, VK_HANGUL, VK_JUNJA, VK_FINAL, VK_HANJA, VK_KANJI, /* Is this correct? */ - VK_NUMLOCK, VK_SCROLL - }; - - BYTE keystate[256] = {0}; - guint i; - - GetKeyboardState (keystate); - - /* Copy over some keystates like numlock and capslock */ - for (i = 0; i < G_N_ELEMENTS(mode_keys); ++i) - lock_state[mode_keys[i]] = keystate[mode_keys[i]] & 0x1; -} - /* keypad decimal mark depends on active keyboard layout * return current decimal mark as unicode character @@ -766,7 +746,6 @@ gdk_win32_keymap_get_entries_for_keyval (GdkKeymap *gdk_keymap, { GdkWin32Keymap *keymap; GArray *retval; - BYTE keystate[256] = {0}; gint group; g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE); @@ -822,8 +801,7 @@ gdk_win32_keymap_get_entries_for_keyval (GdkKeymap *gdk_keymap, /* Check if the additional modifiers change the semantics. * If they do not, add them. */ sym = vk_and_mod_bits_to_gdk_keysym (keymap, info, entry->vk, - keystate, modbits, - NULL); + modbits, 0, NULL); if (sym == keyval || sym == GDK_KEY_VoidSymbol) { gdk_key.keycode = entry->vk; @@ -864,7 +842,6 @@ gdk_win32_keymap_get_entries_for_keycode (GdkKeymap *gdk_keymap, GArray *key_array; GArray *keyval_array; gint group; - BYTE keystate[256] = {0}; BYTE vk; g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE); @@ -901,7 +878,7 @@ gdk_win32_keymap_get_entries_for_keycode (GdkKeymap *gdk_keymap, GdkKeymapKey key = {0}; guint keyval; - keyval = vk_and_mod_bits_to_gdk_keysym (keymap, info, vk, keystate, modbits, &consumed_modbits); + keyval = vk_and_mod_bits_to_gdk_keysym (keymap, info, vk, modbits, 0, &consumed_modbits); if (keyval == GDK_KEY_VoidSymbol || consumed_modbits != modbits) continue; @@ -936,7 +913,6 @@ gdk_win32_keymap_lookup_key (GdkKeymap *gdk_keymap, GdkWin32Keymap *keymap; GdkWin32KeymapLayoutInfo *info; - BYTE keystate[256] = {0}; BYTE modbits; guint sym; @@ -954,7 +930,7 @@ gdk_win32_keymap_lookup_key (GdkKeymap *gdk_keymap, return 0; modbits = info->level_to_modbits[key->level]; - sym = vk_and_mod_bits_to_gdk_keysym (keymap, info, key->keycode, keystate, modbits, NULL); + sym = vk_and_mod_bits_to_gdk_keysym (keymap, info, key->keycode, modbits, 0, NULL); if (sym == GDK_KEY_VoidSymbol) return 0; @@ -981,7 +957,7 @@ gdk_win32_keymap_translate_keyboard_state (GdkKeymap *gdk_keymap, GdkWin32KeymapLayoutInfo *layout_info; guint vk; BYTE mod_bits; - BYTE keystate[256] = {0}; + BYTE lock_bits = 0; g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE); @@ -1005,11 +981,25 @@ gdk_win32_keymap_translate_keyboard_state (GdkKeymap *gdk_keymap, if (vk == VK_RMENU) mod_bits &= ~KBDALTGR; - /* We need to query the existing keyboard state for NumLock, CapsLock etc. */ - get_lock_state (keystate); + /* Translate lock state + * + * Right now the only locking modifier is CAPSLOCK. We don't handle KANALOK + * because GDK doesn't have an equivalent modifier mask to my knowledge (On + * X11, I believe the same effect is achieved by shifting to a different + * group. It's just a different concept, that doesn't translate to Windows). + * But since KANALOK is only used on far-eastern keyboards, which require IME + * anyway, this is probably fine. The IME input module has actually been the + * default for all languages (not just far-eastern) for a while now, which + * means that the keymap is now only used for things like accelerators and + * keybindings, where you probably don't even want KANALOK to affect the + * translation. + */ - tmp_keyval = vk_and_mod_bits_to_gdk_keysym (keymap, layout_info, vk, keystate, - mod_bits, &consumed_mod_bits); + if (state & GDK_LOCK_MASK) + lock_bits |= CAPLOK; + + tmp_keyval = vk_and_mod_bits_to_gdk_keysym (keymap, layout_info, vk, mod_bits, + lock_bits, &consumed_mod_bits); tmp_effective_group = group; tmp_level = modbits_to_level (keymap, layout_info, consumed_mod_bits); diff --git a/gdk/win32/gdkkeys-win32.h b/gdk/win32/gdkkeys-win32.h index 17b7d7125c..f128996de1 100644 --- a/gdk/win32/gdkkeys-win32.h +++ b/gdk/win32/gdkkeys-win32.h @@ -160,8 +160,8 @@ typedef struct BYTE (*modbits_to_level) (GdkWin32KeymapLayoutInfo *info, BYTE modbits); WCHAR (*vk_to_char_fuzzy) (GdkWin32KeymapLayoutInfo *info, - const BYTE keystate[256], - BYTE extra_mod_bits, + BYTE mod_bits, + BYTE lock_bits, BYTE *consumed_mod_bits, gboolean *is_dead, BYTE vk);