- Feeding input programmatically to the Glk program now works: chimara_glk_feed_line_...
[rodin/chimara.git] / libchimara / abort.c
index 61234a06f5743747687e6fbf397763dae528598c..aa8ed732bddfe4eab579d2be9847196e0e907364 100644 (file)
@@ -1,10 +1,11 @@
+#include "abort.h"
 #include "event.h"
 #include <glib.h>
 #include <gtk/gtk.h>
 
 #include "chimara-glk-private.h"
 
-extern ChimaraGlkPrivate *glk_data;
+extern GPrivate *glk_data_key;
 
 /**
  * glk_set_interrupt_handler:
@@ -29,38 +30,27 @@ extern ChimaraGlkPrivate *glk_data;
 void
 glk_set_interrupt_handler(void (*func)(void))
 {
+       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
        glk_data->interrupt_handler = func;
 }
 
 /* Internal function: abort this Glk program, freeing resources and calling the
 user's interrupt handler. */
 static void
-abort_glk()
+abort_glk(void)
 {
+       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
        if(glk_data->interrupt_handler)
                (*(glk_data->interrupt_handler))();
-       g_signal_emit_by_name(glk_data->self, "stopped");
+       shutdown_glk();
        g_thread_exit(NULL);
 }
 
-/* Internal function: Signal this Glk thread to abort. Does nothing if the abort
-mutex has already been freed. (That means the thread already ended.) */
-void
-signal_abort()
-{
-       if(glk_data && glk_data->abort_lock) {
-               g_mutex_lock(glk_data->abort_lock);
-               glk_data->abort_signalled = TRUE;
-               g_mutex_unlock(glk_data->abort_lock);
-               /* Stop blocking on the event queue condition */
-               event_throw(evtype_Abort, NULL, 0, 0);
-       }
-}
-
 /* Internal function: check if the Glk program has been interrupted. */
 void
-check_for_abort()
+check_for_abort(void)
 {
+       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
        g_mutex_lock(glk_data->abort_lock);
        if(glk_data->abort_signalled) 
        {
@@ -69,3 +59,26 @@ check_for_abort()
        }
        g_mutex_unlock(glk_data->abort_lock);
 }
+
+/* Internal function: do any cleanup for shutting down the Glk library. */
+void
+shutdown_glk(void)
+{
+       ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+               
+       if(!glk_data->in_startup)
+               g_signal_emit_by_name(glk_data->self, "stopped");
+
+       /* Stop any timers */
+       glk_request_timer_events(0);
+
+       /* Close any open resource files */
+       if(glk_data->resource_map != NULL) {
+               giblorb_destroy_map(glk_data->resource_map);
+               glk_stream_close(glk_data->resource_file, NULL);
+       }
+       
+       /* Unref the input queues */
+       g_async_queue_unref(glk_data->char_input_queue);
+       g_async_queue_unref(glk_data->line_input_queue);
+}