Generic Event extension RFC

Peter Hutterer mailinglists at
Tue Feb 20 15:29:49 PST 2007

X is running out of event codes, with only 15 or so left for future  
extensions. (Thanks for keithp for pointing that out at the XDC2007)
I didn't want to get beaten up for using up the last event code for  
MPX, so I sat down the last few days and wrote the Generic Event  

The Generic Event extension is a template for future extensions to re- 
use a single opcode. GE doesn't actually do much but provide headers  
and a few API calls. The majority of the work is still to be done in  
the extensions.

GE defines a single event, to be used by all extensions.

     BYTE    type	/* always GenericEvent type */
     CARD8   extension  /* extension specific opcode */
     CARD16  sequenceNumber
     CARD8   evType; /* real event type */
     CARD8   pad0;
     CARD16  pad1;
     CARD32  pad2;
     CARD32  pad3;
     CARD32  pad4;
     CARD32  pad5;
     CARD32  pad6;
     CARD32  pad7;

The field 'extension' is to be set to the offset of the extension  
(see below). The 'evType' field is the actual opcode of the event.  
This event is to be cast by an extension to it's real format. This  
makes it possible to have 256 events per extension, with a max of 256  
extensions. The tradeoff is a maximum of 27 bytes per event useable  
by an extension instead of the current 29 bytes per event.

Two functions are important:
GERegisterExtension() on the server side. Extensions provide the  
EventSwap function and recieve the extension offset. The offset is  
then to be used in the "extension" field of the event. Extensions  
need to call this once when they initialise.

XGERegisterExtension() on the client side. Extensions pass in the  
extension opcode and the event conversion routines event_to_wire and  
wire_to_event. Extensions need to call this once when they initialise.

All work to actually convert events still has to be done in the  
extension, GE just relays the calls, both on the server and on the  
client side. I tried to basically provide similar APIs as already  
exist. Currently an extension passes the event swap functions to the  
server, here they pass it to GE instead.
The only real extra work for the extension is to provide an  
additional request that returns the extension's offset inside the  
server. GE provides a function to set the event mask on a window as  

Internal changes are fairly limited too. I added another field to the  
window optional struct, called geMasks which contains the masks set  
by various clients on the window. The only other thing I had to add  
was adding a different treatment for generic events inside  

I have integrated GE into Xi to get  
PointerKeyboardPairingChangedNotifyEvents* and it works. There will  
be missing pieces and things that need to be added but the proof-of- 
concept works nice. GE mixes well with existing extensions, the  
additional work is fairly limited.

Two of the advantages I liked are that GE allows for fixed event  
opcodes and fixed event masks inside an extension. None of the crazy  
stuff Xi does.
Disadvantages for now are no per-device events (like Xi does) and a  
few missing pieces (dont-propagate handling is missing right now).  
And masks are CARD32, so a maximum of 32 masks per extension.  
Although that could be fixed if necessary.

I put the code for geproto and libXge up at

diff mpx-xge

proof of concept application:

No XCB bindings yet, sorry guys. :)

Yay or nay?


* The event you get when you change which mouse the keyboard focus  
should follow. And it'll be renamed soon, I'm sick of typing it.

Multi-Pointer X Server

More information about the xorg mailing list