2020-10-15

dwm

I've been interested on-and-off in learning more about low-level / systems programming. While I could do this by jumping straight into making something myself in C, I feel like I don't currently have a good idea of what is possible within this new medium.

With that in mind, I took a look at the source code for dwm, a minimalist window manager that runs in the X window system. dwm is developed by the suckless.org community, which focuses on writing very simple and frugal software. Minimalist software is especially interesting to read because you can sit down with it for a few hours and come away with an understanding of what is necessary to create a certain kind of program. dwm consists of about 3,000 lines of C but it will probably not be necessary to read it all.

The main source file dwm.c suggests that the reader start at the main function, so we will start there. Firstly, a number of preliminary steps are taken to check that the program can be run:

I'm going to stop it here for tonight - I have work tomorrow. Nothing that we have seen so far is specific to window managers, it is just generic boilerplate that could in theory be found at the start of any X application.

xlib in nixos

In the process of looking at dwm, I tried building some code using Xlib for myself. I'm running NixOS which is a somewhat strange Linux distribution that allows you to describe your system's configuration in a declarative fashion. A consequence of this is that you can use the same language to describe your system configuration as you do to describe the environments that particular projects and applications run in.

To configure NixOS at the project level, you can create a shell.nix file. If you then navigate to the folder containing this file and run nix-shell then a new shell will be created with the selected packages installed. Here's a shell.nix file that will enable you to build applications using Xlib and gcc:

with import <nixpkgs> {};

stdenv.mkDerivation {
  buildInputs = [gcc xlibs.libX11];
}

To check that this works, I wrote a little test program as follows in main.c:

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

int main(int argc, char *argv[]) {
  Display *dpy = XOpenDisplay(NULL);
  int width = XDisplayWidth(dpy, 0);
  int height = XDisplayHeight(dpy, 0);
  printf("%d x %d", width, height);
}

The above code can now be built and run with:

gcc main.c -o main -lX11
./main

[back]