/* Build with:
   gcc -o cairoframe -g cairoframe.c $(pkg-config --libs --cflags cairo x11)
 */

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <cairo.h>
#include <cairo-xlib.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#define red    0.10
#define green  0.50
#define blue   1.00
#define alpha  0.02
#define linew  2
#define x      100
#define y      100

static void
repaint (cairo_surface_t *surface, cairo_t *cr, int width, int height)
{
    cairo_xlib_surface_set_size (surface, width, height);

    cairo_set_source_rgba (cr, red, green, blue, alpha);
    cairo_paint (cr);

    cairo_set_source_rgba (cr, red, green, blue, 0.1);
    cairo_rectangle (cr, linew / 2, linew / 2, width - linew, height - linew);
    cairo_stroke (cr);
}

int
main ()
{
    Display *xdpy;
    int scr;
    Window xwindow;
    Window xroot;
    XSetWindowAttributes attrs;
    XVisualInfo xvisual_info;
    cairo_surface_t *surface;
    Visual *xvisual;
    int depth;
    int width;
    int height;
    XEvent xevent;
    cairo_t *cr;

    xdpy = XOpenDisplay(NULL);
    if (!xdpy) {
        fprintf (stderr, "Cannot open display\n");
        return -1;
    }

    scr = DefaultScreen(xdpy);
    xroot = DefaultRootWindow(xdpy);

    if (!XMatchVisualInfo (xdpy, scr, 32, TrueColor, &xvisual_info)) {
        fprintf (stderr, "Cannot find matching visual\n");
        return -1;
    }

    xvisual = xvisual_info.visual;
    depth = xvisual_info.depth;

    attrs.override_redirect = False;
    attrs.colormap = XCreateColormap (xdpy, xroot, xvisual, AllocNone);
    attrs.background_pixel = BlackPixel (xdpy, scr);
    attrs.border_pixel = BlackPixel (xdpy, scr);

    width = WidthOfScreen (ScreenOfDisplay (xdpy, scr));
    height = HeightOfScreen (ScreenOfDisplay (xdpy, scr));

    xwindow = XCreateWindow (xdpy, xroot, x, y, width, height, 0, depth, InputOutput, xvisual,
                             CWColormap | CWBackPixel | CWBorderPixel, &attrs);
    XSelectInput(xdpy, xwindow, ExposureMask | StructureNotifyMask);
    XMapWindow (xdpy, xwindow);

    surface = cairo_xlib_surface_create (xdpy, xwindow, xvisual, width, height);
    cr = cairo_create (surface);
    cairo_set_line_width (cr, linew);
    cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);

    while (1) {
        XNextEvent (xdpy, &xevent);

        switch (xevent.type)
        {
          case Expose:
            XClearWindow (xdpy, xwindow);
            repaint (surface, cr, xevent.xexpose.width, xevent.xexpose.height);
            XFlush (xdpy);
            break;

          case ConfigureNotify:
            XClearWindow (xdpy, xwindow);
            repaint (surface, cr, xevent.xconfigure.width, xevent.xconfigure.height);
            XFlush (xdpy);
            break;

          default:
            break;
        }
    }

    XCloseDisplay (xdpy);

    return 0;
}
