Blame


1 038e9089 2004-03-21 devnull /* Copyright (c) 1994-1996 David Hogan, see README for licence details */
2 038e9089 2004-03-21 devnull #include <stdio.h>
3 e62ba5ec 2004-03-21 devnull #include <unistd.h>
4 e62ba5ec 2004-03-21 devnull #include <stdlib.h>
5 e62ba5ec 2004-03-21 devnull #include <string.h>
6 038e9089 2004-03-21 devnull #include <X11/X.h>
7 038e9089 2004-03-21 devnull #include <X11/Xlib.h>
8 038e9089 2004-03-21 devnull #include <X11/Xutil.h>
9 038e9089 2004-03-21 devnull #include "dat.h"
10 038e9089 2004-03-21 devnull #include "fns.h"
11 038e9089 2004-03-21 devnull
12 038e9089 2004-03-21 devnull Client *clients;
13 038e9089 2004-03-21 devnull Client *current;
14 038e9089 2004-03-21 devnull
15 038e9089 2004-03-21 devnull void
16 038e9089 2004-03-21 devnull setactive(Client *c, int on)
17 038e9089 2004-03-21 devnull {
18 cbeb0b26 2006-04-01 devnull /* dbg("setactive client %x %d", c->window, c->on); */
19 ac33a34a 2005-07-13 devnull
20 ac33a34a 2005-07-13 devnull if(c->parent == c->screen->root)
21 ac33a34a 2005-07-13 devnull return;
22 fa325e9b 2020-01-10 cross
23 ac33a34a 2005-07-13 devnull if(on){
24 038e9089 2004-03-21 devnull XUngrabButton(dpy, AnyButton, AnyModifier, c->parent);
25 038e9089 2004-03-21 devnull XSetInputFocus(dpy, c->window, RevertToPointerRoot, timestamp());
26 ac33a34a 2005-07-13 devnull if(c->proto & Ptakefocus)
27 2c1b986e 2004-08-13 devnull sendcmessage(c->window, wm_protocols, wm_take_focus, 0, 1);
28 038e9089 2004-03-21 devnull cmapfocus(c);
29 ac33a34a 2005-07-13 devnull }else{
30 ac33a34a 2005-07-13 devnull if(c->proto & Plosefocus)
31 2c1b986e 2004-08-13 devnull sendcmessage(c->window, wm_protocols, wm_lose_focus, 0, 1);
32 038e9089 2004-03-21 devnull XGrabButton(dpy, AnyButton, AnyModifier, c->parent, False,
33 038e9089 2004-03-21 devnull ButtonMask, GrabModeAsync, GrabModeSync, None, None);
34 c005568a 2004-03-30 devnull }
35 038e9089 2004-03-21 devnull draw_border(c, on);
36 038e9089 2004-03-21 devnull }
37 038e9089 2004-03-21 devnull
38 038e9089 2004-03-21 devnull void
39 038e9089 2004-03-21 devnull draw_border(Client *c, int active)
40 038e9089 2004-03-21 devnull {
41 038e9089 2004-03-21 devnull unsigned long pixel;
42 038e9089 2004-03-21 devnull
43 038e9089 2004-03-21 devnull if(active){
44 038e9089 2004-03-21 devnull if(c->hold)
45 038e9089 2004-03-21 devnull pixel = c->screen->activeholdborder;
46 038e9089 2004-03-21 devnull else
47 038e9089 2004-03-21 devnull pixel = c->screen->activeborder;
48 038e9089 2004-03-21 devnull }else{
49 038e9089 2004-03-21 devnull if(c->hold)
50 038e9089 2004-03-21 devnull pixel = c->screen->inactiveholdborder;
51 038e9089 2004-03-21 devnull else
52 038e9089 2004-03-21 devnull pixel = c->screen->inactiveborder;
53 038e9089 2004-03-21 devnull }
54 038e9089 2004-03-21 devnull
55 cbeb0b26 2006-04-01 devnull if(debug) fprintf(stderr, "draw_border %p pixel %ld active %d hold %d\n", (void*)c, pixel, active, c->hold);
56 038e9089 2004-03-21 devnull XSetWindowBackground(dpy, c->parent, pixel);
57 038e9089 2004-03-21 devnull XClearWindow(dpy, c->parent);
58 038e9089 2004-03-21 devnull }
59 038e9089 2004-03-21 devnull
60 038e9089 2004-03-21 devnull void
61 038e9089 2004-03-21 devnull active(Client *c)
62 038e9089 2004-03-21 devnull {
63 038e9089 2004-03-21 devnull Client *cc;
64 038e9089 2004-03-21 devnull
65 ac33a34a 2005-07-13 devnull if(c == 0){
66 aa808685 2004-04-19 devnull fprintf(stderr, "rio: active(c==0)\n");
67 038e9089 2004-03-21 devnull return;
68 038e9089 2004-03-21 devnull }
69 ac33a34a 2005-07-13 devnull if(c == current)
70 038e9089 2004-03-21 devnull return;
71 ac33a34a 2005-07-13 devnull if(current){
72 038e9089 2004-03-21 devnull setactive(current, 0);
73 ac33a34a 2005-07-13 devnull if(current->screen != c->screen)
74 038e9089 2004-03-21 devnull cmapnofocus(current->screen);
75 038e9089 2004-03-21 devnull }
76 038e9089 2004-03-21 devnull setactive(c, 1);
77 ac33a34a 2005-07-13 devnull for(cc = clients; cc; cc = cc->next)
78 ac33a34a 2005-07-13 devnull if(cc->revert == c)
79 038e9089 2004-03-21 devnull cc->revert = c->revert;
80 038e9089 2004-03-21 devnull c->revert = current;
81 ac33a34a 2005-07-13 devnull while(c->revert && !normal(c->revert))
82 038e9089 2004-03-21 devnull c->revert = c->revert->revert;
83 038e9089 2004-03-21 devnull current = c;
84 038e9089 2004-03-21 devnull #ifdef DEBUG
85 ac33a34a 2005-07-13 devnull if(debug)
86 038e9089 2004-03-21 devnull dump_revert();
87 038e9089 2004-03-21 devnull #endif
88 038e9089 2004-03-21 devnull }
89 038e9089 2004-03-21 devnull
90 038e9089 2004-03-21 devnull void
91 038e9089 2004-03-21 devnull nofocus(void)
92 038e9089 2004-03-21 devnull {
93 038e9089 2004-03-21 devnull static Window w = 0;
94 038e9089 2004-03-21 devnull int mask;
95 038e9089 2004-03-21 devnull XSetWindowAttributes attr;
96 038e9089 2004-03-21 devnull Client *c;
97 038e9089 2004-03-21 devnull
98 ac33a34a 2005-07-13 devnull if(current){
99 038e9089 2004-03-21 devnull setactive(current, 0);
100 ac33a34a 2005-07-13 devnull for(c = current->revert; c; c = c->revert)
101 ac33a34a 2005-07-13 devnull if(normal(c)){
102 038e9089 2004-03-21 devnull active(c);
103 038e9089 2004-03-21 devnull return;
104 038e9089 2004-03-21 devnull }
105 038e9089 2004-03-21 devnull cmapnofocus(current->screen);
106 038e9089 2004-03-21 devnull /* if no candidates to revert to, fall through */
107 038e9089 2004-03-21 devnull }
108 038e9089 2004-03-21 devnull current = 0;
109 ac33a34a 2005-07-13 devnull if(w == 0){
110 c005568a 2004-03-30 devnull mask = CWOverrideRedirect/*|CWColormap*/;
111 038e9089 2004-03-21 devnull attr.override_redirect = 1;
112 c005568a 2004-03-30 devnull /* attr.colormap = screens[0].def_cmap;*/
113 038e9089 2004-03-21 devnull w = XCreateWindow(dpy, screens[0].root, 0, 0, 1, 1, 0,
114 c005568a 2004-03-30 devnull 0 /*screens[0].depth*/, InputOnly, screens[0].vis, mask, &attr);
115 038e9089 2004-03-21 devnull XMapWindow(dpy, w);
116 038e9089 2004-03-21 devnull }
117 038e9089 2004-03-21 devnull XSetInputFocus(dpy, w, RevertToPointerRoot, timestamp());
118 038e9089 2004-03-21 devnull }
119 038e9089 2004-03-21 devnull
120 038e9089 2004-03-21 devnull void
121 038e9089 2004-03-21 devnull top(Client *c)
122 038e9089 2004-03-21 devnull {
123 038e9089 2004-03-21 devnull Client **l, *cc;
124 038e9089 2004-03-21 devnull
125 038e9089 2004-03-21 devnull l = &clients;
126 ac33a34a 2005-07-13 devnull for(cc = *l; cc; cc = *l){
127 ac33a34a 2005-07-13 devnull if(cc == c){
128 038e9089 2004-03-21 devnull *l = c->next;
129 038e9089 2004-03-21 devnull c->next = clients;
130 038e9089 2004-03-21 devnull clients = c;
131 038e9089 2004-03-21 devnull return;
132 038e9089 2004-03-21 devnull }
133 038e9089 2004-03-21 devnull l = &cc->next;
134 038e9089 2004-03-21 devnull }
135 cbeb0b26 2006-04-01 devnull fprintf(stderr, "rio: %p not on client list in top()\n", (void*)c);
136 038e9089 2004-03-21 devnull }
137 038e9089 2004-03-21 devnull
138 038e9089 2004-03-21 devnull Client *
139 038e9089 2004-03-21 devnull getclient(Window w, int create)
140 038e9089 2004-03-21 devnull {
141 038e9089 2004-03-21 devnull Client *c;
142 038e9089 2004-03-21 devnull
143 ac33a34a 2005-07-13 devnull if(w == 0 || getscreen(w))
144 038e9089 2004-03-21 devnull return 0;
145 038e9089 2004-03-21 devnull
146 ac33a34a 2005-07-13 devnull for(c = clients; c; c = c->next)
147 ac33a34a 2005-07-13 devnull if(c->window == w || c->parent == w)
148 038e9089 2004-03-21 devnull return c;
149 038e9089 2004-03-21 devnull
150 ac33a34a 2005-07-13 devnull if(!create)
151 038e9089 2004-03-21 devnull return 0;
152 038e9089 2004-03-21 devnull
153 038e9089 2004-03-21 devnull c = (Client *)malloc(sizeof(Client));
154 ffbdd1aa 2022-09-12 crossd if (!c){
155 ffbdd1aa 2022-09-12 crossd fprintf(stderr, "rio: Failed to allocate memory\n");
156 ffbdd1aa 2022-09-12 crossd exit(1);
157 ffbdd1aa 2022-09-12 crossd }
158 ffbdd1aa 2022-09-12 crossd
159 038e9089 2004-03-21 devnull memset(c, 0, sizeof(Client));
160 038e9089 2004-03-21 devnull c->window = w;
161 038e9089 2004-03-21 devnull /* c->parent will be set by the caller */
162 038e9089 2004-03-21 devnull c->parent = None;
163 038e9089 2004-03-21 devnull c->reparenting = 0;
164 038e9089 2004-03-21 devnull c->state = WithdrawnState;
165 038e9089 2004-03-21 devnull c->init = 0;
166 038e9089 2004-03-21 devnull c->cmap = None;
167 038e9089 2004-03-21 devnull c->label = c->class = 0;
168 038e9089 2004-03-21 devnull c->revert = 0;
169 038e9089 2004-03-21 devnull c->is9term = 0;
170 038e9089 2004-03-21 devnull c->hold = 0;
171 038e9089 2004-03-21 devnull c->ncmapwins = 0;
172 038e9089 2004-03-21 devnull c->cmapwins = 0;
173 038e9089 2004-03-21 devnull c->wmcmaps = 0;
174 038e9089 2004-03-21 devnull c->next = clients;
175 3ddda821 2004-12-28 devnull c->virt = virt;
176 038e9089 2004-03-21 devnull clients = c;
177 038e9089 2004-03-21 devnull return c;
178 038e9089 2004-03-21 devnull }
179 038e9089 2004-03-21 devnull
180 038e9089 2004-03-21 devnull void
181 038e9089 2004-03-21 devnull rmclient(Client *c)
182 038e9089 2004-03-21 devnull {
183 038e9089 2004-03-21 devnull Client *cc;
184 038e9089 2004-03-21 devnull
185 ac33a34a 2005-07-13 devnull for(cc = current; cc && cc->revert; cc = cc->revert)
186 ac33a34a 2005-07-13 devnull if(cc->revert == c)
187 038e9089 2004-03-21 devnull cc->revert = cc->revert->revert;
188 038e9089 2004-03-21 devnull
189 ac33a34a 2005-07-13 devnull if(c == clients)
190 038e9089 2004-03-21 devnull clients = c->next;
191 ac33a34a 2005-07-13 devnull for(cc = clients; cc && cc->next; cc = cc->next)
192 ac33a34a 2005-07-13 devnull if(cc->next == c)
193 038e9089 2004-03-21 devnull cc->next = cc->next->next;
194 038e9089 2004-03-21 devnull
195 ac33a34a 2005-07-13 devnull if(hidden(c))
196 038e9089 2004-03-21 devnull unhidec(c, 0);
197 038e9089 2004-03-21 devnull
198 ac33a34a 2005-07-13 devnull if(c->parent != c->screen->root)
199 038e9089 2004-03-21 devnull XDestroyWindow(dpy, c->parent);
200 038e9089 2004-03-21 devnull
201 038e9089 2004-03-21 devnull c->parent = c->window = None; /* paranoia */
202 ac33a34a 2005-07-13 devnull if(current == c){
203 038e9089 2004-03-21 devnull current = c->revert;
204 ac33a34a 2005-07-13 devnull if(current == 0)
205 038e9089 2004-03-21 devnull nofocus();
206 038e9089 2004-03-21 devnull else {
207 ac33a34a 2005-07-13 devnull if(current->screen != c->screen)
208 038e9089 2004-03-21 devnull cmapnofocus(c->screen);
209 038e9089 2004-03-21 devnull setactive(current, 1);
210 038e9089 2004-03-21 devnull }
211 038e9089 2004-03-21 devnull }
212 ac33a34a 2005-07-13 devnull if(c->ncmapwins != 0){
213 038e9089 2004-03-21 devnull XFree((char *)c->cmapwins);
214 038e9089 2004-03-21 devnull free((char *)c->wmcmaps);
215 038e9089 2004-03-21 devnull }
216 ac33a34a 2005-07-13 devnull if(c->iconname != 0)
217 038e9089 2004-03-21 devnull XFree((char*) c->iconname);
218 ac33a34a 2005-07-13 devnull if(c->name != 0)
219 038e9089 2004-03-21 devnull XFree((char*) c->name);
220 ac33a34a 2005-07-13 devnull if(c->instance != 0)
221 038e9089 2004-03-21 devnull XFree((char*) c->instance);
222 ac33a34a 2005-07-13 devnull if(c->class != 0)
223 038e9089 2004-03-21 devnull XFree((char*) c->class);
224 038e9089 2004-03-21 devnull memset(c, 0, sizeof(Client)); /* paranoia */
225 038e9089 2004-03-21 devnull free(c);
226 038e9089 2004-03-21 devnull }
227 038e9089 2004-03-21 devnull
228 038e9089 2004-03-21 devnull #ifdef DEBUG
229 038e9089 2004-03-21 devnull void
230 038e9089 2004-03-21 devnull dump_revert(void)
231 038e9089 2004-03-21 devnull {
232 038e9089 2004-03-21 devnull Client *c;
233 038e9089 2004-03-21 devnull int i;
234 038e9089 2004-03-21 devnull
235 038e9089 2004-03-21 devnull i = 0;
236 ac33a34a 2005-07-13 devnull for(c = current; c; c = c->revert){
237 cbeb0b26 2006-04-01 devnull fprintf(stderr, "%s(%x:%d)", c->label ? c->label : "?", (int)c->window, c->state);
238 ac33a34a 2005-07-13 devnull if(i++ > 100)
239 038e9089 2004-03-21 devnull break;
240 ac33a34a 2005-07-13 devnull if(c->revert)
241 038e9089 2004-03-21 devnull fprintf(stderr, " -> ");
242 038e9089 2004-03-21 devnull }
243 ac33a34a 2005-07-13 devnull if(current == 0)
244 038e9089 2004-03-21 devnull fprintf(stderr, "empty");
245 038e9089 2004-03-21 devnull fprintf(stderr, "\n");
246 038e9089 2004-03-21 devnull }
247 038e9089 2004-03-21 devnull
248 038e9089 2004-03-21 devnull void
249 038e9089 2004-03-21 devnull dump_clients(void)
250 038e9089 2004-03-21 devnull {
251 038e9089 2004-03-21 devnull Client *c;
252 038e9089 2004-03-21 devnull
253 ac33a34a 2005-07-13 devnull for(c = clients; c; c = c->next)
254 cbeb0b26 2006-04-01 devnull fprintf(stderr, "w 0x%x parent 0x%x @ (%d, %d)\n", (int)c->window, (int)c->parent, c->x, c->y);
255 038e9089 2004-03-21 devnull }
256 038e9089 2004-03-21 devnull #endif
257 ac33a34a 2005-07-13 devnull
258 ac33a34a 2005-07-13 devnull void
259 ac33a34a 2005-07-13 devnull shuffle(int up)
260 ac33a34a 2005-07-13 devnull {
261 ac33a34a 2005-07-13 devnull Client **l, *c;
262 fa325e9b 2020-01-10 cross
263 ac33a34a 2005-07-13 devnull if(clients == 0 || clients->next == 0)
264 ac33a34a 2005-07-13 devnull return;
265 c4da6427 2010-02-19 rsc if(!up){
266 c4da6427 2010-02-19 rsc c = 0;
267 cbeb0b26 2006-04-01 devnull /*for(c=clients; c->next; c=c->next) */
268 cbeb0b26 2006-04-01 devnull /* ; */
269 ac33a34a 2005-07-13 devnull for(l=&clients; (*l)->next; l=&(*l)->next)
270 c4da6427 2010-02-19 rsc if ((*l)->state == 1)
271 c4da6427 2010-02-19 rsc c = *l;
272 c4da6427 2010-02-19 rsc if (c == 0)
273 c4da6427 2010-02-19 rsc return;
274 ac33a34a 2005-07-13 devnull XMapRaised(dpy, c->parent);
275 ac33a34a 2005-07-13 devnull top(c);
276 ac33a34a 2005-07-13 devnull active(c);
277 ac33a34a 2005-07-13 devnull }else{
278 ac33a34a 2005-07-13 devnull c = clients;
279 ac33a34a 2005-07-13 devnull for(l=&clients; *l; l=&(*l)->next)
280 ac33a34a 2005-07-13 devnull ;
281 ac33a34a 2005-07-13 devnull clients = c->next;
282 ac33a34a 2005-07-13 devnull *l = c;
283 ac33a34a 2005-07-13 devnull c->next = 0;
284 ac33a34a 2005-07-13 devnull XLowerWindow(dpy, c->window);
285 ac33a34a 2005-07-13 devnull }
286 cbeb0b26 2006-04-01 devnull /* XMapRaised(dpy, clients->parent); */
287 cbeb0b26 2006-04-01 devnull /* top(clients); */
288 cbeb0b26 2006-04-01 devnull /* active(clients); */
289 ac33a34a 2005-07-13 devnull }