--- /dev/null
+GCC=gcc
+CFLAGS=-ggdb -O1 -pipe
+GOBJ_CFLAGS=`pkg-config --cflags gobject-2.0`
+GOBJ_LIBS=`pkg-config --libs gobject-2.0`
+
+tilda-window: tilda-window.o
+ $(GCC) $(CFLAGS) $^ -o $@ $(GOBJ_LIBS)
+
+tilda-window.o: tilda-window.c tilda-window.h
+ $(GCC) $(CFLAGS) -c -o $@ $< $(GOBJ_CFLAGS)
+
+tilda-terminal: tilda-terminal.o
+ $(GCC) $(CFLAGS) $^ -o $@ $(GOBJ_LIBS)
+
+tilda-terminal.o: tilda-terminal.c tilda-terminal.h
+ $(GCC) $(CFLAGS) -c -o $@ $< $(GOBJ_CFLAGS)
+
+memcheck-tw: tilda-window
+ valgrind --tool=memcheck ./tilda-window
+
+memcheck-tt: tilda-terminal
+ valgrind --tool=memcheck ./tilda-terminal
+
+memcheck: memcheck-tt memcheck-tw
+
+clean:
+ rm -f *.o
+ rm -f tilda-window
+ rm -f tilda-terminal
+
+
+
+
--- /dev/null
+#include "tilda-terminal.h"
+
+static GObjectClass *parent_class = NULL;
+
+/* API */
+
+/*
+ * All GObject stuff is below. You probably don't need to change this...
+ */
+
+enum tilda_terminal_properties {
+ TILDA_TERMINAL_NUMBER = 1,
+ // TODO: All properties
+};
+
+static void
+tilda_terminal_instance_init (GTypeInstance *instance,
+ gpointer g_class)
+{
+ TildaTerminal *self = (TildaTerminal *) instance;
+
+ /* Initialize instance members and allocate any necessary memory here.
+ * NOTE: any constructor-time values will be set later. */
+ self->dispose_has_run = FALSE;
+ self->number = 0;
+}
+
+static void
+tilda_terminal_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TildaTerminal *self = (TildaTerminal *) object;
+
+ switch (property_id) {
+
+ case TILDA_TERMINAL_NUMBER:
+ self->number = g_value_get_int (value);
+ g_print ("terminal number: %d\n", self->number);
+ break;
+
+ default:
+ /* We don't have this property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+tilda_terminal_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TildaTerminal *self = (TildaTerminal *) object;
+
+ switch (property_id) {
+
+ case TILDA_TERMINAL_NUMBER:
+ g_value_set_int (value, self->number);
+ break;
+
+ default:
+ /* We don't have this property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static GObject *
+tilda_terminal_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GObject *obj;
+
+ /* Invoke parent constructor */
+ TildaTerminalClass *klass;
+ klass = TILDA_TERMINAL_CLASS (g_type_class_peek (TILDA_TYPE_TERMINAL));
+ obj = parent_class->constructor (type,
+ n_construct_properties,
+ construct_properties);
+
+ /* Do other stuff here. The object is ready to go now, and all
+ * ctor properties have been set.
+ *
+ * TODO: This is the place to do DBus-init */
+
+
+ return obj;
+}
+
+static void
+tilda_terminal_dispose (GObject *obj)
+{
+ TildaTerminal *self = (TildaTerminal *) obj;
+
+ /* We don't want to run dispose twice, so just return immediately */
+ if (self->dispose_has_run)
+ return;
+
+ self->dispose_has_run = TRUE;
+
+ /*
+ * In dispose, you are supposed to free all types referenced from this
+ * object which might themselves hold a reference to self. Generally,
+ * the most simple solution is to unref all members on which you own a
+ * reference.
+ */
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class)->dispose (obj);
+}
+
+static void
+tilda_terminal_finalize (GObject *obj)
+{
+ TildaTerminal *self = (TildaTerminal *) obj;
+
+ /*
+ * Here, complete object destruction.
+ * You might not need to do much...
+ */
+
+ // TODO: g_free() any primitives here
+
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
+tilda_terminal_class_init (gpointer g_class,
+ gpointer g_class_data)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
+ TildaTerminalClass *klass = TILDA_TERMINAL_CLASS (g_class);
+ GParamSpec *pspec;
+
+ /* Hook our functions to this type */
+ gobject_class->set_property = tilda_terminal_set_property;
+ gobject_class->get_property = tilda_terminal_get_property;
+ gobject_class->dispose = tilda_terminal_dispose;
+ gobject_class->finalize = tilda_terminal_finalize;
+ gobject_class->constructor = tilda_terminal_constructor;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ /* Install all of the properties */
+ pspec = g_param_spec_int ("number",
+ "Terminal number",
+ "Set terminal's number",
+ 0, // min value
+ INT_MAX, // max value
+ 0, // def value
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+ g_object_class_install_property (gobject_class,
+ TILDA_TERMINAL_NUMBER,
+ pspec);
+}
+
+GType
+tilda_terminal_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0)
+ {
+ static const GTypeInfo info = {
+ sizeof (TildaTerminalClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ tilda_terminal_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (TildaTerminal),
+ 0, /* n_preallocs */
+ tilda_terminal_instance_init, /* instance_init */
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "TildaTerminalType",
+ &info,
+ 0);
+ }
+
+ return type;
+}
+
+int main (int argc, char *argv[])
+{
+ GObject *tt;
+ gint test_number = INT_MIN;
+
+ /* Initialize the GObject type system */
+ g_type_init ();
+
+ tt = g_object_new (TILDA_TYPE_TERMINAL, "number", 10, NULL);
+ g_object_get (G_OBJECT (tt), "number", &test_number, NULL);
+ g_assert (test_number == 10);
+
+ g_object_unref (G_OBJECT (tt));
+
+ tt = g_object_new (TILDA_TYPE_TERMINAL, "number", 22, NULL);
+ g_object_get (G_OBJECT (tt), "number", &test_number, NULL);
+ g_assert (test_number == 22);
+
+ g_object_unref (G_OBJECT (tt));
+
+ return 0;
+}
+
+/* vim: set ts=4 sts=4 sw=4 noet tw=112: */
+
--- /dev/null
+#ifndef TILDA_TERMINAL_H
+#define TILDA_TERMINAL_H
+
+#include <glib-object.h>
+
+#define TILDA_TYPE_TERMINAL (tilda_terminal_get_type())
+#define TILDA_TERMINAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TILDA_TYPE_TERMINAL))
+#define TILDA_TERMINAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TILDA_TYPE_TERMINAL, TildaTerminalClass))
+#define TILDA_IS_TERMINAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TILDA_TYPE_TERMINAL))
+#define TILDA_IS_TERMINAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TILDA_TYPE_TERMINAL))
+#define TILDA_TERMINAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TILDA_TYPE_TERMINAL, TildaTerminalClass))
+
+typedef struct _TildaTerminal TildaTerminal;
+typedef struct _TildaTerminalClass TildaTerminalClass;
+
+struct _TildaTerminal {
+ GObject parent;
+ gboolean dispose_has_run;
+
+ /* Instance Members */
+ gint number;
+};
+
+struct _TildaTerminalClass {
+ GObjectClass parent;
+
+ /* Class Members */
+};
+
+/* Used by TILDA_TYPE_TERMINAL */
+GType tilda_terminal_get_type (void);
+
+/* API */
+
+#endif /* TILDA_TERMINAL_H */
+
+/* vim: set ts=4 sts=4 sw=4 noet tw=112: */
+
--- /dev/null
+#include "tilda-window.h"
+
+static GObjectClass *parent_class = NULL;
+
+enum tilda_window_properties {
+ TILDA_WINDOW_NUMBER = 1,
+};
+
+static void
+tilda_window_instance_init (GTypeInstance *instance,
+ gpointer g_class)
+{
+ TildaWindow *self = (TildaWindow *) instance;
+ self->dispose_has_run = FALSE;
+
+ /* Initialize all properties */
+ self->number = 0;
+}
+
+static void
+tilda_window_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TildaWindow *self = (TildaWindow *) object;
+
+ switch (property_id) {
+
+ case TILDA_WINDOW_NUMBER:
+ self->number = g_value_get_int (value);
+ g_print ("window number: %d\n", self->number);
+ break;
+
+ default:
+ /* We don't have this property */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+tilda_window_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TildaWindow *self = (TildaWindow *) object;
+
+ switch (property_id) {
+
+ case TILDA_WINDOW_NUMBER:
+ g_value_set_int (value, self->number);
+ break;
+
+ default:
+ /* We don't have this property */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static GObject *
+tilda_window_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GObject *obj;
+
+ /* Invoke parent constructor */
+ TildaWindowClass *klass;
+ klass = TILDA_WINDOW_CLASS (g_type_class_peek (TILDA_TYPE_WINDOW));
+ obj = parent_class->constructor (type,
+ n_construct_properties,
+ construct_properties);
+
+ /* Do other stuff here. The object is ready to go now, and all
+ * ctor properties have been set.
+ *
+ * TODO: This is the place to do DBus-init */
+
+ return obj;
+}
+
+static void
+tilda_window_dispose (GObject *obj)
+{
+ TildaWindow *self = (TildaWindow *) obj;
+
+ /* We don't want to run dispose twice, so just return immediately */
+ if (self->dispose_has_run)
+ return;
+
+ /*
+ * In dispose, you are supposed to free all types referenced from this
+ * object which might themselves hold a reference to self. Generally,
+ * the most simple solution is to unref all members on which you own a
+ * reference.
+ */
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class)->dispose (obj);
+}
+
+static void
+tilda_window_finalize (GObject *obj)
+{
+ TildaWindow *self = (TildaWindow *) obj;
+
+ /*
+ * Here, complete the object's destruction.
+ * You might not need to do much...
+ */
+ // TODO: g_free() any primitives here
+
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
+tilda_window_class_init (gpointer g_class,
+ gpointer g_class_data)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
+ TildaWindowClass *klass = TILDA_WINDOW_CLASS (g_class);
+ GParamSpec *pspec;
+
+ /* Hook our functions to this type */
+ gobject_class->set_property = tilda_window_set_property;
+ gobject_class->get_property = tilda_window_get_property;
+ gobject_class->dispose = tilda_window_dispose;
+ gobject_class->finalize = tilda_window_finalize;
+ gobject_class->constructor = tilda_window_constructor;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ /* Install all of the properties */
+ pspec = g_param_spec_int ("number",
+ "Window number",
+ "Set window's number",
+ 0, // min value
+ INT_MAX, // max value
+ 0, // def value
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+ g_object_class_install_property (gobject_class,
+ TILDA_WINDOW_NUMBER,
+ pspec);
+
+ /* TODO: more properties */
+}
+
+GType
+tilda_window_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0)
+ {
+ static const GTypeInfo info = {
+ sizeof (TildaWindowClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ tilda_window_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (TildaWindow),
+ 0, /* n_preallocs */
+ tilda_window_instance_init, /* instance_init */
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "TildaWindowType",
+ &info,
+ 0);
+ }
+
+ return type;
+}
+
+
+int main (int argc, char *argv[])
+{
+ GObject *tw;
+ gint test_number = INT_MIN;
+
+ /* Initialize the GObject type system */
+ g_type_init ();
+
+ tw = g_object_new (TILDA_TYPE_WINDOW, "number", 10, NULL);
+ g_object_get (G_OBJECT (tw), "number", &test_number, NULL);
+ g_assert (test_number == 10);
+
+ g_object_unref (G_OBJECT (tw));
+
+ tw = g_object_new (TILDA_TYPE_WINDOW, "number", 22, NULL);
+ g_object_get (G_OBJECT (tw), "number", &test_number, NULL);
+ g_assert (test_number == 22);
+
+ g_object_unref (G_OBJECT (tw));
+
+ return 0;
+}
+
+/* vim: set ts=4 sts=4 sw=4 noet tw=112: */
+
--- /dev/null
+#ifndef TILDA_WINDOW_H
+#define TILDA_WINDOW_H
+
+/*
+Object Creation Order
+========================================
+tilda_window_class_init()
+tilda_window_constructor() BEGINS
+ tilda_window_instance_init()
+ tilda_window_set_property() FOR EACH CTOR PROPERTY USED
+tilda_window_constructor() COMPLETES
+
+... usage ...
+
+g_object_unref(...)
+tilda_window_dispose()
+tilda_window_finalize()
+*/
+
+#include <glib-object.h>
+
+#define TILDA_TYPE_WINDOW (tilda_window_get_type())
+#define TILDA_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TILDA_TYPE_WINDOW, TildaWindow))
+#define TILDA_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TILDA_TYPE_WINDOW, TildaWindowClass))
+#define TILDA_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TILDA_TYPE_WINDOW))
+#define TILDA_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TILDA_TYPE_WINDOW))
+#define TILDA_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TILDA_TYPE_WINDOW, TildaWindowClass))
+
+typedef struct _TildaWindow TildaWindow;
+typedef struct _TildaWindowClass TildaWindowClass;
+
+struct _TildaWindow {
+ GObject parent;
+ gboolean dispose_has_run;
+
+ /* Instance Members */
+ gint number;
+};
+
+struct _TildaWindowClass {
+ GObjectClass parent;
+
+ /* class members */
+};
+
+/* used by TILDA_TYPE_WINDOW */
+GType tilda_window_get_type (void);
+
+/* API */
+
+#endif /* TILDA_WINDOW_H */
+
+/* vim: set ts=4 sts=4 sw=4 noet tw=112: */
+