*/
#include "obt/mainloop.h"
+#include "obt/display.h"
+#include "obt/xqueue.h"
#include "obt/util.h"
+#ifdef HAVE_STDIO_H
#include <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
#include <stdlib.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SIGNAL_H
#include <signal.h>
+#endif
typedef struct _ObtMainLoopTimer ObtMainLoopTimer;
typedef struct _ObtMainLoopSignal ObtMainLoopSignal;
static void sighandler(gint sig);
static void timer_dispatch(ObtMainLoop *loop, GTimeVal **wait);
static void fd_handler_destroy(gpointer data);
+static void calc_max_fd(ObtMainLoop *loop);
struct _ObtMainLoop
{
GDestroyNotify destroy;
};
-ObtMainLoop *obt_main_loop_new(Display *display)
+ObtMainLoop *obt_main_loop_new(void)
{
ObtMainLoop *loop;
- loop = g_new0(ObtMainLoop, 1);
+ loop = g_slice_new0(ObtMainLoop);
loop->ref = 1;
- loop->display = display;
- loop->fd_x = ConnectionNumber(display);
FD_ZERO(&loop->fd_set);
- FD_SET(loop->fd_x, &loop->fd_set);
- loop->fd_max = loop->fd_x;
+ loop->fd_x = -1;
+ loop->fd_max = -1;
loop->fd_handlers = g_hash_table_new_full(g_int_hash, g_int_equal,
NULL, fd_handler_destroy);
for (it = loop->timers; it; it = g_slist_next(it)) {
ObtMainLoopTimer *t = it->data;
if (t->destroy) t->destroy(t->data);
- g_free(t);
+ g_slice_free(ObtMainLoopTimer, t);
}
g_slist_free(loop->timers);
loop->timers = NULL;
}
}
- obt_free0(loop, ObtMainLoop, 1);
+ g_slice_free(ObtMainLoop, loop);
}
}
loop->signal_fired = FALSE;
sigprocmask(SIG_SETMASK, &oldset, NULL);
- } else if (loop->display && XPending(loop->display)) {
- do {
- XNextEvent(loop->display, &e);
+ } else if (loop->display && xqueue_pending_local()) {
+ while (xqueue_next_local(&e) && loop->run) {
+ if (e.type == MappingNotify)
+ XRefreshKeyboardMapping(&e.xmapping);
for (it = loop->x_handlers; it; it = g_slist_next(it)) {
ObtMainLoopXHandlerType *h = it->data;
h->func(&e, h->data);
}
- } while (XPending(loop->display) && loop->run);
+ }
} else {
/* this only runs if there were no x events received */
-
timer_dispatch(loop, (GTimeVal**)&wait);
selset = loop->fd_set;
{
ObtMainLoopXHandlerType *h;
- h = g_new(ObtMainLoopXHandlerType, 1);
+ h = g_slice_new(ObtMainLoopXHandlerType);
h->loop = loop;
h->func = handler;
h->data = data;
h->destroy = notify;
+
+ if (!loop->x_handlers) {
+ g_assert(obt_display); /* is the display open? */
+
+ loop->display = obt_display;
+ loop->fd_x = ConnectionNumber(loop->display);
+ FD_SET(loop->fd_x, &loop->fd_set);
+ calc_max_fd(loop);
+ }
+
loop->x_handlers = g_slist_prepend(loop->x_handlers, h);
}
void obt_main_loop_x_remove(ObtMainLoop *loop,
- ObtMainLoopXHandler handler)
+ ObtMainLoopXHandler handler)
{
GSList *it, *next;
if (h->func == handler) {
loop->x_handlers = g_slist_delete_link(loop->x_handlers, it);
if (h->destroy) h->destroy(h->data);
- g_free(h);
+ g_slice_free(ObtMainLoopXHandlerType, h);
}
}
+
+ if (!loop->x_handlers) {
+ FD_CLR(loop->fd_x, &loop->fd_set);
+ calc_max_fd(loop);
+ }
}
/*** SIGNAL WATCHERS ***/
g_return_if_fail(signal < NUM_SIGNALS);
- h = g_new(ObtMainLoopSignalHandlerType, 1);
+ h = g_slice_new(ObtMainLoopSignalHandlerType);
h->loop = loop;
h->signal = signal;
h->func = handler;
g_slist_delete_link(loop->signal_handlers[i], it);
if (h->destroy) h->destroy(h->data);
- g_free(h);
+ g_slice_free(ObtMainLoopSignalHandlerType, h);
}
}
}
{
ObtMainLoopFdHandlerType *h;
- h = g_new(ObtMainLoopFdHandlerType, 1);
+ h = g_slice_new(ObtMainLoopFdHandlerType);
h->loop = loop;
h->fd = fd;
h->func = handler;
if (h->destroy)
h->destroy(h->data);
+ g_slice_free(ObtMainLoopFdHandlerType, h);
}
void obt_main_loop_fd_remove(ObtMainLoop *loop,
gint fd)
{
g_hash_table_remove(loop->fd_handlers, &fd);
+ calc_max_fd(loop);
}
/*** TIMEOUTS ***/
{
GSList *it;
for (it = loop->timers; it; it = g_slist_next(it)) {
- ObMainLoopTimer *t = it->data;
+ ObtMainLoopTimer *t = it->data;
if (timecompare(&ins->timeout, &t->timeout) <= 0) {
loop->timers = g_slist_insert_before(loop->timers, it, ins);
break;
GEqualFunc cmp,
GDestroyNotify notify)
{
- ObMainLoopTimer *t = g_new(ObMainLoopTimer, 1);
+ ObtMainLoopTimer *t = g_slice_new(ObtMainLoopTimer);
g_assert(microseconds > 0); /* if it's 0 it'll cause an infinite loop */
loop->timers = g_slist_delete_link(loop->timers, it);
if (curr->destroy)
curr->destroy(curr->data);
- g_free(curr);
+ g_slice_free(ObtMainLoopTimer, curr);
continue;
}
} else {
if (curr->destroy)
curr->destroy(curr->data);
- g_free(curr);
+ g_slice_free(ObtMainLoopTimer, curr);
}
/* the timer queue has been shuffled, start from the beginning