Learning to Use X11

 in
A tutorial discussing how to use X11 fully and effectively.

When I started programming many years ago, on a system very, very different from what we use now, producing graphical output from programs was easy; all the necessary commands were usually built right into the language. Later, when I moved to C and UNIX, things were no longer simple. Not only does C not include any graphics manipulation functions, per se, but all graphical output in UNIX has to go through the standard UNIX windowing system: the X Window System, release 11, version 6.6 (its current incarnation), or X11 for short.

Unfortunately, X11 is rather hard to approach. First of all, it is huge (the O'Reilly series of printed manuals and references includes six volumes with close to 6,000 pages among them, not counting the additional four volumes and 2,000 pages when we include Motif--I know of hardly any other language, library, framework or application that big). However, the fact that it is based on concepts quite different from the ones currently in use makes it difficult to understand. To top it all off, the X11 documentation makes use of a specialized and not-so-obvious terminology. Therefore, we need to establish a minimal glossary.

Glossary

The X Window System was specifically designed to allow the graphical output of a program running on one machine to appear on a different machine, possibly one that is physically remote and/or a different make and architecture. In other words, X11 was designed to be a platform-independent, networked graphics framework.

In X11 parlance, the "display" denotes the box on which the graphical output will appear. Interestingly, an individual display is defined by the X11 documentation as having exactly one keyboard and one pointer (i.e., mouse), but potentially multiple CPUs, monitors, etc.

The "screen" corresponds to the actual physical display device; in most cases this will be a monitor. X11 allows for an arbitrary number of screens to be connected to each display. Think of a workstation with two monitors or a departmental server, connected to a larger number of (relatively dumb) X terminals.

Finally, a "window" is a rectangular area of the screen that can be used for input and output. If the rectangular area is not directly associated with a screen, but instead resides in memory, it is referred to as a "pixmap". Pixmaps and windows share the property of being "drawable" and can be used interchangeably in some function calls. It is important to remember that to X11 a window is merely a rectangular area on the screen. As such, it does not include things like titlebars, scrollbars and other GUI elements that we have come to associate with the word window. If these elements are present, they are controlled by a different program called a window manager.

Every GUI-oriented computer ships with a mouse or equivalent. When X11 came about, the development of graphical input devices was still in its infancy. Consequently the X11 documentation always speaks (somewhat bashfully) of a "pointer" (a generic term for mice), trackballs, digitizing tablets or other yet-to-be-invented graphical input devices. A final cause of confusion is the specific usage of the words client and server in X11: a "client" is any application that creates data for graphical output. The "server" is the program that manages the shared resource accessed by all clients, namely the (finite) amount of screen real estate. The unfortunate consequence of this naming convention is that the (X11) client typically executes on the server (machine), while the (X11) server runs on the client (computer).

The Program, Part 1: Preparation Stage

We are now ready to write a simple example program that demonstrates the most important concepts and functions for programming with X11. The program will pop up a window on the screen, draw an X in it and disappear after a mouse-click into the window area. The following is a line-by-line explanation of the program given in Listing 1.

Listing 1. Example Program for Concepts and Functions in X11

Line 1: Xlib.h is the most important header file for X11 programming. It defines several structs and macros used throughout an X11 program and provides function prototypes for all the basic functions in the library. Other headers are part of X11 as well. If those are needed, Xlib.h usually has to be included before any of the other headers because they depend on it. Strangely, the dependent headers do not themselves include Xlib.h.

Lines 5 and 6: Display is a struct defined in Xlib.h that represents the display, i.e., the box on which the graphical output is meant to appear. The library function XOpenDisplay attempts to establish a connection to the X11 server on this machine. As argument, it takes a zero-terminated string with the display_name, in the following format: hostname:servernumber.screennumber. If the argument is NULL, the display_name defaults to the value of the environment variable DISPLAY. If no connection can be established, XOpenDisplay will return NULL.

Line 9: we obtain an identifier to be used for the screen. DefaultScreen is not a function; it is a macro defined in Xlib.h. X11 provides macros like this as accessors for the elements of the Display struct that are accessible to the programmer. Members of this and other library structs should never be accessed directly, only through the provided macros. Variables for which no macros are provided should be considered "private".

Lines 10 and 11: colors in X11 are identified by integer numbers. Since X11 is meant to be platform independent, it does not make any assumptions about the capabilities of any device (i.e., the screen not the display) to render colors. Only two colors are guaranteed to be available, black and white. Note that the actual appearance of these values does not have to correspond to black and white pixels; think of those old monitors with green (or amber) letters on a black background.

Line 14: finally, we are ready to create a window. The data type Window is not a struct as one might assume. Rather it is typedefed to some integer data type and merely provides an identifier for a window.

Line 15: each window is the child of some other window and is geometrically contained by it. Here we set the root window (the entire screen) of the default screen as the parent window.

Line 16: the coordinates of the upper-left-hand corner of the new window with respect to the parent window, designated in pixels. X11 uses graphical coordinates with the origin in the upper left and with the positive X-axis running to the right and the positive Y-axis running down. However, since the placement of new windows is under control of the window manager, the new window can pop up pretty much anywhere on the screen, regardless of the values of these two arguments--expect surprises.

Line 17: the width and height (in that order) of the new window, in pixels.

Line 18: the width and color of the border of the window. This is not the border that may be added by the window manager.

Line 19: the color of the background of the window.

Line 21: so far we have created a data structure for the window, but only in memory. In X11 a window is not automatically displayed when it is created. Making the window visible is a separate process, called mapping. The function XMapWindow consequentially maps the window on the specified display. Note that it is not necessary to specify the screen again; when the window was created, it was explicitly created as child of a parent window, which itself is associated with a specific screen.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

how to run the program

szs's picture

HERE IS THE SOLUTION
-open terminal and type 'apt-get install libx11-dev'.this should download and install the x11 library.
-open the program and include the library 'X11/Xlib.h'.
-compile the program by typing 'g++ -o output x1.cc -lX11'
-run the program by typing ./output.

hope this helps....XD

Draw a bare window (without Close, Minimize, Maximize buttons)

Anonymous's picture

how to create a window described in the subject? I cannot find out the solution.
thanks and regards

woapxp

x11 man

renu's picture

i m new to x11. i m not getting the point how to set the path be4 running x11 prog. and i m not getting the manual pages after writing the man command on the shell.can anybody help me??

how to link xlib

Anonymous's picture

how to link xlib

A Simple OpenGL Program Using GLUT and C

mattv's picture

Running FreeBSD 6.1, I find that example programs shown in "OpenGL Programming Guide, Fifth Edition" (Red Book), can be compiled as follows:

gcc -I /usr/X11R6/include -L /usr/X11R6/lib -o your_program your_program.c -lX11 -lGL -lglut

Red Book examples always use GLUT.

So, just to let you know...

Matt

Re: Learning to Use X11

Anonymous's picture

Hi!

On the web there are some Xlib tutorials like this. They create one or two windows, draw few lines or arcs (some even in color) and some show the typical XLib program main loop like the following:

   Display* xDisplay;

   XEvent xEvent;

   ...

   xDisplay = XOpenDisplay(NULL);

   while(!done) {

      XNextEvent(xDisplay, &xEvent);

      ... // process the event

   }

   CloseDisplay(xDisplay);

Unfortunately it's the point where the tutorials finish. I hope there will be some continuing of this tutorial.

For example I'm unable to find how to handle linux signals in the main loop. XNextEvent() doesn't return EINTR like libc blocking functions.

Imagine you would like to write trivial clock program for X and you need catch some SIGALRM or other signal every second to refresh the clock as well as catch X events.

How to handle such task without busy waiting?

Thanks

Mity

<mity@srnet.cz>

Re: Learning to Use X11

Anonymous's picture

I just made binary coded decimal clock program as my first xlib program to use events, but I didn't use events to tell the time. I just made a for(;;){ loop with sleep(1); as the first statement (this function is defined in unistd.h for some reason, and the parameter 1 means 1 second). This statement keeps the program from being active all the time. After that I just used the functions in time.h to find the time. I am not sure what other non-xlib events you might want to intercept, but you might be able to do something like this.

Unfortunate Title

dlc's picture

What I expected from this article was how to use X, not code an X client. Change the title and you'll have an excellent resource (as how the article employs resources, not how an X user employs resources).

Re: Learning to Use X11

Anonymous's picture

The author must be using Debian because he said the latest version of XFree86 is 4.1.0 not 4.2.0.

Re: Learning to Use X11

masinick's picture

Stuff gets dated rather quickly. You're right, XFree86 does, indeed have 4.2.0 released, (and for all I know, they might even be past that now)! But 4.2.0 is new enough that only the latest distros are actually using it. For many vendors, their NEXT release will likely have 4.2.0 code, but 4.1.0 or even some 3.3.6 stuff is STILL pretty common, and not JUST for Debian-based systems, either.

XFreeGC

Anonymous's picture

"We therefore explicitly free the allocated resources"

To be fussy, I guess we should call XFreeGC then also.

Looking forward for the next episode

servers and clients ... sure they are software

Anonymous's picture

Well, clients and servers are still software-only ...

the problem is that some twisted host and server - doh!

And don't think i'm one of those grey-bearded veterans.

The first thing our information science teacher said about servers:

"Servers are software, not hardware" (He said that in german, but most of you prefare a sort of english i guess *g*)

So: no problem reading the x11-manual - at least not by twisting server and client, the rest ... *caught*

Spank me if i'm wrong!

Dear oh dear... "Server" and "Client" were *never* twisted!

Anonymous's picture

If you think of the meaning of the words "server" and "client" it is difficult to get them confused, even when thinking in terms of X, instead of in terms of (say) a file server.

A "server" is something that provides a service. In the case of a file server, it is something that provides access to files over a network. In the case of X, the service provided is that of the drawing to the screen.

A "client" is something that requests the server to perform a task. In the case of the file server, it is requesting that a certain file be sent to it. In the case of X, it is asking the server to draw something to the screen.

Easy!

Re: Learning to Use X11

Anonymous's picture

or a departmental server, connected to a larger number of (relatively dumb) X terminals.

Nope, that's wrong. Each X terminal would be a separate display (actually, separate host:display usually), not multiple screens. The dual- (or more) head example is a valid multi-screen example.

By the way, on Linux boxes at least, you can have multiple X displays running simultaneously (virtualized) by starting X from different virtual consoles (ie using ctrl-alt-F2 to log in, etc), by adding the display number (eg "startx -- :1"), the catch is that GNOME and KDE can't handle multiple instances of themselves on the same computer (you can run GNOME on one display and KDE on the other). Switch displays using ctrl-alt-F7, ctrl-alt-F8, etc.

Re: Learning to Use X11

Anonymous's picture

Multiple instances for one user of the WindowMaker window manager are also not supported.

Re: Learning to Use X11

Anonymous's picture

found the source, but you must do a

#include

rather than

#include

and you must use the following

g++ -I /usr/X11/include/X11 -L /usr/X11/lib -o x1 x1.cc -lX11

to compile on suse linux.

Re: Learning to Use X11

Anonymous's picture

i make a program with C, and then compile it like this :

cc -g -o myprog myprog.c -lX11

but it is error in X11...!!

can anyone help me...? please..!
did i must configure somethink...to make it clear...?

i use suse 8.2, and i just install xdevel-xxx.rpm

Re: Learning to Use X11

Anonymous's picture

it should read #include

Re: Learning to Use X11

Anonymous's picture

Where is the difference between

#include and #include?

Magical whitespace?

Re: Learning to Use X11

Anonymous's picture

I think the HTML of the original poster's comment got "filtered" by PHP nuke.

Re: Learning to Use X11

Anonymous's picture

Yes, sure, but what is the file to #include between the

/ /

then? 8-)

#include or #include

Anonymous's picture

#include <Xlib.h>
or
#include <X11/Xlib.h>

Re: Learning to Use X11

Anonymous's picture

god I think my brain has frozen on monday morning, I found th e source, compiled it and it work!!!!!

doh!!

Re: Learning to Use X11

Anonymous's picture

I'd like to give this a go? but where's the source luke?

Link

Anonymous's picture

The paragraph titles are links, Jar-Jar. Click them with your favourite pointing device.

Me sah

jar Jar's picture

Me sah no sah point divvy-sicer onna dee clikkers link.

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState