index

pipeline

This is the last part, which should also make clear motivation for the design of Medved driver.

This time i will try to explain concepts behind the code inserted into XKB and DIX parts (and also the input processing in hw/xfre86/common) of the X server by included patches.

let me start with an explanation of the "upper half" of key event processing:

events are taken from xf86EventQueue

and take one of these routes:

A: keyboard is "frozen": the event is put in a queue syncEvents

B:

1/ XKB scans them to detect special sequences (to invoke AccessX functions)

2/ XKB rewrites keycodes into XKB actions: updates XKB state, turns key events into mouse events etc.

3/ the "core" processing: focused window (& its ancestors) is checked for a grab and the event is sent to some client(s).

If the grabbing client requests some events in the syncEvents are re-routed in the route B.

Steps on the route B register some timers, which in case keyboard is frozen need to be canceled. This may be complicated, and cause unpleasant buggy behaviour. 2 years ago i found such a timer (auto-repeat, registered in the step 1/) which was not getting canceled on route A.

I devised a different approach: events take just 1 route, but there is some communication in both directions:

The unique route, which i call pipeline, can even be made modular:

We have a (doubly) linked list of "processors". The original term which i used for such processors was "plugin", since i worked on just one such, and i could be reloaded with dlopen.

Events taken from xf86EventQueue are pushed to the first processor.

Each processor can decide when to hand over events to the next one.

Now, since time (event without any events) is crucial to auto-repeat, and other functionality, "time elapsed without any key" needs to be processed as well.

So, each processor, can call 2 methods of its next neighbour: to hand over time, or hand over an event.

To address the need to freeze the processing (think syncronous grab) each processor can signal the previous neighbour, that it cannot accept key events nor time, temporarily.

When it resumes processing it will signal again the previous neighbour.


event      +--------+   stop
---------->|        |<------
           |proce   |
time       |   ssor |   resume
---------->|(plugin)|<------
           +--------+

To connect this pipeline into the current X code, i made 2 processors for the extremes of the pipeline, called "core", which hands over event to the dix/events.c code, and "stack", which accepts events from xf86EventQueue and never freezes (it replaces syncEvents), and of course i changed the interfacing functions a little.

Thus, for example,

realInputProc & enqueueInputProc (processInputProc) point at my custom functions, which invoke the pipeline ("event" in the schema).

On the opposite end, PlayReleasedEvents is combined with invoking the "resume" of the pipeline.

As i said, the pipeline wants also time as input, so

all the way from WaitForSomething (which gets the current time before calling Select) time is passed on to all functions, through wakeupHandlers to ProcessInputEvents.

otoh, the pipeline, instead of using timers, registers a BlockHandler and wants to set the timeout for Select. To do so, it needs to know the current time, so i had to change BlockHandlers to accept an additional parameter, current time.

Hence, a large part of the patches is related to adding TIME argument to many function signatures.

I changed the signatures unconditionally. W/o #ifdev MMC_PIPELINE ! This might result in breaking ABI with 3rd party drivers?

I also added 2 new methods (for devices)

dev->public.thawProc dev->public.pushTimeProc

The second part (of patches) is an alternative implementation of auto-repeat. programs/Xserver/xkb/xkbAccessX.c

I have NOT implemented a pipeline version of other functionality in that file: slowKey, StickyKeys. I think it's easy to do, though.

3rd part of this patch is related to my original aim: inserting a plugin, which changes keycodes. So it includes code necessary for:

Clients can request to insert/remove plugin (on the pipeline) and set & read configuration. This is inserted into the XKB code.