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