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