Add missing libraries to examples' Makefiles
[dockapps.git] / wmclockmon / src / dockapp.c
blobb3d61913ffc157e87d146c2890535b8fc18f7ecc
1 /*
2 * Copyright (c) 1999 Alfredo K. Kojima
3 * Copyright (c) 2001, 2002 Seiichi SATO <ssato@sh.rim.or.jp>
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * This code is based on libdockapp-0.4.0
23 * modified by Seiichi SATO <ssato@sh.rim.or.jp>
26 #include "dockapp.h"
28 #define WINDOWED_SIZE_W 64
29 #define WINDOWED_SIZE_H 64
31 /* global */
32 Display *display = NULL;
33 Bool dockapp_iswindowed = False;
34 Bool dockapp_isbrokenwm = False;
36 /* private */
37 static Window window = None;
38 static Window icon_window = None;
39 static GC gc = NULL;
40 static int depth = 0;
41 static Atom delete_win;
42 static int width, height;
43 static int offset_w, offset_h;
45 void
46 dockapp_open_window(char *display_specified, char *appname,
47 unsigned w, unsigned h, int argc, char **argv)
49 XClassHint *classhint;
50 XWMHints *wmhints;
51 XTextProperty title;
52 XSizeHints sizehints;
53 Window root;
54 int ww, wh;
56 /* Open Connection to X Server */
57 display = XOpenDisplay(display_specified);
58 if (!display) {
59 fprintf(stderr, "%s: could not open display %s!\n", argv[0],
60 XDisplayName(display_specified));
61 exit(1);
63 root = DefaultRootWindow(display);
65 width = w;
66 height = h;
68 if (dockapp_iswindowed) {
69 offset_w = (WINDOWED_SIZE_W - w) / 2;
70 offset_h = (WINDOWED_SIZE_H - h) / 2;
71 ww = WINDOWED_SIZE_W;
72 wh = WINDOWED_SIZE_H;
73 } else {
74 offset_w = offset_h = 0;
75 ww = w;
76 wh = h;
79 /* Create Windows */
80 icon_window = XCreateSimpleWindow(display, root, 0, 0, ww, wh, 0, 0, 0);
81 if (dockapp_isbrokenwm) {
82 window = XCreateSimpleWindow(display, root, 0, 0, ww, wh, 0, 0, 0);
83 } else {
84 window = XCreateSimpleWindow(display, root, 0, 0, 1, 1, 0, 0, 0);
87 /* Set ClassHint */
88 classhint = XAllocClassHint();
89 if (classhint == NULL) {
90 fprintf(stderr, "%s: can't allocate memory for wm hints!\n", argv[0]);
91 exit(1);
93 classhint->res_class = "DockApp";
94 classhint->res_name = appname;
95 XSetClassHint(display, window, classhint);
96 XFree(classhint);
98 /* Set WMHints */
99 wmhints = XAllocWMHints();
100 if (wmhints == NULL) {
101 fprintf(stderr, "%s: can't allocate memory for wm hints!\n", argv[0]);
102 exit(1);
104 wmhints->flags = IconWindowHint | WindowGroupHint;
105 if (!dockapp_iswindowed) {
106 wmhints->flags |= StateHint;
107 wmhints->initial_state = WithdrawnState;
109 wmhints->window_group = window;
110 wmhints->icon_window = icon_window;
111 XSetWMHints(display, window, wmhints);
112 XFree(wmhints);
114 /* Set WM Protocols */
115 delete_win = XInternAtom(display, "WM_DELETE_WINDOW", False);
116 XSetWMProtocols (display, icon_window, &delete_win, 1);
118 /* Set Size Hints */
119 sizehints.flags = USSize;
120 if (!dockapp_iswindowed) {
121 sizehints.flags |= USPosition;
122 sizehints.x = sizehints.y = 0;
123 } else {
124 sizehints.flags |= PMinSize | PMaxSize;
125 sizehints.min_width = sizehints.max_width = WINDOWED_SIZE_W;
126 sizehints.min_height = sizehints.max_height = WINDOWED_SIZE_H;
128 sizehints.width = ww;
129 sizehints.height = wh;
130 XSetWMNormalHints(display, icon_window, &sizehints);
132 /* Set WindowTitle for AfterStep Wharf */
133 XStringListToTextProperty(&appname, 1, &title);
134 XSetWMName(display, window, &title);
135 XSetWMName(display, icon_window, &title);
137 /* Set Command to start the app so it can be docked properly */
138 XSetCommand(display, window, argv, argc);
140 depth = DefaultDepth(display, DefaultScreen(display));
141 gc = DefaultGC(display, DefaultScreen(display));
143 XFlush(display);
147 void
148 dockapp_set_eventmask(long mask)
150 XSelectInput(display, icon_window, mask);
151 XSelectInput(display, window, mask);
155 static Pixmap
156 create_bg_pixmap(void)
158 Pixmap bg;
160 bg = XCreatePixmap(display, icon_window, WINDOWED_SIZE_W, WINDOWED_SIZE_H,
161 depth);
162 XSetForeground(display, gc, dockapp_getcolor("rgb:ae/aa/ae"));
163 XFillRectangle(display, bg, gc, 0, 0, WINDOWED_SIZE_W, WINDOWED_SIZE_H);
164 XSetForeground(display, gc, dockapp_getcolor("rgb:ff/ff/ff"));
165 XDrawLine(display, bg, gc, 0, 0, 0, 63);
166 XDrawLine(display, bg, gc, 1, 0, 1, 62);
167 XDrawLine(display, bg, gc, 2, 0, 63, 0);
168 XDrawLine(display, bg, gc, 2, 1, 62, 1);
169 XSetForeground(display, gc, dockapp_getcolor("rgb:52/55/52"));
170 XDrawLine(display, bg, gc, 1, 63, 63, 63);
171 XDrawLine(display, bg, gc, 2, 62, 63, 62);
172 XDrawLine(display, bg, gc, 63, 1, 63, 61);
173 XDrawLine(display, bg, gc, 62, 2, 62, 61);
175 return bg;
179 void
180 dockapp_set_background(Pixmap pixmap)
182 if (dockapp_iswindowed) {
183 Pixmap bg;
184 bg = create_bg_pixmap();
185 XCopyArea(display, pixmap, bg, gc, 0, 0, width, height,
186 offset_w, offset_w);
187 XSetWindowBackgroundPixmap(display, icon_window, bg);
188 XSetWindowBackgroundPixmap(display, window, bg);
189 XFreePixmap(display, bg);
190 } else {
191 XSetWindowBackgroundPixmap(display, icon_window, pixmap);
192 XSetWindowBackgroundPixmap(display, window, pixmap);
194 XClearWindow(display, icon_window);
195 XFlush(display);
199 void
200 dockapp_show(void)
202 if (!dockapp_iswindowed)
203 XMapRaised(display, window);
204 else
205 XMapRaised(display, icon_window);
207 XFlush(display);
211 Bool
212 dockapp_xpm2pixmap(char **data, Pixmap *pixmap, Pixmap *mask,
213 XpmColorSymbol * colorSymbol, unsigned int nsymbols)
215 XpmAttributes xpmAttr;
216 xpmAttr.valuemask = XpmCloseness;
217 xpmAttr.closeness = 40000;
219 if (nsymbols) {
220 xpmAttr.colorsymbols = colorSymbol;
221 xpmAttr.numsymbols = nsymbols;
222 xpmAttr.valuemask |= XpmColorSymbols;
225 if (XpmCreatePixmapFromData(display, icon_window, data, pixmap, mask, &xpmAttr) != 0)
226 return False;
228 return True;
232 Bool
233 dockapp_file2pixmap(char *filename, Pixmap *pixmap, Pixmap *mask,
234 XpmColorSymbol * colorSymbol, unsigned int nsymbols)
236 XpmAttributes xpmAttr;
237 xpmAttr.valuemask = XpmCloseness;
238 xpmAttr.closeness = 40000;
240 if (nsymbols) {
241 xpmAttr.colorsymbols = colorSymbol;
242 xpmAttr.numsymbols = nsymbols;
243 xpmAttr.valuemask |= XpmColorSymbols;
246 if (XpmReadFileToPixmap(display, icon_window, filename, pixmap, mask, &xpmAttr) != 0)
247 return False;
249 return True;
253 Pixmap
254 dockapp_XCreatePixmap(int w, int h)
256 return (XCreatePixmap(display, icon_window, w, h, depth));
260 void
261 dockapp_setshape(Pixmap mask, int x_ofs, int y_ofs)
263 XShapeCombineMask(display, icon_window, ShapeBounding, -x_ofs, -y_ofs,
264 mask, ShapeSet);
265 XShapeCombineMask(display, window, ShapeBounding, -x_ofs, -y_ofs,
266 mask, ShapeSet);
267 XFlush(display);
271 void
272 dockapp_copyarea(Pixmap src, Pixmap dist, int x_src, int y_src, int w, int h,
273 int x_dist, int y_dist)
275 XCopyArea(display, src, dist, gc, x_src, y_src, w, h, x_dist, y_dist);
279 void
280 dockapp_copy2window (Pixmap src)
282 if (dockapp_isbrokenwm) {
283 XCopyArea(display, src, window, gc, 0, 0, width, height, offset_w,
284 offset_h);
285 } else {
286 XCopyArea(display, src, icon_window, gc, 0, 0, width, height, offset_w,
287 offset_h);
292 Bool
293 dockapp_nextevent_or_timeout(XEvent *event, unsigned long miliseconds)
295 struct timeval timeout;
296 fd_set rset;
298 XSync(display, False);
299 if (XPending(display)) {
300 XNextEvent(display, event);
301 return True;
304 timeout.tv_sec = miliseconds / 1000;
305 timeout.tv_usec = (miliseconds % 1000) * 1000;
307 FD_ZERO(&rset);
308 FD_SET(ConnectionNumber(display), &rset);
309 if (select(ConnectionNumber(display)+1, &rset, NULL, NULL, &timeout) > 0) {
310 XNextEvent(display, event);
311 if (event->type == ClientMessage) {
312 if ((Atom) event->xclient.data.l[0] == delete_win) {
313 XDestroyWindow(display,event->xclient.window);
314 XCloseDisplay(display);
315 exit(0);
318 if (dockapp_iswindowed) {
319 event->xbutton.x -= offset_w;
320 event->xbutton.y -= offset_h;
322 return True;
325 return False;
329 unsigned long
330 dockapp_getcolor(char *color_name)
332 XColor color;
334 if (!XParseColor(display, DefaultColormap(display, DefaultScreen(display)),
335 color_name, &color))
336 fprintf(stderr, "can't parse color %s\n", color_name), exit(1);
338 if (!XAllocColor(display, DefaultColormap(display, DefaultScreen(display)),
339 &color)) {
340 fprintf(stderr, "can't allocate color %s. Using black\n", color_name);
341 return BlackPixel(display, DefaultScreen(display));
344 return color.pixel;
349 Noberasco Michele <noberasco.gnu@disi.unige.it>
350 divide given color by a factor of n
352 unsigned long
353 dockapp_dividecolor(char *color_name, int n)
355 XColor color;
357 if ( (n<=0) || (n>127) ) {
358 fprintf(stderr, "Divisor must be >0 and <127\n");
359 exit(1);
362 if (!XParseColor(display, DefaultColormap(display, DefaultScreen(display)),
363 color_name, &color))
364 fprintf(stderr, "can't parse color %s\n", color_name), exit(1);
366 if (!XAllocColor(display, DefaultColormap(display, DefaultScreen(display)),
367 &color)) {
368 fprintf(stderr, "can't allocate color %s. Using black\n", color_name);
369 return BlackPixel(display, DefaultScreen(display));
372 if (DefaultDepth(display, DefaultScreen(display)) < 16)
373 return color.pixel;
375 color.red = color.red / n;
376 color.green = color.green / n;
377 color.blue = color.blue / n;
379 color.flags = DoRed | DoGreen | DoBlue;
381 if (!XAllocColor(display, DefaultColormap(display, DefaultScreen(display)),
382 &color)) {
383 fprintf(stderr, "can't allocate color %s. Using black\n", color_name);
384 return BlackPixel(display, DefaultScreen(display));
387 return color.pixel;
391 unsigned long
392 dockapp_blendedcolor(char *color_name, int r, int g, int b, float fac)
394 XColor color;
396 if ((r < -255 || r > 255)||(g < -255 || g > 255)||(b < -255 || b > 255)){
397 fprintf(stderr, "r:%d,g:%d,b:%d (r,g,b must be 0 to 255)", r, g, b);
398 exit(1);
401 r *= 255;
402 g *= 255;
403 b *= 255;
405 if (!XParseColor(display, DefaultColormap(display, DefaultScreen(display)),
406 color_name, &color))
407 fprintf(stderr, "can't parse color %s\n", color_name), exit(1);
409 if (!XAllocColor(display, DefaultColormap(display, DefaultScreen(display)),
410 &color)) {
411 fprintf(stderr, "can't allocate color %s. Using black\n", color_name);
412 return BlackPixel(display, DefaultScreen(display));
415 if (DefaultDepth(display, DefaultScreen(display)) < 16)
416 return color.pixel;
418 /* red */
419 if (color.red + r > 0xffff) {
420 color.red = 0xffff;
421 } else if (color.red + r < 0) {
422 color.red = 0;
423 } else {
424 color.red = (unsigned short)(fac * color.red + r);
427 /* green */
428 if (color.green + g > 0xffff) {
429 color.green = 0xffff;
430 } else if (color.green + g < 0) {
431 color.green = 0;
432 } else {
433 color.green = (unsigned short)(fac * color.green + g);
436 /* blue */
437 if (color.blue + b > 0xffff) {
438 color.blue = 0xffff;
439 } else if (color.blue + b < 0) {
440 color.blue = 0;
441 } else {
442 color.blue = (unsigned short)(fac * color.blue + b);
445 color.flags = DoRed | DoGreen | DoBlue;
447 if (!XAllocColor(display, DefaultColormap(display, DefaultScreen(display)),
448 &color)) {
449 fprintf(stderr, "can't allocate color %s. Using black\n", color_name);
450 return BlackPixel(display, DefaultScreen(display));
453 return color.pixel;