Have you ever wondered how a window system actually works ? I have. When I was preparing my Widgets In-Depth talk for Qt Developer Days last year, I decided I should implement a simple little window system as bonus material.
This blog post will be a rough description of the window system I built using Qt, and a port of Qt to the new system.
Windows And Systems
As you probably know, the window system is the process that manages the windows on your screen.
A window, also known as a window surface, can be described as an area of memory that will be drawn to the screen. Window surfaces are typically arranged in a scene-graph to keep track of them. Finally, window systems typically run as a server process. When other processes that want to show something on screen, they have to talk to it through some form of inter-process communication.
The toy window system up and running.
We need something that represents the memory area used to paint the window contents. In theory, this can be just any class representing a piece of memory, like QByteArray, and paint into it. But I’m lazy. To keep our system simple, I share the window surface with the client and let the client paint directly into that memory. I do this by using QSharedMemory to represent the Window Surface.
I’m guessing you already figured this one out. QGraphicsScene does exactly what we want. It provides features that really come in handy when implementing a window system, like input handling and item caching. For more fancy features, we even get item transparency, transformations and graphics effects.
I already mentioned that I’m using QSharedMemory for the window surfaces. But to handle things like user input and window updates we need to be able to pass messages between the client and the server. The protocol I’m using consists of three types of messages:
Requests are messages sent from the client to the server asking for something, for example a new window. A reply is sent from the server, informing of the result of the request. Request-response pairs are synchronous. However, in our system most requests will not have a corresponding response, in which case the request will be asynchronous.
Events are messages sent from the server, informing the client that something has happened. A typical event would be user input to a window. Since the server doesn’t expect any response from the client, events are always asynchronous.
Lighthouse by The Wandering Angel on flickr
Ports And Lighthouses
A window system is pretty boring if there is nothing running on it. Since I am not implementing a standard protocol, I also have to take care of the client side. Luckily there is the Lighthouse project. Lighthouse is a research project that aims to make it easier to port Qt to different graphics systems.
A port to a new window system takes the form of a plugin that implements a representation of a window surface for the client, and functionality for sending and receiving messages from the window system server.
It’s All Yours
I’ve avoided going into too much detail about the inner workings of the window system and the Qt port. The implementations are surprisingly small, so I recommend that you take a look at the code if you are interested.
The code for the window system is available here, and the code for the graphics plugin is available here (make sure you use the Lighthouse branch to build the plugin). Enjoy and happy hacking! 🙂