Add missing libraries to examples' Makefiles
[dockapps.git] / wmdonkeymon / wmgeneral / wmgeneral.c
blobb151fb77bc64410481c75daad27c7dbaff0b5a5a
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 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
16 * changed the read_rc_file to parse_rcfile, as suggester by Marcelo E. Magallon
17 * debugged the parse_rc file.
18 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
19 * Ripped similar code from all the wm* programs,
20 and put them in a single file.
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <ctype.h>
29 #include <stdarg.h>
31 #include <X11/Xlib.h>
32 #include <X11/xpm.h>
33 #include <X11/extensions/shape.h>
35 #include "wmgeneral.h"
37 /*****************/
38 /* X11 Variables */
39 /*****************/
41 Window Root;
42 int screen;
43 int x_fd;
44 int d_depth;
45 XSizeHints mysizehints;
46 XWMHints mywmhints;
47 Pixel back_pix, fore_pix;
48 char *Geometry = "";
49 Window iconwin, win;
50 GC NormalGC;
51 XpmIcon wmgen;
52 Pixmap pixmask;
54 /*****************/
55 /* Mouse Regions */
56 /*****************/
58 typedef struct {
59 int enable;
60 int top;
61 int bottom;
62 int left;
63 int right;
64 } MOUSE_REGION;
66 #define MAX_MOUSE_REGION (8)
67 MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
69 /***********************/
70 /* Function Prototypes */
71 /***********************/
73 static void GetXPM(XpmIcon *, char **);
74 static Pixel GetColor(char *);
75 void RedrawWindow(void);
76 void AddMouseRegion(unsigned, int, int, int, int);
77 int CheckMouseRegion(int, int);
79 /*******************************************************************************\
80 |* read_rc_file *|
81 \*******************************************************************************/
83 void parse_rcfile(const char *filename, rckeys *keys) {
85 char *p;
86 char temp[128];
87 char *tokens = " :\t\n";
88 FILE *fp;
89 int i,key;
91 fp = fopen(filename, "r");
92 if (fp) {
93 while (fgets(temp, 128, fp)) {
94 key = 0;
95 printf("read: %s\n",temp);
96 while (key >= 0 && keys[key].label) {
97 printf("key: %s\n",keys[key].label);
98 if ((p = strstr(temp, keys[key].label))) {
99 p += strlen(keys[key].label);
100 p += strspn(p, tokens);
101 if ((i = strcspn(p, "#\n"))) p[i] = 0;
102 free(*keys[key].var);
103 *keys[key].var = strdup(p);
104 key = -1;
105 } else key++;
108 fclose(fp);
113 /*******************************************************************************\
114 |* GetXPM *|
115 \*******************************************************************************/
117 static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
119 XWindowAttributes attributes;
120 int err;
122 /* For the colormap */
123 XGetWindowAttributes(display, Root, &attributes);
125 wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
127 err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
128 &(wmgen->mask), &(wmgen->attributes));
130 if (err != XpmSuccess) {
131 fprintf(stderr, "Not enough free colorcells.\n");
132 exit(1);
136 /*******************************************************************************\
137 |* GetColor *|
138 \*******************************************************************************/
140 static Pixel GetColor(char *name) {
142 XColor color;
143 XWindowAttributes attributes;
145 XGetWindowAttributes(display, Root, &attributes);
147 color.pixel = 0;
148 if (!XParseColor(display, attributes.colormap, name, &color)) {
149 fprintf(stderr, "wm.app: can't parse %s.\n", name);
150 } else if (!XAllocColor(display, attributes.colormap, &color)) {
151 fprintf(stderr, "wm.app: can't allocate %s.\n", name);
153 return color.pixel;
156 /*******************************************************************************\
157 |* flush_expose *|
158 \*******************************************************************************/
160 static int flush_expose(Window w) {
162 XEvent dummy;
163 int i=0;
165 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
166 i++;
168 return i;
171 /*******************************************************************************\
172 |* RedrawWindow *|
173 \*******************************************************************************/
175 void RedrawWindow(void) {
177 flush_expose(iconwin);
178 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
179 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
180 flush_expose(win);
181 XCopyArea(display, wmgen.pixmap, win, NormalGC,
182 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
185 /*******************************************************************************\
186 |* RedrawWindowXY *|
187 \*******************************************************************************/
189 void RedrawWindowXY(int x, int y) {
191 flush_expose(iconwin);
192 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
193 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
194 flush_expose(win);
195 XCopyArea(display, wmgen.pixmap, win, NormalGC,
196 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
199 /*******************************************************************************\
200 |* AddMouseRegion *|
201 \*******************************************************************************/
203 void AddMouseRegion(unsigned index, int left, int top, int right, int bottom) {
205 if (index < MAX_MOUSE_REGION) {
206 mouse_region[index].enable = 1;
207 mouse_region[index].top = top;
208 mouse_region[index].left = left;
209 mouse_region[index].bottom = bottom;
210 mouse_region[index].right = right;
214 /*******************************************************************************\
215 |* DelMouseRegion added for wmdonkeymon *|
216 \*******************************************************************************/
218 void DelMouseRegion(int index) {
220 if (index < MAX_MOUSE_REGION) {
221 mouse_region[index].enable = 0;
225 /*******************************************************************************\
226 |* CheckMouseRegion *|
227 \*******************************************************************************/
229 int CheckMouseRegion(int x, int y) {
231 int i;
232 int found;
234 found = 0;
236 for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
237 if (mouse_region[i].enable &&
238 x <= mouse_region[i].right &&
239 x >= mouse_region[i].left &&
240 y <= mouse_region[i].bottom &&
241 y >= mouse_region[i].top)
242 found = 1;
244 if (!found) return -1;
245 return (i-1);
248 /*******************************************************************************\
249 |* copyXPMArea *|
250 \*******************************************************************************/
252 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
254 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
258 /*******************************************************************************\
259 |* copyXBMArea *|
260 \*******************************************************************************/
262 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
264 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
268 /*******************************************************************************\
269 |* setMaskXY *|
270 \*******************************************************************************/
272 void setMaskXY(int x, int y) {
274 XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
275 XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
278 /*******************************************************************************\
279 |* openXwindow *|
280 \*******************************************************************************/
281 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
283 unsigned int borderwidth = 1;
284 XClassHint classHint;
285 char *display_name = NULL;
286 char *wname = argv[0];
287 XTextProperty name;
289 XGCValues gcv;
290 unsigned long gcm;
293 int dummy=0;
294 int i;
296 for (i=1; argv[i]; i++) {
297 if (!strcmp(argv[i], "-display"))
298 display_name = argv[i+1];
301 if (!(display = XOpenDisplay(display_name))) {
302 fprintf(stderr, "%s: can't open display %s\n",
303 wname, XDisplayName(display_name));
304 exit(1);
306 screen = DefaultScreen(display);
307 Root = RootWindow(display, screen);
308 d_depth = DefaultDepth(display, screen);
309 x_fd = XConnectionNumber(display);
311 /* Convert XPM to XImage */
312 GetXPM(&wmgen, pixmap_bytes);
314 /* Create a window to hold the stuff */
315 mysizehints.flags = USSize | USPosition;
316 mysizehints.x = 0;
317 mysizehints.y = 0;
319 back_pix = GetColor("white");
320 fore_pix = GetColor("black");
322 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
323 &mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
325 mysizehints.width = 64;
326 mysizehints.height = 64;
328 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
329 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
331 iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
332 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
334 /* Activate hints */
335 XSetWMNormalHints(display, win, &mysizehints);
336 classHint.res_name = wname;
337 classHint.res_class = wname;
338 XSetClassHint(display, win, &classHint);
340 XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
341 XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
343 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
344 fprintf(stderr, "%s: can't allocate window name\n", wname);
345 exit(1);
348 XSetWMName(display, win, &name);
350 /* Create GC for drawing */
352 gcm = GCForeground | GCBackground | GCGraphicsExposures;
353 gcv.foreground = fore_pix;
354 gcv.background = back_pix;
355 gcv.graphics_exposures = 0;
356 NormalGC = XCreateGC(display, Root, gcm, &gcv);
358 /* ONLYSHAPE ON */
360 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
362 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
363 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
365 /* ONLYSHAPE OFF */
367 mywmhints.initial_state = WithdrawnState;
368 mywmhints.icon_window = iconwin;
369 mywmhints.icon_x = mysizehints.x;
370 mywmhints.icon_y = mysizehints.y;
371 mywmhints.window_group = win;
372 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
374 XSetWMHints(display, win, &mywmhints);
376 XSetCommand(display, win, argv, argc);
377 XMapWindow(display, win);