2 * ion/ioncore/mplexpholder.c
4 * Copyright (c) Tuomo Valkonen 2005-2006.
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.
12 #include <libtu/objp.h>
13 #include <libtu/obj.h>
14 #include <libtu/pointer.h>
18 #include "mplexpholder.h"
22 static void mplex_watch_handler(Watch *watch, Obj *mplex);
28 static bool on_ph_list(WMPlexPHolder *ll, WMPlexPHolder *ph)
30 return ph->prev!=NULL;
34 static void mplexpholder_do_link(WMPlexPHolder *ph,
39 assert(mplex==(WMPlex*)ph->mplex_watch.obj && mplex!=NULL);
42 assert(after->after==or_after);
44 if(after->after!=NULL){
45 LINK_ITEM_AFTER(after->after->phs, after, ph, next, prev);
47 assert(on_ph_list(mplex->mx_phs, after));
48 LINK_ITEM_AFTER(mplex->mx_phs, after, ph, next, prev);
50 ph->after=after->after;
51 }else if(or_after!=NULL){
52 LINK_ITEM_FIRST(or_after->phs, ph, next, prev);
55 LINK_ITEM_FIRST(mplex->mx_phs, ph, next, prev);
61 void mplexpholder_do_unlink(WMPlexPHolder *ph, WMPlex *mplex)
64 UNLINK_ITEM(ph->after->phs, ph, next, prev);
65 }else if(mplex!=NULL && on_ph_list(mplex->mx_phs, ph)){
66 UNLINK_ITEM(mplex->mx_phs, ph, next, prev);
68 assert(ph->next==NULL && ph->prev==NULL);
83 static void mplex_watch_handler(Watch *watch, Obj *mplex)
85 WMPlexPHolder *ph=FIELD_TO_STRUCT(WMPlexPHolder, mplex_watch, watch);
86 mplexpholder_do_unlink(ph, (WMPlex*)mplex);
87 pholder_redirect(&(ph->ph), (WRegion*)mplex);
91 static WMPlexAttachParams dummy_param={0, 0, {0, 0, 0, 0}, 0, 0};
94 bool mplexpholder_init(WMPlexPHolder *ph, WMPlex *mplex, WStacking *st,
95 WMPlexAttachParams *param)
97 pholder_init(&(ph->ph));
99 watch_init(&(ph->mplex_watch));
105 if(!watch_setup(&(ph->mplex_watch), (Obj*)mplex, mplex_watch_handler)){
106 pholder_deinit(&(ph->ph));
115 mplexpholder_do_link(ph, mplex,
116 LIST_LAST(st->lnode->phs, next, prev),
119 ph->param.flags|=MPLEX_ATTACH_UNNUMBERED;
121 ph->param.flags|=(MPLEX_ATTACH_SIZEPOLICY|
124 (st->hidden ? MPLEX_ATTACH_HIDDEN : 0));
125 ph->param.szplcy=st->szplcy;
126 ph->param.geom=REGION_GEOM(st->reg);
127 ph->param.level=st->level;
131 if(!(param->flags&MPLEX_ATTACH_UNNUMBERED)){
132 int index=(param->flags&MPLEX_ATTACH_INDEX
134 : mplex_default_index(mplex));
135 WLListNode *or_after=llist_index_to_after(mplex->mx_list,
138 WMPlexPHolder *after=(index==LLIST_INDEX_LAST
140 ? LIST_LAST(or_after->phs, next, prev)
141 : LIST_LAST(mplex->mx_phs, next, prev))
144 mplexpholder_do_link(ph, mplex, after, or_after);
152 WMPlexPHolder *create_mplexpholder(WMPlex *mplex,
154 WMPlexAttachParams *param)
156 CREATEOBJ_IMPL(WMPlexPHolder, mplexpholder, (p, mplex, st, param));
160 void mplexpholder_deinit(WMPlexPHolder *ph)
162 mplexpholder_do_unlink(ph, (WMPlex*)ph->mplex_watch.obj);
163 watch_reset(&(ph->mplex_watch));
164 pholder_deinit(&(ph->ph));
171 /*{{{ Move, attach, layer */
174 WRegion *mplexpholder_do_attach(WMPlexPHolder *ph, int flags,
175 WRegionAttachData *data)
177 WMPlex *mplex=(WMPlex*)ph->mplex_watch.obj;
183 if(flags&PHOLDER_ATTACH_SWITCHTO)
184 ph->param.flags|=MPLEX_ATTACH_SWITCHTO;
186 ph->param.flags&=~MPLEX_ATTACH_SWITCHTO;
188 return mplex_do_attach_pholder(mplex, ph, data);
192 bool mplexpholder_move(WMPlexPHolder *ph, WMPlex *mplex,
193 WMPlexPHolder *after,
194 WLListNode *or_after)
197 mplexpholder_do_unlink(ph, (WMPlex*)ph->mplex_watch.obj);
199 watch_reset(&(ph->mplex_watch));
204 if(!watch_setup(&(ph->mplex_watch), (Obj*)mplex, mplex_watch_handler))
207 mplexpholder_do_link(ph, mplex, after, or_after);
213 bool mplexpholder_do_goto(WMPlexPHolder *ph)
215 WMPlex *mplex=(WMPlex*)ph->mplex_watch.obj;
218 return region_goto((WRegion*)mplex);
224 WRegion *mplexpholder_do_target(WMPlexPHolder *ph)
226 return (WRegion*)ph->mplex_watch.obj;
233 /*{{{ WMPlex routines */
236 void mplex_move_phs(WMPlex *mplex, WLListNode *node,
237 WMPlexPHolder *after,
238 WLListNode *or_after)
242 assert(node!=or_after);
244 while(node->phs!=NULL){
247 mplexpholder_do_unlink(ph, mplex);
248 mplexpholder_do_link(ph, mplex, after, or_after);
254 void mplex_move_phs_before(WMPlex *mplex, WLListNode *node)
256 WMPlexPHolder *after=NULL;
257 WLListNode *or_after;
259 or_after=LIST_PREV(mplex->mx_list, node, next, prev);
261 after=(or_after!=NULL
262 ? LIST_LAST(or_after->phs, next, prev)
263 : LIST_LAST(mplex->mx_phs, next, prev));
265 mplex_move_phs(mplex, node, after, or_after);
269 WMPlexPHolder *mplex_managed_get_pholder(WMPlex *mplex, WRegion *mgd)
271 WStacking *st=mplex_find_stacking(mplex, mgd);
276 return create_mplexpholder(mplex, st, NULL);
280 WMPlexPHolder *mplex_get_rescue_pholder_for(WMPlex *mplex, WRegion *mgd)
282 WStacking *st=mplex_find_stacking(mplex, mgd);
284 return create_mplexpholder(mplex, st, NULL);
291 /*{{{ Class information */
294 static DynFunTab mplexpholder_dynfuntab[]={
295 {(DynFun*)pholder_do_attach,
296 (DynFun*)mplexpholder_do_attach},
298 {(DynFun*)pholder_do_goto,
299 (DynFun*)mplexpholder_do_goto},
301 {(DynFun*)pholder_do_target,
302 (DynFun*)mplexpholder_do_target},
308 IMPLCLASS(WMPlexPHolder, WPHolder, mplexpholder_deinit,
309 mplexpholder_dynfuntab);