1/*
2 * Copyright © 2008-2009 Julien Danjou <julien@danjou.info>
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Except as contained in this notice, the names of the authors or
24 * their institutions shall not be used in advertising or otherwise to
25 * promote the sale, use or other dealings in this Software without
26 * prior written authorization from the authors.
27 */
28
29#include <assert.h>
30#include <stdlib.h>
31#include <string.h>
32
33#include "xcb_event.h"
34#include "../xcb-util-common.h"
35
36void
37xcb_event_handlers_init(xcb_connection_t *c, xcb_event_handlers_t *evenths)
38{
39    memset(evenths, 0, sizeof(xcb_event_handlers_t));
40    evenths->c = c;
41}
42
43xcb_connection_t *
44xcb_event_get_xcb_connection(xcb_event_handlers_t *evenths)
45{
46    return evenths->c;
47}
48
49static xcb_event_handler_t *
50get_event_handler(xcb_event_handlers_t *evenths, int event)
51{
52    assert(event < 256);
53    event &= XCB_EVENT_RESPONSE_TYPE_MASK;
54    assert(event >= 2);
55    return &evenths->event[event - 2];
56}
57
58static xcb_event_handler_t *
59get_error_handler(xcb_event_handlers_t *evenths, int error)
60{
61    assert(error >= 0 && error < 256);
62    return &evenths->error[error];
63}
64
65int
66xcb_event_handle(xcb_event_handlers_t *evenths, xcb_generic_event_t *event)
67{
68    xcb_event_handler_t *eventh = 0;
69    assert(event->response_type != 1);
70
71    if(event->response_type == 0)
72        eventh = get_error_handler(evenths, ((xcb_generic_error_t *) event)->error_code);
73    else
74        eventh = get_event_handler(evenths, event->response_type);
75
76    if(eventh->handler)
77        return eventh->handler(eventh->data, evenths->c, event);
78    return 0;
79}
80
81void
82xcb_event_wait_for_event_loop(xcb_event_handlers_t *evenths)
83{
84    xcb_generic_event_t *event;
85    while((event = xcb_wait_for_event(evenths->c)))
86    {
87        xcb_event_handle(evenths, event);
88        free(event);
89    }
90}
91
92void
93xcb_event_poll_for_event_loop(xcb_event_handlers_t *evenths)
94{
95    xcb_generic_event_t *event;
96    while ((event = xcb_poll_for_event(evenths->c)))
97    {
98        xcb_event_handle(evenths, event);
99        free(event);
100    }
101}
102
103static void
104set_handler(xcb_generic_event_handler_t handler, void *data, xcb_event_handler_t *place)
105{
106    xcb_event_handler_t eventh = { handler, data };
107    *place = eventh;
108}
109
110void
111xcb_event_set_handler(xcb_event_handlers_t *evenths, int event, xcb_generic_event_handler_t handler, void *data)
112{
113    set_handler(handler, data, get_event_handler(evenths, event));
114}
115
116void
117xcb_event_set_error_handler(xcb_event_handlers_t *evenths, int error, xcb_generic_error_handler_t handler, void *data)
118{
119    set_handler((xcb_generic_event_handler_t) handler, data, get_error_handler(evenths, error));
120}
121
122static const char *labelError[] =
123{
124    "Success",
125    "BadRequest",
126    "BadValue",
127    "BadWindow",
128    "BadPixmap",
129    "BadAtom",
130    "BadCursor",
131    "BadFont",
132    "BadMatch",
133    "BadDrawable",
134    "BadAccess",
135    "BadAlloc",
136    "BadColor",
137    "BadGC",
138    "BadIDChoice",
139    "BadName",
140    "BadLength",
141    "BadImplementation",
142};
143
144static const char *labelRequest[] =
145{
146    "no request",
147    "CreateWindow",
148    "ChangeWindowAttributes",
149    "GetWindowAttributes",
150    "DestroyWindow",
151    "DestroySubwindows",
152    "ChangeSaveSet",
153    "ReparentWindow",
154    "MapWindow",
155    "MapSubwindows",
156    "UnmapWindow",
157    "UnmapSubwindows",
158    "ConfigureWindow",
159    "CirculateWindow",
160    "GetGeometry",
161    "QueryTree",
162    "InternAtom",
163    "GetAtomName",
164    "ChangeProperty",
165    "DeleteProperty",
166    "GetProperty",
167    "ListProperties",
168    "SetSelectionOwner",
169    "GetSelectionOwner",
170    "ConvertSelection",
171    "SendEvent",
172    "GrabPointer",
173    "UngrabPointer",
174    "GrabButton",
175    "UngrabButton",
176    "ChangeActivePointerGrab",
177    "GrabKeyboard",
178    "UngrabKeyboard",
179    "GrabKey",
180    "UngrabKey",
181    "AllowEvents",
182    "GrabServer",
183    "UngrabServer",
184    "QueryPointer",
185    "GetMotionEvents",
186    "TranslateCoords",
187    "WarpPointer",
188    "SetInputFocus",
189    "GetInputFocus",
190    "QueryKeymap",
191    "OpenFont",
192    "CloseFont",
193    "QueryFont",
194    "QueryTextExtents",
195    "ListFonts",
196    "ListFontsWithInfo",
197    "SetFontPath",
198    "GetFontPath",
199    "CreatePixmap",
200    "FreePixmap",
201    "CreateGC",
202    "ChangeGC",
203    "CopyGC",
204    "SetDashes",
205    "SetClipRectangles",
206    "FreeGC",
207    "ClearArea",
208    "CopyArea",
209    "CopyPlane",
210    "PolyPoint",
211    "PolyLine",
212    "PolySegment",
213    "PolyRectangle",
214    "PolyArc",
215    "FillPoly",
216    "PolyFillRectangle",
217    "PolyFillArc",
218    "PutImage",
219    "GetImage",
220    "PolyText",
221    "PolyText",
222    "ImageText",
223    "ImageText",
224    "CreateColormap",
225    "FreeColormap",
226    "CopyColormapAndFree",
227    "InstallColormap",
228    "UninstallColormap",
229    "ListInstalledColormaps",
230    "AllocColor",
231    "AllocNamedColor",
232    "AllocColorCells",
233    "AllocColorPlanes",
234    "FreeColors",
235    "StoreColors",
236    "StoreNamedColor",
237    "QueryColors",
238    "LookupColor",
239    "CreateCursor",
240    "CreateGlyphCursor",
241    "FreeCursor",
242    "RecolorCursor",
243    "QueryBestSize",
244    "QueryExtension",
245    "ListExtensions",
246    "ChangeKeyboardMapping",
247    "GetKeyboardMapping",
248    "ChangeKeyboardControl",
249    "GetKeyboardControl",
250    "Bell",
251    "ChangePointerControl",
252    "GetPointerControl",
253    "SetScreenSaver",
254    "GetScreenSaver",
255    "ChangeHosts",
256    "ListHosts",
257    "SetAccessControl",
258    "SetCloseDownMode",
259    "KillClient",
260    "RotateProperties",
261    "ForceScreenSaver",
262    "SetPointerMapping",
263    "GetPointerMapping",
264    "SetModifierMapping",
265    "GetModifierMapping",
266    "major 120",
267    "major 121",
268    "major 122",
269    "major 123",
270    "major 124",
271    "major 125",
272    "major 126",
273    "NoOperation",
274};
275
276static const char *labelEvent[] =
277{
278    "error",
279    "reply",
280    "KeyPress",
281    "KeyRelease",
282    "ButtonPress",
283    "ButtonRelease",
284    "MotionNotify",
285    "EnterNotify",
286    "LeaveNotify",
287    "FocusIn",
288    "FocusOut",
289    "KeymapNotify",
290    "Expose",
291    "GraphicsExpose",
292    "NoExpose",
293    "VisibilityNotify",
294    "CreateNotify",
295    "DestroyNotify",
296    "UnmapNotify",
297    "MapNotify",
298    "MapRequest",
299    "ReparentNotify",
300    "ConfigureNotify",
301    "ConfigureRequest",
302    "GravityNotify",
303    "ResizeRequest",
304    "CirculateNotify",
305    "CirculateRequest",
306    "PropertyNotify",
307    "SelectionClear",
308    "SelectionRequest",
309    "SelectionNotify",
310    "ColormapNotify",
311    "ClientMessage",
312    "MappingNotify",
313};
314
315const char *
316xcb_event_get_label(uint8_t type)
317{
318    if(type < countof(labelEvent))
319        return labelEvent[type];
320    return NULL;
321}
322
323const char *
324xcb_event_get_error_label(uint8_t type)
325{
326    if(type < countof(labelError))
327        return labelError[type];
328    return NULL;
329}
330
331const char *
332xcb_event_get_request_label(uint8_t type)
333{
334    if(type < countof(labelRequest))
335        return labelRequest[type];
336    return NULL;
337}
338