openbox/openbox/dispatch.c
2003-03-28 09:33:40 +00:00

267 lines
5.2 KiB
C

#include "dispatch.h"
#include "extensions.h"
#include <glib.h>
typedef struct {
EventHandler h;
void *data;
} Func;
/* an array of GSList*s of Func*s */
static GSList **funcs;
void dispatch_startup()
{
guint i;
EventType j;
i = 0;
j = EVENT_RANGE;
while (j > 1) {
j >>= 1;
++i;
}
funcs = g_new0(GSList*, i);
}
void dispatch_shutdown()
{
guint i;
EventType j;
GSList *it;
for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1) {
for (it = funcs[i]; it != NULL; it = it->next)
g_free(it->data);
g_slist_free(funcs[i]);
funcs[i] = NULL;
}
g_free(funcs);
}
void dispatch_register(EventMask mask, EventHandler h, void *data)
{
guint i;
EventType j;
GSList *it, *next;
EventMask m;
Func *f;
/* add to masks it needs to be registered for */
m = mask;
while (m) {
for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1)
if (m & j) {
for (it = funcs[i]; it != NULL; it = it->next) {
f = it->data;
if (f->h == h && f->data == data)
break;
}
if (it == NULL) { /* wasn't already regged */
f = g_new(Func, 1);
f->h = h;
f->data = data;
funcs[i] = g_slist_append(funcs[i], f);
}
m ^= j; /* remove from the mask */
}
g_assert(j >= EVENT_RANGE); /* an invalid event is in the mask */
}
/* remove from masks its not registered for anymore */
for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1) {
if (!(j & mask))
for (it = funcs[i]; it != NULL; it = next) {
next = it->next;
f = it->data;
if (f->h == h && f->data == data) {
g_free(f);
funcs[i] = g_slist_delete_link(funcs[i], it);
}
}
}
}
void dispatch_x(XEvent *xe, Client *c)
{
EventType e;
guint i;
GSList *it;
ObEvent obe;
switch (xe->type) {
case EnterNotify:
e = Event_X_EnterNotify;
break;
case LeaveNotify:
e = Event_X_LeaveNotify;
break;
case KeyPress:
e = Event_X_KeyPress;
break;
case KeyRelease:
e = Event_X_KeyRelease;
break;
case ButtonPress:
e = Event_X_ButtonPress;
break;
case ButtonRelease:
e = Event_X_ButtonRelease;
break;
case MotionNotify:
e = Event_X_MotionNotify;
break;
default:
/* XKB events */
if (xe->type == extensions_xkb_event_basep) {
switch (((XkbAnyEvent*)&e)->xkb_type) {
case XkbBellNotify:
e = Event_X_Bell;
break;
}
}
return;
}
obe.type = e;
obe.data.x.e = xe;
obe.data.x.client = c;
i = 0;
while (e > 1) {
e >>= 1;
++i;
}
for (it = funcs[i]; it != NULL; it = it->next) {
Func *f = it->data;
f->h(&obe, f->data);
}
}
void dispatch_client(EventType e, Client *c, int num0, int num1)
{
guint i;
GSList *it;
ObEvent obe;
g_assert(c != NULL);
obe.type = e;
obe.data.c.client = c;
obe.data.c.num[0] = num0;
obe.data.c.num[1] = num1;
obe.data.c.num[2] = 0;
i = 0;
while (e > 1) {
e >>= 1;
++i;
}
for (it = funcs[i]; it != NULL; it = it->next) {
Func *f = it->data;
f->h(&obe, f->data);
}
}
void dispatch_ob(EventType e, int num0, int num1)
{
guint i;
GSList *it;
ObEvent obe;
obe.type = e;
obe.data.o.num[0] = num0;
obe.data.o.num[1] = num1;
i = 0;
while (e > 1) {
e >>= 1;
++i;
}
for (it = funcs[i]; it != NULL; it = it->next) {
Func *f = it->data;
f->h(&obe, f->data);
}
}
void dispatch_signal(int signal)
{
guint i;
EventType e = Event_Signal;
GSList *it;
ObEvent obe;
obe.type = e;
obe.data.s.signal = signal;
i = 0;
while (e > 1) {
e >>= 1;
++i;
}
for (it = funcs[i]; it != NULL; it = it->next) {
Func *f = it->data;
f->h(&obe, f->data);
}
}
void dispatch_move(Client *c, int *x, int *y)
{
guint i;
GSList *it;
EventType e = Event_Client_Moving;
ObEvent obe;
obe.type = e;
obe.data.c.client = c;
obe.data.c.num[0] = *x;
obe.data.c.num[1] = *y;
i = 0;
while (e > 1) {
e >>= 1;
++i;
}
for (it = funcs[i]; it != NULL; it = it->next) {
Func *f = it->data;
f->h(&obe, f->data);
}
*x = obe.data.c.num[0];
*y = obe.data.c.num[1];
}
void dispatch_resize(Client *c, int *w, int *h, Corner corner)
{
guint i;
GSList *it;
EventType e = Event_Client_Resizing;
ObEvent obe;
obe.type = e;
obe.data.c.client = c;
obe.data.c.num[0] = *w;
obe.data.c.num[1] = *h;
obe.data.c.num[2] = corner;
i = 0;
while (e > 1) {
e >>= 1;
++i;
}
for (it = funcs[i]; it != NULL; it = it->next) {
Func *f = it->data;
f->h(&obe, f->data);
}
*w = obe.data.c.num[0];
*h = obe.data.c.num[1];
}