Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xrandr.h>
#include <stdbool.h>
#include <string.h>
int main(){
Display *dp = XOpenDisplay(NULL); // Connection to X Server
// This is needed for XCreateWindow
XVisualInfo vinfo;
XMatchVisualInfo(dp, DefaultScreen(dp), 32, TrueColor, &vinfo);
// Set WindowAttribute border_pixel and background_pixel to 0 for
XSetWindowAttributes attr;
attr.colormap = XCreateColormap(dp, DefaultRootWindow(dp), vinfo.visual,
attr.border_pixel = 0;
attr.background_pixel = 0;
// Spawn a New Window
Window win = XCreateWindow(dp, DefaultRootWindow(dp), 0, 0,
300, 200, 0, vinfo.depth, InputOutput, vinfo.visual, CWColormap |
CWBorderPixel | CWBackPixel, &attr);
// Set up Event Masks
XSelectInput(dp, win, ExposureMask|StructureNotifyMask);
// Atom to catch Window Closures
Atom wmDeleteMessage = XInternAtom(dp, "WM_DELETE_WINDOW", false);
// Color of String
GC white_gc;
XColor white_clr;
Colormap colormap;
char white[] = "#FFFFFF";
// These 3 lines do the following:
// 1. Generates an XAtom for setting _NET_WM_WINDOW_TYPE to
// 2. Generates an XAtom representation of _NET_WM_WINDOW_TYPE
// 3. Sets the property WM_TYPE of Window win to Atom XA.
Atom XA = XInternAtom(dp, "_NET_WM_WINDOW_TYPE_DOCK", true);
Atom WM_TYPE = XInternAtom(dp, "_NET_WM_WINDOW_TYPE", false);
XChangeProperty(dp, win, WM_TYPE, XA_ATOM, 32, PropModeReplace,
(unsigned char*) &XA, 1);
// Map the Window into the X Server and Flush any pending X Requests
XMapWindow(dp, win);
// Generate our GC. This will be used with XDrawString to set its color.
colormap = DefaultColormap(dp, 0);
white_gc = XCreateGC(dp, win, 0, 0);
XParseColor(dp, colormap, white, &white_clr);
XAllocColor(dp, colormap, &white_clr);
XSetForeground(dp, white_gc, white_clr.pixel);
Main Event loop. The lifetime of an X Window Application is inside this
event loop. How it works is, for all the time, we catch events that
were passed to the Window. Events that are catchable will be dictated
by the Masks we set in XSelectInput. If you are not catching a
particular event, check to make sure you arent missing a mask! These
masks should be listed in Xlib's documentation.
XEvent event;
bool running = true;
XNextEvent(dp, &event);
case Expose:
// From my understanding of Expose, this is an Event that is spawned
// when the Window needs to be redrawn. This is similar to an
// XDamage request, where the "damaged" part of the window is
// basically considered dirty and requires repainting. In the case
// of this program, we simply draw the string 'Beta Image" inside
// the window and then flush any pending requests.
XDrawString(dp, win ,white_gc, 50, 50, "Beta Image", strlen("Beta Image"));
case ClientMessage:
// We use this to terminate our event loop when we close the window.
running = ([0] == wmDeleteMessage ? false : true);
// Destroys window. I think we may need some XFrees for some of the stuff
// we generated? I am not sure, I would think this would be used for an
// 'XMalloc' call if there is such a thing.. a simple valgrind would tell
// us what we are not freeing and use XFree appropriately on those
// objects.
XDestroyWindow(dp, win);
return 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.