Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various Bugfixes #64

Merged
merged 4 commits into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions libchimara/abort.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,73 @@ shutdown_glk_post(void)
glk_data->unregister_arr = NULL;
#endif
}

static gboolean
emit_waiting_signal(ChimaraGlk *glk)
{
g_signal_emit_by_name(glk, "waiting");
return G_SOURCE_REMOVE;
}

static gboolean
emit_stopped_signal(ChimaraGlk *glk)
{
g_signal_emit_by_name(glk, "stopped");
return G_SOURCE_REMOVE;
}

void
shutdown_glk_full(void)
{
ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);

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);
}

/* Wait for a keypress if any text grid or buffer windows are open */
gboolean should_wait = FALSE;
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);
should_wait = TRUE;
}
}
if (should_wait) {
gdk_threads_add_idle((GSourceFunc)emit_waiting_signal, glk_data->self);
if (glk_data->interactive)
g_cond_wait(&glk_data->shutdown_key_pressed, &glk_data->shutdown_lock);
}
g_mutex_unlock(&glk_data->shutdown_lock);

shutdown_glk_post();

gdk_threads_add_idle((GSourceFunc)emit_stopped_signal, glk_data->self);
}
1 change: 1 addition & 0 deletions libchimara/abort.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
G_GNUC_INTERNAL void check_for_abort(void);
G_GNUC_INTERNAL void shutdown_glk_pre(void);
G_GNUC_INTERNAL void shutdown_glk_post(void);
G_GNUC_INTERNAL void shutdown_glk_full(void);

#endif

3 changes: 3 additions & 0 deletions libchimara/chimara-glk-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "chimara-glk.h"
#include "glk.h"
#include "glkstart.h"
#include "gi_blorb.h"
#include "gi_dispa.h"

Expand Down Expand Up @@ -91,6 +92,8 @@ struct _ChimaraGlkPrivate {
gchar *program_name;
gchar *program_info;
gchar *story_name;
/* Startup args (have Glk program lifetime) */
glkunix_startup_t args;
/* User-defined interrupt handler */
void (*interrupt_handler)(void);
/* Global tree of all windows */
Expand Down
29 changes: 14 additions & 15 deletions libchimara/chimara-glk.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <gmodule.h>
#include <gtk/gtk.h>

#include "abort.h"
#include "chimara-glk-private.h"
#include "chimara-marshallers.h"
#include "event.h"
Expand Down Expand Up @@ -550,6 +551,10 @@ chimara_glk_finalize(GObject *object)
g_free(priv->glk_styles);
g_clear_pointer(&priv->thread, g_thread_unref);

for (size_t ix = 0; ix < priv->args.argc; ix++)
g_free(priv->args.argv[ix]);
g_free(priv->args.argv);

/* Chain up to parent */
G_OBJECT_CLASS(chimara_glk_parent_class)->finalize(object);
}
Expand Down Expand Up @@ -1359,17 +1364,12 @@ chimara_glk_get_spacing(ChimaraGlk *self)
struct StartupData {
glk_main_t glk_main;
glkunix_startup_code_t glkunix_startup_code;
glkunix_startup_t args;
ChimaraGlkPrivate *glk_data;
};

static void
free_startup_data(struct StartupData *startup)
{
int i = 0;
while(i < startup->args.argc)
g_free(startup->args.argv[i++]);
g_free(startup->args.argv);
g_slice_free(struct StartupData, startup);
}

Expand All @@ -1392,26 +1392,26 @@ glk_enter(struct StartupData *startup)
g_async_queue_ref(startup->glk_data->char_input_queue);
g_async_queue_ref(startup->glk_data->line_input_queue);

gdk_threads_add_idle((GSourceFunc)emit_started_signal, startup->glk_data->self);

/* Run startup function */
if(startup->glkunix_startup_code) {
startup->glk_data->in_startup = TRUE;
int result = startup->glkunix_startup_code(&startup->args);
int result = startup->glkunix_startup_code(&startup->glk_data->args);
startup->glk_data->in_startup = FALSE;

if(!result) {
free_startup_data(startup);
shutdown_glk_full();
return NULL;
}
}

gdk_threads_add_idle((GSourceFunc)emit_started_signal, startup->glk_data->self);

/* Run main function */
glk_main_t glk_main = startup->glk_main;
free_startup_data(startup);
glk_main();
glk_exit(); /* Run shutdown code in glk_exit() even if glk_main() returns normally */
g_assert_not_reached(); /* because glk_exit() calls g_thread_exit() */
shutdown_glk_full();
return NULL;
}

