all: tilda
-tilda: tilda.o tilda-window.o tilda-terminal.o tomboykeybinder.o tomboyutil.o eggaccelerators.o
+tilda: tilda.o tilda-controller.o tilda-window.o tilda-terminal.o tomboykeybinder.o tomboyutil.o eggaccelerators.o
$(GCC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(ALL_LIBS)
-tilda.o: tilda.c
+tilda.o: tilda.c tilda.h
$(GCC) $(CFLAGS) -c -o $@ $< $(ALL_CFLAGS)
-tilda-window.o: tilda-window.c tilda-window.h
+tilda-controller.o: tilda-controller.c tilda-controller.h tilda-controller.xml
+ dbus-binding-tool --mode=glib-server --prefix=tilda_controller tilda-controller.xml > tilda-controller-dbus-glue.h
+ $(GCC) $(CFLAGS) -c -o $@ $< $(ALL_CFLAGS)
+
+tilda-window.o: tilda-window.c tilda-window.h tilda-window.xml
dbus-binding-tool --mode=glib-server --prefix=tilda_window tilda-window.xml > tilda-window-dbus-glue.h
$(GCC) $(CFLAGS) -c -o $@ $< $(ALL_CFLAGS)
-tilda-terminal.o: tilda-terminal.c tilda-terminal.h
+tilda-terminal.o: tilda-terminal.c tilda-terminal.h tilda-terminal.xml
dbus-binding-tool --mode=glib-server --prefix=tilda_terminal tilda-terminal.xml > tilda-terminal-dbus-glue.h
$(GCC) $(CFLAGS) -c -o $@ $< $(ALL_CFLAGS)
rm -f tilda-window
rm -f tilda-terminal
rm -f tilda
+ rm -f tilda-controller-dbus-glue.h
rm -f tilda-window-dbus-glue.h
rm -f tilda-terminal-dbus-glue.h
--- /dev/null
+#include "tilda.h"
+#include "tilda-controller.h"
+#include "tilda-controller-dbus-glue.h"
+#include "tilda-window.h"
+
+/**
+ * Register this object with DBus, so it can be interacted with!
+ */
+static void
+tilda_controller_dbus_register_object (TildaController *self)
+{
+ debug_enter ();
+ debug_assert (TILDA_IS_CONTROLLER(self));
+
+ static const gchar object_path[] = "/net/sourceforge/Tilda";
+
+ dbus_g_connection_register_g_object (dbus_connection, object_path, G_OBJECT(self));
+}
+
+/**
+ * Find the next free window number, so it can be used by a TildaWindow
+ */
+static gint
+tilda_controller_find_next_free_window_number (TildaController *self)
+{
+ debug_enter ();
+ debug_assert (TILDA_IS_CONTROLLER(self));
+
+ gint i, j;
+ gboolean found;
+
+ for (i=0; i<INT_MAX; ++i)
+ {
+ found = FALSE;
+
+ for (j=0; j<self->windows->len; ++j)
+ {
+ TildaWindow *tw = g_ptr_array_index (self->windows, j);
+
+ if (tw->number == i)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ return i;
+ }
+
+ return 0;
+}
+
+gboolean
+tilda_controller_add_window (TildaController *self)
+{
+ debug_enter ();
+ debug_assert (TILDA_IS_CONTROLLER(self));
+
+ TildaWindow *ret;
+ gint number;
+
+ number = tilda_controller_find_next_free_window_number (self);
+ ret = g_object_new (TILDA_TYPE_WINDOW,
+ "number", number,
+ "controller", G_OBJECT(self),
+ NULL);
+
+ g_ptr_array_add (self->windows, ret);
+
+ debug_printf ("Adding window: 0x%x (number %d of %d)\n", ret, ret->number, self->windows->len);
+ return TRUE;
+}
+
+gboolean
+tilda_controller_delete_window (TildaController *self, gint window_number)
+{
+ debug_enter ();
+ debug_assert (TILDA_IS_CONTROLLER(self));
+ debug_assert (window_number >= 0);
+
+ gint i;
+ TildaWindow *win;
+
+ for (i=0; i<self->windows->len; ++i)
+ {
+ win = g_ptr_array_index (self->windows, i);
+
+ if (win->number == window_number)
+ {
+ debug_printf ("Deleting TildaWindow 0x%x (number %d of %d)\n",
+ win, win->number, self->windows->len);
+ g_ptr_array_remove_index (self->windows, i);
+ g_object_unref (G_OBJECT(win));
+
+ if (self->windows->len == 0)
+ {
+ debug_printf ("No windows left, exiting...\n");
+
+ /* We get unref'd in main() */
+ gtk_main_quit ();
+ }
+
+ /* We were able to delete the window */
+ return TRUE;
+ }
+ }
+
+ /* There must have been no window to delete */
+ return FALSE;
+}
+
+gboolean
+tilda_controller_quit (TildaController *self, GError **error)
+{
+ debug_enter ();
+ debug_assert (TILDA_IS_CONTROLLER(self));
+
+ /* Not much left but to quit, since we get unref'd in main() */
+ gtk_main_quit ();
+
+ return TRUE;
+}
+
+/*******************************************************************************
+ * GObject code below... it is doubtful you'll need to make big changes :)
+ ******************************************************************************/
+
+static GObjectClass *parent_class = NULL;
+
+static void
+tilda_controller_instance_init (GTypeInstance *instance,
+ gpointer g_class)
+{
+ debug_enter ();
+
+ TildaController *self = (TildaController *) instance;
+
+ self->dispose_has_run = FALSE;
+ self->windows = g_ptr_array_new ();
+}
+
+static void
+tilda_controller_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TildaController *self = (TildaController *) self;
+
+ switch (property_id)
+ {
+ default:
+ /* We don't have any other properties */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+tilda_controller_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TildaController *self = (TildaController *) object;
+
+ switch (property_id)
+ {
+ default:
+ /* We don't have any other properties */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static GObject *
+tilda_controller_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ debug_enter ();
+
+ GObject *obj;
+ TildaControllerClass *klass;
+ TildaController *self;
+
+ /* Invoke the parent constructor */
+ klass = TILDA_CONTROLLER_CLASS (g_type_class_peek (TILDA_TYPE_CONTROLLER));
+ obj = parent_class->constructor (type,
+ n_construct_properties,
+ construct_properties);
+
+ /* The object is ready, and all constructor-time properties have been set.
+ * Have fun! */
+ self = TILDA_CONTROLLER(obj);
+
+ /* Register this object with DBus */
+ tilda_controller_dbus_register_object (self);
+
+ /* Add a window -- FIXME: the number should be configurable */
+ tilda_controller_add_window (self);
+
+ return obj;
+}
+
+static void
+tilda_controller_dispose (GObject *obj)
+{
+ debug_enter ();
+
+ TildaController *self = (TildaController *) obj;
+
+ /* We must only run dispose once ... */
+ 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.
+ */
+ g_ptr_array_foreach (self->windows, g_object_unref, NULL);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class)->dispose (obj);
+}
+
+static void
+tilda_controller_finalize (GObject *obj)
+{
+ debug_enter ();
+
+ TildaController *self = (TildaController *) obj;
+
+ /*
+ * Here, complete the object's destruction.
+ * You might not need to do much more than
+ * g_free() any primitives.
+ */
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
+tilda_controller_class_init (gpointer g_class,
+ gpointer g_class_data)
+{
+ debug_enter ();
+
+ GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
+ TildaControllerClass *klass = TILDA_CONTROLLER_CLASS (g_class);
+ GParamSpec *pspec;
+
+ gobject_class->set_property = tilda_controller_set_property;
+ gobject_class->get_property = tilda_controller_get_property;
+ gobject_class->dispose = tilda_controller_dispose;
+ gobject_class->finalize = tilda_controller_finalize;
+ gobject_class->constructor = tilda_controller_constructor;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ /* Add properties here */
+
+ /* Hook the TildaController type into DBus */
+ dbus_g_object_type_install_info (tilda_controller_get_type(),
+ &dbus_glib_tilda_controller_object_info);
+}
+
+GType tilda_controller_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0)
+ {
+ static const GTypeInfo info = {
+ sizeof (TildaControllerClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ tilda_controller_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (TildaController),
+ 0, /* n_preallocs */
+ tilda_controller_instance_init, /* instance_init */
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "TildaControllerType",
+ &info,
+ 0);
+ }
+
+ return type;
+}
+
+/* vim: set ts=4 sts=4 sw=4 noet tw=112: */
--- /dev/null
+#ifndef TILDA_CONTROLLER_H
+#define TILDA_CONTROLLER_H
+
+#include <glib.h>
+
+#define TILDA_TYPE_CONTROLLER (tilda_controller_get_type ())
+#define TILDA_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TILDA_TYPE_CONTROLLER, TildaController))
+#define TILDA_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TILDA_TYPE_CONTROLLER, TildaControllerClass))
+#define TILDA_IS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TILDA_TYPE_CONTROLLER))
+#define TILDA_IS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TILDA_TYPE_CONTROLLER))
+#define TILDA_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TILDA_TYPE_CONTROLLER, TildaControllerClass))
+
+typedef struct _TildaController TildaController;
+typedef struct _TildaControllerClass TildaControllerClass;
+
+struct _TildaController {
+ GObject parent;
+ gboolean dispose_has_run;
+
+ /* instance members */
+ GPtrArray *windows;
+};
+
+struct _TildaControllerClass {
+ GObjectClass parent;
+};
+
+/* Used by TILDA_TYPE_CONTROLLER */
+GType tilda_controller_get_type (void);
+
+/* DBus API */
+gboolean tilda_controller_add_window (TildaController *self); // FIXME: needs GError
+gboolean tilda_controller_quit (TildaController *self, GError **error);
+
+/* API */
+gboolean tilda_controller_delete_window (TildaController *self, gint window_number);
+
+#endif /* TILDA_CONTROLLER_H */
+
+/* vim: set ts=4 sts=4 sw=4 noet tw=112: */
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/net/sourceforge/Tilda">
+
+ <interface name="net.sourceforge.Tilda.Controller">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="tilda_controller" />
+
+ <method name="AddWindow">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="tilda_controller_add_window" />
+ </method>
+
+ <method name="Quit">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="tilda_controller_quit" />
+ </method>
+
+ </interface>
+</node>
+
+<!-- vim: set ts=2 sts=2 sw=2 noet: -->
#include <gdk/gdkx.h> /* for gdk_x11_window_set_user_time() */
#include "tilda.h"
+#include "tilda-controller.h"
#include "tilda-window.h"
#include "tilda-window-dbus-glue.h"
#include "tomboykeybinder.h"
debug_enter ();
debug_assert (TILDA_IS_WINDOW(self));
- tilda_del_window (self->number);
+ tilda_controller_delete_window (TILDA_CONTROLLER(self->controller), self->number);
return TRUE;
}
if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (self->notebook)) < 1)
{
debug_printf ("no terminals left, closing window %d\n", self->number);
- tilda_del_window (self->number);
+ tilda_controller_delete_window (TILDA_CONTROLLER(self->controller), self->number);
}
/* Leave the loop, we're done */
enum tilda_window_properties {
TILDA_WINDOW_NUMBER = 1,
+ TILDA_WINDOW_CONTROLLER,
TILDA_WINDOW_KEY,
/* Somewhat of a "poison" value, incase we don't set this */
self->number = 0xdeadbeef;
+ self->controller = NULL;
self->state = WINDOW_UP;
}
debug_printf ("window number: %d\n", self->number);
break;
+ case TILDA_WINDOW_CONTROLLER:
+ self->controller = g_value_get_pointer (value);
+ debug_printf ("window controller: 0x%x\n", self->controller);
+ break;
+
case TILDA_WINDOW_KEY:
tilda_window_try_to_bind_key (self, g_value_get_string (value));
debug_printf ("window key %s\n", self->key);
g_value_set_int (value, self->number);
break;
+ case TILDA_WINDOW_CONTROLLER:
+ g_value_set_pointer (value, self->controller);
+ break;
+
case TILDA_WINDOW_KEY:
g_value_set_string (value, self->key);
break;
gtk_widget_show (self->notebook);
// FIXME: Remove these, and replace with reads from the config system
- g_object_set (G_OBJECT(self), "key", "F2", NULL);
+ gchar *mykey = g_strdup_printf ("F%d", self->number+3); // TERRIBLE HACK
+ g_object_set (G_OBJECT(self), "key", mykey, NULL);
+ g_free (mykey);
g_object_set (G_OBJECT(self), "x-position", 0, "y-position", 0, NULL);
g_object_set (G_OBJECT(self), "height", 400, "width", 1680, NULL);
g_object_set (G_OBJECT(self), "keep-above", TRUE, "stick", TRUE, NULL);
return obj;
}
-static void
-my_unref (gpointer data, gpointer user_data)
-{
- debug_enter ();
-
- // FIXME: This function should probably be eliminated. It /is/ rather ugly
- g_object_unref (G_OBJECT(data));
-}
-
static void
tilda_window_dispose (GObject *obj)
{
* NOTE: See the following for how to deal with GtkObject-derived things:
* http://library.gnome.org/devel/gtk/unstable/GtkObject.html
*/
- g_ptr_array_foreach (self->terms, my_unref, NULL);
+ g_ptr_array_foreach (self->terms, g_object_unref, NULL);
gtk_widget_destroy (self->window);
/* Unbind if we were set */
TILDA_WINDOW_NUMBER,
pspec);
+ pspec = g_param_spec_pointer ("controller",
+ _("Pointer to window's controlling TildaController"),
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+
+ g_object_class_install_property (gobject_class,
+ TILDA_WINDOW_CONTROLLER,
+ pspec);
+
pspec = g_param_spec_string ("key",
_("Window's drop-down keybinding"),
NULL,
GPtrArray *terms;
gint number;
+ GObject *controller; /* pointer back to TildaController */
enum window_states { WINDOW_UP, WINDOW_DOWN } state;
gchar *key;
-#include <glib.h>
#include <stdlib.h>
#include <signal.h>
#include "tilda.h"
-#include "tilda-window.h"
-#include "tilda-terminal.h"
+#include "tilda-controller.h"
#include "tomboykeybinder.h"
+/* Project-global variables */
DBusGConnection *dbus_connection;
-GPtrArray *windows;
static void
tilda_initialize_dbus ()
g_object_unref (driver_proxy);
}
-static gint
-tilda_find_next_free_window_number ()
-{
- debug_enter ();
-
- gint i, j;
- gboolean found;
-
- for (i=0; i<INT_MAX; ++i)
- {
- found = FALSE;
-
- for (j=0; j<windows->len; ++j)
- {
- TildaWindow *tw = g_ptr_array_index (windows, j);
-
- if (tw->number == i)
- {
- found = TRUE;
- break;
- }
- }
-
- if (!found)
- return i;
- }
-
- return 0;
-}
-
-static TildaWindow *
-tilda_add_window ()
-{
- debug_enter ();
-
- TildaWindow *ret;
- gint number;
-
- number = tilda_find_next_free_window_number ();
- ret = g_object_new (TILDA_TYPE_WINDOW, "number", number, NULL);
-
- g_ptr_array_add (windows, ret);
-
- debug_printf ("Adding window: 0x%x (number %d of %d)\n", ret, ret->number, windows->len-1);
- return ret;
-}
-
-void
-tilda_del_window (gint number)
-{
- debug_enter ();
-
- gint i;
- TildaWindow *win;
-
- for (i=0; i<windows->len; ++i)
- {
- win = g_ptr_array_index (windows, i);
-
- if (win->number == number)
- {
- debug_printf ("Deleting window 0x%x (number %d of %d)\n", win, win->number, windows->len-1);
- g_ptr_array_remove_index (windows, i);
- g_object_unref (G_OBJECT(win));
-
- if (windows->len == 0)
- {
- debug_printf ("No windows left, exiting...\n");
- gtk_main_quit ();
- }
-
- break;
- }
- }
-}
-
static void
tilda_parse_command_line (gint argc, gchar *argv[])
{
{
debug_enter ();
- TildaWindow *tw;
+ TildaController *tilda;
#if ENABLE_NLS
/* Gettext Initialization */
/* Start our connection to DBus */
tilda_initialize_dbus ();
- /* Initialize the array of windows */
- windows = g_ptr_array_new ();
-
- /* Create a TildaWindow, run it, and exit when it does, basically.
- *
- * This is nothing like what the real main() will be, but it's
- * a good start for testing and integration of more of TildaWindow
- * and TildaTerminal. */
- tw = tilda_add_window ();
+ /* Create a TildaController, which manages TildaWindows, which in turn manages
+ * TildaTerminals. Exit when it does. */
+ tilda = g_object_new (TILDA_TYPE_CONTROLLER, NULL);
debug_printf ("Starting gtk_main()!\n");
gtk_main ();
debug_printf ("Out of gtk_main(), going down\n");
- /* Free the pointer array we allocated earlier */
- g_ptr_array_free (windows, TRUE);
+ /* Unref the TildaController that controls this whole operation */
+ g_object_unref (G_OBJECT(tilda));
return 0;
}
#ifndef TILDA_H
#define TILDA_H
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <vte/vte.h>
#include <dbus/dbus-glib-bindings.h>
#include "debug.h"
#define TILDA_VERSION "0.10.0pre"
/* Project-global variables */
-extern DBusGConnection *dbus_connection;
-
-/* API */
-void tilda_del_window (gint number);
+DBusGConnection *dbus_connection;
#endif /* TILDA_H */
/* vim: set ts=4 sts=4 sw=4 noet tw=112: */
-