add copyright headers, adjust --version output to include copyright, and --help outpu...
[dana/openbox.git] / tests / icons.c
1 /* -*- indent-tabs-mode: t; tab-width: 4; c-basic-offset: 4; -*-
2
3    icons.c for the Openbox window manager
4    Copyright (c) 2003        Ben Jansens
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    See the COPYING file for a copy of the GNU General Public License.
17 */
18
19 #include <X11/Xlib.h>
20 #include <X11/Xutil.h>
21 #include <X11/Xatom.h>
22 #include <X11/cursorfont.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <assert.h>
26
27 Window findClient(Display *d, Window win)
28 {
29   Window r, *children;
30   unsigned int n, i;
31   Atom state = XInternAtom(d, "WM_STATE", True);
32   Atom ret_type;
33   int ret_format;
34   unsigned long ret_items, ret_bytesleft;
35   unsigned long *prop_return;
36
37   XQueryTree(d, win, &r, &r, &children, &n);
38   for (i = 0; i < n; ++i) {
39     Window w = findClient(d, children[i]);
40     if (w) return w;
41   }
42
43   // try me
44   XGetWindowProperty(d, win, state, 0, 1,
45                      False, state, &ret_type, &ret_format,
46                      &ret_items, &ret_bytesleft,
47                      (unsigned char**) &prop_return); 
48   if (ret_type == None || ret_items < 1)
49     return None;
50   return win; // found it!
51 }
52
53 int main(int argc, char **argv)
54 {
55   Display *d = XOpenDisplay(NULL);
56   int s = DefaultScreen(d);
57   Atom net_wm_icon = XInternAtom(d, "_NET_WM_ICON", True);
58   Atom ret_type;
59   unsigned int winw = 0, winh = 0;
60   int ret_format;
61   unsigned long ret_items, ret_bytesleft;
62   const int MAX_IMAGES = 10;
63   unsigned long *prop_return[MAX_IMAGES];
64   XImage *i[MAX_IMAGES];
65   long offset = 0;
66   unsigned int image = 0;
67   unsigned int j; // loop counter
68   
69   printf("Click on a window with an icon...\n");
70   
71   //int id = strtol(argv[1], NULL, 16);
72   XUngrabPointer(d, CurrentTime);
73   Window id;
74   Cursor cur = XCreateFontCursor(d, XC_crosshair);
75   XGrabPointer(d, RootWindow(d, s), False, ButtonPressMask, GrabModeAsync,
76                GrabModeAsync, None, cur, CurrentTime);
77   XEvent ev;
78   while (1) {
79     XNextEvent(d, &ev);
80     if (ev.type == ButtonPress) {
81       XUngrabPointer(d, CurrentTime);
82       id = findClient(d, ev.xbutton.subwindow);
83       break;
84     }
85   }
86
87   printf("Using window 0x%lx\n", id);
88   
89   do {
90     unsigned int w, h;
91     
92     XGetWindowProperty(d, id, net_wm_icon, offset++, 1,
93                        False, XA_CARDINAL, &ret_type, &ret_format,
94                        &ret_items, &ret_bytesleft,
95                        (unsigned char**) &prop_return[image]);
96     if (ret_type == None || ret_items < 1) {
97       printf("No icon found\n");
98       return 1;
99     }
100     w = prop_return[image][0];
101     XFree(prop_return[image]);
102
103     XGetWindowProperty(d, id, net_wm_icon, offset++, 1,
104                        False, XA_CARDINAL, &ret_type, &ret_format,
105                        &ret_items, &ret_bytesleft,
106                        (unsigned char**) &prop_return[image]);
107     if (ret_type == None || ret_items < 1) {
108       printf("Failed to get height\n");
109       return 1;
110     }
111     h = prop_return[image][0];
112     XFree(prop_return[image]);
113
114     XGetWindowProperty(d, id, net_wm_icon, offset, w*h,
115                        False, XA_CARDINAL, &ret_type, &ret_format,
116                        &ret_items, &ret_bytesleft,
117                        (unsigned char**) &prop_return[image]);
118     if (ret_type == None || ret_items < w*h) {
119       printf("Failed to get image data\n");
120       return 1;
121     }
122     offset += w*h;
123
124     printf("Found icon with size %dx%d\n", w, h);
125   
126     i[image] = XCreateImage(d, DefaultVisual(d, s), DefaultDepth(d, s),
127                             ZPixmap, 0, NULL, w, h, 32, 0);
128     assert(i[image]);
129     i[image]->byte_order = LSBFirst;
130     i[image]->data = (char*)prop_return[image];
131     for (j = 0; j < w*h; j++) {
132       unsigned char alpha = (unsigned char)i[image]->data[j*4+3];
133       unsigned char r = (unsigned char) i[image]->data[j*4+0];
134       unsigned char g = (unsigned char) i[image]->data[j*4+1];
135       unsigned char b = (unsigned char) i[image]->data[j*4+2];
136
137       // background color
138       unsigned char bgr = 0;
139       unsigned char bgg = 0;
140       unsigned char bgb = 0;
141       
142       r = bgr + (r - bgr) * alpha / 256;
143       g = bgg + (g - bgg) * alpha / 256;
144       b = bgb + (b - bgb) * alpha / 256;
145
146       i[image]->data[j*4+0] = (char) r;
147       i[image]->data[j*4+1] = (char) g;
148       i[image]->data[j*4+2] = (char) b;
149     }
150
151     winw += w;
152     if (h > winh) winh = h;
153
154     ++image;
155   } while (ret_bytesleft > 0 && image < MAX_IMAGES);
156
157   Window win = XCreateSimpleWindow(d, RootWindow(d, s), 0, 0, winw, winh,
158                                    0, 0, 0);
159   assert(win);
160   XMapWindow(d, win);
161
162   Pixmap p = XCreatePixmap(d, win, winw, winh, DefaultDepth(d, s));
163   XFillRectangle(d, p, DefaultGC(d, s), 0, 0, winw, winh);
164
165   unsigned int x = 0;
166   for (j = 0; j < image; ++j) {
167     XPutImage(d, p, DefaultGC(d, s), i[j], 0, 0, x, 0,
168               i[j]->width, i[j]->height);
169     x += i[j]->width;
170     XDestroyImage(i[j]);
171   }
172     
173   XSetWindowBackgroundPixmap(d, win, p);
174   XClearWindow(d, win);
175
176   XFlush(d);
177
178   getchar();
179
180   XFreePixmap(d, p);
181   XCloseDisplay(d);
182 }