From: Martin Mares Date: Thu, 23 Jan 2014 22:03:00 +0000 (+0100) Subject: The test program is no longer necessary X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=4202f6322ee56826561024d4036f4bc4c5be1d6a;p=osdd.git The test program is no longer necessary --- diff --git a/test.c b/test.c deleted file mode 100644 index ced576f..0000000 --- a/test.c +++ /dev/null @@ -1,235 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG -#include "osd.h" - -struct osd_state { - Display *dpy; - int screen; - Visual *visual; - Colormap cmap; - int depth; - int screen_width; - int screen_height; - Window win; - Pixmap mask_bitmap; - Pixmap image_pixmap; - GC gc; - GC mask_gc; - - // Xft stuff - XftFont *font; - XftDraw *mask_draw; - XftDraw *image_draw; -}; - -static void -stay_on_top(struct osd_state *osd) -{ - /* Heavily inspired by a similar function in libxosd */ - Window root = DefaultRootWindow(osd->dpy); - int format; - unsigned long nitems, bytes_after; - unsigned char *prop = NULL; - Atom type; - - // Gnome-compliant way - Atom gnome = XInternAtom(osd->dpy, "_WIN_SUPPORTING_WM_CHECK", False); - if (XGetWindowProperty(osd->dpy, root, gnome, 0, 16384, False, AnyPropertyType, - &type, &format, &nitems, &bytes_after, &prop) == Success && - nitems > 0) - { - DBG("stay_on_top: Gnome mode\n"); - // FIXME: check capabilities - XClientMessageEvent e; - memset(&e, 0, sizeof(e)); - e.type = ClientMessage; - e.window = osd->win; - e.message_type = XInternAtom(osd->dpy, "_WIN_LAYER", False); - e.format = 32; - e.data.l[0] = 6; // WIN_LAYER_ONTOP */ - XSendEvent(osd->dpy, root, False, SubstructureNotifyMask, (XEvent *) &e); - XFree(prop); - return; - } - - // NetWM-compliant way - Atom net_wm = XInternAtom(osd->dpy, "_NET_SUPPORTED", False); - if (XGetWindowProperty(osd->dpy, root, net_wm, 0, 16384, False, AnyPropertyType, - &type, &format, &nitems, &bytes_after, &prop) == Success && - nitems > 0) - { - DBG("stay_on_top: NetWM mode\n"); - XEvent e; - memset(&e, 0, sizeof(e)); - e.xclient.type = ClientMessage; - e.xclient.message_type = XInternAtom(osd->dpy, "_NET_WM_STATE", False); - e.xclient.display = osd->dpy; - e.xclient.window = osd->win; - e.xclient.format = 32; - e.xclient.data.l[0] = 1; // _NET_WM_STATE_ADD - e.xclient.data.l[1] = XInternAtom(osd->dpy, "_NET_WM_STATE_STAYS_ON_TOP", False); - XSendEvent(osd->dpy, root, False, SubstructureRedirectMask, &e); - XFree(prop); - return; - } - - DBG("stay_on_top: WM does not support any known protocol\n"); -} - -int -main(int argc, char **argv) -{ - XInitThreads(); - - struct osd_state osd_static; - bzero(&osd_static, sizeof(osd_static)); - struct osd_state *osd = &osd_static; - - osd->dpy = XOpenDisplay(NULL); - if (!osd->dpy) - die("Cannot open display"); - - int event_basep, error_basep; - if (!XShapeQueryExtension(osd->dpy, &event_basep, &error_basep)) - die("XShape extension not supported by X server, giving up"); - - osd->screen = XDefaultScreen(osd->dpy); - osd->visual = XDefaultVisual(osd->dpy, osd->screen); - osd->depth = XDefaultDepth(osd->dpy, osd->screen); - osd->cmap = DefaultColormap(osd->dpy, osd->screen); - - // These can change. And what about Xinerama? - osd->screen_width = XDisplayWidth(osd->dpy, osd->screen); - osd->screen_height = XDisplayHeight(osd->dpy, osd->screen); - - XSetWindowAttributes win_attr = { - .override_redirect = 1, - }; - osd->win = XCreateWindow(osd->dpy, - XRootWindow(osd->dpy, osd->screen), - 0, 0, - osd->screen_width, osd->screen_height, - 0, - osd->depth, - CopyFromParent, - osd->visual, - CWOverrideRedirect, - &win_attr); - XStoreName(osd->dpy, osd->win, "OSD"); - stay_on_top(osd); - - // FIXME: Size - osd->mask_bitmap = XCreatePixmap(osd->dpy, osd->win, osd->screen_width, osd->screen_height, 1); - osd->image_pixmap = XCreatePixmap(osd->dpy, osd->win, osd->screen_width, osd->screen_height, osd->depth); - DBG("depth = %d\n", osd->depth); - - XGCValues gcv = { - .graphics_exposures = 0, - }; - osd->gc = XCreateGC(osd->dpy, osd->win, GCGraphicsExposures, &gcv); - osd->mask_gc = XCreateGC(osd->dpy, osd->mask_bitmap, GCGraphicsExposures, &gcv); - - XSetBackground(osd->dpy, osd->gc, BlackPixel(osd->dpy, osd->screen)); - XColor shadow_color = { .red = 0xffff, .green = 0xffff, .blue = 0 }; - XAllocColor(osd->dpy, osd->cmap, &shadow_color); - XSetForeground(osd->dpy, osd->gc, shadow_color.pixel); - - XSetBackground(osd->dpy, osd->mask_gc, WhitePixel(osd->dpy, osd->screen)); - XSetForeground(osd->dpy, osd->mask_gc, BlackPixel(osd->dpy, osd->screen)); - - XFillRectangle(osd->dpy, osd->image_pixmap, osd->gc, 0, 0, osd->screen_width, osd->screen_height); - - XFillRectangle(osd->dpy, osd->mask_bitmap, osd->mask_gc, 0, 0, osd->screen_width, osd->screen_height); - - osd->font = XftFontOpenName(osd->dpy, osd->screen, "times-64"); - if (!osd->font) - die("Cannot open font"); - DBG("Font: asc=%d desc=%d ht=%d\n", osd->font->ascent, osd->font->descent, osd->font->height); - - osd->mask_draw = XftDrawCreateBitmap(osd->dpy, osd->mask_bitmap); - if (!osd->mask_draw) - die("Cannot create XftDraw"); - - osd->image_draw = XftDrawCreate(osd->dpy, osd->image_pixmap, osd->visual, osd->cmap); - if (!osd->image_draw) - die("Cannot create XftDraw"); - - XRenderColor xrc = { .red = 0, .green = 0xffff, .blue = 0, .alpha = 0xffff }; - XftColor xfc; - if (!XftColorAllocValue(osd->dpy, osd->visual, osd->cmap, &xrc, &xfc)) - die("XftColorAllocValue failed"); - const unsigned char str[] = "Žluťoučká vlkodlačice"; - XftDrawStringUtf8(osd->image_draw, &xfc, osd->font, 100, 100, str, strlen((char *) str)); - - XRenderColor xrcm = { .red = 0xffff, .green = 0xffff, .blue = 0xffff, .alpha = 0xffff }; - XftColor xfcm; - if (!XftColorAllocValue(osd->dpy, osd->visual, osd->cmap, &xrcm, &xfcm)) - die("XftColorAllocValue failed"); - - // This is slow, but unlike the method used by libxosd, the result isn't ugly. - int outline = 3; - for (int dx = -outline; dx <= outline; dx++) - for (int dy = -outline; dy <= outline; dy++) - if (dx*dx + dy*dy <= outline*outline) - XftDrawStringUtf8(osd->mask_draw, &xfcm, osd->font, 100 + dx, 100 + dy, str, strlen((char *) str)); - -#if 0 - XGlyphInfo gi; - XftTextExtentsUtf8(osd->dpy, osd->font, str, strlen((char *) str), &gi); - DBG("Glyph info: (%d,%d)+(%d,%d) off (%d,%d)\n", gi.x, gi.y, gi.width, gi.height, gi.xOff, gi.yOff); - XftDrawRect(osd->image_draw, &xfc, 100 + gi.x, 100 - gi.y, gi.width, gi.height); -#endif - - XShapeCombineMask(osd->dpy, osd->win, ShapeBounding, 0, 0, osd->mask_bitmap, ShapeSet); - - XSelectInput(osd->dpy, osd->win, ExposureMask); - XMapRaised(osd->dpy, osd->win); - XFlush(osd->dpy); - - struct pollfd pfd = { - .fd = ConnectionNumber(osd->dpy), - .events = POLLIN, - }; - - for (;;) - { - timestamp_t now = get_current_time(); - timestamp_t wait_until = now - 1; - - DBG("... waiting for %d ms\n", (int)(wait_until - now)); - poll(&pfd, 1, wait_until - now); - if (pfd.revents & POLLIN) - { - while (XPending(osd->dpy)) - { - XEvent ev; - XNextEvent(osd->dpy, &ev); - switch (ev.type) - { - case Expose: - { - XExposeEvent *ex = &ev.xexpose; - DBG("Expose cnt=%d (%d,%d)+(%d,%d)\n", ex->count, ex->x, ex->y, ex->width, ex->height); - XCopyArea(osd->dpy, osd->image_pixmap, osd->win, osd->gc, ex->x, ex->y, ex->width, ex->height, ex->x, ex->y); - break; - } - default: - DBG("Event %d\n", ev.type); - } - } - } - } - - // FIXME: Cleanup -}