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