]> git.decadent.org.uk Git - ion3.git/blob - mod_mgmtmode/mgmtmode.c
[svn-upgrade] Integrating new upstream version, ion3 (20070318)
[ion3.git] / mod_mgmtmode / mgmtmode.c
1 /*
2  * ion/mod_mgmtmode/mgmtmode.c
3  *
4  * Copyright (c) Tuomo Valkonen 2004-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 <math.h>
13 #include <sys/time.h>
14 #include <time.h>
15 #include <limits.h>
16
17 #include <libtu/objp.h>
18 #include <ioncore/common.h>
19 #include <ioncore/global.h>
20 #include <ioncore/region.h>
21 #include <ioncore/rootwin.h>
22 #include <ioncore/binding.h>
23 #include <ioncore/grab.h>
24 #include "mgmtmode.h"
25 #include "main.h"
26
27
28 static WMgmtMode *mgmt_mode=NULL;
29
30
31 static void cancel_mgmt(WRegion *reg);
32
33
34 /*{{{ WMgmtMode */
35
36
37 static bool mgmtmode_init(WMgmtMode *mode, WRegion *reg)
38 {
39     watch_init(&(mode->selw));
40     watch_setup(&(mode->selw), (Obj*)reg, NULL);
41     return TRUE;
42 }
43
44
45 static WMgmtMode *create_mgmtmode(WRegion *reg)
46 {
47     CREATEOBJ_IMPL(WMgmtMode, mgmtmode, (p, reg));
48 }
49
50
51 static void mgmtmode_deinit(WMgmtMode *mode)
52 {
53     if(mgmt_mode==mode)
54        mgmt_mode=NULL;
55     
56     watch_reset(&(mode->selw));
57 }
58
59
60 /*EXTL_DOC
61  * Select management mode target.
62  */
63 EXTL_EXPORT_MEMBER
64 void mgmtmode_select(WMgmtMode *mode, WRegion *reg)
65 {
66     watch_setup(&(mode->selw), (Obj*)reg, NULL);
67 }
68
69
70 /*EXTL_DOC
71  * Return management mode target.
72  */
73 EXTL_SAFE
74 EXTL_EXPORT_MEMBER
75 WRegion *mgmtmode_selected(WMgmtMode *mode)
76 {
77     return (WRegion*)(mode->selw.obj);
78 }
79
80
81 /*EXTL_DOC
82  * End management mode.
83  */
84 EXTL_EXPORT_MEMBER
85 void mgmtmode_finish(WMgmtMode *mode)
86 {
87     if(mgmt_mode==mode)
88         cancel_mgmt(NULL);
89 }
90     
91
92 EXTL_EXPORT
93 IMPLCLASS(WMgmtMode, Obj, mgmtmode_deinit, NULL);
94
95
96 /*}}}*/
97
98
99 /*{{{ Rubberband */
100
101
102 static void draw_rubberbox(WRootWin *rw, const WRectangle *rect)
103 {
104     XPoint fpts[5];
105     
106     fpts[0].x=rect->x;
107     fpts[0].y=rect->y;
108     fpts[1].x=rect->x+rect->w;
109     fpts[1].y=rect->y;
110     fpts[2].x=rect->x+rect->w;
111     fpts[2].y=rect->y+rect->h;
112     fpts[3].x=rect->x;
113     fpts[3].y=rect->y+rect->h;
114     fpts[4].x=rect->x;
115     fpts[4].y=rect->y;
116     
117     XDrawLines(ioncore_g.dpy, WROOTWIN_ROOT(rw), rw->xor_gc, fpts, 5, 
118                CoordModeOrigin);
119 }
120
121
122 static void mgmtmode_draw(WMgmtMode *mode)
123 {
124     WRegion *reg=mgmtmode_selected(mode);
125     
126     if(reg!=NULL){
127         WRootWin *rw=region_rootwin_of(reg);
128         WRectangle g=REGION_GEOM(reg);
129         int rx=0, ry=0;
130         
131         region_rootpos(reg, &rx, &ry);
132         
133         g.x=rx;
134         g.y=ry;
135         
136         draw_rubberbox(rw, &g);
137     }
138 }
139
140
141 static void mgmtmode_erase(WMgmtMode *mode)
142 {
143     mgmtmode_draw(mode);
144 }
145
146
147 /*}}}*/
148
149
150 /*{{{ The mode */
151
152
153 static bool mgmt_handler(WRegion *reg, XEvent *xev)
154 {
155     XKeyEvent *ev=&xev->xkey;
156     WBinding *binding=NULL;
157     WMgmtMode *mode;
158     
159     if(ev->type==KeyRelease)
160         return FALSE;
161     
162     if(reg==NULL)
163         return FALSE;
164     
165     mode=mgmt_mode;
166     
167     if(mode==NULL)
168         return FALSE;
169     
170     binding=bindmap_lookup_binding(mod_mgmtmode_bindmap, 
171                                    BINDING_KEYPRESS,
172                                    ev->state, ev->keycode);
173     
174     if(!binding)
175         return FALSE;
176     
177     if(binding!=NULL){
178         mgmtmode_erase(mode);
179         extl_call(binding->func, "o", NULL, mode);
180         if(mgmt_mode!=NULL)
181             mgmtmode_draw(mgmt_mode);
182     }
183     
184     return (mgmt_mode==NULL);
185 }
186
187
188 static void cancel_mgmt(WRegion *reg)
189 {
190     if(mgmt_mode!=NULL){
191         mgmtmode_erase(mgmt_mode);
192         destroy_obj((Obj*)mgmt_mode);
193     }
194     ioncore_grab_remove(mgmt_handler);
195 }
196
197
198 /*EXTL_DOC
199  * Begin management mode.
200  */
201 EXTL_EXPORT
202 WMgmtMode *mod_mgmtmode_begin(WRegion *reg)
203 {
204     if(mgmt_mode!=NULL)
205         return NULL;
206     
207     mgmt_mode=create_mgmtmode(reg);
208
209     if(mgmt_mode==NULL)
210         return NULL;
211     
212     ioncore_grab_establish((WRegion*)region_rootwin_of(reg), 
213                            mgmt_handler,
214                            (GrabKilledHandler*)cancel_mgmt, 0);
215     
216     mgmtmode_draw(mgmt_mode);
217     
218     return mgmt_mode;
219 }
220
221
222 /*}}}*/