Re: Swedish keyboard not recognised

Peter Hunnisett <[email protected]> Wed, 26 Jan 2005 17:35:50 -0500
Newsgroups gmane.comp.emulators.winex.devel
Message-ID <[email protected]>
Peter Hunnisett wrote:

> Göran Uddeborg wrote:
>
>> Dmitry Timoshkov writes:
>>  
>>
>>> Perhaps Peter needs to set Swedish locale (just prepend LC_ALL=sv_SE
>>> to the command line) in order to replicate your setup.
>>>   
>>
>>
>> Sorry for the late reply.
>>
>> I don't think locale is involved.  The code in
>> X11DRV_KEYBOARD_DetectLayout() does a XKeycodeToKeysym() (via
>> TSXKeycodeToKeysym()) for each keycode, and compares to a table.
>> There is no locale dependency here I believe.  Or is it?
>>  
>>
>
> The problem isn't the locale. It appears to depend on the version of 
> X. I'll have to do a little bit of investigation on another setup to 
> see what the fun stuff that's going on is. There is at least the 
> problem where the code isn't willing to deal with 6 keysyms per 
> keycode, but I'm not sure this is the problem.
>
>> The table seems correct, but still the matching fails for some
>> reason.
>>  
>>
> If you feel like instrumenting the code a little more or walking 
> through the code in gdb feel free ... that's what I'm going to be 
> doing :)


Perhaps you could give me the compressed output from the patch that I've 
attached (when running with +keyboard,+key). From my look at things, it 
appears that NoSymbol is returned for index 2 and 3 which is why the 
mismatching is happening. However, this would seem to indicate that 
xmodmap is doing some magic when it's generating the keycode to keysym 
output and I just don't quite understand this.

>
> *Ciao,
> Peter
> *
>

*
Ciao,
Peter
*
keyboard.diff (text/x-patch, 2.9 KB)
Index: windows/x11drv/keyboard.c
===================================================================
RCS file: /home/cvs/winex/windows/x11drv/keyboard.c,v
retrieving revision 1.18
diff -u -r1.18 keyboard.c
--- windows/x11drv/keyboard.c	23 Aug 2004 01:06:59 -0000	1.18
+++ windows/x11drv/keyboard.c	26 Jan 2005 22:25:59 -0000
@@ -961,13 +961,12 @@
   const char (*lkey)[MAIN_LEN][4];
   unsigned max_seq = 0;
   int max_score = 0, ismatch = 0;
-  char ckey[4] =
-  {0, 0, 0, 0};
+  char ckey[6] = {0, 0, 0, 0, 0, 0};
 
   syms = keysyms_per_keycode;
-  if (syms > 4) {
+  if (syms > 6) {
     WARN("%d keysyms per keycode not supported, set to 4\n", syms);
-    syms = 4;
+    syms = 6;
   }
   for (current = 0; main_key_tab[current].comment; current++) {
     TRACE("Attempting to match against \"%s\"\n", main_key_tab[current].comment);
@@ -980,27 +979,38 @@
     for (keyc = min_keycode; keyc <= max_keycode; keyc++) {
       /* get data for keycode from X server */
       for (i = 0; i < syms; i++) {
-	keysym = TSXKeycodeToKeysym (display, keyc, i);
-	/* Allow both one-byte and two-byte national keysyms */
-	if ((keysym < 0x800) && (keysym != ' '))
-	  ckey[i] = keysym & 0xFF;
-	else {
-	  ckey[i] = KEYBOARD_MapDeadKeysym(keysym);
-	}
+         keysym = TSXKeycodeToKeysym (display, keyc, i);
+         TRACE( "keysym is %x for %x at index %d\n", keysym, keyc, i );
+         /* Allow both one-byte and two-byte national keysyms */
+         if ((keysym < 0x800) && (keysym != ' '))
+            ckey[i] = keysym & 0xFF;
+         else {
+            ckey[i] = KEYBOARD_MapDeadKeysym(keysym);
+         }
       }
       if (ckey[0]) {
+         TRACE( "Have ckey %x/%x/%x/%x/%x/%x\n", ckey[0], ckey[1], ckey[2], ckey[3], ckey[4], ckey[5] );
+
 	/* search for a match in layout table */
 	/* right now, we just find an absolute match for defined positions */
 	/* (undefined positions are ignored, so if it's defined as "3#" in */
 	/* the table, it's okay that the X server has "3#£", for example) */
 	/* however, the score will be higher for longer matches */
 	for (key = 0; key < MAIN_LEN; key++) {
+
 	  for (ok = 0, i = 0; (ok >= 0) && (i < syms); i++) {
 	    if ((*lkey)[key][i] && ((*lkey)[key][i] == ckey[i]))
+	    {
+          TRACE( "Matching key %d/%d on %x and %x \n", key, i, (*lkey)[key][i], ckey[i] );
 	      ok++;
+	    }
 	    if ((*lkey)[key][i] && ((*lkey)[key][i] != ckey[i]))
+	    {
+          TRACE( "Bad match key %d/%d on %x and %x \n", key, i, (*lkey)[key][i], ckey[i] );
 	      ok = -1;
+	    }
 	  }
+
 	  if (ok > 0) {
 	    score += ok;
 	    break;
@@ -1013,13 +1023,13 @@
 	  if (key > pkey) seq++;
 	  pkey = key;
 	} else {
-	  TRACE_(key)("mismatch for keycode %d, character %c\n", keyc,
-		 ckey[0]);
+	  TRACE_(key)("mismatch for keycode %d, character %c\n", keyc, ckey[0]);
 	  mismatch++;
 	  score -= syms;
 	}
       }
     }
+
     TRACE("matches=%d, mismatches=%d, seq=%d, score=%d\n",
 	   match, mismatch, seq, score);
     if ((score > max_score) ||