Renamed package to ion1, and made it conflict with package 'ion'.
[ion1.git] / src / thing.c
blob7ba5655709ed15cb8db3cbe181bbd2f62bb76905
1 /*
2 * ion/thing.c
4 * Copyright (c) Tuomo Valkonen 1999-2001.
5 * See the included file LICENSE for details.
6 */
8 #include "common.h"
9 #include "thing.h"
10 #include "thingp.h"
11 #include "global.h"
12 #include "client.h"
13 #include "wedln.h"
14 #include "query.h"
15 #include "grab.h"
18 IMPLOBJ(WThing, WObj, NULL)
21 /*{{{ Destroy */
24 static void do_destroy_thing(WThing *t)
26 WThing *p;
28 p=t->t_parent;
30 /* Make sure that any command sequence doesn't try to
31 * access this thing anymore.
33 query_check_function_thing(t);
35 destroy_subthings(t);
37 if(p!=NULL)
38 CALL_FUNTAB(p, WThingFuntab, remove_child_fn)(p, t);
40 grab_remove_for(t);
42 unlink_thing(t);
44 CALL_FUNTAB(t, WThingFuntab, deinit_fn)(t);
46 free(t);
48 if(wglobal.focus_next==t)
49 wglobal.focus_next=NULL;
50 if(wglobal.grab_holder==t)
51 wglobal.grab_holder=NULL;
52 if(wglobal.previous==t)
53 wglobal.previous=p;
57 void destroy_thing(WThing *t)
59 WThing *p;
61 while(1){
62 p=t->t_parent;
63 do_destroy_thing(t);
65 if(p==NULL)
66 break;
68 if(!(p->flags&WTHING_DESTREMPTY) || p->t_children!=NULL)
69 break;
71 t=p;
76 void destroy_subthings(WThing *parent)
78 WThing *t, *prev=NULL;
80 assert(!(parent->flags&WTHING_SUBDEST));
82 parent->flags|=WTHING_SUBDEST;
84 /* destroy children */
85 while(1){
86 t=parent->t_children;
87 if(t==NULL)
88 break;
89 assert(t!=prev);
90 prev=t;
91 do_destroy_thing(t);
94 parent->flags&=~WTHING_SUBDEST;
98 /*}}}*/
101 /*{{{ Linking */
104 void link_thing(WThing *parent, WThing *thing)
106 LINK_ITEM(parent->t_children, thing, t_next, t_prev);
107 thing->t_parent=parent;
111 /*void link_thing_before(WThing *before, WThing *thing)
113 WThing *parent=before->t_parent;
114 LINK_ITEM_BEFORE(parent->t_children, before, thing, t_next, t_prev);
115 thing->t_parent=parent;
119 void link_thing_after(WThing *after, WThing *thing)
121 WThing *parent=after->t_parent;
122 LINK_ITEM_AFTER(parent->t_children, after, thing, t_next, t_prev);
123 thing->t_parent=parent;
127 void unlink_thing(WThing *thing)
129 WThing *parent=thing->t_parent;
131 if(parent==NULL)
132 return;
134 UNLINK_ITEM(parent->t_children, thing, t_next, t_prev);
135 thing->t_parent=NULL;
139 /*}}}*/
142 /*{{{ Scan */
145 static WThing *get_next_thing(WThing *first, const WObjDescr *descr)
147 while(first!=NULL){
148 if(wobj_is((WObj*)first, descr))
149 break;
150 first=first->t_next;
153 return first;
157 static WThing *get_prev_thing(WThing *first, const WObjDescr *descr)
159 if(first==NULL)
160 return NULL;
162 while(1){
163 first=first->t_prev;
164 if(first->t_next==NULL)
165 return NULL;
166 if(wobj_is((WObj*)first, descr))
167 break;
170 return first;
174 WThing *next_thing(WThing *first, const WObjDescr *descr)
176 if(first==NULL)
177 return NULL;
179 return get_next_thing(first->t_next, descr);
183 WThing *prev_thing(WThing *first, const WObjDescr *descr)
185 if(first==NULL)
186 return NULL;
188 return get_prev_thing(first, descr);
192 WThing *first_thing(WThing *parent, const WObjDescr *descr)
194 if(parent==NULL)
195 return NULL;
197 return get_next_thing(parent->t_children, descr);
201 WThing *last_thing(WThing *parent, const WObjDescr *descr)
203 WThing *p;
205 if(parent==NULL)
206 return NULL;
208 p=parent->t_children;
210 if(p==NULL)
211 return NULL;
213 p=p->t_prev;
215 if(wobj_is((WObj*)p, descr))
216 return p;
218 return get_prev_thing(p, descr);
222 WThing *find_parent(WThing *p, const WObjDescr *descr)
224 while(p!=NULL){
225 if(wobj_is((WObj*)p, descr))
226 break;
227 p=p->t_parent;
230 return p;
234 WThing *nth_thing(WThing *parent, int n, const WObjDescr *descr)
236 WThing *p;
238 if(n<0)
239 return NULL;
241 p=first_thing(parent, descr);
243 while(n-- && p!=NULL)
244 p=next_thing(p, descr);
246 return p;