/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
- mainloop.c for the Openbox window manager
+ obt/mainloop.c for the Openbox window manager
Copyright (c) 2006 Mikael Magnusson
Copyright (c) 2003-2007 Dana Jansens
See the COPYING file for a copy of the GNU General Public License.
*/
-#include "mainloop.h"
-#include "event.h"
+#include "obt/mainloop.h"
+#include "obt/util.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <signal.h>
-typedef struct _ObMainLoopTimer ObMainLoopTimer;
-typedef struct _ObMainLoopSignal ObMainLoopSignal;
-typedef struct _ObMainLoopSignalHandlerType ObMainLoopSignalHandlerType;
-typedef struct _ObMainLoopXHandlerType ObMainLoopXHandlerType;
-typedef struct _ObMainLoopFdHandlerType ObMainLoopFdHandlerType;
+typedef struct _ObtMainLoopTimer ObtMainLoopTimer;
+typedef struct _ObtMainLoopSignal ObtMainLoopSignal;
+typedef struct _ObtMainLoopSignalHandlerType ObtMainLoopSignalHandlerType;
+typedef struct _ObtMainLoopXHandlerType ObtMainLoopXHandlerType;
+typedef struct _ObtMainLoopFdHandlerType ObtMainLoopFdHandlerType;
/* this should be more than the number of possible signals on any
architecture... */
#define NUM_SIGNALS 99
-/* all created ObMainLoops. Used by the signal handler to pass along signals */
+/* all created ObtMainLoops. Used by the signal handler to pass along
+ signals */
static GSList *all_loops;
/* signals are global to all loops */
#define NUM_CORE_SIGNALS (sizeof(core_signals) / sizeof(core_signals[0]))
static void sighandler(gint sig);
-static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait);
+static void timer_dispatch(ObtMainLoop *loop, GTimeVal **wait);
static void fd_handler_destroy(gpointer data);
-struct _ObMainLoop
+struct _ObtMainLoop
{
+ gint ref;
Display *display;
gboolean run; /* do keep running */
GSList *signal_handlers[NUM_SIGNALS];
};
-struct _ObMainLoopTimer
+struct _ObtMainLoopTimer
{
gulong delay;
GSourceFunc func;
gboolean fired;
};
-struct _ObMainLoopSignalHandlerType
+struct _ObtMainLoopSignalHandlerType
{
- ObMainLoop *loop;
+ ObtMainLoop *loop;
gint signal;
gpointer data;
- ObMainLoopSignalHandler func;
+ ObtMainLoopSignalHandler func;
GDestroyNotify destroy;
};
-struct _ObMainLoopXHandlerType
+struct _ObtMainLoopXHandlerType
{
- ObMainLoop *loop;
+ ObtMainLoop *loop;
gpointer data;
- ObMainLoopXHandler func;
+ ObtMainLoopXHandler func;
GDestroyNotify destroy;
};
-struct _ObMainLoopFdHandlerType
+struct _ObtMainLoopFdHandlerType
{
- ObMainLoop *loop;
+ ObtMainLoop *loop;
gint fd;
gpointer data;
- ObMainLoopFdHandler func;
+ ObtMainLoopFdHandler func;
GDestroyNotify destroy;
};
-ObMainLoop *ob_main_loop_new(Display *display)
+ObtMainLoop *obt_main_loop_new(Display *display)
{
- ObMainLoop *loop;
+ ObtMainLoop *loop;
- loop = g_new0(ObMainLoop, 1);
+ loop = g_new0(ObtMainLoop, 1);
+ loop->ref = 1;
loop->display = display;
loop->fd_x = ConnectionNumber(display);
FD_ZERO(&loop->fd_set);
return loop;
}
-void ob_main_loop_destroy(ObMainLoop *loop)
+void obt_main_loop_ref(ObtMainLoop *loop)
+{
+ ++loop->ref;
+}
+
+void obt_main_loop_unref(ObtMainLoop *loop)
{
guint i;
GSList *it, *next;
- if (loop) {
+ if (loop && --loop->ref == 0) {
g_assert(loop->running == FALSE);
for (it = loop->x_handlers; it; it = next) {
- ObMainLoopXHandlerType *h = it->data;
+ ObtMainLoopXHandlerType *h = it->data;
next = g_slist_next(it);
- ob_main_loop_x_remove(loop, h->func);
+ obt_main_loop_x_remove(loop, h->func);
}
g_hash_table_destroy(loop->fd_handlers);
for (it = loop->timers; it; it = g_slist_next(it)) {
- ObMainLoopTimer *t = it->data;
+ ObtMainLoopTimer *t = it->data;
if (t->destroy) t->destroy(t->data);
g_free(t);
}
for (i = 0; i < NUM_SIGNALS; ++i)
for (it = loop->signal_handlers[i]; it; it = next) {
- ObMainLoopSignalHandlerType *h = it->data;
+ ObtMainLoopSignalHandlerType *h = it->data;
next = g_slist_next(it);
- ob_main_loop_signal_remove(loop, h->func);
+ obt_main_loop_signal_remove(loop, h->func);
}
all_loops = g_slist_remove(all_loops, loop);
}
}
- g_free(loop);
+ obt_free0(loop, ObtMainLoop, 1);
}
}
gpointer value,
gpointer data)
{
- ObMainLoopFdHandlerType *h = value;
+ ObtMainLoopFdHandlerType *h = value;
fd_set *set = data;
if (FD_ISSET(h->fd, set))
h->func(h->fd, h->data);
}
-void ob_main_loop_run(ObMainLoop *loop)
+void obt_main_loop_run(ObtMainLoop *loop)
{
XEvent e;
struct timeval *wait;
while (loop->signals_fired[i]) {
for (it = loop->signal_handlers[i];
it; it = g_slist_next(it)) {
- ObMainLoopSignalHandlerType *h = it->data;
+ ObtMainLoopSignalHandlerType *h = it->data;
h->func(i, h->data);
}
loop->signals_fired[i]--;
loop->signal_fired = FALSE;
sigprocmask(SIG_SETMASK, &oldset, NULL);
- } else if (XPending(loop->display)) {
+ } else if (loop->display && XPending(loop->display)) {
do {
XNextEvent(loop->display, &e);
for (it = loop->x_handlers; it; it = g_slist_next(it)) {
- ObMainLoopXHandlerType *h = it->data;
+ ObtMainLoopXHandlerType *h = it->data;
h->func(&e, h->data);
}
} while (XPending(loop->display) && loop->run);
loop->running = FALSE;
}
-void ob_main_loop_exit(ObMainLoop *loop)
+void obt_main_loop_exit(ObtMainLoop *loop)
{
loop->run = FALSE;
}
/*** XEVENT WATCHERS ***/
-void ob_main_loop_x_add(ObMainLoop *loop,
- ObMainLoopXHandler handler,
- gpointer data,
- GDestroyNotify notify)
+void obt_main_loop_x_add(ObtMainLoop *loop,
+ ObtMainLoopXHandler handler,
+ gpointer data,
+ GDestroyNotify notify)
{
- ObMainLoopXHandlerType *h;
+ ObtMainLoopXHandlerType *h;
- h = g_new(ObMainLoopXHandlerType, 1);
+ h = g_new(ObtMainLoopXHandlerType, 1);
h->loop = loop;
h->func = handler;
h->data = data;
loop->x_handlers = g_slist_prepend(loop->x_handlers, h);
}
-void ob_main_loop_x_remove(ObMainLoop *loop,
- ObMainLoopXHandler handler)
+void obt_main_loop_x_remove(ObtMainLoop *loop,
+ ObtMainLoopXHandler handler)
{
GSList *it, *next;
for (it = loop->x_handlers; it; it = next) {
- ObMainLoopXHandlerType *h = it->data;
+ ObtMainLoopXHandlerType *h = it->data;
next = g_slist_next(it);
if (h->func == handler) {
loop->x_handlers = g_slist_delete_link(loop->x_handlers, it);
}
for (it = all_loops; it; it = g_slist_next(it)) {
- ObMainLoop *loop = it->data;
+ ObtMainLoop *loop = it->data;
loop->signal_fired = TRUE;
loop->signals_fired[sig]++;
}
}
-void ob_main_loop_signal_add(ObMainLoop *loop,
- gint signal,
- ObMainLoopSignalHandler handler,
- gpointer data,
- GDestroyNotify notify)
+void obt_main_loop_signal_add(ObtMainLoop *loop,
+ gint signal,
+ ObtMainLoopSignalHandler handler,
+ gpointer data,
+ GDestroyNotify notify)
{
- ObMainLoopSignalHandlerType *h;
+ ObtMainLoopSignalHandlerType *h;
g_return_if_fail(signal < NUM_SIGNALS);
- h = g_new(ObMainLoopSignalHandlerType, 1);
+ h = g_new(ObtMainLoopSignalHandlerType, 1);
h->loop = loop;
h->signal = signal;
h->func = handler;
all_signals[signal].installed++;
}
-void ob_main_loop_signal_remove(ObMainLoop *loop,
- ObMainLoopSignalHandler handler)
+void obt_main_loop_signal_remove(ObtMainLoop *loop,
+ ObtMainLoopSignalHandler handler)
{
guint i;
GSList *it, *next;
for (i = 0; i < NUM_SIGNALS; ++i) {
for (it = loop->signal_handlers[i]; it; it = next) {
- ObMainLoopSignalHandlerType *h = it->data;
+ ObtMainLoopSignalHandlerType *h = it->data;
next = g_slist_next(it);
static void max_fd_func(gpointer key, gpointer value, gpointer data)
{
- ObMainLoop *loop = data;
+ ObtMainLoop *loop = data;
/* key is the fd */
loop->fd_max = MAX(loop->fd_max, *(gint*)key);
}
-static void calc_max_fd(ObMainLoop *loop)
+static void calc_max_fd(ObtMainLoop *loop)
{
loop->fd_max = loop->fd_x;
g_hash_table_foreach(loop->fd_handlers, max_fd_func, loop);
}
-void ob_main_loop_fd_add(ObMainLoop *loop,
- gint fd,
- ObMainLoopFdHandler handler,
- gpointer data,
- GDestroyNotify notify)
+void obt_main_loop_fd_add(ObtMainLoop *loop,
+ gint fd,
+ ObtMainLoopFdHandler handler,
+ gpointer data,
+ GDestroyNotify notify)
{
- ObMainLoopFdHandlerType *h;
+ ObtMainLoopFdHandlerType *h;
- h = g_new(ObMainLoopFdHandlerType, 1);
+ h = g_new(ObtMainLoopFdHandlerType, 1);
h->loop = loop;
h->fd = fd;
h->func = handler;
static void fd_handler_destroy(gpointer data)
{
- ObMainLoopFdHandlerType *h = data;
+ ObtMainLoopFdHandlerType *h = data;
FD_CLR(h->fd, &h->loop->fd_set);
h->destroy(h->data);
}
-void ob_main_loop_fd_remove(ObMainLoop *loop,
- gint fd)
+void obt_main_loop_fd_remove(ObtMainLoop *loop,
+ gint fd)
{
g_hash_table_remove(loop->fd_handlers, &fd);
}
/*** TIMEOUTS ***/
#define NEAREST_TIMEOUT(loop) \
- (((ObMainLoopTimer*)(loop)->timers->data)->timeout)
+ (((ObtMainLoopTimer*)(loop)->timers->data)->timeout)
static glong timecompare(GTimeVal *a, GTimeVal *b)
{
return a->tv_usec - b->tv_usec;
}
-static void insert_timer(ObMainLoop *loop, ObMainLoopTimer *ins)
+static void insert_timer(ObtMainLoop *loop, ObtMainLoopTimer *ins)
{
GSList *it;
for (it = loop->timers; it; it = g_slist_next(it)) {
loop->timers = g_slist_append(loop->timers, ins);
}
-void ob_main_loop_timeout_add(ObMainLoop *loop,
- gulong microseconds,
- GSourceFunc handler,
- gpointer data,
- GEqualFunc cmp,
- GDestroyNotify notify)
+void obt_main_loop_timeout_add(ObtMainLoop *loop,
+ gulong microseconds,
+ GSourceFunc handler,
+ gpointer data,
+ GEqualFunc cmp,
+ GDestroyNotify notify)
{
ObMainLoopTimer *t = g_new(ObMainLoopTimer, 1);
insert_timer(loop, t);
}
-void ob_main_loop_timeout_remove(ObMainLoop *loop,
- GSourceFunc handler)
+void obt_main_loop_timeout_remove(ObtMainLoop *loop,
+ GSourceFunc handler)
{
GSList *it;
for (it = loop->timers; it; it = g_slist_next(it)) {
- ObMainLoopTimer *t = it->data;
+ ObtMainLoopTimer *t = it->data;
if (t->func == handler)
t->del_me = TRUE;
}
}
-void ob_main_loop_timeout_remove_data(ObMainLoop *loop, GSourceFunc handler,
- gpointer data, gboolean cancel_dest)
+void obt_main_loop_timeout_remove_data(ObtMainLoop *loop, GSourceFunc handler,
+ gpointer data, gboolean cancel_dest)
{
GSList *it;
for (it = loop->timers; it; it = g_slist_next(it)) {
- ObMainLoopTimer *t = it->data;
+ ObtMainLoopTimer *t = it->data;
if (t->func == handler && t->equal(t->data, data)) {
t->del_me = TRUE;
if (cancel_dest)
}
/* find the time to wait for the nearest timeout */
-static gboolean nearest_timeout_wait(ObMainLoop *loop, GTimeVal *tm)
+static gboolean nearest_timeout_wait(ObtMainLoop *loop, GTimeVal *tm)
{
if (loop->timers == NULL)
return FALSE;
return TRUE;
}
-static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait)
+static void timer_dispatch(ObtMainLoop *loop, GTimeVal **wait)
{
GSList *it, *next;
g_get_current_time(&loop->now);
for (it = loop->timers; it; it = next) {
- ObMainLoopTimer *curr;
+ ObtMainLoopTimer *curr;
next = g_slist_next(it);