X11DRV: Fix to incorrect detection and other bugs of keyboard driver in XKB presence

Oleh R. Nykyforchyn nick at pu.if.ua
Mon Jan 31 01:18:54 CST 2005


Hello,

ChangeLog:
dlls/x11drv/keyboard.c, dlls/x11drv/event.c, dlls/x11drv/x11drv_main.c

Partially rewrite keyboard driver in x11drv to handle correct detection and switching of
keyboard layout both with and without XKB extension.

Reasons to change:

There are some issues with implementation of keyboard driver in Wine.
These are mainly caused by limitations of core X protocol that is used.
There no support for having several keyboard layouts at once and switching
between them on appropriate event (as Windows does). This feature is easily
implemented, for example, with XKB extension. The only thing that present
Wine x11drv can is to redetect the active layout if something is changed.
Moreover, it does it incorrectly if XKB (and several layouts) is used. 
Use of "merged" layout (e.g. English+Russian or German+French) doesn't help,
is conceptually wrong and has no perspective for future.

For example, the simplest way to have both German and French layouts is 
to construct XKB configuration with two
groups, 3 levels in each. Then, e.g., "E" key produce [e, E, 0xbf] in "French"
group and [e, E, 0x80] in "German" one (taken from layouts in keyboard.c).
By XKB rules compatibility map contains a row [e, E, e, E, 0xbf, 0x80]. x11drv
complains about not supporting >4 keysyms_per_keycode and leaves [e, E, e, E]. All
accents are ignored, closest pattern is "eE". The same with other keys. Of course
Wine will detect "United States keyboard" - no French, no German.

I propose the following structure of keyboard layouts management in Wine. First,
there is a function X11DRV_KEYBOARD_LayoutSwitched() that is called by event
handlers. If this function sees that layout we are switching to is invalid (has
not be determined yet or does not match the current state of keyboard) it
calls X11DRV_KEYBOARD_RefreshLayout(). In most cases it only changes current layout
index and there is no need in detecting layout again (as present code does).
If keyboard layout changes, we can notify appication about it (although I put this
code into #if 0 ... #endif because the respective function isn't implemented yet).

In turn, if this function detect that
the global key mapping was changed, it clears detected layout and get new
keycodes range. It also refreshes information about key redirection (if
XKB overlays are used) by call to X11DRV_KEYBOARD_RefreshOverlays(). Current
code knows nothing about overlays and therefore can't correctly determine
XKB layouts. 

We also should listen not only to XKeyEvent, but also to XkbEvents,
as changes to XKB keyboard state that actually change layout (for example, turn on
Japanese group instead of English) don't change compatibility keyboard map and
therefore are invisible to core X protocol. So it is necessary to add 
X11DRV_ProcessXkbEvent() function.

I also tested the patch and saved some debug logs (the simplest - from
builtin notepad) to ensure that everything is working right:

logall.txt - big log with everything that is doing when layouts are switched
and keys are pressed (WINEDEBUG=+keyboard,+key,+layout);

loglayout.txt - detecting of one layout (WINEDEBUG=+layout)

logkey.txt - detecting of layouts (+keyboard) and processing keyboard events (+key)

logkbd.txt - detecting and switching of layouts (WINEDEBUG=+keyboard).

Also gzipped new keyboard.c is attached as the patch is big and not so easy readable.

Oleh R. Nykyforchyn
-------------- next part --------------
A non-text attachment was scrubbed...
Name: wine.patch.gz
Type: application/octet-stream
Size: 11452 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20050131/4b3dbd63/wine.patch.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: keyboard.c.gz
Type: application/octet-stream
Size: 23832 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20050131/4b3dbd63/keyboard.c.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: logall.txt.gz
Type: application/octet-stream
Size: 32260 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20050131/4b3dbd63/logall.txt.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: logkbd.txt.gz
Type: application/octet-stream
Size: 376 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20050131/4b3dbd63/logkbd.txt.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: logkey.txt.gz
Type: application/octet-stream
Size: 1624 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20050131/4b3dbd63/logkey.txt.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: loglayout.txt.gz
Type: application/octet-stream
Size: 5654 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20050131/4b3dbd63/loglayout.txt.obj


More information about the wine-patches mailing list