diff options
Diffstat (limited to 'src/cmd/rio/client.c')
-rw-r--r-- | src/cmd/rio/client.c | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/src/cmd/rio/client.c b/src/cmd/rio/client.c new file mode 100644 index 00000000..9e346558 --- /dev/null +++ b/src/cmd/rio/client.c @@ -0,0 +1,242 @@ +/* Copyright (c) 1994-1996 David Hogan, see README for licence details */ +#include <stdio.h> +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include "dat.h" +#include "fns.h" + +Client *clients; +Client *current; + +void +setactive(Client *c, int on) +{ + if (c->parent == c->screen->root) { + fprintf(stderr, "9wm: bad parent in setactive; dumping core\n"); + abort(); + } + if (on) { + XUngrabButton(dpy, AnyButton, AnyModifier, c->parent); + XSetInputFocus(dpy, c->window, RevertToPointerRoot, timestamp()); + if (c->proto & Ptakefocus) + sendcmessage(c->window, wm_protocols, wm_take_focus, 0); + cmapfocus(c); + } + else + XGrabButton(dpy, AnyButton, AnyModifier, c->parent, False, + ButtonMask, GrabModeAsync, GrabModeSync, None, None); + draw_border(c, on); +} + +void +draw_border(Client *c, int active) +{ + unsigned long pixel; + + if(active){ + if(c->hold) + pixel = c->screen->activeholdborder; + else + pixel = c->screen->activeborder; + }else{ + if(c->hold) + pixel = c->screen->inactiveholdborder; + else + pixel = c->screen->inactiveborder; + } + + XSetWindowBackground(dpy, c->parent, pixel); + XClearWindow(dpy, c->parent); +} + +void +active(Client *c) +{ + Client *cc; + + if (c == 0) { + fprintf(stderr, "9wm: active(c==0)\n"); + return; + } + if (c == current) + return; + if (current) { + setactive(current, 0); + if (current->screen != c->screen) + cmapnofocus(current->screen); + } + setactive(c, 1); + for (cc = clients; cc; cc = cc->next) + if (cc->revert == c) + cc->revert = c->revert; + c->revert = current; + while (c->revert && !normal(c->revert)) + c->revert = c->revert->revert; + current = c; +#ifdef DEBUG + if (debug) + dump_revert(); +#endif +} + +void +nofocus(void) +{ + static Window w = 0; + int mask; + XSetWindowAttributes attr; + Client *c; + + if (current) { + setactive(current, 0); + for (c = current->revert; c; c = c->revert) + if (normal(c)) { + active(c); + return; + } + cmapnofocus(current->screen); + /* if no candidates to revert to, fall through */ + } + current = 0; + if (w == 0) { + mask = CWOverrideRedirect; + attr.override_redirect = 1; + w = XCreateWindow(dpy, screens[0].root, 0, 0, 1, 1, 0, + CopyFromParent, InputOnly, CopyFromParent, mask, &attr); + XMapWindow(dpy, w); + } + XSetInputFocus(dpy, w, RevertToPointerRoot, timestamp()); +} + +void +top(Client *c) +{ + Client **l, *cc; + + l = &clients; + for (cc = *l; cc; cc = *l) { + if (cc == c) { + *l = c->next; + c->next = clients; + clients = c; + return; + } + l = &cc->next; + } + fprintf(stderr, "9wm: %x not on client list in top()\n", c); +} + +Client * +getclient(Window w, int create) +{ + Client *c; + + if (w == 0 || getscreen(w)) + return 0; + + for (c = clients; c; c = c->next) + if (c->window == w || c->parent == w) + return c; + + if (!create) + return 0; + + c = (Client *)malloc(sizeof(Client)); + memset(c, 0, sizeof(Client)); + c->window = w; + /* c->parent will be set by the caller */ + c->parent = None; + c->reparenting = 0; + c->state = WithdrawnState; + c->init = 0; + c->cmap = None; + c->label = c->class = 0; + c->revert = 0; + c->is9term = 0; + c->hold = 0; + c->ncmapwins = 0; + c->cmapwins = 0; + c->wmcmaps = 0; + c->next = clients; + clients = c; + return c; +} + +void +rmclient(Client *c) +{ + Client *cc; + + for (cc = current; cc && cc->revert; cc = cc->revert) + if (cc->revert == c) + cc->revert = cc->revert->revert; + + if (c == clients) + clients = c->next; + for (cc = clients; cc && cc->next; cc = cc->next) + if (cc->next == c) + cc->next = cc->next->next; + + if (hidden(c)) + unhidec(c, 0); + + if (c->parent != c->screen->root) + XDestroyWindow(dpy, c->parent); + + c->parent = c->window = None; /* paranoia */ + if (current == c) { + current = c->revert; + if (current == 0) + nofocus(); + else { + if (current->screen != c->screen) + cmapnofocus(c->screen); + setactive(current, 1); + } + } + if (c->ncmapwins != 0) { + XFree((char *)c->cmapwins); + free((char *)c->wmcmaps); + } + if (c->iconname != 0) + XFree((char*) c->iconname); + if (c->name != 0) + XFree((char*) c->name); + if (c->instance != 0) + XFree((char*) c->instance); + if (c->class != 0) + XFree((char*) c->class); + memset(c, 0, sizeof(Client)); /* paranoia */ + free(c); +} + +#ifdef DEBUG +void +dump_revert(void) +{ + Client *c; + int i; + + i = 0; + for (c = current; c; c = c->revert) { + fprintf(stderr, "%s(%x:%d)", c->label ? c->label : "?", c->window, c->state); + if (i++ > 100) + break; + if (c->revert) + fprintf(stderr, " -> "); + } + if (current == 0) + fprintf(stderr, "empty"); + fprintf(stderr, "\n"); +} + +void +dump_clients(void) +{ + Client *c; + + for (c = clients; c; c = c->next) + fprintf(stderr, "w 0x%x parent 0x%x @ (%d, %d)\n", c->window, c->parent, c->x, c->y); +} +#endif |