6 #include "chimara-glk-private.h"
9 extern GPrivate *glk_data_key;
12 * glk_set_interrupt_handler:
13 * @func: A pointer to an interrupt handler function.
15 * Sets @func to be the interrupt handler. @func should be a pointer to a
16 * function which takes no argument and returns no result. If Glk receives an
17 * interrupt, and you have set an interrupt handler, your handler will be
18 * called, before the process is shut down.
20 * Initially there is no interrupt handler. You can reset to not having any by
21 * calling <code>#glk_set_interrupt_handler(%NULL)</code>.
23 * If you call glk_set_interrupt_handler() with a new handler function while an
24 * older one is set, the new one replaces the old one. Glk does not try to queue
27 * You should not try to interact with the player in your interrupt handler. Do
28 * not call glk_select() or glk_select_poll(). Anything you print to a window
29 * may not be visible to the player.
32 glk_set_interrupt_handler(void (*func)(void))
34 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
35 glk_data->interrupt_handler = func;
38 /* Internal function: abort this Glk program, freeing resources and calling the
39 user's interrupt handler. */
43 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
44 if(glk_data->interrupt_handler)
45 (*(glk_data->interrupt_handler))();
50 /* Internal function: check if the Glk program has been interrupted. */
54 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
55 g_mutex_lock(glk_data->abort_lock);
56 if(glk_data->abort_signalled)
58 g_mutex_unlock(glk_data->abort_lock);
61 g_mutex_unlock(glk_data->abort_lock);
64 /* Internal function: do any cleanup for shutting down the Glk library. */
68 ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
71 glk_request_timer_events(0);
73 /* Cancel any pending input requests and flush all window buffers */
75 for(win = glk_window_iterate(NULL, NULL); win; win = glk_window_iterate(win, NULL))
77 switch(win->input_request_type)
79 case INPUT_REQUEST_CHARACTER:
80 case INPUT_REQUEST_CHARACTER_UNICODE:
81 glk_cancel_char_event(win);
83 case INPUT_REQUEST_LINE:
84 case INPUT_REQUEST_LINE_UNICODE:
85 glk_cancel_line_event(win, NULL);
87 case INPUT_REQUEST_NONE:
89 ; /* Handle mouse and hyperlink requests */
92 flush_window_buffer(win);
95 /* Close any open resource files */
96 if(glk_data->resource_map != NULL) {
97 giblorb_destroy_map(glk_data->resource_map);
98 glk_stream_close(glk_data->resource_file, NULL);
101 /* Unref the input queues */
102 g_async_queue_unref(glk_data->char_input_queue);
103 g_async_queue_unref(glk_data->line_input_queue);
105 /* Wait for any pending window rearrange */
106 g_mutex_lock(glk_data->arrange_lock);
107 if(glk_data->needs_rearrange)
108 g_cond_wait(glk_data->rearranged, glk_data->arrange_lock);
109 g_mutex_unlock(glk_data->arrange_lock);
111 /* Default handler for 'stopped' unloads the plugin, so be absolutely sure
112 we're not calling any dispatch callbacks after this point */
113 if(!glk_data->in_startup)
114 g_signal_emit_by_name(glk_data->self, "stopped");
116 _chimara_glk_free_nonwindow_private_data(glk_data);
117 glk_data->needs_reset = TRUE;