Add missing libraries to examples' Makefiles
[dockapps.git] / wmgrabimage / wmgeneral / wmgeneral.c
blobc06f8b7b303105af9c12aae6589679279a02a93a
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 int screen;
42 int x_fd;
43 int d_depth;
44 XSizeHints mysizehints;
45 XWMHints mywmhints;
46 Pixel back_pix, fore_pix;
47 char *Geometry = "";
48 Window iconwin, win;
49 Pixmap pixmask;
51 /*****************/
52 /* Mouse Regions */
53 /*****************/
55 typedef struct {
56 int enable;
57 int top;
58 int bottom;
59 int left;
60 int right;
61 } MOUSE_REGION;
63 #define MAX_MOUSE_REGION (8)
64 MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
66 /***********************/
67 /* Function Prototypes */
68 /***********************/
70 static void GetXPM(XpmIcon *, char **);
71 static Pixel GetColor(char *);
72 void RedrawWindow(void);
73 void AddMouseRegion(unsigned, int, int, int, int);
74 int CheckMouseRegion(int, int);
76 /*******************************************************************************\
77 |* read_rc_file *|
78 \*******************************************************************************/
80 void parse_rcfile(const char *filename, rckeys *keys) {
82 char *p;
83 char temp[128];
84 char *tokens = " :\t\n";
85 FILE *fp;
86 int i,key;
88 fp = fopen(filename, "r");
89 if (fp) {
90 while (fgets(temp, 128, fp)) {
91 key = 0;
92 while (key >= 0 && keys[key].label) {
93 if ((p = strstr(temp, keys[key].label))) {
94 p += strlen(keys[key].label);
95 p += strspn(p, tokens);
96 if ((i = strcspn(p, "#\n"))) p[i] = 0;
97 free(*keys[key].var);
98 *keys[key].var = strdup(p);
99 key = -1;
100 } else key++;
103 fclose(fp);
108 /*******************************************************************************\
109 |* GetXPM *|
110 \*******************************************************************************/
112 static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
114 XWindowAttributes attributes;
115 int err;
117 /* For the colormap */
118 XGetWindowAttributes(display, Root, &attributes);
120 wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
122 err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
123 &(wmgen->mask), &(wmgen->attributes));
125 if (err != XpmSuccess) {
126 fprintf(stderr, "Not enough free colorcells.\n");
127 exit(1);
131 /*******************************************************************************\
132 |* GetColor *|
133 \*******************************************************************************/
135 static Pixel GetColor(char *name) {
137 XColor color;
138 XWindowAttributes attributes;
140 XGetWindowAttributes(display, Root, &attributes);
142 color.pixel = 0;
143 if (!XParseColor(display, attributes.colormap, name, &color)) {
144 fprintf(stderr, "wm.app: can't parse %s.\n", name);
145 } else if (!XAllocColor(display, attributes.colormap, &color)) {
146 fprintf(stderr, "wm.app: can't allocate %s.\n", name);
148 return color.pixel;
151 /*******************************************************************************\
152 |* flush_expose *|
153 \*******************************************************************************/
155 static int flush_expose(Window w) {
157 XEvent dummy;
158 int i=0;
160 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
161 i++;
163 return i;
166 /*******************************************************************************\
167 |* RedrawWindow *|
168 \*******************************************************************************/
170 void RedrawWindow(void) {
172 flush_expose(iconwin);
173 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
174 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
175 flush_expose(win);
176 XCopyArea(display, wmgen.pixmap, win, NormalGC,
177 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
180 /*******************************************************************************\
181 |* RedrawWindowXY *|
182 \*******************************************************************************/
184 void RedrawWindowXY(int x, int y) {
186 flush_expose(iconwin);
187 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
188 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
189 flush_expose(win);
190 XCopyArea(display, wmgen.pixmap, win, NormalGC,
191 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
194 /*******************************************************************************\
195 |* AddMouseRegion *|
196 \*******************************************************************************/
198 void AddMouseRegion(unsigned index, int left, int top, int right, int bottom) {
200 if (index < MAX_MOUSE_REGION) {
201 mouse_region[index].enable = 1;
202 mouse_region[index].top = top;
203 mouse_region[index].left = left;
204 mouse_region[index].bottom = bottom;
205 mouse_region[index].right = right;
209 /*******************************************************************************\
210 |* CheckMouseRegion *|
211 \*******************************************************************************/
213 int CheckMouseRegion(int x, int y) {
215 int i;
216 int found;
218 found = 0;
220 for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
221 if (mouse_region[i].enable &&
222 x <= mouse_region[i].right &&
223 x >= mouse_region[i].left &&
224 y <= mouse_region[i].bottom &&
225 y >= mouse_region[i].top)
226 found = 1;
228 if (!found) return -1;
229 return (i-1);
232 /*******************************************************************************\
233 |* copyXPMArea *|
234 \*******************************************************************************/
236 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
238 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
242 /*******************************************************************************\
243 |* copyXBMArea *|
244 \*******************************************************************************/
246 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
248 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
252 /*******************************************************************************\
253 |* setMaskXY *|
254 \*******************************************************************************/
256 void setMaskXY(int x, int y) {
258 XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
259 XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
262 /*******************************************************************************\
263 |* openXwindow *|
264 \*******************************************************************************/
265 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
267 unsigned int borderwidth = 1;
268 XClassHint classHint;
269 char *display_name = NULL;
270 char *wname = argv[0];
271 XTextProperty name;
273 XGCValues gcv;
274 unsigned long gcm;
277 int dummy=0;
278 int i;
280 for (i=1; argv[i]; i++) {
281 if (!strcmp(argv[i], "-display"))
282 display_name = argv[i+1];
285 if (!(display = XOpenDisplay(display_name))) {
286 fprintf(stderr, "%s: can't open display %s\n",
287 wname, XDisplayName(display_name));
288 exit(1);
290 screen = DefaultScreen(display);
291 Root = RootWindow(display, screen);
292 d_depth = DefaultDepth(display, screen);
293 x_fd = XConnectionNumber(display);
295 /* Convert XPM to XImage */
296 GetXPM(&wmgen, pixmap_bytes);
298 /* Create a window to hold the stuff */
299 mysizehints.flags = USSize | USPosition;
300 mysizehints.x = 0;
301 mysizehints.y = 0;
303 back_pix = GetColor("white");
304 fore_pix = GetColor("black");
306 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
307 &mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
309 mysizehints.width = 64;
310 mysizehints.height = 64;
312 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
313 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
315 iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
316 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
318 /* Activate hints */
319 XSetWMNormalHints(display, win, &mysizehints);
320 classHint.res_name = wname;
321 classHint.res_class = wname;
322 XSetClassHint(display, win, &classHint);
324 XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
325 XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
327 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
328 fprintf(stderr, "%s: can't allocate window name\n", wname);
329 exit(1);
332 XSetWMName(display, win, &name);
334 /* Create GC for drawing */
336 gcm = GCForeground | GCBackground | GCGraphicsExposures;
337 gcv.foreground = fore_pix;
338 gcv.background = back_pix;
339 gcv.graphics_exposures = 0;
340 NormalGC = XCreateGC(display, Root, gcm, &gcv);
342 /* ONLYSHAPE ON */
344 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
346 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
347 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
349 /* ONLYSHAPE OFF */
351 mywmhints.initial_state = WithdrawnState;
352 mywmhints.icon_window = iconwin;
353 mywmhints.icon_x = mysizehints.x;
354 mywmhints.icon_y = mysizehints.y;
355 mywmhints.window_group = win;
356 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
358 XSetWMHints(display, win, &mywmhints);
360 XSetCommand(display, win, argv, argc);
361 XMapWindow(display, win);