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