Hi!

I have read much about Xlib and Xkb extension, till I have found the next 
comment:
     /* tell the libX11 that we will do input method handling ourselves
     * that keep libX11 from doing anything whith dead keys, allowing Wine
     * to have total control over dead keys, that is this line allows
     * them to work in Wine, even whith a libX11 including the dead key
     * patches from Th.Quinot (http://Web.FdN.FR/~tquinot/dead-keys.en.html)
     */
    TSXOpenIM( display, NULL, NULL, NULL);

So I have realized, that the keysym conversion should be done manually. So I 
have replaced the error reporting with manual conversion.

I have looked at 'X11/keysymdef.h' to determine the meaning of the third byte 
(0xff00) of the KeySym, and built a confversion map to a windows codepage.

If a codepage is found, then it is used in a MultiByteToWideChar to convert 
the last byte of KeySym.

And it works.
Tested with Hungarian, Serbian (cirillic) and Croatian (latinic - else same as 
serbian) keyboards, and it works perfectly.
But it should work with all of them...

So please apply.

ChangeLog:
Fixed KEYBOARD_ToUnicode to work with non Latin1 chars.

On Saturday 12 October 2002 22:34, Rizsanyi Zsolt wrote:
> The problem is that XLookupString is used, which according to the Xlib
> documentation works only for Latin1 chars. It does _not_ takes locale
> settings into account.
> It is explicitly stated in the docs that XLookupString is for the cases
> when you dont need locale handling. If you want to handle locales you have
> to use the input method framework (described in a separate Xlib chapter).
> And I could not find a simple solution from those docs (tough this was the
> first case I have looked in the X's postscript documentation).
>
> Regards
> Zsolt
>
> > Rizsanyi Zsolt wrote:
> > >On Wednesday 09 October 2002 14:25, Rizsanyi Zsolt wrote:
> > >>Hi!
> > >>
> > >>When running MS Word 97 I get the next error messages when I try to
> > >> write some of the Hungarian characters. So I'm reporting it as
> > >> requested in the message :)
> > >>
> > >>err:keyboard:X11DRV_ToUnicode Please report: no char for keysym 01F5
> > >>(odoubleacute) : err:keyboard:X11DRV_ToUnicode
> > >>(virtKey=DB,scanCode=1A,keycode=22,state=10)
> > >> err:keyboard:X11DRV_ToUnicode Please report: no char for keysym 01FB
> > >> (udoubleacute) :
> > >>err:keyboard:X11DRV_ToUnicode
> > >> (virtKey=DC,scanCode=2B,keycode=33,state=10)
> > >>
> > >>Is it trivial to fix, or there are some problems with it? I would like
> > >> if that could work... I'm also willing to code it if that is needed :)
> > >
> > >I have investigated it, and the problem is in this code (from
> > >dlls/x11drv/keyboard.c):
> > >
> > >    else TRACE("Found keycode %d (0x%2X)\n",e.keycode,e.keycode);
> > >
> > >    ret = XLookupString(&e, (LPVOID)lpChar, 2, &keysym, NULL);
> > >    wine_tsx11_unlock();
> > >
> > >    if (ret == 0)
> > >·       {
> > >·       BYTE dead_char;
> > >
> > >·       dead_char = KEYBOARD_MapDeadKeysym(keysym);
> > >·       if (dead_char)
> > >·           {
> > >·           MultiByteToWideChar(main_key_tab[kbd_layout].layout_cp, 0,
> > >&dead_char, 1, bufW, bufW_siz
> > >e);
> > >·           ret = -1;
> > >·           }
> > >·       else
> > >·           {
> > >·           char·       *ksname;
> > >
> > >·           ksname = TSXKeysymToString(keysym);
> > >·           if (!ksname)
> > >·       ·       ksname = "No Name";
> > >·           if ((keysym >> 8) != 0xff)
> > >·       ·       {
> > >·       ·       ERR("Please report: no char for keysym %04lX (%s) :\n",
> > >                    keysym, ksname);
> > >·       ·       ERR("(virtKey=%X,scanCode=%X,keycode=%X,state=%X)\n",
> > >                    virtKey, scanCode, e.keycode, e.state);
> > >·       ·       }
> > >·           }
> > >·       }
> > >
> > >The problems come from that the XLookupString is used to convert the
> > > keycode to the display string. It does properly display that the
> > > pressed key is odoubleacute, but because XLookupString works only for
> > > Latin1 characters, so the string representation is not returned.
> > >
> > >I dont see how this situation should be handled.
> > >Maybe another X function should be used instead of XLookupString (one
> > > which works with chars other than Latin1).
> > >
> > >I'm not too good in X programming so please HELP!!
> > >
> > >Thanks
> > >Zsolt
Index: dlls/x11drv/keyboard.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/keyboard.c,v
retrieving revision 1.11
diff -u -p -r1.11 keyboard.c
--- dlls/x11drv/keyboard.c	10 Oct 2002 23:30:13 -0000	1.11
+++ dlls/x11drv/keyboard.c	14 Oct 2002 21:43:34 -0000
@@ -1773,17 +1773,61 @@ INT X11DRV_ToUnicode(UINT virtKey, UINT 
 	    }
 	else
 	    {
-	    char	*ksname;
-
-	    ksname = TSXKeysymToString(keysym);
-	    if (!ksname)
-		ksname = "No Name";
-	    if ((keysym >> 8) != 0xff)
+		if ((keysym >> 8) != 0xff)
 		{
-		ERR("Please report: no char for keysym %04lX (%s) :\n",
-                    keysym, ksname);
-		ERR("(virtKey=%X,scanCode=%X,keycode=%X,state=%X)\n",
-                    virtKey, scanCode, e.keycode, e.state);
+		    unsigned char byte3 = (unsigned char )(keysym >> 8);
+		    UINT cp = 0;
+		    switch (byte3) {
+			case 0: // Latin 1
+			case 1: // Latin 2
+			case 2: // Latin 3
+			case 3: // Latin 4
+			case 5: // arabic
+			    cp = 28591 + byte3; break;
+			case 4: // kana
+			    break;
+			case 6: // Cyrillic
+			    cp = 28595; break;
+			case 7: //greek
+			    cp = 28597; break;
+			case 8: // Technical
+			case 9: // Special
+			case 10: // Publishing
+			case 11: // APL
+			    break;
+			case 12: // Hebrew
+			    cp = 28598; break;
+			case 13: // Thai
+			    cp = 874; break; // not ISO
+			case 14: // Korean, no mapping
+			    cp = 949; break; // not ISO
+			case 18: // Latin 8
+			    cp = 28604; break;
+			case 19: // Latin 9
+			    cp = 28605; break;
+			case 20: // Armenian
+			case 21: // Gregorian
+			case 22: // Azeri
+			case 30: // Vietnamese
+			case 32: // Currency
+			    break;
+		    }
+		    if (cp)
+		    {
+			BYTE key_char = keysym & 0xff;
+			ret = MultiByteToWideChar(cp, 0, &key_char, 1, bufW, bufW_size);
+		    }
+		    else
+		    {
+			char        *ksname;
+			ksname = TSXKeysymToString(keysym);
+			if (!ksname)
+			    ksname = "No Name";
+			ERR("Please report: no char for keysym %04lX (%s) :\n",
+				keysym, ksname);
+			ERR("(virtKey=%X,scanCode=%X,keycode=%X,state=%X)\n",
+				virtKey, scanCode, e.keycode, e.state);
+		    }
 		}
 	    }
 	}

Reply via email to