]> icculus.org git repositories - dana/openbox.git/blob - openbox/dispatch.c
save the stacking order of the windows, and sort the saved session data based on...
[dana/openbox.git] / 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 }