Site hosted by Angelfire.com: Build your free website today!

Hands-on Projects for the Linux Graphics Subsystem

New book from Christos Karayiannis

Available in Amazon Kindle format at:

amazon.com   amazon.co.uk   amazon.de   amazon.es   amazon.fr   amazon.it

Please notice that the subjects of the current section are discussed in detail in section 3, "The X Server Side".

X Client's X Protocol Requests Dispatching

As we saw at section 2.2 after the connection establishment the requests are handled in Dispatch() by the instruction:

result = (* client->requestVector[MAJOROP])(client);

where the requestVector was set during the connection establishment to either SwappedProcVector or ProcVector:

    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;

and MAJOROP is the reqType field of the client's request.

The ProcVector table

At the following image we see the contents of ProcVector[], that is the pointers to functions that are executing according to the major opcode (MAJOROP) found at the request of the X client:

_X_EXPORT int (* ProcVector[256]) (
	ClientPtr /* client */
    ) =
{
    ProcBadRequest,
    ProcCreateWindow,
    ProcChangeWindowAttributes,
    ProcGetWindowAttributes,
    ProcDestroyWindow,
    ProcDestroySubwindows,		/* 5 */
    ProcChangeSaveSet,
    ProcReparentWindow,
    ProcMapWindow,
    ProcMapSubwindows,
    ProcUnmapWindow,			/* 10 */
    ProcUnmapSubwindows,
    ProcConfigureWindow,
    ProcCirculateWindow,
    ProcGetGeometry,
    ProcQueryTree,			/* 15 */
    ProcInternAtom,
    ProcGetAtomName,
    ProcChangeProperty,
    ProcDeleteProperty,
    ProcGetProperty,			/* 20 */
    ProcListProperties,
    ProcSetSelectionOwner,
    ProcGetSelectionOwner,
    ProcConvertSelection,
    ProcSendEvent,			/* 25 */
    ProcGrabPointer,
    ProcUngrabPointer,
    ProcGrabButton,
    ProcUngrabButton,
    ProcChangeActivePointerGrab,	/* 30 */
    ProcGrabKeyboard,
    ProcUngrabKeyboard,
    ProcGrabKey,
    ProcUngrabKey,
    ProcAllowEvents,			/* 35 */
    ProcGrabServer,
    ProcUngrabServer,
    ProcQueryPointer,
    ProcGetMotionEvents,
    ProcTranslateCoords,		/* 40 */
    ProcWarpPointer,
    ProcSetInputFocus,
    ProcGetInputFocus,
    ProcQueryKeymap,
    ProcOpenFont,			/* 45 */
    ProcCloseFont,
    ProcQueryFont,
    ProcQueryTextExtents,
    ProcListFonts,
    ProcListFontsWithInfo,		/* 50 */
    ProcSetFontPath,
    ProcGetFontPath,
    ProcCreatePixmap,
    ProcFreePixmap,
    ProcCreateGC,			/* 55 */
    ProcChangeGC,
    ProcCopyGC,
    ProcSetDashes,
    ProcSetClipRectangles,
    ProcFreeGC,				/* 60 */
    ProcClearToBackground,
    ProcCopyArea,
    ProcCopyPlane,
    ProcPolyPoint,
    ProcPolyLine,			/* 65 */
    ProcPolySegment,
    ProcPolyRectangle,
    ProcPolyArc,
    ProcFillPoly,
    ProcPolyFillRectangle,		/* 70 */
    ProcPolyFillArc,
    ProcPutImage,
    ProcGetImage,
    ProcPolyText,
    ProcPolyText,			/* 75 */
    ProcImageText8,
    ProcImageText16,
    ProcCreateColormap,
    ProcFreeColormap,
    ProcCopyColormapAndFree,		/* 80 */
    ProcInstallColormap,
    ProcUninstallColormap,
    ProcListInstalledColormaps,
    ProcAllocColor,
    ProcAllocNamedColor,		/* 85 */
    ProcAllocColorCells,
    ProcAllocColorPlanes,
    ProcFreeColors,
    ProcStoreColors,
    ProcStoreNamedColor,		/* 90 */
    ProcQueryColors,
    ProcLookupColor,
    ProcCreateCursor,
    ProcCreateGlyphCursor,
    ProcFreeCursor,			/* 95 */
    ProcRecolorCursor,
    ProcQueryBestSize,
    ProcQueryExtension,
    ProcListExtensions,
    ProcChangeKeyboardMapping,		/* 100 */
    ProcGetKeyboardMapping,
    ProcChangeKeyboardControl,
    ProcGetKeyboardControl,
    ProcBell,
    ProcChangePointerControl,		/* 105 */
    ProcGetPointerControl,
    ProcSetScreenSaver,
    ProcGetScreenSaver,
    ProcChangeHosts,
    ProcListHosts,			/* 110 */
    ProcChangeAccessControl,
    ProcChangeCloseDownMode,
    ProcKillClient,
    ProcRotateProperties,
    ProcForceScreenSaver,		/* 115 */
    ProcSetPointerMapping,
    ProcGetPointerMapping,
    ProcSetModifierMapping,
    ProcGetModifierMapping,
    0,					/* 120 */
    0,
    0,
    0,
    0,
    0,					/* 125 */
    0,
    ProcNoOperation    
};

Case study: X_CreateWindow request

Let's consider that the X client has send an X_CreateWindow request which was described in section 1.2, where reqType (the MAJOROP) becomes X_CreateWindow, which is defined in Xproto.h as:


#define X_CreateWindow                  1    

Looking up to ProcVector at index 1 we find that it corresponds to ProcCreateWindow, which is a DIX routine.

ProcCreateWindow() dispatching routine

ProcCreateWindow() extracts the fields of the xCreateWindowReq request sent by the client to use them as arguments for a CreateWindow() call:


    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
			      stuff->y, stuff->width, stuff->height, 
			      stuff->borderWidth, stuff->class,
			      stuff->mask, (XID *) &stuff[1], 
			      (int)stuff->depth, 
			      client, stuff->visual, &result);

stuff is used to get access to the fields and is introduced with the following instruction:

REQUEST(xCreateWindowReq);

where REQUEST is defined in dix.h as:

#define REQUEST(type) \
	register type *stuff = (type *)client->requestBuffer

In other words a pointer of type xCreateWindowReq is placed in the client's buffer (the client struct that is found inside the X server) and the request fields are accessed. What looks interesting here is the 10th argument:

(XID *) &stuff[1]

which advances the pointer after the current xCreateWindowReq struct. As seen in section 1.2.2 and in image image1_3 XCreateSimpleWindow() after the XCreateWindowReq it places 8 additional bytes for the background and the border color that are not included in the XCreateWindowReq fields. In other words struct XCreateWindowReq is used mainly by XCreateWindow() and when used by XCreateSimpleWindow() its fields are extended by the additional bytes. When those bytes are placed the mask of the request is updated to indicate that additional values should also be processed along with the XCreateWindowReq fields. This takes place in CrWindow.c:

req->mask = CWBackPixel | CWBorderPixel

The mask bits are taken into account when CreateWindow() calls ChangeWindowAttributes(), described latter in this text.

The DIX layer's CreateWindow() routine

CreateWindow() also a DIX routine which calls the screen specific CreateWindow routine as:

    if (!(*pScreen->CreateWindow)(pWin))

We will continue with the request dispatching in section 3.2.5.3, where ReadRequestFromClient() is examined and then with section 7.1, where a compete example is presented.