Hello. i've seen the announcement of the deadline for new code for 4.5, and decided to present my work. There are some rough edges, but, let me try:
First of all, the patch is here http://bugs.xfree86.org/show_bug.cgi?id=1529 or alternatively http://maruska.dyndns.org/comp/packages/xkb-plugin.patch * MOTIVATION: The motivation for these patches is to make possible to load a plugin which rewrites the stream of pressed and released keycodes with possibly some delay, into other keycodes, in function of the duration and parallelism of the strokes. As a simple example, think that pressing "f" longer than usual the keycode is rewritten to that of a key "Shift". I have written such plugin, and I can say (only 2 people have tried it so far), that it enables better use of central keys of the keyboard, and void the need for peripheral (slow to reach) modifier keys. This can remove strain on weak little fingers, pushing their job on the strong central fingers, and overall diminish side-movement of fingers, because having many modifiers is much easier this way. All that is needed (once activated) is correct configuration of various time limits to distinguish a normal stroke (to produce a letter) from unusually longer, or unusual parallelism of 2 strokes. Not that this is an easy task. I have made the patches in a way, so that with no plugin loaded all works as normal, in fact better due to patches to auto-repeat code, and some XKB functions (there were bugs in configuration requests server-side, and in reconfiguration-notification events processing client-side). For a more detailed explanation of what my plugin can do, see http://maruska.dyndns.org/wiki/forkExtension.html (it's just a finite automaton, which works with time intervals as well) Now, I will comment on subproblems solved, as I met them in chronological order, and list the filenames where patches were needed. * Since the rewriter(plugin) is independent code, I decided to make it (re-)loadable via dlopen. So, it is a simple .so file. I provide one such plugin, which is here: http://maruska.dyndns.org/comp/packages/xkb-plugin-2.6.tar.gz Note: It's a C++ program, which has a fixed Makefile with hard-wired /usr/X11R6/. I have no idea on how to write a flexible imakefile/Makefile So, I extended ProcXkbDispatch in xc/programs/Xserver/xkb/xkb.c to permit: 1/ a new request X_kbSetPlugin (with filename as argument) 2/ subrequests, handled by the plugin. The request (ProcXkbSetPlugin) initializes a new slot in DeviceIntRec, to point at DeviceIntRec_plugin, where the API/methods (& some data) are kept. Limitations/drawbacks: - one plugin only (per device, but tested only on "one keyboard"). - Anyone can request a plugin, just by filename. Files: programs/Xserver/xkb/xkb.c new request(s) programs/Xserver/xkb/xkb.h useless declaration programs/Xserver/include/inputstr.h new slot in device & definition of DeviceIntRec_plugin with comments. include/extensions/XKBsrv.h make C++ friendly. The plugin itself is compiled as a C++ program (though not "OO-oriented"). lib/X11/XKBCtrls.c request the plugin include/extensions/XKB.h new request include/extensions/XKBproto.h idem lib/X11/XKBlib.h idem * ProcessKeyboardEvent calls the plugin (instead of calling AccessXFilterPressEvent/AccessXFilterReleaseEvent) so, these are the functions which the plugin should call to deliver the rewritten events, when it decides. files: programs/Xserver/xkb/xkbPrKeyEv.c programs/Xserver/hw/xfree86/input/mouse/mouse.c I want the keyboard plugin to know about mouse events too. This patch is quite ugly, since it searches for the keyboard in global variables. * The plugin may place its timers. via TimerSet This solution will probably be replaced soon. Since the processing depends only on the time of the keyboard, a timed action should be invoked in xf86eqProcessInputEvents when we go throught the timed sequence of events. (in case of no events present, we use the upper bound of no-events-from-keybard time). * the plugin (which can be invoked from timers) must be aware of Synchronous grabs, ie. device freeze (of its device). Obviously replaying from queue needs to push events into the plugin. files: programs/Xserver/dix/events.c many modifications to the freeze-queue code. * autorepeat (AR) code, up to now, did nor work reasonably, so I had to fix it somewhat. During a device freeze timers associated with the plugin and autorepeat(AR) are "disabled". On thawing I look at the time of first queued event, or the "keyboard current time", invoke the plugin (if it has another event which should come before the first on the queue); I also calculate what timers would have run before the first event for AR, and invoke a substitution for them. All of this, of course, must happen 1 event at a time (a new freeze could accur). - it is possible to repeat more keys (at the same time). Maybe I should make it optional? files: programs/Xserver/xkb/xkbAccessX.c this requires a futher refinement, as mentioned above, timers are not the right tool, and xf86eqProcessInputEvents should be used instead. include/extensions/XKBsrv.h * another bug during device freeze see my other post (spontaneous lost keyboard events during sync grab) programs/Xserver/hw/xfree86/common/xf86Events.c hwdown (the attribute "down" is unused, here) refactoring for a new entry xf86PostKbdEvent_timed, from keyboard driver(s), which provide the time, and convert scancode->keycode themselves! programs/Xserver/hw/xfree86/common/xf86Io.c VT switch - my new functions releasing emulation! GetTimeInMillis changes ???? programs/Xserver/dix/devices.c ok. what about ->down? programs/Xserver/xkb/xkbActions.c modifies down. but it's useless now! FixKeyState(xE,dev); * But this requires precise time information about the key events. context switches happen even between reading from keyboard and getting the current time, and also between getting the current time and using that time (value), so I hacked some code to read (on linux) from /dev/input/event* files/devices (provided by evdev linux kernel module; for usb keyboards in 2.4, and for all in 2.6 series). These (afaik) provide the precise time of event. In making this piece of code, my priority was simplicity and security to never end up without keyboard. files: programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c ... discovering evdev devices. programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c reading from evdev (with time) programs/Xserver/hw/xfree86/common/xf86Priv.h the new function & evdev structures * time: The time provided in the evdev events, is the same as returned by gettimeofday(). I had to change GetTimeInMillis, unfortunately, reverting a previous patch to make time monotone. Maybe, whey I drop Timers in favour of a patch to xf86eqProcessInputEvents there won't be a danger for non-monotoe time (of events). files: programs/Xserver/os/utils.c * There are several (independent) bugfixes for XKB. ** xkb-unaware applications don't update the keyboard mapping, when xkb _types_ are changed. lib/X11/XKBGetMap.c some serious bugs fixed. lib/X11/XKBMAlloc.c a bugfix lib/X11/XKBUse.c bugfix ** calls to configure (xkb) so called "client map" fail, if no xkb type is modified. programs/Xserver/xkb/xkb.c important bug fixes! * Known issues: ** hardware (non XKB-generated) auto-repeat. appears to work ok, but i'm not sure about the implications of the patch to programs/Xserver/dix/events.c ** Some parts of the patch should be #ifdef XKB: the auto-repeat code in programs/Xserver/dix/events.c ** evdev: I don't know how the select()-related code works. So, I do rely on xf86Info.consoleFd. ** security: the plugin should be loadable from restricted directory. ** installation to build the plugin, I need some server headers. for now i do: cp -a programs/Xserver/include/ ${projectroot}/include/X11/server/ ** inconsistent code indentation and symbol names. I would like to hear, what modifications are needed to consider it for inclusion, and then I would like to know what plans are there for the keyboard driver (evdev), as I have read about some changes under way in the keybord drivers. My desired features (for keyboard) is to have a flexible mappings scancode -> keycode per keybord (laptop buillt-in layout differs from external keyboard). that's all. _______________________________________________ Devel mailing list [email protected] http://XFree86.Org/mailman/listinfo/devel
