Blame


1 038e9089 2004-03-21 devnull /* Copyright (c) 1994-1996 David Hogan, see README for licence details */
2 038e9089 2004-03-21 devnull #include <stdio.h>
3 038e9089 2004-03-21 devnull #include <signal.h>
4 038e9089 2004-03-21 devnull #include <errno.h>
5 e62ba5ec 2004-03-21 devnull #include <stdlib.h>
6 e62ba5ec 2004-03-21 devnull #include <unistd.h>
7 038e9089 2004-03-21 devnull #include <X11/X.h>
8 038e9089 2004-03-21 devnull #include <X11/Xos.h>
9 038e9089 2004-03-21 devnull #include <X11/Xlib.h>
10 038e9089 2004-03-21 devnull #include <X11/Xutil.h>
11 038e9089 2004-03-21 devnull #include <X11/Xatom.h>
12 8ad51794 2004-03-25 devnull #ifdef SHAPE
13 8ad51794 2004-03-25 devnull #include <X11/extensions/shape.h>
14 8ad51794 2004-03-25 devnull #endif
15 038e9089 2004-03-21 devnull #include "dat.h"
16 038e9089 2004-03-21 devnull #include "fns.h"
17 038e9089 2004-03-21 devnull #include "patchlevel.h"
18 038e9089 2004-03-21 devnull
19 038e9089 2004-03-21 devnull char *version[] =
20 038e9089 2004-03-21 devnull {
21 038e9089 2004-03-21 devnull "rio version 1.0, Copyright (c) 1994-1996 David Hogan, (c) 2004 Russ Cox", 0,
22 038e9089 2004-03-21 devnull };
23 038e9089 2004-03-21 devnull
24 038e9089 2004-03-21 devnull Display *dpy;
25 038e9089 2004-03-21 devnull ScreenInfo *screens;
26 038e9089 2004-03-21 devnull int initting;
27 038e9089 2004-03-21 devnull XFontStruct *font;
28 038e9089 2004-03-21 devnull int nostalgia;
29 038e9089 2004-03-21 devnull char **myargv;
30 038e9089 2004-03-21 devnull char *termprog;
31 038e9089 2004-03-21 devnull char *shell;
32 038e9089 2004-03-21 devnull Bool shape;
33 038e9089 2004-03-21 devnull int _border = 4;
34 1cb3fa80 2004-03-29 devnull int _corner = 25;
35 038e9089 2004-03-21 devnull int _inset = 1;
36 038e9089 2004-03-21 devnull int curtime;
37 038e9089 2004-03-21 devnull int debug;
38 038e9089 2004-03-21 devnull int signalled;
39 038e9089 2004-03-21 devnull int num_screens;
40 038e9089 2004-03-21 devnull int solidsweep = 0;
41 038e9089 2004-03-21 devnull
42 038e9089 2004-03-21 devnull Atom exit_9wm;
43 038e9089 2004-03-21 devnull Atom restart_9wm;
44 038e9089 2004-03-21 devnull Atom wm_state;
45 038e9089 2004-03-21 devnull Atom wm_change_state;
46 038e9089 2004-03-21 devnull Atom wm_protocols;
47 038e9089 2004-03-21 devnull Atom wm_delete;
48 038e9089 2004-03-21 devnull Atom wm_take_focus;
49 c005568a 2004-03-30 devnull Atom wm_lose_focus;
50 038e9089 2004-03-21 devnull Atom wm_colormaps;
51 038e9089 2004-03-21 devnull Atom _9wm_running;
52 038e9089 2004-03-21 devnull Atom _9wm_hold_mode;
53 038e9089 2004-03-21 devnull
54 038e9089 2004-03-21 devnull char *fontlist[] = {
55 038e9089 2004-03-21 devnull "lucm.latin1.9",
56 038e9089 2004-03-21 devnull "blit",
57 e62ba5ec 2004-03-21 devnull "*-lucidatypewriter-bold-*-14-*-75-*",
58 e62ba5ec 2004-03-21 devnull "*-lucidatypewriter-medium-*-12-*-75-*",
59 038e9089 2004-03-21 devnull "9x15bold",
60 038e9089 2004-03-21 devnull "fixed",
61 038e9089 2004-03-21 devnull "*",
62 038e9089 2004-03-21 devnull 0,
63 038e9089 2004-03-21 devnull };
64 038e9089 2004-03-21 devnull
65 038e9089 2004-03-21 devnull void
66 038e9089 2004-03-21 devnull usage(void)
67 038e9089 2004-03-21 devnull {
68 038e9089 2004-03-21 devnull fprintf(stderr, "usage: rio [-grey] [-version] [-font fname] [-term prog] [exit|restart]\n");
69 038e9089 2004-03-21 devnull exit(1);
70 038e9089 2004-03-21 devnull }
71 038e9089 2004-03-21 devnull
72 038e9089 2004-03-21 devnull int
73 038e9089 2004-03-21 devnull main(int argc, char *argv[])
74 038e9089 2004-03-21 devnull {
75 038e9089 2004-03-21 devnull int i, background, do_exit, do_restart;
76 038e9089 2004-03-21 devnull char *fname;
77 e62ba5ec 2004-03-21 devnull int shape_event;
78 8ad51794 2004-03-25 devnull #ifdef SHAPE
79 8ad51794 2004-03-25 devnull int dummy;
80 8ad51794 2004-03-25 devnull #endif
81 038e9089 2004-03-21 devnull
82 e62ba5ec 2004-03-21 devnull shape_event = 0;
83 038e9089 2004-03-21 devnull myargv = argv; /* for restart */
84 038e9089 2004-03-21 devnull
85 038e9089 2004-03-21 devnull do_exit = do_restart = 0;
86 8ad51794 2004-03-25 devnull background = 0;
87 038e9089 2004-03-21 devnull font = 0;
88 038e9089 2004-03-21 devnull fname = 0;
89 038e9089 2004-03-21 devnull for (i = 1; i < argc; i++)
90 038e9089 2004-03-21 devnull if (strcmp(argv[i], "-nostalgia") == 0)
91 038e9089 2004-03-21 devnull nostalgia++;
92 038e9089 2004-03-21 devnull else if (strcmp(argv[i], "-grey") == 0)
93 038e9089 2004-03-21 devnull background = 1;
94 038e9089 2004-03-21 devnull else if (strcmp(argv[i], "-debug") == 0)
95 038e9089 2004-03-21 devnull debug++;
96 038e9089 2004-03-21 devnull else if (strcmp(argv[i], "-font") == 0 && i+1<argc) {
97 038e9089 2004-03-21 devnull i++;
98 038e9089 2004-03-21 devnull fname = argv[i];
99 038e9089 2004-03-21 devnull }
100 038e9089 2004-03-21 devnull else if (strcmp(argv[i], "-term") == 0 && i+1<argc)
101 038e9089 2004-03-21 devnull termprog = argv[++i];
102 038e9089 2004-03-21 devnull else if (strcmp(argv[i], "-version") == 0) {
103 038e9089 2004-03-21 devnull fprintf(stderr, "%s", version[0]);
104 038e9089 2004-03-21 devnull if (PATCHLEVEL > 0)
105 038e9089 2004-03-21 devnull fprintf(stderr, "; patch level %d", PATCHLEVEL);
106 038e9089 2004-03-21 devnull fprintf(stderr, "\n");
107 038e9089 2004-03-21 devnull exit(0);
108 038e9089 2004-03-21 devnull }
109 038e9089 2004-03-21 devnull else if (argv[i][0] == '-')
110 038e9089 2004-03-21 devnull usage();
111 038e9089 2004-03-21 devnull else
112 038e9089 2004-03-21 devnull break;
113 038e9089 2004-03-21 devnull for (; i < argc; i++)
114 038e9089 2004-03-21 devnull if (strcmp(argv[i], "exit") == 0)
115 038e9089 2004-03-21 devnull do_exit++;
116 038e9089 2004-03-21 devnull else if (strcmp(argv[i], "restart") == 0)
117 038e9089 2004-03-21 devnull do_restart++;
118 038e9089 2004-03-21 devnull else
119 038e9089 2004-03-21 devnull usage();
120 038e9089 2004-03-21 devnull
121 038e9089 2004-03-21 devnull if (do_exit && do_restart)
122 038e9089 2004-03-21 devnull usage();
123 038e9089 2004-03-21 devnull
124 038e9089 2004-03-21 devnull shell = (char *)getenv("SHELL");
125 038e9089 2004-03-21 devnull if (shell == NULL)
126 038e9089 2004-03-21 devnull shell = DEFSHELL;
127 038e9089 2004-03-21 devnull
128 038e9089 2004-03-21 devnull dpy = XOpenDisplay("");
129 038e9089 2004-03-21 devnull if (dpy == 0)
130 038e9089 2004-03-21 devnull fatal("can't open display");
131 038e9089 2004-03-21 devnull
132 038e9089 2004-03-21 devnull initting = 1;
133 038e9089 2004-03-21 devnull XSetErrorHandler(handler);
134 038e9089 2004-03-21 devnull if (signal(SIGTERM, sighandler) == SIG_IGN)
135 038e9089 2004-03-21 devnull signal(SIGTERM, SIG_IGN);
136 038e9089 2004-03-21 devnull if (signal(SIGINT, sighandler) == SIG_IGN)
137 038e9089 2004-03-21 devnull signal(SIGINT, SIG_IGN);
138 038e9089 2004-03-21 devnull if (signal(SIGHUP, sighandler) == SIG_IGN)
139 038e9089 2004-03-21 devnull signal(SIGHUP, SIG_IGN);
140 038e9089 2004-03-21 devnull
141 038e9089 2004-03-21 devnull exit_9wm = XInternAtom(dpy, "9WM_EXIT", False);
142 038e9089 2004-03-21 devnull restart_9wm = XInternAtom(dpy, "9WM_RESTART", False);
143 038e9089 2004-03-21 devnull
144 038e9089 2004-03-21 devnull curtime = -1; /* don't care */
145 038e9089 2004-03-21 devnull if (do_exit) {
146 038e9089 2004-03-21 devnull sendcmessage(DefaultRootWindow(dpy), exit_9wm, 0L, 1);
147 038e9089 2004-03-21 devnull XSync(dpy, False);
148 038e9089 2004-03-21 devnull exit(0);
149 038e9089 2004-03-21 devnull }
150 038e9089 2004-03-21 devnull if (do_restart) {
151 038e9089 2004-03-21 devnull sendcmessage(DefaultRootWindow(dpy), restart_9wm, 0L, 1);
152 038e9089 2004-03-21 devnull XSync(dpy, False);
153 038e9089 2004-03-21 devnull exit(0);
154 038e9089 2004-03-21 devnull }
155 038e9089 2004-03-21 devnull
156 c005568a 2004-03-30 devnull if (0) XSynchronize(dpy, True);
157 c005568a 2004-03-30 devnull
158 038e9089 2004-03-21 devnull wm_state = XInternAtom(dpy, "WM_STATE", False);
159 038e9089 2004-03-21 devnull wm_change_state = XInternAtom(dpy, "WM_CHANGE_STATE", False);
160 038e9089 2004-03-21 devnull wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
161 038e9089 2004-03-21 devnull wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
162 038e9089 2004-03-21 devnull wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
163 c005568a 2004-03-30 devnull wm_lose_focus = XInternAtom(dpy, "_9WM_LOSE_FOCUS", False);
164 038e9089 2004-03-21 devnull wm_colormaps = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False);
165 038e9089 2004-03-21 devnull _9wm_running = XInternAtom(dpy, "_9WM_RUNNING", False);
166 038e9089 2004-03-21 devnull _9wm_hold_mode = XInternAtom(dpy, "_9WM_HOLD_MODE", False);
167 038e9089 2004-03-21 devnull
168 038e9089 2004-03-21 devnull if (fname != 0)
169 038e9089 2004-03-21 devnull if ((font = XLoadQueryFont(dpy, fname)) == 0)
170 038e9089 2004-03-21 devnull fprintf(stderr, "9wm: warning: can't load font %s\n", fname);
171 038e9089 2004-03-21 devnull
172 038e9089 2004-03-21 devnull if (font == 0) {
173 038e9089 2004-03-21 devnull i = 0;
174 038e9089 2004-03-21 devnull for (;;) {
175 038e9089 2004-03-21 devnull fname = fontlist[i++];
176 038e9089 2004-03-21 devnull if (fname == 0) {
177 038e9089 2004-03-21 devnull fprintf(stderr, "9wm: warning: can't find a font\n");
178 038e9089 2004-03-21 devnull break;
179 038e9089 2004-03-21 devnull }
180 038e9089 2004-03-21 devnull font = XLoadQueryFont(dpy, fname);
181 038e9089 2004-03-21 devnull if (font != 0)
182 038e9089 2004-03-21 devnull break;
183 038e9089 2004-03-21 devnull }
184 038e9089 2004-03-21 devnull }
185 038e9089 2004-03-21 devnull if (nostalgia) {
186 038e9089 2004-03-21 devnull _border--;
187 038e9089 2004-03-21 devnull _inset--;
188 038e9089 2004-03-21 devnull }
189 038e9089 2004-03-21 devnull
190 038e9089 2004-03-21 devnull #ifdef SHAPE
191 038e9089 2004-03-21 devnull shape = XShapeQueryExtension(dpy, &shape_event, &dummy);
192 038e9089 2004-03-21 devnull #endif
193 038e9089 2004-03-21 devnull
194 038e9089 2004-03-21 devnull num_screens = ScreenCount(dpy);
195 038e9089 2004-03-21 devnull screens = (ScreenInfo *)malloc(sizeof(ScreenInfo) * num_screens);
196 038e9089 2004-03-21 devnull
197 038e9089 2004-03-21 devnull for (i = 0; i < num_screens; i++)
198 038e9089 2004-03-21 devnull initscreen(&screens[i], i, background);
199 038e9089 2004-03-21 devnull
200 038e9089 2004-03-21 devnull /* set selection so that 9term knows we're running */
201 038e9089 2004-03-21 devnull curtime = CurrentTime;
202 038e9089 2004-03-21 devnull XSetSelectionOwner(dpy, _9wm_running, screens[0].menuwin, timestamp());
203 038e9089 2004-03-21 devnull
204 038e9089 2004-03-21 devnull XSync(dpy, False);
205 038e9089 2004-03-21 devnull initting = 0;
206 038e9089 2004-03-21 devnull
207 038e9089 2004-03-21 devnull nofocus();
208 038e9089 2004-03-21 devnull
209 038e9089 2004-03-21 devnull for (i = 0; i < num_screens; i++)
210 038e9089 2004-03-21 devnull scanwins(&screens[i]);
211 038e9089 2004-03-21 devnull
212 038e9089 2004-03-21 devnull mainloop(shape_event);
213 e62ba5ec 2004-03-21 devnull return 0;
214 038e9089 2004-03-21 devnull }
215 038e9089 2004-03-21 devnull
216 038e9089 2004-03-21 devnull void
217 038e9089 2004-03-21 devnull initscreen(ScreenInfo *s, int i, int background)
218 038e9089 2004-03-21 devnull {
219 038e9089 2004-03-21 devnull char *ds, *colon, *dot1;
220 038e9089 2004-03-21 devnull unsigned long mask;
221 c005568a 2004-03-30 devnull unsigned long gmask;
222 038e9089 2004-03-21 devnull XGCValues gv;
223 038e9089 2004-03-21 devnull XSetWindowAttributes attr;
224 c005568a 2004-03-30 devnull XVisualInfo xvi;
225 c005568a 2004-03-30 devnull XSetWindowAttributes attrs;
226 038e9089 2004-03-21 devnull
227 038e9089 2004-03-21 devnull s->num = i;
228 038e9089 2004-03-21 devnull s->root = RootWindow(dpy, i);
229 038e9089 2004-03-21 devnull s->def_cmap = DefaultColormap(dpy, i);
230 038e9089 2004-03-21 devnull s->min_cmaps = MinCmapsOfScreen(ScreenOfDisplay(dpy, i));
231 038e9089 2004-03-21 devnull s->depth = DefaultDepth(dpy, i);
232 038e9089 2004-03-21 devnull
233 c005568a 2004-03-30 devnull /*
234 c005568a 2004-03-30 devnull * Figure out underlying screen format.
235 c005568a 2004-03-30 devnull */
236 c005568a 2004-03-30 devnull if(XMatchVisualInfo(dpy, i, 16, TrueColor, &xvi)
237 c005568a 2004-03-30 devnull || XMatchVisualInfo(dpy, i, 16, DirectColor, &xvi)){
238 c005568a 2004-03-30 devnull s->vis = xvi.visual;
239 c005568a 2004-03-30 devnull s->depth = 16;
240 c005568a 2004-03-30 devnull }
241 c005568a 2004-03-30 devnull else
242 c005568a 2004-03-30 devnull if(XMatchVisualInfo(dpy, i, 15, TrueColor, &xvi)
243 c005568a 2004-03-30 devnull || XMatchVisualInfo(dpy, i, 15, DirectColor, &xvi)){
244 c005568a 2004-03-30 devnull s->vis = xvi.visual;
245 c005568a 2004-03-30 devnull s->depth = 15;
246 c005568a 2004-03-30 devnull }
247 c005568a 2004-03-30 devnull else
248 c005568a 2004-03-30 devnull if(XMatchVisualInfo(dpy, i, 24, TrueColor, &xvi)
249 c005568a 2004-03-30 devnull || XMatchVisualInfo(dpy, i, 24, DirectColor, &xvi)){
250 c005568a 2004-03-30 devnull s->vis = xvi.visual;
251 c005568a 2004-03-30 devnull s->depth = 24;
252 c005568a 2004-03-30 devnull }
253 c005568a 2004-03-30 devnull else
254 c005568a 2004-03-30 devnull if(XMatchVisualInfo(dpy, i, 8, PseudoColor, &xvi)
255 c005568a 2004-03-30 devnull || XMatchVisualInfo(dpy, i, 8, StaticColor, &xvi)){
256 c005568a 2004-03-30 devnull s->vis = xvi.visual;
257 c005568a 2004-03-30 devnull s->depth = 8;
258 c005568a 2004-03-30 devnull }
259 c005568a 2004-03-30 devnull else{
260 c005568a 2004-03-30 devnull s->depth = DefaultDepth(dpy, i);
261 c005568a 2004-03-30 devnull if(s->depth != 8){
262 c005568a 2004-03-30 devnull fprintf(stderr, "can't understand depth %d screen", s->depth);
263 c005568a 2004-03-30 devnull exit(1);
264 c005568a 2004-03-30 devnull }
265 c005568a 2004-03-30 devnull s->vis = DefaultVisual(dpy, i);
266 c005568a 2004-03-30 devnull }
267 c005568a 2004-03-30 devnull if(DefaultDepth(dpy, i) != s->depth) {
268 c005568a 2004-03-30 devnull s->def_cmap = XCreateColormap(dpy, s->root, s->vis, AllocNone);
269 c005568a 2004-03-30 devnull }
270 c005568a 2004-03-30 devnull
271 038e9089 2004-03-21 devnull ds = DisplayString(dpy);
272 038e9089 2004-03-21 devnull colon = rindex(ds, ':');
273 038e9089 2004-03-21 devnull if (colon && num_screens > 1) {
274 038e9089 2004-03-21 devnull strcpy(s->display, "DISPLAY=");
275 038e9089 2004-03-21 devnull strcat(s->display, ds);
276 038e9089 2004-03-21 devnull colon = s->display + 8 + (colon - ds); /* use version in buf */
277 038e9089 2004-03-21 devnull dot1 = index(colon, '.'); /* first period after colon */
278 038e9089 2004-03-21 devnull if (!dot1)
279 038e9089 2004-03-21 devnull dot1 = colon + strlen(colon); /* if not there, append */
280 038e9089 2004-03-21 devnull sprintf(dot1, ".%d", i);
281 038e9089 2004-03-21 devnull }
282 038e9089 2004-03-21 devnull else
283 038e9089 2004-03-21 devnull s->display[0] = '\0';
284 038e9089 2004-03-21 devnull
285 038e9089 2004-03-21 devnull s->black = BlackPixel(dpy, i);
286 038e9089 2004-03-21 devnull s->white = WhitePixel(dpy, i);
287 7934b1c6 2004-04-05 devnull s->activeholdborder = colorpixel(dpy, s, s->depth, 0x000099, s->white);
288 7934b1c6 2004-04-05 devnull s->inactiveholdborder = colorpixel(dpy, s, s->depth, 0x005DBB, s->black);
289 7934b1c6 2004-04-05 devnull s->activeborder = colorpixel(dpy, s, s->depth, 0x55AAAA, s->black);
290 7934b1c6 2004-04-05 devnull s->inactiveborder = colorpixel(dpy, s, s->depth, 0x9EEEEE, s->white);
291 7934b1c6 2004-04-05 devnull s->red = colorpixel(dpy, s, s->depth, 0xDD0000, s->white);
292 038e9089 2004-03-21 devnull s->width = WidthOfScreen(ScreenOfDisplay(dpy, i));
293 038e9089 2004-03-21 devnull s->height = HeightOfScreen(ScreenOfDisplay(dpy, i));
294 038e9089 2004-03-21 devnull s->bkup[0] = XCreatePixmap(dpy, s->root, 2*s->width, BORDER, DefaultDepth(dpy, i));
295 038e9089 2004-03-21 devnull s->bkup[1] = XCreatePixmap(dpy, s->root, BORDER, 2*s->height, DefaultDepth(dpy, i));
296 038e9089 2004-03-21 devnull
297 038e9089 2004-03-21 devnull gv.foreground = s->black^s->white;
298 038e9089 2004-03-21 devnull gv.background = s->white;
299 038e9089 2004-03-21 devnull gv.function = GXxor;
300 038e9089 2004-03-21 devnull gv.line_width = 0;
301 038e9089 2004-03-21 devnull gv.subwindow_mode = IncludeInferiors;
302 c005568a 2004-03-30 devnull gmask = GCForeground | GCBackground | GCFunction | GCLineWidth
303 038e9089 2004-03-21 devnull | GCSubwindowMode;
304 038e9089 2004-03-21 devnull if (font != 0) {
305 038e9089 2004-03-21 devnull gv.font = font->fid;
306 c005568a 2004-03-30 devnull gmask |= GCFont;
307 038e9089 2004-03-21 devnull }
308 c005568a 2004-03-30 devnull s->gc = XCreateGC(dpy, s->root, gmask, &gv);
309 038e9089 2004-03-21 devnull
310 038e9089 2004-03-21 devnull gv.function = GXcopy;
311 c005568a 2004-03-30 devnull s->gccopy = XCreateGC(dpy, s->root, gmask, &gv);
312 038e9089 2004-03-21 devnull
313 038e9089 2004-03-21 devnull gv.foreground = s->red;
314 c005568a 2004-03-30 devnull s->gcred = XCreateGC(dpy, s->root, gmask, &gv);
315 038e9089 2004-03-21 devnull
316 7934b1c6 2004-04-05 devnull gv.foreground = colorpixel(dpy, s, s->depth, 0xEEEEEE, s->black);
317 c005568a 2004-03-30 devnull s->gcsweep = XCreateGC(dpy, s->root, gmask, &gv);
318 038e9089 2004-03-21 devnull
319 038e9089 2004-03-21 devnull initcurs(s);
320 038e9089 2004-03-21 devnull
321 038e9089 2004-03-21 devnull attr.cursor = s->arrow;
322 038e9089 2004-03-21 devnull attr.event_mask = SubstructureRedirectMask
323 038e9089 2004-03-21 devnull | SubstructureNotifyMask | ColormapChangeMask
324 038e9089 2004-03-21 devnull | ButtonPressMask | ButtonReleaseMask | PropertyChangeMask;
325 038e9089 2004-03-21 devnull mask = CWCursor|CWEventMask;
326 038e9089 2004-03-21 devnull XChangeWindowAttributes(dpy, s->root, mask, &attr);
327 038e9089 2004-03-21 devnull XSync(dpy, False);
328 038e9089 2004-03-21 devnull
329 038e9089 2004-03-21 devnull if (background) {
330 038e9089 2004-03-21 devnull XSetWindowBackgroundPixmap(dpy, s->root, s->root_pixmap);
331 038e9089 2004-03-21 devnull XClearWindow(dpy, s->root);
332 8ad51794 2004-03-25 devnull } else
333 038e9089 2004-03-21 devnull system("xsetroot -solid grey30");
334 c005568a 2004-03-30 devnull
335 7934b1c6 2004-04-05 devnull attrs.border_pixel = colorpixel(dpy, s, s->depth, 0x88CC88, s->black);
336 7934b1c6 2004-04-05 devnull attrs.background_pixel = colorpixel(dpy, s, s->depth, 0xE9FFE9, s->white);
337 c005568a 2004-03-30 devnull attrs.colormap = s->def_cmap;
338 c005568a 2004-03-30 devnull
339 c005568a 2004-03-30 devnull s->menuwin = XCreateWindow(dpy, s->root, 0, 0, 1, 1, 2,
340 c005568a 2004-03-30 devnull s->depth,
341 c005568a 2004-03-30 devnull CopyFromParent,
342 c005568a 2004-03-30 devnull s->vis,
343 7934b1c6 2004-04-05 devnull CWBackPixel | CWBorderPixel | CWColormap,
344 c005568a 2004-03-30 devnull &attrs
345 c005568a 2004-03-30 devnull );
346 c005568a 2004-03-30 devnull
347 7934b1c6 2004-04-05 devnull
348 7934b1c6 2004-04-05 devnull gv.foreground = colorpixel(dpy, s, s->depth, 0xE9FFE9, s->white);
349 7934b1c6 2004-04-05 devnull s->gcmenubg = XCreateGC(dpy, s->menuwin, gmask, &gv);
350 7934b1c6 2004-04-05 devnull
351 7934b1c6 2004-04-05 devnull gv.foreground = colorpixel(dpy, s, s->depth, 0x448844, s->black);
352 7934b1c6 2004-04-05 devnull s->gcmenubgs = XCreateGC(dpy, s->menuwin, gmask, &gv);
353 7934b1c6 2004-04-05 devnull
354 7934b1c6 2004-04-05 devnull gv.foreground = s->black;
355 7934b1c6 2004-04-05 devnull gv.background = colorpixel(dpy, s, s->depth, 0xE9FFE9, s->white);
356 7934b1c6 2004-04-05 devnull s->gcmenufg = XCreateGC(dpy, s->menuwin, gmask, &gv);
357 7934b1c6 2004-04-05 devnull
358 7934b1c6 2004-04-05 devnull gv.foreground = colorpixel(dpy, s, s->depth, 0xE9FFE9, s->white);
359 7934b1c6 2004-04-05 devnull gv.background = colorpixel(dpy, s, s->depth, 0x448844, s->black);
360 7934b1c6 2004-04-05 devnull s->gcmenufgs = XCreateGC(dpy, s->menuwin, gmask, &gv);
361 7934b1c6 2004-04-05 devnull
362 c005568a 2004-03-30 devnull attrs.border_pixel = s->red;
363 7934b1c6 2004-04-05 devnull attrs.background_pixel = colorpixel(dpy, s, s->depth, 0xEEEEEE, s->black);
364 c005568a 2004-03-30 devnull attrs.colormap = s->def_cmap;
365 1cb3fa80 2004-03-29 devnull s->sweepwin = XCreateWindow(dpy, s->root, 0, 0, 1, 1, 4,
366 c005568a 2004-03-30 devnull s->depth,
367 1cb3fa80 2004-03-29 devnull CopyFromParent,
368 c005568a 2004-03-30 devnull s->vis,
369 7934b1c6 2004-04-05 devnull CWBackPixel | CWBorderPixel | CWColormap,
370 1cb3fa80 2004-03-29 devnull &attrs
371 1cb3fa80 2004-03-29 devnull );
372 038e9089 2004-03-21 devnull }
373 038e9089 2004-03-21 devnull
374 038e9089 2004-03-21 devnull ScreenInfo*
375 038e9089 2004-03-21 devnull getscreen(Window w)
376 038e9089 2004-03-21 devnull {
377 038e9089 2004-03-21 devnull int i;
378 038e9089 2004-03-21 devnull
379 038e9089 2004-03-21 devnull for (i = 0; i < num_screens; i++)
380 038e9089 2004-03-21 devnull if (screens[i].root == w)
381 038e9089 2004-03-21 devnull return &screens[i];
382 038e9089 2004-03-21 devnull
383 038e9089 2004-03-21 devnull return 0;
384 038e9089 2004-03-21 devnull }
385 038e9089 2004-03-21 devnull
386 038e9089 2004-03-21 devnull Time
387 038e9089 2004-03-21 devnull timestamp(void)
388 038e9089 2004-03-21 devnull {
389 038e9089 2004-03-21 devnull XEvent ev;
390 038e9089 2004-03-21 devnull
391 038e9089 2004-03-21 devnull if (curtime == CurrentTime) {
392 038e9089 2004-03-21 devnull XChangeProperty(dpy, screens[0].root, _9wm_running, _9wm_running, 8,
393 038e9089 2004-03-21 devnull PropModeAppend, (unsigned char *)"", 0);
394 038e9089 2004-03-21 devnull XMaskEvent(dpy, PropertyChangeMask, &ev);
395 038e9089 2004-03-21 devnull curtime = ev.xproperty.time;
396 038e9089 2004-03-21 devnull }
397 038e9089 2004-03-21 devnull return curtime;
398 038e9089 2004-03-21 devnull }
399 038e9089 2004-03-21 devnull
400 038e9089 2004-03-21 devnull void
401 038e9089 2004-03-21 devnull sendcmessage(Window w, Atom a, long x, int isroot)
402 038e9089 2004-03-21 devnull {
403 038e9089 2004-03-21 devnull XEvent ev;
404 038e9089 2004-03-21 devnull int status;
405 038e9089 2004-03-21 devnull long mask;
406 038e9089 2004-03-21 devnull
407 038e9089 2004-03-21 devnull memset(&ev, 0, sizeof(ev));
408 038e9089 2004-03-21 devnull ev.xclient.type = ClientMessage;
409 038e9089 2004-03-21 devnull ev.xclient.window = w;
410 038e9089 2004-03-21 devnull ev.xclient.message_type = a;
411 038e9089 2004-03-21 devnull ev.xclient.format = 32;
412 038e9089 2004-03-21 devnull ev.xclient.data.l[0] = x;
413 038e9089 2004-03-21 devnull ev.xclient.data.l[1] = timestamp();
414 038e9089 2004-03-21 devnull mask = 0L;
415 038e9089 2004-03-21 devnull if (isroot)
416 038e9089 2004-03-21 devnull mask = SubstructureRedirectMask; /* magic! */
417 c005568a 2004-03-30 devnull else
418 c005568a 2004-03-30 devnull mask = ExposureMask; /* not really correct but so be it */
419 038e9089 2004-03-21 devnull status = XSendEvent(dpy, w, False, mask, &ev);
420 038e9089 2004-03-21 devnull if (status == 0)
421 038e9089 2004-03-21 devnull fprintf(stderr, "9wm: sendcmessage failed\n");
422 038e9089 2004-03-21 devnull }
423 038e9089 2004-03-21 devnull
424 038e9089 2004-03-21 devnull void
425 038e9089 2004-03-21 devnull sendconfig(Client *c)
426 038e9089 2004-03-21 devnull {
427 038e9089 2004-03-21 devnull XConfigureEvent ce;
428 038e9089 2004-03-21 devnull
429 038e9089 2004-03-21 devnull ce.type = ConfigureNotify;
430 038e9089 2004-03-21 devnull ce.event = c->window;
431 038e9089 2004-03-21 devnull ce.window = c->window;
432 038e9089 2004-03-21 devnull ce.x = c->x;
433 038e9089 2004-03-21 devnull ce.y = c->y;
434 038e9089 2004-03-21 devnull ce.width = c->dx;
435 038e9089 2004-03-21 devnull ce.height = c->dy;
436 038e9089 2004-03-21 devnull ce.border_width = c->border;
437 038e9089 2004-03-21 devnull ce.above = None;
438 038e9089 2004-03-21 devnull ce.override_redirect = 0;
439 038e9089 2004-03-21 devnull XSendEvent(dpy, c->window, False, StructureNotifyMask, (XEvent*)&ce);
440 038e9089 2004-03-21 devnull }
441 038e9089 2004-03-21 devnull
442 038e9089 2004-03-21 devnull void
443 038e9089 2004-03-21 devnull sighandler(void)
444 038e9089 2004-03-21 devnull {
445 038e9089 2004-03-21 devnull signalled = 1;
446 038e9089 2004-03-21 devnull }
447 038e9089 2004-03-21 devnull
448 038e9089 2004-03-21 devnull void
449 038e9089 2004-03-21 devnull getevent(XEvent *e)
450 038e9089 2004-03-21 devnull {
451 038e9089 2004-03-21 devnull int fd;
452 038e9089 2004-03-21 devnull fd_set rfds;
453 038e9089 2004-03-21 devnull struct timeval t;
454 038e9089 2004-03-21 devnull
455 038e9089 2004-03-21 devnull if (!signalled) {
456 038e9089 2004-03-21 devnull if (QLength(dpy) > 0) {
457 038e9089 2004-03-21 devnull XNextEvent(dpy, e);
458 038e9089 2004-03-21 devnull return;
459 038e9089 2004-03-21 devnull }
460 038e9089 2004-03-21 devnull fd = ConnectionNumber(dpy);
461 038e9089 2004-03-21 devnull FD_ZERO(&rfds);
462 038e9089 2004-03-21 devnull FD_SET(fd, &rfds);
463 038e9089 2004-03-21 devnull t.tv_sec = t.tv_usec = 0;
464 038e9089 2004-03-21 devnull if (select(fd+1, &rfds, NULL, NULL, &t) == 1) {
465 038e9089 2004-03-21 devnull XNextEvent(dpy, e);
466 038e9089 2004-03-21 devnull return;
467 038e9089 2004-03-21 devnull }
468 038e9089 2004-03-21 devnull XFlush(dpy);
469 038e9089 2004-03-21 devnull FD_SET(fd, &rfds);
470 038e9089 2004-03-21 devnull if (select(fd+1, &rfds, NULL, NULL, NULL) == 1) {
471 038e9089 2004-03-21 devnull XNextEvent(dpy, e);
472 038e9089 2004-03-21 devnull return;
473 038e9089 2004-03-21 devnull }
474 038e9089 2004-03-21 devnull if (errno != EINTR || !signalled) {
475 038e9089 2004-03-21 devnull perror("9wm: select failed");
476 038e9089 2004-03-21 devnull exit(1);
477 038e9089 2004-03-21 devnull }
478 038e9089 2004-03-21 devnull }
479 038e9089 2004-03-21 devnull fprintf(stderr, "9wm: exiting on signal\n");
480 038e9089 2004-03-21 devnull cleanup();
481 038e9089 2004-03-21 devnull exit(1);
482 038e9089 2004-03-21 devnull }
483 038e9089 2004-03-21 devnull
484 038e9089 2004-03-21 devnull void
485 038e9089 2004-03-21 devnull cleanup(void)
486 038e9089 2004-03-21 devnull {
487 038e9089 2004-03-21 devnull Client *c, *cc[2], *next;
488 038e9089 2004-03-21 devnull XWindowChanges wc;
489 038e9089 2004-03-21 devnull int i;
490 038e9089 2004-03-21 devnull
491 038e9089 2004-03-21 devnull /* order of un-reparenting determines final stacking order... */
492 038e9089 2004-03-21 devnull cc[0] = cc[1] = 0;
493 038e9089 2004-03-21 devnull for (c = clients; c; c = next) {
494 038e9089 2004-03-21 devnull next = c->next;
495 038e9089 2004-03-21 devnull i = normal(c);
496 038e9089 2004-03-21 devnull c->next = cc[i];
497 038e9089 2004-03-21 devnull cc[i] = c;
498 038e9089 2004-03-21 devnull }
499 038e9089 2004-03-21 devnull
500 038e9089 2004-03-21 devnull for (i = 0; i < 2; i++) {
501 038e9089 2004-03-21 devnull for (c = cc[i]; c; c = c->next) {
502 038e9089 2004-03-21 devnull if (!withdrawn(c)) {
503 038e9089 2004-03-21 devnull gravitate(c, 1);
504 038e9089 2004-03-21 devnull XReparentWindow(dpy, c->window, c->screen->root,
505 038e9089 2004-03-21 devnull c->x, c->y);
506 038e9089 2004-03-21 devnull }
507 038e9089 2004-03-21 devnull wc.border_width = c->border;
508 038e9089 2004-03-21 devnull XConfigureWindow(dpy, c->window, CWBorderWidth, &wc);
509 038e9089 2004-03-21 devnull }
510 038e9089 2004-03-21 devnull }
511 038e9089 2004-03-21 devnull
512 038e9089 2004-03-21 devnull XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, timestamp());
513 038e9089 2004-03-21 devnull for (i = 0; i < num_screens; i++)
514 038e9089 2004-03-21 devnull cmapnofocus(&screens[i]);
515 038e9089 2004-03-21 devnull XCloseDisplay(dpy);
516 038e9089 2004-03-21 devnull }