Draw the hilite texture with the icon appearance instead of the background.
[openbox.git] / obt / xevent.c
blob9732c8f9a27d24046b4c3f4db8e4842444546512
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 obt/xevent.c for the Openbox window manager
4 Copyright (c) 2007 Dana Jansens
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 See the COPYING file for a copy of the GNU General Public License.
19 #include "obt/xevent.h"
20 #include "obt/mainloop.h"
21 #include "obt/util.h"
23 typedef struct _ObtXEventBinding ObtXEventBinding;
25 struct _ObtXEventHandler
27 gint ref;
28 ObtMainLoop *loop;
30 /* An array of hash tables where the key is the window, and the value is
31 the ObtXEventBinding */
32 GHashTable **bindings;
33 gint num_event_types; /* the length of the bindings array */
36 struct _ObtXEventBinding
38 Window win;
39 ObtXEventCallback func;
40 gpointer data;
43 static void xevent_handler(const XEvent *e, gpointer data);
44 static guint window_hash(Window *w) { return *w; }
45 static gboolean window_comp(Window *w1, Window *w2) { return *w1 == *w2; }
47 ObtXEventHandler* xevent_new()
49 ObtXEventHandler *h;
51 h = g_new0(ObtXEventHandler, 1);
52 h->ref = 1;
54 return h;
57 void xevent_ref(ObtXEventHandler *h)
59 ++h->ref;
62 void xevent_unref(ObtXEventHandler *h)
64 if (h && --h->ref == 0) {
65 gint i;
67 if (h->loop)
68 obt_main_loop_x_remove(h->loop, xevent_handler);
69 for (i = 0; i < h->num_event_types; ++i)
70 g_hash_table_destroy(h->bindings[i]);
71 g_free(h->bindings);
73 obt_free0(h, ObtXEventHandler, 1);
77 void xevent_register(ObtXEventHandler *h, ObtMainLoop *loop)
79 h->loop = loop;
80 obt_main_loop_x_add(loop, xevent_handler, h, NULL);
83 void xevent_set_handler(ObtXEventHandler *h, gint type, Window win,
84 ObtXEventCallback func, gpointer data)
86 ObtXEventBinding *b;
88 g_assert(func);
90 /* make sure we have a spot for the event */
91 if (type + 1 < h->num_event_types) {
92 gint i;
93 h->bindings = g_renew(GHashTable*, h->bindings, type + 1);
94 for (i = h->num_event_types; i < type + 1; ++i)
95 h->bindings[i] = g_hash_table_new_full((GHashFunc)window_hash,
96 (GEqualFunc)window_comp,
97 NULL, g_free);
98 h->num_event_types = type + 1;
101 b = g_new(ObtXEventBinding, 1);
102 b->win = win;
103 b->func = func;
104 b->data = data;
105 g_hash_table_replace(h->bindings[type], &b->win, b);
108 void xevent_remove_handler(ObtXEventHandler *h, gint type, Window win)
110 g_assert(type < h->num_event_types);
111 g_assert(win);
113 g_hash_table_remove(h->bindings[type], &win);
116 static void xevent_handler(const XEvent *e, gpointer data)
118 ObtXEventHandler *h;
119 ObtXEventBinding *b;
121 h = data;
123 if (e->type < h->num_event_types) {
124 const gint all = OBT_XEVENT_ALL_WINDOWS;
125 /* run the all_windows handler first */
126 b = g_hash_table_lookup(h->bindings[e->xany.type], &all);
127 if (b) b->func(e, b->data);
128 /* then run the per-window handler */
129 b = g_hash_table_lookup(h->bindings[e->xany.type], &e->xany.window);
130 if (b) b->func(e, b->data);
132 else
133 g_message("Unhandled X Event type %d", e->xany.type);