PROP_SPACING,
PROP_PROGRAM_NAME,
PROP_PROGRAM_INFO,
- PROP_STORY_NAME
+ PROP_STORY_NAME,
+ PROP_RUNNING
};
enum {
static void
chimara_glk_init(ChimaraGlk *self)
{
+ chimara_init(); /* This is a library entry point */
+
gtk_widget_set_has_window(GTK_WIDGET(self), FALSE);
ChimaraGlkPrivate *priv = CHIMARA_GLK_PRIVATE(self);
case PROP_STORY_NAME:
g_value_set_string(value, priv->story_name);
break;
+ case PROP_RUNNING:
+ g_value_set_boolean(value, priv->running);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS) );
+ /**
+ * ChimaraGlk:running:
+ *
+ * Whether this Glk widget is currently running a game or not.
+ */
+ g_object_class_install_property(object_class, PROP_RUNNING,
+ g_param_spec_boolean("running", _("Running"),
+ _("Whether there is a program currently running"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS) );
+
/* Private data */
g_type_class_add_private(klass, sizeof(ChimaraGlkPrivate));
}
g_assert( g_module_supported() );
/* If there is already a module loaded, free it first -- you see, we want to
* keep modules loaded as long as possible to avoid crashes in stack unwinding */
- if( priv->program && !g_module_close(priv->program) )
- g_warning( "Error closing module :%s", g_module_error() );
+ chimara_glk_unload_plugin(glk);
/* Open the module to run */
priv->program = g_module_open(plugin, G_MODULE_BIND_LAZY);
return !(priv->thread == NULL);
}
+/**
+ * chimara_glk_run_file:
+ * @self: a #ChimaraGlk widget
+ * @plugin_file: a #GFile pointing to a plugin module compiled with <filename
+ * class="header">glk.h</filename>
+ * @argc: Number of command line arguments in @argv
+ * @argv: Array of command line arguments to pass to the plugin
+ * @error: location to store a <link
+ * linkend="glib-Error-Reporting">GError</link>, or %NULL
+ *
+ * Opens a Glk program compiled as a plugin, from a #GFile. See
+ * chimara_glk_run() for details.
+ *
+ * Return value: %TRUE if the Glk program was started successfully.
+ */
+gboolean
+chimara_glk_run_file(ChimaraGlk *self, GFile *plugin_file, int argc, char *argv[], GError **error)
+{
+ g_return_val_if_fail(self || CHIMARA_IS_GLK(self), FALSE);
+ g_return_val_if_fail(plugin_file || G_IS_FILE(plugin_file), FALSE);
+ g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+ char *path = g_file_get_path(plugin_file);
+ gboolean retval = chimara_glk_run(self, path, argc, argv, error);
+ g_free(path);
+
+ return retval;
+}
+
/**
* chimara_glk_stop:
* @glk: a #ChimaraGlk widget
gdk_threads_enter();
}
+/**
+ * chimara_glk_unload_plugin:
+ * @glk: a #ChimaraGlk widget
+ *
+ * The plugin containing the Glk program is unloaded as late as possible before
+ * loading a new plugin, in order to prevent crashes while printing stack
+ * backtraces during debugging. Sometimes this behavior is not desirable. This
+ * function forces @glk to unload the plugin running in it.
+ *
+ * This function does nothing if there is no plugin loaded.
+ */
+void
+chimara_glk_unload_plugin(ChimaraGlk *glk)
+{
+ g_return_if_fail(glk || CHIMARA_IS_GLK(glk));
+ CHIMARA_GLK_USE_PRIVATE(glk, priv);
+ if( priv->program && !g_module_close(priv->program) )
+ g_warning( "Error closing module :%s", g_module_error() );
+}
+
/**
* chimara_glk_get_running:
* @glk: a #ChimaraGlk widget