wmtictactoe: Add version 1.1 to repository.
[dockapps.git] / wmtictactoe / wmgeneral / wmgeneral.c~
blob2dac8b4b7c5638b45275d0038b66a0db79397d8f
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 int                     screen;
59 int                     x_fd;
60 int                     d_depth;
61 XSizeHints      mysizehints;
62 XWMHints        mywmhints;
63 Pixel           back_pix, fore_pix;
64 char            *Geometry = "";
65 GC                      NormalGC;
66 XpmIcon         wmgen;
67 Pixmap          pixmask;
69   /*****************/
70  /* Mouse Regions */
71 /*****************/
73 typedef struct {
74         int             enable;
75         int             top;
76         int             bottom;
77         int             left;
78         int             right;
79 } MOUSE_REGION;
81 MOUSE_REGION    mouse_region[MAX_MOUSE_REGION];
83   /***********************/
84  /* Function Prototypes */
85 /***********************/
87 static void GetXPM(XpmIcon *, char **);
88 static Pixel GetColor(char *);
89 void RedrawWindow(void);
90 void AddMouseRegion(int, int, int, int, int);
91 int CheckMouseRegion(int, int);
93 /*******************************************************************************\
94 |* parse_rcfile                                                                                                                            *|
95 \*******************************************************************************/
97 void parse_rcfile(const char *filename, rckeys *keys) {
99         char    *p,*q;
100         char    temp[128];
101         char    *tokens = " :\t\n";
102         FILE    *fp;
103         int             i,key;
105         fp = fopen(filename, "r");
106         if (fp) {
107                 while (fgets(temp, 128, fp)) {
108                         key = 0;
109                         q = strdup(temp);
110                         q = strtok(q, tokens);
111                         while (key >= 0 && keys[key].label) {
112                                 if ((!strcmp(q, keys[key].label))) {
113                                         p = strstr(temp, keys[key].label);
114                                         p += strlen(keys[key].label);
115                                         p += strspn(p, tokens);
116                                         if ((i = strcspn(p, "#\n"))) p[i] = 0;
117                                         free(*keys[key].var);
118                                         *keys[key].var = strdup(p);
119                                         key = -1;
120                                 } else key++;
121                         }
122                         free(q);
123                 }
124                 fclose(fp);
125         }
128 /*******************************************************************************\
129 |* parse_rcfile2                                                                                                                           *|
130 \*******************************************************************************/
132 void parse_rcfile2(const char *filename, rckeys2 *keys) {
134         char    *p;
135         char    temp[128];
136         char    *tokens = " :\t\n";
137         FILE    *fp;
138         int             i,key;
139         char    *family = NULL;
141         fp = fopen(filename, "r");
142         if (fp) {
143                 while (fgets(temp, 128, fp)) {
144                         key = 0;
145                         while (key >= 0 && keys[key].label) {
146                                 if ((p = strstr(temp, keys[key].label))) {
147                                         p += strlen(keys[key].label);
148                                         p += strspn(p, tokens);
149                                         if ((i = strcspn(p, "#\n"))) p[i] = 0;
150                                         free(*keys[key].var);
151                                         *keys[key].var = strdup(p);
152                                         key = -1;
153                                 } else key++;
154                         }
155                 }
156                 fclose(fp);
157         }
158         free(family);
162 /*******************************************************************************\
163 |* GetXPM                                                                                                                                          *|
164 \*******************************************************************************/
166 static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
168         XWindowAttributes       attributes;
169         int                                     err;
171         /* For the colormap */
172         XGetWindowAttributes(display, Root, &attributes);
174         wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
176         err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
177                                         &(wmgen->mask), &(wmgen->attributes));
178         
179         if (err != XpmSuccess) {
180                 fprintf(stderr, "Not enough free colorcells.\n");
181                 exit(1);
182         }
185 /*******************************************************************************\
186 |* GetColor                                                                                                                                        *|
187 \*******************************************************************************/
189 static Pixel GetColor(char *name) {
191         XColor                          color;
192         XWindowAttributes       attributes;
194         XGetWindowAttributes(display, Root, &attributes);
196         color.pixel = 0;
197         if (!XParseColor(display, attributes.colormap, name, &color)) {
198                 fprintf(stderr, "wm.app: can't parse %s.\n", name);
199         } else if (!XAllocColor(display, attributes.colormap, &color)) {
200                 fprintf(stderr, "wm.app: can't allocate %s.\n", name);
201         }
202         return color.pixel;
205 /*******************************************************************************\
206 |* flush_expose                                                                                                                            *|
207 \*******************************************************************************/
209 static int flush_expose(Window w) {
211         XEvent          dummy;
212         int                     i=0;
214         while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
215                 i++;
217         return i;
220 /*******************************************************************************\
221 |* RedrawWindow                                                                                                                            *|
222 \*******************************************************************************/
224 void RedrawWindow(void) {
225         
226         flush_expose(iconwin);
227         XCopyArea(display, wmgen.pixmap, iconwin, NormalGC, 
228                                 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
229         flush_expose(win);
230         XCopyArea(display, wmgen.pixmap, win, NormalGC,
231                                 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
234 /*******************************************************************************\
235 |* RedrawWindowXY                                                                                                                          *|
236 \*******************************************************************************/
238 void RedrawWindowXY(int x, int y) {
239         
240         flush_expose(iconwin);
241         XCopyArea(display, wmgen.pixmap, iconwin, NormalGC, 
242                                 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
243         flush_expose(win);
244         XCopyArea(display, wmgen.pixmap, win, NormalGC,
245                                 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
248 /*******************************************************************************\
249 |* AddMouseRegion                                                                                                                          *|
250 \*******************************************************************************/
252 void AddMouseRegion(int index, int left, int top, int right, int bottom) {
254         if (index < MAX_MOUSE_REGION) {
255                 mouse_region[index].enable = 1;
256                 mouse_region[index].top = top;
257                 mouse_region[index].left = left;
258                 mouse_region[index].bottom = bottom;
259                 mouse_region[index].right = right;
260         }
263 /*******************************************************************************\
264 |* CheckMouseRegion                                                                                                                        *|
265 \*******************************************************************************/
267 int CheckMouseRegion(int x, int y) {
269         int             i;
270         int             found;
272         found = 0;
274         for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
275                 if (mouse_region[i].enable &&
276                         x <= mouse_region[i].right &&
277                         x >= mouse_region[i].left &&
278                         y <= mouse_region[i].bottom &&
279                         y >= mouse_region[i].top)
280                         found = 1;
281         }
282         if (!found) return -1;
283         return (i-1);
286 /*******************************************************************************\
287 |* createXBMfromXPM                                                                                                                        *|
288 \*******************************************************************************/
289 void createXBMfromXPM(char *xbm, char **xpm, int sx, int sy) {
291         int             i,j,k;
292         int             width, height, numcol, depth;
293     int         zero=0;
294         unsigned char   bwrite;
295     int         bcount;
296     int     curpixel;
297         
298         sscanf(*xpm, "%d %d %d %d", &width, &height, &numcol, &depth);
301     for (k=0; k!=depth; k++)
302     {
303         zero <<=8;
304         zero |= xpm[1][k];
305     }
306         
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             {
316                 curpixel <<=8;
317                 curpixel |= xpm[i][j+k];
318             }
319                 
320             if ( curpixel != zero ) {
321                                 bwrite += 128;
322                         }
323                         bcount++;
324                         if (bcount == 8) {
325                                 *xbm = bwrite;
326                                 xbm++;
327                                 bcount = 0;
328                                 bwrite = 0;
329                         }
330                 }
331         }
334 /*******************************************************************************\
335 |* copyXPMArea                                                                                                                             *|
336 \*******************************************************************************/
338 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
340         XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
344 /*******************************************************************************\
345 |* copyXBMArea                                                                                                                             *|
346 \*******************************************************************************/
348 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
350         XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
354 /*******************************************************************************\
355 |* setMaskXY                                                                                                                               *|
356 \*******************************************************************************/
358 void setMaskXY(int x, int y) {
360          XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
361          XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
364 /*******************************************************************************\
365 |* openXwindow                                                                                                                             *|
366 \*******************************************************************************/
367 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
369         unsigned int    borderwidth = 1;
370         XClassHint              classHint;
371         char                    *display_name = NULL;
372         char                    *wname = argv[0];
373         XTextProperty   name;
375         XGCValues               gcv;
376         unsigned long   gcm;
378         char                    *geometry = NULL;
380         int                             dummy=0;
381         int                             i, wx, wy;
383         for (i=1; argv[i]; i++) {
384                 if (!strcmp(argv[i], "-display")) {
385                         display_name = argv[i+1];
386                         i++;
387                 }
388                 if (!strcmp(argv[i], "-geometry")) {
389                         geometry = argv[i+1];
390                         i++;
391                 }
392         }
394         if (!(display = XOpenDisplay(display_name))) {
395                 fprintf(stderr, "%s: can't open display %s\n", 
396                                                 wname, XDisplayName(display_name));
397                 exit(1);
398         }
399         screen  = DefaultScreen(display);
400         Root    = RootWindow(display, screen);
401         d_depth = DefaultDepth(display, screen);
402         x_fd    = XConnectionNumber(display);
404         /* Convert XPM to XImage */
405         GetXPM(&wmgen, pixmap_bytes);
407         /* Create a window to hold the stuff */
408         mysizehints.flags = USSize | USPosition;
409         mysizehints.x = 0;
410         mysizehints.y = 0;
412         back_pix = GetColor("white");
413         fore_pix = GetColor("black");
415         XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
416                                 &mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
418         mysizehints.width = 64;
419         mysizehints.height = 64;
420                 
421         win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
422                                 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
423         
424         iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
425                                 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
427         /* Activate hints */
428         XSetWMNormalHints(display, win, &mysizehints);
429         classHint.res_name = wname;
430         classHint.res_class = wname;
431         XSetClassHint(display, win, &classHint);
433         XSelectInput(display, win, ButtonPressMask | ExposureMask /*| ButtonReleaseMask | PointerMotionMask*/ | StructureNotifyMask);
434         XSelectInput(display, iconwin, ButtonPressMask | ExposureMask /*| ButtonReleaseMask | PointerMotionMask */ | StructureNotifyMask);
436         if (XStringListToTextProperty(&wname, 1, &name) == 0) {
437                 fprintf(stderr, "%s: can't allocate window name\n", wname);
438                 exit(1);
439         }
441         XSetWMName(display, win, &name);
443         /* Create GC for drawing */
444         
445         gcm = GCForeground | GCBackground | GCGraphicsExposures;
446         gcv.foreground = fore_pix;
447         gcv.background = back_pix;
448         gcv.graphics_exposures = 0;
449         NormalGC = XCreateGC(display, Root, gcm, &gcv);
451         /* ONLYSHAPE ON */
453         pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
455         XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
456         XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
458         /* ONLYSHAPE OFF */
460         mywmhints.initial_state = WithdrawnState;
461         mywmhints.icon_window = iconwin;
462         mywmhints.icon_x = mysizehints.x;
463         mywmhints.icon_y = mysizehints.y;
464         mywmhints.window_group = win;
465         mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
467         XSetWMHints(display, win, &mywmhints);
469         XSetCommand(display, win, argv, argc);
470         XMapWindow(display, win);
472         if (geometry) {
473                 if (sscanf(geometry, "+%d+%d", &wx, &wy) != 2) {
474                         fprintf(stderr, "Bad geometry string.\n");
475                         exit(1);
476                 }
477                 XMoveWindow(display, win, wx, wy);
478         }