wmclockmon: update change-log
[dockapps.git] / wmmemload / src / dockapp.c
blob77f4d7122b63c9ec38fbe552c3964ce1d6c70fa2
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;
40 static int depth;
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);
86 /* Set ClassHint */
87 classhint = XAllocClassHint();
88 if (classhint == NULL) {
89 fprintf(stderr, "%s: can't allocate memory for wm hints!\n", argv[0]);
90 exit(1);
92 classhint->res_class = "DockApp";
93 classhint->res_name = appname;
94 XSetClassHint(display, window, classhint);
95 XFree(classhint);
97 /* Set WMHints */
98 wmhints = XAllocWMHints();
99 if (wmhints == NULL) {
100 fprintf(stderr, "%s: can't allocate memory for wm hints!\n", argv[0]);
101 exit(1);
103 wmhints->flags = IconWindowHint | WindowGroupHint;
104 if (!dockapp_iswindowed) {
105 wmhints->flags |= StateHint;
106 wmhints->initial_state = WithdrawnState;
108 wmhints->window_group = window;
109 wmhints->icon_window = icon_window;
110 XSetWMHints(display, window, wmhints);
111 XFree(wmhints);
113 /* Set WM Protocols */
114 delete_win = XInternAtom(display, "WM_DELETE_WINDOW", False);
115 XSetWMProtocols(display, icon_window, &delete_win, 1);
117 /* Set Size Hints */
118 sizehints.flags = USSize;
119 if (!dockapp_iswindowed) {
120 sizehints.flags |= USPosition;
121 sizehints.x = sizehints.y = 0;
122 } else {
123 sizehints.flags |= PMinSize | PMaxSize;
124 sizehints.min_width = sizehints.max_width = WINDOWED_SIZE_W;
125 sizehints.min_height = sizehints.max_height = WINDOWED_SIZE_H;
127 sizehints.width = ww;
128 sizehints.height = wh;
129 XSetWMNormalHints(display, icon_window, &sizehints);
131 /* Set WindowTitle for AfterStep Wharf */
132 XStringListToTextProperty(&appname, 1, &title);
133 XSetWMName(display, window, &title);
134 XSetWMName(display, icon_window, &title);
136 /* Set Command to start the app so it can be docked properly */
137 XSetCommand(display, window, argv, argc);
139 depth = DefaultDepth(display, DefaultScreen(display));
140 gc = DefaultGC(display, DefaultScreen(display));
142 XFlush(display);
146 void
147 dockapp_set_eventmask(long mask)
149 XSelectInput(display, icon_window, mask);
150 XSelectInput(display, window, mask);
154 static Pixmap
155 create_bg_pixmap(void)
157 Pixmap bg;
159 bg = XCreatePixmap(display, icon_window, WINDOWED_SIZE_W, WINDOWED_SIZE_H,
160 depth);
161 XSetForeground(display, gc, dockapp_getcolor("rgb:ae/aa/ae"));
162 XFillRectangle(display, bg, gc, 0, 0, WINDOWED_SIZE_W, WINDOWED_SIZE_H);
163 XSetForeground(display, gc, dockapp_getcolor("rgb:ff/ff/ff"));
164 XDrawLine(display, bg, gc, 0, 0, 0, 63);
165 XDrawLine(display, bg, gc, 1, 0, 1, 62);
166 XDrawLine(display, bg, gc, 2, 0, 63, 0);
167 XDrawLine(display, bg, gc, 2, 1, 62, 1);
168 XSetForeground(display, gc, dockapp_getcolor("rgb:52/55/52"));
169 XDrawLine(display, bg, gc, 1, 63, 63, 63);
170 XDrawLine(display, bg, gc, 2, 62, 63, 62);
171 XDrawLine(display, bg, gc, 63, 1, 63, 61);
172 XDrawLine(display, bg, gc, 62, 2, 62, 61);
174 return bg;
178 void
179 dockapp_set_background(Pixmap pixmap)
181 if (dockapp_iswindowed) {
182 Pixmap bg;
183 bg = create_bg_pixmap();
184 XCopyArea(display, pixmap, bg, gc, 0, 0, width, height,
185 offset_w, offset_w);
186 XSetWindowBackgroundPixmap(display, icon_window, bg);
187 XSetWindowBackgroundPixmap(display, window, bg);
188 XFreePixmap(display, bg);
189 } else {
190 XSetWindowBackgroundPixmap(display, icon_window, pixmap);
191 XSetWindowBackgroundPixmap(display, window, pixmap);
193 XClearWindow(display, icon_window);
194 XFlush(display);
198 void
199 dockapp_show(void)
201 if (!dockapp_iswindowed)
202 XMapRaised(display, window);
203 else
204 XMapRaised(display, icon_window);
206 XFlush(display);
210 Bool
211 dockapp_xpm2pixmap(char **data, Pixmap *pixmap, Pixmap *mask,
212 XpmColorSymbol *colorSymbol, unsigned int nsymbols)
214 XpmAttributes xpmAttr;
215 xpmAttr.valuemask = XpmCloseness;
216 xpmAttr.closeness = 40000;
218 if (nsymbols) {
219 xpmAttr.colorsymbols = colorSymbol;
220 xpmAttr.numsymbols = nsymbols;
221 xpmAttr.valuemask |= XpmColorSymbols;
224 if (XpmCreatePixmapFromData(display, icon_window, data, pixmap, mask, &xpmAttr) != 0)
225 return False;
227 return True;
231 Pixmap
232 dockapp_XCreatePixmap(int w, int h)
234 return XCreatePixmap(display, icon_window, w, h, depth);
238 void
239 dockapp_setshape(Pixmap mask, int x_ofs, int y_ofs)
241 XShapeCombineMask(display, icon_window, ShapeBounding, -x_ofs, -y_ofs,
242 mask, ShapeSet);
243 XShapeCombineMask(display, window, ShapeBounding, -x_ofs, -y_ofs,
244 mask, ShapeSet);
245 XFlush(display);
249 void
250 dockapp_copyarea(Pixmap src, Pixmap dist, int x_src, int y_src, int w, int h,
251 int x_dist, int y_dist)
253 XCopyArea(display, src, dist, gc, x_src, y_src, w, h, x_dist, y_dist);
257 void
258 dockapp_copy2window(Pixmap src)
260 if (dockapp_isbrokenwm) {
261 XCopyArea(display, src, window, gc, 0, 0, width, height, offset_w,
262 offset_h);
263 } else {
264 XCopyArea(display, src, icon_window, gc, 0, 0, width, height, offset_w,
265 offset_h);
270 Bool
271 dockapp_nextevent_or_timeout(XEvent *event, unsigned long miliseconds)
273 struct timeval timeout;
274 fd_set rset;
276 XSync(display, False);
277 if (XPending(display)) {
278 XNextEvent(display, event);
279 return True;
282 timeout.tv_sec = miliseconds / 1000;
283 timeout.tv_usec = (miliseconds % 1000) * 1000;
285 FD_ZERO(&rset);
286 FD_SET(ConnectionNumber(display), &rset);
287 if (select(ConnectionNumber(display)+1, &rset, NULL, NULL, &timeout) > 0) {
288 XNextEvent(display, event);
289 if (event->type == ClientMessage) {
290 if (event->xclient.data.l[0] == delete_win) {
291 XDestroyWindow(display, event->xclient.window);
292 XCloseDisplay(display);
293 exit(0);
296 if (dockapp_iswindowed) {
297 event->xbutton.x -= offset_w;
298 event->xbutton.y -= offset_h;
300 return True;
303 return False;
307 unsigned long
308 dockapp_getcolor(char *color_name)
310 XColor color;
312 if (!XParseColor(display, DefaultColormap(display, DefaultScreen(display)),
313 color_name, &color))
314 fprintf(stderr, "can't parse color %s\n", color_name), exit(1);
316 if (!XAllocColor(display, DefaultColormap(display, DefaultScreen(display)),
317 &color)) {
318 fprintf(stderr, "can't allocate color %s. Using black\n", color_name);
319 return BlackPixel(display, DefaultScreen(display));
322 return color.pixel;
326 unsigned long
327 dockapp_blendedcolor(char *color_name, int r, int g, int b, float fac)
329 XColor color;
331 if ((r < -255 || r > 255) || (g < -255 || g > 255) || (b < -255 || b > 255)) {
332 fprintf(stderr, "r:%d,g:%d,b:%d (r,g,b must be 0 to 255)", r, g, b);
333 exit(1);
336 r *= 255;
337 g *= 255;
338 b *= 255;
340 if (!XParseColor(display, DefaultColormap(display, DefaultScreen(display)),
341 color_name, &color))
342 fprintf(stderr, "can't parse color %s\n", color_name), exit(1);
344 if (!XAllocColor(display, DefaultColormap(display, DefaultScreen(display)),
345 &color)) {
346 fprintf(stderr, "can't allocate color %s. Using black\n", color_name);
347 return BlackPixel(display, DefaultScreen(display));
350 if (DefaultDepth(display, DefaultScreen(display)) < 16)
351 return color.pixel;
353 /* red */
354 if (color.red + r > 0xffff)
355 color.red = 0xffff;
356 else if (color.red + r < 0)
357 color.red = 0;
358 else
359 color.red = (unsigned short)(fac * color.red + r);
361 /* green */
362 if (color.green + g > 0xffff)
363 color.green = 0xffff;
364 else if (color.green + g < 0)
365 color.green = 0;
366 else
367 color.green = (unsigned short)(fac * color.green + g);
369 /* blue */
370 if (color.blue + b > 0xffff)
371 color.blue = 0xffff;
372 else if (color.blue + b < 0)
373 color.blue = 0;
374 else
375 color.blue = (unsigned short)(fac * color.blue + b);
377 color.flags = DoRed | DoGreen | DoBlue;
379 if (!XAllocColor(display, DefaultColormap(display, DefaultScreen(display)),
380 &color)) {
381 fprintf(stderr, "can't allocate color %s. Using black\n", color_name);
382 return BlackPixel(display, DefaultScreen(display));
385 return color.pixel;