]> git.decadent.org.uk Git - ion3.git/blob - ioncore/grouppholder.c
[svn-upgrade] Integrating new upstream version, ion3 (20070506)
[ion3.git] / ioncore / grouppholder.c
1 /*
2  * ion/ioncore/grouppholder.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 <libtu/obj.h>
11 #include <libtu/pointer.h>
12
13 #include <ioncore/common.h>
14 #include "group.h"
15 #include "grouppholder.h"
16
17
18 static void group_watch_handler(Watch *watch, Obj *ws);
19
20
21 /*{{{ Init/deinit */
22
23
24 static void group_watch_handler(Watch *watch, Obj *ws)
25 {
26     WGroupPHolder *ph=FIELD_TO_STRUCT(WGroupPHolder, 
27                                       group_watch, watch);
28     pholder_redirect(&(ph->ph), (WRegion*)ws);
29 }
30
31
32 static WGroupAttachParams dummy_param=GROUPATTACHPARAMS_INIT;
33
34
35 bool grouppholder_init(WGroupPHolder *ph, WGroup *ws,
36                        const WStacking *st,
37                        const WGroupAttachParams *param)
38 {
39     pholder_init(&(ph->ph));
40
41     watch_init(&(ph->group_watch));
42     watch_init(&(ph->stack_above_watch));
43     
44     if(ws!=NULL){
45         if(!watch_setup(&(ph->group_watch), (Obj*)ws, 
46                         group_watch_handler)){
47             pholder_deinit(&(ph->ph));
48             return FALSE;
49         }
50     }
51     
52     if(param==NULL)
53         param=&dummy_param;
54     
55     if(st!=NULL){
56         /* TODO? Just link to the stacking structure to remember 
57          * stacking order? 
58          */
59         
60         ph->param.szplcy_set=TRUE;
61         ph->param.szplcy=st->szplcy;
62         ph->param.level_set=TRUE;
63         ph->param.level=st->level;
64         
65         if(st->reg!=NULL){
66             ph->param.geom_set=TRUE;
67             ph->param.geom=REGION_GEOM(st->reg);
68         }
69         
70         if(st->above!=NULL && st->above->reg!=NULL)
71             ph->param.stack_above=st->above->reg;
72         
73         ph->param.bottom=(st==ws->bottom);
74     }else{
75         ph->param=*param;
76     }
77
78     ph->param.switchto_set=FALSE;
79
80     if(ph->param.stack_above!=NULL){
81         /* We must move stack_above pointer into a Watch. */
82         watch_setup(&(ph->stack_above_watch), 
83                     (Obj*)ph->param.stack_above, NULL);
84         ph->param.stack_above=NULL;
85     }
86     
87     return TRUE;
88 }
89  
90
91 WGroupPHolder *create_grouppholder(WGroup *ws,
92                                    const WStacking *st,
93                                    const WGroupAttachParams *param)
94 {
95     CREATEOBJ_IMPL(WGroupPHolder, grouppholder, (p, ws, st, param));
96 }
97
98
99 void grouppholder_deinit(WGroupPHolder *ph)
100 {
101     watch_reset(&(ph->group_watch));
102     watch_reset(&(ph->stack_above_watch));
103     pholder_deinit(&(ph->ph));
104 }
105
106
107 /*}}}*/
108
109
110 /*{{{ Dynfuns */
111
112
113 WRegion *grouppholder_do_attach(WGroupPHolder *ph, int flags,
114                                 WRegionAttachData *data)
115 {
116     WGroup *ws=(WGroup*)ph->group_watch.obj;
117     WRegion *reg;
118
119     if(ws==NULL)
120         return FALSE;
121
122     ph->param.switchto_set=1;
123     ph->param.switchto=(flags&PHOLDER_ATTACH_SWITCHTO ? 1 : 0);
124     
125     /* Get stack_above from Watch. */
126     ph->param.stack_above=(WRegion*)ph->stack_above_watch.obj;
127     
128     reg=group_do_attach(ws, &ph->param, data);
129     
130     ph->param.stack_above=NULL;
131
132     return reg;
133 }
134
135
136 bool grouppholder_do_goto(WGroupPHolder *ph)
137 {
138     WGroup *ws=(WGroup*)ph->group_watch.obj;
139     
140     if(ws!=NULL)
141         return region_goto((WRegion*)ws);
142     
143     return FALSE;
144 }
145
146
147 WRegion *grouppholder_do_target(WGroupPHolder *ph)
148 {
149     return (WRegion*)ph->group_watch.obj;
150 }
151
152
153 /*}}}*/
154
155
156 /*{{{ WGroup stuff */
157
158
159 WGroupPHolder *group_managed_get_pholder(WGroup *ws, WRegion *mgd)
160 {
161     WStacking *st=group_find_stacking(ws, mgd);
162     
163     if(mgd==NULL)
164         return NULL;
165     else
166         return create_grouppholder(ws, st, NULL);
167 }
168
169
170 /*}}}*/
171
172
173 /*{{{ Class information */
174
175
176 static DynFunTab grouppholder_dynfuntab[]={
177     {(DynFun*)pholder_do_attach, 
178      (DynFun*)grouppholder_do_attach},
179
180     {(DynFun*)pholder_do_goto, 
181      (DynFun*)grouppholder_do_goto},
182
183     {(DynFun*)pholder_do_target, 
184      (DynFun*)grouppholder_do_target},
185     
186     END_DYNFUNTAB
187 };
188
189 IMPLCLASS(WGroupPHolder, WPHolder, grouppholder_deinit, 
190           grouppholder_dynfuntab);
191
192
193 /*}}}*/
194