From 736fcc1c96235189b1069b7356cc620aba38acca Mon Sep 17 00:00:00 2001 From: Sasha Vasko <sasha@aftercode.net> Date: Sun, 24 Nov 2013 18:59:48 -0600 Subject: [PATCH 08/18] added more dbus crap in hopes of getting it to work: timeouts and dispatches --- libAfterBase/timer.c | 21 +++++++---- libAfterBase/timer.h | 1 + src/afterstep/asinternals.h | 1 + src/afterstep/dbus.c | 72 ++++++++++++++++++++++++++++++++++--- src/afterstep/events.c | 1 + 5 files changed, 85 insertions(+), 11 deletions(-) diff --git a/libAfterBase/timer.c b/libAfterBase/timer.c index a62a5b04..20920c2f 100644 --- a/libAfterBase/timer.c +++ b/libAfterBase/timer.c @@ -121,6 +121,15 @@ timer_subtract_times (time_t * sec1, time_t * usec1, time_t sec2, time_t usec2) *sec1 = sec; } +void tv_add_ms(struct timeval *tv, time_t ms) { + tv->tv_sec += ms/1000; + tv->tv_usec += 1000*(ms%1000); + if (tv->tv_usec > 1000000L){ + tv->tv_usec -= 1000000L; + tv->tv_sec += 1; + } +} + Bool timer_delay_till_next_alarm (time_t * sec, time_t * usec) { Timer *timer; @@ -142,12 +151,12 @@ Bool timer_delay_till_next_alarm (time_t * sec, time_t * usec) LOCAL_DEBUG_OUT( "next : sec = %ld, usec = %ld( curr %ld, %ld)", tsec, tusec, *sec, *usec ); timer_subtract_times (&tsec, &tusec, *sec, *usec); LOCAL_DEBUG_OUT( "waiting for sec = %ld, usec = %ld( curr %ld, %ld)", tsec, tusec, *sec, *usec ); - + *sec = tsec; *usec = tusec; if (tsec < 0 || tusec < 0) - { - *sec = 0 ; + { + *sec = 0 ; *usec = 1; } return True; @@ -163,9 +172,9 @@ Bool timer_handle (void) for (timer = timer_first; timer != NULL; timer = timer->next) if (timer->sec < sec || (timer->sec == sec && timer->usec <= usec)) { /* oldest event gets executed first ! */ - if( good_timer != NULL ) + if( good_timer != NULL ) if( good_timer->sec < timer->sec || (timer->sec == good_timer->sec && timer->usec > good_timer->usec )) - continue; + continue; good_timer = timer ; } if (good_timer != NULL) @@ -195,7 +204,7 @@ Bool timer_remove_by_data (void *data) return success; } -void +void timer_remove_all () { while(timer_first != NULL) diff --git a/libAfterBase/timer.h b/libAfterBase/timer.h index 411a3e80..ac1d3287 100644 --- a/libAfterBase/timer.h +++ b/libAfterBase/timer.h @@ -46,6 +46,7 @@ Bool timer_handle (void); Bool timer_remove_by_data (void *data); void timer_remove_all (); Bool timer_find_by_data (void *data); +void tv_add_ms(struct timeval *tv, time_t msec); #ifdef __cplusplus } diff --git a/src/afterstep/asinternals.h b/src/afterstep/asinternals.h index 71a95851..eccb51f4 100644 --- a/src/afterstep/asinternals.h +++ b/src/afterstep/asinternals.h @@ -577,6 +577,7 @@ typedef struct ASDBusFd { int asdbus_init(); ASVector* asdbus_getFds(); +void asdbus_handleDispatches (); void asdbus_shutdown(); void asdbus_process_messages (ASDBusFd*); diff --git a/src/afterstep/dbus.c b/src/afterstep/dbus.c index b0efe7a9..23cf72bf 100644 --- a/src/afterstep/dbus.c +++ b/src/afterstep/dbus.c @@ -111,9 +111,10 @@ typedef struct ASDBusContext { char *gnomeSessionPath; Bool sessionManagerCanShutdown; int kdeSessionVersion; + ASBiDirList *dispatches; } ASDBusContext; -static ASDBusContext ASDBus = { NULL, NULL, NULL, NULL, False, 0 }; +static ASDBusContext ASDBus = { NULL, NULL, NULL, NULL, False, 0, NULL }; static DBusHandlerResult asdbus_handle_message (DBusConnection *, DBusMessage *, void *); @@ -250,10 +251,51 @@ static void toggle_watch(DBusWatch *w, void *data) remove_watch(w, data); } +static void queue_dispatch(DBusConnection *connection, DBusDispatchStatus new_status, void *data){ + if (new_status == DBUS_DISPATCH_DATA_REMAINS){ + append_bidirelem (ASDBus.dispatches, data); + } +} + +static void asdbus_handle_timer (void *vdata) { + dbus_timeout_handle (vdata); +} + +static void asdbus_set_dbus_timer (struct timeval *expires, DBusTimeout *timeout) { + int interval = dbus_timeout_get_interval(timeout); + gettimeofday (expires, NULL); + tv_add_ms(expires, interval); + timer_new (interval, asdbus_handle_timer, timeout); +} + +static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data){ + /* add expiration data to timeout */ + struct timeval *expires = dbus_malloc(sizeof(struct timeval)); + if (!expires) + return FALSE; + dbus_timeout_set_data(timeout, expires, dbus_free); + + asdbus_set_dbus_timer (expires, timeout); + return TRUE; +} + +static void toggle_timeout(DBusTimeout *timeout, void *data){ + /* reset expiration data */ + struct timeval *expires = dbus_timeout_get_data(timeout); + timer_remove_by_data (timeout); + + asdbus_set_dbus_timer (expires, timeout); +} + +static void remove_timeout(DBusTimeout *timeout, void *data){ + timer_remove_by_data (timeout); +} + +void asdbus_dispatch_destroy (void *data) { + + +} -/******************************************************************************/ -/* External interfaces : */ -/******************************************************************************/ static _asdbus_add_match (DBusConnection *conn, const char* iface, const char* member) { char match[256]; sprintf(match, "type='signal',interface='%s',member='%s'", iface, member); @@ -266,9 +308,15 @@ static _asdbus_add_match (DBusConnection *conn, const char* iface, const char* m } } +/******************************************************************************/ +/* External interfaces : */ +/******************************************************************************/ Bool asdbus_init () { /* return connection unix fd */ char *tmp; + if (!ASDBus.dispatches) + ASDBus.dispatches = create_asbidirlist(asdbus_dispatch_destroy); + if (!ASDBus.session_conn) { ASDBus.session_conn = _asdbus_get_session_connection(); if (!dbus_connection_set_watch_functions(ASDBus.session_conn, add_watch, remove_watch, toggle_watch, ASDBus.session_conn, NULL)) { @@ -277,6 +325,9 @@ Bool asdbus_init () _asdbus_add_match (ASDBus.session_conn, IFACE_SESSION_PRIVATE, "QueryEndSession"); _asdbus_add_match (ASDBus.session_conn, IFACE_SESSION_PRIVATE, "EndSession"); _asdbus_add_match (ASDBus.session_conn, IFACE_SESSION_PRIVATE, "Stop"); + dbus_connection_set_timeout_functions(ASDBus.session_conn, add_timeout, remove_timeout, toggle_timeout, NULL, NULL); + dbus_connection_set_dispatch_status_function(ASDBus.session_conn, queue_dispatch, NULL, NULL); + //queue_dispatch(ASDBus.session_conn, dbus_connection_get_dispatch_status(ASDBus.session_conn), NULL); } if (!ASDBus.system_conn){ @@ -301,6 +352,15 @@ ASVector* asdbus_getFds() { return ASDBus.watchFds; } +void asdbus_handleDispatches (){ + void *data; + while ((data = extract_first_bidirelem (ASDBus.dispatches)) != NULL){ + while (dbus_connection_get_dispatch_status(data) == DBUS_DISPATCH_DATA_REMAINS){ + dbus_connection_dispatch(data); + } + } +} + void asdbus_shutdown () { if (ASDBus.session_conn) @@ -320,7 +380,9 @@ Bool get_gnome_autosave () #ifdef HAVE_GIOLIB static Bool g_types_inited = False; if (!g_types_inited) { - g_type_init(); +#if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION <= 35 && GLIB_MICRO_VERSION <= 0) + g_type_init (); +#endif g_types_inited = True; } if (ASDBus.gnomeSessionPath) { diff --git a/src/afterstep/events.c b/src/afterstep/events.c index dcdcecb5..7a5b5aa8 100644 --- a/src/afterstep/events.c +++ b/src/afterstep/events.c @@ -1856,6 +1856,7 @@ void afterstep_wait_pipes_input (int timeout_sec) break; } } + asdbus_handleDispatches (); } } -- 2.22.0