]> git.decadent.org.uk Git - ion3.git/blob - ioncore/region.c
[svn-inject] Installing original source of ion3
[ion3.git] / ioncore / region.c
1 /*
2  * ion/ioncore/region.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
14 #include <libtu/objp.h>
15 #include <libextl/extl.h>
16 #include <libmainloop/defer.h>
17
18 #include "common.h"
19 #include "global.h"
20 #include "region.h"
21 #include "focus.h"
22 #include "regbind.h"
23 #include "names.h"
24 #include "resize.h"
25 #include "manage.h"
26 #include "extlconv.h"
27 #include "activity.h"
28 #include "region-iter.h"
29
30
31 #define D2(X)
32
33
34 WHook *region_notify_hook=NULL;
35
36 static void region_notify_change_(WRegion *reg, const char *how, 
37                                   Obj *detail);
38
39
40 /*{{{ Init & deinit */
41
42
43 void region_init(WRegion *reg, WWindow *par, const WFitParams *fp)
44 {
45     if(fp->g.w<0 || fp->g.h<0)
46         warn(TR("Creating region with negative width or height!"));
47     
48     reg->geom=fp->g;
49     reg->flags=0;
50     reg->bindings=NULL;
51     reg->rootwin=NULL;
52     
53     reg->children=NULL;
54     reg->parent=NULL;
55     reg->p_next=NULL;
56     reg->p_prev=NULL;
57     
58     reg->active_sub=NULL;
59     reg->active_prev=NULL;
60     reg->active_next=NULL;
61     
62     reg->ni.name=NULL;
63     reg->ni.inst_off=0;
64     reg->ni.node=NULL;
65     
66     reg->manager=NULL;
67     
68     reg->submapstat=NULL;
69     
70     reg->mgd_activity=FALSE;
71
72     if(par!=NULL){
73         reg->rootwin=((WRegion*)par)->rootwin;
74         region_set_parent(reg, par);
75     }else{
76         assert(OBJ_IS(reg, WRootWin));/* || OBJ_IS(reg, WScreen));*/
77     }
78 }
79
80
81 static void destroy_children(WRegion *reg)
82 {
83     WRegion *sub, *prev=NULL;
84     bool complained=FALSE;
85     
86     /* destroy children */
87     while(1){
88         sub=reg->children;
89         if(sub==NULL)
90             break;
91         assert(!OBJ_IS_BEING_DESTROYED(sub));
92         assert(sub!=prev);
93         if(ioncore_g.opmode!=IONCORE_OPMODE_DEINIT && !complained && OBJ_IS(reg, WClientWin)){
94             warn(TR("Destroying object \"%s\" with client windows as "
95                     "children."), region_name(reg));
96             complained=TRUE;
97         }
98         prev=sub;
99         destroy_obj((Obj*)sub);
100     }
101 }
102
103
104 void region_deinit(WRegion *reg)
105 {
106     destroy_children(reg);
107
108     if(ioncore_g.focus_next==reg){
109         D(warn("Region to be focused next destroyed[1]."));
110         ioncore_g.focus_next=NULL;
111     }
112
113     region_detach_manager(reg);
114     region_unset_parent(reg);
115     region_remove_bindings(reg);
116     
117     region_unregister(reg);
118
119     region_focuslist_deinit(reg);
120
121     if(ioncore_g.focus_next==reg){
122         D(warn("Region to be focused next destroyed[2]."));
123         ioncore_g.focus_next=NULL;
124     }
125 }
126
127
128 /*}}}*/
129
130
131 /*{{{ Dynfuns */
132
133
134 bool region_fitrep(WRegion *reg, WWindow *par, const WFitParams *fp)
135 {
136     bool ret=FALSE;
137     CALL_DYN_RET(ret, bool, region_fitrep, reg, (reg, par, fp));
138     return ret;
139 }
140
141
142 void region_updategr(WRegion *reg)
143 {
144     CALL_DYN(region_updategr, reg, (reg));
145 }
146
147
148 void region_map(WRegion *reg)
149 {
150     CALL_DYN(region_map, reg, (reg));
151 }
152
153
154 void region_unmap(WRegion *reg)
155 {
156     CALL_DYN(region_unmap, reg, (reg));
157 }
158
159
160 void region_notify_rootpos(WRegion *reg, int x, int y)
161 {
162     CALL_DYN(region_notify_rootpos, reg, (reg, x, y));
163 }
164
165
166 Window region_xwindow(const WRegion *reg)
167 {
168     Window ret=None;
169     CALL_DYN_RET(ret, Window, region_xwindow, reg, (reg));
170     return ret;
171 }
172
173
174 void region_activated(WRegion *reg)
175 {
176     CALL_DYN(region_activated, reg, (reg));
177 }
178
179
180 void region_inactivated(WRegion *reg)
181 {
182     CALL_DYN(region_inactivated, reg, (reg));
183 }
184
185
186 void region_do_set_focus(WRegion *reg, bool warp)
187 {
188     CALL_DYN(region_do_set_focus, reg, (reg, warp));
189 }
190
191
192 /*{{{ Manager region dynfuns */
193
194
195 void region_managed_activated(WRegion *mgr, WRegion *reg)
196 {
197     CALL_DYN(region_managed_activated, mgr, (mgr, reg));
198 }
199
200
201 void region_managed_inactivated(WRegion *mgr, WRegion *reg)
202 {
203     CALL_DYN(region_managed_inactivated, mgr, (mgr, reg));
204 }
205
206
207 static bool region_managed_prepare_focus_default(WRegion *mgr, WRegion *reg, 
208                                                  int flags, 
209                                                  WPrepareFocusResult *res)
210 {
211     if(!region_prepare_focus(mgr, flags, res))
212         return FALSE;
213     
214     res->reg=reg;
215     res->flags=flags;
216     return TRUE;
217 }
218
219     
220 bool region_managed_prepare_focus(WRegion *mgr, WRegion *reg, 
221                                   int flags, 
222                                   WPrepareFocusResult *res)
223 {
224     bool ret=TRUE;
225     CALL_DYN_RET(ret, bool, region_managed_prepare_focus, mgr, 
226                  (mgr, reg, flags, res));
227     return ret;
228 }
229
230
231 void region_managed_notify(WRegion *mgr, WRegion *reg, const char *how)
232 {
233     CALL_DYN(region_managed_notify, mgr, (mgr, reg, how));
234 }
235
236
237 void region_managed_remove(WRegion *mgr, WRegion *reg)
238 {
239     CALL_DYN(region_managed_remove, mgr, (mgr, reg));
240 }
241
242
243 /*EXTL_DOC
244  * Return the object, if any, that is considered ''currently active''
245  * within the objects managed by \var{mplex}.
246  */
247 EXTL_SAFE
248 EXTL_EXPORT_MEMBER
249 WRegion *region_current(WRegion *mgr)
250 {
251     WRegion *ret=NULL;
252     CALL_DYN_RET(ret, WRegion*, region_current, mgr, (mgr));
253     return ret;
254 }
255
256
257 void region_child_removed(WRegion *reg, WRegion *sub)
258 {
259     CALL_DYN(region_child_removed, reg, (reg, sub));
260 }
261
262
263 /*}}}*/
264
265
266 /*{{{ Dynfun defaults */
267
268
269 void region_updategr_default(WRegion *reg)
270 {
271     WRegion *sub=NULL;
272     
273     FOR_ALL_CHILDREN(reg, sub){
274         region_updategr(sub);
275     }
276 }
277
278
279 /*}}}*/
280
281
282 /*}}}*/
283
284
285 /*{{{ Goto */
286
287
288 bool region_prepare_focus(WRegion *reg, int flags, 
289                           WPrepareFocusResult *res)
290 {
291     WRegion *mgr=REGION_MANAGER(reg);
292     WRegion *par=REGION_PARENT_REG(reg);
293
294     if(REGION_IS_MAPPED(reg) && region_may_control_focus(reg)){
295         res->reg=reg;
296         res->flags=0;
297         return TRUE;
298     }else{
299         if(mgr!=NULL){
300             return region_managed_prepare_focus(mgr, reg, flags, res);
301         }else if(par!=NULL){
302             if(!region_prepare_focus(par, flags, res))
303                 return FALSE;
304             /* Just focus reg, if it has no manager, and parent can be 
305              * focused. 
306              */
307         }
308         res->reg=reg;
309         res->flags=flags;
310         return TRUE;
311     }
312 }
313
314
315 bool region_goto_flags(WRegion *reg, int flags)
316 {
317     WPrepareFocusResult res;
318     bool ret;
319     
320     ret=region_prepare_focus(reg, flags, &res);
321     
322     if(res.reg!=NULL){
323         if(res.flags&REGION_GOTO_FOCUS)
324             region_maybewarp(res.reg, !(res.flags&REGION_GOTO_NOWARP));
325     }
326     
327     return ret;
328 }
329
330
331 /*EXTL_DOC
332  * Attempt to display \var{reg}, save region activity status and then
333  * warp to (or simply set focus to if warping is disabled) \var{reg}.
334  * 
335  * Note that this function is asynchronous; the region will not
336  * actually have received the focus when this function returns.
337  */
338 EXTL_EXPORT_MEMBER
339 bool region_goto(WRegion *reg)
340 {
341     return region_goto_flags(reg, REGION_GOTO_FOCUS);
342 }
343
344
345 /*}}}*/
346
347
348 /*{{{ Fit/reparent */
349
350
351 void region_fit(WRegion *reg, const WRectangle *geom, WRegionFitMode mode)
352 {
353     WFitParams fp;
354     fp.g=*geom;
355     fp.mode=mode&~REGION_FIT_GRAVITY;
356     fp.gravity=ForgetGravity;
357     region_fitrep(reg, NULL, &fp);
358 }
359
360
361 bool region_reparent(WRegion *reg, WWindow *par,
362                      const WRectangle *geom, WRegionFitMode mode)
363 {
364     WFitParams fp;
365     fp.g=*geom;
366     fp.mode=mode;
367     return region_fitrep(reg, par, &fp);
368 }
369
370
371 /*}}}*/
372
373
374 /*{{{ Close */
375
376
377 static bool region_rqclose_default(WRegion *reg, bool relocate)
378 {
379     WPHolder *ph;
380     bool refuse=TRUE;
381     
382     if((!relocate && !region_may_destroy(reg)) ||
383        !region_manager_allows_destroying(reg)){
384         return FALSE;
385     }
386     
387     ph=region_get_rescue_pholder(reg);
388     
389     if(ph!=NULL){
390         refuse=!region_rescue_clientwins(reg, ph);
391         destroy_obj((Obj*)ph);
392     }
393
394     if(refuse){
395         warn(TR("Failed to rescue some client windows - not closing."));
396         return FALSE;
397     }
398
399     mainloop_defer_destroy((Obj*)reg);
400     
401     return TRUE;
402 }
403
404
405 /*EXTL_DOC
406  * Attempt to close/destroy \var{reg}. Whether this operation works
407  * depends on whether the particular type of region in question has
408  * implemented the feature and, in case of client windows, whether
409  * the client supports the \code{WM_DELETE} protocol (see also
410  * \fnref{WClientWin.kill}). If the operation is likely to succeed,
411  * \code{true} is returned, otherwise \code{false}. In most cases the
412  * region will not have been actually destroyed when this function returns.
413  * If \var{relocate} is not set, and \var{reg} manages other regions, it
414  * will not be closed. Otherwise the managed regions will be attempted
415  * to be relocated.
416  */
417 EXTL_EXPORT_MEMBER
418 bool region_rqclose(WRegion *reg, bool relocate)
419 {
420     bool ret=FALSE;
421     CALL_DYN_RET(ret, bool, region_rqclose, reg, (reg, relocate));
422     return ret;
423 }
424
425
426 static WRegion *region_rqclose_propagate_default(WRegion *reg, 
427                                                  WRegion *maybe_sub)
428 {
429     if(maybe_sub==NULL)
430         maybe_sub=region_current(reg);
431     if(maybe_sub!=NULL)
432         return region_rqclose_propagate(maybe_sub, NULL);
433     return (region_rqclose(reg, FALSE) ? reg : NULL);
434 }
435
436
437 /*EXTL_DOC
438  * Recursively attempt to close a region or one of the regions managed by 
439  * it. If \var{sub} is set, it will be used as the managed region, otherwise
440  * \fnref{WRegion.current}\code{(reg)}. The object to be closed is
441  * returned or NULL if nothing can be closed. Also see notes for
442  * \fnref{WRegion.rqclose}.
443  */
444 EXTL_EXPORT_MEMBER
445 WRegion *region_rqclose_propagate(WRegion *reg, WRegion *maybe_sub)
446 {
447     WRegion *ret=NULL;
448     CALL_DYN_RET(ret, WRegion*, region_rqclose_propagate, reg,
449                  (reg, maybe_sub));
450     return ret;
451 }
452
453
454 bool region_may_destroy(WRegion *reg)
455 {
456     bool ret=TRUE;
457     CALL_DYN_RET(ret, bool, region_may_destroy, reg, (reg));
458     return ret;
459 }
460
461
462 bool region_managed_may_destroy(WRegion *mgr, WRegion *reg)
463 {
464     bool ret=TRUE;
465     CALL_DYN_RET(ret, bool, region_managed_may_destroy, mgr, (mgr, reg));
466     return ret;
467 }
468
469
470 bool region_manager_allows_destroying(WRegion *reg)
471 {
472     WRegion *mgr=REGION_MANAGER(reg);
473     
474     if(mgr==NULL)
475         return TRUE;
476     
477     return region_managed_may_destroy(mgr, reg);
478 }
479
480
481 /*}}}*/
482
483
484 /*{{{ Manager/parent stuff */
485
486
487 /* Routine to call to unmanage a region */
488 void region_detach_manager(WRegion *reg)
489 {
490     WRegion *mgr;
491     
492     mgr=REGION_MANAGER(reg);
493     
494     if(mgr==NULL)
495         return;
496     
497     /* Restore activity state to non-parent manager */
498     if(region_may_control_focus(reg)){
499         WRegion *par=REGION_PARENT_REG(reg);
500         if(par!=NULL && mgr!=par && REGION_PARENT_REG(mgr)==par){
501             /* REGION_ACTIVE shouldn't be set for windowless regions
502              * but make the parent's active_sub point to it
503              * nevertheless so that region_may_control_focus can
504              * be made to work.
505              */
506             par->active_sub=mgr;
507             /*if(region_xwindow(mgr)!=None){*/
508                 region_do_set_focus(mgr, FALSE);
509             /*}*/
510         }
511     }
512
513     region_set_activity(reg, SETPARAM_UNSET);
514
515     region_managed_remove(mgr, reg);
516
517     assert(REGION_MANAGER(reg)==NULL);
518 }
519
520
521 /* This should only be called within region_managed_remove,
522  * _after_ any managed lists and other essential structures
523  * of mgr have been broken.
524  */
525 void region_unset_manager(WRegion *reg, WRegion *mgr)
526 {
527     if(reg->manager!=mgr)
528         return;
529     
530     reg->manager=NULL;
531     
532     if(region_is_activity_r(reg))
533         region_clear_mgd_activity(mgr);
534
535     region_notify_change_(reg, "unset_manager", (Obj*)mgr);
536 }
537
538
539 /* This should be called within region attach routines,
540  * _after_ any managed lists and other essential structures
541  * of mgr have been set up.
542  */
543 void region_set_manager(WRegion *reg, WRegion *mgr)
544 {
545     assert(reg->manager==NULL);
546     
547     reg->manager=mgr;
548     
549     if(region_is_activity_r(reg))
550         region_mark_mgd_activity(mgr);
551     
552     region_notify_change_(reg, "set_manager", (Obj*)mgr);
553 }
554
555
556 void region_set_parent(WRegion *reg, WWindow *parent)
557 {
558     assert(reg->parent==NULL && parent!=NULL);
559     LINK_ITEM(((WRegion*)parent)->children, reg, p_next, p_prev);
560     reg->parent=parent;
561 }
562
563
564 void region_unset_parent(WRegion *reg)
565 {
566     WRegion *p=REGION_PARENT_REG(reg);
567
568     if(p==NULL || p==reg)
569         return;
570
571     UNLINK_ITEM(p->children, reg, p_next, p_prev);
572     reg->parent=NULL;
573
574     if(p->active_sub==reg){
575         p->active_sub=NULL;
576         region_update_owned_grabs(p);
577     }
578     
579     region_child_removed(p, reg);
580 }
581
582
583 /*EXTL_DOC
584  * Returns the region that manages \var{reg}.
585  */
586 EXTL_SAFE
587 EXTL_EXPORT_MEMBER
588 WRegion *region_manager(WRegion *reg)
589 {
590     return reg->manager;
591 }
592
593
594 /*EXTL_DOC
595  * Returns the parent region of \var{reg}.
596  */
597 EXTL_SAFE
598 EXTL_EXPORT_MEMBER
599 WWindow *region_parent(WRegion *reg)
600 {
601     return reg->parent;
602 }
603
604
605 WRegion *region_manager_or_parent(WRegion *reg)
606 {
607     if(reg->manager!=NULL)
608         return reg->manager;
609     else
610         return (WRegion*)(reg->parent);
611 }
612
613
614 WRegion *region_get_manager_chk(WRegion *p, const ClassDescr *descr)
615 {
616     WRegion *mgr=NULL;
617     
618     if(p!=NULL){
619         mgr=REGION_MANAGER(p);
620         if(obj_is((Obj*)mgr, descr))
621             return mgr;
622     }
623     
624     return NULL;
625 }
626
627 /*}}}*/
628
629
630 /*{{{ Stacking and ordering */
631
632
633 static void region_stacking_default(WRegion *reg, 
634                                     Window *bottomret, Window *topret)
635 {
636     Window win=region_xwindow(reg);
637     *bottomret=win;
638     *topret=win;
639 }
640
641
642 void region_stacking(WRegion *reg, Window *bottomret, Window *topret)
643 {
644     CALL_DYN(region_stacking, reg, (reg, bottomret, topret));
645 }
646
647
648 void region_restack(WRegion *reg, Window other, int mode)
649 {
650     CALL_DYN(region_restack, reg, (reg, other, mode));
651 }
652
653
654
655 bool region_managed_rqorder(WRegion *reg, WRegion *sub, WRegionOrder order)
656 {
657     bool ret=FALSE;
658     CALL_DYN_RET(ret, bool, region_managed_rqorder, reg, (reg, sub, order));
659     return ret;
660 }
661
662
663 bool region_rqorder(WRegion *reg, WRegionOrder order)
664 {
665     WRegion *mgr=REGION_MANAGER(reg);
666     
667     if(mgr==NULL)
668         return FALSE;
669     else
670         return region_managed_rqorder(mgr, reg, order);
671 }
672
673
674 /*EXTL_DOC
675  * Request ordering. Currently supported values for \var{ord}
676  * are 'front' and 'back'.
677  */
678 EXTL_EXPORT_AS(WRegion, rqorder)
679 bool region_rqorder_extl(WRegion *reg, const char *ord)
680 {
681     WRegionOrder order;
682     
683     if(strcmp(ord, "front")==0){
684         order=REGION_ORDER_FRONT;
685     }else if(strcmp(ord, "back")==0){
686         order=REGION_ORDER_BACK;
687     }else{
688         return FALSE;
689     }
690     
691     return region_rqorder(reg, order);
692 }
693
694
695 /*}}}*/
696
697
698 /*{{{ Misc. */
699
700
701 /*EXTL_DOC
702  * Returns the root window \var{reg} is on.
703  */
704 EXTL_SAFE
705 EXTL_EXPORT_MEMBER
706 WRootWin *region_rootwin_of(const WRegion *reg)
707 {
708     WRootWin *rw;
709     assert(reg!=NULL); /* Lua interface should not pass NULL reg. */
710     rw=(WRootWin*)(reg->rootwin);
711     assert(rw!=NULL);
712     return rw;
713 }
714
715
716 /*EXTL_DOC
717  * Returns the screen \var{reg} is on.
718  */
719 EXTL_SAFE
720 EXTL_EXPORT_MEMBER
721 WScreen *region_screen_of(WRegion *reg)
722 {
723     while(reg!=NULL){
724         if(OBJ_IS(reg, WScreen))
725             return (WScreen*)reg;
726         reg=REGION_PARENT_REG(reg);
727     }
728     return NULL;
729 }
730
731
732 Window region_root_of(const WRegion *reg)
733 {
734     return WROOTWIN_ROOT(region_rootwin_of(reg));
735 }
736
737
738 bool region_same_rootwin(const WRegion *reg1, const WRegion *reg2)
739 {
740     return (reg1->rootwin==reg2->rootwin);
741 }
742
743
744 /*EXTL_DOC
745  * Is \var{reg} visible/is it and all it's ancestors mapped?
746  */
747 EXTL_SAFE
748 EXTL_EXPORT_AS(WRegion, is_mapped)
749 bool region_is_fully_mapped(WRegion *reg)
750 {
751     for(; reg!=NULL; reg=REGION_PARENT_REG(reg)){
752         if(!REGION_IS_MAPPED(reg))
753             return FALSE;
754     }
755     
756     return TRUE;
757 }
758
759
760 void region_rootpos(WRegion *reg, int *xret, int *yret)
761 {
762     WRegion *par;
763
764     par=REGION_PARENT_REG(reg);
765     
766     if(par==NULL || par==reg){
767         *xret=0;
768         *yret=0;
769         return;
770     }
771     
772     region_rootpos(par, xret, yret);
773     
774     *xret+=REGION_GEOM(reg).x;
775     *yret+=REGION_GEOM(reg).y;
776 }
777
778
779 static bool mrsh_not(WHookDummy *fn, void *p)
780 {
781     WRegion *reg=(WRegion*)((void**)p)[0];
782     const char *how=(const char*)((void**)p)[1];
783     Obj *detail=(Obj*)((void**)p)[2];
784     
785     fn(reg, how, detail);
786     
787     return TRUE;
788 }
789
790
791 static bool mrshe_not(ExtlFn fn, void *p)
792 {
793     WRegion *reg=(WRegion*)((void**)p)[0];
794     const char *how=(const char*)((void**)p)[1];
795     Obj *detail=(Obj*)((void**)p)[2];
796     
797     extl_call(fn, "oso", NULL, reg, how, detail);
798     
799     return TRUE;
800 }
801
802
803 static void region_notify_change_(WRegion *reg, const char *how, 
804                                   Obj *detail)
805 {
806     const void *p[3];
807     
808     p[0]=reg;
809     p[1]=how;
810     p[2]=detail;
811
812     extl_protect(NULL);
813     hook_call(region_notify_hook, p, mrsh_not, mrshe_not),
814     extl_unprotect(NULL);
815     
816 }
817
818
819 void region_notify_change(WRegion *reg, const char *how)
820 {
821     WRegion *mgr=REGION_MANAGER(reg);
822
823     if(mgr!=NULL)
824         region_managed_notify(mgr, reg, how);
825     
826     region_notify_change_(reg, how, NULL);
827 }
828
829
830 /*EXTL_DOC
831  * Returns the geometry of \var{reg} within its parent; a table with fields
832  * \var{x}, \var{y}, \var{w} and \var{h}.
833  */
834 EXTL_SAFE
835 EXTL_EXPORT_MEMBER
836 ExtlTab region_geom(WRegion *reg)
837 {
838     return extl_table_from_rectangle(&REGION_GEOM(reg));
839 }
840
841
842 bool region_handle_drop(WRegion *reg, int x, int y, WRegion *dropped)
843 {
844     bool ret=FALSE;
845     CALL_DYN_RET(ret, bool, region_handle_drop, reg, (reg, x, y, dropped));
846     return ret;
847 }
848
849
850 WRegion *region_managed_within(WRegion *reg, WRegion *mgd)
851 {
852     while(mgd!=NULL && 
853           (REGION_PARENT_REG(mgd)==reg ||
854            REGION_PARENT_REG(mgd)==REGION_PARENT_REG(reg))){
855         
856         if(REGION_MANAGER(mgd)==reg)
857             return mgd;
858         mgd=REGION_MANAGER(mgd);
859     }
860     
861     return NULL;
862 }
863
864
865 /*}}}*/
866
867
868 /*{{{ Dynamic function table and class implementation */
869
870
871 static DynFunTab region_dynfuntab[]={
872     {region_managed_rqgeom,
873      region_managed_rqgeom_allow},
874      
875     {region_managed_rqgeom_absolute,
876      region_managed_rqgeom_absolute_default},
877     
878     {region_updategr, 
879      region_updategr_default},
880     
881     {(DynFun*)region_rescue_clientwins,
882      (DynFun*)region_rescue_child_clientwins},
883
884     {(DynFun*)region_prepare_manage,
885      (DynFun*)region_prepare_manage_default},
886
887     {(DynFun*)region_prepare_manage_transient,
888      (DynFun*)region_prepare_manage_transient_default},
889
890     {(DynFun*)region_managed_prepare_focus,
891      (DynFun*)region_managed_prepare_focus_default},
892
893     {(DynFun*)region_rqclose_propagate,
894      (DynFun*)region_rqclose_propagate_default},
895
896     {(DynFun*)region_rqclose,
897      (DynFun*)region_rqclose_default},
898     
899     {(DynFun*)region_displayname,
900      (DynFun*)region_name},
901     
902     {region_stacking, 
903      region_stacking_default},
904     
905     END_DYNFUNTAB
906 };
907
908
909 EXTL_EXPORT
910 IMPLCLASS(WRegion, Obj, region_deinit, region_dynfuntab);
911
912     
913 /*}}}*/
914