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