b740e5e0895a5131a093c1ca4fb4c04fb22e3a67
[rodin/chimara.git] / libchimara / chimara-if.c
1 #include <glib.h>
2 #include <glib-object.h>
3 #include <config.h>
4 #include <glib/gi18n-lib.h>
5 #include "chimara-if.h"
6 #include "chimara-glk.h"
7 #include "chimara-marshallers.h"
8 #include "init.h"
9
10 static gboolean supported_formats[CHIMARA_IF_NUM_FORMATS][CHIMARA_IF_NUM_INTERPRETERS] = {
11         /* Frotz Nitfol Glulxe Git */
12         { TRUE,  TRUE,  FALSE, FALSE }, /* Z5 */
13         { TRUE,  TRUE,  FALSE, FALSE }, /* Z6 */
14         { TRUE,  TRUE,  FALSE, FALSE }, /* Z8 */
15         { FALSE, FALSE, TRUE,  TRUE  }  /* Glulx */
16 };
17 static gchar *format_names[CHIMARA_IF_NUM_FORMATS] = {
18         N_("Z-code version 5"),
19         N_("Z-code version 6"),
20         N_("Z-code version 8"),
21         N_("Glulx")
22 };
23 static gchar *interpreter_names[CHIMARA_IF_NUM_INTERPRETERS] = {
24         N_("Frotz"), N_("Nitfol"), N_("Glulxe"), N_("Git")
25 };
26
27 typedef struct _ChimaraIFPrivate {
28         ChimaraIFInterpreter preferred_interpreter[CHIMARA_IF_NUM_FORMATS];
29 } ChimaraIFPrivate;
30
31 #define CHIMARA_IF_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), CHIMARA_TYPE_IF, ChimaraIFPrivate))
32 #define CHIMARA_IF_USE_PRIVATE(o, n) ChimaraIFPrivate *n = CHIMARA_IF_PRIVATE(o)
33
34 enum {
35         PROP_0
36 };
37
38 enum {
39         COMMAND,
40
41         LAST_SIGNAL
42 };
43
44 static guint chimara_if_signals[LAST_SIGNAL] = { 0 };
45
46 G_DEFINE_TYPE(ChimaraIF, chimara_if, CHIMARA_TYPE_GLK);
47
48 static void
49 chimara_if_init(ChimaraIF *self)
50 {
51         CHIMARA_IF_USE_PRIVATE(self, priv);
52         priv->preferred_interpreter[CHIMARA_IF_FORMAT_Z5] = CHIMARA_IF_INTERPRETER_FROTZ;
53         priv->preferred_interpreter[CHIMARA_IF_FORMAT_Z6] = CHIMARA_IF_INTERPRETER_FROTZ;
54         priv->preferred_interpreter[CHIMARA_IF_FORMAT_Z8] = CHIMARA_IF_INTERPRETER_FROTZ;
55         priv->preferred_interpreter[CHIMARA_IF_FORMAT_GLULX] = CHIMARA_IF_INTERPRETER_GLULXE;
56 }
57
58 static void
59 chimara_if_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
60 {
61     switch(prop_id)
62     {
63         default:
64             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
65     }
66 }
67
68 static void
69 chimara_if_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
70 {
71     switch(prop_id)
72     {
73
74         default:
75             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
76     }
77 }
78
79 static void
80 chimara_if_finalize(GObject *object)
81 {
82     G_OBJECT_CLASS(chimara_if_parent_class)->finalize(object);
83 }
84
85 static void
86 chimara_if_command(ChimaraIF *self, gchar *input, gchar *response)
87 {
88         /* TODO: Add default signal handler */
89 }
90
91 static void
92 chimara_if_class_init(ChimaraIFClass *klass)
93 {
94         /* Override methods of parent classes */
95         GObjectClass *object_class = G_OBJECT_CLASS(klass);
96         object_class->set_property = chimara_if_set_property;
97         object_class->get_property = chimara_if_get_property;
98         object_class->finalize = chimara_if_finalize;
99
100         /* Signals */
101         klass->command = chimara_if_command;
102         /* Gtk-Doc for command */
103         chimara_if_signals[COMMAND] = g_signal_new("command",
104                 G_OBJECT_CLASS_TYPE(klass), 0,
105                 G_STRUCT_OFFSET(ChimaraIFClass, command), NULL, NULL,
106                 chimara_marshal_VOID__STRING_STRING,
107                 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
108
109         /* Properties */
110         /* Gtk-Doc for property */
111         /* g_object_class_install_property(object_class, PROPERTY, ...); */
112
113         /* Private data */
114         g_type_class_add_private(klass, sizeof(ChimaraIFPrivate));
115 }
116
117 /* PUBLIC FUNCTIONS */
118
119 /**
120  * chimara_if_new:
121  *
122  * Creates and initializes a new #ChimaraIF widget.
123  *
124  * Return value: a #ChimaraIF widget, with a floating reference.
125  */
126 GtkWidget *
127 chimara_if_new(void)
128 {
129         /* This is a library entry point; initialize the library */
130         chimara_init();
131     return GTK_WIDGET(g_object_new(CHIMARA_TYPE_IF, NULL));
132 }
133
134 void
135 chimara_if_set_preferred_interpreter(ChimaraIF *self, ChimaraIFFormat format, ChimaraIFInterpreter interpreter)
136 {
137         g_return_if_fail(self);
138         g_return_if_fail(format < CHIMARA_IF_NUM_FORMATS);
139         g_return_if_fail(format < CHIMARA_IF_NUM_INTERPRETERS);
140
141         CHIMARA_IF_USE_PRIVATE(self, priv);
142
143         if(supported_formats[format][interpreter])
144                 priv->preferred_interpreter[format] = interpreter;
145         else
146                 g_warning("Format '%s' is not supported by interpreter '%s'", format_names[format], interpreter_names[interpreter]);
147 }
148
149 ChimaraIFInterpreter
150 chimara_if_get_preferred_interpreter(ChimaraIF *self, ChimaraIFFormat format)
151 {
152         g_return_val_if_fail(self, -1);
153         g_return_val_if_fail(format < CHIMARA_IF_NUM_FORMATS, -1);
154         CHIMARA_IF_USE_PRIVATE(self, priv);
155         return priv->preferred_interpreter[format];
156 }