X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=libchimara%2Fevent.c;h=18f7281bfa9899dd71d0e385e4107b66eb11bcdb;hb=fabc4f9b35b4d4e1bb3c3f67971e8e134889c453;hp=1bcdcd9b872ab26a0f3e581d68bf2b8e87eee5c5;hpb=2090f5576f520435b22417c3246ad2286d95a391;p=projects%2Fchimara%2Fchimara.git diff --git a/libchimara/event.c b/libchimara/event.c index 1bcdcd9..18f7281 100644 --- a/libchimara/event.c +++ b/libchimara/event.c @@ -8,7 +8,7 @@ #include "chimara-glk.h" #include "chimara-glk-private.h" -extern GPrivate *glk_data_key; +extern GPrivate glk_data_key; #define EVENT_TIMEOUT_MICROSECONDS (3000000) @@ -23,18 +23,16 @@ event_throw(ChimaraGlk *glk, glui32 type, winid_t win, glui32 val1, glui32 val2) if(!priv->event_queue) return; - GTimeVal timeout; - g_get_current_time(&timeout); - g_time_val_add(&timeout, EVENT_TIMEOUT_MICROSECONDS); + gint64 timeout = g_get_monotonic_time() + EVENT_TIMEOUT_MICROSECONDS; - g_mutex_lock(priv->event_lock); + g_mutex_lock(&priv->event_lock); /* Wait for room in the event queue */ while( g_queue_get_length(priv->event_queue) >= EVENT_QUEUE_MAX_LENGTH ) - if( !g_cond_timed_wait(priv->event_queue_not_full, priv->event_lock, &timeout) ) + if( !g_cond_wait_until(&priv->event_queue_not_full, &priv->event_lock, timeout) ) { - /* Drop the event after 3 seconds */ - g_mutex_unlock(priv->event_lock); + /* Drop the event if the event queue is still not emptying */ + g_mutex_unlock(&priv->event_lock); return; } @@ -46,9 +44,9 @@ event_throw(ChimaraGlk *glk, glui32 type, winid_t win, glui32 val1, glui32 val2) g_queue_push_head(priv->event_queue, event); /* Signal that there is an event */ - g_cond_signal(priv->event_queue_not_empty); + g_cond_signal(&priv->event_queue_not_empty); - g_mutex_unlock(priv->event_lock); + g_mutex_unlock(&priv->event_lock); } /* Helper function: Wait for an event in the event queue. If it is a forced @@ -58,23 +56,23 @@ event_throw(ChimaraGlk *glk, glui32 type, winid_t win, glui32 val1, glui32 val2) static void get_appropriate_event(event_t *event) { - ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key); - - g_mutex_lock(glk_data->event_lock); + ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key); + + g_mutex_lock(&glk_data->event_lock); event_t *retrieved_event = NULL; /* Wait for an event */ if( g_queue_is_empty(glk_data->event_queue) ) - g_cond_wait(glk_data->event_queue_not_empty, glk_data->event_lock); + g_cond_wait(&glk_data->event_queue_not_empty, &glk_data->event_lock); retrieved_event = g_queue_pop_tail(glk_data->event_queue); /* Signal that the event queue is no longer full */ - g_cond_signal(glk_data->event_queue_not_full); - - g_mutex_unlock(glk_data->event_lock); - + g_cond_signal(&glk_data->event_queue_not_full); + + g_mutex_unlock(&glk_data->event_lock); + if(retrieved_event->type == evtype_ForcedCharInput) { /* Check for forced character input in the queue */ @@ -90,10 +88,10 @@ get_appropriate_event(event_t *event) else { get_appropriate_event(event); - g_mutex_lock(glk_data->event_lock); + g_mutex_lock(&glk_data->event_lock); g_queue_push_tail(glk_data->event_queue, retrieved_event); - g_cond_signal(glk_data->event_queue_not_empty); - g_mutex_unlock(glk_data->event_lock); + g_cond_signal(&glk_data->event_queue_not_empty); + g_mutex_unlock(&glk_data->event_lock); } } else if(retrieved_event->type == evtype_ForcedLineInput) @@ -111,10 +109,10 @@ get_appropriate_event(event_t *event) else { get_appropriate_event(event); - g_mutex_lock(glk_data->event_lock); + g_mutex_lock(&glk_data->event_lock); g_queue_push_tail(glk_data->event_queue, retrieved_event); - g_cond_signal(glk_data->event_queue_not_empty); - g_mutex_unlock(glk_data->event_lock); + g_cond_signal(&glk_data->event_queue_not_empty); + g_mutex_unlock(&glk_data->event_lock); } } else @@ -147,11 +145,15 @@ glk_select(event_t *event) { g_return_if_fail(event != NULL); - ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key); - - /* Emit the "waiting" signal to let listeners know we are ready for input */ - g_signal_emit_by_name(glk_data->self, "waiting"); - + /* Flush all window buffers */ + winid_t win; + for(win = glk_window_iterate(NULL, NULL); win != NULL; win = glk_window_iterate(win, NULL)) { + if(win->type == wintype_TextBuffer || win->type == wintype_TextGrid) + flush_window_buffer(win); + } + + ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key); + get_appropriate_event(event); /* Check for interrupt */ @@ -232,12 +234,15 @@ glk_select_poll(event_t *event) { g_return_if_fail(event != NULL); - ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key); - + ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key); + event->type = evtype_None; - - g_mutex_lock(glk_data->event_lock); - + event->win = NULL; + event->val1 = 0; + event->val2 = 0; + + g_mutex_lock(&glk_data->event_lock); + if( !g_queue_is_empty(glk_data->event_queue) ) { GList *link; @@ -250,14 +255,14 @@ glk_select_poll(event_t *event) memcpy(event, link->data, sizeof(event_t)); g_free(link->data); g_queue_delete_link(glk_data->event_queue, link); - g_cond_signal(glk_data->event_queue_not_full); + g_cond_signal(&glk_data->event_queue_not_full); break; } } } - - g_mutex_unlock(glk_data->event_lock); - + + g_mutex_unlock(&glk_data->event_lock); + /* Check for interrupt */ glk_tick();