]> Dogcows Code - chaz/openbox/blob - openbox/dispatch.c
more menu fixes.
[chaz/openbox] / openbox / dispatch.c
1 #include "dispatch.h"
2 #include "extensions.h"
3 #include "client.h"
4
5 #include <glib.h>
6
7 typedef struct {
8 EventHandler h;
9 void *data;
10 } Func;
11
12 /* an array of GSList*s of Func*s */
13 static GSList **funcs;
14
15 void dispatch_startup()
16 {
17 guint i;
18 EventType j;
19
20 i = 0;
21 j = EVENT_RANGE;
22 while (j > 1) {
23 j >>= 1;
24 ++i;
25 }
26 funcs = g_new0(GSList*, i);
27 }
28
29 void dispatch_shutdown()
30 {
31 guint i;
32 EventType j;
33 GSList *it;
34
35 for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1) {
36 for (it = funcs[i]; it != NULL; it = it->next)
37 g_free(it->data);
38 g_slist_free(funcs[i]);
39 funcs[i] = NULL;
40 }
41
42 g_free(funcs);
43 }
44
45 void dispatch_register(EventMask mask, EventHandler h, void *data)
46 {
47 guint i;
48 EventType j;
49 GSList *it, *next;
50 EventMask m;
51 Func *f;
52
53 /* add to masks it needs to be registered for */
54 m = mask;
55 while (m) {
56 for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1)
57 if (m & j) {
58 for (it = funcs[i]; it != NULL; it = it->next) {
59 f = it->data;
60 if (f->h == h && f->data == data)
61 break;
62 }
63 if (it == NULL) { /* wasn't already regged */
64 f = g_new(Func, 1);
65 f->h = h;
66 f->data = data;
67 funcs[i] = g_slist_append(funcs[i], f);
68 }
69 m ^= j; /* remove from the mask */
70 }
71 g_assert(j >= EVENT_RANGE); /* an invalid event is in the mask */
72 }
73
74 /* remove from masks its not registered for anymore */
75 for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1) {
76 if (!(j & mask))
77 for (it = funcs[i]; it != NULL; it = next) {
78 next = it->next;
79 f = it->data;
80 if (f->h == h && f->data == data) {
81 g_free(f);
82 funcs[i] = g_slist_delete_link(funcs[i], it);
83 }
84 }
85 }
86 }
87
88 void dispatch_x(XEvent *xe, ObClient *c)
89 {
90 EventType e;
91 guint i;
92 GSList *it;
93 ObEvent obe;
94
95 switch (xe->type) {
96 case EnterNotify:
97 e = Event_X_EnterNotify;
98 break;
99 case LeaveNotify:
100 e = Event_X_LeaveNotify;
101 break;
102 case KeyPress:
103 e = Event_X_KeyPress;
104 break;
105 case KeyRelease:
106 e = Event_X_KeyRelease;
107 break;
108 case ButtonPress:
109 e = Event_X_ButtonPress;
110 break;
111 case ButtonRelease:
112 e = Event_X_ButtonRelease;
113 break;
114 case MotionNotify:
115 e = Event_X_MotionNotify;
116 break;
117 default:
118 /* XKB events */
119 if (xe->type == extensions_xkb_event_basep) {
120 switch (((XkbAnyEvent*)&e)->xkb_type) {
121 case XkbBellNotify:
122 e = Event_X_Bell;
123 break;
124 }
125 }
126 return;
127 }
128
129 obe.type = e;
130 obe.data.x.e = xe;
131 obe.data.x.client = c;
132
133 i = 0;
134 while (e > 1) {
135 e >>= 1;
136 ++i;
137 }
138
139 for (it = funcs[i]; it != NULL; it = it->next) {
140 Func *f = it->data;
141 f->h(&obe, f->data);
142 }
143 }
144
145 void dispatch_client(EventType e, ObClient *c, int num0, int num1)
146 {
147 guint i;
148 GSList *it;
149 ObEvent obe;
150
151 g_assert(c != NULL);
152
153 obe.type = e;
154 obe.data.c.client = c;
155 obe.data.c.num[0] = num0;
156 obe.data.c.num[1] = num1;
157 obe.data.c.num[2] = 0;
158
159 i = 0;
160 while (e > 1) {
161 e >>= 1;
162 ++i;
163 }
164
165 for (it = funcs[i]; it != NULL; it = it->next) {
166 Func *f = it->data;
167 f->h(&obe, f->data);
168 }
169 }
170
171 void dispatch_ob(EventType e, int num0, int num1)
172 {
173 guint i;
174 GSList *it;
175 ObEvent obe;
176
177 obe.type = e;
178 obe.data.o.num[0] = num0;
179 obe.data.o.num[1] = num1;
180
181 i = 0;
182 while (e > 1) {
183 e >>= 1;
184 ++i;
185 }
186
187 for (it = funcs[i]; it != NULL; it = it->next) {
188 Func *f = it->data;
189 f->h(&obe, f->data);
190 }
191 }
192
193 void dispatch_signal(int signal)
194 {
195 guint i;
196 EventType e = Event_Signal;
197 GSList *it;
198 ObEvent obe;
199
200 obe.type = e;
201 obe.data.s.signal = signal;
202
203 i = 0;
204 while (e > 1) {
205 e >>= 1;
206 ++i;
207 }
208
209 for (it = funcs[i]; it != NULL; it = it->next) {
210 Func *f = it->data;
211 f->h(&obe, f->data);
212 }
213 }
214
215 void dispatch_move(ObClient *c, int *x, int *y)
216 {
217 guint i;
218 GSList *it;
219 EventType e = Event_Client_Moving;
220 ObEvent obe;
221
222 obe.type = e;
223 obe.data.c.client = c;
224 obe.data.c.num[0] = *x;
225 obe.data.c.num[1] = *y;
226
227 i = 0;
228 while (e > 1) {
229 e >>= 1;
230 ++i;
231 }
232
233 for (it = funcs[i]; it != NULL; it = it->next) {
234 Func *f = it->data;
235 f->h(&obe, f->data);
236 }
237
238 *x = obe.data.c.num[0];
239 *y = obe.data.c.num[1];
240 }
241
242 void dispatch_resize(ObClient *c, int *w, int *h, ObCorner corner)
243 {
244 guint i;
245 GSList *it;
246 EventType e = Event_Client_Resizing;
247 ObEvent obe;
248
249 obe.type = e;
250 obe.data.c.client = c;
251 obe.data.c.num[0] = *w;
252 obe.data.c.num[1] = *h;
253 obe.data.c.num[2] = corner;
254
255 i = 0;
256 while (e > 1) {
257 e >>= 1;
258 ++i;
259 }
260
261 for (it = funcs[i]; it != NULL; it = it->next) {
262 Func *f = it->data;
263 f->h(&obe, f->data);
264 }
265
266 *w = obe.data.c.num[0];
267 *h = obe.data.c.num[1];
268 }
This page took 0.0463 seconds and 4 git commands to generate.