Blob


1 /* Copyright (c) 1994-1996 David Hogan, see README for licence details */
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <X11/X.h>
7 #include <X11/Xlib.h>
8 #include <X11/Xutil.h>
9 #include "dat.h"
10 #include "fns.h"
12 Client *clients;
13 Client *current;
15 void
16 setactive(Client *c, int on)
17 {
18 if (c->parent == c->screen->root) {
19 fprintf(stderr, "rio: bad parent in setactive; dumping core\n");
20 abort();
21 }
22 if (on) {
23 XUngrabButton(dpy, AnyButton, AnyModifier, c->parent);
24 XSetInputFocus(dpy, c->window, RevertToPointerRoot, timestamp());
25 if (c->proto & Ptakefocus)
26 sendcmessage(c->window, wm_protocols, wm_take_focus, 0, 1);
27 cmapfocus(c);
28 } else {
29 if (c->proto & Plosefocus)
30 sendcmessage(c->window, wm_protocols, wm_lose_focus, 0, 1);
31 XGrabButton(dpy, AnyButton, AnyModifier, c->parent, False,
32 ButtonMask, GrabModeAsync, GrabModeSync, None, None);
33 }
34 draw_border(c, on);
35 }
37 void
38 draw_border(Client *c, int active)
39 {
40 unsigned long pixel;
42 if(active){
43 if(c->hold)
44 pixel = c->screen->activeholdborder;
45 else
46 pixel = c->screen->activeborder;
47 }else{
48 if(c->hold)
49 pixel = c->screen->inactiveholdborder;
50 else
51 pixel = c->screen->inactiveborder;
52 }
54 if (debug) fprintf(stderr, "draw_border %p pixel %ld active %d hold %d\n", c, pixel, active, c->hold);
55 XSetWindowBackground(dpy, c->parent, pixel);
56 XClearWindow(dpy, c->parent);
57 }
59 void
60 active(Client *c)
61 {
62 Client *cc;
64 if (c == 0) {
65 fprintf(stderr, "rio: active(c==0)\n");
66 return;
67 }
68 if (c == current)
69 return;
70 if (current) {
71 setactive(current, 0);
72 if (current->screen != c->screen)
73 cmapnofocus(current->screen);
74 }
75 setactive(c, 1);
76 for (cc = clients; cc; cc = cc->next)
77 if (cc->revert == c)
78 cc->revert = c->revert;
79 c->revert = current;
80 while (c->revert && !normal(c->revert))
81 c->revert = c->revert->revert;
82 current = c;
83 #ifdef DEBUG
84 if (debug)
85 dump_revert();
86 #endif
87 }
89 void
90 nofocus(void)
91 {
92 static Window w = 0;
93 int mask;
94 XSetWindowAttributes attr;
95 Client *c;
97 if (current) {
98 setactive(current, 0);
99 for (c = current->revert; c; c = c->revert)
100 if (normal(c)) {
101 active(c);
102 return;
104 cmapnofocus(current->screen);
105 /* if no candidates to revert to, fall through */
107 current = 0;
108 if (w == 0) {
109 mask = CWOverrideRedirect/*|CWColormap*/;
110 attr.override_redirect = 1;
111 /* attr.colormap = screens[0].def_cmap;*/
112 w = XCreateWindow(dpy, screens[0].root, 0, 0, 1, 1, 0,
113 0 /*screens[0].depth*/, InputOnly, screens[0].vis, mask, &attr);
114 XMapWindow(dpy, w);
116 XSetInputFocus(dpy, w, RevertToPointerRoot, timestamp());
119 void
120 top(Client *c)
122 Client **l, *cc;
124 l = &clients;
125 for (cc = *l; cc; cc = *l) {
126 if (cc == c) {
127 *l = c->next;
128 c->next = clients;
129 clients = c;
130 return;
132 l = &cc->next;
134 fprintf(stderr, "rio: %p not on client list in top()\n", c);
137 Client *
138 getclient(Window w, int create)
140 Client *c;
142 if (w == 0 || getscreen(w))
143 return 0;
145 for (c = clients; c; c = c->next)
146 if (c->window == w || c->parent == w)
147 return c;
149 if (!create)
150 return 0;
152 c = (Client *)malloc(sizeof(Client));
153 memset(c, 0, sizeof(Client));
154 c->window = w;
155 /* c->parent will be set by the caller */
156 c->parent = None;
157 c->reparenting = 0;
158 c->state = WithdrawnState;
159 c->init = 0;
160 c->cmap = None;
161 c->label = c->class = 0;
162 c->revert = 0;
163 c->is9term = 0;
164 c->hold = 0;
165 c->ncmapwins = 0;
166 c->cmapwins = 0;
167 c->wmcmaps = 0;
168 c->next = clients;
169 c->virt = virt;
170 clients = c;
171 return c;
174 void
175 rmclient(Client *c)
177 Client *cc;
179 for (cc = current; cc && cc->revert; cc = cc->revert)
180 if (cc->revert == c)
181 cc->revert = cc->revert->revert;
183 if (c == clients)
184 clients = c->next;
185 for (cc = clients; cc && cc->next; cc = cc->next)
186 if (cc->next == c)
187 cc->next = cc->next->next;
189 if (hidden(c))
190 unhidec(c, 0);
192 if (c->parent != c->screen->root)
193 XDestroyWindow(dpy, c->parent);
195 c->parent = c->window = None; /* paranoia */
196 if (current == c) {
197 current = c->revert;
198 if (current == 0)
199 nofocus();
200 else {
201 if (current->screen != c->screen)
202 cmapnofocus(c->screen);
203 setactive(current, 1);
206 if (c->ncmapwins != 0) {
207 XFree((char *)c->cmapwins);
208 free((char *)c->wmcmaps);
210 if (c->iconname != 0)
211 XFree((char*) c->iconname);
212 if (c->name != 0)
213 XFree((char*) c->name);
214 if (c->instance != 0)
215 XFree((char*) c->instance);
216 if (c->class != 0)
217 XFree((char*) c->class);
218 memset(c, 0, sizeof(Client)); /* paranoia */
219 free(c);
222 #ifdef DEBUG
223 void
224 dump_revert(void)
226 Client *c;
227 int i;
229 i = 0;
230 for (c = current; c; c = c->revert) {
231 fprintf(stderr, "%s(%x:%d)", c->label ? c->label : "?", c->window, c->state);
232 if (i++ > 100)
233 break;
234 if (c->revert)
235 fprintf(stderr, " -> ");
237 if (current == 0)
238 fprintf(stderr, "empty");
239 fprintf(stderr, "\n");
242 void
243 dump_clients(void)
245 Client *c;
247 for (c = clients; c; c = c->next)
248 fprintf(stderr, "w 0x%x parent 0x%x @ (%d, %d)\n", c->window, c->parent, c->x, c->y);
250 #endif