--- /dev/null
+#include <glib.h>
+#include <libchimara/chimara-glk.h>
+#include <libchimara/chimara-if.h>
+#include "error.h"
+
+#define LOAD_WIDGET(name) GTK_WIDGET(gtk_builder_get_object(builder, name))
+
+typedef struct {
+ GtkWidget *window, *test_picker, *go, *stop, *interp;
+} Widgets;
+
+gboolean
+on_window_delete_event()
+{
+ gtk_main_quit();
+ return TRUE;
+}
+
+void
+on_go_clicked(GtkButton *go, Widgets *w)
+{
+ GError *error = NULL;
+
+ gchar *filename = NULL;
+ GtkTreeIter iter;
+ GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(w->test_picker));
+ gtk_combo_box_get_active_iter(GTK_COMBO_BOX(w->test_picker), &iter);
+ gtk_tree_model_get(model, &iter, 1, &filename, -1);
+ g_object_unref(model);
+
+ if( !chimara_if_run_game(CHIMARA_IF(w->interp), filename, &error) )
+ {
+ error_dialog(GTK_WINDOW(w->window), error, "Error starting Glk library: ");
+ gtk_main_quit();
+ }
+
+ gtk_widget_set_sensitive(w->go, FALSE);
+ gtk_widget_set_sensitive(w->stop, TRUE);
+ gtk_widget_set_sensitive(w->test_picker, FALSE);
+}
+
+void
+on_stop_clicked(GtkButton *stop, Widgets *w)
+{
+ chimara_glk_stop( CHIMARA_GLK(w->interp) );
+ chimara_glk_wait( CHIMARA_GLK(w->interp) );
+
+ gtk_widget_set_sensitive(w->stop, FALSE);
+ gtk_widget_set_sensitive(w->go, TRUE);
+ gtk_widget_set_sensitive(w->test_picker, TRUE);
+}
+
+void
+on_glulxe_toggled(GtkToggleButton *glulxe, Widgets *w)
+{
+ if(gtk_toggle_button_get_active(glulxe))
+ chimara_if_set_preferred_interpreter(CHIMARA_IF(w->interp), CHIMARA_IF_FORMAT_GLULX, CHIMARA_IF_INTERPRETER_GLULXE);
+}
+
+void
+on_git_toggled(GtkToggleButton *git, Widgets *w)
+{
+ if(gtk_toggle_button_get_active(git))
+ chimara_if_set_preferred_interpreter(CHIMARA_IF(w->interp), CHIMARA_IF_FORMAT_GLULX, CHIMARA_IF_INTERPRETER_GIT);
+}
+
+int
+main(int argc, char *argv[])
+{
+ GError *error = NULL;
+
+ if( !g_thread_supported() )
+ g_thread_init(NULL);
+ gdk_threads_init();
+ gtk_init(&argc, &argv);
+
+ GtkBuilder *builder = gtk_builder_new();
+ if(!gtk_builder_add_from_file(builder, "glulxercise.ui", &error))
+ {
+ error_dialog(NULL, error, "Failed to build interface: ");
+ return 1;
+ }
+
+ Widgets *w = g_slice_new0(Widgets);
+ w->window = LOAD_WIDGET("window");
+ GtkWidget *vbox = LOAD_WIDGET("vbox");
+ w->test_picker = LOAD_WIDGET("test_picker");
+ w->go = LOAD_WIDGET("go");
+ w->stop = LOAD_WIDGET("stop");
+ w->interp = chimara_if_new();
+ gtk_box_pack_end_defaults(GTK_BOX(vbox), w->interp);
+ gtk_builder_connect_signals(builder, w);
+ gtk_widget_show_all(w->window);
+
+ gdk_threads_enter();
+ gtk_main();
+ gdk_threads_leave();
+
+ chimara_glk_stop( CHIMARA_GLK(w->interp) );
+ chimara_glk_wait( CHIMARA_GLK(w->interp) );
+
+ g_slice_free(Widgets, w);
+
+ return 0;
+}
--- /dev/null
+<?xml version="1.0"?>
+<interface>
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkWindow" id="window">
+ <property name="width_request">500</property>
+ <property name="height_request">600</property>
+ <property name="border_width">6</property>
+ <signal name="delete_event" handler="on_window_delete_event"/>
+ <child>
+ <object class="GtkVBox" id="vbox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkComboBox" id="test_picker">
+ <property name="visible">True</property>
+ <property name="model">tests</property>
+ <property name="active">0</property>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHButtonBox" id="hbuttonbox1">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkButton" id="go">
+ <property name="label" translatable="yes">_Go</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="image">image1</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="on_go_clicked"/>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="stop">
+ <property name="label" translatable="yes">gtk-stop</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ <signal name="clicked" handler="on_stop_clicked"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Use</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="glulxe">
+ <property name="label" translatable="yes">Glulx_e</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="on_glulxe_toggled"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="git">
+ <property name="label" translatable="yes">Gi_t</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">glulxe</property>
+ <signal name="toggled" handler="on_git_toggled"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkListStore" id="tests">
+ <columns>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ <!-- column-name glulxfile -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">Glulxercise</col>
+ <col id="1" translatable="yes">glulxercise.ulx</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">AccelFuncTest</col>
+ <col id="1" translatable="yes">accelfunctest.ulx</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">InputEventTest</col>
+ <col id="1" translatable="yes">inputeventtest.ulx</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">MemCopyTest</col>
+ <col id="1" translatable="yes">memcopytest.ulx</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">MemHeapTest</col>
+ <col id="1" translatable="yes">memheaptest.ulx</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">MemStreamTest</col>
+ <col id="1" translatable="yes">memstreamtest.ulx</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">UnicodeTest</col>
+ <col id="1" translatable="yes">unicodetest.ulx</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-yes</property>
+ <property name="icon-size">4</property>
+ </object>
+</interface>