/*
  xroot.c
  A clickable swatch of root window for rootless X servers.
  Greg Parker     gparker-web@sealiesoftware.com     January 9, 2003
  
  This code is in the public domain and may be copied or modified without
  permission.

  To compile:
     c++ xroot.c -Wall -L/usr/X11R6/lib -I/usr/X11R6/include -lX11 -o xroot

  To run:
     ./xroot  -display :0  -geometry 100x100+0-0  -color blue
     (100x100 in lower-left corner, colored blue)
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h> // XWMGeometry

void draw(Display *dpy, Window w, GC gc)
{
    XFillRectangle(dpy, w, gc, 0, 0, 20000, 20000);
}

int main(int argc, char **argv)
{
    char *display = NULL;
    char *geometry = NULL;
    char *color = NULL;
    
    // read command-line arguments
    for (int arg = 0; arg < argc; arg++) {
        if (0 == strcmp(argv[arg], "-d")  ||  
            0 == strcmp(argv[arg], "-display")) {
            if (arg+1 < argc) display = argv[arg+1];
        }
        if (0 == strcmp(argv[arg], "-geometry")) {
            if (arg+1 < argc) geometry = argv[arg+1];
        }
        if (0 == strcmp(argv[arg], "-color")) {
            if (arg+1 < argc) color = argv[arg+1];
        }
        if (0 == strcmp(argv[arg], "-help")  ||
            0 == strcmp(argv[arg], "-h")) {
            fprintf(stderr, "usage:  %s [-display displayname] [-geometry geom] [-color colorname]\n", argv[0]);
            return 0;
        }
    }
    
    // environment variables
    if (!display) display = getenv("DISPLAY");

    // open display
    Display *dpy = XOpenDisplay(display);
    if (!dpy) {
        fprintf(stderr, "%s: couldn't open display '%s'\n", 
                argv[0], display ? display : "");
        return 1;
    }
    
    // grab some colors
    int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
    int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));

    // parse geometry
    int x, y, w, h, g;
    XSizeHints hints = {0};
    XWMGeometry(dpy, DefaultScreen(dpy), geometry, "100x100+0+0", 0, &hints, 
                &x, &y, &w, &h, &g);

    // create window
    Window win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), x, y, 
                                     w, h, 0, blackColor, whiteColor);
    XSelectInput(dpy, win, StructureNotifyMask);
    
    // We want all input events to propagate to the root window
    // We want override-redirect set so the window manager doesn't trap events
    //   (a window manager's container window would almost certainly have 
    //   do_not_propagate set)
    XSetWindowAttributes attr;
    attr.do_not_propagate_mask = NoEventMask;
    attr.override_redirect = True;
    XChangeWindowAttributes(dpy, win, CWOverrideRedirect | CWDontPropagate, &attr);
    
    XMapWindow(dpy, win);

    // create gc using specified color
    GC gc = XCreateGC(dpy, win, 0, NULL);
    XSetForeground(dpy, gc, whiteColor); // default white
    if (color) {
        XColor screenColor, exactColor;
        if (XAllocNamedColor(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), 
                             color, &screenColor, &exactColor)) 
        {
            XSetForeground(dpy, gc, screenColor.pixel);
        }
    }

    // run until killed
    while (1) {
        XEvent e;
        XNextEvent(dpy, &e);
        switch (e.type) {
        case MapNotify: 
        case Expose:
        case ConfigureNotify:
            draw(dpy, win, gc);
            break;
        }
    }
}
