Hook into DBus
[tilda-gobject.git] / tilda-window.c
1 #include "tilda.h"
2 #include "tilda-window.h"
3 #include "tilda-window-dbus-glue.h"
4
5 static gboolean
6 tilda_window_add_term (TildaWindow *tw)
7 {
8         // FIXME: this is totally bad, but it's a good hack for feasability
9         static gint mynumber = 0;
10         TildaTerminal *tt = g_object_new (TILDA_TYPE_TERMINAL,
11                                                                           "number", mynumber++,
12                                                                           "window-number", tw->number,
13                                                                           NULL);
14         g_ptr_array_add (tw->terms, tt);
15
16         GtkWidget *label = gtk_label_new ("Tilda");
17         gint index = gtk_notebook_prepend_page (GTK_NOTEBOOK(tw->notebook), tt->hbox, label);
18         gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK(tw->notebook), tt->hbox, TRUE, TRUE, GTK_PACK_END);
19         //gtk_notebook_set_current_page (GTK_NOTEBOOK(tw->notebook), index);
20
21         if (gtk_notebook_get_n_pages (GTK_NOTEBOOK(tw->notebook)) > 1)
22                 gtk_notebook_set_show_tabs (GTK_NOTEBOOK(tw->notebook), TRUE);
23
24         return TRUE;
25 }
26
27 static gboolean
28 tilda_window_remove_term (TildaWindow *tw, int number)
29 {
30         int i;
31
32         for (i=0; i<tw->terms->len; ++i)
33         {
34                 TildaTerminal *tt = g_ptr_array_index (tw->terms, i);
35
36                 if (tt->number == number)
37                         g_print ("Need to remove window %d terminal %d\n", tw->number, tt->number);
38         }
39
40         return TRUE;
41 }
42
43 static void
44 tilda_window_dbus_register_object (TildaWindow *tw)
45 {
46         gchar *object_path;
47
48         // Register this object with DBus
49         object_path = g_strdup_printf ("/net/sourceforge/Tilda/Window%d", tw->number);
50         dbus_g_connection_register_g_object (dbus_connection, object_path, G_OBJECT(tw));
51         g_free (object_path);
52 }
53
54 /*******************************************************************************
55  * ALL GOBJECT STUFF BELOW PLEASE
56  ******************************************************************************/
57
58 static GObjectClass *parent_class = NULL;
59
60 enum tilda_window_properties {
61         TILDA_WINDOW_NUMBER = 1,
62 };
63
64 static void
65 tilda_window_instance_init (GTypeInstance *instance,
66                                                         gpointer       g_class)
67 {
68         TildaWindow *self = (TildaWindow *) instance;
69         self->dispose_has_run = FALSE;
70
71         /* Initialize all properties */
72         self->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
73         self->notebook = gtk_notebook_new ();
74         self->terms = g_ptr_array_new ();
75
76         /* Somewhat of a "poison" value, incase we don't set this */
77         self->number = 0xdeadbeef;
78 }
79
80 static void
81 tilda_window_set_property (GObject      *object,
82                                                    guint         property_id,
83                                                    const GValue *value,
84                                                    GParamSpec   *pspec)
85 {
86         TildaWindow *self = (TildaWindow *) object;
87
88         switch (property_id) {
89
90                 case TILDA_WINDOW_NUMBER:
91                         self->number = g_value_get_int (value);
92                         g_print ("window number: %d\n", self->number);
93                         break;
94
95                 default:
96                         /* We don't have this property */
97                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
98                         break;
99         }
100 }
101
102 static void
103 tilda_window_get_property (GObject    *object,
104                                                    guint       property_id,
105                                                    GValue     *value,
106                                                    GParamSpec *pspec)
107 {
108         TildaWindow *self = (TildaWindow *) object;
109
110         switch (property_id) {
111
112                 case TILDA_WINDOW_NUMBER:
113                         g_value_set_int (value, self->number);
114                         break;
115
116                 default:
117                         /* We don't have this property */
118                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
119                         break;
120         }
121 }
122
123 static GObject *
124 tilda_window_constructor (GType                  type,
125                                                   guint                  n_construct_properties,
126                                                   GObjectConstructParam *construct_properties)
127 {
128         GObject *obj;
129         TildaWindow *self;
130
131         /* Invoke parent constructor */
132         TildaWindowClass *klass;
133         klass = TILDA_WINDOW_CLASS (g_type_class_peek (TILDA_TYPE_WINDOW));
134         obj = parent_class->constructor (type,
135                                                                          n_construct_properties,
136                                                                          construct_properties);
137
138         /* Do other stuff here. The object is ready to go now, and all
139          * ctor properties have been set.
140          *
141          * TODO: This is the place to do DBus-init */
142         self = TILDA_WINDOW(obj);
143
144         /* Register this object with DBus */
145         tilda_window_dbus_register_object (self);
146
147         gtk_container_add (GTK_CONTAINER(self->window), self->notebook);
148         gtk_widget_show (self->notebook);
149
150         tilda_window_add_term (self);
151         gtk_widget_show_all (self->window);
152
153         return obj;
154 }
155
156 static void
157 my_unref (gpointer data, gpointer user_data)
158 {
159         g_object_unref (G_OBJECT(data));
160 }
161
162 static void
163 tilda_window_dispose (GObject *obj)
164 {
165         TildaWindow *self = (TildaWindow *) obj;
166
167         /* We don't want to run dispose twice, so just return immediately */
168         if (self->dispose_has_run)
169                 return;
170
171         /*
172          * In dispose, you are supposed to free all types referenced from this
173          * object which might themselves hold a reference to self. Generally,
174          * the most simple solution is to unref all members on which you own a
175          * reference.
176          *
177          * NOTE: See the following for how to deal with GtkObject-derived things:
178          * http://library.gnome.org/devel/gtk/unstable/GtkObject.html
179          */
180         g_ptr_array_foreach (self->terms, my_unref, NULL);
181         gtk_widget_destroy (self->window);
182
183         /* Chain up to the parent class */
184         G_OBJECT_CLASS (parent_class)->dispose (obj);
185 }
186
187 static void
188 tilda_window_finalize (GObject *obj)
189 {
190         TildaWindow *self = (TildaWindow *) obj;
191
192         /*
193          * Here, complete the object's destruction.
194          * You might not need to do much...
195          */
196         // TODO: g_free() any primitives here
197         g_ptr_array_free (self->terms, TRUE);
198
199
200         /* Chain up to the parent class */
201         G_OBJECT_CLASS (parent_class)->finalize (obj);
202 }
203
204 static void
205 tilda_window_class_init (gpointer g_class,
206                                                  gpointer g_class_data)
207 {
208         GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
209         TildaWindowClass *klass = TILDA_WINDOW_CLASS (g_class);
210         GParamSpec *pspec;
211
212         /* Hook our functions to this type */
213         gobject_class->set_property = tilda_window_set_property;
214         gobject_class->get_property = tilda_window_get_property;
215         gobject_class->dispose = tilda_window_dispose;
216         gobject_class->finalize = tilda_window_finalize;
217         gobject_class->constructor = tilda_window_constructor;
218
219         parent_class = g_type_class_peek_parent (klass);
220
221         /* Install all of the properties */
222         pspec = g_param_spec_int ("number",
223                                                           "Window number",
224                                                           "Set window's number",
225                                                           0,            // min value
226                                                           INT_MAX,      // max value
227                                                           0,            // def value
228                                                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
229
230         g_object_class_install_property (gobject_class,
231                                                                          TILDA_WINDOW_NUMBER,
232                                                                          pspec);
233
234         /* TODO: more properties */
235
236         /* Hook the TildaWindow type into DBus */
237         dbus_g_object_type_install_info (tilda_window_get_type(), &dbus_glib_tilda_window_object_info);
238 }
239
240 GType
241 tilda_window_get_type (void)
242 {
243         static GType type = 0;
244
245         if (type == 0)
246         {
247                 static const GTypeInfo info = {
248                         sizeof (TildaWindowClass),
249                         NULL,   /* base_init */
250                         NULL,   /* base_finalize */
251                         tilda_window_class_init,        /* class_init */
252                         NULL,   /* class_finalize */
253                         NULL,   /* class_data */
254                         sizeof (TildaWindow),
255                         0,              /* n_preallocs */
256                         tilda_window_instance_init,     /* instance_init */
257                 };
258
259                 type = g_type_register_static (G_TYPE_OBJECT,
260                                                                            "TildaWindowType",
261                                                                            &info,
262                                                                            0);
263         }
264
265         return type;
266 }
267
268 #if 0
269
270 int main (int argc, char *argv[])
271 {
272         GObject *tw;
273         gint test_number = INT_MIN;
274
275         /* Initialize the GObject type system */
276         g_type_init ();
277         gtk_init (&argc, &argv);
278
279         tw = g_object_new (TILDA_TYPE_WINDOW, "number", 10, NULL);
280         g_object_get (G_OBJECT (tw), "number", &test_number, NULL);
281         g_assert (test_number == 10);
282
283         g_object_unref (G_OBJECT (tw));
284
285         tw = g_object_new (TILDA_TYPE_WINDOW, "number", 22, NULL);
286         g_object_get (G_OBJECT (tw), "number", &test_number, NULL);
287         g_assert (test_number == 22);
288
289         gtk_main ();
290
291         g_object_unref (G_OBJECT (tw));
292
293         return 0;
294 }
295
296 #endif
297
298 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */