Remove trailing whitespace.
[dockapps.git] / wmtime / wmgeneral / wmgeneral.c
blob7e3b5087b39d56cd03614e6dbb392df065d58ebc
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 10/10/2003 (Simon Law, sfllaw@debian.org)
16 * changed the parse_rcfile function to use getline instead of fgets.
17 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
18 * changed the read_rc_file to parse_rcfile, as suggester by Marcelo E. Magallon
19 * debugged the parse_rc file.
20 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
21 * Ripped similar code from all the wm* programs,
22 and put them in a single file.
26 #define _GNU_SOURCE
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <ctype.h>
32 #include <stdarg.h>
34 #include <X11/Xlib.h>
35 #include <X11/xpm.h>
36 #include <X11/extensions/shape.h>
38 #include "wmgeneral.h"
40 /*****************/
41 /* X11 Variables */
42 /*****************/
44 Window Root;
45 int screen;
46 int x_fd;
47 int d_depth;
48 XSizeHints mysizehints;
49 /* Deal with strange X11 function prototyping...
50 * If I don't do this, I will get warnings about the sign
51 * of the width/height variables - which are thrown away anyway. */
52 int dummy_int_width, dummy_int_height;
53 unsigned int uint_width, uint_height;
54 XWMHints mywmhints;
55 Pixel back_pix, fore_pix;
56 char *Geometry = "";
57 Window iconwin, win;
58 GC NormalGC;
59 XpmIcon wmgen;
60 Pixmap pixmask;
62 /*****************/
63 /* Mouse Regions */
64 /*****************/
66 typedef struct {
67 int enable;
68 int top;
69 int bottom;
70 int left;
71 int right;
72 } MOUSE_REGION;
74 #define MAX_MOUSE_REGION (8)
75 MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
77 /***********************/
78 /* Function Prototypes */
79 /***********************/
81 static void GetXPM(XpmIcon *, char **);
82 static Pixel GetColor(char *);
83 void RedrawWindow(void);
84 void AddMouseRegion(int, int, int, int, int);
85 int CheckMouseRegion(int, int);
87 /*******************************************************************************\
88 |* read_rc_file *|
89 \*******************************************************************************/
91 void parse_rcfile(const char *filename, rckeys *keys) {
93 char *p;
94 char *line = NULL;
95 size_t line_size = 0;
96 char *tokens = " :\t\n";
97 FILE *fp;
98 int i,key;
100 fp = fopen(filename, "r");
101 if (fp) {
102 while (getline(&line, &line_size, fp) >= 0) {
103 key = 0;
104 while (key >= 0 && keys[key].label) {
105 if ((p = strstr(line, keys[key].label))) {
106 p += strlen(keys[key].label);
107 p += strspn(p, tokens);
108 if ((i = strcspn(p, "#\n"))) p[i] = 0;
109 free(*keys[key].var);
110 *keys[key].var = strdup(p);
111 key = -1;
112 } else key++;
115 fclose(fp);
120 /*******************************************************************************\
121 |* GetXPM *|
122 \*******************************************************************************/
124 static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
126 XWindowAttributes attributes;
127 int err;
129 /* For the colormap */
130 XGetWindowAttributes(display, Root, &attributes);
132 wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
134 err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
135 &(wmgen->mask), &(wmgen->attributes));
137 if (err != XpmSuccess) {
138 fprintf(stderr, "Not enough free colorcells.\n");
139 exit(1);
143 /*******************************************************************************\
144 |* GetColor *|
145 \*******************************************************************************/
147 static Pixel GetColor(char *name) {
149 XColor color;
150 XWindowAttributes attributes;
152 XGetWindowAttributes(display, Root, &attributes);
154 color.pixel = 0;
155 if (!XParseColor(display, attributes.colormap, name, &color)) {
156 fprintf(stderr, "wm.app: can't parse %s.\n", name);
157 } else if (!XAllocColor(display, attributes.colormap, &color)) {
158 fprintf(stderr, "wm.app: can't allocate %s.\n", name);
160 return color.pixel;
163 /*******************************************************************************\
164 |* flush_expose *|
165 \*******************************************************************************/
167 static int flush_expose(Window w) {
169 XEvent dummy;
170 int i=0;
172 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
173 i++;
175 return i;
178 /*******************************************************************************\
179 |* RedrawWindow *|
180 \*******************************************************************************/
182 void RedrawWindow(void) {
184 flush_expose(iconwin);
185 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
186 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
187 flush_expose(win);
188 XCopyArea(display, wmgen.pixmap, win, NormalGC,
189 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
192 /*******************************************************************************\
193 |* RedrawWindowXY *|
194 \*******************************************************************************/
196 void RedrawWindowXY(int x, int y) {
198 flush_expose(iconwin);
199 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
200 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
201 flush_expose(win);
202 XCopyArea(display, wmgen.pixmap, win, NormalGC,
203 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
206 /*******************************************************************************\
207 |* AddMouseRegion *|
208 \*******************************************************************************/
210 void AddMouseRegion(int index, int left, int top, int right, int bottom) {
212 if (index < MAX_MOUSE_REGION) {
213 mouse_region[index].enable = 1;
214 mouse_region[index].top = top;
215 mouse_region[index].left = left;
216 mouse_region[index].bottom = bottom;
217 mouse_region[index].right = right;
221 /*******************************************************************************\
222 |* CheckMouseRegion *|
223 \*******************************************************************************/
225 int CheckMouseRegion(int x, int y) {
227 int i;
228 int found;
230 found = 0;
232 for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
233 if (mouse_region[i].enable &&
234 x <= mouse_region[i].right &&
235 x >= mouse_region[i].left &&
236 y <= mouse_region[i].bottom &&
237 y >= mouse_region[i].top)
238 found = 1;
240 if (!found) return -1;
241 return (i-1);
244 /*******************************************************************************\
245 |* copyXPMArea *|
246 \*******************************************************************************/
248 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
250 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
254 /*******************************************************************************\
255 |* copyXBMArea *|
256 \*******************************************************************************/
258 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
260 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
264 /*******************************************************************************\
265 |* setMaskXY *|
266 \*******************************************************************************/
268 void setMaskXY(int x, int y) {
270 XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
271 XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
274 /*******************************************************************************\
275 |* openXwindow *|
276 \*******************************************************************************/
277 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
279 unsigned int borderwidth = 1;
280 XClassHint classHint;
281 char *display_name = NULL;
282 char *geometry = NULL;
283 char *wname = argv[0];
284 XTextProperty name;
286 XGCValues gcv;
287 unsigned long gcm;
290 int dummy=0;
291 int i;
293 for (i=1; argv[i]; i++) {
294 if (!strcmp(argv[i], "-display"))
295 display_name = argv[++i];
296 else if (!strcmp(argv[i], "-geometry"))
297 geometry = argv[++i];
300 if (!(display = XOpenDisplay(display_name))) {
301 fprintf(stderr, "%s: can't open display %s\n",
302 wname, XDisplayName(display_name));
303 exit(1);
305 screen = DefaultScreen(display);
306 Root = RootWindow(display, screen);
307 d_depth = DefaultDepth(display, screen);
308 x_fd = XConnectionNumber(display);
310 /* Convert XPM to XImage */
311 GetXPM(&wmgen, pixmap_bytes);
313 /* Create a window to hold the stuff */
314 mysizehints.flags = USSize | USPosition;
315 mysizehints.x = 0;
316 mysizehints.y = 0;
318 back_pix = GetColor("white");
319 fore_pix = GetColor("black");
321 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
322 &mysizehints.x, &mysizehints.y,
323 &dummy_int_width, &dummy_int_height, &dummy);
324 if (geometry)
325 XParseGeometry(geometry, &mysizehints.x, &mysizehints.y,
326 &uint_width, &uint_height);
328 /* Override width/height anyway */
329 uint_width = 64;
330 uint_height = 64;
332 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
333 uint_width, uint_height, borderwidth, fore_pix, back_pix);
335 iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
336 uint_width, uint_height, borderwidth, fore_pix, back_pix);
338 /* Activate hints */
339 XSetWMNormalHints(display, win, &mysizehints);
340 classHint.res_name = wname;
341 classHint.res_class = wname;
342 XSetClassHint(display, win, &classHint);
344 XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
345 XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
347 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
348 fprintf(stderr, "%s: can't allocate window name\n", wname);
349 exit(1);
352 XSetWMName(display, win, &name);
354 /* Create GC for drawing */
356 gcm = GCForeground | GCBackground | GCGraphicsExposures;
357 gcv.foreground = fore_pix;
358 gcv.background = back_pix;
359 gcv.graphics_exposures = 0;
360 NormalGC = XCreateGC(display, Root, gcm, &gcv);
362 /* ONLYSHAPE ON */
364 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
366 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
367 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
369 /* ONLYSHAPE OFF */
371 mywmhints.initial_state = WithdrawnState;
372 mywmhints.icon_window = iconwin;
373 mywmhints.icon_x = mysizehints.x;
374 mywmhints.icon_y = mysizehints.y;
375 mywmhints.window_group = win;
376 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
378 XSetWMHints(display, win, &mywmhints);
380 XSetCommand(display, win, argv, argc);
381 XMapWindow(display, win);
385 /* vim: ts=4 columns=82