/..

Developing on Xlib (for X11)

Warning

Everything here is still heavy work in progress, and probably useless, mistaken and incomplete.

I decided to develop a graphical user interface library on top of X11, in C. Something very lightweight and hopefully portable. (I could port the library to other backends later, like OpenGL.) I didn't find many write-ups on X on the internet (which might be partially Twitter's fault) and that encouraged me to describe what I learned in this tract. Partly to help those who come after me, and partly for future reference. Note: I am using the Xlib library, not XCB.

This is not a replacement for Xlib documentation, more of a supplement, kind of mapping out X11 and its' structure. So you know what to look for within documentation and the rough terminology.

Display server

X11 operates as a server with clients that can connect to it. In most cases clients are local (connecting from the same computer) but it's possible to connect to an X11 server from across the internet. There are 'resources' that can exist in X, which are something a client requests the server to allocate, and then receives a handle to it. Those can be, for example, fonts, windows, bitmaps.

So in typical usage, you establish a connection to X11 'display', request some resources, operate on them, and then terminate the connection. Drawing to a window is simply an operation on the window resource. And so is 'mapping' a window, which means putting the window on a 'screen' (there can be multiple 'screens' per 'display'). X can also send you events to notify you of various happenings, like your windows being successfully mapped or a keyboard key being pressed.

Pixel formats

X11 supports a variety of pixel formats, perhaps even going back to monochrome displays. So some things, like specifying pixel buffer format for an XImage, can get pretty verbose. This also propagates to drawables, like Windows or Pixmaps, where 'graphic contexts' (GCs) are created for drawing to them, which can only be reused for drawables created on the same root window and with the same (color) depth. There are convenience mechanisms for managing color palettes, for paletted output, like CGA.

I still have not figured out how to properly manage all of that, even if I just want to target 24 or 32 bit depth TrueColor output. Byte order (endianess) seems to play a role, in fact for creating an XImage you are required to not just specify the byte order, but also bit order. There does not seem to be an option for just using client's byte and bit orders. It seems I am responsible for querying those myself via other means and putting them in?

It would seem like X11 servers (or even specifically their 'displays') have a particular format they store framebuffers in, which you can query via functions like ImageByteOrder(). Then X11 and XLib built mechanisms to aid user programs in converting to that format, sometimes implicitly. But in certain cases -- notably when using MIT-SHM extension, which is used for sharing XImage memory across client and server, when they are both on the same computer -- you are forced to explicitly abide by the X11 server format. (Not sure if there are functions for copying regions between XImages of different formats, that would help.)

Keep in mind also, that base Xlib or X11 does not support 'color blending', meaning you cannot directly draw semi-transparent or anti-aliased things. Seek 'render' extension for such operations.

Fonts

X11 has a font format and Xlib has utilities for drawing text. However, I found the whole thing pretty clunky and not worth the effort to figure out, so I wrote my own font drawing using TrueType fonts (via the STB library) and bitmap masks.

Resources

TODO

Atoms

TODO

Events

TODO