]> git.decadent.org.uk Git - ion3.git/blob - ioncore/window.c
Imported Upstream version 20090110
[ion3.git] / ioncore / window.c
1 /*
2  * ion/ioncore/window.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2009. 
5  *
6  * See the included file LICENSE for details.
7  */
8
9 #include <libtu/objp.h>
10 #include <libtu/minmax.h>
11
12 #include "common.h"
13 #include "global.h"
14 #include "window.h"
15 #include "focus.h"
16 #include "rootwin.h"
17 #include "region.h"
18 #include "xwindow.h"
19 #include "region-iter.h"
20
21
22 /*{{{ Dynfuns */
23
24
25 void window_draw(WWindow *wwin, bool complete)
26 {
27     CALL_DYN(window_draw, wwin, (wwin, complete));
28 }
29
30
31 void window_insstr(WWindow *wwin, const char *buf, size_t n)
32 {
33     CALL_DYN(window_insstr, wwin, (wwin, buf, n));
34 }
35
36
37 int window_press(WWindow *wwin, XButtonEvent *ev, WRegion **reg_ret)
38 {
39     int area=0;
40     CALL_DYN_RET(area, int, window_press, wwin, (wwin, ev, reg_ret));
41     return area;
42 }
43
44
45 void window_release(WWindow *wwin)
46 {
47     CALL_DYN(window_release, wwin, (wwin));
48 }
49
50
51 /*}}}*/
52     
53
54 /*{{{ Init, create */
55
56
57 bool window_do_init(WWindow *wwin, WWindow *par, 
58                     const WFitParams *fp, Window win)
59 {
60     if(win==None){
61         assert(par!=NULL);
62         win=create_xwindow(region_rootwin_of((WRegion*)par),
63                            par->win, &(fp->g));
64         if(win==None)
65             return FALSE;
66     }
67
68     wwin->win=win;
69     wwin->xic=NULL;
70     wwin->event_mask=0;
71     wwin->stacking=NULL;
72     
73     region_init(&(wwin->region), par, fp);
74     
75     XSaveContext(ioncore_g.dpy, win, ioncore_g.win_context, 
76                  (XPointer)wwin);
77     
78     return TRUE;
79 }
80
81
82 bool window_init(WWindow *wwin, WWindow *par, const WFitParams *fp)
83 {
84     return window_do_init(wwin, par, fp, None);
85 }
86
87
88 void window_deinit(WWindow *wwin)
89 {
90     region_deinit((WRegion*)wwin);
91     
92     region_pointer_focus_hack(&wwin->region);
93     
94     if(wwin->xic!=NULL)
95         XDestroyIC(wwin->xic);
96         
97     if(wwin->win!=None){
98         XDeleteContext(ioncore_g.dpy, wwin->win, ioncore_g.win_context);
99         /* Probably should not try destroy if root window... */
100         XDestroyWindow(ioncore_g.dpy, wwin->win);
101     }
102     
103     /* There are no backlinks from WStacking to us, so it is not
104      * necessary to do any deinitialisation there.
105      */
106 }
107
108
109 /*}}}*/
110
111
112 /*{{{ Region dynfuns */
113
114
115 static void window_notify_subs_rootpos(WWindow *wwin, int x, int y)
116 {
117     WRegion *sub;
118     
119     FOR_ALL_CHILDREN(wwin, sub){
120         region_notify_rootpos(sub,
121                               x+REGION_GEOM(sub).x, 
122                               y+REGION_GEOM(sub).y);
123     }
124 }
125
126
127 void window_notify_subs_move(WWindow *wwin)
128 {
129     int x=0, y=0;
130     region_rootpos(&(wwin->region), &x, &y);
131     window_notify_subs_rootpos(wwin, x, y);
132 }
133
134
135 void window_do_fitrep(WWindow *wwin, WWindow *par, const WRectangle *geom)
136 {
137     bool move=(REGION_GEOM(wwin).x!=geom->x ||
138                REGION_GEOM(wwin).y!=geom->y);
139     int w=maxof(1, geom->w);
140     int h=maxof(1, geom->h);
141
142     if(par!=NULL){
143         region_unset_parent((WRegion*)wwin);
144         XReparentWindow(ioncore_g.dpy, wwin->win, par->win, geom->x, geom->y);
145         XResizeWindow(ioncore_g.dpy, wwin->win, w, h);
146         region_set_parent((WRegion*)wwin, par);
147     }else{
148         XMoveResizeWindow(ioncore_g.dpy, wwin->win, geom->x, geom->y, w, h);
149     }
150     
151     REGION_GEOM(wwin)=*geom;
152
153     if(move)
154         window_notify_subs_move(wwin);
155 }
156
157
158 bool window_fitrep(WWindow *wwin, WWindow *par, const WFitParams *fp)
159 {
160     if(par!=NULL && !region_same_rootwin((WRegion*)wwin, (WRegion*)par))
161         return FALSE;
162     window_do_fitrep(wwin, par, &(fp->g));
163     return TRUE;
164 }
165
166
167 void window_map(WWindow *wwin)
168 {
169     XMapWindow(ioncore_g.dpy, wwin->win);
170     REGION_MARK_MAPPED(wwin);
171 }
172
173
174 void window_unmap(WWindow *wwin)
175 {
176     region_pointer_focus_hack(&wwin->region);
177
178     XUnmapWindow(ioncore_g.dpy, wwin->win);
179     REGION_MARK_UNMAPPED(wwin);
180 }
181
182
183 void window_do_set_focus(WWindow *wwin, bool warp)
184 {
185     region_finalise_focusing((WRegion*)wwin, wwin->win, warp);
186 }
187
188
189 void window_restack(WWindow *wwin, Window other, int mode)
190 {
191     xwindow_restack(wwin->win, other, mode);
192 }
193
194
195 Window window_xwindow(const WWindow *wwin)
196 {
197     return wwin->win;
198 }
199
200
201 /*}}}*/
202
203
204 /*{{{ Misc. */
205
206
207 /*EXTL_DOC
208  * Return the X window id for \var{wwin}.
209  */
210 EXTL_SAFE
211 EXTL_EXPORT_MEMBER
212 double window_xid(WWindow *wwin)
213 {
214     return wwin->win;
215 }
216
217
218 void window_select_input(WWindow *wwin, long event_mask)
219 {
220     XSelectInput(ioncore_g.dpy, wwin->win, event_mask);
221     wwin->event_mask=event_mask;
222 }
223
224
225 /*}}}*/
226
227
228 /*{{{ Dynamic function table and class implementation */
229
230
231 static DynFunTab window_dynfuntab[]={
232     {region_map, window_map},
233     {region_unmap, window_unmap},
234     {region_do_set_focus, window_do_set_focus},
235     {(DynFun*)region_fitrep, (DynFun*)window_fitrep},
236     {(DynFun*)region_xwindow, (DynFun*)window_xwindow},
237     {region_notify_rootpos, window_notify_subs_rootpos},
238     {region_restack, window_restack},
239     END_DYNFUNTAB
240 };
241
242
243 EXTL_EXPORT
244 IMPLCLASS(WWindow, WRegion, window_deinit, window_dynfuntab);
245
246     
247 /*}}}*/
248