This is the mail archive of the cygwin-xfree mailing list for the Cygwin XFree86 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fixes for Canadian Multilingual Standard keyboard layout handling


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, &regkey))
+          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, &regkey) &&
-          !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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]