[Terminal] Add web browser property
[tilda-gobject.git] / tilda-terminal.c
1 #include "tilda.h"
2 #include "tilda-terminal.h"
3 #include "tilda-terminal-dbus-glue.h"
4
5 // FIXME: temporary helpers for gettext
6 // TODO:  remove these
7 #define _(X) X
8 #define N_(X) X
9
10 static void
11 tilda_terminal_dbus_register_object (TildaTerminal *tt)
12 {
13         gchar *object_path;
14
15         // Register this object with DBus
16         object_path = g_strdup_printf ("/net/sourceforge/Tilda/Window%d/Terminal%d",
17                                                                    tt->window_number, tt->number);
18         dbus_g_connection_register_g_object (dbus_connection, object_path, G_OBJECT(tt));
19         g_free (object_path);
20 }
21
22 /**
23  * Start the current tt->shell in the given TildaTerminal
24  * NOTE: this will kill whatever is running in the terminal,
25  * NOTE: and run the current tt->shell instead :)
26  * Return: TRUE if ok, FALSE otherwise
27  */
28 static gboolean
29 tilda_terminal_start_shell (TildaTerminal *tt)
30 {
31         gint ret;
32         gint argc;
33         gchar **argv;
34         GError *error = NULL;
35
36         /* Launch a custom command if tt->shell is set (not NULL) */
37         if (tt->shell)
38         {
39                 /* Try to parse the user's custom command */
40                 ret = g_shell_parse_argv (tt->shell, &argc, &argv, &error);
41
42                 if (ret == FALSE)
43                 {
44                         g_printerr (_("Problem parsing custom command: %s\n"), error->message);
45                         g_printerr (_("Launching default shell instead\n"));
46
47                         g_error_free (error);
48                         goto launch_default_shell;
49                 }
50
51                 /* Try to start the user's custom command */
52                 ret = vte_terminal_fork_command (VTE_TERMINAL(tt->vte_term),
53                                                                                  argv[0], /* Command */
54                                                                                  argv,    /* Arg Vector */
55                                                                                  NULL,    /* Env Vector */
56                                                                                  tt->working_directory, /* Start directory */
57                                                                                  TRUE,    /* Add to lastlog */
58                                                                                  TRUE,    /* Add to utmp */
59                                                                                  TRUE);   /* Add to wtmp */
60
61                 g_strfreev (argv);
62
63                 /* Check for error */
64                 if (ret == -1)
65                 {
66                         g_printerr (_("Unable to launch custom command: %s\n"), tt->shell);
67                         g_printerr (_("Launching default shell instead\n"));
68
69                         goto launch_default_shell;
70                 }
71
72                 return TRUE; /* SUCCESS: the early way out */
73         }
74
75 launch_default_shell:
76
77     ret = vte_terminal_fork_command (VTE_TERMINAL(tt->vte_term),
78                                                                          NULL, /* Command -- VTE will figure it out */
79                                                                          NULL, /* Arg Vector */
80                                                                          NULL, /* Env Vector */
81                                                                          tt->working_directory, /* Start Directory */
82                                                                          TRUE, /* Add to lastlog */
83                                                                          TRUE, /* Add to utmp */
84                                                                          TRUE);/* Add to wtmp */
85
86         if (ret == -1)
87         {
88                 g_printerr (_("Unable to launch default shell\n"));
89                 return FALSE;
90         }
91
92         return TRUE;
93 }
94
95 /**
96  * Called when the child process running in the VteTerminal exits.
97  */
98 static void
99 tilda_terminal_child_exited_cb (GtkWidget *widget, gpointer data)
100 {
101         TildaTerminal *self = TILDA_TERMINAL(data);
102
103         /* These can stay here. They don't need to go into a header because
104          * they are only used at this point in the code. */
105         enum exit_actions { HOLD_TERMINAL_OPEN, RESTART_COMMAND, EXIT_TERMINAL };
106
107         /* Check the user's preference for what to do when the child terminal
108          * is closed. Take the appropriate action */
109         switch (self->exit_action)
110         {
111                 case EXIT_TERMINAL:
112                         tilda_window_remove_term (TILDA_WINDOW(self->parent_window), self->number);
113                         break;
114                 case RESTART_COMMAND:
115                         vte_terminal_feed (VTE_TERMINAL(self->vte_term), "\r\n\r\n", 4);
116                         tilda_terminal_start_shell (self);
117                         break;
118                 case HOLD_TERMINAL_OPEN:
119                         break;
120                 default:
121                         break;
122         }
123 }
124
125 /**
126  * Called when the child window title changes. Determines if a new
127  * title needs to be put into the notebook's tab label.
128  */
129 static void
130 tilda_terminal_window_title_changed_cb (GtkWidget *widget, gpointer data)
131 {
132         TildaTerminal *self = TILDA_TERMINAL(data);
133         TildaWindow *parent_window = TILDA_WINDOW(self->parent_window);
134         GtkWidget *label;
135         const gchar *vte_title;
136         gchar *new_title;
137
138         enum dynamic_titles { NOT_DISPLAYED, AFTER_INITIAL, BEFORE_INITIAL, REPLACE_INITIAL };
139         label = gtk_notebook_get_tab_label (GTK_NOTEBOOK(parent_window->notebook), self->hbox);
140
141         /* If we aren't using a dynamic title -- NOT_DISPLAYED -- then just
142          * set it to the static title and exit */
143         if (!self->dynamic_title)
144         {
145                 gtk_label_set_text (GTK_LABEL(label), self->title);
146                 return;
147         }
148
149         /* Get the title from VTE */
150         vte_title = vte_terminal_get_window_title (VTE_TERMINAL (widget));
151
152         /* Take the appropriate action */
153         switch (self->dynamic_title)
154         {
155                 case REPLACE_INITIAL:
156                         new_title = g_strdup (vte_title);
157                         break;
158
159                 case BEFORE_INITIAL:
160                         new_title = g_strdup_printf ("%s - %s", vte_title, self->title);
161                         break;
162
163                 case AFTER_INITIAL:
164                         new_title = g_strdup_printf ("%s - %s", self->title, vte_title);
165                         break;
166
167                 case NOT_DISPLAYED:
168                 default:
169                         g_printerr (_("FIXME: Bad value of self->dynamic_title\n"));
170                         new_title = g_strdup(self->title);
171                         break;
172         }
173
174         gtk_label_set_text (GTK_LABEL(label), new_title);
175         g_free (new_title);
176 }
177
178 /**
179  * Set the given TildaTerminal to the appropriate transparency level
180  * based on the self->transparency_percent member. */
181 static void
182 tilda_terminal_set_transparent (TildaTerminal *self)
183 {
184         TildaWindow *parent_window = TILDA_WINDOW(self->parent_window);
185         gdouble temp;
186
187         /* Convert the transparency to VTE's format */
188         temp = ((gdouble) self->transparency_percent) / 100.0;
189
190         if (self->transparency_percent > 0)
191         {
192                 vte_terminal_set_background_saturation (VTE_TERMINAL(self->vte_term), temp);
193                 vte_terminal_set_opacity (VTE_TERMINAL(self->vte_term), (1.0 - temp) * 0xffff);
194
195                 /* Use fake transparency if necessary */
196                 vte_terminal_set_background_transparent (VTE_TERMINAL(self->vte_term),
197                                                                                                  !parent_window->have_real_transparency);
198                 return;
199         }
200
201         /* Turn off transparency */
202         vte_terminal_set_background_saturation (VTE_TERMINAL(self->vte_term), 0);
203         vte_terminal_set_opacity (VTE_TERMINAL(self->vte_term), 0xffff);
204         vte_terminal_set_background_transparent (VTE_TERMINAL(self->vte_term), FALSE);
205 }
206
207 /*******************************************************************************
208  * All GObject stuff is below. You probably don't need to change this...
209  ******************************************************************************/
210
211 static GObjectClass *parent_class = NULL;
212
213 enum tilda_terminal_properties {
214         TILDA_TERMINAL_NUMBER = 1,
215         TILDA_TERMINAL_WINDOW_NUMBER,
216         TILDA_TERMINAL_TW,
217
218         /* All non-constructor-only properties */
219         TILDA_TERMINAL_BACKGROUND_IMAGE,
220         TILDA_TERMINAL_SHELL,
221         TILDA_TERMINAL_FONT,
222         TILDA_TERMINAL_TITLE,
223         TILDA_TERMINAL_WORKING_DIRECTORY,
224         TILDA_TERMINAL_WEB_BROWSER,
225
226         TILDA_TERMINAL_SCROLLBACK_LINES,
227         TILDA_TERMINAL_TRANSPARENCY_PERCENT,
228
229         TILDA_TERMINAL_BACKSPACE_BINDING,
230         TILDA_TERMINAL_DELETE_BINDING,
231         TILDA_TERMINAL_DYNAMIC_TITLE,
232         TILDA_TERMINAL_EXIT_ACTION,
233
234         TILDA_TERMINAL_SCROLL_BACKGROUND,
235         TILDA_TERMINAL_SCROLL_ON_OUTPUT,
236         TILDA_TERMINAL_SCROLL_ON_KEYSTROKE,
237         TILDA_TERMINAL_ANTIALIASED,
238         TILDA_TERMINAL_ALLOW_BOLD_TEXT,
239         TILDA_TERMINAL_CURSOR_BLINKS,
240         TILDA_TERMINAL_AUDIBLE_BELL,
241         TILDA_TERMINAL_VISIBLE_BELL,
242         TILDA_TERMINAL_DOUBLE_BUFFERED,
243         TILDA_TERMINAL_MOUSE_AUTOHIDE,
244 };
245
246 static void
247 tilda_terminal_instance_init (GTypeInstance *instance,
248                                                           gpointer       g_class)
249 {
250         TildaTerminal *self = (TildaTerminal *) instance;
251
252         /* Initialize instance members and allocate any necessary memory here.
253          * NOTE: any constructor-time values will be set later. */
254         self->dispose_has_run = FALSE;
255         self->number = 0;
256
257         self->vte_term = vte_terminal_new ();
258         self->scrollbar = gtk_vscrollbar_new (VTE_TERMINAL(self->vte_term)->adjustment);
259         self->hbox = gtk_hbox_new (FALSE, 0);
260 }
261
262 static void
263 tilda_terminal_set_property (GObject      *object,
264                                                          guint         property_id,
265                                                          const GValue *value,
266                                                          GParamSpec   *pspec)
267 {
268         TildaTerminal *self = (TildaTerminal *) object;
269
270         switch (property_id) {
271
272                 case TILDA_TERMINAL_NUMBER:
273                         self->number = g_value_get_int (value);
274                         g_print ("terminal number: %d\n", self->number);
275                         break;
276
277                 case TILDA_TERMINAL_WINDOW_NUMBER:
278                         self->window_number = g_value_get_int (value);
279                         g_print ("terminal parent window number: %d\n", self->window_number);
280                         break;
281
282                 case TILDA_TERMINAL_TW:
283                         self->parent_window = g_value_get_pointer (value);
284                         g_print ("terminal parent window: 0x%x\n", self->parent_window);
285                         g_print ("terminal parent window number (direct): %d\n", TILDA_WINDOW(self->parent_window)->number);
286                         break;
287
288                 case TILDA_TERMINAL_BACKGROUND_IMAGE:
289                         g_free (self->background_image);
290                         self->background_image = g_value_dup_string (value);
291                         vte_terminal_set_background_image_file (VTE_TERMINAL(self->vte_term), self->background_image);
292                         g_print ("terminal back img: %s\n", self->background_image);
293                         break;
294
295                 case TILDA_TERMINAL_SHELL:
296                         g_free (self->shell);
297                         self->shell = g_value_dup_string (value);
298                         tilda_terminal_start_shell (self);
299                         g_print ("terminal shell: %s\n", self->shell);
300                         break;
301
302                 case TILDA_TERMINAL_FONT:
303                         g_free (self->font);
304                         self->font = g_value_dup_string (value);
305                         vte_terminal_set_font_from_string_full (VTE_TERMINAL(self->vte_term),
306                                                                                                         self->font,
307                                                                                                         self->antialiased);
308                         g_print ("terminal font: %s\n", self->font);
309                         break;
310
311                 case TILDA_TERMINAL_TITLE:
312                         g_free (self->title);
313                         self->title = g_value_dup_string (value);
314                         g_print ("terminal title: %s\n", self->title);
315                         break;
316
317                 case TILDA_TERMINAL_WORKING_DIRECTORY:
318                         g_free (self->working_directory);
319                         self->working_directory = g_value_dup_string (value);
320                         g_print ("terminal wrk dir: %s\n", self->working_directory);
321                         break;
322
323                 case TILDA_TERMINAL_WEB_BROWSER:
324                         g_free (self->web_browser);
325                         self->web_browser = g_value_dup_string (value);
326                         g_print ("terminal web browser: %s\n", self->web_browser);
327                         break;
328
329                 case TILDA_TERMINAL_SCROLLBACK_LINES:
330                         self->scrollback_lines = g_value_get_int (value);
331                         vte_terminal_set_scrollback_lines (VTE_TERMINAL(self->vte_term), self->scrollback_lines);
332                         g_print ("terminal scrollback lines: %d\n", self->scrollback_lines);
333                         break;
334
335                 case TILDA_TERMINAL_TRANSPARENCY_PERCENT:
336                         self->transparency_percent = g_value_get_int (value);
337                         tilda_terminal_set_transparent (self);
338                         g_print ("terminal transp percent: %d\n", self->transparency_percent);
339                         break;
340
341                 case TILDA_TERMINAL_BACKSPACE_BINDING:
342                         self->backspace_binding = g_value_get_int (value);
343                         vte_terminal_set_backspace_binding (VTE_TERMINAL(self->vte_term), self->backspace_binding);
344                         g_print ("terminal backspace key: %d\n", self->backspace_binding);
345                         break;
346
347                 case TILDA_TERMINAL_DELETE_BINDING:
348                         self->delete_binding = g_value_get_int (value);
349                         vte_terminal_set_delete_binding (VTE_TERMINAL(self->vte_term), self->delete_binding);
350                         g_print ("terminal delete key: %d\n", self->delete_binding);
351                         break;
352
353                 case TILDA_TERMINAL_DYNAMIC_TITLE:
354                         self->dynamic_title = g_value_get_int (value);
355                         g_print ("terminal dynamic title: %d\n", self->dynamic_title);
356                         break;
357
358                 case TILDA_TERMINAL_EXIT_ACTION:
359                         self->exit_action = g_value_get_int (value);
360                         g_print ("terminal exit action: %d\n", self->exit_action);
361                         break;
362
363                 case TILDA_TERMINAL_SCROLL_BACKGROUND:
364                         self->scroll_background = g_value_get_boolean (value);
365                         vte_terminal_set_scroll_background (VTE_TERMINAL(self->vte_term), self->scroll_background);
366                         g_print ("terminal scroll background: %d\n", self->scroll_background);
367                         break;
368
369                 case TILDA_TERMINAL_SCROLL_ON_OUTPUT:
370                         self->scroll_on_output = g_value_get_boolean (value);
371                         vte_terminal_set_scroll_on_output (VTE_TERMINAL(self->vte_term), self->scroll_on_output);
372                         g_print ("terminal scroll on output: %d\n", self->scroll_on_output);
373                         break;
374
375                 case TILDA_TERMINAL_SCROLL_ON_KEYSTROKE:
376                         self->scroll_on_keystroke = g_value_get_boolean (value);
377                         vte_terminal_set_scroll_on_keystroke (VTE_TERMINAL(self->vte_term), self->scroll_on_keystroke);
378                         g_print ("terminal scroll on keystroke: %d\n", self->scroll_on_keystroke);
379                         break;
380
381                 case TILDA_TERMINAL_ANTIALIASED:
382                         self->antialiased = g_value_get_boolean (value);
383                         vte_terminal_set_font_from_string_full (VTE_TERMINAL(self->vte_term),
384                                                                                                         self->font,
385                                                                                                         self->antialiased);
386                         g_print ("terminal antialiased: %d\n", self->antialiased);
387                         break;
388
389                 case TILDA_TERMINAL_ALLOW_BOLD_TEXT:
390                         self->allow_bold_text = g_value_get_boolean (value);
391                         vte_terminal_set_allow_bold (VTE_TERMINAL(self->vte_term), self->allow_bold_text);
392                         g_print ("terminal allow bold text: %d\n", self->allow_bold_text);
393                         break;
394
395                 case TILDA_TERMINAL_CURSOR_BLINKS:
396                         self->cursor_blinks = g_value_get_boolean (value);
397                         vte_terminal_set_cursor_blinks (VTE_TERMINAL(self->vte_term), self->cursor_blinks);
398                         g_print ("terminal cursor blinks: %d\n", self->cursor_blinks);
399                         break;
400
401                 case TILDA_TERMINAL_AUDIBLE_BELL:
402                         self->audible_bell = g_value_get_boolean (value);
403                         vte_terminal_set_audible_bell (VTE_TERMINAL(self->vte_term), self->audible_bell);
404                         g_print ("terminal audible bell: %d\n", self->audible_bell);
405                         break;
406
407                 case TILDA_TERMINAL_VISIBLE_BELL:
408                         self->visible_bell = g_value_get_boolean (value);
409                         vte_terminal_set_visible_bell (VTE_TERMINAL(self->vte_term), self->visible_bell);
410                         g_print ("terminal visible bell: %d\n", self->visible_bell);
411                         break;
412
413                 case TILDA_TERMINAL_DOUBLE_BUFFERED:
414                         self->double_buffered = g_value_get_boolean (value);
415                         gtk_widget_set_double_buffered (GTK_WIDGET(self->vte_term), self->double_buffered);
416                         g_print ("terminal double buffered: %d\n", self->double_buffered);
417                         break;
418
419                 case TILDA_TERMINAL_MOUSE_AUTOHIDE:
420                         self->mouse_autohide = g_value_get_boolean (value);
421                         vte_terminal_set_mouse_autohide (VTE_TERMINAL(self->vte_term), self->mouse_autohide);
422                         g_print ("terminal mouse autohide: %d\n", self->mouse_autohide);
423                         break;
424
425                 default:
426                         /* We don't have this property... */
427                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
428                         break;
429         }
430 }
431
432 static void
433 tilda_terminal_get_property (GObject    *object,
434                                                          guint       property_id,
435                                                          GValue     *value,
436                                                          GParamSpec *pspec)
437 {
438         TildaTerminal *self = (TildaTerminal *) object;
439
440         switch (property_id) {
441
442                 case TILDA_TERMINAL_NUMBER:
443                         g_value_set_int (value, self->number);
444                         break;
445
446                 case TILDA_TERMINAL_WINDOW_NUMBER:
447                         g_value_set_int (value, self->window_number);
448                         break;
449
450                 case TILDA_TERMINAL_TW:
451                         g_value_set_pointer (value, self->parent_window);
452                         break;
453
454                 case TILDA_TERMINAL_BACKGROUND_IMAGE:
455                         g_value_set_string (value, self->background_image);
456                         break;
457
458                 case TILDA_TERMINAL_SHELL:
459                         g_value_set_string (value, self->shell);
460                         break;
461
462                 case TILDA_TERMINAL_FONT:
463                         g_value_set_string (value, self->font);
464                         break;
465
466                 case TILDA_TERMINAL_TITLE:
467                         g_value_set_string (value, self->title);
468                         break;
469
470                 case TILDA_TERMINAL_WORKING_DIRECTORY:
471                         g_value_set_string (value, self->working_directory);
472                         break;
473
474                 case TILDA_TERMINAL_WEB_BROWSER:
475                         g_value_set_string (value, self->web_browser);
476                         break;
477
478                 case TILDA_TERMINAL_SCROLLBACK_LINES:
479                         g_value_set_int (value, self->scrollback_lines);
480                         break;
481
482                 case TILDA_TERMINAL_TRANSPARENCY_PERCENT:
483                         g_value_set_int (value, self->transparency_percent);
484                         break;
485
486                 case TILDA_TERMINAL_BACKSPACE_BINDING:
487                         g_value_set_int (value, self->backspace_binding);
488                         break;
489
490                 case TILDA_TERMINAL_DELETE_BINDING:
491                         g_value_set_int (value, self->delete_binding);
492                         break;
493
494                 case TILDA_TERMINAL_DYNAMIC_TITLE:
495                         g_value_set_int (value, self->dynamic_title);
496                         break;
497
498                 case TILDA_TERMINAL_EXIT_ACTION:
499                         g_value_set_int (value, self->exit_action);
500                         break;
501
502                 case TILDA_TERMINAL_SCROLL_BACKGROUND:
503                         g_value_set_boolean (value, self->scroll_background);
504                         break;
505
506                 case TILDA_TERMINAL_SCROLL_ON_OUTPUT:
507                         g_value_set_boolean (value, self->scroll_on_output);
508                         break;
509
510                 case TILDA_TERMINAL_SCROLL_ON_KEYSTROKE:
511                         g_value_set_boolean (value, self->scroll_on_keystroke);
512                         break;
513
514                 case TILDA_TERMINAL_ANTIALIASED:
515                         g_value_set_boolean (value, self->antialiased);
516                         break;
517
518                 case TILDA_TERMINAL_ALLOW_BOLD_TEXT:
519                         g_value_set_boolean (value, self->allow_bold_text);
520                         break;
521
522                 case TILDA_TERMINAL_CURSOR_BLINKS:
523                         g_value_set_boolean (value, self->cursor_blinks);
524                         break;
525
526                 case TILDA_TERMINAL_AUDIBLE_BELL:
527                         g_value_set_boolean (value, self->audible_bell);
528                         break;
529
530                 case TILDA_TERMINAL_VISIBLE_BELL:
531                         g_value_set_boolean (value, self->visible_bell);
532                         break;
533
534                 case TILDA_TERMINAL_DOUBLE_BUFFERED:
535                         g_value_set_boolean (value, self->double_buffered);
536                         break;
537
538                 case TILDA_TERMINAL_MOUSE_AUTOHIDE:
539                         g_value_set_boolean (value, self->mouse_autohide);
540
541                 default:
542                         /* We don't have this property... */
543                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
544                         break;
545         }
546 }
547
548 static GObject *
549 tilda_terminal_constructor (GType                  type,
550                                                         guint                  n_construct_properties,
551                                                         GObjectConstructParam *construct_properties)
552 {
553         GObject *obj;
554         TildaTerminal *self;
555
556         /* Invoke parent constructor */
557         TildaTerminalClass *klass;
558         klass = TILDA_TERMINAL_CLASS (g_type_class_peek (TILDA_TYPE_TERMINAL));
559         obj = parent_class->constructor (type,
560                                                                          n_construct_properties,
561                                                                          construct_properties);
562
563         /* Do other stuff here. The object is ready to go now, and all
564          * ctor properties have been set.
565          *
566          * TODO: This is the place to do DBus-init */
567         self = TILDA_TERMINAL(obj);
568
569         /* Pack into the hbox */
570         gtk_box_pack_end (GTK_BOX(self->hbox), self->scrollbar, FALSE, FALSE, 0);
571         gtk_box_pack_end (GTK_BOX(self->hbox), self->vte_term, TRUE, TRUE, 0);
572         gtk_widget_show (self->scrollbar);
573
574
575         /* Connect Signals */
576         g_signal_connect (G_OBJECT(self->vte_term), "child-exited",
577                                           G_CALLBACK(tilda_terminal_child_exited_cb), self);
578         g_signal_connect (G_OBJECT(self->vte_term), "eof",
579                                           G_CALLBACK(tilda_terminal_child_exited_cb), self);
580         g_signal_connect (G_OBJECT(self->vte_term), "window-title-changed",
581                                           G_CALLBACK(tilda_terminal_window_title_changed_cb), self);
582
583         tilda_terminal_start_shell (self);
584         tilda_terminal_dbus_register_object (self);
585
586         return obj;
587 }
588
589 static void
590 tilda_terminal_dispose (GObject *obj)
591 {
592         TildaTerminal *self = (TildaTerminal *) obj;
593
594         /* We don't want to run dispose twice, so just return immediately */
595         if (self->dispose_has_run)
596                 return;
597
598         self->dispose_has_run = TRUE;
599
600         /*
601          * In dispose, you are supposed to free all types referenced from this
602          * object which might themselves hold a reference to self. Generally,
603          * the most simple solution is to unref all members on which you own a
604          * reference.
605          */
606
607         /* Chain up to the parent class */
608         G_OBJECT_CLASS (parent_class)->dispose (obj);
609 }
610
611 static void
612 tilda_terminal_finalize (GObject *obj)
613 {
614         TildaTerminal *self = (TildaTerminal *) obj;
615
616         /*
617          * Here, complete object destruction.
618          * You might not need to do much...
619          */
620
621         // TODO: g_free() any primitives here
622         g_free (self->background_image);
623         g_free (self->shell);
624         g_free (self->font);
625         g_free (self->title);
626         g_free (self->working_directory);
627
628
629         /* Chain up to the parent class */
630         G_OBJECT_CLASS (parent_class)->finalize (obj);
631 }
632
633 static void
634 tilda_terminal_class_init (gpointer g_class,
635                                                    gpointer g_class_data)
636 {
637         GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
638         TildaTerminalClass *klass = TILDA_TERMINAL_CLASS (g_class);
639         GParamSpec *pspec;
640
641         /* Hook our functions to this type */
642         gobject_class->set_property = tilda_terminal_set_property;
643         gobject_class->get_property = tilda_terminal_get_property;
644         gobject_class->dispose = tilda_terminal_dispose;
645         gobject_class->finalize = tilda_terminal_finalize;
646         gobject_class->constructor = tilda_terminal_constructor;
647
648         parent_class = g_type_class_peek_parent (klass);
649
650         /* Hook the TildaTerminal type into DBus */
651         dbus_g_object_type_install_info (tilda_terminal_get_type(), &dbus_glib_tilda_terminal_object_info);
652
653         /* Install all of the properties */
654         pspec = g_param_spec_int ("number",
655                                                           "Terminal number",
656                                                           "Set terminal's number",
657                                                           0,            // min value
658                                                           INT_MAX,      // max value
659                                                           0,            // def value
660                                                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
661
662         g_object_class_install_property (gobject_class,
663                                                                          TILDA_TERMINAL_NUMBER,
664                                                                          pspec);
665
666         pspec = g_param_spec_int ("window-number",
667                                                           "Number of the window to which this terminal belongs",
668                                                           "Set the number of the parent window",
669                                                           0,
670                                                           INT_MAX,
671                                                           0x0000beef,
672                                                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
673
674         g_object_class_install_property (gobject_class,
675                                                                          TILDA_TERMINAL_WINDOW_NUMBER,
676                                                                          pspec);
677
678         pspec = g_param_spec_pointer ("parent-window",
679                                                                   "Pointer to terminal's parent TildaWindow",
680                                                                   "Set the pointer to the terminal's parent TildaWindow",
681                                                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
682
683         g_object_class_install_property (gobject_class,
684                                                                          TILDA_TERMINAL_TW,
685                                                                          pspec);
686
687         pspec = g_param_spec_string ("background-image",
688                                                                  "Terminal's background image",
689                                                                  "Get/Set terminal's background image",
690                                                                  NULL,
691                                                                  G_PARAM_READWRITE);
692
693         g_object_class_install_property (gobject_class,
694                                                                          TILDA_TERMINAL_BACKGROUND_IMAGE,
695                                                                          pspec);
696
697         pspec = g_param_spec_string ("shell",
698                                                                  "Terminal's shell",
699                                                                  "Get/Set terminal's shell",
700                                                                  NULL,
701                                                                  G_PARAM_READWRITE);
702
703         g_object_class_install_property (gobject_class,
704                                                                          TILDA_TERMINAL_SHELL,
705                                                                          pspec);
706
707         pspec = g_param_spec_string ("font",
708                                                                  "Terminal's font",
709                                                                  "Get/Set terminal's font",
710                                                                  NULL,
711                                                                  G_PARAM_READWRITE);
712
713         g_object_class_install_property (gobject_class,
714                                                                          TILDA_TERMINAL_FONT,
715                                                                          pspec);
716
717         pspec = g_param_spec_string ("title",
718                                                                  "Terminal's title",
719                                                                  "Get/Set terminal's title",
720                                                                  NULL,
721                                                                  G_PARAM_READWRITE);
722
723         g_object_class_install_property (gobject_class,
724                                                                          TILDA_TERMINAL_TITLE,
725                                                                          pspec);
726
727         pspec = g_param_spec_string ("working-directory",
728                                                                  "Terminal's initial working directory",
729                                                                  "Get/Set terminal's initial working directory",
730                                                                  NULL,
731                                                                  G_PARAM_READWRITE);
732
733         g_object_class_install_property (gobject_class,
734                                                                          TILDA_TERMINAL_WORKING_DIRECTORY,
735                                                                          pspec);
736
737         pspec = g_param_spec_string ("web-browser",
738                                                                  "Terminal's web browser command",
739                                                                  NULL,
740                                                                  NULL,
741                                                                  G_PARAM_READWRITE);
742
743         g_object_class_install_property (gobject_class,
744                                                                          TILDA_TERMINAL_WEB_BROWSER,
745                                                                          pspec);
746
747         pspec = g_param_spec_int ("scrollback-lines",
748                                                           "Terminal's scrollback amount (lines)",
749                                                           "Get/Set terminal's scrollback amount",
750                                                           0,
751                                                           INT_MAX, // TODO: artificially limit this?
752                                                           1000,
753                                                           G_PARAM_READWRITE);
754
755         g_object_class_install_property (gobject_class,
756                                                                          TILDA_TERMINAL_SCROLLBACK_LINES,
757                                                                          pspec);
758
759         pspec = g_param_spec_int ("transparency-percent",
760                                                           "Terminal's transparency (percent)",
761                                                           "Get/Set terminal's transparency",
762                                                           0,
763                                                           100,
764                                                           0,
765                                                           G_PARAM_READWRITE);
766
767         g_object_class_install_property (gobject_class,
768                                                                          TILDA_TERMINAL_TRANSPARENCY_PERCENT,
769                                                                          pspec);
770
771         pspec = g_param_spec_int ("backspace-binding",
772                                                           "Terminal's backspace binding",
773                                                           "Get/Set terminal's backspace key binding",
774                                                           VTE_ERASE_AUTO,
775                                                           VTE_ERASE_DELETE_SEQUENCE,
776                                                           VTE_ERASE_AUTO,
777                                                           G_PARAM_READWRITE);
778
779         g_object_class_install_property (gobject_class,
780                                                                          TILDA_TERMINAL_BACKSPACE_BINDING,
781                                                                          pspec);
782
783         pspec = g_param_spec_int ("delete-binding",
784                                                           "Terminal's delete binding",
785                                                           "Get/Set terminal's delete key binding",
786                                                           VTE_ERASE_AUTO,
787                                                           VTE_ERASE_DELETE_SEQUENCE,
788                                                           VTE_ERASE_AUTO,
789                                                           G_PARAM_READWRITE);
790
791         g_object_class_install_property (gobject_class,
792                                                                          TILDA_TERMINAL_DELETE_BINDING,
793                                                                          pspec);
794
795         pspec = g_param_spec_int ("dynamic-title",
796                                                           "Terminal's dynamic title generation method",
797                                                           "Get/Set terminal's dynamic title generation method",
798                                                           0,
799                                                           INT_MAX,
800                                                           0,
801                                                           G_PARAM_READWRITE);
802
803         g_object_class_install_property (gobject_class,
804                                                                          TILDA_TERMINAL_DYNAMIC_TITLE,
805                                                                          pspec);
806
807         pspec = g_param_spec_int ("exit-action",
808                                                           "Terminal's action upon child exit",
809                                                           "Get/Set terminal's action upon child exit",
810                                                           0,
811                                                           INT_MAX,
812                                                           0,
813                                                           G_PARAM_READWRITE);
814
815         g_object_class_install_property (gobject_class,
816                                                                          TILDA_TERMINAL_EXIT_ACTION,
817                                                                          pspec);
818
819         pspec = g_param_spec_boolean ("scroll-background",
820                                                                   "Controls terminal's scrolling behavior",
821                                                                   "Get/Set terminal's scrolling behavior",
822                                                                   FALSE,
823                                                                   G_PARAM_READWRITE);
824
825         g_object_class_install_property (gobject_class,
826                                                                          TILDA_TERMINAL_SCROLL_BACKGROUND,
827                                                                          pspec);
828
829         pspec = g_param_spec_boolean ("scroll-on-output",
830                                                                   "Controls terminal's scrolling behavior on output",
831                                                                   "Get/Set terminal's scrolling behavior on output",
832                                                                   FALSE,
833                                                                   G_PARAM_READWRITE);
834
835         g_object_class_install_property (gobject_class,
836                                                                          TILDA_TERMINAL_SCROLL_ON_OUTPUT,
837                                                                          pspec);
838
839         pspec = g_param_spec_boolean ("scroll-on-keystroke",
840                                                                   "Controls the terminal's scrolling behavior on keystroke",
841                                                                   NULL, FALSE, G_PARAM_READWRITE);
842
843         g_object_class_install_property (gobject_class,
844                                                                          TILDA_TERMINAL_SCROLL_ON_KEYSTROKE,
845                                                                          pspec);
846
847         pspec = g_param_spec_boolean ("antialiased",
848                                                                   "Attempt to antialias fonts",
849                                                                   NULL, FALSE, G_PARAM_READWRITE);
850
851         g_object_class_install_property (gobject_class,
852                                                                          TILDA_TERMINAL_ANTIALIASED,
853                                                                          pspec);
854
855         pspec = g_param_spec_boolean ("allow-bold-text",
856                                                                   "Allow bold text",
857                                                                   NULL, FALSE, G_PARAM_READWRITE);
858
859         g_object_class_install_property (gobject_class,
860                                                                          TILDA_TERMINAL_ALLOW_BOLD_TEXT,
861                                                                          pspec);
862
863         pspec = g_param_spec_boolean ("cursor-blinks",
864                                                                   NULL, NULL, FALSE, G_PARAM_READWRITE);
865
866         g_object_class_install_property (gobject_class,
867                                                                          TILDA_TERMINAL_CURSOR_BLINKS,
868                                                                          pspec);
869
870         pspec = g_param_spec_boolean ("audible-bell",
871                                                                   NULL, NULL, FALSE, G_PARAM_READWRITE);
872
873         g_object_class_install_property (gobject_class,
874                                                                          TILDA_TERMINAL_AUDIBLE_BELL,
875                                                                          pspec);
876
877         pspec = g_param_spec_boolean ("visible-bell",
878                                                                   NULL, NULL, FALSE, G_PARAM_READWRITE);
879
880         g_object_class_install_property (gobject_class,
881                                                                          TILDA_TERMINAL_VISIBLE_BELL,
882                                                                          pspec);
883
884         pspec = g_param_spec_boolean ("double-buffered",
885                                                                   NULL, NULL, FALSE, G_PARAM_READWRITE);
886
887         g_object_class_install_property (gobject_class,
888                                                                          TILDA_TERMINAL_DOUBLE_BUFFERED,
889                                                                          pspec);
890
891         pspec = g_param_spec_boolean ("mouse-autohide",
892                                                                   NULL, NULL, FALSE, G_PARAM_READWRITE);
893
894         g_object_class_install_property (gobject_class,
895                                                                          TILDA_TERMINAL_MOUSE_AUTOHIDE,
896                                                                          pspec);
897 }
898
899 GType
900 tilda_terminal_get_type (void)
901 {
902         static GType type = 0;
903
904         if (type == 0)
905         {
906                 static const GTypeInfo info = {
907                         sizeof (TildaTerminalClass),
908                         NULL,   /* base_init */
909                         NULL,   /* base_finalize */
910                         tilda_terminal_class_init,      /* class_init */
911                         NULL,   /* class_finalize */
912                         NULL,   /* class_data */
913                         sizeof (TildaTerminal),
914                         0,              /* n_preallocs */
915                         tilda_terminal_instance_init,   /* instance_init */
916                 };
917
918                 type = g_type_register_static (G_TYPE_OBJECT,
919                                                                            "TildaTerminalType",
920                                                                            &info,
921                                                                            0);
922         }
923
924         return type;
925 }
926
927 #if 0
928
929 int main (int argc, char *argv[])
930 {
931         GObject *tt;
932         gint test_number = INT_MIN;
933         gchar *test_string = NULL;
934
935         /* Initialize the GObject type system */
936         g_type_init ();
937         gtk_init (&argc, &argv);
938
939         tt = g_object_new (TILDA_TYPE_TERMINAL, "number", 10, NULL);
940         g_object_get (G_OBJECT (tt), "number", &test_number, NULL);
941         g_assert (test_number == 10);
942
943         g_object_unref (G_OBJECT (tt));
944
945         tt = g_object_new (TILDA_TYPE_TERMINAL, "number", 22, NULL);
946         g_object_get (G_OBJECT (tt), "number", &test_number, NULL);
947         g_assert (test_number == 22);
948
949         g_object_set (G_OBJECT (tt), "font", "hello I'm a font");
950         g_object_set (G_OBJECT (tt), "font", "Bitstream Vera Sans Mono 13");
951
952         g_object_get (G_OBJECT (tt), "font", &test_string, NULL);
953         g_print ("Read Font: %s\n", test_string);
954         // NOTE: you MUST free the string!!!!
955         g_free (test_string);
956
957         g_object_set (G_OBJECT (tt), "transparency-percent", 50);
958
959         g_object_unref (G_OBJECT (tt));
960
961         return 0;
962 }
963
964 #endif
965
966 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */