add a keyboard plugin
[mikachu/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 static GSList **funcs;
12
13 void dispatch_startup()
14 {
15     guint i;
16     EventType j;
17
18     i = 0;
19     j = EVENT_RANGE;
20     while (j > 1) {
21         j >>= 1;
22         ++i;
23     }
24     funcs = g_new(GSList*, i);
25
26     for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1)
27         funcs[i] = NULL;
28 }
29
30 void dispatch_shutdown()
31 {
32     guint i;
33     EventType j;
34     GSList *it;
35
36     for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1) {
37         for (it = funcs[i]; it != NULL; it = it->next)
38             g_free(it->data);
39         g_slist_free(funcs[i]);
40         funcs[i] = NULL;
41     }
42
43     g_free(funcs);
44 }
45
46 void dispatch_register(EventMask mask, EventHandler h, void *data)
47 {
48     guint i;
49     EventType j;
50     GSList *it, *next;
51     EventMask m;
52     Func *f;
53
54     /* add to masks it needs to be registered for */
55     m = mask;
56     while (m) {
57         for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1)
58             if (m & j) {
59                 for (it = funcs[i]; it != NULL; it = it->next) {
60                     f = it->data;
61                     if (f->h == h && f->data == data)
62                         break;
63                 }
64                 if (it == NULL) { /* wasn't already regged */
65                     f = g_new(Func, 1);
66                     f->h = h;
67                     f->data = data;
68                     funcs[i] = g_slist_append(funcs[i], f);
69                 }
70                 m ^= j; /* remove from the mask */
71             }
72         g_assert(j >= EVENT_RANGE); /* an invalid event is in the mask */
73     }
74
75     /* remove from masks its not registered for anymore */
76     for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1) {
77         if (!(j & mask))
78             for (it = funcs[i]; it != NULL; it = next) {
79                 next = it->next;
80                 f = it->data;
81                 if (f->h == h && f->data == data) {
82                     g_free(f);
83                     funcs[i] = g_slist_delete_link(funcs[i], it);
84                 }
85             }
86     }
87 }
88
89 void dispatch_x(XEvent *xe, Client *c)
90 {
91     EventType e;
92     guint i;
93     GSList *it;
94     ObEvent obe;
95
96     switch (xe->type) {
97     case EnterNotify:
98         e = Event_X_EnterNotify;
99         break;
100     case LeaveNotify:
101         e = Event_X_LeaveNotify;
102         break;
103     case KeyPress:
104         e = Event_X_KeyPress;
105         break;
106     case KeyRelease:
107         e = Event_X_KeyRelease;
108         break;
109     case ButtonPress:
110         e = Event_X_ButtonPress;
111         break;
112     case ButtonRelease:
113         e = Event_X_ButtonRelease;
114         break;
115     case MotionNotify:
116         e = Event_X_MotionNotify;
117         break;
118     default:
119         /* XKB events */
120         if (xe->type == extensions_xkb_event_basep) {
121             switch (((XkbAnyEvent*)&e)->xkb_type) {
122             case XkbBellNotify:
123                 e = Event_X_Bell;
124                 break;
125             }
126         }
127         return;
128     }
129
130     obe.type = e;
131     obe.data.x.e = xe;
132     obe.data.x.client = c;
133
134     i = 0;
135     while (e > 1) {
136         e >>= 1;
137         ++i;
138     }
139
140     for (it = funcs[i]; it != NULL; it = it->next) {
141         Func *f = it->data;
142         f->h(&obe, f->data);
143     }
144 }
145
146 void dispatch_client(EventType e, Client *c, int num0, int num1)
147 {
148     guint i;
149     GSList *it;
150     ObEvent obe;
151
152     g_assert(c != NULL);
153
154     obe.type = e;
155     obe.data.c.client = c;
156     obe.data.c.num[0] = num0;
157     obe.data.c.num[1] = num1;
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 }