1 /* Copyright (c) 1994-1996 David Hogan, see README for licence details */
9 #include <X11/extensions/shape.h>
12 #include "patchlevel.h"
15 mainloop(int shape_event)
31 if (shape && ev.type == shape_event)
32 shapenotify((XShapeEvent *)&ev);
35 fprintf(stderr, "rio: unknown ev.type %d\n", ev.type);
43 mapreq(&ev.xmaprequest);
45 case ConfigureRequest:
46 configurereq(&ev.xconfigurerequest);
48 case CirculateRequest:
49 circulatereq(&ev.xcirculaterequest);
55 newwindow(&ev.xcreatewindow);
58 destroy(ev.xdestroywindow.window);
61 clientmesg(&ev.xclient);
67 property(&ev.xproperty);
70 fprintf(stderr, "rio: SelectionClear (this should not happen)\n");
73 fprintf(stderr, "rio: SelectionNotify (this should not happen)\n");
75 case SelectionRequest:
76 fprintf(stderr, "rio: SelectionRequest (this should not happen)\n");
85 reparent(&ev.xreparent);
91 motionnotify(&ev.xmotion);
101 trace("ignore", 0, &ev);
109 configurereq(XConfigureRequestEvent *e)
114 /* we don't set curtime as nothing here uses it */
115 c = getclient(e->window, 0);
116 trace("configurereq", c, e);
118 e->value_mask &= ~CWSibling;
122 if (e->value_mask & CWX)
124 if (e->value_mask & CWY)
126 if (e->value_mask & CWWidth)
128 if (e->value_mask & CWHeight)
130 if (e->value_mask & CWBorderWidth)
131 c->border = e->border_width;
133 if (e->value_mask & CWStackMode) {
134 if (wc.stack_mode == Above)
137 e->value_mask &= ~CWStackMode;
139 if (c->parent != c->screen->root && c->window == e->window) {
142 wc.width = c->dx+2*BORDER;
143 wc.height = c->dy+2*BORDER;
146 wc.stack_mode = e->detail;
147 XConfigureWindow(dpy, c->parent, e->value_mask, &wc);
163 wc.height = e->height;
166 wc.stack_mode = Above;
167 e->value_mask &= ~CWStackMode;
168 e->value_mask |= CWBorderWidth;
170 XConfigureWindow(dpy, e->window, e->value_mask, &wc);
174 mapreq(XMapRequestEvent *e)
179 curtime = CurrentTime;
180 c = getclient(e->window, 0);
181 trace("mapreq", c, e);
183 if (c == 0 || c->window != e->window) {
184 /* workaround for stupid NCDware */
185 fprintf(stderr, "rio: bad mapreq c %p w %x, rescanning\n",
187 for (i = 0; i < num_screens; i++)
188 scanwins(&screens[i]);
189 c = getclient(e->window, 0);
190 if (c == 0 || c->window != e->window) {
191 fprintf(stderr, "rio: window not found after rescan\n");
198 if (c->parent == c->screen->root) {
203 XReparentWindow(dpy, c->window, c->parent, BORDER-1, BORDER-1);
204 XAddToSaveSet(dpy, c->window);
205 /* fall through... */
207 XMapWindow(dpy, c->window);
208 XMapRaised(dpy, c->parent);
210 setstate(c, NormalState);
211 if (c->trans != None && current && c->trans == current->window)
221 unmap(XUnmapEvent *e)
225 curtime = CurrentTime;
226 c = getclient(e->window, 0);
247 circulatereq(XCirculateRequestEvent *e)
249 fprintf(stderr, "It must be the warlock Krill!\n"); /* ☺ */
253 newwindow(XCreateWindowEvent *e)
258 /* we don't set curtime as nothing here uses it */
259 if (e->override_redirect)
261 c = getclient(e->window, 1);
262 if (c && c->window == e->window && (s = getscreen(e->parent))) {
267 c->border = e->border_width;
269 if (c->parent == None)
270 c->parent = c->screen->root;
279 curtime = CurrentTime;
286 /* flush any errors generated by the window's sudden demise */
287 ignore_badwindow = 1;
289 ignore_badwindow = 0;
293 clientmesg(XClientMessageEvent *e)
297 curtime = CurrentTime;
298 if (e->message_type == exit_rio) {
302 if (e->message_type == restart_rio) {
303 fprintf(stderr, "*** rio restarting ***\n");
305 execvp(myargv[0], myargv);
306 perror("rio: exec failed");
309 if (e->message_type == wm_change_state) {
310 c = getclient(e->window, 0);
311 if (e->format == 32 && e->data.l[0] == IconicState && c != 0) {
316 fprintf(stderr, "rio: WM_CHANGE_STATE: format %d data %d w 0x%x\n",
317 (int)e->format, (int)e->data.l[0], (int)e->window);
320 fprintf(stderr, "rio: strange ClientMessage, type 0x%x window 0x%x\n",
321 (int)e->message_type, (int)e->window);
325 cmap(XColormapEvent *e)
330 /* we don't set curtime as nothing here uses it */
332 c = getclient(e->window, 0);
334 c->cmap = e->colormap;
339 for (c = clients; c; c = c->next) {
340 for (i = 0; i < c->ncmapwins; i++)
341 if (c->cmapwins[i] == e->window) {
342 c->wmcmaps[i] = e->colormap;
352 property(XPropertyEvent *e)
359 /* we don't set curtime as nothing here uses it */
361 delete = (e->state == PropertyDelete);
362 c = getclient(e->window, 0);
367 case XA_WM_ICON_NAME:
368 if (c->iconname != 0)
369 XFree((char*) c->iconname);
370 c->iconname = delete ? 0 : getprop(c->window, a);
372 renamec(c, c->label);
376 XFree((char*) c->name);
377 c->name = delete ? 0 : getprop(c->window, a);
379 renamec(c, c->label);
381 case XA_WM_TRANSIENT_FOR:
385 case XA_WM_SIZE_HINTS:
386 case XA_WM_ZOOM_HINTS:
387 /* placeholders to not forget. ignore for now. -Axel */
389 case XA_WM_NORMAL_HINTS:
390 if (XGetWMNormalHints(dpy, c->window, &c->size, &msize) == 0 || c->size.flags == 0)
391 c->size.flags = PSize; /* not specified - punt */
394 if (a == _rio_hold_mode) {
395 c->hold = getiprop(c->window, _rio_hold_mode);
399 else if (a == wm_colormaps) {
407 reparent(XReparentEvent *e)
410 XWindowAttributes attr;
413 /* we don't set curtime as nothing here uses it */
414 if (!getscreen(e->event) || e->override_redirect)
416 if ((s = getscreen(e->parent)) != 0) {
417 c = getclient(e->window, 1);
418 if (c != 0 && (c->dx == 0 || c->dy == 0)) {
419 /* flush any errors */
420 ignore_badwindow = 1;
421 XGetWindowAttributes(dpy, c->window, &attr);
423 ignore_badwindow = 0;
429 c->border = attr.border_width;
431 if (c->parent == None)
432 c->parent = c->screen->root;
436 c = getclient(e->window, 0);
437 if (c != 0 && (c->parent == c->screen->root || withdrawn(c)))
444 shapenotify(XShapeEvent *e)
448 /* we don't set curtime as nothing here uses it */
449 c = getclient(e->window, 0);
458 enter(XCrossingEvent *e)
463 if (e->mode != NotifyGrab || e->detail != NotifyNonlinearVirtual)
465 c = getclient(e->window, 0);
466 if (c != 0 && c != current) {
467 /* someone grabbed the pointer; make them current */
468 XMapRaised(dpy, c->parent);
475 leave(XCrossingEvent *e)
479 c = getclient(e->window, 0);
481 XUndefineCursor(dpy, c->parent);
482 /* XDefineCursor(dpy, c->parent, c->screen->arrow); */
486 focusin(XFocusChangeEvent *e)
490 curtime = CurrentTime;
491 if (e->detail != NotifyNonlinearVirtual)
493 c = getclient(e->window, 0);
494 if (c != 0 && c->window == e->window && c != current) {
495 /* someone grabbed keyboard or seized focus; make them current */
496 XMapRaised(dpy, c->parent);
503 borderorient(Client *c, int x, int y)
507 if (debug) fprintf(stderr, "topleft\n");
510 if (y >= (c->dy + 2*BORDER) - CORNER) {
511 if (debug) fprintf(stderr, "botleft\n");
515 y < (c->dy + 2*BORDER) - CORNER) {
516 if (debug) fprintf(stderr, "left\n");
519 } else if (x <= CORNER) {
521 if (debug) fprintf(stderr, "topleft\n");
524 if (y >= (c->dy + BORDER)) {
525 if (debug) fprintf(stderr, "botleft\n");
528 } else if (x >= (c->dx + BORDER)) {
530 if (debug) fprintf(stderr, "topright\n");
533 if (y >= (c->dy + 2*BORDER) - CORNER) {
534 if (debug) fprintf(stderr, "botright\n");
538 y < (c->dy + 2*BORDER) - CORNER) {
539 if (debug) fprintf(stderr, "right\n");
542 } else if (x >= (c->dx + 2*BORDER) - CORNER) {
544 if (debug) fprintf(stderr, "topright\n");
547 if (y >= (c->dy + BORDER)) {
548 if (debug) fprintf(stderr, "botright\n");
551 } else if (x > CORNER &&
552 x < (c->dx + 2*BORDER) - CORNER) {
554 if (debug) fprintf(stderr, "top\n");
557 if (y >= (c->dy + BORDER)) {
558 if (debug) fprintf(stderr, "bot\n");
562 return BorderUnknown;
566 motionnotify(XMotionEvent *e)
571 c = getclient(e->window, 0);
573 bl = borderorient(c, e->x, e->y);
574 if (bl == BorderUnknown)
575 XUndefineCursor(dpy, c->parent);
577 XDefineCursor(dpy, c->parent, c->screen->bordcurs[bl]);