Expand Down Expand Up @@ -1501,15 +1501,14 @@ chimara_glk_run(ChimaraGlk *self, const gchar *plugin, int argc, char *argv[], G
glkunix_argumentlist_t *glkunix_arguments;

if( !(g_module_symbol(priv->program, "glkunix_arguments", (gpointer *) &glkunix_arguments)
&& parse_command_line(glkunix_arguments, argc, argv, &startup->args)) )
{
&& parse_command_line(glkunix_arguments, argc, argv, &priv->args))) {
/* arguments could not be parsed, so create data ourselves */
startup->args.argc = 1;
startup->args.argv = g_new0(gchar *, 1);
priv->args.argc = 1;
priv->args.argv = g_new0(gchar *, 1);
}

/* Set the program invocation name */
startup->args.argv[0] = g_strdup(plugin);
priv->args.argv[0] = g_strdup(plugin);
}
startup->glk_data = priv;

Expand Down
14 changes: 7 additions & 7 deletions libchimara/doc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3670,36 +3670,36 @@
/**
* giblorb_ID_Copyright:
*
* Resource usage constant representing the copyright message (date and holder,
* Chunk type constant representing the copyright message (date and holder,
* without the actual copyright symbol). There should only be one such chunk per
* file.
*/

/**
* giblorb_ID_AUTH:
*
* Resource usage constant representing the name of the author or creator of the
* Chunk type constant representing the name of the author or creator of the
* file. This could be a login name on multi-user systems, for example. There
* should only be one such chunk per file.
*/

/**
* giblorb_ID_ANNO:
*
* Resource usage constant representing any textual annotation that the user or
* Chunk type constant representing any textual annotation that the user or
* writing program sees fit to include.
*/
*/

/**
* giblorb_ID_TEXT:
*
* Resource usage constant representing a text data file.
* Chunk type constant representing a text data file.
*/

/**
* giblorb_ID_BINA:
*
* Resource usage constant representing a binary data file.
* Chunk type constant representing a binary data file.
*/

/**
Expand Down
71 changes: 1 addition & 70 deletions libchimara/glk.c
Original file line number Diff line number Diff line change
@@ -1,27 +1,9 @@
#include <glib.h>

#include "abort.h"
#include "chimara-glk-private.h"
#include "strio.h"
#include "ui-message.h"
#include "window.h"

G_GNUC_INTERNAL GPrivate glk_data_key = G_PRIVATE_INIT(NULL);

static gboolean
emit_waiting_signal(ChimaraGlk *glk)
{
g_signal_emit_by_name(glk, "waiting");
return G_SOURCE_REMOVE;
}

static gboolean
emit_stopped_signal(ChimaraGlk *glk)
{
g_signal_emit_by_name(glk, "stopped");
return G_SOURCE_REMOVE;
}

/**
* glk_exit:
*
Expand Down Expand Up @@ -56,58 +38,7 @@ emit_stopped_signal(ChimaraGlk *glk)
void
glk_exit(void)
{
ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);

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);
}

/* Wait for a keypress if any text grid or buffer windows are open */
gboolean should_wait = FALSE;
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);
should_wait = TRUE;
}
}
if (should_wait) {
gdk_threads_add_idle((GSourceFunc)emit_waiting_signal, glk_data->self);
if (glk_data->interactive)
g_cond_wait(&glk_data->shutdown_key_pressed, &glk_data->shutdown_lock);
}
g_mutex_unlock(&glk_data->shutdown_lock);

shutdown_glk_post();

gdk_threads_add_idle((GSourceFunc)emit_stopped_signal, glk_data->self);

shutdown_glk_full();
g_thread_exit(NULL);
}

Expand Down
6 changes: 5 additions & 1 deletion libchimara/glkunix.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,11 @@ parse_command_line(glkunix_argumentlist_t glkunix_arguments[], int argc, char *a
}
}
}


for (size_t ix = 0; ix < data->argc; ix++)
g_free(data->argv[ix]);
g_free(data->argv);

data->argc = g_slist_length(arglist) + 1;
data->argv = g_new0(char *, data->argc);
arglist = g_slist_reverse(arglist);
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/glkunit.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ glk_main(void)
struct TestDescription *test = tests;
int total, tested, failed = 0;

printf("TAP version 13\n");

/* Print test plan. Use stdio.h to print to stdout, Glk can't do that */
for(total = 0; tests[total].name != NULL; total++)
; /* count tests for test plan*/
Expand Down
Loading