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

Reply via email to