wmclockmon: update change-log
[dockapps.git] / wmtv / src / wmgeneral / wmgeneral.c
blob068d13a2c36102603f19782c03a26a79ea910d41
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 12/03/1999 (Wee Liang, wliang@tartarus.uwa.edu.au)
16 * Removed argument parsing from openXwindow
17 12/02/1999 (Wee Liang, wliang@tartarus.uwa.edu.au)
18 * Removed parse_rcfile and parse_rcfile2.
19 * Change RedrawWindowXY to RedrawWindowXYWH
20 * Minor modifications to openXwindow. Added execute
21 file support.
22 11/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
23 * Removed a bug from parse_rcfile. You could
24 not use "start" in a command if a label was
25 also start.
26 * Changed the needed geometry string.
27 We don't use window size, and don't support
28 negative positions.
29 03/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
30 * Added parse_rcfile2
31 02/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
32 * Added -geometry support (untested)
33 28/08/1998 (Martijn Pieterse, pieterse@xs4all.nl)
34 * Added createXBMfromXPM routine
35 * Saves a lot of work with changing xpm's.
36 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
37 * changed the read_rc_file to parse_rcfile, as suggested by Marcelo E. Magallon
38 * debugged the parse_rc file.
39 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
40 * Ripped similar code from all the wm* programs,
41 and put them in a single file.
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <string.h>
48 #include <unistd.h>
49 #include <ctype.h>
50 #include <stdarg.h>
51 #include <errno.h>
53 #include <X11/Xlib.h>
54 #include <X11/xpm.h>
55 #include <X11/extensions/shape.h>
57 #include "wmgeneral.h"
59 /*****************/
60 /* X11 Variables */
61 /*****************/
63 Window Root;
64 int screen;
65 int x_fd;
66 int d_depth;
67 XSizeHints mysizehints;
68 XWMHints mywmhints;
69 Pixel back_pix, fore_pix;
70 char *Geometry = "";
71 Window iconwin, win;
72 GC NormalGC;
73 XpmIcon wmgen;
74 Pixmap pixmask;
75 char *exef = NULL;
76 char *display_name = NULL;
77 char *geometry = NULL;
78 char *exe = NULL;
80 /*****************/
81 /* Mouse Regions */
82 /*****************/
84 typedef struct {
85 int enable;
86 int top;
87 int bottom;
88 int left;
89 int right;
90 } MOUSE_REGION;
92 MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
94 /***********************/
95 /* Function Prototypes */
96 /***********************/
98 static void GetXPM(XpmIcon *, char **);
99 static Pixel GetColor(char *);
100 void RedrawWindow(void);
101 void AddMouseRegion(unsigned, int, int, int, int);
102 int CheckMouseRegion(int, int);
104 /*******************************************************************************\
105 |* GetXPM *|
106 \*******************************************************************************/
108 static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
110 XWindowAttributes attributes;
111 int err;
113 /* For the colormap */
114 XGetWindowAttributes(display, Root, &attributes);
116 wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
118 err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
119 &(wmgen->mask), &(wmgen->attributes));
121 if (err != XpmSuccess) {
122 fprintf(stderr, "Not enough free colorcells.\n");
123 exit(1);
127 /*******************************************************************************\
128 |* GetColor *|
129 \*******************************************************************************/
131 static Pixel GetColor(char *name) {
133 XColor color;
134 XWindowAttributes attributes;
136 XGetWindowAttributes(display, Root, &attributes);
138 color.pixel = 0;
139 if (!XParseColor(display, attributes.colormap, name, &color)) {
140 fprintf(stderr, "wm.app: can't parse %s.\n", name);
141 } else if (!XAllocColor(display, attributes.colormap, &color)) {
142 fprintf(stderr, "wm.app: can't allocate %s.\n", name);
144 return color.pixel;
147 /*******************************************************************************\
148 |* flush_expose *|
149 \*******************************************************************************/
151 static int flush_expose(Window w) {
153 XEvent dummy;
154 int i=0;
156 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
157 i++;
159 return i;
162 /*******************************************************************************\
163 |* RedrawWindow *|
164 \*******************************************************************************/
166 void RedrawWindow(void) {
168 flush_expose(iconwin);
169 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
170 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
171 flush_expose(win);
172 XCopyArea(display, wmgen.pixmap, win, NormalGC,
173 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
176 /*******************************************************************************\
177 |* RedrawWindowXYWH *|
178 \*******************************************************************************/
180 void RedrawWindowXYWH(int x, int y, int w, int h) {
182 flush_expose(iconwin);
183 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
184 x,y, w, h, 0,0);
185 flush_expose(win);
186 XCopyArea(display, wmgen.pixmap, win, NormalGC,
187 x,y, w, h, 0,0);
190 /*******************************************************************************\
191 |* AddMouseRegion *|
192 \*******************************************************************************/
194 void AddMouseRegion(unsigned index, int left, int top, int right, int bottom) {
196 if (index < MAX_MOUSE_REGION) {
197 mouse_region[index].enable = 1;
198 mouse_region[index].top = top;
199 mouse_region[index].left = left;
200 mouse_region[index].bottom = bottom;
201 mouse_region[index].right = right;
205 /*******************************************************************************\
206 |* CheckMouseRegion *|
207 \*******************************************************************************/
209 int CheckMouseRegion(int x, int y) {
211 int i;
212 int found;
214 found = 0;
216 for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
217 if (mouse_region[i].enable &&
218 x <= mouse_region[i].right &&
219 x >= mouse_region[i].left &&
220 y <= mouse_region[i].bottom &&
221 y >= mouse_region[i].top)
222 found = 1;
224 if (!found) return -1;
225 return (i-1);
228 /*******************************************************************************\
229 |* createXBMfromXPM *|
230 \*******************************************************************************/
231 void createXBMfromXPM(char *xbm, char **xpm, int sx, int sy) {
233 int i,j;
234 int width, height, numcol;
235 char zero;
236 unsigned char bwrite;
237 int bcount;
240 sscanf(*xpm, "%d %d %d", &width, &height, &numcol);
242 zero = xpm[1][0];
243 for (i=numcol+1; i < numcol+sy+1; i++) {
244 bcount = 0;
245 bwrite = 0;
246 for (j=0; j<sx; j++) {
247 bwrite >>= 1;
248 if (xpm[i][j] != zero) {
249 bwrite += 128;
251 bcount++;
252 if (bcount == 8) {
253 *xbm = bwrite;
254 xbm++;
255 bcount = 0;
256 bwrite = 0;
262 /*******************************************************************************\
263 |* copyXPMArea *|
264 \*******************************************************************************/
266 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
268 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
272 /*******************************************************************************\
273 |* copyXBMArea *|
274 \*******************************************************************************/
276 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
278 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
282 /*******************************************************************************\
283 |* setMaskXY *|
284 \*******************************************************************************/
286 void setMaskXY(int x, int y) {
288 XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
289 XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
292 /*******************************************************************************\
293 |* openXwindow *|
294 \*******************************************************************************/
295 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
297 unsigned int borderwidth = 1;
298 XClassHint classHint;
299 char *wname = argv[0];
300 XTextProperty name;
302 XGCValues gcv;
303 unsigned long gcm;
305 int dummy=0;
306 int wx, wy;
307 //Window junkwin;
308 //int rx, ry;
309 //XWindowAttributes winatr;
312 for (i=1; argv[i]; i++) {
313 if (!strcmp(argv[i], "-display")) {
314 display_name = argv[i+1];
315 i++;
317 if (!strcmp(argv[i], "-geometry")) {
318 geometry = argv[i+1];
319 i++;
321 if (!strcmp(argv[i], "-exe")) {
322 exe = argv[i+1];
323 strcat (exe, " &");
324 exef = exe;
325 i++;
330 if (!(display = XOpenDisplay(display_name))) {
331 fprintf(stderr, "%s: can't open display %s\n",
332 wname, XDisplayName(display_name));
333 exit(1);
336 screen = DefaultScreen(display);
337 Root = RootWindow(display, screen);
338 d_depth = DefaultDepth(display, screen);
339 x_fd = XConnectionNumber(display);
341 /* Convert XPM to XImage */
342 GetXPM(&wmgen, pixmap_bytes);
344 /* Create a window to hold the stuff */
345 mysizehints.flags = USSize | USPosition;
346 mysizehints.x = 0;
347 mysizehints.y = 0;
349 back_pix = GetColor("white");
350 fore_pix = GetColor("black");
352 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
353 &mysizehints.x, &mysizehints.y, &mysizehints.width, &mysizehints.height, &dummy);
355 mysizehints.width = 64;
356 mysizehints.height = 64;
358 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
359 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
361 iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
362 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
364 /* Activate hints */
365 XSetWMNormalHints(display, win, &mysizehints);
366 classHint.res_name = wname;
367 classHint.res_class = wname;
368 XSetClassHint(display, win, &classHint);
370 XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | VisibilityChangeMask);
371 XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | VisibilityChangeMask);
373 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
374 fprintf(stderr, "%s: can't allocate window name\n", wname);
375 exit(1);
378 XSetWMName(display, win, &name);
380 /* Create GC for drawing */
382 gcm = GCForeground | GCBackground | GCGraphicsExposures;
383 gcv.foreground = fore_pix;
384 gcv.background = back_pix;
385 gcv.graphics_exposures = 0;
386 NormalGC = XCreateGC(display, Root, gcm, &gcv);
388 /* ONLYSHAPE ON */
390 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
392 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
393 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
395 /* ONLYSHAPE OFF */
397 mywmhints.initial_state = WithdrawnState;
398 mywmhints.icon_window = iconwin;
399 mywmhints.icon_x = mysizehints.x;
400 mywmhints.icon_y = mysizehints.y;
401 mywmhints.window_group = win;
402 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
403 XSetWMHints(display, win, &mywmhints);
405 XSetCommand(display, win, argv, argc);
406 XMapWindow(display, win);
408 // XGetWindowAttributes(display, iconwin, &winatr);
409 // XTranslateCoordinates(display, iconwin, winatr.root, -winatr.border_width, - winatr.border_width,
410 // &rx, &ry, &junkwin);
412 if (geometry) {
413 if (sscanf(geometry, "+%d+%d", &wx, &wy) != 2) {
414 fprintf(stderr, "Bad geometry string.\n");
415 exit(1);
417 XMoveWindow(display, win, wx, wy);