all repos — barito @ 3bd7bd3ee6150bfbb7288b4969a85e3d5a7b022f

an x11 bar

barito.c (view raw)

  1#include <err.h>
  2#include <stdio.h>
  3#include <stdlib.h>
  4#include <string.h>
  5#include <X11/Xlib.h>
  6#include <X11/Xatom.h>
  7#include <X11/Xutil.h>
  8#include <X11/Xft/Xft.h>
  9#include "config.h"
 10
 11static Display *dpy;
 12static Visual *visual;
 13static Window root;
 14static Colormap colormap;
 15static int depth;
 16static int screen;
 17
 18static Window create_win(int x, int y, int w, int h)
 19{
 20	XSetWindowAttributes swa;
 21	Window win;
 22
 23	swa.background_pixel = WhitePixel(dpy, screen);
 24	swa.override_redirect = 1;
 25	swa.event_mask = ExposureMask;
 26	win = XCreateWindow(dpy, root, x, y, w, h, 0, CopyFromParent,
 27			    CopyFromParent, CopyFromParent,
 28			    CWBackPixel | CWOverrideRedirect | CWEventMask,
 29			    &swa);
 30
 31	return win;
 32}
 33
 34static void init_atoms(Window win)
 35{
 36	/* set up atoms in the worst possibly way */
 37	Atom dock = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", 0);
 38	Atom win_type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", 0);
 39	XChangeProperty(dpy, win, win_type, XA_ATOM, 32, PropModeReplace,
 40			(unsigned char *)&dock, 1);
 41
 42	Atom win_state = XInternAtom(dpy, "_NET_WM_STATE", 0);
 43	Atom sticky = XInternAtom(dpy, "_NET_WM_STATE_STICKY", 0);
 44	XChangeProperty(dpy, win, win_state, XA_ATOM, 32, PropModeReplace,
 45			(unsigned char *)&sticky, 1);
 46
 47	Atom above = XInternAtom(dpy, "_NET_WM_STATE_ABOVE", 0);
 48	XChangeProperty(dpy, win, win_state, XA_ATOM, 32, PropModeReplace,
 49			(unsigned char *)&above, 1);
 50
 51	Atom wm_name = XInternAtom(dpy, "_NET_WM_NAME", 0);
 52	Atom utf8string = XInternAtom(dpy, "UTF8_STRING", 0);
 53	char *name = "icybar";
 54	XChangeProperty(dpy, win, wm_name, utf8string, 8, PropModeReplace,
 55			(unsigned char *)name, strlen(name));
 56
 57	unsigned long prop = 0xFFFFFFFF;
 58	Atom desktop = XInternAtom(dpy, "_NET_WM_DESKTOP", 0);
 59	XChangeProperty(dpy, win, desktop, XA_CARDINAL, 32, PropModeReplace,
 60			(unsigned char *)&prop, 1);
 61}
 62
 63static Pixmap create_pixmap(GC gc, int w, int h)
 64{
 65	Pixmap pix;
 66
 67	pix = XCreatePixmap(dpy, root, w, h, depth);
 68
 69	XSetForeground(dpy, gc, WhitePixel(dpy, screen));
 70	XFillRectangle(dpy, pix, gc, 0, 0, w, h);
 71	XSetForeground(dpy, gc, BlackPixel(dpy, screen));
 72
 73	return pix;
 74}
 75
 76/* allocate color for Xft */
 77static void xft_alloc_color(const char *colorname, XftColor *color)
 78{
 79	if (!XftColorAllocName(dpy, visual, colormap, colorname, color))
 80		errx(1, "could not allocate color");
 81}
 82
 83/* draw text on pixmap */
 84static void draw(Drawable pix, XftFont *font, XftColor *color, const char *text)
 85{
 86	XGlyphInfo ext;
 87	XftDraw *draw;
 88	int x, y;
 89	size_t len;
 90
 91	draw = XftDrawCreate(dpy, pix, visual, colormap);
 92
 93	len = strlen(text);
 94
 95	/* get text extents */
 96	XftTextExtentsUtf8(dpy, font, text, len, &ext);
 97	x = (WIDTH - ext.width) / 2;
 98	y = (HEIGHT + ext.height) / 2;
 99
100	/* draw text */
101	XftDrawStringUtf8(draw, color, font, x, y, text, len);
102
103	XftDrawDestroy(draw);
104}
105
106/* enter the event loop */
107static void run(GC gc, Pixmap pix)
108{
109	XEvent ev;
110
111	while (XNextEvent(dpy, &ev) == 0) {
112		switch (ev.type) {
113		case Expose:
114			XCopyArea(dpy, pix, ev.xexpose.window, gc, ev.xexpose.x,
115				  ev.xexpose.y, ev.xexpose.width,
116				  ev.xexpose.height, ev.xexpose.x,
117				  ev.xexpose.y);
118			break;
119		}
120	}
121}
122
123int main(int argc, char *argv[])
124{
125	XftColor color;
126	XftFont *font;
127	Pixmap pix;
128	Window win;
129	GC gc;
130
131	if (argc != 2) {
132		fprintf(stderr, "usage: %s STRING\n", argv[0]);
133		return 1;
134	}
135
136	if ((dpy = XOpenDisplay(NULL)) == NULL)
137		errx(1, "could not open display");
138	screen = DefaultScreen(dpy);
139	colormap = DefaultColormap(dpy, screen);
140	visual = DefaultVisual(dpy, screen);
141	depth = DefaultDepth(dpy, screen);
142	root = RootWindow(dpy, screen);
143
144	win = create_win(0, 0, WIDTH, HEIGHT);
145	gc = XCreateGC(dpy, root, 0, NULL);
146	pix = create_pixmap(gc, WIDTH, HEIGHT);
147	font = XftFontOpenName(dpy, screen, fontname);
148	xft_alloc_color(colorname, &color);
149
150	init_atoms(win);
151
152	draw(pix, font, &color, argv[1]);
153	XMapWindow(dpy, win);
154	run(gc, pix);
155
156	/* housekeeping */
157	XUnmapWindow(dpy, win);
158	XDestroyWindow(dpy, win);
159	XFreePixmap(dpy, pix);
160	XFreeGC(dpy, gc);
161	XftColorFree(dpy, visual, colormap, &color);
162	XftFontClose(dpy, font);
163	XCloseDisplay(dpy);
164
165	return 0;
166}