make the xevent stuff work for events from extensions (these go beyond LASTEvent)
This commit is contained in:
parent
9f5296fb14
commit
03f45e79b8
1 changed files with 33 additions and 14 deletions
41
obt/xevent.c
41
obt/xevent.c
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "obt/xevent.h"
|
#include "obt/xevent.h"
|
||||||
#include "obt/mainloop.h"
|
#include "obt/mainloop.h"
|
||||||
|
#include "obt/util.h"
|
||||||
|
|
||||||
typedef struct _ObtXEventBinding ObtXEventBinding;
|
typedef struct _ObtXEventBinding ObtXEventBinding;
|
||||||
|
|
||||||
|
@ -26,9 +27,10 @@ struct _ObtXEventHandler
|
||||||
gint ref;
|
gint ref;
|
||||||
ObtMainLoop *loop;
|
ObtMainLoop *loop;
|
||||||
|
|
||||||
/* A hash table where the key is the window, and the value is the
|
/* An array of hash tables where the key is the window, and the value is
|
||||||
ObtXEventBinding */
|
the ObtXEventBinding */
|
||||||
GHashTable *bindings[LASTEvent]; /* LASTEvent comes from X.h */
|
GHashTable **bindings;
|
||||||
|
gint num_event_types; /* the length of the bindings array */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ObtXEventBinding
|
struct _ObtXEventBinding
|
||||||
|
@ -45,14 +47,10 @@ static gboolean window_comp(Window *w1, Window *w2) { return *w1 == *w2; }
|
||||||
ObtXEventHandler* xevent_new()
|
ObtXEventHandler* xevent_new()
|
||||||
{
|
{
|
||||||
ObtXEventHandler *h;
|
ObtXEventHandler *h;
|
||||||
gint i;
|
|
||||||
|
|
||||||
h = g_new(ObtXEventHandler, 1);
|
h = g_new0(ObtXEventHandler, 1);
|
||||||
h->ref = 1;
|
h->ref = 1;
|
||||||
for (i = 0; i < LASTEvent; ++i)
|
|
||||||
h->bindings[i] = g_hash_table_new_full((GHashFunc)window_hash,
|
|
||||||
(GEqualFunc)window_comp,
|
|
||||||
NULL, g_free);
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,8 +62,15 @@ void xevent_ref(ObtXEventHandler *h)
|
||||||
void xevent_unref(ObtXEventHandler *h)
|
void xevent_unref(ObtXEventHandler *h)
|
||||||
{
|
{
|
||||||
if (h && --h->ref == 0) {
|
if (h && --h->ref == 0) {
|
||||||
|
gint i;
|
||||||
|
|
||||||
if (h->loop)
|
if (h->loop)
|
||||||
obt_main_loop_x_remove(h->loop, xevent_handler);
|
obt_main_loop_x_remove(h->loop, xevent_handler);
|
||||||
|
for (i = 0; i < h->num_event_types; ++i)
|
||||||
|
g_hash_table_destroy(h->bindings[i]);
|
||||||
|
g_free(h->bindings);
|
||||||
|
|
||||||
|
obt_free0(h, ObtXEventHandler, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,10 +85,20 @@ void xevent_set_handler(ObtXEventHandler *h, gint type, Window win,
|
||||||
{
|
{
|
||||||
ObtXEventBinding *b;
|
ObtXEventBinding *b;
|
||||||
|
|
||||||
g_assert(type < LASTEvent);
|
|
||||||
g_assert(win);
|
g_assert(win);
|
||||||
g_assert(func);
|
g_assert(func);
|
||||||
|
|
||||||
|
/* make sure we have a spot for the event */
|
||||||
|
if (type + 1 < h->num_event_types) {
|
||||||
|
gint i;
|
||||||
|
h->bindings = g_renew(GHashTable*, h->bindings, type + 1);
|
||||||
|
for (i = h->num_event_types; i < type + 1; ++i)
|
||||||
|
h->bindings[i] = g_hash_table_new_full((GHashFunc)window_hash,
|
||||||
|
(GEqualFunc)window_comp,
|
||||||
|
NULL, g_free);
|
||||||
|
h->num_event_types = type + 1;
|
||||||
|
}
|
||||||
|
|
||||||
b = g_new(ObtXEventBinding, 1);
|
b = g_new(ObtXEventBinding, 1);
|
||||||
b->win = win;
|
b->win = win;
|
||||||
b->func = func;
|
b->func = func;
|
||||||
|
@ -93,7 +108,7 @@ void xevent_set_handler(ObtXEventHandler *h, gint type, Window win,
|
||||||
|
|
||||||
void xevent_remove_handler(ObtXEventHandler *h, gint type, Window win)
|
void xevent_remove_handler(ObtXEventHandler *h, gint type, Window win)
|
||||||
{
|
{
|
||||||
g_assert(type < LASTEvent);
|
g_assert(type < h->num_event_types);
|
||||||
g_assert(win);
|
g_assert(win);
|
||||||
|
|
||||||
g_hash_table_remove(h->bindings[type], &win);
|
g_hash_table_remove(h->bindings[type], &win);
|
||||||
|
@ -104,7 +119,11 @@ static void xevent_handler(const XEvent *e, gpointer data)
|
||||||
ObtXEventHandler *h;
|
ObtXEventHandler *h;
|
||||||
ObtXEventBinding *b;
|
ObtXEventBinding *b;
|
||||||
|
|
||||||
|
if (e->type < h->num_event_types) {
|
||||||
h = data;
|
h = data;
|
||||||
b = g_hash_table_lookup(h->bindings[e->xany.type], &e->xany.window);
|
b = g_hash_table_lookup(h->bindings[e->xany.type], &e->xany.window);
|
||||||
if (b) b->func(e, b->data);
|
if (b) b->func(e, b->data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_message("Unhandled X Event type %d", e->xany.type);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue