]> git.decadent.org.uk Git - ion3.git/blob - ioncore/pholder.c
[svn-upgrade] Integrating new upstream version, ion3 (20070506)
[ion3.git] / ioncore / pholder.c
1 /*
2  * ion/ioncore/pholder.c
3  *
4  * Copyright (c) Tuomo Valkonen 2005-2007. 
5  *
6  * See the included file LICENSE for details.
7  */
8
9 #include <libtu/objp.h>
10 #include "common.h"
11 #include "attach.h"
12 #include "pholder.h"
13 #include "focus.h"
14
15
16 bool pholder_init(WPHolder *ph)
17 {
18     ph->redirect=NULL;
19     return TRUE;
20 }
21
22
23 void pholder_deinit(WPHolder *ph)
24 {
25     if(ph->redirect!=NULL)
26         destroy_obj((Obj*)ph->redirect);
27 }
28
29
30 WRegion *pholder_do_attach(WPHolder *ph, int flags,
31                            WRegionAttachData *data)
32
33 {
34     WRegion *ret=NULL;
35     CALL_DYN_RET(ret, WRegion*, pholder_do_attach, ph, (ph, flags, data));
36     return ret;
37 }
38
39
40 WRegion *pholder_attach_(WPHolder *ph, int flags, WRegionAttachData *data)
41 {
42     WPHolder *root=pholder_root(ph);
43     
44     /* Use the root, so that extra containers are not added from
45      * stale chains.
46      */
47     
48     return (root==NULL
49             ? NULL
50             : pholder_do_attach(root, flags, data));
51 }
52
53
54 bool pholder_attach(WPHolder *ph, int flags, WRegion *reg)
55 {
56     WRegionAttachData data;
57         
58     data.type=REGION_ATTACH_REPARENT;
59     data.u.reg=reg;
60     
61     return (pholder_attach_(ph, flags, &data)!=NULL);
62 }
63
64
65 bool pholder_attach_mcfgoto(WPHolder *ph, int flags, WRegion *reg)
66 {
67     bool cf=region_may_control_focus(reg);
68     
69     if(!pholder_attach(ph, flags, reg))
70         return FALSE;
71         
72     if(cf)
73         region_goto(reg);
74     
75     return TRUE;
76 }
77
78
79 WRegion *pholder_do_target(WPHolder *ph)
80 {
81     WRegion *ret=NULL;
82     CALL_DYN_RET(ret, WRegion*, pholder_do_target, ph, (ph));
83     return ret;
84 }
85
86
87 WRegion *pholder_target(WPHolder *ph)
88 {
89     return (ph->redirect!=NULL
90             ? pholder_target(ph->redirect)
91             : pholder_do_target(ph));
92 }
93
94
95 static bool pholder_do_check_reparent_default(WPHolder *ph, WRegion *reg)
96 {
97     WRegion *target=pholder_do_target(ph);
98     
99     return (target==NULL 
100             ? FALSE
101             : region_ancestor_check(target, reg));
102 }
103
104
105 DYNFUN bool pholder_do_check_reparent(WPHolder *ph, WRegion *reg)
106 {
107     bool ret=FALSE;
108     CALL_DYN_RET(ret, bool, pholder_do_check_reparent, ph, (ph, reg));
109     return ret;
110 }
111
112
113 bool pholder_check_reparent(WPHolder *ph, WRegion *reg)
114 {
115     if(ph->redirect!=NULL)
116         return pholder_check_reparent(ph->redirect, reg);
117     else
118         return pholder_do_check_reparent(ph, reg);
119 }
120     
121
122 bool pholder_do_goto(WPHolder *ph)
123 {
124     bool ret=FALSE;
125     CALL_DYN_RET(ret, bool, pholder_do_goto, ph, (ph));
126     return ret;
127 }
128
129
130 bool pholder_goto(WPHolder *ph)
131 {
132     return (ph->redirect!=NULL
133             ? pholder_goto(ph->redirect)
134             : pholder_do_goto(ph));
135 }
136
137
138 WPHolder *pholder_do_root_default(WPHolder *ph)
139 {
140     return ph;
141 }
142
143
144 WPHolder *pholder_do_root(WPHolder *ph)
145 {
146     WPHolder *ret=NULL;
147     CALL_DYN_RET(ret, WPHolder*, pholder_do_root, ph, (ph));
148     return ret;
149 }
150
151
152 WPHolder *pholder_root(WPHolder *ph)
153 {
154     return (ph->redirect!=NULL
155             ? pholder_root(ph->redirect)
156             : pholder_do_root(ph));
157 }
158
159
160 bool pholder_stale(WPHolder *ph)
161 {
162     return (pholder_root(ph)!=ph);
163 }
164
165
166 bool pholder_redirect(WPHolder *ph, WRegion *old_target)
167 {
168     WPHolder *ph2=region_get_rescue_pholder(old_target);
169     
170     if(ph2==NULL)
171         return FALSE;
172     
173     if(ph->redirect!=NULL)
174         destroy_obj((Obj*)ph->redirect);
175
176     ph->redirect=ph2;
177     
178     return TRUE;
179 }
180
181
182 WPHolder *region_managed_get_pholder(WRegion *reg, WRegion *mgd)
183 {
184     WPHolder *ret=NULL;
185     CALL_DYN_RET(ret, WPHolder*, region_managed_get_pholder, 
186                  reg, (reg, mgd));
187     return ret;
188 }
189
190
191 WPHolder *region_get_rescue_pholder_for(WRegion *reg, WRegion *mgd)
192 {
193     if(OBJ_IS_BEING_DESTROYED(reg) || reg->flags&REGION_CWINS_BEING_RESCUED){
194         return FALSE;
195     }else{
196         WPHolder *ret=NULL;
197     
198         CALL_DYN_RET(ret, WPHolder*, region_get_rescue_pholder_for,
199                      reg, (reg, mgd));
200         return ret;
201     }
202 }
203
204
205 WPHolder *region_get_rescue_pholder(WRegion *reg)
206 {
207     WRegion *mgr;
208     WPHolder *ph=NULL;
209
210     while(1){
211         mgr=region_manager_or_parent(reg);
212         if(mgr==NULL)
213             break;
214         ph=region_get_rescue_pholder_for(mgr, reg);
215         if(ph!=NULL)
216             break;
217         reg=mgr;
218     }
219     
220     return ph;
221 }
222
223
224 WPHolder *pholder_either(WPHolder *a, WPHolder *b)
225 {
226     return (a!=NULL ? a : b);
227 }
228
229
230 static DynFunTab pholder_dynfuntab[]={
231     {(DynFun*)pholder_do_check_reparent, 
232      (DynFun*)pholder_do_check_reparent_default},
233      
234     {(DynFun*)pholder_do_root, 
235      (DynFun*)pholder_do_root_default},
236
237     END_DYNFUNTAB
238 };
239
240
241 IMPLCLASS(WPHolder, Obj, pholder_deinit, pholder_dynfuntab);
242