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);
49 mapreq(&ev.xmaprequest);
51 case ConfigureRequest:
52 configurereq(&ev.xconfigurerequest);
54 case CirculateRequest:
55 circulatereq(&ev.xcirculaterequest);
61 newwindow(&ev.xcreatewindow);
64 destroy(ev.xdestroywindow.window);
67 clientmesg(&ev.xclient);
73 property(&ev.xproperty);
76 fprintf(stderr, "rio: SelectionClear (this should not happen)\n");
79 fprintf(stderr, "rio: SelectionNotify (this should not happen)\n");
81 case SelectionRequest:
82 fprintf(stderr, "rio: SelectionRequest (this should not happen)\n");
91 reparent(&ev.xreparent);
97 motionnotify(&ev.xmotion);
102 case ConfigureNotify:
107 trace("ignore", 0, &ev);
115 configurereq(XConfigureRequestEvent *e)
120 /* we don't set curtime as nothing here uses it */
121 c = getclient(e->window, 0);
122 trace("configurereq", c, e);
124 e->value_mask &= ~CWSibling;
127 if(e->value_mask & CWX)
129 if(e->value_mask & CWY)
131 if(e->value_mask & CWWidth)
133 if(e->value_mask & CWHeight)
135 if(e->value_mask & CWBorderWidth)
136 c->border = e->border_width;
138 if(c->dx >= c->screen->width && c->dy >= c->screen->height)
143 if(e->value_mask & CWStackMode){
144 if(e->detail == Above)
147 e->value_mask &= ~CWStackMode;
149 e->value_mask |= CWX|CWY|CWHeight|CWWidth;
151 if(c->parent != c->screen->root && c->window == e->window){
152 wc.x = c->x - c->border;
153 wc.y = c->y - c->border;
154 wc.width = c->dx+c->border+c->border;
155 wc.height = c->dy+c->border+c->border;
158 wc.stack_mode = e->detail;
159 XConfigureWindow(dpy, c->parent, e->value_mask, &wc);
161 if(e->value_mask & CWStackMode){
168 if(c && c->parent != c->screen->root){
179 wc.stack_mode = Above;
180 e->value_mask &= ~CWStackMode;
181 e->value_mask |= CWBorderWidth;
182 XConfigureWindow(dpy, c->window, e->value_mask, &wc);
186 mapreq(XMapRequestEvent *e)
191 curtime = CurrentTime;
192 c = getclient(e->window, 0);
193 trace("mapreq", c, e);
195 if(c == 0 || c->window != e->window){
196 /* workaround for stupid NCDware */
197 fprintf(stderr, "rio: bad mapreq c %p w %x, rescanning\n",
198 (void*)c, (int)e->window);
199 for(i = 0; i < num_screens; i++)
200 scanwins(&screens[i]);
201 c = getclient(e->window, 0);
202 if(c == 0 || c->window != e->window){
203 fprintf(stderr, "rio: window not found after rescan\n");
210 if(c->parent == c->screen->root){
215 XReparentWindow(dpy, c->window, c->parent, BORDER-1, BORDER-1);
216 XAddToSaveSet(dpy, c->window);
217 /* fall through... */
219 XMapWindow(dpy, c->window);
220 XMapRaised(dpy, c->parent);
222 setstate(c, NormalState);
223 if(c->trans != None && current && c->trans == current->window)
233 unmap(XUnmapEvent *e)
237 curtime = CurrentTime;
238 c = getclient(e->window, 0);
259 circulatereq(XCirculateRequestEvent *e)
261 fprintf(stderr, "It must be the warlock Krill!\n"); /* ☺ */
265 newwindow(XCreateWindowEvent *e)
270 /* we don't set curtime as nothing here uses it */
271 if(e->override_redirect)
273 c = getclient(e->window, 1);
274 if(c && c->window == e->window && (s = getscreen(e->parent))){
279 c->border = e->border_width;
281 if(c->parent == None)
282 c->parent = c->screen->root;
292 curtime = CurrentTime;
298 for(i=0; i<numvirtuals; i++)
304 /* flush any errors generated by the window's sudden demise */
305 ignore_badwindow = 1;
307 ignore_badwindow = 0;
311 clientmesg(XClientMessageEvent *e)
315 curtime = CurrentTime;
316 if(e->message_type == exit_rio){
320 if(e->message_type == restart_rio){
321 fprintf(stderr, "*** rio restarting ***\n");
323 execvp(myargv[0], myargv);
324 perror("rio: exec failed");
327 if(e->message_type == wm_protocols)
329 if(e->message_type == wm_change_state){
330 c = getclient(e->window, 0);
331 if(e->format == 32 && e->data.l[0] == IconicState && c != 0){
336 fprintf(stderr, "rio: WM_CHANGE_STATE: format %d data %d w 0x%x\n",
337 (int)e->format, (int)e->data.l[0], (int)e->window);
340 fprintf(stderr, "rio: strange ClientMessage, type 0x%x window 0x%x\n",
341 (int)e->message_type, (int)e->window);
345 cmap(XColormapEvent *e)
350 /* we don't set curtime as nothing here uses it */
352 c = getclient(e->window, 0);
354 c->cmap = e->colormap;
359 for(c = clients; c; c = c->next){
360 for(i = 0; i < c->ncmapwins; i++)
361 if(c->cmapwins[i] == e->window){
362 c->wmcmaps[i] = e->colormap;
372 property(XPropertyEvent *e)
379 /* we don't set curtime as nothing here uses it */
381 delete = (e->state == PropertyDelete);
382 c = getclient(e->window, 0);
387 case XA_WM_ICON_NAME:
389 XFree((char*) c->iconname);
390 c->iconname = delete ? 0 : getprop(c->window, a);
392 renamec(c, c->label);
396 XFree((char*) c->name);
397 c->name = delete ? 0 : getprop(c->window, a);
399 renamec(c, c->label);
401 case XA_WM_TRANSIENT_FOR:
405 case XA_WM_SIZE_HINTS:
406 case XA_WM_ZOOM_HINTS:
407 /* placeholders to not forget. ignore for now. -Axel */
409 case XA_WM_NORMAL_HINTS:
410 if(XGetWMNormalHints(dpy, c->window, &c->size, &msize) == 0 || c->size.flags == 0)
411 c->size.flags = PSize; /* not specified - punt */
414 if(a == _rio_hold_mode){
415 c->hold = getiprop(c->window, _rio_hold_mode);
419 else if(a == wm_colormaps){
427 reparent(XReparentEvent *e)
430 XWindowAttributes attr;
433 /* we don't set curtime as nothing here uses it */
434 if(!getscreen(e->event) || e->override_redirect)
436 if((s = getscreen(e->parent)) != 0){
437 c = getclient(e->window, 1);
438 if(c != 0 && (c->dx == 0 || c->dy == 0)){
439 /* flush any errors */
440 ignore_badwindow = 1;
441 XGetWindowAttributes(dpy, c->window, &attr);
443 ignore_badwindow = 0;
449 c->border = attr.border_width;
451 if(c->parent == None)
452 c->parent = c->screen->root;
456 c = getclient(e->window, 0);
457 if(c != 0 && (c->parent == c->screen->root || withdrawn(c)))
464 shapenotify(XShapeEvent *e)
468 /* we don't set curtime as nothing here uses it */
469 c = getclient(e->window, 0);
478 enter(XCrossingEvent *e)
484 if(e->mode != NotifyGrab || e->detail != NotifyNonlinearVirtual)
486 c = getclient(e->window, 0);
487 if(c != 0 && c != current){
488 /* someone grabbed the pointer; make them current */
490 XMapRaised(dpy, c->parent);
497 leave(XCrossingEvent *e)
501 c = getclient(e->window, 0);
503 XUndefineCursor(dpy, c->parent);
504 /* XDefineCursor(dpy, c->parent, c->screen->arrow); */
508 focusin(XFocusChangeEvent *e)
512 curtime = CurrentTime;
513 if(e->detail != NotifyNonlinearVirtual)
515 c = getclient(e->window, 0);
516 if(c != 0 && c->window == e->window && c != current){
517 /* someone grabbed keyboard or seized focus; make them current */
518 XMapRaised(dpy, c->parent);
525 borderorient(Client *c, int x, int y)
529 if(debug) fprintf(stderr, "topleft\n");
532 if(y >= (c->dy + 2*BORDER) - CORNER){
533 if(debug) fprintf(stderr, "botleft\n");
537 y < (c->dy + 2*BORDER) - CORNER){
538 if(debug) fprintf(stderr, "left\n");
541 } else if(x <= CORNER){
543 if(debug) fprintf(stderr, "topleft\n");
546 if (y >= (c->dy + BORDER)){
547 if(debug) fprintf(stderr, "botleft\n");
550 } else if(x >= (c->dx + BORDER)){
552 if(debug) fprintf(stderr, "topright\n");
555 if(y >= (c->dy + 2*BORDER) - CORNER){
556 if(debug) fprintf(stderr, "botright\n");
560 y < (c->dy + 2*BORDER) - CORNER){
561 if(debug) fprintf(stderr, "right\n");
564 } else if(x >= (c->dx + 2*BORDER) - CORNER){
566 if(debug) fprintf(stderr, "topright\n");
569 if (y >= (c->dy + BORDER)){
570 if(debug) fprintf(stderr, "botright\n");
573 } else if(x > CORNER &&
574 x < (c->dx + 2*BORDER) - CORNER){
576 if(debug) fprintf(stderr, "top\n");
579 if(y >= (c->dy + BORDER)){
580 if(debug) fprintf(stderr, "bot\n");
584 return BorderUnknown;
588 motionnotify(XMotionEvent *e)
593 c = getclient(e->window, 0);
595 bl = borderorient(c, e->x, e->y);
596 if(bl == BorderUnknown)
597 XUndefineCursor(dpy, c->parent);
599 XDefineCursor(dpy, c->parent, c->screen->bordcurs[bl]);