summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Bacci <luca.bacci982@gmail.com>2022-01-12 21:36:19 +0000
committerLuca Bacci <luca.bacci982@gmail.com>2022-01-12 21:36:19 +0000
commit4a4a579fd9d8c12efa0c31b9ade8d93b98659460 (patch)
tree5af29039608d5087e18c5b2ea97f6589d4722347
parentdf716e5c9f3152dbf9fc6159ca1ddb2b6f4c5e3d (diff)
parent7d6257cb1e1115c58b279f8357118091a24b2457 (diff)
downloadgtk+-4a4a579fd9d8c12efa0c31b9ade8d93b98659460.tar.gz
Merge branch 'forward-port-gdk-win32-keymap-bugfixes-to-gtk4' into 'main'
GdkWin32Keymap bugfixes See merge request GNOME/gtk!4372
-rw-r--r--gdk/win32/gdkkeys-win32-impl.c80
-rw-r--r--gdk/win32/gdkkeys-win32.c231
-rw-r--r--gdk/win32/gdkkeys-win32.h4
-rw-r--r--gdk/win32/gdkprivate-win32.h1
4 files changed, 206 insertions, 110 deletions
diff --git a/gdk/win32/gdkkeys-win32-impl.c b/gdk/win32/gdkkeys-win32-impl.c
index f792c4e24b..2e2a382d0a 100644
--- a/gdk/win32/gdkkeys-win32-impl.c
+++ b/gdk/win32/gdkkeys-win32-impl.c
@@ -180,7 +180,8 @@ keystate_to_modbits (GdkWin32KeymapLayoutInfo *info,
BYTE result = 0;
int i;
- g_return_val_if_fail (tables != NULL, 0);
+ if (tables == NULL)
+ return 0;
vk_to_bit = tables->pCharModifiers.ptr->pVkToBit.ptr;
@@ -198,7 +199,8 @@ modbits_to_level (GdkWin32KeymapLayoutInfo *info,
PKBDTABLES tables = (PKBDTABLES) info->tables;
PMODIFIERS modifiers;
- g_return_val_if_fail (tables != NULL, 0);
+ if (tables == NULL)
+ return 0;
modifiers = tables->pCharModifiers.ptr;
if (modbits > modifiers->wMaxModBits)
@@ -213,7 +215,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 +223,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 held down modifiers are supplied in `mod_bits` as a bitmask of KBDSHIFT,
+ * KBDCTRL, KBDALT etc.
*
- * The caller can supply additional modifiers to be added to the
- * keystate in `extra_mod_bits`.
+ * 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)
@@ -262,7 +270,8 @@ vk_to_char_fuzzy (GdkWin32KeymapLayoutInfo *info,
if (is_dead)
*is_dead = FALSE;
- g_return_val_if_fail (tables != NULL, WCH_NONE);
+ if (tables == NULL)
+ return WCH_NONE;
wch_tables = tables->pVkToWcharTable.ptr;
@@ -282,18 +291,13 @@ vk_to_char_fuzzy (GdkWin32KeymapLayoutInfo *info,
if (entry->VirtualKey == vk)
{
- BYTE modbits;
+ gboolean have_sgcaps = FALSE;
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 +306,28 @@ 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. */
+ * for some keys. For such keys, the characters for active capslock are
+ * in the next entry. */
if ((entry->Attributes & SGCAPS) &&
- (keystate[VK_CAPITAL] & 0x01))
- modbits ^= KBDCTRL;
+ (lock_bits & CAPLOK))
+ have_sgcaps = TRUE;
/* 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,13 +337,13 @@ vk_to_char_fuzzy (GdkWin32KeymapLayoutInfo *info,
WCHAR c;
int score;
- if (candidate_modbits & ~modbits)
- continue;
+ if (candidate_modbits & ~mod_bits)
+ continue;
c = entry->wch[level];
- if (c == WCH_DEAD)
+ if (c == WCH_DEAD || have_sgcaps)
{
- /* Next entry contains the undead keys */
+ /* Next entry contains the undead/capslocked keys */
PVK_TO_WCHARS next_entry;
next_entry = (PVK_TO_WCHARS) ((PBYTE) wch_table->pVkToWchars.ptr
+ entry_size * (entry_index + 1));
@@ -349,7 +354,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;
@@ -455,8 +460,13 @@ init_vk_lookup_table (GdkWin32KeymapLayoutInfo *info)
/* Lookup table to find entry for a VK in O(1). */
- info->vk_lookup_table[entry->VirtualKey].table = table_idx;
- info->vk_lookup_table[entry->VirtualKey].index = entry_idx;
+ /* Only add the first entry, as some layouts (Swiss German) contain
+ * multiple successive entries for the same VK (SGCAPS). */
+ if (info->vk_lookup_table[entry->VirtualKey].table < 0)
+ {
+ info->vk_lookup_table[entry->VirtualKey].table = table_idx;
+ info->vk_lookup_table[entry->VirtualKey].index = entry_idx;
+ }
/* Create reverse lookup entries to find a VK+modifier combinations
* that results in a given character. */
@@ -494,7 +504,7 @@ init_vk_lookup_table (GdkWin32KeymapLayoutInfo *info)
g_hash_table_insert (info->reverse_lookup_table,
GINT_TO_POINTER (c),
GINT_TO_POINTER (inserted_idx));
- }
+ }
}
}
}
diff --git a/gdk/win32/gdkkeys-win32.c b/gdk/win32/gdkkeys-win32.c
index a8f976e2ab..caa170b20a 100644
--- a/gdk/win32/gdkkeys-win32.c
+++ b/gdk/win32/gdkkeys-win32.c
@@ -158,16 +158,77 @@ 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);
}
+/*
+ * Return the keyboard layout according to the user's keyboard layout
+ * substitution preferences.
+ *
+ * The result is heap-allocated and should be freed with g_free().
+ */
+static char*
+get_keyboard_layout_substituted_name (const char *layout_name)
+{
+ HKEY hkey = 0;
+ DWORD var_type = REG_SZ;
+ char *result = NULL;
+ DWORD buf_len = 0;
+ LSTATUS status;
+
+ static const char *substitute_path = "Keyboard Layout\\Substitutes";
+
+ status = RegOpenKeyExA (HKEY_CURRENT_USER, substitute_path, 0,
+ KEY_QUERY_VALUE, &hkey);
+ if (status != ERROR_SUCCESS)
+ {
+ /* No substitute set for this value, not sure if this is a normal case */
+ g_warning("Could not open registry key '%s'. Error code: %d",
+ substitute_path, (int)status);
+
+ goto fail1;
+ }
+
+ status = RegQueryValueExA (hkey, layout_name, 0, &var_type, 0, &buf_len);
+ if (status != ERROR_SUCCESS)
+ {
+ g_debug("Could not query registry key '%s\\%s'. Error code: %d",
+ substitute_path, layout_name, (int)status);
+ goto fail2;
+ }
+
+ /* Allocate buffer */
+ result = (char*) g_malloc (buf_len);
+
+ /* Retrieve substitute name */
+ status = RegQueryValueExA (hkey, layout_name, 0, &var_type,
+ (LPBYTE) result, &buf_len);
+ if (status != ERROR_SUCCESS)
+ {
+ g_warning("Could not obtain registry value at key '%s\\%s'. "
+ "Error code: %d",
+ substitute_path, layout_name, (int)status);
+ goto fail3;
+ }
+
+ RegCloseKey (hkey);
+ return result;
+
+fail3:
+ g_free (result);
+fail2:
+ RegCloseKey (hkey);
+fail1:
+ return NULL;
+}
+
/*
* Get the file path of the keyboard layout dll.
* The result is heap-allocated and should be freed with g_free().
@@ -175,32 +236,63 @@ vk_to_char_fuzzy (GdkWin32Keymap *keymap,
static char*
get_keyboard_layout_file (const char *layout_name)
{
- HKEY hkey = 0;
- DWORD var_type = REG_SZ;
- char *result = NULL;
- DWORD file_name_len = 0;
- int dir_len = 0;
- int buf_len = 0;
+ char *final_layout_name = NULL;
+ HKEY hkey = 0;
+ DWORD var_type = REG_SZ;
+ char *result = NULL;
+ DWORD file_name_len = 0;
+ int dir_len = 0;
+ int buf_len = 0;
+ LSTATUS status;
static const char prefix[] = "SYSTEM\\CurrentControlSet\\Control\\"
"Keyboard Layouts\\";
char kbdKeyPath[sizeof (prefix) + KL_NAMELENGTH];
- g_snprintf (kbdKeyPath, sizeof (prefix) + KL_NAMELENGTH, "%s%s", prefix,
- layout_name);
+ /* The user may have a keyboard substitute configured */
+ final_layout_name = get_keyboard_layout_substituted_name (layout_name);
+ if (final_layout_name != NULL)
+ {
+ g_debug ("Substituting keyboard layout name from '%s' to '%s'",
+ layout_name, final_layout_name);
+ g_snprintf (kbdKeyPath, sizeof (prefix) + KL_NAMELENGTH, "%s%s",
+ prefix, final_layout_name);
+ g_free (final_layout_name);
+ final_layout_name = NULL;
+ }
+ else
+ {
+ g_debug ("Could not get substitute keyboard layout name for '%s', "
+ "will use '%s' directly", layout_name, layout_name);
+ g_snprintf (kbdKeyPath, sizeof (prefix) + KL_NAMELENGTH, "%s%s",
+ prefix, layout_name);
+ }
- if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, (LPCSTR) kbdKeyPath, 0,
- KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS)
- goto fail1;
+ status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, (LPCSTR) kbdKeyPath, 0,
+ KEY_QUERY_VALUE, &hkey);
+ if (status != ERROR_SUCCESS)
+ {
+ g_warning("Could not open registry key '%s'. Error code: %d",
+ kbdKeyPath, (int)status);
+ goto fail1;
+ }
/* Get sizes */
- if (RegQueryValueExA (hkey, "Layout File", 0, &var_type, 0,
- &file_name_len) != ERROR_SUCCESS)
- goto fail2;
+ status = RegQueryValueExA (hkey, "Layout File", 0, &var_type, 0,
+ &file_name_len);
+ if (status != ERROR_SUCCESS)
+ {
+ g_warning("Could not query registry key '%s\\Layout File'. Error code: %d",
+ kbdKeyPath, (int)status);
+ goto fail2;
+ }
dir_len = GetSystemDirectoryA (0, 0); /* includes \0 */
if (dir_len == 0)
- goto fail2;
+ {
+ g_warning("GetSystemDirectoryA failed. Error: %d", (int)GetLastError());
+ goto fail2;
+ }
/* Allocate buffer */
buf_len = dir_len + (int) strlen ("\\") + file_name_len;
@@ -214,10 +306,12 @@ get_keyboard_layout_file (const char *layout_name)
result[dir_len - 1] = '\\';
/* Append file name */
- if (RegQueryValueExA (hkey, "Layout File", 0, &var_type,
- (LPBYTE) &result[dir_len], &file_name_len)
- != ERROR_SUCCESS)
- goto fail3;
+ status = RegQueryValueExA (hkey, "Layout File", 0, &var_type,
+ (LPBYTE) &result[dir_len], &file_name_len);
+ if (status != ERROR_SUCCESS)
+ {
+ goto fail3;
+ }
result[dir_len + file_name_len] = '\0';
@@ -322,7 +416,8 @@ clear_keyboard_layout_info (gpointer data)
map (VK_SCROLL, GDK_KEY_Scroll_Lock) \
map (VK_RSHIFT, GDK_KEY_Shift_R) \
map (VK_RCONTROL, GDK_KEY_Control_R) \
- map (VK_RMENU, GDK_KEY_Alt_R)
+ map (VK_RMENU, GDK_KEY_Alt_R) \
+ map (VK_CAPITAL, GDK_KEY_Caps_Lock)
#define DEFINE_DEAD(map) \
@@ -349,8 +444,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)
{
@@ -386,7 +481,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)
@@ -414,6 +509,9 @@ gdk_keysym_to_key_entry_index (GdkWin32KeymapLayoutInfo *info,
gunichar c;
gintptr index;
+ if (info->reverse_lookup_table == NULL)
+ return -1;
+
/* Special cases */
if (sym == GDK_KEY_Tab)
return VK_TAB;
@@ -438,8 +536,6 @@ gdk_keysym_to_key_entry_index (GdkWin32KeymapLayoutInfo *info,
/* Try converting to Unicode and back */
c = gdk_keyval_to_unicode (sym);
- g_return_val_if_fail (info->reverse_lookup_table != NULL, -1);
-
index = -1;
if (g_hash_table_lookup_extended (info->reverse_lookup_table,
GINT_TO_POINTER (c),
@@ -479,26 +575,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
@@ -556,7 +632,7 @@ update_keymap (GdkWin32Keymap *keymap)
info->file = get_keyboard_layout_file (info->name);
- if (load_layout_dll (keymap, info->file, info))
+ if (info->file != NULL && load_layout_dll (keymap, info->file, info))
{
info->key_entries = g_array_new (FALSE, FALSE,
sizeof (GdkWin32KeymapKeyEntry));
@@ -565,6 +641,11 @@ update_keymap (GdkWin32Keymap *keymap)
g_direct_equal);
init_vk_lookup_table (keymap, info);
}
+ else
+ {
+ g_warning("Failed to load keyboard layout DLL for layout %s: %s",
+ info->name, info->file);
+ }
}
if (info->handle == current_layout)
@@ -598,17 +679,6 @@ _gdk_win32_keymap_set_active_layout (GdkWin32Keymap *keymap,
}
}
-gboolean
-_gdk_win32_keymap_has_altgr (GdkWin32Keymap *keymap)
-{
- /* We just return FALSE, since it doesn't really matter because AltGr
- * is the same as Ctrl + Alt. Hence, we will never get a GDK_MOD2_MASK,
- * rather we will just get GDK_CONTROL_MASK | GDK_ALT_MASK. I don't
- * think there is any clean way to distinguish <Ctrl + Alt> from
- * <AltGr> on Windows. */
- return FALSE;
-}
-
guint8
_gdk_win32_keymap_get_active_group (GdkWin32Keymap *keymap)
{
@@ -745,7 +815,6 @@ gdk_win32_keymap_get_entries_for_keyval (GdkKeymap *gdk_keymap,
GArray *retval)
{
GdkWin32Keymap *keymap;
- BYTE keystate[256] = {0};
int group;
guint len = retval->len;
@@ -798,8 +867,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;
@@ -827,7 +895,6 @@ gdk_win32_keymap_get_entries_for_keycode (GdkKeymap *gdk_keymap,
GArray *key_array;
GArray *keyval_array;
int group;
- BYTE keystate[256] = {0};
BYTE vk;
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), FALSE);
@@ -864,7 +931,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;
@@ -899,7 +966,6 @@ gdk_win32_keymap_lookup_key (GdkKeymap *gdk_keymap,
GdkWin32Keymap *keymap;
GdkWin32KeymapLayoutInfo *info;
- BYTE keystate[256] = {0};
BYTE modbits;
guint sym;
@@ -915,9 +981,9 @@ gdk_win32_keymap_lookup_key (GdkKeymap *gdk_keymap,
return 0;
if (key->level < 0 || key->level > info->max_level)
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;
@@ -944,7 +1010,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);
@@ -968,11 +1034,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.
+ */
+
+ if (state & GDK_LOCK_MASK)
+ lock_bits |= CAPLOK;
- tmp_keyval = vk_and_mod_bits_to_gdk_keysym (keymap, layout_info, vk, keystate,
- mod_bits, &consumed_mod_bits);
+ 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);
@@ -987,6 +1067,13 @@ gdk_win32_keymap_translate_keyboard_state (GdkKeymap *gdk_keymap,
if (consumed_modifiers)
*consumed_modifiers = mod_bits_to_gdk_mod_mask (consumed_mod_bits);
+ /* Just a diagnostic message to inform the user why their keypresses aren't working.
+ * Shouldn't happen under normal circumstances. */
+ if (tmp_keyval == GDK_KEY_VoidSymbol && layout_info->tables == NULL)
+ g_warning("Failed to translate keypress (keycode: %u) for group %d (%s) because "
+ "we could not load the layout.",
+ hardware_keycode, group, layout_info->name);
+
return tmp_keyval != GDK_KEY_VoidSymbol;
}
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);
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index 58185697a6..69fdc4b9b7 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -351,7 +351,6 @@ GList *_gdk_win32_display_list_devices (GdkDisplay *dpy);
gboolean _gdk_win32_display_has_pending (GdkDisplay *display);
void _gdk_win32_display_queue_events (GdkDisplay *display);
-gboolean _gdk_win32_keymap_has_altgr (GdkWin32Keymap *keymap);
guint8 _gdk_win32_keymap_get_active_group (GdkWin32Keymap *keymap);
guint8 _gdk_win32_keymap_get_rshift_scancode (GdkWin32Keymap *keymap);
void _gdk_win32_keymap_set_active_layout (GdkWin32Keymap *keymap,