]> git.decadent.org.uk Git - ion3.git/blob - ioncore/attach.c
[svn-inject] Installing original source of ion3
[ion3.git] / ioncore / attach.c
1 /*
2  * ion/ioncore/attach.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2006. 
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 static WRegion *doit_load(WRegion *mgr,
94                           WWindow *par, const WFitParams *fp,
95                           WRegionDoAttachFn *cont, void *cont_param,
96                           ExtlTab tab)
97 {
98     WRegion *reg;
99     
100     if(extl_table_gets_o(tab, "reg", (Obj**)&reg)){
101         if(!OBJ_IS(reg, WRegion))
102             return FALSE;
103         return doit_reparent(mgr, par, fp, cont, cont_param, reg);
104     }
105     
106     return doit_new(mgr, par, fp, cont, cont_param,
107                     (WRegionCreateFn*)wrap_load, &tab);
108 }
109
110 WRegion *region_attach_helper(WRegion *mgr,
111                               WWindow *par, const WFitParams *fp,
112                               WRegionDoAttachFn *fn, void *fn_param,
113                               const WRegionAttachData *data)
114 {
115     if(data->type==REGION_ATTACH_NEW){
116         return doit_new(mgr, par, fp, fn, fn_param, 
117                         data->u.n.fn, data->u.n.param);
118     }else if(data->type==REGION_ATTACH_LOAD){
119         return doit_load(mgr, par, fp, fn, fn_param, data->u.tab);
120     }else if(data->type==REGION_ATTACH_REPARENT){
121         return doit_reparent(mgr, par, fp, fn, fn_param, data->u.reg);
122     }else{
123         return NULL;
124     }
125 }
126
127
128 /*}}}*/
129
130
131 /*{{{ Reparent check */
132
133
134 bool region_attach_reparent_check(WRegion *mgr, WRegion *reg)
135 {
136     WRegion *reg2;
137     
138     /*if(REGION_MANAGER(reg)==mgr){
139         warn(TR("Same manager."));
140         return FALSE;
141     }*/
142     
143     /* Check that reg is not a parent or manager of mgr */
144     for(reg2=mgr; reg2!=NULL; reg2=REGION_MANAGER(reg2)){
145         if(reg2==reg)
146             goto err;
147     }
148     
149     for(reg2=REGION_PARENT_REG(mgr); reg2!=NULL; reg2=REGION_PARENT_REG(reg2)){
150         if(reg2==reg)
151             goto err;
152     }
153
154     return TRUE;
155     
156 err:
157     warn(TR("Attempt to make region %s manage its ancestor %s."),
158          region_name(mgr), region_name(reg));
159     return FALSE;
160 }
161
162
163 /*}}}*/
164
165