X-Git-Url: https://git.stderr.nl/gitweb?p=rodin%2Fchimara.git;a=blobdiff_plain;f=libchimara%2Fchimara-glk.c;h=625460243e7caa9579e2b2138f29993b8464a2d9;hp=f0d946d87a9f7be77df5c74cdb51d08dd1e0d84d;hb=268cb7d6d08efc2fcbe52aa7b1e0d27ec19b6dc0;hpb=1c04c8a0a43723e3de4a7f495b76cb26fd93e0c4 diff --git a/libchimara/chimara-glk.c b/libchimara/chimara-glk.c index f0d946d..6254602 100644 --- a/libchimara/chimara-glk.c +++ b/libchimara/chimara-glk.c @@ -125,6 +125,9 @@ enum { PROP_INTERACTIVE, PROP_PROTECT, PROP_SPACING, + PROP_PROGRAM_NAME, + PROP_PROGRAM_INFO, + PROP_STORY_NAME }; enum { @@ -134,6 +137,7 @@ enum { CHAR_INPUT, LINE_INPUT, TEXT_BUFFER_OUTPUT, + ILIAD_SCREEN_UPDATE, LAST_SIGNAL }; @@ -152,8 +156,8 @@ chimara_glk_init(ChimaraGlk *self) priv->self = self; priv->interactive = TRUE; priv->protect = FALSE; - priv->default_styles = g_new0(StyleSet,1); - priv->current_styles = g_new0(StyleSet,1); + priv->styles = g_new0(StyleSet,1); + priv->glk_styles = g_new0(StyleSet,1); priv->pager_attr_list = pango_attr_list_new(); priv->final_message = g_strdup("[ The game has finished ]"); priv->running = FALSE; @@ -178,6 +182,9 @@ chimara_glk_init(ChimaraGlk *self) priv->resource_loaded = g_cond_new(); priv->resource_info_available = g_cond_new(); priv->image_cache = NULL; + priv->program_name = NULL; + priv->program_info = NULL; + priv->story_name = NULL; priv->interrupt_handler = NULL; priv->root_window = NULL; priv->fileref_list = NULL; @@ -227,7 +234,16 @@ chimara_glk_get_property(GObject *object, guint prop_id, GValue *value, GParamSp case PROP_SPACING: g_value_set_uint(value, priv->spacing); break; - default: + case PROP_PROGRAM_NAME: + g_value_set_string(value, priv->program_name); + break; + case PROP_PROGRAM_INFO: + g_value_set_string(value, priv->program_info); + break; + case PROP_STORY_NAME: + g_value_set_string(value, priv->story_name); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } } @@ -241,10 +257,10 @@ chimara_glk_finalize(GObject *object) /* Free widget properties */ g_free(priv->final_message); /* Free styles */ - g_hash_table_destroy(priv->default_styles->text_buffer); - g_hash_table_destroy(priv->default_styles->text_grid); - g_hash_table_destroy(priv->current_styles->text_buffer); - g_hash_table_destroy(priv->current_styles->text_grid); + g_hash_table_destroy(priv->styles->text_buffer); + g_hash_table_destroy(priv->styles->text_grid); + g_hash_table_destroy(priv->glk_styles->text_buffer); + g_hash_table_destroy(priv->glk_styles->text_grid); pango_attr_list_unref(priv->pager_attr_list); /* Free the event queue */ @@ -286,6 +302,9 @@ chimara_glk_finalize(GObject *object) /* Free other stuff */ g_free(priv->current_dir); + g_free(priv->program_name); + g_free(priv->program_info); + g_free(priv->story_name); /* Chain up to parent */ G_OBJECT_CLASS(chimara_glk_parent_class)->finalize(object); @@ -630,6 +649,12 @@ chimara_glk_stopped(ChimaraGlk *self) { CHIMARA_GLK_USE_PRIVATE(self, priv); priv->running = FALSE; + priv->program_name = NULL; + g_object_notify(G_OBJECT(self), "program-name"); + priv->program_info = NULL; + g_object_notify(G_OBJECT(self), "program-info"); + priv->story_name = NULL; + g_object_notify(G_OBJECT(self), "story-name"); } static void @@ -663,6 +688,12 @@ chimara_glk_text_buffer_output(ChimaraGlk *self, guint window_rock, gchar *text) /* Default signal handler */ } +static void +chimara_glk_iliad_screen_update(ChimaraGlk *self, gboolean typing) +{ + /* Default signal handler */ +} + /* COMPAT: G_PARAM_STATIC_STRINGS only appeared in GTK 2.13.0 */ #ifndef G_PARAM_STATIC_STRINGS @@ -698,6 +729,8 @@ chimara_glk_class_init(ChimaraGlkClass *klass) klass->char_input = chimara_glk_char_input; klass->line_input = chimara_glk_line_input; klass->text_buffer_output = chimara_glk_text_buffer_output; + klass->iliad_screen_update = chimara_glk_iliad_screen_update; + /** * ChimaraGlk::stopped: * @glk: The widget that received the signal @@ -744,7 +777,7 @@ chimara_glk_class_init(ChimaraGlkClass *klass) 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, + _chimara_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); /** * ChimaraGlk::line-input: @@ -758,7 +791,7 @@ chimara_glk_class_init(ChimaraGlkClass *klass) 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, + _chimara_marshal_VOID__UINT_STRING, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING); /** * ChimaraGlk::text-buffer-output: @@ -771,8 +804,22 @@ chimara_glk_class_init(ChimaraGlkClass *klass) 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, + _chimara_marshal_VOID__UINT_STRING, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING); + /** + * ChimaraGlk::iliad-update-screen: + * @self: The widget that received the signal + * @typing: Whether to perform a typing or full screen update + * + * Iliad specific signal which is emitted whenever the screen needs to be updated. + * Since iliad screen updates are very slow, updating should only be done when + * necessary. + */ + chimara_glk_signals[ILIAD_SCREEN_UPDATE] = g_signal_new("iliad-screen-update", + G_OBJECT_CLASS_TYPE(klass), 0, + G_STRUCT_OFFSET(ChimaraGlkClass, iliad_screen_update), NULL, NULL, + _chimara_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); /* Properties */ /** @@ -815,7 +862,54 @@ chimara_glk_class_init(ChimaraGlkClass *klass) 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_LAX_VALIDATION | G_PARAM_STATIC_STRINGS) ); - /* Private data */ + /** + * ChimaraGlk:program-name: + * + * The name of the currently running Glk program. You cannot set this + * property yourself. It is set to the filename of the plugin when you call + * chimara_glk_run(), but the plugin can change it by calling + * garglk_set_program_name(). To find out when this information changes, + * for example to put the program name in the title bar of a window, connect + * to the ::notify::program-name signal. + */ + g_object_class_install_property(object_class, PROP_PROGRAM_NAME, + g_param_spec_string("program-name", _("Program name"), + _("Name of the currently running program"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS) ); + + /** + * ChimaraGlk:program-info: + * + * Information about the currently running Glk program. You cannot set this + * property yourself. The plugin can change it by calling + * garglk_set_program_info(). See also #ChimaraGlk:program-name. + */ + g_object_class_install_property(object_class, PROP_PROGRAM_INFO, + g_param_spec_string("program-info", _("Program info"), + _("Information about the currently running program"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS) ); + + /** + * ChimaraGlk:story-name: + * + * The name of the story currently running in the Glk interpreter. You + * cannot set this property yourself. It is set to the story filename when + * you call chimara_if_run_game(), but the plugin can change it by calling + * garglk_set_story_name(). + * + * Strictly speaking, this should be a property of #ChimaraIF, but it is + * legal for any Glk program to call garglk_set_story_name(), even if it is + * not an interpreter and does not load story files. + */ + g_object_class_install_property(object_class, PROP_STORY_NAME, + g_param_spec_string("story-name", _("Story name"), + _("Name of the story currently loaded in the interpreter"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS) ); + + /* Private data */ g_type_class_add_private(klass, sizeof(ChimaraGlkPrivate)); } @@ -973,10 +1067,6 @@ chimara_glk_set_css_from_file(ChimaraGlk *glk, const gchar *filename, GError **e scanner->input_name = filename; scan_css_file(scanner, glk); - /* Set the current style to a copy of the default style */ - /* FIXME this is not correct */ - copy_default_styles_to_current_styles(glk); - if(close(fd) == -1) { *error = g_error_new(G_IO_ERROR, g_io_error_from_errno(errno), _("Error closing file \"%s\": %s"), filename, g_strerror(errno)); @@ -1005,10 +1095,6 @@ chimara_glk_set_css_from_string(ChimaraGlk *glk, const gchar *css) g_scanner_input_text(scanner, css, strlen(css)); scanner->input_name = ""; scan_css_file(scanner, glk); - - /* Set the current style to a copy of the default style */ - /* FIXME this is not correct */ - copy_default_styles_to_current_styles(glk); } /** @@ -1159,11 +1245,15 @@ chimara_glk_run(ChimaraGlk *glk, const gchar *plugin, int argc, char *argv[], GE startup->args.argv = g_new0(gchar *, 1); } - /* Set the program name */ + /* Set the program invocation name */ startup->args.argv[0] = g_strdup(plugin); } startup->glk_data = priv; + /* Set the program name */ + priv->program_name = g_path_get_basename(plugin); + g_object_notify(G_OBJECT(glk), "program-name"); + /* Run in a separate thread */ priv->thread = g_thread_create((GThreadFunc)glk_enter, startup, TRUE, error);