From 636666718ffafd18a9890bd9d1580842644c61ee Mon Sep 17 00:00:00 2001 From: fliep Date: Sun, 11 Oct 2009 20:49:05 +0000 Subject: [PATCH] Implemented the signals 'char-input', 'line-input', and 'text-buffer-output' on the ChimaraGlk widget. --- libchimara/.svnignore | 3 +++ libchimara/Makefile.am | 11 +++++++- libchimara/chimara-glk.c | 43 ++++++++++++++++++++++++++++++ libchimara/chimara-glk.h | 18 ++++++------- libchimara/chimara-marshallers.txt | 5 ++++ libchimara/input.c | 38 ++++++++++++++++++-------- libchimara/strio.c | 4 +++ tests/main.c | 23 +++++++++++++++- 8 files changed, 122 insertions(+), 23 deletions(-) create mode 100644 libchimara/chimara-marshallers.txt diff --git a/libchimara/.svnignore b/libchimara/.svnignore index cffa601..98cf102 100644 --- a/libchimara/.svnignore +++ b/libchimara/.svnignore @@ -1,4 +1,7 @@ + .deps .libs Makefile Makefile.in +chimara-marshallers.c +chimara-marshallers.h diff --git a/libchimara/Makefile.am b/libchimara/Makefile.am index 64e6ebc..dd20557 100644 --- a/libchimara/Makefile.am +++ b/libchimara/Makefile.am @@ -9,6 +9,8 @@ libchimara_la_SOURCES = \ case.c \ charset.c charset.h \ chimara-glk.c chimara-glk.h chimara-glk-private.h \ + chimara-if.c chimara-if.h \ + chimara-marshallers.c chimara-marshallers.h \ dispatch.c \ event.c event.h \ fileref.c fileref.h \ @@ -49,4 +51,11 @@ libchimara_include_HEADERS = \ gi_blorb.h \ garglk.h -EXTRA_DIST = doc.c glkstart.c +BUILT_SOURCES = chimara-marshallers.c chimara-marshallers.h +chimara-marshallers.c: chimara-marshallers.txt + glib-genmarshal --body --prefix=chimara_marshal $< > $@ + +chimara-marshallers.h: chimara-marshallers.txt + glib-genmarshal --header --prefix=chimara_marshal $< > $@ + +EXTRA_DIST = doc.c glkstart.c chimara-marshallers.txt diff --git a/libchimara/chimara-glk.c b/libchimara/chimara-glk.c index e0b6059..3f5c71b 100644 --- a/libchimara/chimara-glk.c +++ b/libchimara/chimara-glk.c @@ -8,6 +8,7 @@ #include #include "chimara-glk.h" #include "chimara-glk-private.h" +#include "chimara-marshallers.h" #include "glk.h" #include "abort.h" #include "window.h" @@ -58,6 +59,9 @@ enum { enum { STOPPED, STARTED, + CHAR_INPUT, + LINE_INPUT, + TEXT_BUFFER_OUTPUT, LAST_SIGNAL }; @@ -545,6 +549,24 @@ chimara_glk_started(ChimaraGlk *self) /* TODO: Add default signal handler implementation here */ } +static void +chimara_glk_char_input(ChimaraGlk *self, guint window_rock, guint keysym) +{ + /* TODO: Add default signal handler */ +} + +static void +chimara_glk_line_input(ChimaraGlk *self, guint window_rock, gchar *text) +{ + /* TODO: Add default signal handler */ +} + +static void +chimara_glk_text_buffer_output(ChimaraGlk *self, guint window_rock, gchar *text) +{ + /* TODO: Add default signal handler */ +} + /* G_PARAM_STATIC_STRINGS only appeared in GTK 2.13.0 */ #ifndef G_PARAM_STATIC_STRINGS #define G_PARAM_STATIC_STRINGS (G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB) @@ -569,6 +591,9 @@ chimara_glk_class_init(ChimaraGlkClass *klass) /* Signals */ klass->stopped = chimara_glk_stopped; klass->started = chimara_glk_started; + klass->char_input = chimara_glk_char_input; + klass->line_input = chimara_glk_line_input; + klass->text_buffer_output = chimara_glk_text_buffer_output; /** * ChimaraGlk::stopped: * @glk: The widget that received the signal @@ -592,6 +617,24 @@ chimara_glk_class_init(ChimaraGlkClass *klass) G_STRUCT_OFFSET(ChimaraGlkClass, started), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + chimara_glk_signals[CHAR_INPUT] = g_signal_new("char-input", + G_OBJECT_CLASS_TYPE(klass), 0, + G_STRUCT_OFFSET(ChimaraGlkClass, char_input), NULL, NULL, + chimara_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + + chimara_glk_signals[LINE_INPUT] = g_signal_new("line-input", + G_OBJECT_CLASS_TYPE(klass), 0, + G_STRUCT_OFFSET(ChimaraGlkClass, line_input), NULL, NULL, + chimara_marshal_VOID__UINT_STRING, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING); + + chimara_glk_signals[TEXT_BUFFER_OUTPUT] = g_signal_new("text-buffer-output", + G_OBJECT_CLASS_TYPE(klass), 0, + G_STRUCT_OFFSET(ChimaraGlkClass, text_buffer_output), NULL, NULL, + chimara_marshal_VOID__UINT_STRING, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING); + /* Properties */ /** * ChimaraGlk:interactive: diff --git a/libchimara/chimara-glk.h b/libchimara/chimara-glk.h index 87a3f75..78ea8de 100644 --- a/libchimara/chimara-glk.h +++ b/libchimara/chimara-glk.h @@ -10,16 +10,11 @@ G_BEGIN_DECLS #define CHIMARA_TYPE_GLK (chimara_glk_get_type()) -#define CHIMARA_GLK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - CHIMARA_TYPE_GLK, ChimaraGlk)) -#define CHIMARA_GLK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \ - CHIMARA_TYPE_GLK, ChimaraGlkClass)) -#define CHIMARA_IS_GLK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ - CHIMARA_TYPE_GLK)) -#define CHIMARA_IS_GLK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \ - CHIMARA_TYPE_GLK)) -#define CHIMARA_GLK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \ - CHIMARA_TYPE_GLK, ChimaraGlkClass)) +#define CHIMARA_GLK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CHIMARA_TYPE_GLK, ChimaraGlk)) +#define CHIMARA_GLK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CHIMARA_TYPE_GLK, ChimaraGlkClass)) +#define CHIMARA_IS_GLK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CHIMARA_TYPE_GLK)) +#define CHIMARA_IS_GLK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CHIMARA_TYPE_GLK)) +#define CHIMARA_GLK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CHIMARA_TYPE_GLK, ChimaraGlkClass)) /** * ChimaraGlk: @@ -37,6 +32,9 @@ typedef struct _ChimaraGlkClass { /* Signals */ void(* stopped) (ChimaraGlk *self); void(* started) (ChimaraGlk *self); + void(* char_input) (ChimaraGlk *self, guint32 window_rock, guint keysym); + void(* line_input) (ChimaraGlk *self, guint32 window_rock, gchar *text); + void(* text_buffer_output) (ChimaraGlk *self, guint32 window_rock, gchar *text); } ChimaraGlkClass; GType chimara_glk_get_type(void) G_GNUC_CONST; diff --git a/libchimara/chimara-marshallers.txt b/libchimara/chimara-marshallers.txt new file mode 100644 index 0000000..d4fccc5 --- /dev/null +++ b/libchimara/chimara-marshallers.txt @@ -0,0 +1,5 @@ +# Extra callback marshallers for chimara +# Run this file through glib-genmarshal to create chimara-marshallers.c +VOID:UINT,UINT +VOID:UINT,STRING +VOID:STRING,STRING diff --git a/libchimara/input.c b/libchimara/input.c index 44334b4..80455ec 100644 --- a/libchimara/input.c +++ b/libchimara/input.c @@ -6,8 +6,8 @@ extern GPrivate *glk_data_key; /* Forward declarations */ -static int flush_text_buffer(winid_t win); -static int flush_text_grid(winid_t win); +static int finish_text_buffer_line_input(winid_t win, gboolean emit_signal); +static int finish_text_grid_line_input(winid_t win, gboolean emit_signal); /* Internal function: code common to both flavors of char event request */ void @@ -344,11 +344,11 @@ glk_cancel_line_event(winid_t win, event_t *event) if(win->type == wintype_TextGrid) { g_signal_handler_block( G_OBJECT(win->widget), win->keypress_handler ); - chars_written = flush_text_grid(win); + chars_written = finish_text_grid_line_input(win, FALSE); } else if(win->type == wintype_TextBuffer) { GtkTextBuffer *window_buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) ); g_signal_handler_block(window_buffer, win->insert_text_handler); - chars_written = flush_text_buffer(win); + chars_written = finish_text_buffer_line_input(win, FALSE); } ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key); @@ -446,8 +446,11 @@ on_window_key_press_event(GtkWidget *widget, GdkEventKey *event, winid_t win) keycode = keycode_Unknown; } - event_throw(CHIMARA_GLK(gtk_widget_get_ancestor(widget, CHIMARA_TYPE_GLK)), evtype_CharInput, win, keycode, 0); - + ChimaraGlk *glk = CHIMARA_GLK(gtk_widget_get_ancestor(widget, CHIMARA_TYPE_GLK)); + g_assert(glk); + event_throw(glk, evtype_CharInput, win, keycode, 0); + g_signal_emit_by_name(glk, "char-input", win->rock, event->keyval); + /* Only one keypress will be handled */ win->input_request_type = INPUT_REQUEST_NONE; g_signal_handler_block( G_OBJECT(win->widget), win->keypress_handler ); @@ -506,7 +509,7 @@ write_to_window_buffer(winid_t win, const gchar *inserted_text) /* Internal function: Retrieves the input of a TextBuffer window and stores it in the window buffer. * Returns the number of characters written, suitable for inclusion in a line input event. */ static int -flush_text_buffer(winid_t win) +finish_text_buffer_line_input(winid_t win, gboolean emit_signal) { VALID_WINDOW(win, return 0); g_return_val_if_fail(win->type == wintype_TextBuffer, 0); @@ -528,6 +531,12 @@ flush_text_buffer(winid_t win) gchar* inserted_text = gtk_text_buffer_get_text(window_buffer, &start_iter, &end_iter, FALSE); int chars_written = write_to_window_buffer(win, inserted_text); + if(emit_signal) + { + ChimaraGlk *glk = CHIMARA_GLK(gtk_widget_get_ancestor(win->widget, CHIMARA_TYPE_GLK)); + g_assert(glk); + g_signal_emit_by_name(glk, "line-input", win->rock, inserted_text); + } g_free(inserted_text); return chars_written; @@ -536,7 +545,7 @@ flush_text_buffer(winid_t win) /* Internal function: Retrieves the input of a TextGrid window and stores it in the window buffer. * Returns the number of characters written, suitable for inclusion in a line input event. */ static int -flush_text_grid(winid_t win) +finish_text_grid_line_input(winid_t win, gboolean emit_signal) { VALID_WINDOW(win, return 0); g_return_val_if_fail(win->type == wintype_TextGrid, 0); @@ -565,6 +574,12 @@ flush_text_grid(winid_t win) g_free(text_to_insert); int chars_written = write_to_window_buffer(win, text); + if(emit_signal) + { + ChimaraGlk *glk = CHIMARA_GLK(gtk_widget_get_ancestor(win->widget, CHIMARA_TYPE_GLK)); + g_assert(glk); + g_signal_emit_by_name(glk, "line-input", win->rock, text); + } g_free(text); return chars_written; @@ -587,8 +602,9 @@ after_window_insert_text(GtkTextBuffer *textbuffer, GtkTextIter *location, gchar /* Make the window uneditable again and retrieve the text that was input */ gtk_text_view_set_editable(GTK_TEXT_VIEW(win->widget), FALSE); - int chars_written = flush_text_buffer(win); - event_throw(CHIMARA_GLK(gtk_widget_get_ancestor(win->widget, CHIMARA_TYPE_GLK)), evtype_LineInput, win, chars_written, 0); + int chars_written = finish_text_buffer_line_input(win, TRUE); + ChimaraGlk *glk = CHIMARA_GLK(gtk_widget_get_ancestor(win->widget, CHIMARA_TYPE_GLK)); + event_throw(glk, evtype_LineInput, win, chars_written, 0); } } @@ -599,7 +615,7 @@ on_input_entry_activate(GtkEntry *input_entry, winid_t win) { g_signal_handler_block( G_OBJECT(win->widget), win->keypress_handler ); - int chars_written = flush_text_grid(win); + int chars_written = finish_text_grid_line_input(win, TRUE); event_throw(CHIMARA_GLK(gtk_widget_get_ancestor(win->widget, CHIMARA_TYPE_GLK)), evtype_LineInput, win, chars_written, 0); } diff --git a/libchimara/strio.c b/libchimara/strio.c index 4d410cd..3153e3e 100644 --- a/libchimara/strio.c +++ b/libchimara/strio.c @@ -80,6 +80,10 @@ write_utf8_to_window(winid_t win, gchar *s) gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, s, -1, win->window_stream->style, NULL); gdk_threads_leave(); + + ChimaraGlk *glk = CHIMARA_GLK(gtk_widget_get_ancestor(win->widget, CHIMARA_TYPE_GLK)); + g_assert(glk); + g_signal_emit_by_name(glk, "text-buffer-output", win->rock, s); } /* Internal function: write a Latin-1 buffer with length to a stream. */ diff --git a/tests/main.c b/tests/main.c index 4acd4ed..9ed6158 100644 --- a/tests/main.c +++ b/tests/main.c @@ -62,6 +62,24 @@ on_stopped(ChimaraGlk *glk) g_printerr("Stopped!\n"); } +static void +on_char_input(ChimaraGlk *glk, guint32 window_rock, guint keysym) +{ + g_printerr("Character input in window %d: key %d\n", window_rock, keysym); +} + +static void +on_line_input(ChimaraGlk *glk, guint32 window_rock, gchar *text) +{ + g_printerr("Line input in window %d: '%s'\n", window_rock, text); +} + +static void +on_text_buffer_output(ChimaraGlk *glk, guint32 window_rock, gchar *text) +{ + g_printerr("Text buffer output in window %d: '%s'\n", window_rock, text); +} + static GObject * load_object(const gchar *name) { @@ -115,6 +133,9 @@ create_window(void) chimara_glk_set_monospace_font_string(CHIMARA_GLK(glk), "Monospace 12"); g_signal_connect(glk, "started", G_CALLBACK(on_started), NULL); g_signal_connect(glk, "stopped", G_CALLBACK(on_stopped), NULL); + g_signal_connect(glk, "char-input", G_CALLBACK(on_char_input), NULL); + g_signal_connect(glk, "line-input", G_CALLBACK(on_line_input), NULL); + g_signal_connect(glk, "text-buffer-output", G_CALLBACK(on_text_buffer_output), NULL); GtkBox *vbox = GTK_BOX( gtk_builder_get_object(builder, "vbox") ); if(vbox == NULL) @@ -154,7 +175,7 @@ main(int argc, char *argv[]) g_object_unref( G_OBJECT(builder) ); g_object_unref( G_OBJECT(uimanager) ); - if( !chimara_glk_run(CHIMARA_GLK(glk), "../interpreters/glulxe/.libs/glulxe.so", argc, argv, &error) ) { + if( !chimara_glk_run(CHIMARA_GLK(glk), "../interpreters/frotz/.libs/frotz.so", argc, argv, &error) ) { error_dialog(GTK_WINDOW(window), error, "Error starting Glk library: "); return 1; } -- 2.30.2