1 /*
2 Best viewed with vim5, using ts=4
3
4 wmgeneral was taken from wmppp.
5
6 It has a lot of routines which most of the wm* programs use.
7
8 ------------------------------------------------------------
9
10 Author: Martijn Pieterse (pieterse@xs4all.nl)
11
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.
21
22 */
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <ctype.h>
29 #include <stdarg.h>
30
31 #include <X11/Xlib.h>
32 #include <X11/xpm.h>
33 #include <X11/extensions/shape.h>
34
35 #include "wmgeneral.h"
36
37 /*****************/
38 /* X11 Variables */
39 /*****************/
40
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;
53
54 Display *display;
55 /*****************/
56 /* Mouse Regions */
57 /*****************/
58
59 typedef struct {
60 int enable;
61 int top;
62 int bottom;
63 int left;
64 int right;
65 } MOUSE_REGION;
66
67 #define MAX_MOUSE_REGION (8)
68 MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
69
70 /***********************/
71 /* Function Prototypes */
72 /***********************/
73
74 static void GetXPM(XpmIcon *, char **);
75 static Pixel GetColor(char *);
76 void RedrawWindow(void);
77 void AddMouseRegion(int, int, int, int, int);
78 int CheckMouseRegion(int, int);
79
80 /*******************************************************************************\
81 |* read_rc_file *|
82 \*******************************************************************************/
83
parse_rcfile(const char * filename,rckeys * keys)84 void parse_rcfile(const char *filename, rckeys *keys) {
85
86 char *p;
87 char temp[128];
88 char *tokens = " :\t\n";
89 FILE *fp;
90 int i,key;
91
92 fp = fopen(filename, "r");
93 if (fp) {
94 while (fgets(temp, 128, fp)) {
95 key = 0;
96 while (key >= 0 && keys[key].label) {
97 if ((p = strstr(temp, keys[key].label))) {
98 p += strlen(keys[key].label);
99 p += strspn(p, tokens);
100 if ((i = strcspn(p, "#\n"))) p[i] = 0;
101 free(*keys[key].var);
102 *keys[key].var = strdup(p);
103 key = -1;
104 } else key++;
105 }
106 }
107 fclose(fp);
108 }
109 }
110
111
112 /*******************************************************************************\
113 |* GetXPM *|
114 \*******************************************************************************/
115
GetXPM(XpmIcon * wmgen,char * pixmap_bytes[])116 static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
117
118 XWindowAttributes attributes;
119 int err;
120
121 /* For the colormap */
122 XGetWindowAttributes(display, Root, &attributes);
123
124 wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
125
126 err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
127 &(wmgen->mask), &(wmgen->attributes));
128
129 if (err != XpmSuccess) {
130 fprintf(stderr, "Not enough free colorcells.\n");
131 exit(1);
132 }
133 }
134
135 /*******************************************************************************\
136 |* GetColor *|
137 \*******************************************************************************/
138
GetColor(char * name)139 static Pixel GetColor(char *name) {
140
141 XColor color;
142 XWindowAttributes attributes;
143
144 XGetWindowAttributes(display, Root, &attributes);
145
146 color.pixel = 0;
147 if (!XParseColor(display, attributes.colormap, name, &color)) {
148 fprintf(stderr, "wm.app: can't parse %s.\n", name);
149 } else if (!XAllocColor(display, attributes.colormap, &color)) {
150 fprintf(stderr, "wm.app: can't allocate %s.\n", name);
151 }
152 return color.pixel;
153 }
154
155 /*******************************************************************************\
156 |* flush_expose *|
157 \*******************************************************************************/
158
flush_expose(Window w)159 static int flush_expose(Window w) {
160
161 XEvent dummy;
162 int i=0;
163
164 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
165 i++;
166
167 return i;
168 }
169
170 /*******************************************************************************\
171 |* RedrawWindow *|
172 \*******************************************************************************/
173
RedrawWindow(void)174 void RedrawWindow(void) {
175
176 flush_expose(iconwin);
177 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
178 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
179 flush_expose(win);
180 XCopyArea(display, wmgen.pixmap, win, NormalGC,
181 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
182 }
183
184 /*******************************************************************************\
185 |* RedrawWindowXY *|
186 \*******************************************************************************/
187
RedrawWindowXY(int x,int y)188 void RedrawWindowXY(int x, int y) {
189
190 flush_expose(iconwin);
191 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
192 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
193 flush_expose(win);
194 XCopyArea(display, wmgen.pixmap, win, NormalGC,
195 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
196 }
197
198 /*******************************************************************************\
199 |* AddMouseRegion *|
200 \*******************************************************************************/
201
AddMouseRegion(int index,int left,int top,int right,int bottom)202 void AddMouseRegion(int index, int left, int top, int right, int bottom) {
203
204 if (index < MAX_MOUSE_REGION) {
205 mouse_region[index].enable = 1;
206 mouse_region[index].top = top;
207 mouse_region[index].left = left;
208 mouse_region[index].bottom = bottom;
209 mouse_region[index].right = right;
210 }
211 }
212
213 /*******************************************************************************\
214 |* CheckMouseRegion *|
215 \*******************************************************************************/
216
CheckMouseRegion(int x,int y)217 int CheckMouseRegion(int x, int y) {
218
219 int i;
220 int found;
221
222 found = 0;
223
224 for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
225 if (mouse_region[i].enable &&
226 x <= mouse_region[i].right &&
227 x >= mouse_region[i].left &&
228 y <= mouse_region[i].bottom &&
229 y >= mouse_region[i].top)
230 found = 1;
231 }
232 if (!found) return -1;
233 return (i-1);
234 }
235
236 /*******************************************************************************\
237 |* copyXPMArea *|
238 \*******************************************************************************/
239
copyXPMArea(int x,int y,int sx,int sy,int dx,int dy)240 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
241
242 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
243
244 }
245
246 /*******************************************************************************\
247 |* copyXBMArea *|
248 \*******************************************************************************/
249
copyXBMArea(int x,int y,int sx,int sy,int dx,int dy)250 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
251
252 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
253 }
254
255
256 /*******************************************************************************\
257 |* setMaskXY *|
258 \*******************************************************************************/
259
setMaskXY(int x,int y)260 void setMaskXY(int x, int y) {
261
262 XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
263 XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
264 }
265
266 /*******************************************************************************\
267 |* openXwindow *|
268 \*******************************************************************************/
openXwindow(int argc,char * argv[],char * pixmap_bytes[],char * pixmask_bits,int pixmask_width,int pixmask_height)269 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
270
271 unsigned int borderwidth = 1;
272 XClassHint classHint;
273 char *display_name = NULL;
274 char *wname = argv[0];
275 XTextProperty name;
276
277 XGCValues gcv;
278 unsigned long gcm;
279
280
281 int dummy=0;
282 int i;
283
284 for (i=1; argv[i]; i++) {
285 if (!strcmp(argv[i], "-display"))
286 display_name = argv[i+1];
287 }
288
289 if (!(display = XOpenDisplay(display_name))) {
290 fprintf(stderr, "%s: can't open display %s\n",
291 wname, XDisplayName(display_name));
292 exit(1);
293 }
294 screen = DefaultScreen(display);
295 Root = RootWindow(display, screen);
296 d_depth = DefaultDepth(display, screen);
297 x_fd = XConnectionNumber(display);
298
299 /* Convert XPM to XImage */
300 GetXPM(&wmgen, pixmap_bytes);
301
302 /* Create a window to hold the stuff */
303 mysizehints.flags = USSize | USPosition;
304 mysizehints.x = 0;
305 mysizehints.y = 0;
306
307 back_pix = GetColor("white");
308 fore_pix = GetColor("black");
309
310 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
311 &mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
312
313 mysizehints.width = 64;
314 mysizehints.height = 64;
315
316 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
317 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
318
319 iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
320 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
321
322 /* Activate hints */
323 XSetWMNormalHints(display, win, &mysizehints);
324 classHint.res_name = wname;
325 classHint.res_class = wname;
326 XSetClassHint(display, win, &classHint);
327
328 XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
329 XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
330
331 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
332 fprintf(stderr, "%s: can't allocate window name\n", wname);
333 exit(1);
334 }
335
336 XSetWMName(display, win, &name);
337
338 /* Create GC for drawing */
339
340 gcm = GCForeground | GCBackground | GCGraphicsExposures;
341 gcv.foreground = fore_pix;
342 gcv.background = back_pix;
343 gcv.graphics_exposures = 0;
344 NormalGC = XCreateGC(display, Root, gcm, &gcv);
345
346 /* ONLYSHAPE ON */
347
348 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
349
350 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
351 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
352
353 /* ONLYSHAPE OFF */
354
355 mywmhints.initial_state = WithdrawnState;
356 mywmhints.icon_window = iconwin;
357 mywmhints.icon_x = mysizehints.x;
358 mywmhints.icon_y = mysizehints.y;
359 mywmhints.window_group = win;
360 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
361
362 XSetWMHints(display, win, &mywmhints);
363
364 XSetCommand(display, win, argv, argc);
365 XMapWindow(display, win);
366
367 }
368