rename the Client struct to ObClient
[dana/openbox.git] / 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, ObClient *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, ObClient *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(ObClient *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(ObClient *c, int *w, int *h, ObCorner 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 }