wmtictactoe: Add version 1.1 to repository.
[dockapps.git] / wmtictactoe / wmgeneral / wmgeneral.c
bloba558a1f9b44a1eae4911d3fef0f915da8a3a440b
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++;
122 free(q);
124 fclose(fp);
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++;
156 fclose(fp);
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));
179 if (err != XpmSuccess) {
180 fprintf(stderr, "Not enough free colorcells.\n");
181 exit(1);
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);
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) {
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) {
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;
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;
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;
298 sscanf(*xpm, "%d %d %d %d", &width, &height, &numcol, &depth);
301 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++)
316 curpixel <<=8;
317 curpixel |= xpm[i][j+k];
320 if ( curpixel != zero ) {
321 bwrite += 128;
323 bcount++;
324 if (bcount == 8) {
325 *xbm = bwrite;
326 xbm++;
327 bcount = 0;
328 bwrite = 0;
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++;
388 if (!strcmp(argv[i], "-geometry")) {
389 geometry = argv[i+1];
390 i++;
394 if (!(display = XOpenDisplay(display_name))) {
395 fprintf(stderr, "%s: can't open display %s\n",
396 wname, XDisplayName(display_name));
397 exit(1);
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;
421 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
422 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
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);
441 XSetWMName(display, win, &name);
443 /* Create GC for drawing */
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);
477 XMoveWindow(display, win, wx, wy);