From 3913d1778318cd0c6bfb871148d38abb33ec7fd3 Mon Sep 17 00:00:00 2001 From: nasr Date: Wed, 28 Jan 2026 13:13:40 +0100 Subject: checkpoint --- xlib-tutorial/2nd-program-anatomy.html | 282 +++++++++++++++++++++++++++++++++ xlib-tutorial/Xlib.pdf | Bin 0 -> 357941 bytes xlib-tutorial/index.html | 116 ++++++++++++++ xlib-tutorial/prog-1.cc | 29 ++++ xlib-tutorial/prog-2.cc | 74 +++++++++ xlib-tutorial/server.html | 89 +++++++++++ 6 files changed, 590 insertions(+) create mode 100644 xlib-tutorial/2nd-program-anatomy.html create mode 100644 xlib-tutorial/Xlib.pdf create mode 100644 xlib-tutorial/index.html create mode 100644 xlib-tutorial/prog-1.cc create mode 100644 xlib-tutorial/prog-2.cc create mode 100644 xlib-tutorial/server.html (limited to 'xlib-tutorial') diff --git a/xlib-tutorial/2nd-program-anatomy.html b/xlib-tutorial/2nd-program-anatomy.html new file mode 100644 index 0000000..d156f7a --- /dev/null +++ b/xlib-tutorial/2nd-program-anatomy.html @@ -0,0 +1,282 @@ + + +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
+ + diff --git a/xlib-tutorial/Xlib.pdf b/xlib-tutorial/Xlib.pdf new file mode 100644 index 0000000..cef1647 Binary files /dev/null and b/xlib-tutorial/Xlib.pdf differ diff --git a/xlib-tutorial/index.html b/xlib-tutorial/index.html new file mode 100644 index 0000000..5e57eaf --- /dev/null +++ b/xlib-tutorial/index.html @@ -0,0 +1,116 @@ + + +Xlib programming: a short tutorial + + + + +

Xlib programming: a short tutorial

+ +I haven't found anything very satisfying on the Web as an Xlib +tutorial. Many of them are too much Motif-oriented for my +taste. Furthermore, I answer questions about X programming almost +daily, so I've started to put together some small coursewares. + +

Important note:

the example programs are written in C++, but +this is mainly for the ability to declare variables anywhere. + +
+ +Let's begin with a short story: the eternal story of the newbie at +Xlib writing his/her first program. + +

+ + +"Ok, I've to open a connection to the X server (whatever this means), +with XOpenDisplay, then create a window with XCreateWindow, then draw +a line with XDrawLine. Then, the program sleeps for ten seconds so I +can see the result. Sounds easy." + + +

+ +The poor newbie writes the program. And nothing happens. He then +calls his wizard friend. + +

+ + +-"Did you perform an XFlush after you've done everything ?
+- No, why ?
+- The requests stay in the client,"
wizard doubletalk, thinks the +poor newbie, " if you +don't." + + +

+ +The poor newbie changes the program. And nothing happens. He then +calls his wizard friend. + +

+ + +-"Did you map your window ?
+- Did I do what ???
+- Creating a window doesn't make it appear on the screen. You've to + map it with XMapWindow first. +
+ +

+ +The poor newbie changes the program. The window appears with nothing +in it (like this). The poor newbie then calls +his wizard friend. + +

