| /* Copyright (c) 1994-1996 David Hogan, see README for licence details */ |
| #include <stdio.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <string.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, "rio: 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, 1); |
| cmapfocus(c); |
| } else { |
| if (c->proto & Plosefocus) |
| sendcmessage(c->window, wm_protocols, wm_lose_focus, 0, 1); |
| 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; |
| } |
| |
| if (debug) fprintf(stderr, "draw_border %p pixel %ld active %d hold %d\n", c, pixel, active, c->hold); |
| XSetWindowBackground(dpy, c->parent, pixel); |
| XClearWindow(dpy, c->parent); |
| } |
| |
| void |
| active(Client *c) |
| { |
| Client *cc; |
| |
| if (c == 0) { |
| fprintf(stderr, "rio: 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/*|CWColormap*/; |
| attr.override_redirect = 1; |
| /* attr.colormap = screens[0].def_cmap;*/ |
| w = XCreateWindow(dpy, screens[0].root, 0, 0, 1, 1, 0, |
| 0 /*screens[0].depth*/, InputOnly, screens[0].vis, 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, "rio: %p 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; |
| c->virt = virt; |
| 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 |