wmmon: Code style clean.
[dockapps.git] / wmppp.app / wmgeneral / wmgeneral.c
blobc9c7446f0e6b724ad690895cc62fa9f6ad991959
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 11/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
16 * Removed a bug from parse_rcfile. You could
17 not use "start" in a command if a label was
18 also start.
19 * Changed the needed geometry string.
20 We don't use window size, and don't support
21 negative positions.
22 03/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
23 * Added parse_rcfile2
24 02/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
25 * Added -geometry support (untested)
26 28/08/1998 (Martijn Pieterse, pieterse@xs4all.nl)
27 * Added createXBMfromXPM routine
28 * Saves a lot of work with changing xpm's.
29 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
30 * changed the read_rc_file to parse_rcfile, as suggested by Marcelo E. Magallon
31 * debugged the parse_rc file.
32 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
33 * Ripped similar code from all the wm* programs,
34 and put them in a single file.
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <ctype.h>
43 #include <stdarg.h>
45 #include <X11/Xlib.h>
46 #include <X11/xpm.h>
47 #include <X11/extensions/shape.h>
49 #include "wmgeneral.h"
51 /*****************/
52 /* X11 Variables */
53 /*****************/
55 Window Root;
56 int screen;
57 int x_fd;
58 int d_depth;
59 XSizeHints mysizehints;
60 XWMHints mywmhints;
61 Pixel back_pix, fore_pix;
62 char *Geometry = "";
63 Window iconwin, win;
64 GC NormalGC;
65 XpmIcon wmgen;
66 Pixmap pixmask;
68 /*****************/
69 /* Mouse Regions */
70 /*****************/
72 typedef struct {
73 int enable;
74 int top;
75 int bottom;
76 int left;
77 int right;
78 } MOUSE_REGION;
80 MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
82 /***********************/
83 /* Function Prototypes */
84 /***********************/
86 static void GetXPM(XpmIcon *, char **);
87 static Pixel GetColor(char *);
88 void RedrawWindow(void);
89 void AddMouseRegion(int, int, int, int, int);
90 int CheckMouseRegion(int, int);
92 /*******************************************************************************\
93 |* parse_rcfile *|
94 \*******************************************************************************/
96 void parse_rcfile(const char *filename, rckeys *keys) {
98 char *p,*q;
99 char temp[128];
100 char *tokens = " :\t\n";
101 FILE *fp;
102 int i,key;
104 fp = fopen(filename, "r");
105 if (fp) {
106 while (fgets(temp, 128, fp)) {
107 key = 0;
108 q = strdup(temp);
109 q = strtok(q, tokens);
110 while (key >= 0 && keys[key].label) {
111 if ((!strcmp(q, keys[key].label))) {
112 p = strstr(temp, keys[key].label);
113 p += strlen(keys[key].label);
114 p += strspn(p, tokens);
115 if ((i = strcspn(p, "#\n"))) p[i] = 0;
116 free(*keys[key].var);
117 *keys[key].var = strdup(p);
118 key = -1;
119 } else key++;
121 free(q);
123 fclose(fp);
127 /*******************************************************************************\
128 |* parse_rcfile2 *|
129 \*******************************************************************************/
131 void parse_rcfile2(const char *filename, rckeys2 *keys) {
133 char *p;
134 char temp[128];
135 char *tokens = " :\t\n";
136 FILE *fp;
137 int i,key;
138 char *family = NULL;
140 fp = fopen(filename, "r");
141 if (fp) {
142 while (fgets(temp, 128, fp)) {
143 key = 0;
144 while (key >= 0 && keys[key].label) {
145 if ((p = strstr(temp, keys[key].label))) {
146 p += strlen(keys[key].label);
147 p += strspn(p, tokens);
148 if ((i = strcspn(p, "#\n"))) p[i] = 0;
149 free(*keys[key].var);
150 *keys[key].var = strdup(p);
151 key = -1;
152 } else key++;
155 fclose(fp);
157 free(family);
161 /*******************************************************************************\
162 |* GetXPM *|
163 \*******************************************************************************/
165 static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
167 XWindowAttributes attributes;
168 int err;
170 /* For the colormap */
171 XGetWindowAttributes(display, Root, &attributes);
173 wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
175 err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
176 &(wmgen->mask), &(wmgen->attributes));
178 if (err != XpmSuccess) {
179 fprintf(stderr, "Not enough free colorcells.\n");
180 exit(1);
184 /*******************************************************************************\
185 |* GetColor *|
186 \*******************************************************************************/
188 static Pixel GetColor(char *name) {
190 XColor color;
191 XWindowAttributes attributes;
193 XGetWindowAttributes(display, Root, &attributes);
195 color.pixel = 0;
196 if (!XParseColor(display, attributes.colormap, name, &color)) {
197 fprintf(stderr, "wm.app: can't parse %s.\n", name);
198 } else if (!XAllocColor(display, attributes.colormap, &color)) {
199 fprintf(stderr, "wm.app: can't allocate %s.\n", name);
201 return color.pixel;
204 /*******************************************************************************\
205 |* flush_expose *|
206 \*******************************************************************************/
208 static int flush_expose(Window w) {
210 XEvent dummy;
211 int i=0;
213 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
214 i++;
216 return i;
219 /*******************************************************************************\
220 |* RedrawWindow *|
221 \*******************************************************************************/
223 void RedrawWindow(void) {
225 flush_expose(iconwin);
226 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
227 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
228 flush_expose(win);
229 XCopyArea(display, wmgen.pixmap, win, NormalGC,
230 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
233 /*******************************************************************************\
234 |* RedrawWindowXY *|
235 \*******************************************************************************/
237 void RedrawWindowXY(int x, int y) {
239 flush_expose(iconwin);
240 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
241 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
242 flush_expose(win);
243 XCopyArea(display, wmgen.pixmap, win, NormalGC,
244 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
247 /*******************************************************************************\
248 |* AddMouseRegion *|
249 \*******************************************************************************/
251 void AddMouseRegion(int index, int left, int top, int right, int bottom) {
253 if (index < MAX_MOUSE_REGION) {
254 mouse_region[index].enable = 1;
255 mouse_region[index].top = top;
256 mouse_region[index].left = left;
257 mouse_region[index].bottom = bottom;
258 mouse_region[index].right = right;
262 /*******************************************************************************\
263 |* CheckMouseRegion *|
264 \*******************************************************************************/
266 int CheckMouseRegion(int x, int y) {
268 int i;
269 int found;
271 found = 0;
273 for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
274 if (mouse_region[i].enable &&
275 x <= mouse_region[i].right &&
276 x >= mouse_region[i].left &&
277 y <= mouse_region[i].bottom &&
278 y >= mouse_region[i].top)
279 found = 1;
281 if (!found) return -1;
282 return (i-1);
285 /*******************************************************************************\
286 |* createXBMfromXPM *|
287 \*******************************************************************************/
288 void createXBMfromXPM(char *xbm, char **xpm, int sx, int sy) {
290 int i,j;
291 int width, height, numcol;
292 char zero;
293 unsigned char bwrite;
294 int bcount;
297 sscanf(*xpm, "%d %d %d", &width, &height, &numcol);
299 zero = xpm[1][0];
300 for (i=numcol+1; i < numcol+sy+1; i++) {
301 bcount = 0;
302 bwrite = 0;
303 for (j=0; j<sx; j++) {
304 bwrite >>= 1;
305 if (xpm[i][j] != zero) {
306 bwrite += 128;
308 bcount++;
309 if (bcount == 8) {
310 *xbm = bwrite;
311 xbm++;
312 bcount = 0;
313 bwrite = 0;
319 /*******************************************************************************\
320 |* copyXPMArea *|
321 \*******************************************************************************/
323 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
325 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
329 /*******************************************************************************\
330 |* copyXBMArea *|
331 \*******************************************************************************/
333 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
335 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
339 /*******************************************************************************\
340 |* setMaskXY *|
341 \*******************************************************************************/
343 void setMaskXY(int x, int y) {
345 XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
346 XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
349 /*******************************************************************************\
350 |* openXwindow *|
351 \*******************************************************************************/
352 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
354 unsigned int borderwidth = 1;
355 XClassHint classHint;
356 char *display_name = NULL;
357 char *wname = argv[0];
358 XTextProperty name;
360 XGCValues gcv;
361 unsigned long gcm;
363 char *geometry = NULL;
365 int dummy=0;
366 int i, wx, wy;
368 for (i=1; argv[i]; i++) {
369 if (!strcmp(argv[i], "-display")) {
370 display_name = argv[i+1];
371 i++;
373 if (!strcmp(argv[i], "-geometry")) {
374 geometry = argv[i+1];
375 i++;
379 if (!(display = XOpenDisplay(display_name))) {
380 fprintf(stderr, "%s: can't open display %s\n",
381 wname, XDisplayName(display_name));
382 exit(1);
384 screen = DefaultScreen(display);
385 Root = RootWindow(display, screen);
386 d_depth = DefaultDepth(display, screen);
387 x_fd = XConnectionNumber(display);
389 /* Convert XPM to XImage */
390 GetXPM(&wmgen, pixmap_bytes);
392 /* Create a window to hold the stuff */
393 mysizehints.flags = USSize | USPosition;
394 mysizehints.x = 0;
395 mysizehints.y = 0;
397 back_pix = GetColor("white");
398 fore_pix = GetColor("black");
400 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
401 &mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
403 mysizehints.width = 64;
404 mysizehints.height = 64;
406 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
407 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
409 iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
410 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
412 /* Activate hints */
413 XSetWMNormalHints(display, win, &mysizehints);
414 classHint.res_name = wname;
415 classHint.res_class = wname;
416 XSetClassHint(display, win, &classHint);
418 XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
419 XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
421 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
422 fprintf(stderr, "%s: can't allocate window name\n", wname);
423 exit(1);
426 XSetWMName(display, win, &name);
428 /* Create GC for drawing */
430 gcm = GCForeground | GCBackground | GCGraphicsExposures;
431 gcv.foreground = fore_pix;
432 gcv.background = back_pix;
433 gcv.graphics_exposures = 0;
434 NormalGC = XCreateGC(display, Root, gcm, &gcv);
436 /* ONLYSHAPE ON */
438 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
440 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
441 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
443 /* ONLYSHAPE OFF */
445 mywmhints.initial_state = WithdrawnState;
446 mywmhints.icon_window = iconwin;
447 mywmhints.icon_x = mysizehints.x;
448 mywmhints.icon_y = mysizehints.y;
449 mywmhints.window_group = win;
450 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
452 XSetWMHints(display, win, &mywmhints);
454 XSetCommand(display, win, argv, argc);
455 XMapWindow(display, win);
457 if (geometry) {
458 if (sscanf(geometry, "+%d+%d", &wx, &wy) != 2) {
459 fprintf(stderr, "Bad geometry string.\n");
460 exit(1);
462 XMoveWindow(display, win, wx, wy);