obt/internal.h \
obt/keyboard.h \
obt/keyboard.c \
- obt/mainloop.h \
- obt/mainloop.c \
obt/xml.h \
obt/xml.c \
obt/ddparse.h \
obt/prop.h \
obt/prop.c \
obt/util.h \
- obt/xevent.h \
- obt/xevent.c \
obt/xqueue.h \
obt/xqueue.c
obt/link.h \
obt/display.h \
obt/keyboard.h \
- obt/mainloop.h \
obt/xml.h \
obt/paths.h \
obt/prop.h \
obt/util.h \
obt/version.h \
- obt/xevent.h \
obt/xqueue.h
nodist_pkgconfig_DATA = \
+++ /dev/null
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-
- obt/mainloop.c for the Openbox window manager
- Copyright (c) 2006 Mikael Magnusson
- Copyright (c) 2003-2007 Dana Jansens
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- See the COPYING file for a copy of the GNU General Public License.
-*/
-
-#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;
-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 ObtMainLoops. Used by the signal handler to pass along
- signals */
-static GSList *all_loops;
-
-/* signals are global to all loops */
-static struct {
- guint installed; /* a ref count */
- struct sigaction oldact;
-} all_signals[NUM_SIGNALS];
-
-/* a set of all possible signals */
-static sigset_t all_signals_set;
-
-/* signals which cause a core dump, these can't be used for callbacks */
-static gint core_signals[] =
-{
- SIGABRT,
- SIGSEGV,
- SIGFPE,
- SIGILL,
- SIGQUIT,
- SIGTRAP,
- SIGSYS,
- SIGBUS,
- SIGXCPU,
- SIGXFSZ
-};
-#define NUM_CORE_SIGNALS (sizeof(core_signals) / sizeof(core_signals[0]))
-
-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
-{
- gint ref;
- Display *display;
-
- gboolean run; /* do keep running */
- gboolean running; /* is still running */
-
- GSList *x_handlers;
-
- gint fd_x; /* The X fd is a special case! */
- gint fd_max;
- GHashTable *fd_handlers;
- fd_set fd_set;
-
- GSList *timers;
- GTimeVal now;
- GTimeVal ret_wait;
-
- gboolean signal_fired;
- guint signals_fired[NUM_SIGNALS];
- GSList *signal_handlers[NUM_SIGNALS];
-};
-
-struct _ObtMainLoopTimer
-{
- gulong delay;
- GSourceFunc func;
- gpointer data;
- GEqualFunc equal;
- GDestroyNotify destroy;
-
- /* The timer needs to be freed */
- gboolean del_me;
- /* The time the last fire should've been at */
- GTimeVal last;
- /* When this timer will next trigger */
- GTimeVal timeout;
-
- /* Only allow a timer's function to fire once per run through the list,
- so that it doesn't get locked in there forever */
- gboolean fired;
-};
-
-struct _ObtMainLoopSignalHandlerType
-{
- ObtMainLoop *loop;
- gint signal;
- gpointer data;
- ObtMainLoopSignalHandler func;
- GDestroyNotify destroy;
-};
-
-struct _ObtMainLoopXHandlerType
-{
- ObtMainLoop *loop;
- gpointer data;
- ObtMainLoopXHandler func;
- GDestroyNotify destroy;
-};
-
-struct _ObtMainLoopFdHandlerType
-{
- ObtMainLoop *loop;
- gint fd;
- gpointer data;
- ObtMainLoopFdHandler func;
- GDestroyNotify destroy;
-};
-
-ObtMainLoop *obt_main_loop_new(void)
-{
- ObtMainLoop *loop;
-
- loop = g_slice_new0(ObtMainLoop);
- loop->ref = 1;
- FD_ZERO(&loop->fd_set);
- 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);
-
- g_get_current_time(&loop->now);
-
- /* only do this if we're the first loop created */
- if (!all_loops) {
- guint i;
- struct sigaction action;
- sigset_t sigset;
-
- /* initialize the all_signals_set */
- sigfillset(&all_signals_set);
-
- sigemptyset(&sigset);
- action.sa_handler = sighandler;
- action.sa_mask = sigset;
- action.sa_flags = SA_NOCLDSTOP;
-
- /* grab all the signals that cause core dumps */
- for (i = 0; i < NUM_CORE_SIGNALS; ++i) {
- /* SIGABRT is curiously not grabbed here!! that's because when we
- get one of the core_signals, we use abort() to dump the core.
- And having the abort() only go back to our signal handler again
- is less than optimal */
- if (core_signals[i] != SIGABRT) {
- sigaction(core_signals[i], &action,
- &all_signals[core_signals[i]].oldact);
- all_signals[core_signals[i]].installed++;
- }
- }
- }
-
- all_loops = g_slist_prepend(all_loops, loop);
-
- return loop;
-}
-
-void obt_main_loop_ref(ObtMainLoop *loop)
-{
- ++loop->ref;
-}
-
-void obt_main_loop_unref(ObtMainLoop *loop)
-{
- guint i;
- GSList *it, *next;
-
- if (loop && --loop->ref == 0) {
- g_assert(loop->running == FALSE);
-
- for (it = loop->x_handlers; it; it = next) {
- ObtMainLoopXHandlerType *h = it->data;
- next = g_slist_next(it);
- 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)) {
- ObtMainLoopTimer *t = it->data;
- if (t->destroy) t->destroy(t->data);
- g_slice_free(ObtMainLoopTimer, t);
- }
- g_slist_free(loop->timers);
- loop->timers = NULL;
-
- for (i = 0; i < NUM_SIGNALS; ++i)
- for (it = loop->signal_handlers[i]; it; it = next) {
- ObtMainLoopSignalHandlerType *h = it->data;
- next = g_slist_next(it);
- obt_main_loop_signal_remove(loop, h->func);
- }
-
- all_loops = g_slist_remove(all_loops, loop);
-
- /* only do this if we're the last loop destroyed */
- if (!all_loops) {
- /* grab all the signals that cause core dumps */
- for (i = 0; i < NUM_CORE_SIGNALS; ++i) {
- if (all_signals[core_signals[i]].installed) {
- sigaction(core_signals[i],
- &all_signals[core_signals[i]].oldact, NULL);
- all_signals[core_signals[i]].installed--;
- }
- }
- }
-
- g_slice_free(ObtMainLoop, loop);
- }
-}
-
-static void fd_handle_foreach(gpointer key,
- gpointer value,
- gpointer data)
-{
- ObtMainLoopFdHandlerType *h = value;
- fd_set *set = data;
-
- if (FD_ISSET(h->fd, set))
- h->func(h->fd, h->data);
-}
-
-void obt_main_loop_run(ObtMainLoop *loop)
-{
- XEvent e;
- struct timeval *wait;
- fd_set selset;
- GSList *it;
-
- loop->run = TRUE;
- loop->running = TRUE;
-
- while (loop->run) {
- if (loop->signal_fired) {
- guint i;
- sigset_t oldset;
-
- /* block signals so that we can do this without the data changing
- on us */
- sigprocmask(SIG_SETMASK, &all_signals_set, &oldset);
-
- for (i = 0; i < NUM_SIGNALS; ++i) {
- while (loop->signals_fired[i]) {
- for (it = loop->signal_handlers[i];
- it; it = g_slist_next(it)) {
- ObtMainLoopSignalHandlerType *h = it->data;
- h->func(i, h->data);
- }
- loop->signals_fired[i]--;
- }
- }
- loop->signal_fired = FALSE;
-
- sigprocmask(SIG_SETMASK, &oldset, NULL);
- } 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);
- }
- }
- } else {
- /* this only runs if there were no x events received */
- timer_dispatch(loop, (GTimeVal**)&wait);
-
- selset = loop->fd_set;
- /* there is a small race condition here. if a signal occurs
- between this if() and the select() then we will not process
- the signal until 'wait' expires. possible solutions include
- using GStaticMutex, and having the signal handler set 'wait'
- to 0 */
- if (!loop->signal_fired)
- select(loop->fd_max + 1, &selset, NULL, NULL, wait);
-
- /* handle the X events with highest prioirity */
- if (FD_ISSET(loop->fd_x, &selset))
- continue;
-
- g_hash_table_foreach(loop->fd_handlers,
- fd_handle_foreach, &selset);
- }
- }
-
- loop->running = FALSE;
-}
-
-void obt_main_loop_exit(ObtMainLoop *loop)
-{
- loop->run = FALSE;
-}
-
-/*** XEVENT WATCHERS ***/
-
-void obt_main_loop_x_add(ObtMainLoop *loop,
- ObtMainLoopXHandler handler,
- gpointer data,
- GDestroyNotify notify)
-{
- ObtMainLoopXHandlerType *h;
-
- 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)
-{
- GSList *it, *next;
-
- for (it = loop->x_handlers; it; it = next) {
- ObtMainLoopXHandlerType *h = it->data;
- next = g_slist_next(it);
- if (h->func == handler) {
- loop->x_handlers = g_slist_delete_link(loop->x_handlers, it);
- if (h->destroy) h->destroy(h->data);
- g_slice_free(ObtMainLoopXHandlerType, h);
- }
- }
-
- if (!loop->x_handlers) {
- FD_CLR(loop->fd_x, &loop->fd_set);
- calc_max_fd(loop);
- }
-}
-
-/*** SIGNAL WATCHERS ***/
-
-static void sighandler(gint sig)
-{
- GSList *it;
- guint i;
-
- g_return_if_fail(sig < NUM_SIGNALS);
-
- for (i = 0; i < NUM_CORE_SIGNALS; ++i)
- if (sig == core_signals[i]) {
- /* XXX special case for signals that default to core dump.
- but throw some helpful output here... */
-
- fprintf(stderr, "How are you gentlemen? All your base are"
- " belong to us. (Openbox received signal %d)\n", sig);
-
- /* die with a core dump */
- abort();
- }
-
- for (it = all_loops; it; it = g_slist_next(it)) {
- ObtMainLoop *loop = it->data;
- loop->signal_fired = TRUE;
- loop->signals_fired[sig]++;
- }
-}
-
-void obt_main_loop_signal_add(ObtMainLoop *loop,
- gint signal,
- ObtMainLoopSignalHandler handler,
- gpointer data,
- GDestroyNotify notify)
-{
- ObtMainLoopSignalHandlerType *h;
-
- g_return_if_fail(signal < NUM_SIGNALS);
-
- h = g_slice_new(ObtMainLoopSignalHandlerType);
- h->loop = loop;
- h->signal = signal;
- h->func = handler;
- h->data = data;
- h->destroy = notify;
- loop->signal_handlers[h->signal] =
- g_slist_prepend(loop->signal_handlers[h->signal], h);
-
- if (!all_signals[signal].installed) {
- struct sigaction action;
- sigset_t sigset;
-
- sigemptyset(&sigset);
- action.sa_handler = sighandler;
- action.sa_mask = sigset;
- action.sa_flags = SA_NOCLDSTOP;
-
- sigaction(signal, &action, &all_signals[signal].oldact);
- }
-
- all_signals[signal].installed++;
-}
-
-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) {
- ObtMainLoopSignalHandlerType *h = it->data;
-
- next = g_slist_next(it);
-
- if (h->func == handler) {
- g_assert(all_signals[h->signal].installed > 0);
-
- all_signals[h->signal].installed--;
- if (!all_signals[h->signal].installed) {
- sigaction(h->signal, &all_signals[h->signal].oldact, NULL);
- }
-
- loop->signal_handlers[i] =
- g_slist_delete_link(loop->signal_handlers[i], it);
- if (h->destroy) h->destroy(h->data);
-
- g_slice_free(ObtMainLoopSignalHandlerType, h);
- }
- }
- }
-
-}
-
-/*** FILE DESCRIPTOR WATCHERS ***/
-
-static void max_fd_func(gpointer key, gpointer value, gpointer data)
-{
- ObtMainLoop *loop = data;
-
- /* key is the fd */
- loop->fd_max = MAX(loop->fd_max, *(gint*)key);
-}
-
-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 obt_main_loop_fd_add(ObtMainLoop *loop,
- gint fd,
- ObtMainLoopFdHandler handler,
- gpointer data,
- GDestroyNotify notify)
-{
- ObtMainLoopFdHandlerType *h;
-
- h = g_slice_new(ObtMainLoopFdHandlerType);
- h->loop = loop;
- h->fd = fd;
- h->func = handler;
- h->data = data;
- h->destroy = notify;
-
- g_hash_table_replace(loop->fd_handlers, &h->fd, h);
- FD_SET(h->fd, &loop->fd_set);
- calc_max_fd(loop);
-}
-
-static void fd_handler_destroy(gpointer data)
-{
- ObtMainLoopFdHandlerType *h = data;
-
- FD_CLR(h->fd, &h->loop->fd_set);
-
- 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 ***/
-
-#define NEAREST_TIMEOUT(loop) \
- (((ObtMainLoopTimer*)(loop)->timers->data)->timeout)
-
-static glong timecompare(GTimeVal *a, GTimeVal *b)
-{
- glong r;
- if ((r = a->tv_sec - b->tv_sec)) return r;
- return a->tv_usec - b->tv_usec;
-}
-
-static void insert_timer(ObtMainLoop *loop, ObtMainLoopTimer *ins)
-{
- GSList *it;
- for (it = loop->timers; it; it = g_slist_next(it)) {
- ObtMainLoopTimer *t = it->data;
- if (timecompare(&ins->timeout, &t->timeout) <= 0) {
- loop->timers = g_slist_insert_before(loop->timers, it, ins);
- break;
- }
- }
- if (it == NULL) /* didnt fit anywhere in the list */
- loop->timers = g_slist_append(loop->timers, ins);
-}
-
-void obt_main_loop_timeout_add(ObtMainLoop *loop,
- gulong microseconds,
- GSourceFunc handler,
- gpointer data,
- GEqualFunc cmp,
- GDestroyNotify notify)
-{
- ObtMainLoopTimer *t = g_slice_new(ObtMainLoopTimer);
-
- g_assert(microseconds > 0); /* if it's 0 it'll cause an infinite loop */
-
- t->delay = microseconds;
- t->func = handler;
- t->data = data;
- t->equal = cmp;
- t->destroy = notify;
- t->del_me = FALSE;
- g_get_current_time(&loop->now);
- t->last = t->timeout = loop->now;
- g_time_val_add(&t->timeout, t->delay);
-
- insert_timer(loop, t);
-}
-
-void obt_main_loop_timeout_remove(ObtMainLoop *loop,
- GSourceFunc handler)
-{
- GSList *it;
-
- for (it = loop->timers; it; it = g_slist_next(it)) {
- ObtMainLoopTimer *t = it->data;
- if (t->func == handler)
- t->del_me = TRUE;
- }
-}
-
-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)) {
- ObtMainLoopTimer *t = it->data;
- if (t->func == handler && t->equal(t->data, data)) {
- t->del_me = TRUE;
- if (cancel_dest)
- t->destroy = NULL;
- }
- }
-}
-
-/* find the time to wait for the nearest timeout */
-static gboolean nearest_timeout_wait(ObtMainLoop *loop, GTimeVal *tm)
-{
- if (loop->timers == NULL)
- return FALSE;
-
- tm->tv_sec = NEAREST_TIMEOUT(loop).tv_sec - loop->now.tv_sec;
- tm->tv_usec = NEAREST_TIMEOUT(loop).tv_usec - loop->now.tv_usec;
-
- while (tm->tv_usec < 0) {
- tm->tv_usec += G_USEC_PER_SEC;
- tm->tv_sec--;
- }
- tm->tv_sec += tm->tv_usec / G_USEC_PER_SEC;
- tm->tv_usec %= G_USEC_PER_SEC;
- if (tm->tv_sec < 0)
- tm->tv_sec = 0;
-
- return TRUE;
-}
-
-static void timer_dispatch(ObtMainLoop *loop, GTimeVal **wait)
-{
- GSList *it, *next;
-
- gboolean fired = FALSE;
-
- g_get_current_time(&loop->now);
-
- for (it = loop->timers; it; it = next) {
- ObtMainLoopTimer *curr;
-
- next = g_slist_next(it);
-
- curr = it->data;
-
- /* since timer_stop doesn't actually free the timer, we have to do our
- real freeing in here.
- */
- if (curr->del_me) {
- /* delete the top */
- loop->timers = g_slist_delete_link(loop->timers, it);
- if (curr->destroy)
- curr->destroy(curr->data);
- g_slice_free(ObtMainLoopTimer, curr);
- continue;
- }
-
- /* the queue is sorted, so if this timer shouldn't fire, none are
- ready */
- if (timecompare(&NEAREST_TIMEOUT(loop), &loop->now) > 0)
- break;
-
- /* we set the last fired time to delay msec after the previous firing,
- then re-insert. timers maintain their order and may trigger more
- than once if they've waited more than one delay's worth of time.
- */
- loop->timers = g_slist_delete_link(loop->timers, it);
- g_time_val_add(&curr->last, curr->delay);
- if (curr->func(curr->data)) {
- g_time_val_add(&curr->timeout, curr->delay);
- insert_timer(loop, curr);
- } else {
- if (curr->destroy)
- curr->destroy(curr->data);
- g_slice_free(ObtMainLoopTimer, curr);
- }
-
- /* the timer queue has been shuffled, start from the beginning
- (which is the next one to fire) */
- next = loop->timers;
-
- fired = TRUE;
- }
-
- if (fired) {
- /* if at least one timer fires, then don't wait on X events, as there
- may already be some in the queue from the timer callbacks.
- */
- loop->ret_wait.tv_sec = loop->ret_wait.tv_usec = 0;
- *wait = &loop->ret_wait;
- } else if (nearest_timeout_wait(loop, &loop->ret_wait))
- *wait = &loop->ret_wait;
- else
- *wait = NULL;
-}
+++ /dev/null
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-
- obt/mainloop.h for the Openbox window manager
- Copyright (c) 2006 Mikael Magnusson
- Copyright (c) 2003-2007 Dana Jansens
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- See the COPYING file for a copy of the GNU General Public License.
-*/
-
-#ifndef __obt_mainloop_h
-#define __obt_mainloop_h
-
-#include <X11/Xlib.h>
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-typedef struct _ObtMainLoop ObtMainLoop;
-
-ObtMainLoop *obt_main_loop_new(void);
-void obt_main_loop_ref(ObtMainLoop *loop);
-void obt_main_loop_unref(ObtMainLoop *loop);
-
-typedef void (*ObtMainLoopXHandler) (const XEvent *e, gpointer data);
-
-void obt_main_loop_x_add(ObtMainLoop *loop,
- ObtMainLoopXHandler handler,
- gpointer data,
- GDestroyNotify notify);
-void obt_main_loop_x_remove(ObtMainLoop *loop,
- ObtMainLoopXHandler handler);
-
-typedef void (*ObtMainLoopFdHandler) (gint fd, gpointer data);
-
-void obt_main_loop_fd_add(ObtMainLoop *loop,
- gint fd,
- ObtMainLoopFdHandler handler,
- gpointer data,
- GDestroyNotify notify);
-void obt_main_loop_fd_remove(ObtMainLoop *loop,
- gint fd);
-
-typedef void (*ObtMainLoopSignalHandler) (gint signal, gpointer data);
-
-void obt_main_loop_signal_add(ObtMainLoop *loop,
- gint signal,
- ObtMainLoopSignalHandler handler,
- gpointer data,
- GDestroyNotify notify);
-void obt_main_loop_signal_remove(ObtMainLoop *loop,
- ObtMainLoopSignalHandler handler);
-
-void obt_main_loop_timeout_add(ObtMainLoop *loop,
- gulong microseconds,
- GSourceFunc handler,
- gpointer data,
- GEqualFunc cmp,
- GDestroyNotify notify);
-void obt_main_loop_timeout_remove(ObtMainLoop *loop,
- GSourceFunc handler);
-void obt_main_loop_timeout_remove_data(ObtMainLoop *loop,
- GSourceFunc handler,
- gpointer data,
- gboolean cancel_dest);
-
-void obt_main_loop_run(ObtMainLoop *loop);
-void obt_main_loop_exit(ObtMainLoop *loop);
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-
- obt/xevent.c for the Openbox window manager
- Copyright (c) 2007 Dana Jansens
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- See the COPYING file for a copy of the GNU General Public License.
-*/
-
-#include "obt/xevent.h"
-#include "obt/mainloop.h"
-#include "obt/util.h"
-
-typedef struct _ObtXEventBinding ObtXEventBinding;
-
-struct _ObtXEventHandler
-{
- gint ref;
- ObtMainLoop *loop;
-
- /* An array of hash tables where the key is the window, and the value is
- the ObtXEventBinding */
- GHashTable **bindings;
- gint num_event_types; /* the length of the bindings array */
-};
-
-struct _ObtXEventBinding
-{
- Window win;
- ObtXEventCallback func;
- gpointer data;
-};
-
-static void xevent_handler(const XEvent *e, gpointer data);
-static guint window_hash(Window *w) { return *w; }
-static gboolean window_comp(Window *w1, Window *w2) { return *w1 == *w2; }
-static void binding_free(gpointer b);
-
-ObtXEventHandler* xevent_new(void)
-{
- ObtXEventHandler *h;
-
- h = g_slice_new0(ObtXEventHandler);
- h->ref = 1;
-
- return h;
-}
-
-void xevent_ref(ObtXEventHandler *h)
-{
- ++h->ref;
-}
-
-void xevent_unref(ObtXEventHandler *h)
-{
- if (h && --h->ref == 0) {
- gint i;
-
- if (h->loop)
- 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);
-
- g_slice_free(ObtXEventHandler, h);
- }
-}
-
-void xevent_register(ObtXEventHandler *h, ObtMainLoop *loop)
-{
- h->loop = loop;
- obt_main_loop_x_add(loop, xevent_handler, h, NULL);
-}
-
-void xevent_set_handler(ObtXEventHandler *h, gint type, Window win,
- ObtXEventCallback func, gpointer data)
-{
- ObtXEventBinding *b;
-
- 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, binding_free);
- h->num_event_types = type + 1;
- }
-
- b = g_slice_new(ObtXEventBinding);
- b->win = win;
- b->func = func;
- b->data = data;
- g_hash_table_replace(h->bindings[type], &b->win, b);
-}
-
-static void binding_free(gpointer b)
-{
- g_slice_free(ObtXEventBinding, b);
-}
-
-void xevent_remove_handler(ObtXEventHandler *h, gint type, Window win)
-{
- g_assert(type < h->num_event_types);
- g_assert(win);
-
- g_hash_table_remove(h->bindings[type], &win);
-}
-
-static void xevent_handler(const XEvent *e, gpointer data)
-{
- ObtXEventHandler *h;
- ObtXEventBinding *b;
-
- h = data;
-
- if (e->type < h->num_event_types) {
- const gint all = OBT_XEVENT_ALL_WINDOWS;
- /* run the all_windows handler first */
- b = g_hash_table_lookup(h->bindings[e->xany.type], &all);
- if (b) b->func(e, b->data);
- /* then run the per-window handler */
- b = g_hash_table_lookup(h->bindings[e->xany.type], &e->xany.window);
- if (b) b->func(e, b->data);
- }
- else
- g_message("Unhandled X Event type %d", e->xany.type);
-}
+++ /dev/null
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-
- obt/xevent.h for the Openbox window manager
- Copyright (c) 2007 Dana Jansens
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- See the COPYING file for a copy of the GNU General Public License.
-*/
-
-#ifndef __obt_xevent_h
-#define __obt_xevent_h
-
-#include <X11/Xlib.h>
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-struct _ObtMainLoop;
-
-typedef struct _ObtXEventHandler ObtXEventHandler;
-
-typedef void (*ObtXEventCallback) (const XEvent *e, gpointer data);
-
-ObtXEventHandler* xevent_new(void);
-void xevent_ref(ObtXEventHandler *h);
-void xevent_unref(ObtXEventHandler *h);
-
-void xevent_register(ObtXEventHandler *h,
- struct _ObtMainLoop *loop);
-
-#define OBT_XEVENT_ALL_WINDOWS None
-
-void xevent_set_handler(ObtXEventHandler *h, gint type, Window win,
- ObtXEventCallback func, gpointer data);
-void xevent_remove_handler(ObtXEventHandler *h, gint type, Window win);
-
-G_END_DECLS
-
-#endif /*__obt_xevent_h*/
if (!qnum) read_events(FALSE);
return qnum != 0;
}
+
+typedef struct _ObtXQueueCB {
+ ObtXQueueFunc func;
+ gpointer data;
+} ObtXQueueCB;
+
+static ObtXQueueCB *callbacks = NULL;
+static guint n_callbacks = 0;
+
+static gboolean event_read(GIOChannel *s, GIOCondition cond, gpointer data)
+{
+ XEvent ev;
+
+ while (xqueue_next_local(&ev)) {
+ guint i;
+ for (i = 0; i < n_callbacks; ++i)
+ callbacks[i].func(&ev, callbacks[i].data);
+ }
+
+ return TRUE; /* repeat */
+}
+
+void xqueue_listen(void)
+{
+ GIOChannel *ch;
+
+ g_assert(obt_display != NULL);
+
+ ch = g_io_channel_unix_new(ConnectionNumber(obt_display));
+ g_io_add_watch(ch, G_IO_IN, event_read, NULL);
+ g_io_channel_unref(ch);
+}
+
+void xqueue_add_callback(ObtXQueueFunc f, gpointer data)
+{
+ guint i;
+
+ g_return_if_fail(f != NULL);
+
+ for (i = 0; i < n_callbacks; ++i)
+ if (callbacks[i].func == f && callbacks[i].data == data)
+ return;
+
+ callbacks = g_renew(ObtXQueueCB, callbacks, n_callbacks + 1);
+ callbacks[n_callbacks].func = f;
+ callbacks[n_callbacks].data = data;
+ ++n_callbacks;
+}
+
+void xqueue_remove_callback(ObtXQueueFunc f, gpointer data)
+{
+ guint i;
+
+ g_return_if_fail(f != NULL);
+
+ for (i = 0; i < n_callbacks; ++i) {
+ if (callbacks[i].func == f && callbacks[i].data == data) {
+ /* remove it */
+ for (; i < n_callbacks - 1; ++i)
+ callbacks[i] = callbacks[i+1];
+ callbacks = g_renew(ObtXQueueCB, callbacks, n_callbacks - 1);
+ --n_callbacks;
+ break;
+ }
+ }
+}
gboolean xqueue_remove_local(XEvent *event_return,
xqueue_match_func match, gpointer data);
+typedef void (*ObtXQueueFunc)(const XEvent *ev, gpointer data);
+
+/*! Begin listening for X events in the default GMainContext, and feed them
+ to the registered callback functions, added with xqueue_add_callback(). */
+void xqueue_listen(void);
+
+void xqueue_add_callback(ObtXQueueFunc f, gpointer data);
+void xqueue_remove_callback(ObtXQueueFunc f, gpointer data);
+
G_END_DECLS
#endif
ButtonMotionMask)
static ObDock *dock;
+static guint show_timeout_id;
+static guint hide_timeout_id;
StrutPartial dock_strut;
dock->hidden = TRUE;
dock_configure();
+ hide_timeout_id = 0;
+
return FALSE; /* don't repeat */
}
static gboolean show_timeout(gpointer data)
{
- /* hide */
+ /* show */
dock->hidden = FALSE;
dock_configure();
+ show_timeout_id = 0;
+
return FALSE; /* don't repeat */
}
{
if (!hide) {
if (dock->hidden && config_dock_hide) {
- obt_main_loop_timeout_add(ob_main_loop,
- config_dock_show_delay * 1000,
- show_timeout, NULL,
- g_direct_equal, NULL);
- } else if (!dock->hidden && config_dock_hide) {
- obt_main_loop_timeout_remove(ob_main_loop, hide_timeout);
+ show_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT,
+ config_dock_show_delay,
+ show_timeout, NULL, NULL);
+ } else if (!dock->hidden && config_dock_hide && hide_timeout_id) {
+ if (hide_timeout_id) g_source_remove(hide_timeout_id);
+ hide_timeout_id = 0;
}
} else {
if (!dock->hidden && config_dock_hide) {
- obt_main_loop_timeout_add(ob_main_loop,
- config_dock_hide_delay * 1000,
- hide_timeout, NULL,
- g_direct_equal, NULL);
- } else if (dock->hidden && config_dock_hide) {
- obt_main_loop_timeout_remove(ob_main_loop, show_timeout);
+ hide_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT,
+ config_dock_show_delay,
+ hide_timeout, NULL, NULL);
+ } else if (dock->hidden && config_dock_hide && show_timeout_id) {
+ if (show_timeout_id) g_source_remove(show_timeout_id);
+ show_timeout_id = 0;
}
}
}
static void event_ignore_enter_range(gulong start, gulong end);
static void focus_delay_dest(gpointer data);
-static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2);
+static void unfocus_delay_dest(gpointer data);
static gboolean focus_delay_func(gpointer data);
static gboolean unfocus_delay_func(gpointer data);
static void focus_delay_client_dest(ObClient *client, gpointer data);
static gboolean waiting_for_focusin = FALSE;
/*! A list of ObSerialRanges which are to be ignored for mouse enter events */
static GSList *ignore_serials = NULL;
+static guint focus_delay_timeout_id = 0;
+static ObClient *focus_delay_timeout_client = NULL;
+static guint unfocus_delay_timeout_id = 0;
+static ObClient *unfocus_delay_timeout_client = NULL;
#ifdef USE_SM
-static void ice_handler(gint fd, gpointer conn)
+static gboolean ice_handler(GIOChannel *source, GIOCondition cond,
+ gpointer conn)
{
Bool b;
IceProcessMessages(conn, NULL, &b);
+ return TRUE; /* don't remove the event source */
}
static void ice_watch(IceConn conn, IcePointer data, Bool opening,
IcePointer *watch_data)
{
- static gint fd = -1;
+ static guint id = 0;
if (opening) {
- fd = IceConnectionNumber(conn);
- obt_main_loop_fd_add(ob_main_loop, fd, ice_handler, conn, NULL);
- } else {
- obt_main_loop_fd_remove(ob_main_loop, fd);
- fd = -1;
+ GIOChannel *ch;
+
+ ch = g_io_channel_unix_new(IceConnectionNumber(conn));
+ id = g_io_add_watch(ch, G_IO_IN, ice_handler, conn);
+ g_io_channel_unref(ch);
+ } else if (id) {
+ g_source_remove(id);
+ id = 0;
}
}
#endif
{
if (reconfig) return;
- obt_main_loop_x_add(ob_main_loop, event_process, NULL, NULL);
+ xqueue_add_callback(event_process, NULL);
#ifdef USE_SM
IceAddConnectionWatch(ice_watch, NULL);
if (config_focus_delay) {
ObFocusDelayData *data;
- obt_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
+ if (focus_delay_timeout_id)
+ g_source_remove(focus_delay_timeout_id);
data = g_slice_new(ObFocusDelayData);
data->client = client;
data->time = event_time();
data->serial = event_curserial;
- obt_main_loop_timeout_add(ob_main_loop,
- config_focus_delay * 1000,
- focus_delay_func,
- data, focus_delay_cmp, focus_delay_dest);
+ focus_delay_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT,
+ config_focus_delay,
+ focus_delay_func,
+ data,
+ focus_delay_dest);
+ focus_delay_timeout_client = client;
} else {
ObFocusDelayData data;
data.client = client;
if (config_focus_delay) {
ObFocusDelayData *data;
- obt_main_loop_timeout_remove(ob_main_loop, unfocus_delay_func);
+ if (unfocus_delay_timeout_id)
+ g_source_remove(unfocus_delay_timeout_id);
data = g_slice_new(ObFocusDelayData);
data->client = client;
data->time = event_time();
data->serial = event_curserial;
- obt_main_loop_timeout_add(ob_main_loop,
- config_focus_delay * 1000,
- unfocus_delay_func,
- data, focus_delay_cmp, focus_delay_dest);
+ unfocus_delay_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT,
+ config_focus_delay,
+ unfocus_delay_func,
+ data,
+ unfocus_delay_dest);
+ unfocus_delay_timeout_client = client;
} else {
ObFocusDelayData data;
data.client = client;
delay is up */
e->xcrossing.detail != NotifyInferior)
{
- if (config_focus_delay)
- obt_main_loop_timeout_remove_data(ob_main_loop,
- focus_delay_func,
- client, FALSE);
+ if (config_focus_delay && focus_delay_timeout_id)
+ g_source_remove(focus_delay_timeout_id);
if (config_unfocus_leave)
event_leave_client(client);
}
e->xcrossing.serial,
(client?client->window:0));
if (config_focus_follow) {
- if (config_focus_delay)
- obt_main_loop_timeout_remove_data(ob_main_loop,
- unfocus_delay_func,
- client, FALSE);
+ if (config_focus_delay && unfocus_delay_timeout_id)
+ g_source_remove(unfocus_delay_timeout_id);
event_enter_client(client);
}
}
static void focus_delay_dest(gpointer data)
{
g_slice_free(ObFocusDelayData, data);
+ focus_delay_timeout_id = 0;
+ focus_delay_timeout_client = NULL;
}
-static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2)
+static void unfocus_delay_dest(gpointer data)
{
- const ObFocusDelayData *f1 = d1;
- return f1->client == d2;
+ g_slice_free(ObFocusDelayData, data);
+ unfocus_delay_timeout_id = 0;
+ unfocus_delay_timeout_client = NULL;
}
static gboolean focus_delay_func(gpointer data)
static void focus_delay_client_dest(ObClient *client, gpointer data)
{
- obt_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func,
- client, FALSE);
- obt_main_loop_timeout_remove_data(ob_main_loop, unfocus_delay_func,
- client, FALSE);
+ if (focus_delay_timeout_client == client && focus_delay_timeout_id)
+ g_source_remove(focus_delay_timeout_id);
+ if (unfocus_delay_timeout_client == client && unfocus_delay_timeout_id)
+ g_source_remove(unfocus_delay_timeout_id);
}
void event_halt_focus_delay(void)
{
/* ignore all enter events up till the event which caused this to occur */
if (event_curserial) event_ignore_enter_range(1, event_curserial);
- obt_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
- obt_main_loop_timeout_remove(ob_main_loop, unfocus_delay_func);
+ if (focus_delay_timeout_id) g_source_remove(focus_delay_timeout_id);
+ if (unfocus_delay_timeout_id) g_source_remove(unfocus_delay_timeout_id);
}
gulong event_start_ignore_all_enters(void)
EnterWindowMask | LeaveWindowMask)
#define FRAME_ANIMATE_ICONIFY_TIME 150000 /* .15 seconds */
-#define FRAME_ANIMATE_ICONIFY_STEP_TIME (G_USEC_PER_SEC / 60) /* 60 Hz */
+#define FRAME_ANIMATE_ICONIFY_STEP_TIME (1000 / 60) /* 60 Hz */
#define FRAME_HANDLE_Y(f) (f->size.top + f->client->area.height + f->cbwidth_b)
void frame_release_client(ObFrame *self)
{
/* if there was any animation going on, kill it */
- obt_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
- self, FALSE);
+ if (self->iconify_animation_timer)
+ g_source_remove(self->iconify_animation_timer);
/* check if the app has already reparented its window away */
if (!xqueue_exists_local(find_reparent, self)) {
window_remove(self->rgriptop);
window_remove(self->rgripbottom);
- obt_main_loop_timeout_remove_data(ob_main_loop, flash_timeout, self, TRUE);
+ if (self->flash_timer) g_source_remove(self->flash_timer);
}
/* is there anything present between us and the label? */
self->flash_on = self->focused;
if (!self->flashing)
- obt_main_loop_timeout_add(ob_main_loop,
- G_USEC_PER_SEC * 0.6,
- flash_timeout,
- self,
- g_direct_equal,
- flash_done);
+ self->flash_timer = g_timeout_add_full(G_PRIORITY_DEFAULT,
+ 600, flash_timeout, self,
+ flash_done);
g_get_current_time(&self->flash_end);
g_time_val_add(&self->flash_end, G_USEC_PER_SEC * 5);
}
if (new_anim) {
- obt_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
- self, FALSE);
- obt_main_loop_timeout_add(ob_main_loop,
- FRAME_ANIMATE_ICONIFY_STEP_TIME,
- frame_animate_iconify, self,
- g_direct_equal, NULL);
+ if (self->iconify_animation_timer)
+ g_source_remove(self->iconify_animation_timer);
+ self->iconify_animation_timer =
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ FRAME_ANIMATE_ICONIFY_STEP_TIME,
+ frame_animate_iconify, self, NULL);
+
/* do the first step */
frame_animate_iconify(self);
gboolean flashing;
gboolean flash_on;
GTimeVal flash_end;
+ guint flash_timer;
/*! Is the frame currently in an animation for iconify or restore.
0 means that it is not animating. > 0 means it is animating an iconify.
< 0 means it is animating a restore.
*/
gint iconify_animation_going;
+ guint iconify_animation_timer;
GTimeVal iconify_animation_end;
};
KeyBindingTree *keyboard_firstnode = NULL;
static ObPopup *popup = NULL;
static KeyBindingTree *curpos;
+static guint chain_timer = 0;
static void grab_keys(gboolean grab)
{
return FALSE; /* don't repeat */
}
+static void chain_done(gpointer data)
+{
+ chain_timer = 0;
+}
+
static void set_curpos(KeyBindingTree *newpos)
{
if (curpos == newpos) return;
a = screen_physical_area_primary(FALSE);
popup_position(popup, NorthWestGravity, a->x + 10, a->y + 10);
/* 1 second delay for the popup to show */
- popup_delay_show(popup, G_USEC_PER_SEC, text);
+ popup_delay_show(popup, 1000, text);
g_free(text);
} else {
popup_hide(popup);
if (e->xkey.keycode == config_keyboard_reset_keycode &&
mods == config_keyboard_reset_state)
{
- obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
+ if (chain_timer) g_source_remove(chain_timer);
keyboard_reset_chains(-1);
return TRUE;
}
menu_frame_hide_all();
if (p->first_child != NULL) { /* part of a chain */
- obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
+ if (chain_timer) g_source_remove(chain_timer);
/* 3 second timeout for chains */
- obt_main_loop_timeout_add(ob_main_loop, 3 * G_USEC_PER_SEC,
- chain_timeout, NULL,
- g_direct_equal, NULL);
+ chain_timer =
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ 3000, chain_timeout, NULL,
+ chain_done);
set_curpos(p);
} else if (p->chroot) /* an empty chroot */
set_curpos(p);
void keyboard_shutdown(gboolean reconfig)
{
- obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
+ if (chain_timer) g_source_remove(chain_timer);
keyboard_unbind_all();
set_curpos(NULL);
menu_can_hide = TRUE;
else {
menu_can_hide = FALSE;
- obt_main_loop_timeout_add(ob_main_loop,
- config_menu_hide_delay * 1000,
- menu_hide_delay_func,
- NULL, g_direct_equal, NULL);
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ config_menu_hide_delay,
+ menu_hide_delay_func,
+ NULL, NULL);
}
}
}
GHashTable *menu_frame_map;
static RrAppearance *a_sep;
+static guint submenu_show_timer = 0;
+static guint submenu_hide_timer = 0;
static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry,
ObMenuFrame *frame);
*/
static void remove_submenu_hide_timeout(ObMenuFrame *child)
{
- obt_main_loop_timeout_remove_data(ob_main_loop, submenu_hide_timeout,
- child, FALSE);
+ if (submenu_hide_timer) g_source_remove(submenu_hide_timer);
+ submenu_hide_timer = 0;
}
gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
if (config_submenu_show_delay) {
/* remove any submenu open requests */
- obt_main_loop_timeout_remove(ob_main_loop, submenu_show_timeout);
+ if (submenu_show_timer) g_source_remove(submenu_show_timer);
+ submenu_show_timer = 0;
}
if ((it = g_list_last(menu_frame_visible)))
menu_frame_hide(it->data);
if (config_submenu_show_delay) {
/* remove any submenu open requests */
- obt_main_loop_timeout_remove(ob_main_loop, submenu_show_timeout);
+ if (submenu_show_timer) g_source_remove(submenu_show_timer);
+ submenu_show_timer = 0;
}
self->selected = entry;
submenu */
if (immediate || config_submenu_hide_delay == 0)
menu_frame_hide(oldchild);
- else if (config_submenu_hide_delay > 0)
- obt_main_loop_timeout_add(ob_main_loop,
- config_submenu_hide_delay * 1000,
- submenu_hide_timeout,
- oldchild, g_direct_equal,
- NULL);
+ else if (config_submenu_hide_delay > 0) {
+ if (submenu_hide_timer) g_source_remove(submenu_hide_timer);
+ submenu_hide_timer =
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ config_submenu_hide_delay,
+ submenu_hide_timeout, oldchild, NULL);
+ }
}
}
if (oldchild_entry != self->selected) {
if (immediate || config_submenu_hide_delay == 0)
menu_entry_frame_show_submenu(self->selected);
- else if (config_submenu_hide_delay > 0)
- obt_main_loop_timeout_add(ob_main_loop,
- config_submenu_show_delay * 1000,
- submenu_show_timeout,
- self->selected, g_direct_equal,
- NULL);
+ else if (config_submenu_hide_delay > 0) {
+ if (submenu_show_timer)
+ g_source_remove(submenu_show_timer);
+ submenu_show_timer =
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ config_submenu_show_delay,
+ submenu_show_timeout,
+ self->selected, NULL);
+ }
}
/* hide the grandchildren of this menu. and move the cursor to
the current menu */
static guint32 corner;
static ObDirection edge_warp_dir = -1;
static gboolean edge_warp_odd = FALSE;
+static guint edge_warp_timer = 0;
static ObDirection key_resize_edge = -1;
#ifdef SYNC
static guint waiting_for_sync;
+static guint sync_timer = 0;
#endif
static ObPopup *popup = NULL;
moveresize_alarm = None;
}
- obt_main_loop_timeout_remove(ob_main_loop, sync_timeout_func);
+ if (sync_timer) g_source_remove(sync_timer);
+ sync_timer = 0;
#endif
}
waiting_for_sync = 1;
- obt_main_loop_timeout_remove(ob_main_loop, sync_timeout_func);
- obt_main_loop_timeout_add(ob_main_loop, G_USEC_PER_SEC * 2,
- sync_timeout_func,
- NULL, NULL, NULL);
+ if (sync_timer) g_source_remove(sync_timer);
+ sync_timer = g_timeout_add(2000, sync_timeout_func, NULL);
}
#endif
++waiting_for_sync; /* we timed out waiting for our sync... */
do_resize(); /* ...so let any pending resizes through */
- if (waiting_for_sync > SYNC_TIMEOUTS)
+ if (waiting_for_sync > SYNC_TIMEOUTS) {
+ sync_timer = 0;
return FALSE; /* don't repeat */
+ }
else
return TRUE; /* keep waiting */
}
cancel_edge_warp();
if (dir != (ObDirection)-1) {
edge_warp_odd = TRUE; /* switch on the first timeout */
- obt_main_loop_timeout_add(ob_main_loop,
- config_mouse_screenedgetime * 1000,
- edge_warp_delay_func,
- NULL, NULL, NULL);
+ edge_warp_timer = g_timeout_add(config_mouse_screenedgetime,
+ edge_warp_delay_func, NULL);
}
edge_warp_dir = dir;
}
static void cancel_edge_warp(void)
{
- obt_main_loop_timeout_remove(ob_main_loop, edge_warp_delay_func);
+ if (edge_warp_timer) g_source_remove(edge_warp_timer);
+ edge_warp_timer = 0;
}
static void move_with_keys(KeySym sym, guint state)
#include "obrender/render.h"
#include "obrender/theme.h"
#include "obt/display.h"
+#include "obt/xqueue.h"
#include "obt/prop.h"
#include "obt/keyboard.h"
#include "obt/xml.h"
RrInstance *ob_rr_inst;
RrImageCache *ob_rr_icons;
RrTheme *ob_rr_theme;
-ObtMainLoop *ob_main_loop;
+GMainLoop *ob_main_loop;
gint ob_screen;
gboolean ob_replace_wm = FALSE;
gboolean ob_sm_use = TRUE;
exit(EXIT_SUCCESS);
}
- ob_main_loop = obt_main_loop_new();
+ ob_main_loop = g_main_loop_new(NULL, FALSE);
/* set up signal handler */
- obt_main_loop_signal_add(ob_main_loop, SIGUSR1, signal_handler, NULL,NULL);
- obt_main_loop_signal_add(ob_main_loop, SIGUSR2, signal_handler, NULL,NULL);
- obt_main_loop_signal_add(ob_main_loop, SIGTERM, signal_handler, NULL,NULL);
- obt_main_loop_signal_add(ob_main_loop, SIGINT, signal_handler, NULL,NULL);
- obt_main_loop_signal_add(ob_main_loop, SIGHUP, signal_handler, NULL,NULL);
- obt_main_loop_signal_add(ob_main_loop, SIGPIPE, signal_handler, NULL,NULL);
- obt_main_loop_signal_add(ob_main_loop, SIGCHLD, signal_handler, NULL,NULL);
- obt_main_loop_signal_add(ob_main_loop, SIGTTIN, signal_handler, NULL,NULL);
- obt_main_loop_signal_add(ob_main_loop, SIGTTOU, signal_handler, NULL,NULL);
+// obt_main_loop_signal_add(ob_main_loop, SIGUSR1, signal_handler, NULL,NULL);
+// obt_main_loop_signal_add(ob_main_loop, SIGUSR2, signal_handler, NULL,NULL);
+// obt_main_loop_signal_add(ob_main_loop, SIGTERM, signal_handler, NULL,NULL);
+// obt_main_loop_signal_add(ob_main_loop, SIGINT, signal_handler, NULL,NULL);
+// obt_main_loop_signal_add(ob_main_loop, SIGHUP, signal_handler, NULL,NULL);
+// obt_main_loop_signal_add(ob_main_loop, SIGPIPE, signal_handler, NULL,NULL);
+// obt_main_loop_signal_add(ob_main_loop, SIGCHLD, signal_handler, NULL,NULL);
+// obt_main_loop_signal_add(ob_main_loop, SIGTTIN, signal_handler, NULL,NULL);
+// obt_main_loop_signal_add(ob_main_loop, SIGTTOU, signal_handler, NULL,NULL);
ob_screen = DefaultScreen(obt_display);
menu_startup(reconfigure);
prompt_startup(reconfigure);
+ /* do this after everything is started so no events will get
+ missed */
+ xqueue_listen();
+
if (!reconfigure) {
guint32 xid;
ObWindow *w;
}
}
- obt_main_loop_run(ob_main_loop);
+ g_main_loop_run(ob_main_loop);
ob_set_state(reconfigure ?
OB_STATE_RECONFIGURING : OB_STATE_EXITING);
void ob_exit(gint code)
{
exitcode = code;
- obt_main_loop_exit(ob_main_loop);
+ g_main_loop_quit(ob_main_loop);
}
void ob_exit_replace(void)
{
exitcode = 0;
being_replaced = TRUE;
- obt_main_loop_exit(ob_main_loop);
+ g_main_loop_quit(ob_main_loop);
}
Cursor ob_cursor(ObCursor cursor)
#include "obrender/render.h"
#include "obrender/theme.h"
-#include "obt/mainloop.h"
#include "obt/display.h"
#include <glib.h>
extern RrImageCache *ob_rr_icons;
extern RrTheme *ob_rr_theme;
-extern ObtMainLoop *ob_main_loop;
+extern GMainLoop *ob_main_loop;
/*! The number of the screen on which we're running */
extern gint ob_screen;
#include "event.h"
#include "debug.h"
#include "openbox.h"
-#include "obt/mainloop.h"
#include "obt/prop.h"
typedef struct _ObPingTarget
ObClient *client;
ObPingEventHandler h;
guint32 id;
+ guint loopid;
gint waiting;
} ObPingTarget;
static GHashTable *ping_ids = NULL;
static guint32 ping_next_id = 1;
-#define PING_TIMEOUT (G_USEC_PER_SEC * 3)
+#define PING_TIMEOUT 3000 /* in MS */
/*! Warn the user after this many PING_TIMEOUT intervals */
#define PING_TIMEOUT_WARN 2
t->client = client;
t->h = h;
- obt_main_loop_timeout_add(ob_main_loop, PING_TIMEOUT, ping_timeout,
- t, g_direct_equal, NULL);
+ t->loopid = g_timeout_add_full(G_PRIORITY_DEFAULT, PING_TIMEOUT,
+ ping_timeout, t, NULL);
/* act like we just timed out immediately, to start the pinging process
now instead of after the first delay. this makes sure the client
ends up in the ping_ids hash table now. */
if ((t = g_hash_table_find(ping_ids, find_client, client))) {
g_hash_table_remove(ping_ids, &t->id);
- obt_main_loop_timeout_remove_data(ob_main_loop, ping_timeout,
- t, FALSE);
+ g_source_remove(t->loopid);
g_slice_free(ObPingTarget, t);
}
stacking_raise(INTERNAL_AS_WINDOW(self));
self->mapped = TRUE;
self->delay_mapped = FALSE;
+ self->delay_timer = 0;
return FALSE; /* don't repeat */
}
-void popup_delay_show(ObPopup *self, gulong usec, gchar *text)
+void popup_delay_show(ObPopup *self, gulong msec, gchar *text)
{
gint l, t, r, b;
gint x, y, w, h;
/* do the actual showing */
if (!self->mapped) {
- if (usec) {
+ if (msec) {
/* don't kill previous show timers */
if (!self->delay_mapped) {
- obt_main_loop_timeout_add(ob_main_loop, usec,
- popup_show_timeout, self,
- g_direct_equal, NULL);
+ self->delay_timer =
+ g_timeout_add(msec, popup_show_timeout, self);
self->delay_mapped = TRUE;
}
} else {
event_end_ignore_all_enters(ignore_start);
} else if (self->delay_mapped) {
- obt_main_loop_timeout_remove_data(ob_main_loop, popup_show_timeout, self, FALSE);
+ g_source_remove(self->delay_timer);
+ self->delay_timer = 0;
self->delay_mapped = FALSE;
}
}
}
}
-void icon_popup_delay_show(ObIconPopup *self, gulong usec,
+void icon_popup_delay_show(ObIconPopup *self, gulong msec,
gchar *text, RrImage *icon)
{
if (icon) {
self->a_icon->texture[0].type = RR_TEXTURE_NONE;
}
- popup_delay_show(self->popup, usec, text);
+ popup_delay_show(self->popup, msec, text);
}
void icon_popup_icon_size_multiplier(ObIconPopup *self, guint wm, guint hm)
}
}
-void pager_popup_delay_show(ObPagerPopup *self, gulong usec,
+void pager_popup_delay_show(ObPagerPopup *self, gulong msec,
gchar *text, guint desk)
{
guint i;
self->desks = screen_num_desktops;
self->curdesk = desk;
- popup_delay_show(self->popup, usec, text);
+ popup_delay_show(self->popup, msec, text);
}
void pager_popup_icon_size_multiplier(ObPagerPopup *self, guint wm, guint hm)
guint iconhm; /* icon height multiplier. multipled by the normal height */
gboolean mapped;
gboolean delay_mapped;
+ guint delay_timer;
void (*draw_icon)(gint x, gint y, gint w, gint h, gpointer data);
gpointer draw_icon_data;
void popup_set_text_align(ObPopup *self, RrJustify align);
#define popup_show(s, t) popup_delay_show((s),0,(t))
-void popup_delay_show(ObPopup *self, gulong usec, gchar *text);
+void popup_delay_show(ObPopup *self, gulong msec, gchar *text);
void popup_hide(ObPopup *self);
RrAppearance *popup_icon_appearance(ObPopup *self);
void icon_popup_free(ObIconPopup *self);
#define icon_popup_show(s, t, i) icon_popup_delay_show((s),0,(t),(i))
-void icon_popup_delay_show(ObIconPopup *self, gulong usec,
+void icon_popup_delay_show(ObIconPopup *self, gulong msec,
gchar *text, RrImage *icon);
#define icon_popup_hide(p) popup_hide((p)->popup)
#define icon_popup_position(p, g, x, y) popup_position((p)->popup,(g),(x),(y))
void pager_popup_free(ObPagerPopup *self);
#define pager_popup_show(s, t, d) pager_popup_delay_show((s),0,(t),(d))
-void pager_popup_delay_show(ObPagerPopup *self, gulong usec,
+void pager_popup_delay_show(ObPagerPopup *self, gulong msec,
gchar *text, guint desk);
#define pager_popup_hide(p) popup_hide((p)->popup)
#define pager_popup_position(p, g, x, y) popup_position((p)->popup,(g),(x),(y))
#include "obt/display.h"
#include "obt/xqueue.h"
#include "obt/prop.h"
-#include "obt/mainloop.h"
#include <X11/Xlib.h>
#ifdef HAVE_UNISTD_H
static Size screen_physical_size;
static guint screen_old_desktop;
static gboolean screen_desktop_timeout = TRUE;
+static guint screen_desktop_timer = 0;
/*! An array of desktops, holding an array of areas per monitor */
static Rect *monitor_area = NULL;
/*! An array of desktops, holding an array of struts */
static GSList *struts_bottom = NULL;
static ObPagerPopup *desktop_popup;
+static guint desktop_popup_timer = 0;
static gboolean desktop_popup_perm;
/*! The number of microseconds that you need to be on a desktop before it will
replace the remembered "last desktop" */
-#define REMEMBER_LAST_DESKTOP_TIME 750000
+#define REMEMBER_LAST_DESKTOP_TIME 750
static gboolean replace_wm(void)
{
static gboolean last_desktop_func(gpointer data)
{
screen_desktop_timeout = TRUE;
- return FALSE;
+ screen_desktop_timer = 0;
+ return FALSE; /* don't repeat */
}
void screen_set_desktop(guint num, gboolean dofocus)
}
}
screen_desktop_timeout = FALSE;
- obt_main_loop_timeout_remove(ob_main_loop, last_desktop_func);
- obt_main_loop_timeout_add(ob_main_loop, REMEMBER_LAST_DESKTOP_TIME,
- last_desktop_func, NULL, NULL, NULL);
+ if (screen_desktop_timer) g_source_remove(screen_desktop_timer);
+ screen_desktop_timer = g_timeout_add(REMEMBER_LAST_DESKTOP_TIME,
+ last_desktop_func, NULL);
ob_debug("Moving to desktop %d", num+1);
static gboolean hide_desktop_popup_func(gpointer data)
{
pager_popup_hide(desktop_popup);
+ desktop_popup_timer = 0;
return FALSE; /* don't repeat */
}
MAX(a->width/3, POPUP_WIDTH));
pager_popup_show(desktop_popup, screen_desktop_names[d], d);
- obt_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
+ if (desktop_popup_timer) g_source_remove(desktop_popup_timer);
+ desktop_popup_timer = 0;
if (!perm && !desktop_popup_perm)
/* only hide if its not already being show permanently */
- obt_main_loop_timeout_add(ob_main_loop,
- config_desktop_popup_time * 1000,
- hide_desktop_popup_func, desktop_popup,
- g_direct_equal, NULL);
+ desktop_popup_timer = g_timeout_add(config_desktop_popup_time,
+ hide_desktop_popup_func,
+ desktop_popup);
if (perm)
desktop_popup_perm = TRUE;
}
void screen_hide_desktop_popup(void)
{
- obt_main_loop_timeout_remove_data(ob_main_loop, hide_desktop_popup_func,
- desktop_popup, FALSE);
+ if (desktop_popup_timer) g_source_remove(desktop_popup_timer);
+ desktop_popup_timer = 0;
pager_popup_hide(desktop_popup);
desktop_popup_perm = FALSE;
}
#include "startupnotify.h"
#include "gettext.h"
#include "event.h"
+#include "obt/xqueue.h"
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
sn_event_func, NULL, NULL);
sn_launcher = sn_launcher_context_new(sn_display, ob_screen);
- obt_main_loop_x_add(ob_main_loop, sn_handler, NULL, NULL);
+ xqueue_add_callback(sn_handler, NULL);
}
void sn_shutdown(gboolean reconfig)
if (reconfig) return;
- obt_main_loop_x_remove(ob_main_loop, sn_handler);
+ xqueue_remove_callback(sn_handler, NULL);
for (it = sn_waits; it; it = g_slist_next(it))
sn_startup_sequence_unref((SnStartupSequence*)it->data);
sn_waits = g_slist_prepend(sn_waits, seq);
/* 20 second timeout for apps to start if the launcher doesn't
have a timeout */
- obt_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC,
- sn_wait_timeout, seq,
- g_direct_equal,
- (GDestroyNotify)sn_startup_sequence_unref);
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ 20 * 1000, sn_wait_timeout, seq,
+ (GDestroyNotify)sn_startup_sequence_unref);
change = TRUE;
break;
case SN_MONITOR_EVENT_CHANGED:
case SN_MONITOR_EVENT_CANCELED:
if ((seq = sequence_find(sn_startup_sequence_get_id(seq)))) {
sn_waits = g_slist_remove(sn_waits, seq);
- obt_main_loop_timeout_remove_data(ob_main_loop, sn_wait_timeout,
- seq, FALSE);
+ g_source_remove_by_user_data(seq);
change = TRUE;
}
break;
/* 20 second timeout for apps to start */
sn_launcher_context_ref(sn_launcher);
- obt_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC,
- sn_launch_wait_timeout, sn_launcher,
- g_direct_equal,
- (GDestroyNotify)sn_launcher_context_unref);
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ 20 * 1000, sn_launch_wait_timeout, sn_launcher,
+ (GDestroyNotify)sn_launcher_context_unref);
setenv("DESKTOP_STARTUP_ID", id, TRUE);