Hands-on Projects for the Linux Graphics Subsystem
|
We will use the code sample from section 1.5 to make a summary of the initial steps of the X client-server connection, discussed in the previous sections, and then start examining the normal operation between the server and the client at the X Protocol layer.
/* Simple Xlib application drawing a box in a window. To Compile: gcc -O2 -Wall -o test test.c -L /usr/X11R6/lib -lX11 -lm */ #include<X11/Xlib.h> #include<stdio.h> #include<stdlib.h> // prevents error for exit on line 18 when compiling with gcc int main() { Display *d; int s; Window w; XEvent e; /* open connection with the server */ d=XOpenDisplay(NULL); if(d==NULL) { printf("Cannot open display\n"); exit(1); } s=DefaultScreen(d); /* create window */ w=XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1, BlackPixel(d, s), WhitePixel(d, s)); // Prosses Window Close Event through event handler so XNextEvent does Not fail Atom delWindow = XInternAtom( d, "WM_DELETE_WINDOW", 0 ); XSetWMProtocols(d , w, &delWindow, 1); /* select kind of events we are interested in */ XSelectInput(d, w, ExposureMask | KeyPressMask); /* map (show) the window */ XMapWindow(d, w); /* event loop */ while(1) { XNextEvent(d, &e); /* draw or redraw the window */ if(e.type==Expose) { XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10); } /* exit on key press */ if(e.type==KeyPress) break; // Handle Windows Close Event if(e.type==ClientMessage) break; } /* destroy our window */ XDestroyWindow(d, w); /* close connection to server */ XCloseDisplay(d); return 0; } |
The first two of the following steps summarize the client-server connection between the X Client and the X Server, discussed in the previous sections and the last step in the process of the client-server connection is about the message passing at the X Protocol layer, which is discussed in the following sections.
The initial connection in the interprocess communication layer (between the client and server processes) starts with the first instruction at the source code example, which is a XOpenDisplay() call. As we see in section 1.2 XOpenDisplay() among other things makes the socket() call. This call as we see in section 1.4.1 creates the client's 'socket', the one end-point of a two-way communication link between two programs running on the network or on the same system. The socket connects then to the other end-point, the X Server's socket with a connect() call.
Recall from section 1.6, the following figure, that shows the strace output (the system calls) in the first moments of our sample X Client program:
At this figure we see the socket() and the connect() calls issued from the client program and also the setsockopt(), which sets some socket options.
After the X Client gets connected to the X Server, with the socket() and connect() calls it uses the writev() and read() calls to send and receive messages. The first messages exchanged perform the initial X client-server handshake, discussed in sections 1.5, 1.6 and 1.7. Notice that at this stage we are still in XOpenDisplay() of our sample program and that the client-server handshake, as explained in section 1.5 takes place in routines called by XOpenDisplay(), for instance _X11TransConnectDisplay() and _XSendClientPrefix().
Next the X Protocol message exchange begin. As we see from the sample source code the X Client uses a number of X Library calls that are sent to the X Server as a X Protocol requests. For instance for XCreateSimpleWindow() struct xCreateWindowReq is created. As we read in section 1.3 the request structs are grouped in the memory, to be send when a XFlush() is called from the client. This reduces the overhead in the network traffic. As we previously saw in section 1.3 XNextEvent() called in the 'while' loop of the sample client program actually uses XFlush().
From the Xlib Programming Manual we read:
"The XFlush() function flushes the output buffer. Most client applications need not use this function because the output buffer is automatically flushed as needed by calls to XPending(), XNextEvent(), and XWindowEvent()."
The next image from section 1.3 illustrates the packing of some request struct until they are finally sent to the X Server:
Notice that as we see in section 2.3 the messages of this figure are flushed in two groups.
The subsections of section 2, that come up next, describe the X Protocol messages in detail.