wmshutdown: Destroy dialog window before shutting down. This is especially useful...
[dockapps.git] / wmMatrix / xutils.c
blob5af32d754c41e1454d78c1f950212c341d1e2ec0
1 /*
2 * xutils.c - A collection of X-windows utilties for creating WindowMAker
3 * DockApps.
5 * This file contains alot of the lower-level X windows routines. Origins with wmppp
6 * (by Martijn Pieterse (pieterse@xs4all.nl)), but its been hacked up quite a bit
7 * and passed on from one new DockApp to the next.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program (see the file COPYING); if not, write to the
24 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 * Boston, MA 02110-1301 USA
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <ctype.h>
36 #include <stdarg.h>
37 #include <X11/Xlib.h>
38 #include <X11/xpm.h>
39 #include <X11/extensions/shape.h>
40 #include <sys/time.h>
41 #include <sys/select.h>
42 #include "xutils.h"
45 * X11 Variables
47 int x_fd;
48 XSizeHints mysizehints;
49 XWMHints mywmhints;
50 Pixel back_pix, fore_pix;
51 char *Geometry = "";
52 GC NormalGC;
53 GC EraseGC;
54 XpmIcon wmgen;
55 Pixmap pixmask;
58 * Colors for wmCalClock
60 extern char TimeColor[30];
61 extern char BackgroundColor[30];
64 * flush_expose
66 static int flush_expose(Window w)
69 XEvent dummy;
70 int i = 0;
72 while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
73 i++;
75 return i;
80 * RedrawWindow
81 * RedrawWindowXY
83 void RedrawWindow(void)
86 flush_expose(iconwin);
87 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC, 0, 0, wmgen.attributes.width, wmgen.attributes.height, 0, 0);
89 flush_expose(win);
90 XCopyArea(display, wmgen.pixmap, win, NormalGC, 0, 0, wmgen.attributes.width, wmgen.attributes.height, 0, 0);
94 void RedrawWindowXY(int x, int y)
97 flush_expose(iconwin);
98 XCopyArea(display, wmgen.pixmap, iconwin, NormalGC, x, y, wmgen.attributes.width, wmgen.attributes.height, 0, 0);
100 flush_expose(win);
101 XCopyArea(display, wmgen.pixmap, win, NormalGC, x, y, wmgen.attributes.width, wmgen.attributes.height, 0, 0);
106 * copyXPMArea
107 * copyXBMArea
109 void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy)
111 XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
114 void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy)
117 XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
121 * initXwindow
123 void initXwindow(int argc, char *argv[])
126 int i;
127 char *display_name = NULL;
129 for (i = 1; argv[i]; ++i) {
130 if (!strcmp(argv[i], "-display"))
131 display_name = argv[i + 1];
134 if (!(display = XOpenDisplay(display_name))) {
135 fprintf(stderr, "%s: can't open display %s\n", argv[0], XDisplayName(display_name));
136 exit(1);
139 screen = DefaultScreen(display);
140 Root = RootWindow(display, screen);
141 DisplayDepth = DefaultDepth(display, screen);
142 x_fd = XConnectionNumber(display);
147 * openXwindow
149 void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height)
152 unsigned int borderwidth = 1;
153 XClassHint classHint;
154 char *wname = argv[0];
155 XTextProperty name;
156 XGCValues gcv;
157 unsigned long gcm;
158 int dummy = 0, red, grn, blu;
159 XpmColorSymbol cols[10] = { {"Back", NULL, 0},
160 {"Color1", NULL, 0},
161 {"Color2", NULL, 0},
162 {"Color3", NULL, 0},
163 {"Color4", NULL, 0},
164 {"Color5", NULL, 0},
165 {"Color6", NULL, 0},
166 {"Color7", NULL, 0},
167 {"Color8", NULL, 0},
168 {"Color9", NULL, 0}
172 * Create Pixmap
174 cols[0].pixel = getColor(BackgroundColor, 1.0000, &red, &grn, &blu);
175 cols[1].pixel = getBlendedColor(TimeColor, 0.1522, red, grn, blu);
176 cols[2].pixel = getBlendedColor(TimeColor, 0.2602, red, grn, blu);
177 cols[3].pixel = getBlendedColor(TimeColor, 0.3761, red, grn, blu);
178 cols[4].pixel = getBlendedColor(TimeColor, 0.4841, red, grn, blu);
179 cols[5].pixel = getBlendedColor(TimeColor, 0.5922, red, grn, blu);
180 cols[6].pixel = getBlendedColor(TimeColor, 0.6980, red, grn, blu);
181 cols[7].pixel = getBlendedColor(TimeColor, 0.7961, red, grn, blu);
182 cols[8].pixel = getBlendedColor(TimeColor, 0.8941, red, grn, blu);
183 cols[9].pixel = getBlendedColor(TimeColor, 1.0000, red, grn, blu);
185 wmgen.attributes.numsymbols = 10;
186 wmgen.attributes.colorsymbols = cols;
187 wmgen.attributes.exactColors = False;
188 wmgen.attributes.closeness = 40000;
189 wmgen.attributes.valuemask = XpmReturnPixels | XpmReturnExtensions | XpmColorSymbols | XpmExactColors | XpmCloseness | XpmSize;
190 if (XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen.pixmap), &(wmgen.mask), &(wmgen.attributes)) != XpmSuccess) {
191 fprintf(stderr, "Not enough free colorcells.\n");
192 exit(1);
196 * Create a window
198 mysizehints.flags = USSize | USPosition;
199 mysizehints.x = 0;
200 mysizehints.y = 0;
202 back_pix = getColor("black", 1.0, &red, &grn, &blu);
203 fore_pix = getColor("white", 1.0, &red, &grn, &blu);
205 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
206 &mysizehints.x, &mysizehints.y, &mysizehints.width, &mysizehints.height, &dummy);
208 mysizehints.width = 64;
209 mysizehints.height = 64;
211 win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
212 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
214 iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
215 mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
218 * Activate hints
220 XSetWMNormalHints(display, win, &mysizehints);
221 classHint.res_name = wname;
222 classHint.res_class = wname;
223 XSetClassHint(display, win, &classHint);
226 * Set up the xevents that you want the relevent windows to inherit
227 * Currently, its seems that setting KeyPress events here has no
228 * effect. I.e. for some you will need to Grab the focus and then return
229 * it after you are done...
231 XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask
232 | PointerMotionMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask);
233 XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask
234 | PointerMotionMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask);
236 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
237 fprintf(stderr, "%s: can't allocate window name\n", wname);
238 exit(1);
241 XSetWMName(display, win, &name);
244 * Create Graphics Context (GC) for drawing
246 gcm = GCForeground | GCBackground | GCGraphicsExposures;
247 gcv.foreground = fore_pix;
248 gcv.background = back_pix;
249 gcv.graphics_exposures = 0;
250 NormalGC = XCreateGC(display, Root, gcm, &gcv);
253 * Create Graphics Context (GC) for erasing
255 gcm = GCForeground | GCBackground | GCGraphicsExposures;
256 gcv.foreground = back_pix;
257 gcv.background = back_pix;
258 gcv.graphics_exposures = 0;
259 EraseGC = XCreateGC(display, Root, gcm, &gcv);
261 pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
262 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
263 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
265 mywmhints.initial_state = WithdrawnState;
266 mywmhints.icon_window = iconwin;
267 mywmhints.icon_x = mysizehints.x;
268 mywmhints.icon_y = mysizehints.y;
269 mywmhints.window_group = win;
270 mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
272 XSetWMHints(display, win, &mywmhints);
274 XSetCommand(display, win, argv, argc);
275 XMapWindow(display, win);
279 unsigned long getColor(char *ColorName, float fac, int *red, int *grn, int *blu)
282 XColor Color;
283 XWindowAttributes Attributes;
285 XGetWindowAttributes(display, Root, &Attributes);
286 Color.pixel = 0;
288 XParseColor(display, Attributes.colormap, ColorName, &Color);
289 Color.red = (unsigned short)(fac * (Color.red - 24) + 24);
290 Color.blue = (unsigned short)(fac * (Color.blue - 24) + 24);
291 Color.green = (unsigned short)(fac * (Color.green - 24) + 24);
292 Color.flags = DoRed | DoGreen | DoBlue;
293 XAllocColor(display, Attributes.colormap, &Color);
295 *red = Color.red;
296 *grn = Color.green;
297 *blu = Color.blue;
298 return Color.pixel;
302 unsigned long getBlendedColor(char *ColorName, float fac, int red, int grn, int blu)
305 XColor Color;
306 XWindowAttributes Attributes;
308 XGetWindowAttributes(display, Root, &Attributes);
309 Color.pixel = 0;
311 XParseColor(display, Attributes.colormap, ColorName, &Color);
312 Color.red = (unsigned short)(fac * (Color.red - red) + red);
313 Color.blue = (unsigned short)(fac * (Color.blue - grn) + grn);
314 Color.green = (unsigned short)(fac * (Color.green - blu) + blu);
315 Color.flags = DoRed | DoGreen | DoBlue;
316 XAllocColor(display, Attributes.colormap, &Color);
318 return Color.pixel;
323 * Here is a faster version of usleep using select()
325 void uusleep(unsigned long usecs)
328 struct timeval tv;
329 fd_set fds;
330 tv.tv_sec = usecs / 1000000UL;
331 tv.tv_usec = usecs % 1000000UL;
332 FD_ZERO(&fds);
333 FD_SET(x_fd, &fds);
334 select(x_fd + 1, &fds, NULL, NULL, &tv);
339 * This version assumes the tv_sec value will be zero. I.e. the delay
340 * will be less than 1 second. This allows us to save on a div operation.
343 void short_uusleep(unsigned long usecs)
346 struct timeval tv;
347 fd_set fds;
348 tv.tv_sec = 0;
349 tv.tv_usec = usecs;
350 FD_ZERO(&fds);
351 FD_SET(x_fd, &fds);
352 select(x_fd + 1, &fds, NULL, NULL, &tv);