This is the mail archive of the
cygwin-xfree
mailing list for the Cygwin XFree86 project.
[PATCH] Fixes for Canadian Multilingual Standard keyboard layout handling
- From: Jon TURNEY <jon dot turney at dronecode dot org dot uk>
- To: cygwin-xfree at cygwin dot com
- Cc: Jon TURNEY <jon dot turney at dronecode dot org dot uk>
- Date: Tue, 13 Jul 2010 19:53:19 +0100
- Subject: [PATCH] Fixes for Canadian Multilingual Standard keyboard layout handling
- References: <4C3CB352.6080605@dronecode.org.uk>
- Reply-to: cygwin-xfree at cygwin dot com
Try to make the keyboard detection logging a bit clearer
I don't see why we don't just always load the US keyboard layout as all we
care about are scan codes: So add a flag to do that and turn it on for
Japanese (which already does that) and new layouts...
Add a keycode mapping for VK_OEM_8 which can be issued by Canadian Multilingual
Standard layout
Reformat the keyboard layout mapping table
Clarify XKB options in XWin man page
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
---
hw/xwin/XWin.man.pre | 8 ++--
hw/xwin/winconfig.c | 108 ++++++++++++++++++++++++++++++-------------------
hw/xwin/winkeybd.c | 4 ++
hw/xwin/winkeybd.h | 2 +-
hw/xwin/winlayouts.h | 83 +++++++++++++++++++-------------------
5 files changed, 117 insertions(+), 88 deletions(-)
diff --git a/hw/xwin/XWin.man.pre b/hw/xwin/XWin.man.pre
index 6b28b51..51268f6 100644
--- a/hw/xwin/XWin.man.pre
+++ b/hw/xwin/XWin.man.pre
@@ -251,7 +251,7 @@ exit silently and don't display any error message.
.B "\-xkbrules \fIrule\fP"
.TP 8
.B "\-xkbvariant \fIvariant\fp"
-These options implement the xkeyboard extension for loading
+These options configure the xkeyboard extension to load
a particular keyboard map as the X server starts. The behavior is similar
to the \fIsetxkbmap\fP program. The layout data is located at \fI
__datadir__/X11/xkb/\fP. Additional information is found in the
@@ -264,9 +264,9 @@ the options:
Alternatively one may use the \fIsetxkbmap\fP program after \fIXWin\fP is
running.
-The default is to select a layout matching your current layout as
-reported by \fIWindows\fP if known, or the default X server layout
-if no matching keyboard layout was found.
+The default is to select a configuration matching your current layout as
+reported by \fIWindows\fP, if known, or the default X server configuration
+if no matching keyboard configuration was found.
.SH UNDOCUMENTED OPTIONS
These options are undocumented. Do not use them.
diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c
index b05867b..3dc8ac4 100644
--- a/hw/xwin/winconfig.c
+++ b/hw/xwin/winconfig.c
@@ -240,6 +240,7 @@ Bool
winConfigKeyboard (DeviceIntPtr pDevice)
{
char layoutName[KL_NAMELENGTH];
+ unsigned char layoutFriendlyName[256];
static unsigned int layoutNum = 0;
int keyboardType;
#ifdef XWIN_XF86CONFIG
@@ -291,19 +292,30 @@ winConfigKeyboard (DeviceIntPtr pDevice)
Same might apply for chinese, korean and other symbol languages
too */
layoutNum = (layoutNum & 0xffff);
- if (keyboardType == 7)
- {
- /* Japanese layouts have problems with key event messages
- such as the lack of WM_KEYUP for Caps Lock key.
- Loading US layout fixes this problem. */
- if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL)
- winMsg (X_INFO, "Loading US keyboard layout.\n");
- else
- winMsg (X_ERROR, "LoadKeyboardLaout failed.\n");
- }
}
- winMsg (X_PROBED, "winConfigKeyboard - Layout: \"%s\" (%08x) \n",
- layoutName, layoutNum);
+
+ /* Discover the friendly name of the current layout */
+ {
+ HKEY regkey = NULL;
+ const char regtempl[] = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
+ char *regpath;
+ DWORD namesize = sizeof(layoutFriendlyName);
+
+ regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1);
+ strcpy(regpath, regtempl);
+ strcat(regpath, layoutName);
+
+ if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, ®key))
+ RegQueryValueEx(regkey, "Layout Text", 0, NULL, layoutFriendlyName, &namesize);
+
+ /* Close registry key */
+ if (regkey)
+ RegCloseKey (regkey);
+ free(regpath);
+ }
+
+ winMsg (X_PROBED, "Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n",
+ layoutName, layoutNum, layoutFriendlyName, keyboardType);
for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++)
{
@@ -311,46 +323,58 @@ winConfigKeyboard (DeviceIntPtr pDevice)
continue;
if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType)
continue;
-
+
bfound = TRUE;
winMsg (X_PROBED,
- "Using preset keyboard for \"%s\" (%x), type \"%d\"\n",
- pLayout->layoutname, pLayout->winlayout, keyboardType);
-
+ "Found matching XKB configuration \"%s\"\n",
+ pLayout->layoutname);
+
+ winMsg(X_PROBED,
+ "Model = \"%s\" Layout = \"%s\""
+ " Variant = \"%s\" Options = \"%s\"\n",
+ pLayout->xkbmodel ? pLayout->xkbmodel : "none",
+ pLayout->xkblayout ? pLayout->xkblayout : "none",
+ pLayout->xkbvariant ? pLayout->xkbvariant : "none",
+ pLayout->xkboptions ? pLayout->xkboptions : "none");
+
g_winInfo.xkb.model = pLayout->xkbmodel;
g_winInfo.xkb.layout = pLayout->xkblayout;
g_winInfo.xkb.variant = pLayout->xkbvariant;
- g_winInfo.xkb.options = pLayout->xkboptions;
+ g_winInfo.xkb.options = pLayout->xkboptions;
+
+ /*
+ All we care about are getting keyboard scan codes.
+
+ Some keyboard layouts have lots of quirks we would need to
+ work around, for e.g.
+
+ - Japanese layouts have problems with key event messages
+ such as the lack of WM_KEYUP for Caps Lock key.
+
+ - Candian Multilingual Standard generates fake Ctrl_L keypress
+ before AltGr and maps the Ctrl_R key to VK_OEM_8
+
+ So for simple and predictable behaviour, load the US keyboard
+ layout to avoid these problems. We could probably do this for
+ all layouts.
+ */
+ if (!pLayout->keeplayout)
+ {
+ if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL)
+ winMsg (X_INFO, "Loading Windows keyboard layout \"US\" to avoid layout quirks.\n");
+ else
+ winMsg (X_ERROR, "LoadKeyboardLayout failed.\n");
+ }
+
break;
}
-
+
if (!bfound)
{
- HKEY regkey = NULL;
- const char regtempl[] =
- "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
- char *regpath;
- unsigned char lname[256];
- DWORD namesize = sizeof(lname);
-
- regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1);
- strcpy(regpath, regtempl);
- strcat(regpath, layoutName);
-
- if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, ®key) &&
- !RegQueryValueEx(regkey, "Layout Text", 0, NULL, lname, &namesize))
- {
- winMsg (X_ERROR,
- "Keyboardlayout \"%s\" (%s) is unknown\n", lname, layoutName);
- }
-
- /* Close registry key */
- if (regkey)
- RegCloseKey (regkey);
- free(regpath);
+ winMsg (X_ERROR, "Keyboardlayout \"%s\" (%s) is unknown, using X server default layout\n", layoutFriendlyName, layoutName);
}
- }
-
+ }
+
/* parse the configuration */
#ifdef XWIN_XF86CONFIG
if (g_cmdline.keyboard)
diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index ad9e66a..fa3e12f 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -73,6 +73,10 @@ winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode)
int iParam = HIWORD (lParam);
int iParamScanCode = LOBYTE (iParam);
+#if CYGDEBUG
+ ErrorF("winTranslateKey: wParam %04x lParam %08x\n", wParam, (unsigned int)lParam);
+#endif
+
/* WM_ key messages faked by Vista speech recognition (WSR) don't have a
* scan code.
*
diff --git a/hw/xwin/winkeybd.h b/hw/xwin/winkeybd.h
index 5b2a589..90ad28e 100644
--- a/hw/xwin/winkeybd.h
+++ b/hw/xwin/winkeybd.h
@@ -266,7 +266,7 @@ g_iKeyMap [] = {
/* 220 */ 0, 0, 0,
/* 221 */ 0, 0, 0,
/* 222 */ 0, 0, 0,
- /* 223 */ 0, 0, 0,
+ /* 223 */ VK_OEM_8, 0, KEY_RCtrl, /* at least on Candian Multilingual Standard layout */
/* 224 */ 0, 0, 0,
/* 225 */ 0, 0, 0,
/* 226 */ 0, 0, 0,
diff --git a/hw/xwin/winlayouts.h b/hw/xwin/winlayouts.h
index 724465f..ad222bd 100644
--- a/hw/xwin/winlayouts.h
+++ b/hw/xwin/winlayouts.h
@@ -35,6 +35,7 @@ typedef struct
char *xkblayout;
char *xkbvariant;
char *xkboptions;
+ Bool keeplayout;
char *layoutname;
} WinKBLayoutRec, *WinKBLayoutPtr;
@@ -44,47 +45,47 @@ typedef struct
WinKBLayoutRec winKBLayouts[] =
{
- { 0x404, -1, "pc105", "zh_TW", NULL, NULL, "Chinese (Taiwan)"},
- { 0x405, -1, "pc105", "cz", NULL, NULL, "Czech"},
- {0x10405, -1, "pc105", "cz_qwerty", NULL, NULL, "Czech (QWERTY)"},
- { 0x406, -1, "pc105", "dk", NULL, NULL, "Danish"},
- { 0x407, -1, "pc105", "de", NULL, NULL, "German (Germany)"},
- {0x10407, -1, "pc105", "de", NULL, NULL, "German (Germany, IBM)"},
- { 0x807, -1, "pc105", "ch", "de", NULL, "German (Switzerland)"},
- { 0x409, -1, "pc105", "us", NULL, NULL, "English (USA)"},
- {0x10409, -1, "pc105", "dvorak", NULL, NULL, "English (USA, Dvorak)"},
- {0x20409, -1, "pc105", "us_intl", NULL, NULL, "English (USA, International)"},
- { 0x809, -1, "pc105", "gb", NULL, NULL, "English (United Kingdom)"},
- { 0x1009, -1, "pc105", "ca", "fr", NULL, "French (Canada)"},
- {0x11009, -1, "pc105", "ca", "multix", NULL, "Candian Multilingual Standard"},
- { 0x1809, -1, "pc105", "ie", NULL, NULL, "Irish"},
- { 0x40a, -1, "pc105", "es", NULL, NULL, "Spanish (Spain, Traditional Sort)"},
- { 0x80a, -1, "pc105", "latam", NULL, NULL, "Latin American"},
- { 0x40b, -1, "pc105", "fi", NULL, NULL, "Finnish"},
- { 0x40c, -1, "pc105", "fr", NULL, NULL, "French (Standard)"},
- { 0x80c, -1, "pc105", "be", NULL, NULL, "French (Belgian)"},
- { 0xc0c, -1, "pc105", "ca", "fr-legacy", NULL, "French (Canada) (Legacy)"},
- { 0x100c, -1, "pc105", "ch", "fr", NULL, "French (Switzerland)"},
- { 0x40d, -1, "pc105", "il", NULL, NULL, "Hebrew"},
- { 0x40e, -1, "pc105", "hu", NULL, NULL, "Hungarian"},
- { 0x40f, -1, "pc105", "is", NULL, NULL, "Icelandic"},
- { 0x410, -1, "pc105", "it", NULL, NULL, "Italian"},
- {0x10410, -1, "pc105", "it", NULL, NULL, "Italian (142)"},
- {0xa0000410,-1, "macbook79","it", "mac",NULL, "Italiano (Apple)"},
- { 0x411, 7, "jp106", "jp", NULL, NULL, "Japanese"},
- { 0x413, -1, "pc105", "nl", NULL, NULL, "Dutch"},
- { 0x813, -1, "pc105", "be", NULL, NULL, "Dutch (Belgian)"},
- { 0x414, -1, "pc105", "no", NULL, NULL, "Norwegian"},
- { 0x415, -1, "pc105", "pl", NULL, NULL, "Polish (Programmers)"},
- { 0x416, -1, "pc105", "br", NULL, NULL, "Portuguese (Brazil, ABNT)"},
- {0x10416, -1, "abnt2", "br", NULL, NULL, "Portuguese (Brazil, ABNT2)"},
- { 0x816, -1, "pc105", "pt", NULL, NULL, "Portuguese (Portugal)"},
- { 0x41a, -1, "pc105", "hr", NULL, NULL, "Croatian"},
- { 0x41d, -1, "pc105", "se", NULL, NULL, "Swedish (Sweden)"},
- { 0x424, -1, "pc105", "si", NULL, NULL, "Slovenian"},
- { 0x425, -1, "pc105", "ee", NULL, NULL, "Estonian"},
- { 0x452, -1, "pc105", "gb", "intl", NULL, "United Kingdom (Extended)"},
- { -1, -1, NULL, NULL, NULL, NULL, NULL}
+ { 0x00000404, -1, "pc105", "zh_TW", NULL, NULL, TRUE, "Chinese (Taiwan)"},
+ { 0x00000405, -1, "pc105", "cz", NULL, NULL, TRUE, "Czech"},
+ { 0x00010405, -1, "pc105", "cz_qwerty", NULL, NULL, TRUE, "Czech (QWERTY)"},
+ { 0x00000406, -1, "pc105", "dk", NULL, NULL, TRUE, "Danish"},
+ { 0x00000407, -1, "pc105", "de", NULL, NULL, TRUE, "German (Germany)"},
+ { 0x00010407, -1, "pc105", "de", NULL, NULL, TRUE, "German (Germany, IBM)"},
+ { 0x00000807, -1, "pc105", "ch", "de", NULL, TRUE, "German (Switzerland)"},
+ { 0x00000409, -1, "pc105", "us", NULL, NULL, TRUE, "English (USA)"},
+ { 0x00010409, -1, "pc105", "dvorak", NULL, NULL, TRUE, "English (USA, Dvorak)"},
+ { 0x00020409, -1, "pc105", "us_intl", NULL, NULL, TRUE, "English (USA, International)"},
+ { 0x00000809, -1, "pc105", "gb", NULL, NULL, TRUE, "English (United Kingdom)"},
+ { 0x00001009, -1, "pc105", "ca", "fr", NULL, TRUE, "French (Canada)"},
+ { 0x00011009, -1, "pc105", "ca", "multix", NULL, FALSE, "Candian Multilingual Standard"},
+ { 0x00001809, -1, "pc105", "ie", NULL, NULL, TRUE, "Irish"},
+ { 0x0000040a, -1, "pc105", "es", NULL, NULL, TRUE, "Spanish (Spain, Traditional Sort)"},
+ { 0x0000080a, -1, "pc105", "latam", NULL, NULL, TRUE, "Latin American"},
+ { 0x0000040b, -1, "pc105", "fi", NULL, NULL, TRUE, "Finnish"},
+ { 0x0000040c, -1, "pc105", "fr", NULL, NULL, TRUE, "French (Standard)"},
+ { 0x0000080c, -1, "pc105", "be", NULL, NULL, TRUE, "French (Belgian)"},
+ { 0x00000c0c, -1, "pc105", "ca", "fr-legacy", NULL, TRUE, "French (Canada, Legacy)"},
+ { 0x0000100c, -1, "pc105", "ch", "fr", NULL, TRUE, "French (Switzerland)"},
+ { 0x0000040d, -1, "pc105", "il", NULL, NULL, TRUE, "Hebrew"},
+ { 0x0000040e, -1, "pc105", "hu", NULL, NULL, TRUE, "Hungarian"},
+ { 0x0000040f, -1, "pc105", "is", NULL, NULL, TRUE, "Icelandic"},
+ { 0x00000410, -1, "pc105", "it", NULL, NULL, TRUE, "Italian"},
+ { 0x00010410, -1, "pc105", "it", NULL, NULL, TRUE, "Italian (142)"},
+ { 0xa0000410, -1, "macbook79","it", "mac",NULL, TRUE, "Italiano (Apple)"},
+ { 0x00000411, 7, "jp106", "jp", NULL, NULL, FALSE, "Japanese"},
+ { 0x00000413, -1, "pc105", "nl", NULL, NULL, TRUE, "Dutch"},
+ { 0x00000813, -1, "pc105", "be", NULL, NULL, TRUE, "Dutch (Belgian)"},
+ { 0x00000414, -1, "pc105", "no", NULL, NULL, TRUE, "Norwegian"},
+ { 0x00000415, -1, "pc105", "pl", NULL, NULL, TRUE, "Polish (Programmers)"},
+ { 0x00000416, -1, "pc105", "br", NULL, NULL, TRUE, "Portuguese (Brazil, ABNT)"},
+ { 0x00010416, -1, "abnt2", "br", NULL, NULL, TRUE, "Portuguese (Brazil, ABNT2)"},
+ { 0x00000816, -1, "pc105", "pt", NULL, NULL, TRUE, "Portuguese (Portugal)"},
+ { 0x0000041a, -1, "pc105", "hr", NULL, NULL, TRUE, "Croatian"},
+ { 0x0000041d, -1, "pc105", "se", NULL, NULL, TRUE, "Swedish (Sweden)"},
+ { 0x00000424, -1, "pc105", "si", NULL, NULL, TRUE, "Slovenian"},
+ { 0x00000425, -1, "pc105", "ee", NULL, NULL, TRUE, "Estonian"},
+ { 0x00000452, -1, "pc105", "gb", "intl", NULL, TRUE, "United Kingdom (Extended)"},
+ { -1, -1, NULL, NULL, NULL, NULL, FALSE, NULL}
};
/*
--
1.7.1
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://x.cygwin.com/docs/
FAQ: http://x.cygwin.com/docs/faq/