X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=libchimara%2Fglk.c;h=f5df12ee4cc80c7fd88dd055bb11f91f52f6085f;hb=5cbd4d79bb8699746b85353d6ab25ee5c48174ff;hp=27e30072769198e0ec2a0ec2959ca0a0a5fee8d6;hpb=d5610e149e0384a24d00727a5815df12e85de026;p=projects%2Fchimara%2Fchimara.git
diff --git a/libchimara/glk.c b/libchimara/glk.c
index 27e3007..f5df12e 100644
--- a/libchimara/glk.c
+++ b/libchimara/glk.c
@@ -5,6 +5,7 @@
#include "chimara-glk.h"
#include "chimara-glk-private.h"
#include "gi_blorb.h"
+#include "window.h"
G_GNUC_INTERNAL GPrivate *glk_data_key = NULL;
@@ -44,18 +45,48 @@ glk_exit(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);
+ shutdown_glk_pre();
+
+ /* Find the biggest text buffer window */
+ winid_t win, largewin = NULL;
+ glui32 largearea = 0;
+ for(win = glk_window_iterate(NULL, NULL); win; win = glk_window_iterate(win, NULL)) {
+ if(win->type == wintype_TextBuffer) {
+ glui32 w, h;
+ if(!largewin) {
+ largewin = win;
+ glk_window_get_size(largewin, &w, &h);
+ largearea = w * h;
+ } else {
+ glk_window_get_size(win, &w, &h);
+ if(w * h > largearea) {
+ largewin = win;
+ largearea = w * h;
+ }
+ }
+ }
+ }
+ if(largewin) {
+ glk_set_window(largewin);
+ glk_set_style(style_Alert);
+ glk_put_string("\n");
+ glk_put_string(glk_data->final_message);
+ glk_put_string("\n");
+ flush_window_buffer(largewin);
}
+
+ g_mutex_lock(glk_data->shutdown_lock);
+ for(win = glk_window_iterate(NULL, NULL); win; win = glk_window_iterate(win, NULL)) {
+ if(win->type == wintype_TextGrid || win->type == wintype_TextBuffer)
+ g_signal_handler_unblock(win->widget, win->shutdown_keypress_handler);
+ }
+ g_cond_wait(glk_data->shutdown_key_pressed, glk_data->shutdown_lock);
+ g_mutex_unlock(glk_data->shutdown_lock);
+
+ shutdown_glk_post();
+ g_signal_emit_by_name(glk_data->self, "stopped");
+
g_thread_exit(NULL);
}
@@ -69,8 +100,10 @@ glk_exit(void)
* all. So you can call it often.
*
*
- * In a virtual machine interpreter, once per opcode is appropriate. In a
- * program with lots of computation, pick a comparable rate.
+ * In a virtual machine interpreter, once per opcode is appropriate. A more
+ * parsimonious approach would be once per branch and function call opcode;
+ * this guarantees it will be called inside loops. In a program with lots of
+ * computation, pick a comparable rate.
*
*
* glk_tick() does not try to update the screen, or check for player input, or
@@ -91,8 +124,8 @@ glk_exit(void)
* loop, this is critical. In a C program, you can often eyeball it.
*
* But the next version of model.c will have a
- * glk_tick() in the ornate printing loop of verb_yada().
- * Just to make the point.
+ * glk_tick() in the ornate printing loop of
+ * verb_yada(). Just to make the point.
*
*
*/