From 444bfa2f41143aff7490e4fa21565947565b7d30 Mon Sep 17 00:00:00 2001 From: nasr Date: Fri, 13 Mar 2026 22:31:21 +0100 Subject: cleanup: generalisation --- xlib-tutorial/2nd-program-anatomy.html | 282 --------------------------------- 1 file changed, 282 deletions(-) delete mode 100644 xlib-tutorial/2nd-program-anatomy.html (limited to 'xlib-tutorial/2nd-program-anatomy.html') diff --git a/xlib-tutorial/2nd-program-anatomy.html b/xlib-tutorial/2nd-program-anatomy.html deleted file mode 100644 index d156f7a..0000000 --- a/xlib-tutorial/2nd-program-anatomy.html +++ /dev/null @@ -1,282 +0,0 @@ - - -Xlib programming tutorial: anatomy of the most basic Xlib program - - - -

Anatomy of the most basic Xlib program

- -The program starts with the legal stuff: - -

-#include <X11/Xlib.h> // Every Xlib program must include this
-#include <assert.h>   // I include this to test return values the lazy way
-#include <unistd.h>   // So we got the profile for 10 seconds
-
-#define NIL (0)       // A name for the void pointer
-
- -Then the serious thing. First we open a connection to the server. - -

-Display *dpy = XOpenDisplay(NIL);
-assert(dpy);
-
- -If it fails (and it may), XOpenDisplay() will return NIL. - -

- -We gonna create a window, but we need to get the window's background -color first. X uses a quite complex color model in order to accommodate -to every conceivable piece of hardware. Each color is encoded by an integer, -but the integer for a given color may change from a machine to another -one, and even on the same machine, from an execution of the program to -the next. The only "colors" that X guarantees to exist are black and -white. We can get them using the -BlackPixel() -and -WhitePixel() -macros. - -


-      int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
-      int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
-
- -As we yet can see, most of the Xlib calls take the "display" (the -value returned by -XOpenDisplay()) -as their first parameter. You want to know why ? - -

- -There is still someting magic, (the -DefaultScreen() -stuff), but we gonna keep it for a later -explanation. We now can -create our window: - -


-      // Create the window
-
-      Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 
-				     200, 100, 0, blackColor, blackColor);
-
- -Unlike what appears in the dialog, we use the -function -XCreateSimpleWindow() -instead of -XCreateWindow(). -XCreateSimpleWindow() -is not really simpler than -XCreateWindow() -(it takes only a few less parameters), but it uses less concepts, so -we gonna stick to it for now. There are still a bunch of parameters to -explain: - - - -

-      // We want to get MapNotify events
-
-      XSelectInput(dpy, w, StructureNotifyMask);
-
- -As we're starting to know, X is based upon a -client-server architecture. The X server -sends events to the client (the program we're writing), to keep it -informed of the modifications in the server. There are many of them -(each time a window is created, moved, masked, unmasked, and many -other things), so a client must tell the server the events it is -interested in. With this XSelectInput() stuff, we tell the -server we want to be informed of "structural" changes occuring on the -w window. Creation and mapping are such changes. There is no -way to be informed for example of only mapping modification, and not -creations, so we've to take everything. In this particular application -we're interesting in "mapping" events (grosso modo, the window -appears on the screen). - -

-      // "Map" the window (that is, make it appear on the screen)
-
-      XMapWindow(dpy, w);
-
- -And (once again) this is a client-server -system. The map request is asynchronous, meaning that the time this -instruction is executed doesn't tell us when the window is actually -mapped. To be sure, we've to wait for the server to send us a -MapNotify -event (this is why we want to be sensitive to such events). - -

-      // Create a "Graphics Context"
-
-      GC gc = XCreateGC(dpy, w, 0, NIL);
-
- -Yet another magic stuff. But mastering them is the reason of the -existence of this tutorial... - -

- -For several reasons, the graphical model of X is stateless, meaning -that the server doesn't remember (among other things) attributes such -as the drawing color, the thickness of the lines and so on. Thus, -we've to give all these parameters to the server on each -drawing request. To avoid passing two dozens of parameters, many of -them unchanged from one request to the next, X uses an object called -the Graphics Context, or GC for short. We store in the -graphics context all the needed parameters. Here, we want the color -used to draw lines, called the foregound color: - -


-      // Tell the GC we draw using the white color
-
-      XSetForeground(dpy, gc, whiteColor);
-
- -There are many other parameters used to draw a line, but all of them -have reasonable default values. - -

- -That's okay for now. Everything is set up, and we wait for the window -mapping. - -


-      // Wait for the MapNotify event
-
-      for(;;) {
-	    XEvent e;
-	    XNextEvent(dpy, &e);
-	    if (e.type == MapNotify)
-		  break;
-      }
-
- -We loop, taking events as they come and discarding them. When we get a -MapNotify, we exit the loop. We may get events other than -MapNotify for two reasons: - - - -The non-maskable events are sent only in response to some program -requests (such as copying an area), so they aren't likely to happen in -our context. - -

- -The -XNextEvent() -procedure is blocking, so if there are no event to read, the program -just wait inside the -XNextEvent(). - -

- -When we have exited the loop, we have good confidence that the window -appears on the screen. Actually, this may not be the case since, for -example, the user may have iconified it using the -window manager, but for now, we assume the window -actually appears. We can draw our line: - -


-      // Draw the line
-      
-      XDrawLine(dpy, w, gc, 10, 60, 180, 20);
-
- -The line is between points (10, 60) and (180, 20). The (0,0) is at the -upper left corner of the window, as usual. If the program just -sleeps here, nothing will happen, because, in case you don't -know, X has a client-server -architecture. Thus the request stays in the client, unless we tell it -to go to the server. This is done by XFlush(): - -

-      // Send the "DrawLine" request to the server
-
-      XFlush(dpy);
-
- -Clever readers may have noticed that we didn't use -XFlush() -before, and it didn't prevent all the requests such as -XMapWindow() -to be sent to the server. The answer is that -XNextEvent() -performs an implicit -XFlush() -before trying to read some events. We have our line now, we just wait -for 10 seconds, so we can make people see how beautiful is our work: - -

-      // Wait for 10 seconds
-
-      sleep(10);
-
- -That's all for now. In next -lesson, we will have a (very) little more interaction. [to be continued] - -
Christophe Tronche, ch.tronche@computer.org
- - -- cgit v1.3