wmbattery: fix a couple of potential memory-leaks.
[dockapps.git] / buttonmaker / src / wmgeneral.c
blobfd0233caa1f2af9cb4c4f77a53fe0b190445ab8c
1 /*
2 * wmgeneral.c
3 * Copyright (C) Renan Vedovato Traba 2012 <rvt10@inf.ufpr.br>
5 ButtonMaker is free software: you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 ButtonMaker is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program. If not, see <http://www.gnu.org/licenses/>.
19 /* wmgeneral was taken from wmppp.
21 It has a lot of routines which most of the wm* programs use.
23 ------------------------------------------------------------
24 Author: Martijn Pieterse (pieterse@xs4all.nl)
26 --- CHANGES: ---
27 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
28 * changed the read_rc_file to parse_rcfile, as suggester by Marcelo E. Magallon
29 * debugged the parse_rc file.
30 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
31 * Ripped similar code from all the wm* programs,
32 and put them in a single file.
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <unistd.h>
39 #include <ctype.h>
40 #include <stdarg.h>
41 #include <X11/Xlib.h>
42 #include <X11/xpm.h>
43 #include <X11/extensions/shape.h>
44 #include "wmgeneral.h"
46 /* X11 Variables */
47 int screen;
48 int x_fd;
49 int d_depth;
50 XSizeHints mysizehints;
51 XWMHints mywmhints;
52 Pixel back_pix, fore_pix;
53 char *Geometry = "";
54 Window iconwin, win;
55 Pixmap pixmask;
57 /* Mouse Regions */
58 typedef struct {
59 int enable;
60 int top;
61 int bottom;
62 int left;
63 int right;
64 } MOUSE_REGION;
66 #define MAX_MOUSE_REGION (8)
67 MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
69 /* Function Prototypes */
70 static void GetXPM(XpmIcon *, char **);
71 static Pixel GetColor(char *);
72 void RedrawWindow(void);
73 void AddMouseRegion(int, int, int, int, int);
74 int CheckMouseRegion(int, int);
76 /* read_rc_file */
77 void parse_rcfile(const char *filename, rckeys *keys)
79 char *p;
80 char temp[128];
81 char *tokens = " : \n";
82 FILE *fp;
83 int i,key;
85 fp = fopen(filename, "r");
86 if (fp) {
87 while (fgets(temp, 128, fp)) {
88 key = 0;
89 while (key >= 0 && keys[key].label) {
90 if ((p = strstr(temp, keys[key].label))) {
91 p += strlen(keys[key].label);
92 p += strspn(p, tokens);
93 if ((i = strcspn(p, "#\n"))) p[i] = 0;
94 free(*keys[key].var);
95 *keys[key].var = strdup(p);
96 key = -1;
97 } else key++;
100 fclose(fp);
104 static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[])
106 XWindowAttributes attributes;
107 int err;
109 /* For the colormap */
110 XGetWindowAttributes(display, Root, &attributes);
112 wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
114 err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
115 &(wmgen->mask), &(wmgen->attributes));
117 if (err != XpmSuccess) {
118 fprintf(stderr, "Not enough free colorcells.\n");
119 exit(1);
123 static Pixel GetColor(char *name)
125 XColor color;
126 XWindowAttributes attributes;
128 XGetWindowAttributes(display, Root, &attributes);
130 color.pixel = 0;
131 if (!XParseColor(display, attributes.colormap, name, &color)) {
132 fprintf(stderr, "wm.app: can't parse %s.\n", name);
133 } else if (!XAllocColor(display, attributes.colormap, &color)) {
134 fprintf(stderr, "wm.app: can't allocate %s.\n", name);
136 return color.pixel;
139 static int flush_expose(Window w)
141 XEvent dummy;
142 int i=0;
144 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
145 i++;
146 return i;
149 void RedrawWindow(void)
151 flush_expose(iconwin);
152 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
153 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
154 flush_expose(win);
155 XCopyArea(display, wmgen.pixmap, win, NormalGC,
156 0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
159 void RedrawWindowXY(int x, int y)
161 flush_expose(iconwin);
162 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
163 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
164 flush_expose(win);
165 XCopyArea(display, wmgen.pixmap, win, NormalGC,
166 x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
169 void AddMouseRegion(int idx, int left, int top, int right, int bottom)
171 if (idx < MAX_MOUSE_REGION) {
172 mouse_region[idx].enable = 1;
173 mouse_region[idx].top = top;
174 mouse_region[idx].left = left;
175 mouse_region[idx].bottom = bottom;
176 mouse_region[idx].right = right;
180 int CheckMouseRegion(int x, int y)
182 int i;
184 for (i=0; i<MAX_MOUSE_REGION; i++) {
185 if (mouse_region[i].enable &&
186 x <= mouse_region[i].right &&
187 x >= mouse_region[i].left &&
188 y <= mouse_region[i].bottom &&
189 y >= mouse_region[i].top)
190 return (i-1);
192 return -1;
195 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy)
197 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
200 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy)
202 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
205 void setMaskXY(int x, int y)
207 XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
208 XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
211 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height)
213 unsigned int borderwidth = 1;
214 XClassHint classHint;
215 char *display_name = NULL;
216 char *wname = argv[0];
217 XTextProperty name;
218 XGCValues gcv;
219 unsigned long gcm;
220 int i, dummy = 0;
222 for (i=1; argv[i]; i++) {
223 if (!strcmp(argv[i], "-display"))
224 display_name = argv[i+1];
227 if (!(display = XOpenDisplay(display_name))) {
228 fprintf(stderr, "%s: can't open display %s\n",
229 wname, XDisplayName(display_name));
230 exit(1);
232 screen = DefaultScreen(display);
233 Root = RootWindow(display, screen);
234 d_depth = DefaultDepth(display, screen);
235 x_fd = XConnectionNumber(display);
237 /* Convert XPM to XImage */
238 GetXPM(&wmgen, pixmap_bytes);
240 /* Create a window to hold the stuff */
241 mysizehints.flags = USSize | USPosition;
242 mysizehints.x = 0;
243 mysizehints.y = 0;
245 back_pix = GetColor("white");
246 fore_pix = GetColor("black");
248 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
249 &mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
251 mysizehints.width = 64;
252 mysizehints.height = 64;
254 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
255 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
257 iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
258 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
260 /* Activate hints */
261 XSetWMNormalHints(display, win, &mysizehints);
262 classHint.res_name = wname;
263 classHint.res_class = wname;
264 XSetClassHint(display, win, &classHint);
266 XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask |
267 PointerMotionMask | StructureNotifyMask);
268 XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask |
269 PointerMotionMask | StructureNotifyMask);
271 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
272 fprintf(stderr, "%s: can't allocate window name\n", wname);
273 exit(1);
276 XSetWMName(display, win, &name);
278 /* Create GC for drawing */
279 gcm = GCForeground | GCBackground | GCGraphicsExposures;
280 gcv.foreground = fore_pix;
281 gcv.background = back_pix;
282 gcv.graphics_exposures = 0;
283 NormalGC = XCreateGC(display, Root, gcm, &gcv);
285 /* ONLYSHAPE ON */
286 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
287 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
288 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
290 /* ONLYSHAPE OFF */
291 mywmhints.initial_state = WithdrawnState;
292 mywmhints.icon_window = iconwin;
293 mywmhints.icon_x = mysizehints.x;
294 mywmhints.icon_y = mysizehints.y;
295 mywmhints.window_group = win;
296 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
298 XSetWMHints(display, win, &mywmhints);
300 XSetCommand(display, win, argv, argc);
301 XMapWindow(display, win);