wmmon: debian patches applied to upstream
[dockapps.git] / wmmon / wmgeneral / wmgeneral.c
blob87be71288f2ee3de18b462875bdffec93a486ec1
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 XWMHints mywmhints;
50 Pixel back_pix, fore_pix;
51 char *Geometry = "";
52 Window iconwin, win;
53 GC NormalGC;
54 XpmIcon wmgen;
55 Pixmap pixmask;
57 /*****************/
58 /* Mouse Regions */
59 /*****************/
61 typedef struct {
62 int enable;
63 int top;
64 int bottom;
65 int left;
66 int right;
67 } MOUSE_REGION;
69 #define MAX_MOUSE_REGION (8)
70 MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
72 /***********************/
73 /* Function Prototypes */
74 /***********************/
76 static void GetXPM(XpmIcon *, char **);
77 static Pixel GetColor(char *);
78 void RedrawWindow(void);
79 void AddMouseRegion(int, int, int, int, int);
80 int CheckMouseRegion(int, int);
82 /*******************************************************************************\
83 |* read_rc_file *|
84 \*******************************************************************************/
86 void parse_rcfile(const char *filename, rckeys *keys) {
88 char *p;
89 char *line = NULL;
90 size_t line_size = 0;
91 char *tokens = " :\t\n";
92 FILE *fp;
93 int i,key;
95 fp = fopen(filename, "r");
96 if (fp) {
97 while (getline(&line, &line_size, fp) >= 0) {
98 key = 0;
99 while (key >= 0 && keys[key].label) {
100 if ((p = strstr(line, keys[key].label))) {
101 p += strlen(keys[key].label);
102 p += strspn(p, tokens);
103 if ((i = strcspn(p, "#\n"))) p[i] = 0;
104 free(*keys[key].var);
105 *keys[key].var = strdup(p);
106 key = -1;
107 } else key++;
110 fclose(fp);
115 /*******************************************************************************\
116 |* GetXPM *|
117 \*******************************************************************************/
119 static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
121 XWindowAttributes attributes;
122 int err;
124 /* For the colormap */
125 XGetWindowAttributes(display, Root, &attributes);
127 wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
129 err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
130 &(wmgen->mask), &(wmgen->attributes));
132 if (err != XpmSuccess) {
133 fprintf(stderr, "Not enough free colorcells.\n");
134 exit(1);
138 /*******************************************************************************\
139 |* GetColor *|
140 \*******************************************************************************/
142 static Pixel GetColor(char *name) {
144 XColor color;
145 XWindowAttributes attributes;
147 XGetWindowAttributes(display, Root, &attributes);
149 color.pixel = 0;
150 if (!XParseColor(display, attributes.colormap, name, &color)) {
151 fprintf(stderr, "wm.app: can't parse %s.\n", name);
152 } else if (!XAllocColor(display, attributes.colormap, &color)) {
153 fprintf(stderr, "wm.app: can't allocate %s.\n", name);
155 return color.pixel;
158 /*******************************************************************************\
159 |* flush_expose *|
160 \*******************************************************************************/
162 static int flush_expose(Window w) {
164 XEvent dummy;
165 int i=0;
167 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
168 i++;
170 return i;
173 /*******************************************************************************\
174 |* RedrawWindow *|
175 \*******************************************************************************/
177 void RedrawWindow(void) {
179 flush_expose(iconwin);
180 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
181 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
182 flush_expose(win);
183 XCopyArea(display, wmgen.pixmap, win, NormalGC,
184 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
187 /*******************************************************************************\
188 |* RedrawWindowXY *|
189 \*******************************************************************************/
191 void RedrawWindowXY(int x, int y) {
193 flush_expose(iconwin);
194 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
195 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
196 flush_expose(win);
197 XCopyArea(display, wmgen.pixmap, win, NormalGC,
198 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
201 /*******************************************************************************\
202 |* AddMouseRegion *|
203 \*******************************************************************************/
205 void AddMouseRegion(int index, int left, int top, int right, int bottom) {
207 if (index < MAX_MOUSE_REGION) {
208 mouse_region[index].enable = 1;
209 mouse_region[index].top = top;
210 mouse_region[index].left = left;
211 mouse_region[index].bottom = bottom;
212 mouse_region[index].right = right;
216 /*******************************************************************************\
217 |* CheckMouseRegion *|
218 \*******************************************************************************/
220 int CheckMouseRegion(int x, int y) {
222 int i;
223 int found;
225 found = 0;
227 for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
228 if (mouse_region[i].enable &&
229 x <= mouse_region[i].right &&
230 x >= mouse_region[i].left &&
231 y <= mouse_region[i].bottom &&
232 y >= mouse_region[i].top)
233 found = 1;
235 if (!found) return -1;
236 return (i-1);
239 /*******************************************************************************\
240 |* copyXPMArea *|
241 \*******************************************************************************/
243 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
245 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
249 /*******************************************************************************\
250 |* copyXBMArea *|
251 \*******************************************************************************/
253 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
255 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
259 /*******************************************************************************\
260 |* setMaskXY *|
261 \*******************************************************************************/
263 void setMaskXY(int x, int y) {
265 XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
266 XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
269 /*******************************************************************************\
270 |* openXwindow *|
271 \*******************************************************************************/
272 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
274 unsigned int borderwidth = 1;
275 XClassHint classHint;
276 char *display_name = NULL;
277 char *geometry = NULL;
278 char *wname = argv[0];
279 XTextProperty name;
281 XGCValues gcv;
282 unsigned long gcm;
285 int dummy=0;
286 int i;
288 for (i=1; argv[i]; i++) {
289 if (!strcmp(argv[i], "-display"))
290 display_name = argv[++i];
291 else if (!strcmp(argv[i], "-geometry"))
292 geometry = argv[++i];
295 if (!(display = XOpenDisplay(display_name))) {
296 fprintf(stderr, "%s: can't open display %s\n",
297 wname, XDisplayName(display_name));
298 exit(1);
300 screen = DefaultScreen(display);
301 Root = RootWindow(display, screen);
302 d_depth = DefaultDepth(display, screen);
303 x_fd = XConnectionNumber(display);
305 /* Convert XPM to XImage */
306 GetXPM(&wmgen, pixmap_bytes);
308 /* Create a window to hold the stuff */
309 mysizehints.flags = USSize | USPosition;
310 mysizehints.x = 0;
311 mysizehints.y = 0;
313 back_pix = GetColor("white");
314 fore_pix = GetColor("black");
316 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
317 &mysizehints.x, &mysizehints.y,
318 &mysizehints.width, &mysizehints.height, &dummy);
319 if (geometry)
320 XParseGeometry(geometry, &mysizehints.x, &mysizehints.y,
321 &mysizehints.width, &mysizehints.height);
323 mysizehints.width = 64;
324 mysizehints.height = 64;
326 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
327 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
329 iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
330 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
332 /* Activate hints */
333 XSetWMNormalHints(display, win, &mysizehints);
334 classHint.res_name = wname;
335 classHint.res_class = wname;
336 XSetClassHint(display, win, &classHint);
338 XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
339 XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
341 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
342 fprintf(stderr, "%s: can't allocate window name\n", wname);
343 exit(1);
346 XSetWMName(display, win, &name);
348 /* Create GC for drawing */
350 gcm = GCForeground | GCBackground | GCGraphicsExposures;
351 gcv.foreground = fore_pix;
352 gcv.background = back_pix;
353 gcv.graphics_exposures = 0;
354 NormalGC = XCreateGC(display, Root, gcm, &gcv);
356 /* ONLYSHAPE ON */
358 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
360 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
361 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
363 /* ONLYSHAPE OFF */
365 mywmhints.initial_state = WithdrawnState;
366 mywmhints.icon_window = iconwin;
367 mywmhints.icon_x = mysizehints.x;
368 mywmhints.icon_y = mysizehints.y;
369 mywmhints.window_group = win;
370 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
372 XSetWMHints(display, win, &mywmhints);
374 XSetCommand(display, win, argv, argc);
375 XMapWindow(display, win);
379 /* vim: sw=4 ts=4 columns=82