+ + +-"Did you wait for a MapNotify before drawing your line ?" (more wizard doubletalk)
+- "No, why ?
+- X has a stateless drawing model, the content of the window may be lost + when the window isn't on the screen."
(overflow, why can't these + wizard guys speak just like you and me ?) "You've to wait for a MapNotify + before drawing." + + +

+ +The poor newbie changes the program. Things are getting more and more +complex. Not as easy as it first seemed. A loop gets the events until a +MapNotify. The window appears with nothing +in it. The poor newbie then calls his wizard friend. + +

+ + +-"I got it, did you select the StructureNotifyMask on your window ?
+- ???
+- Just do it, and everything'll be fine. +
+ +

+ +The poor newbie fixes the program. And the miracle happens ! A line in the +window. Until now, the program looks like this +(it is actually slighty more complex than the dialog may let you think). + +

+ +Now you've learned at least 2 things: + +

+ +Now, if you want to learn more and get a deeper understanding of the +program, go to next lesson. + +

More about X.

+ + +
Christophe Tronche, ch.tronche@computer.org
+ + diff --git a/xlib-tutorial/prog-1.cc b/xlib-tutorial/prog-1.cc new file mode 100644 index 0000000..3ba596b --- /dev/null +++ b/xlib-tutorial/prog-1.cc @@ -0,0 +1,29 @@ +// Written by Ch. Tronche (http://tronche.lri.fr:8000/) +// Copyright by the author. This is unmaintained, no-warranty free software. +// Please use freely. It is appreciated (but by no means mandatory) to +// acknowledge the author's contribution. Thank you. +// Started on Thu Jun 26 23:29:03 1997 + +// +// Xlib tutorial: 1st program +// Make a window appear on the screen. +// + +#include // Every Xlib program must include this +#include // I include this to test return values the lazy way +#include // So we got the profile for 10 seconds + +#define NIL (0) // A name for the void pointer + +main() +{ + Display *dpy = XOpenDisplay(NIL); + assert(dpy); + Window w = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, + 200, 100, 0, + CopyFromParent, CopyFromParent, CopyFromParent, + NIL, 0); + XMapWindow(dpy, w); + XFlush(dpy); + sleep(10); +} diff --git a/xlib-tutorial/prog-2.cc b/xlib-tutorial/prog-2.cc new file mode 100644 index 0000000..51ea0e9 --- /dev/null +++ b/xlib-tutorial/prog-2.cc @@ -0,0 +1,74 @@ +// Written by Ch. Tronche (http://tronche.lri.fr:8000/) +// Copyright by the author. This is unmaintained, no-warranty free software. +// Please use freely. It is appreciated (but by no means mandatory) to +// acknowledge the author's contribution. Thank you. +// Started on Thu Jun 26 23:29:03 1997 + +// +// Xlib tutorial: 2nd program +// Make a window appear on the screen and draw a line inside. +// If you don't understand this program, go to +// http://tronche.lri.fr:8000/gui/x/xlib-tutorial/2nd-program-anatomy.html +// + +#include // Every Xlib program must include this +#include // I include this to test return values the lazy way +#include // So we got the profile for 10 seconds + +#define NIL (0) // A name for the void pointer + +main() +{ + // Open the display + + Display *dpy = XOpenDisplay(NIL); + assert(dpy); + + // Get some colors + + int blackColor = BlackPixel(dpy, DefaultScreen(dpy)); + int whiteColor = WhitePixel(dpy, DefaultScreen(dpy)); + + // Create the window + + Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, + 200, 100, 0, blackColor, blackColor); + + // We want to get MapNotify events + + XSelectInput(dpy, w, StructureNotifyMask); + + // "Map" the window (that is, make it appear on the screen) + + XMapWindow(dpy, w); + + // Create a "Graphics Context" + + GC gc = XCreateGC(dpy, w, 0, NIL); + + // Tell the GC we draw using the white color + + XSetForeground(dpy, gc, whiteColor); + + // Wait for the MapNotify event + + for(;;) { + XEvent e; + XNextEvent(dpy, &e); + if (e.type == MapNotify) + break; + } + + // Draw the line + + XDrawLine(dpy, w, gc, 10, 60, 180, 20); + + // Send the "DrawLine" request to the server + + XFlush(dpy); + + // Wait for 10 seconds + + sleep(10); +} + diff --git a/xlib-tutorial/server.html b/xlib-tutorial/server.html new file mode 100644 index 0000000..a408834 --- /dev/null +++ b/xlib-tutorial/server.html @@ -0,0 +1,89 @@ + + +Xlib programming tutorial: What is all this "client-server" stuff ? + + + +

What does all this stuff about "client-server" mean ?

+ +Everybody says that X has a "client-server" architecture. So this must +be true, but what does it mean ? + +

+ +Well, basically a client-server architecture is conceptually a simple +thing, but the consequences may be a bit subtle, especially the way it +is implemented in the Xlib. + +

What is a client-server architecture ?

+ +A client-server architecture is a general mechanism for handling a +shared resource that several programs may want to access +simultaneously. In the case of X, the shared resources are the drawing +area and the input channel. If every process was allowed to write on +it at its will, several processes may want to draw at the same place, +resulting in an unpredictable chaos. Thus, only one process is allowed +to get access to the drawing area: the X server. The processes wanting +to draw stuff or get inputs send requests to the X servers (they are +"clients"). They do this over a communication channel. The X server +performs the requests for its clients, and sends them back replies. It +may also send messages without explicit client's requests to keep them +informed of what is going on. These messages sent by the server on its +own behalf are called "events". + +

Advantages of the client-server architecture

+ +The client-server architecture has several advantages, many of them +resulting from the ability to run the server and the clients on +separate machines. Here are some advantages: + +
    + +
  • A client-server architectured system can be very robust: since + the server runs in its own address space, it can protect itself + against poorly written clients. Thus, if a client has a bug, it + will crash alone, the server and the other clients still running + as if nothing has happened. + +
  • The client and the server don't have to run on the same machine, + so we have some communication mechanism here. + +
  • The client and the server may run on separate machines, resulting + in a better load distribution (possibly). + +
  • The client and the server don't have to run on the same hardware, + operating system, etc., giving a better interoperability. + +
+ +

Structure of the X client-server architecture

+ +As we already mentioned, the server and a client communicates over a +communication channel. This channel is composed of two layers: the +low-level one, which is responsible for carrying bytes in a reliable +way (that is with no loss nor duplication). This link may be among +others a named pipe in the Unix environment, a DECNet link and of +course a TCP/IP connection. + +

+ +The upper layer use the byte-transport channel to implement a +higher-level protocol: the X protocol. This protocol says how to tell +the server to request window creation, graphics drawing, and so on, +and how the server answers and sends events. The protocol itself is +separated into different parts: + +

    + +
  • How to connect and how to break a connection, +
  • how to represent the different data types, +
  • what are the requests and what they mean and +
  • what are the replies and what they mean. + +
+ +[to be continued]. + +
Christophe Tronche, ch.tronche@computer.org
+ + -- cgit v1.3