1 /*
2 * pwm/thing.c
3 *
4 * Copyright (c) Tuomo Valkonen 1999-2001.
5 *
6 * You may distribute and modify this program under the terms of either
7 * the Clarified Artistic License or the GNU GPL, version 2 or later.
8 */
9
10 #include "common.h"
11 #include "thing.h"
12 #include "frame.h"
13 #include "clientwin.h"
14
15
destroy_thing(WThing * t)16 void destroy_thing(WThing *t)
17 {
18 if(WTHING_IS(t, WTHING_FRAME))
19 destroy_frame((WFrame*)t);
20 else if(WTHING_IS(t, WTHING_DOCK))
21 destroy_dock((WDock*)t);
22 else if(WTHING_IS(t, WTHING_MENU))
23 destroy_menu_tree((WMenu*)t);
24 else if(WTHING_IS(t, WTHING_CLIENTWIN))
25 unmanage_clientwin((WClientWin*)t);
26 }
27
28
free_thing(WThing * t)29 void free_thing(WThing *t)
30 {
31 if(wglobal.focus_next==t)
32 wglobal.focus_next=NULL/*(WThing*)SCREEN*/;
33 if(wglobal.grab_holder==t)
34 wglobal.grab_holder=NULL;
35 free(t);
36 }
37
38
destroy_subthings(WThing * parent)39 void destroy_subthings(WThing *parent)
40 {
41 WThing *t, *prev=NULL;
42
43 /* assert(!(parent->flags&WTHING_SUBDEST)); */
44 if (parent->flags & WTHING_SUBDEST) {
45 fprintf(stderr, __FILE__ ": %d: destroy_subthings: "
46 "parent->flags & WTHING_SUBDEST\n", __LINE__);
47 /* Do nothing - we're in some weird trouble here. */
48 } else {
49 parent->flags |= WTHING_SUBDEST;
50
51 /* destroy children */
52 while ((t = parent->t_children) != NULL) {
53 assert(t!=prev);
54 prev=t;
55 destroy_thing(t);
56 }
57
58 parent->flags&=~WTHING_SUBDEST;
59 }
60 }
61
62
63 /* */
64
65
link_thing(WThing * parent,WThing * thing)66 void link_thing(WThing *parent, WThing *thing)
67 {
68 LINK_ITEM(parent->t_children, thing, t_next, t_prev);
69 thing->t_parent=parent;
70 }
71
72
link_thing_before(WThing * before,WThing * thing)73 void link_thing_before(WThing *before, WThing *thing)
74 {
75 WThing *parent=before->t_parent;
76 LINK_ITEM_BEFORE(parent->t_children, before, thing, t_next, t_prev);
77 thing->t_parent=parent;
78 }
79
80
unlink_thing(WThing * thing)81 void unlink_thing(WThing *thing)
82 {
83 WThing *parent=thing->t_parent;
84
85 if(parent==NULL)
86 return;
87
88 UNLINK_ITEM(parent->t_children, thing, t_next, t_prev);
89 }
90
91
92 /* */
93
94
get_next_thing(WThing * first,int filt)95 static WThing *get_next_thing(WThing *first, int filt)
96 {
97 while(first!=NULL){
98 if(filt==0 || WTHING_IS(first, filt))
99 break;
100 first=first->t_next;
101 };
102
103 return first;
104 }
105
106
next_thing(WThing * first,int filt)107 WThing *next_thing(WThing *first, int filt)
108 {
109 if(first==NULL)
110 return NULL;
111
112 return get_next_thing(first->t_next, filt);
113 }
114
get_prev_thing(WThing * first,int filt)115 static WThing *get_prev_thing(WThing *first, int filt)
116 {
117 while(first!=NULL){
118 if(filt==0 || WTHING_IS(first, filt))
119 break;
120 first=first->t_prev;
121 };
122
123 return first;
124 }
125
prev_thing(WThing * first,int filt)126 WThing *prev_thing(WThing *first, int filt)
127 {
128 if(first==NULL)
129 return NULL;
130
131 return get_prev_thing(first->t_prev, filt);
132 }
133
subthing(WThing * parent,int filt)134 WThing *subthing(WThing *parent, int filt)
135 {
136 if(parent==NULL)
137 return NULL;
138
139 return get_next_thing(parent->t_children, filt);
140 }
141
142
next_clientwin(WClientWin * cwin)143 WClientWin *next_clientwin(WClientWin *cwin)
144 {
145 return (WClientWin*)next_thing((WThing*)cwin, WTHING_CLIENTWIN);
146 }
147
148
prev_clientwin(WClientWin * cwin)149 WClientWin *prev_clientwin(WClientWin *cwin)
150 {
151 return (WClientWin*)prev_thing((WThing*)cwin, WTHING_CLIENTWIN);
152 }
153
first_clientwin(WThing * thing)154 WClientWin *first_clientwin(WThing *thing)
155 {
156 return (WClientWin*)subthing(thing, WTHING_CLIENTWIN);
157 }
158
159
nth_thing(WThing * first,int num)160 WThing *nth_thing(WThing *first, int num)
161 {
162 if(first==NULL)
163 return NULL;
164
165 while(num!=0){
166 if(num<0){
167 num++;
168 first=first->t_prev;
169 }else if(num>0){
170 num--;
171 if(first->t_next!=NULL)
172 first=first->t_next;
173 else
174 first=first->t_parent->t_children;
175 }
176 if(num==0)
177 break;
178 }
179
180 return first;
181 }
182
183
nth_subthing(WThing * parent,int num)184 WThing *nth_subthing(WThing *parent, int num)
185 {
186 if(parent==NULL)
187 return NULL;
188
189 return nth_thing(parent->t_children, num);
190 }
191
192
193 /* */
194
195
find_thing(Window win)196 WThing *find_thing(Window win)
197 {
198 WThing *thing;
199
200 if(XFindContext(wglobal.dpy, win, wglobal.win_context,
201 (XPointer*)&thing)!=0)
202 return NULL;
203
204 return thing;
205 }
206
207
find_thing_t(Window win,int type)208 WThing *find_thing_t(Window win, int type)
209 {
210 WThing *thing=find_thing(win);
211
212 if(thing==NULL || !WTHING_IS(thing, type))
213 return NULL;
214
215 return thing;
216 }
217
218
find_clientwin(Window win)219 WClientWin *find_clientwin(Window win)
220 {
221 return (WClientWin*)find_thing_t(win, WTHING_CLIENTWIN);
222 }
223
224
225 /* */
226
227
find_frame_of(Window win)228 WFrame *find_frame_of(Window win)
229 {
230 WWinObj *winobj=find_winobj_of(win);
231
232 if(winobj==NULL || !WTHING_IS(winobj, WTHING_FRAME))
233 return NULL;
234
235 return (WFrame*)winobj;
236 }
237
238
find_winobj_of(Window win)239 WWinObj *find_winobj_of(Window win)
240 {
241 WThing *thing=find_thing(win);
242
243 if(thing==NULL)
244 return NULL;
245
246 if(WTHING_IS(thing, WTHING_FRAME))
247 return (WWinObj*)thing;
248
249 if(WTHING_IS(thing, WTHING_CLIENTWIN) && thing->t_parent!=NULL &&
250 WTHING_IS(thing->t_parent, WTHING_WINOBJ))
251 return (WWinObj*)thing->t_parent;
252
253 return NULL;
254 }
255
256
257 /* */
258
259
winobj_of(WThing * thing)260 WWinObj *winobj_of(WThing *thing)
261 {
262 if(WTHING_IS(thing, WTHING_WINOBJ))
263 return (WWinObj*)thing;
264
265 if(WTHING_IS(thing, WTHING_CLIENTWIN))
266 return (WWinObj*)CWIN_FRAME((WClientWin*)thing);
267
268 return NULL;
269 }
270