diff options
Diffstat (limited to 'src/cmd/rio/event.c')
-rw-r--r-- | src/cmd/rio/event.c | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/src/cmd/rio/event.c b/src/cmd/rio/event.c new file mode 100644 index 00000000..1b27e85a --- /dev/null +++ b/src/cmd/rio/event.c @@ -0,0 +1,465 @@ +/* Copyright (c) 1994-1996 David Hogan, see README for licence details */ +#include <stdio.h> +#include <X11/X.h> +#include <X11/Xos.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <X11/extensions/shape.h> +#include "dat.h" +#include "fns.h" +#include "patchlevel.h" + +void +mainloop(int shape_event) +{ + XEvent ev; + + for (;;) { + getevent(&ev); + +#ifdef DEBUG_EV + if (debug) { + ShowEvent(&ev); + printf("\n"); + } +#endif + switch (ev.type) { + default: +#ifdef SHAPE + if (shape && ev.type == shape_event) + shapenotify((XShapeEvent *)&ev); + else +#endif + fprintf(stderr, "9wm: unknown ev.type %d\n", ev.type); + break; + case ButtonPress: + button(&ev.xbutton); + break; + case ButtonRelease: + break; + case MapRequest: + mapreq(&ev.xmaprequest); + break; + case ConfigureRequest: + configurereq(&ev.xconfigurerequest); + break; + case CirculateRequest: + circulatereq(&ev.xcirculaterequest); + break; + case UnmapNotify: + unmap(&ev.xunmap); + break; + case CreateNotify: + newwindow(&ev.xcreatewindow); + break; + case DestroyNotify: + destroy(ev.xdestroywindow.window); + break; + case ClientMessage: + clientmesg(&ev.xclient); + break; + case ColormapNotify: + cmap(&ev.xcolormap); + break; + case PropertyNotify: + property(&ev.xproperty); + break; + case SelectionClear: + fprintf(stderr, "9wm: SelectionClear (this should not happen)\n"); + break; + case SelectionNotify: + fprintf(stderr, "9wm: SelectionNotify (this should not happen)\n"); + break; + case SelectionRequest: + fprintf(stderr, "9wm: SelectionRequest (this should not happen)\n"); + break; + case EnterNotify: + enter(&ev.xcrossing); + break; + case ReparentNotify: + reparent(&ev.xreparent); + break; + case FocusIn: + focusin(&ev.xfocus); + break; + case MotionNotify: + case Expose: + case NoExpose: + case FocusOut: + case ConfigureNotify: + case MapNotify: + case MappingNotify: + /* not interested */ + trace("ignore", 0, &ev); + break; + } + } +} + + +void +configurereq(XConfigureRequestEvent *e) +{ + XWindowChanges wc; + Client *c; + + /* we don't set curtime as nothing here uses it */ + c = getclient(e->window, 0); + trace("configurereq", c, e); + + e->value_mask &= ~CWSibling; + + if (c) { + gravitate(c, 1); + if (e->value_mask & CWX) + c->x = e->x; + if (e->value_mask & CWY) + c->y = e->y; + if (e->value_mask & CWWidth) + c->dx = e->width; + if (e->value_mask & CWHeight) + c->dy = e->height; + if (e->value_mask & CWBorderWidth) + c->border = e->border_width; + gravitate(c, 0); + if (e->value_mask & CWStackMode) { + if (wc.stack_mode == Above) + top(c); + else + e->value_mask &= ~CWStackMode; + } + if (c->parent != c->screen->root && c->window == e->window) { + wc.x = c->x-BORDER; + wc.y = c->y-BORDER; + wc.width = c->dx+2*BORDER; + wc.height = c->dy+2*BORDER; + wc.border_width = 1; + wc.sibling = None; + wc.stack_mode = e->detail; + XConfigureWindow(dpy, c->parent, e->value_mask, &wc); + sendconfig(c); + } + } + + if (c && c->init) { + wc.x = BORDER; + wc.y = BORDER; + } + else { + wc.x = e->x; + wc.y = e->y; + } + wc.width = e->width; + wc.height = e->height; + wc.border_width = 0; + wc.sibling = None; + wc.stack_mode = Above; + e->value_mask &= ~CWStackMode; + e->value_mask |= CWBorderWidth; + + XConfigureWindow(dpy, e->window, e->value_mask, &wc); +} + +void +mapreq(XMapRequestEvent *e) +{ + Client *c; + int i; + + curtime = CurrentTime; + c = getclient(e->window, 0); + trace("mapreq", c, e); + + if (c == 0 || c->window != e->window) { + /* workaround for stupid NCDware */ + fprintf(stderr, "9wm: bad mapreq c %x w %x, rescanning\n", + c, e->window); + for (i = 0; i < num_screens; i++) + scanwins(&screens[i]); + c = getclient(e->window, 0); + if (c == 0 || c->window != e->window) { + fprintf(stderr, "9wm: window not found after rescan\n"); + return; + } + } + + switch (c->state) { + case WithdrawnState: + if (c->parent == c->screen->root) { + if (!manage(c, 0)) + return; + break; + } + XReparentWindow(dpy, c->window, c->parent, BORDER-1, BORDER-1); + XAddToSaveSet(dpy, c->window); + /* fall through... */ + case NormalState: + XMapWindow(dpy, c->window); + XMapRaised(dpy, c->parent); + top(c); + setstate(c, NormalState); + if (c->trans != None && current && c->trans == current->window) + active(c); + break; + case IconicState: + unhidec(c, 1); + break; + } +} + +void +unmap(XUnmapEvent *e) +{ + Client *c; + + curtime = CurrentTime; + c = getclient(e->window, 0); + if (c) { + switch (c->state) { + case IconicState: + if (e->send_event) { + unhidec(c, 0); + withdraw(c); + } + break; + case NormalState: + if (c == current) + nofocus(); + if (!c->reparenting) + withdraw(c); + break; + } + c->reparenting = 0; + } +} + +void +circulatereq(XCirculateRequestEvent *e) +{ + fprintf(stderr, "It must be the warlock Krill!\n"); /* ☺ */ +} + +void +newwindow(XCreateWindowEvent *e) +{ + Client *c; + ScreenInfo *s; + + /* we don't set curtime as nothing here uses it */ + if (e->override_redirect) + return; + c = getclient(e->window, 1); + if (c && c->window == e->window && (s = getscreen(e->parent))) { + c->x = e->x; + c->y = e->y; + c->dx = e->width; + c->dy = e->height; + c->border = e->border_width; + c->screen = s; + if (c->parent == None) + c->parent = c->screen->root; + } +} + +void +destroy(Window w) +{ + Client *c; + + curtime = CurrentTime; + c = getclient(w, 0); + if (c == 0) + return; + + rmclient(c); + + /* flush any errors generated by the window's sudden demise */ + ignore_badwindow = 1; + XSync(dpy, False); + ignore_badwindow = 0; +} + +void +clientmesg(XClientMessageEvent *e) +{ + Client *c; + + curtime = CurrentTime; + if (e->message_type == exit_9wm) { + cleanup(); + exit(0); + } + if (e->message_type == restart_9wm) { + fprintf(stderr, "*** 9wm restarting ***\n"); + cleanup(); + execvp(myargv[0], myargv); + perror("9wm: exec failed"); + exit(1); + } + if (e->message_type == wm_change_state) { + c = getclient(e->window, 0); + if (e->format == 32 && e->data.l[0] == IconicState && c != 0) { + if (normal(c)) + hide(c); + } + else + fprintf(stderr, "9wm: WM_CHANGE_STATE: format %d data %d w 0x%x\n", + e->format, e->data.l[0], e->window); + return; + } + fprintf(stderr, "9wm: strange ClientMessage, type 0x%x window 0x%x\n", + e->message_type, e->window); +} + +void +cmap(XColormapEvent *e) +{ + Client *c; + int i; + + /* we don't set curtime as nothing here uses it */ + if (e->new) { + c = getclient(e->window, 0); + if (c) { + c->cmap = e->colormap; + if (c == current) + cmapfocus(c); + } + else + for (c = clients; c; c = c->next) { + for (i = 0; i < c->ncmapwins; i++) + if (c->cmapwins[i] == e->window) { + c->wmcmaps[i] = e->colormap; + if (c == current) + cmapfocus(c); + return; + } + } + } +} + +void +property(XPropertyEvent *e) +{ + Atom a; + int delete; + Client *c; + + /* we don't set curtime as nothing here uses it */ + a = e->atom; + delete = (e->state == PropertyDelete); + c = getclient(e->window, 0); + if (c == 0) + return; + + switch (a) { + case XA_WM_ICON_NAME: + if (c->iconname != 0) + XFree((char*) c->iconname); + c->iconname = delete ? 0 : getprop(c->window, a); + setlabel(c); + renamec(c, c->label); + return; + case XA_WM_NAME: + if (c->name != 0) + XFree((char*) c->name); + c->name = delete ? 0 : getprop(c->window, a); + setlabel(c); + renamec(c, c->label); + return; + case XA_WM_TRANSIENT_FOR: + gettrans(c); + return; + } + if (a == _9wm_hold_mode) { + c->hold = getiprop(c->window, _9wm_hold_mode); + if (c == current) + draw_border(c, 1); + } + else if (a == wm_colormaps) { + getcmaps(c); + if (c == current) + cmapfocus(c); + } +} + +void +reparent(XReparentEvent *e) +{ + Client *c; + XWindowAttributes attr; + ScreenInfo *s; + + /* we don't set curtime as nothing here uses it */ + if (!getscreen(e->event) || e->override_redirect) + return; + if ((s = getscreen(e->parent)) != 0) { + c = getclient(e->window, 1); + if (c != 0 && (c->dx == 0 || c->dy == 0)) { + XGetWindowAttributes(dpy, c->window, &attr); + c->x = attr.x; + c->y = attr.y; + c->dx = attr.width; + c->dy = attr.height; + c->border = attr.border_width; + c->screen = s; + if (c->parent == None) + c->parent = c->screen->root; + } + } + else { + c = getclient(e->window, 0); + if (c != 0 && (c->parent == c->screen->root || withdrawn(c))) + rmclient(c); + } +} + +#ifdef SHAPE +void +shapenotify(XShapeEvent *e) +{ + Client *c; + + /* we don't set curtime as nothing here uses it */ + c = getclient(e->window, 0); + if (c == 0) + return; + + setshape(c); +} +#endif + +void +enter(XCrossingEvent *e) +{ + Client *c; + + curtime = e->time; + if (e->mode != NotifyGrab || e->detail != NotifyNonlinearVirtual) + return; + c = getclient(e->window, 0); + if (c != 0 && c != current) { + /* someone grabbed the pointer; make them current */ + XMapRaised(dpy, c->parent); + top(c); + active(c); + } +} + +void +focusin(XFocusChangeEvent *e) +{ + Client *c; + + curtime = CurrentTime; + if (e->detail != NotifyNonlinearVirtual) + return; + c = getclient(e->window, 0); + if (c != 0 && c->window == e->window && c != current) { + /* someone grabbed keyboard or seized focus; make them current */ + XMapRaised(dpy, c->parent); + top(c); + active(c); + } +} |