]> git.decadent.org.uk Git - ion3.git/blob - ioncore/attach.c
Merge commit '20070203' into HEAD
[ion3.git] / ioncore / attach.c
1 /*
2  * ion/ioncore/attach.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-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 <string.h>
13 #include <limits.h>
14
15 #include "common.h"
16 #include "global.h"
17 #include "region.h"
18 #include "attach.h"
19 #include "clientwin.h"
20 #include "saveload.h"
21 #include "manage.h"
22 #include "extlconv.h"
23 #include "names.h"
24
25
26 /*{{{ Helper */
27
28
29 static WRegion *doit_new(WRegion *mgr,
30                          WWindow *par, const WFitParams *fp,
31                          WRegionDoAttachFn *cont, void *cont_param,
32                          WRegionCreateFn *fn, void *fn_param)
33 {
34     WRegion *reg=fn(par, fp, fn_param);
35     
36     if(reg==NULL)
37         return NULL;
38         
39     if(!cont(mgr, reg, cont_param)){
40         destroy_obj((Obj*)reg);
41         return NULL;
42     }
43     
44     return reg;
45 }
46
47
48 static WRegion *doit_reparent(WRegion *mgr,
49                               WWindow *par, const WFitParams *fp,
50                               WRegionDoAttachFn *cont, void *cont_param,
51                               WRegion *reg)
52 {
53     WFitParams fp2;
54
55     if(!region_attach_reparent_check(mgr, reg))
56         return NULL;
57     
58     if(fp->mode&REGION_FIT_WHATEVER){
59         /* fp->g is not final; substitute size with current to avoid
60          * useless resizing. 
61          */
62         fp2.mode=fp->mode;
63         fp2.g.x=fp->g.x;
64         fp2.g.y=fp->g.y;
65         fp2.g.w=REGION_GEOM(reg).w;
66         fp2.g.h=REGION_GEOM(reg).h;
67         fp=&fp2;
68     }
69     
70     if(!region_fitrep(reg, par, fp)){
71         warn(TR("Unable to reparent."));
72         return NULL;
73     }
74     
75     region_detach_manager(reg);
76     
77     if(!cont(mgr, reg, cont_param)){
78         #warning "TODO: What?"
79         return NULL;
80     }
81        
82     return reg;
83 }
84
85
86 static WRegion *wrap_load(WWindow *par, const WFitParams *fp, 
87                           ExtlTab *tab)
88 {
89     return create_region_load(par, fp, *tab);
90 }
91
92
93 WRegion *ioncore_newly_created=NULL;
94
95
96 static WRegion *doit_load(WRegion *mgr,
97                           WWindow *par, const WFitParams *fp,
98                           WRegionDoAttachFn *cont, void *cont_param,
99                           ExtlTab tab)
100 {
101     WRegion *reg=NULL;
102     
103     if(extl_table_gets_o(tab, "reg", (Obj**)&reg)){
104         if(!OBJ_IS(reg, WRegion))
105             return FALSE;
106     }/*else if(extl_table_is_bool_set(tab, "reg_use_new")){
107         reg=ioncore_newly_created;
108         if(reg==NULL)
109             return NULL;
110     }*/
111     
112     if(reg!=NULL){
113         return doit_reparent(mgr, par, fp, cont, cont_param, reg);
114     }else{
115         return doit_new(mgr, par, fp, cont, cont_param,
116                         (WRegionCreateFn*)wrap_load, &tab);
117     }
118 }
119
120 WRegion *region_attach_helper(WRegion *mgr,
121                               WWindow *par, const WFitParams *fp,
122                               WRegionDoAttachFn *fn, void *fn_param,
123                               const WRegionAttachData *data)
124 {
125     if(data->type==REGION_ATTACH_NEW){
126         return doit_new(mgr, par, fp, fn, fn_param, 
127                         data->u.n.fn, data->u.n.param);
128     }else if(data->type==REGION_ATTACH_LOAD){
129         return doit_load(mgr, par, fp, fn, fn_param, data->u.tab);
130     }else if(data->type==REGION_ATTACH_REPARENT){
131         return doit_reparent(mgr, par, fp, fn, fn_param, data->u.reg);
132     }else{
133         return NULL;
134     }
135 }
136
137
138 /*}}}*/
139
140
141 /*{{{ Reparent check */
142
143
144 bool region_attach_reparent_check(WRegion *mgr, WRegion *reg)
145 {
146     WRegion *reg2;
147     
148     /*if(REGION_MANAGER(reg)==mgr){
149         warn(TR("Same manager."));
150         return FALSE;
151     }*/
152     
153     /* Check that reg is not a parent or manager of mgr */
154     for(reg2=mgr; reg2!=NULL; reg2=REGION_MANAGER(reg2)){
155         if(reg2==reg)
156             goto err;
157     }
158     
159     for(reg2=REGION_PARENT_REG(mgr); reg2!=NULL; reg2=REGION_PARENT_REG(reg2)){
160         if(reg2==reg)
161             goto err;
162     }
163
164     return TRUE;
165     
166 err:
167     warn(TR("Attempt to make region %s manage its ancestor %s."),
168          region_name(mgr), region_name(reg));
169     return FALSE;
170 }
171
172
173 /*}}}*/
174
175