#include #include #include #include #include #include #include #include #include "config.h" static Display *dpy; static Visual *visual; static Window root; static Colormap colormap; static int depth; static int screen; static Window create_win(int x, int y, int w, int h) { XSetWindowAttributes swa; Window win; swa.background_pixel = WhitePixel(dpy, screen); swa.override_redirect = 1; swa.event_mask = ExposureMask; win = XCreateWindow(dpy, root, x, y, w, h, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel | CWOverrideRedirect | CWEventMask, &swa); return win; } static void init_atoms(Window win) { /* set up atoms in the worst possibly way */ Atom dock = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", 0); Atom win_type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", 0); XChangeProperty(dpy, win, win_type, XA_ATOM, 32, PropModeReplace, (unsigned char *)&dock, 1); Atom win_state = XInternAtom(dpy, "_NET_WM_STATE", 0); Atom sticky = XInternAtom(dpy, "_NET_WM_STATE_STICKY", 0); XChangeProperty(dpy, win, win_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&sticky, 1); Atom above = XInternAtom(dpy, "_NET_WM_STATE_ABOVE", 0); XChangeProperty(dpy, win, win_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&above, 1); Atom wm_name = XInternAtom(dpy, "_NET_WM_NAME", 0); Atom utf8string = XInternAtom(dpy, "UTF8_STRING", 0); char *name = "icybar"; XChangeProperty(dpy, win, wm_name, utf8string, 8, PropModeReplace, (unsigned char *)name, strlen(name)); unsigned long prop = 0xFFFFFFFF; Atom desktop = XInternAtom(dpy, "_NET_WM_DESKTOP", 0); XChangeProperty(dpy, win, desktop, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&prop, 1); } static Pixmap create_pixmap(GC gc, int w, int h) { Pixmap pix; pix = XCreatePixmap(dpy, root, w, h, depth); XSetForeground(dpy, gc, WhitePixel(dpy, screen)); XFillRectangle(dpy, pix, gc, 0, 0, w, h); XSetForeground(dpy, gc, BlackPixel(dpy, screen)); return pix; } /* allocate color for Xft */ static void xft_alloc_color(const char *colorname, XftColor *color) { if (!XftColorAllocName(dpy, visual, colormap, colorname, color)) errx(1, "could not allocate color"); } /* draw text on pixmap */ static void draw(Drawable pix, XftFont *font, XftColor *color, const char *text) { XGlyphInfo ext; XftDraw *draw; int x, y; size_t len; draw = XftDrawCreate(dpy, pix, visual, colormap); len = strlen(text); /* get text extents */ XftTextExtentsUtf8(dpy, font, text, len, &ext); x = (WIDTH - ext.width) / 2; y = (HEIGHT + ext.height) / 2; /* draw text */ XftDrawStringUtf8(draw, color, font, x, y, text, len); XftDrawDestroy(draw); } /* enter the event loop */ static void run(GC gc, Pixmap pix) { XEvent ev; while (XNextEvent(dpy, &ev) == 0) { switch (ev.type) { case Expose: XCopyArea(dpy, pix, ev.xexpose.window, gc, ev.xexpose.x, ev.xexpose.y, ev.xexpose.width, ev.xexpose.height, ev.xexpose.x, ev.xexpose.y); break; } } } int main(int argc, char *argv[]) { XftColor color; XftFont *font; Pixmap pix; Window win; GC gc; if (argc != 2) { fprintf(stderr, "usage: %s STRING\n", argv[0]); return 1; } if ((dpy = XOpenDisplay(NULL)) == NULL) errx(1, "could not open display"); screen = DefaultScreen(dpy); colormap = DefaultColormap(dpy, screen); visual = DefaultVisual(dpy, screen); depth = DefaultDepth(dpy, screen); root = RootWindow(dpy, screen); win = create_win(0, 0, WIDTH, HEIGHT); gc = XCreateGC(dpy, root, 0, NULL); pix = create_pixmap(gc, WIDTH, HEIGHT); font = XftFontOpenName(dpy, screen, fontname); xft_alloc_color(colorname, &color); init_atoms(win); draw(pix, font, &color, argv[1]); XMapWindow(dpy, win); run(gc, pix); /* housekeeping */ XUnmapWindow(dpy, win); XDestroyWindow(dpy, win); XFreePixmap(dpy, pix); XFreeGC(dpy, gc); XftColorFree(dpy, visual, colormap, &color); XftFontClose(dpy, font); XCloseDisplay(dpy); return 0; }