Make TildaWindow properly generate terminal numbers
[tilda-gobject.git] / tilda-terminal.c
1 #include "tilda.h"
2 #include "tilda-terminal.h"
3 #include "tilda-terminal-dbus-glue.h"
4
5 static void
6 tilda_terminal_dbus_register_object (TildaTerminal *tt)
7 {
8         gchar *object_path;
9
10         // Register this object with DBus
11         object_path = g_strdup_printf ("/net/sourceforge/Tilda/Window%d/Terminal%d",
12                                                                    tt->window_number, tt->number);
13         dbus_g_connection_register_g_object (dbus_connection, object_path, G_OBJECT(tt));
14         g_free (object_path);
15 }
16
17 static GObjectClass *parent_class = NULL;
18
19 /* API */
20
21 /*
22  * All GObject stuff is below. You probably don't need to change this...
23  */
24
25 enum tilda_terminal_properties {
26         TILDA_TERMINAL_NUMBER = 1,
27         TILDA_TERMINAL_WINDOW_NUMBER,
28         TILDA_TERMINAL_TW,
29
30         /* All non-constructor-only properties */
31         TILDA_TERMINAL_BACKGROUND_IMAGE,
32         TILDA_TERMINAL_SHELL,
33         TILDA_TERMINAL_FONT,
34         TILDA_TERMINAL_TITLE,
35         TILDA_TERMINAL_WORKING_DIRECTORY,
36
37         TILDA_TERMINAL_SCROLLBACK_LINES,
38         TILDA_TERMINAL_TRANSPARENCY_PERCENT,
39
40         TILDA_TERMINAL_BACKSPACE_BINDING,
41         TILDA_TERMINAL_DELETE_BINDING,
42         TILDA_TERMINAL_DYNAMIC_TITLE,
43         TILDA_TERMINAL_EXIT_ACTION,
44 };
45
46 static void
47 tilda_terminal_instance_init (GTypeInstance *instance,
48                                                           gpointer       g_class)
49 {
50         TildaTerminal *self = (TildaTerminal *) instance;
51
52         /* Initialize instance members and allocate any necessary memory here.
53          * NOTE: any constructor-time values will be set later. */
54         self->dispose_has_run = FALSE;
55         self->number = 0;
56
57         self->vte_term = vte_terminal_new ();
58         self->scrollbar = gtk_vscrollbar_new (VTE_TERMINAL(self->vte_term)->adjustment);
59         self->hbox = gtk_hbox_new (FALSE, 0);
60 }
61
62 static void
63 tilda_terminal_set_property (GObject      *object,
64                                                          guint         property_id,
65                                                          const GValue *value,
66                                                          GParamSpec   *pspec)
67 {
68         TildaTerminal *self = (TildaTerminal *) object;
69
70         switch (property_id) {
71
72                 case TILDA_TERMINAL_NUMBER:
73                         self->number = g_value_get_int (value);
74                         g_print ("terminal number: %d\n", self->number);
75                         break;
76
77                 case TILDA_TERMINAL_WINDOW_NUMBER:
78                         self->window_number = g_value_get_int (value);
79                         g_print ("terminal parent window number: %d\n", self->window_number);
80                         break;
81
82                 case TILDA_TERMINAL_TW:
83                         self->parent_window = g_value_get_pointer (value);
84                         g_print ("terminal parent window: 0x%x\n", self->parent_window);
85                         g_print ("terminal parent window number (direct): %d\n", TILDA_WINDOW(self->parent_window)->number);
86                         break;
87
88                 case TILDA_TERMINAL_BACKGROUND_IMAGE:
89                         g_free (self->background_image);
90                         self->background_image = g_value_dup_string (value);
91                         // TODO: Actually set it in self->vte_term
92                         g_print ("terminal back img: %s\n", self->background_image);
93                         break;
94
95                 case TILDA_TERMINAL_SHELL:
96                         g_free (self->shell);
97                         self->shell = g_value_dup_string (value);
98                         g_print ("terminal shell: %s\n", self->shell);
99                         break;
100
101                 case TILDA_TERMINAL_FONT:
102                         g_free (self->font);
103                         self->font = g_value_dup_string (value);
104                         vte_terminal_set_font_from_string (VTE_TERMINAL(self->vte_term), self->font);
105                         g_print ("terminal font: %s\n", self->font);
106                         break;
107
108                 case TILDA_TERMINAL_TITLE:
109                         g_free (self->title);
110                         self->title = g_value_dup_string (value);
111                         g_print ("terminal title: %s\n", self->title);
112                         break;
113
114                 case TILDA_TERMINAL_WORKING_DIRECTORY:
115                         g_free (self->working_directory);
116                         self->working_directory = g_value_dup_string (value);
117                         g_print ("terminal wrk dir: %s\n", self->working_directory);
118                         break;
119
120                 case TILDA_TERMINAL_SCROLLBACK_LINES:
121                         self->scrollback_lines = g_value_get_int (value);
122                         g_print ("terminal scrollback lines: %d\n", self->scrollback_lines);
123                         break;
124
125                 case TILDA_TERMINAL_TRANSPARENCY_PERCENT:
126                         self->transparency_percent = g_value_get_int (value);
127                         g_print ("terminal transp percent: %d\n", self->transparency_percent);
128                         break;
129
130                 case TILDA_TERMINAL_BACKSPACE_BINDING:
131                         self->backspace_binding = g_value_get_int (value);
132                         //vte_terminal_set_backspace_binding (VTE_TERMINAL(self->vte_term), self->backspace_binding);
133                         g_print ("terminal backspace key: %d\n", self->backspace_binding);
134                         break;
135
136                 case TILDA_TERMINAL_DELETE_BINDING:
137                         self->delete_binding = g_value_get_int (value);
138                         //vte_terminal_set_delete_binding (VTE_TERMINAL(self->vte_term), self->delete_binding);
139                         g_print ("terminal delete key: %d\n", self->delete_binding);
140                         break;
141
142                 case TILDA_TERMINAL_DYNAMIC_TITLE:
143                         self->dynamic_title = g_value_get_int (value);
144                         g_print ("terminal dynamic title: %d\n", self->dynamic_title);
145                         break;
146
147                 case TILDA_TERMINAL_EXIT_ACTION:
148                         self->exit_action = g_value_get_int (value);
149                         g_print ("terminal exit action: %d\n", self->exit_action);
150                         break;
151
152                 default:
153                         /* We don't have this property... */
154                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
155                         break;
156         }
157 }
158
159 static void
160 tilda_terminal_get_property (GObject    *object,
161                                                          guint       property_id,
162                                                          GValue     *value,
163                                                          GParamSpec *pspec)
164 {
165         TildaTerminal *self = (TildaTerminal *) object;
166
167         switch (property_id) {
168
169                 case TILDA_TERMINAL_NUMBER:
170                         g_value_set_int (value, self->number);
171                         break;
172
173                 case TILDA_TERMINAL_WINDOW_NUMBER:
174                         g_value_set_int (value, self->window_number);
175                         break;
176
177                 case TILDA_TERMINAL_TW:
178                         g_value_set_pointer (value, self->parent_window);
179                         break;
180
181                 case TILDA_TERMINAL_BACKGROUND_IMAGE:
182                         g_value_set_string (value, self->background_image);
183                         break;
184
185                 case TILDA_TERMINAL_SHELL:
186                         g_value_set_string (value, self->shell);
187                         break;
188
189                 case TILDA_TERMINAL_FONT:
190                         g_value_set_string (value, self->font);
191                         break;
192
193                 case TILDA_TERMINAL_TITLE:
194                         g_value_set_string (value, self->title);
195                         break;
196
197                 case TILDA_TERMINAL_WORKING_DIRECTORY:
198                         g_value_set_string (value, self->working_directory);
199                         break;
200
201                 case TILDA_TERMINAL_SCROLLBACK_LINES:
202                         g_value_set_int (value, self->scrollback_lines);
203                         break;
204
205                 case TILDA_TERMINAL_TRANSPARENCY_PERCENT:
206                         g_value_set_int (value, self->transparency_percent);
207                         break;
208
209                 default:
210                         /* We don't have this property... */
211                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
212                         break;
213         }
214 }
215
216 static GObject *
217 tilda_terminal_constructor (GType                  type,
218                                                         guint                  n_construct_properties,
219                                                         GObjectConstructParam *construct_properties)
220 {
221         GObject *obj;
222         TildaTerminal *self;
223
224         /* Invoke parent constructor */
225         TildaTerminalClass *klass;
226         klass = TILDA_TERMINAL_CLASS (g_type_class_peek (TILDA_TYPE_TERMINAL));
227         obj = parent_class->constructor (type,
228                                                                          n_construct_properties,
229                                                                          construct_properties);
230
231         /* Do other stuff here. The object is ready to go now, and all
232          * ctor properties have been set.
233          *
234          * TODO: This is the place to do DBus-init */
235         self = TILDA_TERMINAL(obj);
236
237         /* Pack into the hbox */
238         gtk_box_pack_end (GTK_BOX(self->hbox), self->scrollbar, FALSE, FALSE, 0);
239         gtk_box_pack_end (GTK_BOX(self->hbox), self->vte_term, TRUE, TRUE, 0);
240         gtk_widget_show (self->scrollbar);
241
242
243         g_signal_connect (G_OBJECT(self->vte_term), "child-exited",
244                                           G_CALLBACK(gtk_main_quit), self);
245
246         vte_terminal_fork_command (VTE_TERMINAL(self->vte_term), NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE);
247
248         tilda_terminal_dbus_register_object (self);
249
250         return obj;
251 }
252
253 static void
254 tilda_terminal_dispose (GObject *obj)
255 {
256         TildaTerminal *self = (TildaTerminal *) obj;
257
258         /* We don't want to run dispose twice, so just return immediately */
259         if (self->dispose_has_run)
260                 return;
261
262         self->dispose_has_run = TRUE;
263
264         /*
265          * In dispose, you are supposed to free all types referenced from this
266          * object which might themselves hold a reference to self. Generally,
267          * the most simple solution is to unref all members on which you own a
268          * reference.
269          */
270
271         /* Chain up to the parent class */
272         G_OBJECT_CLASS (parent_class)->dispose (obj);
273 }
274
275 static void
276 tilda_terminal_finalize (GObject *obj)
277 {
278         TildaTerminal *self = (TildaTerminal *) obj;
279
280         /*
281          * Here, complete object destruction.
282          * You might not need to do much...
283          */
284
285         // TODO: g_free() any primitives here
286         g_free (self->background_image);
287         g_free (self->shell);
288         g_free (self->font);
289         g_free (self->title);
290         g_free (self->working_directory);
291
292
293         /* Chain up to the parent class */
294         G_OBJECT_CLASS (parent_class)->finalize (obj);
295 }
296
297 static void
298 tilda_terminal_class_init (gpointer g_class,
299                                                    gpointer g_class_data)
300 {
301         GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
302         TildaTerminalClass *klass = TILDA_TERMINAL_CLASS (g_class);
303         GParamSpec *pspec;
304
305         /* Hook our functions to this type */
306         gobject_class->set_property = tilda_terminal_set_property;
307         gobject_class->get_property = tilda_terminal_get_property;
308         gobject_class->dispose = tilda_terminal_dispose;
309         gobject_class->finalize = tilda_terminal_finalize;
310         gobject_class->constructor = tilda_terminal_constructor;
311
312         parent_class = g_type_class_peek_parent (klass);
313
314         /* Hook the TildaTerminal type into DBus */
315         dbus_g_object_type_install_info (tilda_terminal_get_type(), &dbus_glib_tilda_terminal_object_info);
316
317         /* Install all of the properties */
318         pspec = g_param_spec_int ("number",
319                                                           "Terminal number",
320                                                           "Set terminal's number",
321                                                           0,            // min value
322                                                           INT_MAX,      // max value
323                                                           0,            // def value
324                                                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
325
326         g_object_class_install_property (gobject_class,
327                                                                          TILDA_TERMINAL_NUMBER,
328                                                                          pspec);
329
330         pspec = g_param_spec_int ("window-number",
331                                                           "Number of the window to which this terminal belongs",
332                                                           "Set the number of the parent window",
333                                                           0,
334                                                           INT_MAX,
335                                                           0x0000beef,
336                                                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
337
338         g_object_class_install_property (gobject_class,
339                                                                          TILDA_TERMINAL_WINDOW_NUMBER,
340                                                                          pspec);
341
342         pspec = g_param_spec_pointer ("parent-window",
343                                                                   "Pointer to terminal's parent TildaWindow",
344                                                                   "Set the pointer to the terminal's parent TildaWindow",
345                                                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
346
347         g_object_class_install_property (gobject_class,
348                                                                          TILDA_TERMINAL_TW,
349                                                                          pspec);
350
351         pspec = g_param_spec_string ("background-image",
352                                                                  "Terminal's background image",
353                                                                  "Get/Set terminal's background image",
354                                                                  NULL,
355                                                                  G_PARAM_READWRITE);
356
357         g_object_class_install_property (gobject_class,
358                                                                          TILDA_TERMINAL_BACKGROUND_IMAGE,
359                                                                          pspec);
360
361         pspec = g_param_spec_string ("shell",
362                                                                  "Terminal's shell",
363                                                                  "Get/Set terminal's shell",
364                                                                  NULL,
365                                                                  G_PARAM_READWRITE);
366
367         g_object_class_install_property (gobject_class,
368                                                                          TILDA_TERMINAL_SHELL,
369                                                                          pspec);
370
371         pspec = g_param_spec_string ("font",
372                                                                  "Terminal's font",
373                                                                  "Get/Set terminal's font",
374                                                                  NULL,
375                                                                  G_PARAM_READWRITE);
376
377         g_object_class_install_property (gobject_class,
378                                                                          TILDA_TERMINAL_FONT,
379                                                                          pspec);
380
381         pspec = g_param_spec_string ("title",
382                                                                  "Terminal's title",
383                                                                  "Get/Set terminal's title",
384                                                                  NULL,
385                                                                  G_PARAM_READWRITE);
386
387         g_object_class_install_property (gobject_class,
388                                                                          TILDA_TERMINAL_TITLE,
389                                                                          pspec);
390
391         pspec = g_param_spec_string ("working-directory",
392                                                                  "Terminal's initial working directory",
393                                                                  "Get/Set terminal's initial working directory",
394                                                                  NULL,
395                                                                  G_PARAM_READWRITE);
396
397         g_object_class_install_property (gobject_class,
398                                                                          TILDA_TERMINAL_WORKING_DIRECTORY,
399                                                                          pspec);
400
401         pspec = g_param_spec_int ("scrollback-lines",
402                                                           "Terminal's scrollback amount (lines)",
403                                                           "Get/Set terminal's scrollback amount",
404                                                           0,
405                                                           INT_MAX, // TODO: artificially limit this?
406                                                           1000,
407                                                           G_PARAM_READWRITE);
408
409         g_object_class_install_property (gobject_class,
410                                                                          TILDA_TERMINAL_SCROLLBACK_LINES,
411                                                                          pspec);
412
413         pspec = g_param_spec_int ("transparency-percent",
414                                                           "Terminal's transparency (percent)",
415                                                           "Get/Set terminal's transparency",
416                                                           0,
417                                                           100,
418                                                           0,
419                                                           G_PARAM_READWRITE);
420
421         g_object_class_install_property (gobject_class,
422                                                                          TILDA_TERMINAL_TRANSPARENCY_PERCENT,
423                                                                          pspec);
424 }
425
426 GType
427 tilda_terminal_get_type (void)
428 {
429         static GType type = 0;
430
431         if (type == 0)
432         {
433                 static const GTypeInfo info = {
434                         sizeof (TildaTerminalClass),
435                         NULL,   /* base_init */
436                         NULL,   /* base_finalize */
437                         tilda_terminal_class_init,      /* class_init */
438                         NULL,   /* class_finalize */
439                         NULL,   /* class_data */
440                         sizeof (TildaTerminal),
441                         0,              /* n_preallocs */
442                         tilda_terminal_instance_init,   /* instance_init */
443                 };
444
445                 type = g_type_register_static (G_TYPE_OBJECT,
446                                                                            "TildaTerminalType",
447                                                                            &info,
448                                                                            0);
449         }
450
451         return type;
452 }
453
454 #if 0
455
456 int main (int argc, char *argv[])
457 {
458         GObject *tt;
459         gint test_number = INT_MIN;
460         gchar *test_string = NULL;
461
462         /* Initialize the GObject type system */
463         g_type_init ();
464         gtk_init (&argc, &argv);
465
466         tt = g_object_new (TILDA_TYPE_TERMINAL, "number", 10, NULL);
467         g_object_get (G_OBJECT (tt), "number", &test_number, NULL);
468         g_assert (test_number == 10);
469
470         g_object_unref (G_OBJECT (tt));
471
472         tt = g_object_new (TILDA_TYPE_TERMINAL, "number", 22, NULL);
473         g_object_get (G_OBJECT (tt), "number", &test_number, NULL);
474         g_assert (test_number == 22);
475
476         g_object_set (G_OBJECT (tt), "font", "hello I'm a font");
477         g_object_set (G_OBJECT (tt), "font", "Bitstream Vera Sans Mono 13");
478
479         g_object_get (G_OBJECT (tt), "font", &test_string, NULL);
480         g_print ("Read Font: %s\n", test_string);
481         // NOTE: you MUST free the string!!!!
482         g_free (test_string);
483
484         g_object_set (G_OBJECT (tt), "transparency-percent", 50);
485
486         g_object_unref (G_OBJECT (tt));
487
488         return 0;
489 }
490
491 #endif
492
493 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */