tests/icons.c (raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
#include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xatom.h> #include <X11/cursorfont.h> #include <stdlib.h> #include <stdio.h> #include <assert.h> Window findClient(Display *d, Window win) { Window r, *children; unsigned int n, i; Atom state = XInternAtom(d, "WM_STATE", True); Atom ret_type; int ret_format; unsigned long ret_items, ret_bytesleft; unsigned long *prop_return; XQueryTree(d, win, &r, &r, &children, &n); for (i = 0; i < n; ++i) { Window w = findClient(d, children[i]); if (w) return w; } // try me XGetWindowProperty(d, win, state, 0, 1, False, state, &ret_type, &ret_format, &ret_items, &ret_bytesleft, (unsigned char**) &prop_return); if (ret_type == None || ret_items < 1) return None; return win; // found it! } int main(int argc, char **argv) { Display *d = XOpenDisplay(NULL); int s = DefaultScreen(d); Atom net_wm_icon = XInternAtom(d, "_NET_WM_ICON", True); Atom ret_type; unsigned int winw = 0, winh = 0; int ret_format; unsigned long ret_items, ret_bytesleft; const int MAX_IMAGES = 10; unsigned long *prop_return[MAX_IMAGES]; XImage *i[MAX_IMAGES]; long offset = 0; unsigned int image = 0; unsigned int j; // loop counter printf("Click on a window with an icon...\n"); //int id = strtol(argv[1], NULL, 16); XUngrabPointer(d, CurrentTime); Window id; Cursor cur = XCreateFontCursor(d, XC_crosshair); XGrabPointer(d, RootWindow(d, s), False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, cur, CurrentTime); XEvent ev; while (1) { XNextEvent(d, &ev); if (ev.type == ButtonPress) { XUngrabPointer(d, CurrentTime); id = findClient(d, ev.xbutton.subwindow); break; } } printf("Using window 0x%lx\n", id); do { unsigned int w, h; XGetWindowProperty(d, id, net_wm_icon, offset++, 1, False, XA_CARDINAL, &ret_type, &ret_format, &ret_items, &ret_bytesleft, (unsigned char**) &prop_return[image]); if (ret_type == None || ret_items < 1) { printf("No icon found\n"); return 1; } w = prop_return[image][0]; XFree(prop_return[image]); XGetWindowProperty(d, id, net_wm_icon, offset++, 1, False, XA_CARDINAL, &ret_type, &ret_format, &ret_items, &ret_bytesleft, (unsigned char**) &prop_return[image]); if (ret_type == None || ret_items < 1) { printf("Failed to get height\n"); return 1; } h = prop_return[image][0]; XFree(prop_return[image]); XGetWindowProperty(d, id, net_wm_icon, offset, w*h, False, XA_CARDINAL, &ret_type, &ret_format, &ret_items, &ret_bytesleft, (unsigned char**) &prop_return[image]); if (ret_type == None || ret_items < w*h) { printf("Failed to get image data\n"); return 1; } offset += w*h; printf("Found icon with size %dx%d\n", w, h); i[image] = XCreateImage(d, DefaultVisual(d, s), DefaultDepth(d, s), ZPixmap, 0, NULL, w, h, 32, 0); assert(i[image]); i[image]->byte_order = LSBFirst; i[image]->data = (char*)prop_return[image]; for (j = 0; j < w*h; j++) { unsigned char alpha = (unsigned char)i[image]->data[j*4+3]; unsigned char r = (unsigned char) i[image]->data[j*4+0]; unsigned char g = (unsigned char) i[image]->data[j*4+1]; unsigned char b = (unsigned char) i[image]->data[j*4+2]; // background color unsigned char bgr = 0; unsigned char bgg = 0; unsigned char bgb = 0; r = bgr + (r - bgr) * alpha / 256; g = bgg + (g - bgg) * alpha / 256; b = bgb + (b - bgb) * alpha / 256; i[image]->data[j*4+0] = (char) r; i[image]->data[j*4+1] = (char) g; i[image]->data[j*4+2] = (char) b; } winw += w; if (h > winh) winh = h; ++image; } while (ret_bytesleft > 0 && image < MAX_IMAGES); Window win = XCreateSimpleWindow(d, RootWindow(d, s), 0, 0, winw, winh, 0, 0, 0); assert(win); XMapWindow(d, win); Pixmap p = XCreatePixmap(d, win, winw, winh, DefaultDepth(d, s)); XFillRectangle(d, p, DefaultGC(d, s), 0, 0, winw, winh); unsigned int x = 0; for (j = 0; j < image; ++j) { XPutImage(d, p, DefaultGC(d, s), i[j], 0, 0, x, 0, i[j]->width, i[j]->height); x += i[j]->width; XDestroyImage(i[j]); } XSetWindowBackgroundPixmap(d, win, p); XClearWindow(d, win); XFlush(d); getchar(); XFreePixmap(d, p); XCloseDisplay(d); } |