[gtk/gtk-3-24: 5/6] gdkkeys-win32: Perform keyboard layout substitution
- From: Luca Bacci <lbacci src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gtk-3-24: 5/6] gdkkeys-win32: Perform keyboard layout substitution
- Date: Tue, 11 Jan 2022 09:56:51 +0000 (UTC)
commit cc47262ccbea9c9660b0ffeaf1b4d12e5908a505
Author: David Hogan <david q hogan gmail com>
Date: Mon Jan 10 03:34:59 2022 +0100
gdkkeys-win32: Perform keyboard layout substitution
For some users, GetKeyboardLayoutNameA() returns an alias instead of the
fully resolved keyboard layout identifier. In that case, we have to
query the registry to resolve the alias before we can look up the DLL
path.
See comments under #4610
gdk/win32/gdkkeys-win32.c | 97 ++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 87 insertions(+), 10 deletions(-)
---
diff --git a/gdk/win32/gdkkeys-win32.c b/gdk/win32/gdkkeys-win32.c
index 4cb1e176a1..84aa381902 100644
--- a/gdk/win32/gdkkeys-win32.c
+++ b/gdk/win32/gdkkeys-win32.c
@@ -166,6 +166,67 @@ vk_to_char_fuzzy (GdkWin32Keymap *keymap,
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().
@@ -173,21 +234,37 @@ 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;
- LSTATUS status;
+ 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);
+ }
status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, (LPCSTR) kbdKeyPath, 0,
KEY_QUERY_VALUE, &hkey);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]