wmSMPmon: Code formating cleanup
[dockapps.git] / wmSMPmon / wmgeneral / wmgeneral.c
blob13caa7b7df099b0a7b34d810ed4496bb13bf5436
1 /*
2 Best viewed with vim5, using ts=4
4 wmgeneral was taken from wmppp.
6 It has a lot of routines which most of the wm* programs use.
8 ------------------------------------------------------------
10 Author: Martijn Pieterse (pieterse@xs4all.nl)
12 ---
13 CHANGES:
14 ---
15 14/09/1998 (Dave Clark, clarkd@skyia.com)
16 * Updated createXBMfromXPM routine
17 * Now supports >256 colors
18 11/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
19 * Removed a bug from parse_rcfile. You could
20 not use "start" in a command if a label was
21 also start.
22 * Changed the needed geometry string.
23 We don't use window size, and don't support
24 negative positions.
25 03/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
26 * Added parse_rcfile2
27 02/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
28 * Added -geometry support (untested)
29 28/08/1998 (Martijn Pieterse, pieterse@xs4all.nl)
30 * Added createXBMfromXPM routine
31 * Saves a lot of work with changing xpm's.
32 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
33 * changed the read_rc_file to parse_rcfile, as suggested by Marcelo E. Magallon
34 * debugged the parse_rc file.
35 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
36 * Ripped similar code from all the wm* programs,
37 and put them in a single file.
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <unistd.h>
45 #include <ctype.h>
46 #include <stdarg.h>
48 #include <X11/Xlib.h>
49 #include <X11/xpm.h>
50 #include <X11/extensions/shape.h>
52 #include "wmgeneral.h"
54 /*****************/
55 /* X11 Variables */
56 /*****************/
58 Window Root;
59 int screen;
60 int x_fd;
61 int d_depth;
62 XSizeHints mysizehints;
63 XWMHints mywmhints;
64 Pixel back_pix, fore_pix;
65 char *Geometry = "";
66 Window iconwin, win;
67 GC NormalGC;
68 XpmIcon wmgen;
69 Pixmap pixmask;
71 /*****************/
72 /* Mouse Regions */
73 /*****************/
75 typedef struct {
76 int enable;
77 int top;
78 int bottom;
79 int left;
80 int right;
81 } MOUSE_REGION;
83 MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
85 /***********************/
86 /* Function Prototypes */
87 /***********************/
89 static void GetXPM(XpmIcon *, char **);
90 static Pixel GetColor(char *);
91 void RedrawWindow(void);
92 void AddMouseRegion(int, int, int, int, int);
93 int CheckMouseRegion(int, int);
95 /*****************************************************************************\
96 |* parse_rcfile *|
97 \*****************************************************************************/
99 void parse_rcfile(const char *filename, rckeys *keys) {
101 char *p,*q;
102 char temp[128];
103 char *tokens = " :\t\n";
104 FILE *fp;
105 int i,key;
107 fp = fopen(filename, "r");
108 if (fp) {
109 while (fgets(temp, 128, fp)) {
110 key = 0;
111 q = strdup(temp);
112 q = strtok(q, tokens);
113 while (key >= 0 && keys[key].label) {
114 if ((!strcmp(q, keys[key].label))) {
115 p = strstr(temp, keys[key].label);
116 p += strlen(keys[key].label);
117 p += strspn(p, tokens);
118 if ((i = strcspn(p, "#\n"))) p[i] = 0;
119 free(*keys[key].var);
120 *keys[key].var = strdup(p);
121 key = -1;
122 } else key++;
124 free(q);
126 fclose(fp);
130 /***************************************************************************\
131 |* parse_rcfile2 *|
132 \***************************************************************************/
134 void parse_rcfile2(const char *filename, rckeys2 *keys) {
136 char *p;
137 char temp[128];
138 char *tokens = " :\t\n";
139 FILE *fp;
140 int i,key;
141 char *family = NULL;
143 fp = fopen(filename, "r");
144 if (fp) {
145 while (fgets(temp, 128, fp)) {
146 key = 0;
147 while (key >= 0 && keys[key].label) {
148 if ((p = strstr(temp, keys[key].label))) {
149 p += strlen(keys[key].label);
150 p += strspn(p, tokens);
151 if ((i = strcspn(p, "#\n"))) p[i] = 0;
152 free(*keys[key].var);
153 *keys[key].var = strdup(p);
154 key = -1;
155 } else key++;
158 fclose(fp);
160 free(family);
164 /***************************************************************************\
165 |* GetXPM *|
166 \***************************************************************************/
168 static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
170 XWindowAttributes attributes;
171 int err;
173 /* For the colormap */
174 XGetWindowAttributes(display, Root, &attributes);
176 wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
178 err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
179 &(wmgen->mask), &(wmgen->attributes));
181 if (err != XpmSuccess) {
182 fprintf(stderr, "Not enough free colorcells.\n");
183 exit(1);
187 /***************************************************************************\
188 |* GetColor *|
189 \***************************************************************************/
191 static Pixel GetColor(char *name) {
193 XColor color;
194 XWindowAttributes attributes;
196 XGetWindowAttributes(display, Root, &attributes);
198 color.pixel = 0;
199 if (!XParseColor(display, attributes.colormap, name, &color)) {
200 fprintf(stderr, "wm.app: can't parse %s.\n", name);
201 } else if (!XAllocColor(display, attributes.colormap, &color)) {
202 fprintf(stderr, "wm.app: can't allocate %s.\n", name);
204 return color.pixel;
207 /***************************************************************************\
208 |* flush_expose *|
209 \***************************************************************************/
211 static int flush_expose(Window w) {
213 XEvent dummy;
214 int i=0;
216 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
217 i++;
219 return i;
222 /***************************************************************************\
223 |* RedrawWindow *|
224 \***************************************************************************/
226 void RedrawWindow(void) {
228 flush_expose(iconwin);
229 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
230 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
231 flush_expose(win);
232 XCopyArea(display, wmgen.pixmap, win, NormalGC,
233 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
236 /***************************************************************************\
237 |* RedrawWindowXY *|
238 \***************************************************************************/
240 void RedrawWindowXY(int x, int y) {
242 flush_expose(iconwin);
243 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
244 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
245 flush_expose(win);
246 XCopyArea(display, wmgen.pixmap, win, NormalGC,
247 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
250 /***************************************************************************\
251 |* AddMouseRegion *|
252 \***************************************************************************/
254 void AddMouseRegion(int index, int left, int top, int right, int bottom) {
256 if (index < MAX_MOUSE_REGION) {
257 mouse_region[index].enable = 1;
258 mouse_region[index].top = top;
259 mouse_region[index].left = left;
260 mouse_region[index].bottom = bottom;
261 mouse_region[index].right = right;
265 /***************************************************************************\
266 |* CheckMouseRegion *|
267 \***************************************************************************/
269 int CheckMouseRegion(int x, int y) {
271 int i;
272 int found;
274 found = 0;
276 for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
277 if (mouse_region[i].enable &&
278 x <= mouse_region[i].right &&
279 x >= mouse_region[i].left &&
280 y <= mouse_region[i].bottom &&
281 y >= mouse_region[i].top)
282 found = 1;
284 if (!found) return -1;
285 return (i-1);
288 /***************************************************************************\
289 |* createXBMfromXPM *|
290 \***************************************************************************/
291 void createXBMfromXPM(char *xbm, char **xpm, int sx, int sy) {
293 int i,j,k;
294 int width, height, numcol, depth;
295 int zero = 0;
296 unsigned char bwrite;
297 int bcount;
298 int curpixel;
300 sscanf(*xpm, "%d %d %d %d", &width, &height, &numcol, &depth);
302 for (k = 0; k != depth; k++) {
303 zero <<=8;
304 zero |= xpm[1][k];
307 for (i = numcol + 1; i < numcol + sy + 1; i++) {
308 bcount = 0;
309 bwrite = 0;
310 for (j = 0; j < sx * depth; j += depth) {
311 bwrite >>= 1;
313 curpixel=0;
314 for (k = 0; k != depth; k++) {
315 curpixel <<=8;
316 curpixel |= xpm[i][j+k];
319 if (curpixel != zero) {
320 bwrite += 128;
322 bcount++;
323 if (bcount == 8) {
324 *xbm = bwrite;
325 xbm++;
326 bcount = 0;
327 bwrite = 0;
333 /***************************************************************************\
334 |* copyXPMArea *|
335 |* *|
336 |* copies pixel area from master XPM to application window *|
337 |* *|
338 |* x,y: first corner of area to be copied from master XPM *|
339 |* sx,sy: second corner of area to be copied from master XPM *|
340 |* dx,dy: first corner of target area *|
341 \***************************************************************************/
343 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy)
345 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC,
346 x, y, sx, sy, dx, dy);
349 /***************************************************************************\
350 |* copyXBMArea *|
351 |* *|
352 |* copies pixel area from XBM to master XPM?!?!? *|
353 |* *|
354 |* x,y: first corner of area to be copied from XBM *|
355 |* sx,sy: width and height of area to be copied from XBM *|
356 |* dx,dy: first corner of target area *|
357 \***************************************************************************/
359 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy)
361 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC,
362 x, y, sx, sy, dx, dy);
366 /***************************************************************************\
367 |* setMaskXY *|
368 \***************************************************************************/
370 void setMaskXY(int x, int y)
372 XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
373 XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
376 /***************************************************************************\
377 |* openXwindow *|
378 \***************************************************************************/
379 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
381 unsigned int borderwidth = 1;
382 XClassHint classHint;
383 char *display_name = NULL;
384 char *wname = argv[0];
385 XTextProperty name;
387 XGCValues gcv;
388 unsigned long gcm;
390 char *geometry = NULL;
392 int dummy=0;
393 int i, wx, wy;
395 for (i = 1; argv[i]; i++) {
396 if (!strcmp(argv[i], "-display")) {
397 display_name = argv[i+1];
398 i++;
400 if (!strcmp(argv[i], "-geometry")) {
401 geometry = argv[i+1];
402 i++;
406 if (!(display = XOpenDisplay(display_name))) {
407 fprintf(stderr, "%s: can't open display %s\n",
408 wname, XDisplayName(display_name));
409 exit(1);
411 screen = DefaultScreen(display);
412 Root = RootWindow(display, screen);
413 d_depth = DefaultDepth(display, screen);
414 x_fd = XConnectionNumber(display);
416 /* Convert XPM to XImage */
417 GetXPM(&wmgen, pixmap_bytes);
419 /* Create a window to hold the stuff */
420 mysizehints.flags = USSize | USPosition;
421 mysizehints.x = 0;
422 mysizehints.y = 0;
424 back_pix = GetColor("white");
425 fore_pix = GetColor("black");
427 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
428 &mysizehints.x, &mysizehints.y, &mysizehints.width,
429 &mysizehints.height, &dummy);
431 mysizehints.width = 64;
432 mysizehints.height = 64;
434 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
435 mysizehints.width, mysizehints.height, borderwidth,
436 fore_pix, back_pix);
438 iconwin = XCreateSimpleWindow(display, win,
439 mysizehints.x, mysizehints.y, mysizehints.width, mysizehints.height,
440 borderwidth, fore_pix, back_pix);
442 /* Activate hints */
443 XSetWMNormalHints(display, win, &mysizehints);
444 classHint.res_name = wname;
445 classHint.res_class = wname;
446 XSetClassHint(display, win, &classHint);
448 XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
449 XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
451 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
452 fprintf(stderr, "%s: can't allocate window name\n", wname);
453 exit(1);
456 XSetWMName(display, win, &name);
458 /* Create GC for drawing */
460 gcm = GCForeground | GCBackground | GCGraphicsExposures;
461 gcv.foreground = fore_pix;
462 gcv.background = back_pix;
463 gcv.graphics_exposures = 0;
464 NormalGC = XCreateGC(display, Root, gcm, &gcv);
466 /* ONLYSHAPE ON */
468 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
470 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
471 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
473 /* ONLYSHAPE OFF */
475 mywmhints.initial_state = WithdrawnState;
476 mywmhints.icon_window = iconwin;
477 mywmhints.icon_x = mysizehints.x;
478 mywmhints.icon_y = mysizehints.y;
479 mywmhints.window_group = win;
480 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
482 XSetWMHints(display, win, &mywmhints);
484 XSetCommand(display, win, argv, argc);
485 XMapWindow(display, win);
487 if (geometry) {
488 if (sscanf(geometry, "+%d+%d", &wx, &wy) != 2) {
489 fprintf(stderr, "Bad geometry string.\n");
490 exit(1);
492 XMoveWindow(display, win, wx, wy);