CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/win_regions.c
Go to the documentation of this file.
1/*
2 * WindowRegion handling
3 */
4
5#include "ctwm.h"
6
7#include <stdlib.h>
8
9#include "list.h"
10#include "screen.h"
11#include "win_regions.h"
12#include "xparsegeometry.h"
13
14
16 RegGravity grav1, RegGravity grav2,
17 int w, int h);
22
23
24
25/*
26 * Backend for the parser when it hits WindowRegion
27 */
28name_list **
30{
31 WindowRegion *wr;
32 int mask;
33
34 wr = malloc(sizeof(WindowRegion));
35 wr->next = NULL;
36
37 if(!Scr->FirstWindowRegion) {
38 Scr->FirstWindowRegion = wr;
39 }
40
41 wr->entries = NULL;
42 wr->clientlist = NULL;
43 wr->grav1 = grav1;
44 wr->grav2 = grav2;
45 wr->x = wr->y = wr->w = wr->h = 0;
46
47 mask = RLayoutXParseGeometry(Scr->Layout, geom, &wr->x, &wr->y,
48 (unsigned int *) &wr->w,
49 (unsigned int *) &wr->h);
50
51 if(mask & XNegative) {
52 wr->x += Scr->rootw - wr->w;
53 }
54 if(mask & YNegative) {
55 wr->y += Scr->rooth - wr->h;
56 }
57
58 return (&(wr->clientlist));
59}
60
61
62/*
63 * Called during startup after the config parsing (which would hit
64 * AddWindowRegion() above) to do some further setup.
65 */
66void
68{
69 WindowRegion *wr, *wr1 = NULL, *wr2 = NULL;
70 WorkSpace *wl;
71
72 for(wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) {
74 wr2 = NULL;
75 for(wr = Scr->FirstWindowRegion; wr != NULL; wr = wr->next) {
76 wr1 = malloc(sizeof(WindowRegion));
77 *wr1 = *wr;
78 wr1->entries = calloc(1, sizeof(WindowEntry));
79 wr1->entries->x = wr1->x;
80 wr1->entries->y = wr1->y;
81 wr1->entries->w = wr1->w;
82 wr1->entries->h = wr1->h;
83 if(wr2) {
84 wr2->next = wr1;
85 }
86 else {
88 }
89 wr2 = wr1;
90 }
91 if(wr1) {
92 wr1->next = NULL;
93 }
94 }
95}
96
97
98/*
99 * Funcs for putting windows into and taking them out of regions.
100 * Similarly to icons in IconRegion's, this writes the coordinates into
101 * final_[xy] after setting up the Window Region/Entry structures and
102 * stashing them in tmp_win as necessary. Or it doesn't have anything to
103 * do (like if the user doesn't have WindowRegion's config'd), and it
104 * doesn't touch anything and returns false.
105 */
106bool
108{
109 WindowRegion *wr;
111 int w, h;
112 WorkSpace *wl;
113
114 if(!Scr->FirstWindowRegion) {
115 return false;
116 }
117 for(wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) {
118 if(OCCUPY(tmp_win, wl)) {
119 break;
120 }
121 }
122 if(!wl) {
123 return false;
124 }
125 w = tmp_win->frame_width;
126 h = tmp_win->frame_height;
127 we = NULL;
128 for(wr = wl->FirstWindowRegion; wr; wr = wr->next) {
129 if(LookInList(wr->clientlist, tmp_win->name, &tmp_win->class)) {
130 for(we = wr->entries; we; we = we->next) {
131 if(we->used) {
132 continue;
133 }
134 if(we->w >= w && we->h >= h) {
135 break;
136 }
137 }
138 if(we) {
139 break;
140 }
141 }
142 }
143 tmp_win->wr = NULL;
144 if(!we) {
145 return false;
146 }
147
148 splitWindowRegionEntry(we, wr->grav1, wr->grav2, w, h);
149 we->used = true;
150 we->twm_win = tmp_win;
151 *final_x = we->x;
152 *final_y = we->y;
153 tmp_win->wr = wr;
154 return true;
155}
156
157
158/*
159 * Taking a window out of a region. Doesn't do anything with the
160 * _window_, just disconnects it from the data structures describing the
161 * regions and entries.
162 */
163void
165{
166 WindowEntry *we, *wp, *wn;
167 WindowRegion *wr;
168 WorkSpace *wl;
169
170 if(!Scr->FirstWindowRegion) {
171 return;
172 }
173 we = NULL;
174 for(wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) {
175 we = findWindowEntry(wl, tmp_win, &wr);
176 if(we) {
177 break;
178 }
179 }
180 if(!we) {
181 return;
182 }
183
184 we->twm_win = NULL;
185 we->used = false;
186 wp = prevWindowEntry(we, wr);
187 wn = we->next;
188 for(;;) {
189 if(wp && wp->used == false &&
190 ((wp->x == we->x && wp->w == we->w) ||
191 (wp->y == we->y && wp->h == we->h))) {
192 wp->next = we->next;
194 free(we);
195 we = wp;
196 wp = prevWindowEntry(wp, wr);
197 }
198 else if(wn && wn->used == false &&
199 ((wn->x == we->x && wn->w == we->w) ||
200 (wn->y == we->y && wn->h == we->h))) {
201 we->next = wn->next;
203 free(wn);
204 wn = we->next;
205 }
206 else {
207 break;
208 }
209 }
210}
211
212
213/*
214 * Creating a new space inside a region.
215 *
216 * x-ref comment on splitIconRegionEntry() for grodiness.
217 */
218static void
220 int w, int h)
221{
222 switch(grav1) {
223 case GRAV_NORTH:
224 case GRAV_SOUTH:
225 if(w != we->w) {
226 splitWindowRegionEntry(we, grav2, grav1, w, we->h);
227 }
228 if(h != we->h) {
229 WindowEntry *new = calloc(1, sizeof(WindowEntry));
230 new->next = we->next;
231 we->next = new;
232 new->x = we->x;
233 new->h = (we->h - h);
234 new->w = we->w;
235 we->h = h;
236 if(grav1 == GRAV_SOUTH) {
237 new->y = we->y;
238 we->y = new->y + new->h;
239 }
240 else {
241 new->y = we->y + we->h;
242 }
243 }
244 break;
245 case GRAV_EAST:
246 case GRAV_WEST:
247 if(h != we->h) {
248 splitWindowRegionEntry(we, grav2, grav1, we->w, h);
249 }
250 if(w != we->w) {
251 WindowEntry *new = calloc(1, sizeof(WindowEntry));
252 new->next = we->next;
253 we->next = new;
254 new->y = we->y;
255 new->w = (we->w - w);
256 new->h = we->h;
257 we->w = w;
258 if(grav1 == GRAV_EAST) {
259 new->x = we->x;
260 we->x = new->x + new->w;
261 }
262 else {
263 new->x = we->x + we->w;
264 }
265 }
266 break;
267 }
268}
269
270
271/*
272 * Utils for finding and merging various WindowEntry's
273 */
274static WindowEntry *
276{
277 WindowRegion *wr;
279
280 for(wr = wl->FirstWindowRegion; wr; wr = wr->next) {
281 for(we = wr->entries; we; we = we->next) {
282 if(we->twm_win == tmp_win) {
283 if(wrp) {
284 *wrp = wr;
285 }
286 return we;
287 }
288 }
289 }
290 return NULL;
291}
292
293
294static WindowEntry *
296{
298
299 if(we == wr->entries) {
300 return 0;
301 }
302 for(wp = wr->entries; wp->next != we; wp = wp->next);
303 return wp;
304}
305
306
307static void
309{
310 if(old->y == we->y) {
311 we->w = old->w + we->w;
312 if(old->x < we->x) {
313 we->x = old->x;
314 }
315 }
316 else {
317 we->h = old->h + we->h;
318 if(old->y < we->y) {
319 we->y = old->y;
320 }
321 }
322}
static int PlaceX
Definition add_window.c:82
#define OCCUPY(w, b)
Definition ctwm.h:369
RegGravity
Definition ctwm.h:227
@ GRAV_WEST
Definition ctwm.h:231
@ GRAV_SOUTH
Definition ctwm.h:230
@ GRAV_EAST
Definition ctwm.h:229
@ GRAV_NORTH
Definition ctwm.h:228
#define Scr
void * LookInList(name_list *list_head, const char *name, XClassHint *class)
Definition list.c:101
Info and control for every X Window we take over.
int w
Definition ctwm.h:297
struct WindowRegion * next
Definition ctwm.h:288
RegGravity grav1
Definition ctwm.h:290
RegGravity grav2
Definition ctwm.h:290
struct WindowEntry * entries
Definition ctwm.h:292
name_list * clientlist
Definition ctwm.h:291
struct WindowRegion * FirstWindowRegion
struct WorkSpace * next
char * name
Definition list.h:22
static WindowEntry * prevWindowEntry(WindowEntry *we, WindowRegion *wr)
void RemoveWindowFromRegion(TwmWindow *tmp_win)
static void mergeWindowEntries(WindowEntry *old, WindowEntry *we)
static WindowEntry * findWindowEntry(WorkSpace *wl, TwmWindow *tmp_win, WindowRegion **wrp)
static void splitWindowRegionEntry(WindowEntry *we, RegGravity grav1, RegGravity grav2, int w, int h)
bool PlaceWindowInRegion(TwmWindow *tmp_win, int *final_x, int *final_y)
void CreateWindowRegions(void)
Definition win_regions.c:67
name_list ** AddWindowRegion(char *geom, RegGravity grav1, RegGravity grav2)
Definition win_regions.c:29
int RLayoutXParseGeometry(RLayout *layout, const char *geometry, int *x, int *y, unsigned int *width, unsigned int *height)
Parse an X Geometry out to get the positions and sizes.