Implemented the signals 'char-input', 'line-input', and 'text-buffer-output' on the...
authorfliep <fliep@ddfedd41-794f-dd11-ae45-00112f111e67>
Sun, 11 Oct 2009 20:49:05 +0000 (20:49 +0000)
committerfliep <fliep@ddfedd41-794f-dd11-ae45-00112f111e67>
Sun, 11 Oct 2009 20:49:05 +0000 (20:49 +0000)
libchimara/.svnignore
libchimara/Makefile.am
libchimara/chimara-glk.c
libchimara/chimara-glk.h
libchimara/chimara-marshallers.txt [new file with mode: 0644]
libchimara/input.c
libchimara/strio.c
tests/main.c

index cffa6011938a6e005629995bedceb8d6d46e44ce..98cf102edf4032b66bb01e80dce41646663a8d53 100644 (file)
@@ -1,4 +1,7 @@
+
 .deps
 .libs
 Makefile
 Makefile.in
+chimara-marshallers.c
+chimara-marshallers.h
index 64e6ebc5b7286331ed45a71f41a12934f7937c22..dd205572ef70029867e2ea653d3dff0cb7ee5c07 100644 (file)
@@ -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
index e0b60592b2e842ff988e35f53c5cb4fd8c70e184..3f5c71b91030cf738f114d1480287e920f7a7666 100644 (file)
@@ -8,6 +8,7 @@
 #include <pango/pango.h>
 #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:
index 87a3f758d205e4f2b34c04fc4f9086c55786bc2c..78ea8deae477e6b593f52d946a20a05f9972fd06 100644 (file)
 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 (file)
index 0000000..d4fccc5
--- /dev/null
@@ -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
index 44334b40f660c9e6c9316508cace9541985438ba..80455ecd64cd42b9184885776071778dfee4a279 100644 (file)
@@ -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);
 }
 
index 4d410cdfbaa344c61cf772b841a506bda7ea7c7b..3153e3ee4c0b6282c0750e25541bb9a4d17e278e 100644 (file)
@@ -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. */
index 4acd4ed4072d13e6e312462c0ee338eb6e91a415..9ed6158f2245e49593f63e87e820ec33a8cf463d 100644 (file)
@@ -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;
        }