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}