9 #include <X11/extensions/shape.h>
10 #include <X11/extensions/render.h>
11 #include <X11/Xft/Xft.h>
36 main(int argc, char **argv)
40 struct osd_state osd_static;
41 bzero(&osd_static, sizeof(osd_static));
42 struct osd_state *osd = &osd_static;
44 osd->dpy = XOpenDisplay(NULL);
46 die("Cannot open display");
48 int event_basep, error_basep;
49 if (!XShapeQueryExtension(osd->dpy, &event_basep, &error_basep))
50 die("XShape extension not supported by X server, giving up");
52 osd->screen = XDefaultScreen(osd->dpy);
53 osd->visual = XDefaultVisual(osd->dpy, osd->screen);
54 osd->depth = XDefaultDepth(osd->dpy, osd->screen);
55 osd->cmap = DefaultColormap(osd->dpy, osd->screen);
57 // These can change. And what about Xinerama?
58 osd->screen_width = XDisplayWidth(osd->dpy, osd->screen);
59 osd->screen_height = XDisplayHeight(osd->dpy, osd->screen);
61 XSetWindowAttributes win_attr = {
62 .override_redirect = 0, // FIXME: 1
64 osd->win = XCreateWindow(osd->dpy,
65 XRootWindow(osd->dpy, osd->screen),
67 osd->screen_width, osd->screen_height,
74 XStoreName(osd->dpy, osd->win, "OSD");
77 osd->mask_bitmap = XCreatePixmap(osd->dpy, osd->win, osd->screen_width, osd->screen_height, 1);
78 osd->image_pixmap = XCreatePixmap(osd->dpy, osd->win, osd->screen_width, osd->screen_height, osd->depth);
79 DBG("depth = %d\n", osd->depth);
82 .graphics_exposures = 0,
84 osd->gc = XCreateGC(osd->dpy, osd->win, GCGraphicsExposures, &gcv);
85 osd->mask_gc = XCreateGC(osd->dpy, osd->mask_bitmap, GCGraphicsExposures, &gcv);
87 XSetBackground(osd->dpy, osd->gc, BlackPixel(osd->dpy, osd->screen));
88 XSetForeground(osd->dpy, osd->gc, BlackPixel(osd->dpy, osd->screen));
90 XSetBackground(osd->dpy, osd->mask_gc, WhitePixel(osd->dpy, osd->screen));
91 XSetForeground(osd->dpy, osd->mask_gc, BlackPixel(osd->dpy, osd->screen));
95 XFillRectangle(osd->dpy, osd->image_pixmap, osd->gc, 0, 0, osd->screen_width, osd->screen_height);
97 osd->font = XftFontOpenName(osd->dpy, osd->screen, "times-64");
99 die("Cannot open font");
101 osd->xft_draw = XftDrawCreate(osd->dpy, osd->image_pixmap, osd->visual, osd->cmap);
103 die("Cannot create XftDraw");
105 XRenderColor xrc = { .red = 0, .green = 0xffff, .blue = 0, .alpha = 0xffff };
107 if (!XftColorAllocValue(osd->dpy, osd->visual, osd->cmap, &xrc, &xfc))
108 die("XftColorAllocValue failed");
109 const unsigned char str[] = "Žluťoučká vlkodlačice";
110 XftDrawStringUtf8(osd->xft_draw, &xfc, osd->font, 100, 100, str, strlen((char *) str));
113 XftTextExtentsUtf8(osd->dpy, osd->font, str, strlen((char *) str), &gi);
114 DBG("Glyph info: (%d,%d)+(%d,%d) off (%d,%d)\n", gi.x, gi.y, gi.width, gi.height, gi.xOff, gi.yOff);
115 XftDrawRect(osd->xft_draw, &xfc, 100 + gi.x, 100 - gi.y, gi.width, gi.height);
117 XftDrawRect(osd->xft_draw, &xfc, 30, 30, 50, 50);
119 XSelectInput(osd->dpy, osd->win, ExposureMask);
120 XMapRaised(osd->dpy, osd->win);
123 struct pollfd pfd = {
124 .fd = ConnectionNumber(osd->dpy),
130 timestamp_t now = get_current_time();
131 timestamp_t wait_until = now - 1;
133 DBG("... waiting for %d ms\n", (int)(wait_until - now));
134 poll(&pfd, 1, wait_until - now);
135 if (pfd.revents & POLLIN)
137 while (XPending(osd->dpy))
140 XNextEvent(osd->dpy, &ev);
145 XExposeEvent *ex = &ev.xexpose;
146 DBG("Expose cnt=%d (%d,%d)+(%d,%d)\n", ex->count, ex->x, ex->y, ex->width, ex->height);
147 XCopyArea(osd->dpy, osd->image_pixmap, osd->win, osd->gc, ex->x, ex->y, ex->width, ex->height, ex->x, ex->y);
151 DBG("Event %d\n", ev.type);