[Terminal] Make dynamic titles work properly
[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  * All GObject stuff is below. You probably don't need to change this...
180  ******************************************************************************/
181
182 static GObjectClass *parent_class = NULL;
183
184 enum tilda_terminal_properties {
185         TILDA_TERMINAL_NUMBER = 1,
186         TILDA_TERMINAL_WINDOW_NUMBER,
187         TILDA_TERMINAL_TW,
188
189         /* All non-constructor-only properties */
190         TILDA_TERMINAL_BACKGROUND_IMAGE,
191         TILDA_TERMINAL_SHELL,
192         TILDA_TERMINAL_FONT,
193         TILDA_TERMINAL_TITLE,
194         TILDA_TERMINAL_WORKING_DIRECTORY,
195
196         TILDA_TERMINAL_SCROLLBACK_LINES,
197         TILDA_TERMINAL_TRANSPARENCY_PERCENT,
198
199         TILDA_TERMINAL_BACKSPACE_BINDING,
200         TILDA_TERMINAL_DELETE_BINDING,
201         TILDA_TERMINAL_DYNAMIC_TITLE,
202         TILDA_TERMINAL_EXIT_ACTION,
203
204         TILDA_TERMINAL_SCROLL_BACKGROUND,
205         TILDA_TERMINAL_SCROLL_ON_OUTPUT,
206         TILDA_TERMINAL_SCROLL_ON_KEYSTROKE,
207         TILDA_TERMINAL_ANTIALIASED,
208         TILDA_TERMINAL_ALLOW_BOLD_TEXT,
209         TILDA_TERMINAL_CURSOR_BLINKS,
210         TILDA_TERMINAL_AUDIBLE_BELL,
211         TILDA_TERMINAL_VISIBLE_BELL,
212         TILDA_TERMINAL_DOUBLE_BUFFERED,
213         TILDA_TERMINAL_MOUSE_AUTOHIDE,
214 };
215
216 static void
217 tilda_terminal_instance_init (GTypeInstance *instance,
218                                                           gpointer       g_class)
219 {
220         TildaTerminal *self = (TildaTerminal *) instance;
221
222         /* Initialize instance members and allocate any necessary memory here.
223          * NOTE: any constructor-time values will be set later. */
224         self->dispose_has_run = FALSE;
225         self->number = 0;
226
227         self->vte_term = vte_terminal_new ();
228         self->scrollbar = gtk_vscrollbar_new (VTE_TERMINAL(self->vte_term)->adjustment);
229         self->hbox = gtk_hbox_new (FALSE, 0);
230 }
231
232 static void
233 tilda_terminal_set_property (GObject      *object,
234                                                          guint         property_id,
235                                                          const GValue *value,
236                                                          GParamSpec   *pspec)
237 {
238         TildaTerminal *self = (TildaTerminal *) object;
239
240         switch (property_id) {
241
242                 case TILDA_TERMINAL_NUMBER:
243                         self->number = g_value_get_int (value);
244                         g_print ("terminal number: %d\n", self->number);
245                         break;
246
247                 case TILDA_TERMINAL_WINDOW_NUMBER:
248                         self->window_number = g_value_get_int (value);
249                         g_print ("terminal parent window number: %d\n", self->window_number);
250                         break;
251
252                 case TILDA_TERMINAL_TW:
253                         self->parent_window = g_value_get_pointer (value);
254                         g_print ("terminal parent window: 0x%x\n", self->parent_window);
255                         g_print ("terminal parent window number (direct): %d\n", TILDA_WINDOW(self->parent_window)->number);
256                         break;
257
258                 case TILDA_TERMINAL_BACKGROUND_IMAGE:
259                         g_free (self->background_image);
260                         self->background_image = g_value_dup_string (value);
261                         vte_terminal_set_background_image_file (VTE_TERMINAL(self->vte_term), self->background_image);
262                         g_print ("terminal back img: %s\n", self->background_image);
263                         break;
264
265                 case TILDA_TERMINAL_SHELL:
266                         g_free (self->shell);
267                         self->shell = g_value_dup_string (value);
268                         tilda_terminal_start_shell (self);
269                         g_print ("terminal shell: %s\n", self->shell);
270                         break;
271
272                 case TILDA_TERMINAL_FONT:
273                         g_free (self->font);
274                         self->font = g_value_dup_string (value);
275                         vte_terminal_set_font_from_string_full (VTE_TERMINAL(self->vte_term),
276                                                                                                         self->font,
277                                                                                                         self->antialiased);
278                         g_print ("terminal font: %s\n", self->font);
279                         break;
280
281                 case TILDA_TERMINAL_TITLE:
282                         g_free (self->title);
283                         self->title = g_value_dup_string (value);
284                         g_print ("terminal title: %s\n", self->title);
285                         break;
286
287                 case TILDA_TERMINAL_WORKING_DIRECTORY:
288                         g_free (self->working_directory);
289                         self->working_directory = g_value_dup_string (value);
290                         g_print ("terminal wrk dir: %s\n", self->working_directory);
291                         break;
292
293                 case TILDA_TERMINAL_SCROLLBACK_LINES:
294                         self->scrollback_lines = g_value_get_int (value);
295                         vte_terminal_set_scrollback_lines (VTE_TERMINAL(self->vte_term), self->scrollback_lines);
296                         g_print ("terminal scrollback lines: %d\n", self->scrollback_lines);
297                         break;
298
299                 case TILDA_TERMINAL_TRANSPARENCY_PERCENT:
300                         self->transparency_percent = g_value_get_int (value);
301                         g_print ("terminal transp percent: %d\n", self->transparency_percent);
302                         break;
303
304                 case TILDA_TERMINAL_BACKSPACE_BINDING:
305                         self->backspace_binding = g_value_get_int (value);
306                         vte_terminal_set_backspace_binding (VTE_TERMINAL(self->vte_term), self->backspace_binding);
307                         g_print ("terminal backspace key: %d\n", self->backspace_binding);
308                         break;
309
310                 case TILDA_TERMINAL_DELETE_BINDING:
311                         self->delete_binding = g_value_get_int (value);
312                         vte_terminal_set_delete_binding (VTE_TERMINAL(self->vte_term), self->delete_binding);
313                         g_print ("terminal delete key: %d\n", self->delete_binding);
314                         break;
315
316                 case TILDA_TERMINAL_DYNAMIC_TITLE:
317                         self->dynamic_title = g_value_get_int (value);
318                         g_print ("terminal dynamic title: %d\n", self->dynamic_title);
319                         break;
320
321                 case TILDA_TERMINAL_EXIT_ACTION:
322                         self->exit_action = g_value_get_int (value);
323                         g_print ("terminal exit action: %d\n", self->exit_action);
324                         break;
325
326                 case TILDA_TERMINAL_SCROLL_BACKGROUND:
327                         self->scroll_background = g_value_get_boolean (value);
328                         vte_terminal_set_scroll_background (VTE_TERMINAL(self->vte_term), self->scroll_background);
329                         g_print ("terminal scroll background: %d\n", self->scroll_background);
330                         break;
331
332                 case TILDA_TERMINAL_SCROLL_ON_OUTPUT:
333                         self->scroll_on_output = g_value_get_boolean (value);
334                         vte_terminal_set_scroll_on_output (VTE_TERMINAL(self->vte_term), self->scroll_on_output);
335                         g_print ("terminal scroll on output: %d\n", self->scroll_on_output);
336                         break;
337
338                 case TILDA_TERMINAL_SCROLL_ON_KEYSTROKE:
339                         self->scroll_on_keystroke = g_value_get_boolean (value);
340                         vte_terminal_set_scroll_on_keystroke (VTE_TERMINAL(self->vte_term), self->scroll_on_keystroke);
341                         g_print ("terminal scroll on keystroke: %d\n", self->scroll_on_keystroke);
342                         break;
343
344                 case TILDA_TERMINAL_ANTIALIASED:
345                         self->antialiased = g_value_get_boolean (value);
346                         vte_terminal_set_font_from_string_full (VTE_TERMINAL(self->vte_term),
347                                                                                                         self->font,
348                                                                                                         self->antialiased);
349                         g_print ("terminal antialiased: %d\n", self->antialiased);
350                         break;
351
352                 case TILDA_TERMINAL_ALLOW_BOLD_TEXT:
353                         self->allow_bold_text = g_value_get_boolean (value);
354                         vte_terminal_set_allow_bold (VTE_TERMINAL(self->vte_term), self->allow_bold_text);
355                         g_print ("terminal allow bold text: %d\n", self->allow_bold_text);
356                         break;
357
358                 case TILDA_TERMINAL_CURSOR_BLINKS:
359                         self->cursor_blinks = g_value_get_boolean (value);
360                         vte_terminal_set_cursor_blinks (VTE_TERMINAL(self->vte_term), self->cursor_blinks);
361                         g_print ("terminal cursor blinks: %d\n", self->cursor_blinks);
362                         break;
363
364                 case TILDA_TERMINAL_AUDIBLE_BELL:
365                         self->audible_bell = g_value_get_boolean (value);
366                         vte_terminal_set_audible_bell (VTE_TERMINAL(self->vte_term), self->audible_bell);
367                         g_print ("terminal audible bell: %d\n", self->audible_bell);
368                         break;
369
370                 case TILDA_TERMINAL_VISIBLE_BELL:
371                         self->visible_bell = g_value_get_boolean (value);
372                         vte_terminal_set_visible_bell (VTE_TERMINAL(self->vte_term), self->visible_bell);
373                         g_print ("terminal visible bell: %d\n", self->visible_bell);
374                         break;
375
376                 case TILDA_TERMINAL_DOUBLE_BUFFERED:
377                         self->double_buffered = g_value_get_boolean (value);
378                         gtk_widget_set_double_buffered (GTK_WIDGET(self->vte_term), self->double_buffered);
379                         g_print ("terminal double buffered: %d\n", self->double_buffered);
380                         break;
381
382                 case TILDA_TERMINAL_MOUSE_AUTOHIDE:
383                         self->mouse_autohide = g_value_get_boolean (value);
384                         vte_terminal_set_mouse_autohide (VTE_TERMINAL(self->vte_term), self->mouse_autohide);
385                         g_print ("terminal mouse autohide: %d\n", self->mouse_autohide);
386                         break;
387
388                 default:
389                         /* We don't have this property... */
390                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
391                         break;
392         }
393 }
394
395 static void
396 tilda_terminal_get_property (GObject    *object,
397                                                          guint       property_id,
398                                                          GValue     *value,
399                                                          GParamSpec *pspec)
400 {
401         TildaTerminal *self = (TildaTerminal *) object;
402
403         switch (property_id) {
404
405                 case TILDA_TERMINAL_NUMBER:
406                         g_value_set_int (value, self->number);
407                         break;
408
409                 case TILDA_TERMINAL_WINDOW_NUMBER:
410                         g_value_set_int (value, self->window_number);
411                         break;
412
413                 case TILDA_TERMINAL_TW:
414                         g_value_set_pointer (value, self->parent_window);
415                         break;
416
417                 case TILDA_TERMINAL_BACKGROUND_IMAGE:
418                         g_value_set_string (value, self->background_image);
419                         break;
420
421                 case TILDA_TERMINAL_SHELL:
422                         g_value_set_string (value, self->shell);
423                         break;
424
425                 case TILDA_TERMINAL_FONT:
426                         g_value_set_string (value, self->font);
427                         break;
428
429                 case TILDA_TERMINAL_TITLE:
430                         g_value_set_string (value, self->title);
431                         break;
432
433                 case TILDA_TERMINAL_WORKING_DIRECTORY:
434                         g_value_set_string (value, self->working_directory);
435                         break;
436
437                 case TILDA_TERMINAL_SCROLLBACK_LINES:
438                         g_value_set_int (value, self->scrollback_lines);
439                         break;
440
441                 case TILDA_TERMINAL_TRANSPARENCY_PERCENT:
442                         g_value_set_int (value, self->transparency_percent);
443                         break;
444
445                 case TILDA_TERMINAL_BACKSPACE_BINDING:
446                         g_value_set_int (value, self->backspace_binding);
447                         break;
448
449                 case TILDA_TERMINAL_DELETE_BINDING:
450                         g_value_set_int (value, self->delete_binding);
451                         break;
452
453                 case TILDA_TERMINAL_DYNAMIC_TITLE:
454                         g_value_set_int (value, self->dynamic_title);
455                         break;
456
457                 case TILDA_TERMINAL_EXIT_ACTION:
458                         g_value_set_int (value, self->exit_action);
459                         break;
460
461                 case TILDA_TERMINAL_SCROLL_BACKGROUND:
462                         g_value_set_boolean (value, self->scroll_background);
463                         break;
464
465                 case TILDA_TERMINAL_SCROLL_ON_OUTPUT:
466                         g_value_set_boolean (value, self->scroll_on_output);
467                         break;
468
469                 case TILDA_TERMINAL_SCROLL_ON_KEYSTROKE:
470                         g_value_set_boolean (value, self->scroll_on_keystroke);
471                         break;
472
473                 case TILDA_TERMINAL_ANTIALIASED:
474                         g_value_set_boolean (value, self->antialiased);
475                         break;
476
477                 case TILDA_TERMINAL_ALLOW_BOLD_TEXT:
478                         g_value_set_boolean (value, self->allow_bold_text);
479                         break;
480
481                 case TILDA_TERMINAL_CURSOR_BLINKS:
482                         g_value_set_boolean (value, self->cursor_blinks);
483                         break;
484
485                 case TILDA_TERMINAL_AUDIBLE_BELL:
486                         g_value_set_boolean (value, self->audible_bell);
487                         break;
488
489                 case TILDA_TERMINAL_VISIBLE_BELL:
490                         g_value_set_boolean (value, self->visible_bell);
491                         break;
492
493                 case TILDA_TERMINAL_DOUBLE_BUFFERED:
494                         g_value_set_boolean (value, self->double_buffered);
495                         break;
496
497                 case TILDA_TERMINAL_MOUSE_AUTOHIDE:
498                         g_value_set_boolean (value, self->mouse_autohide);
499
500                 default:
501                         /* We don't have this property... */
502                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
503                         break;
504         }
505 }
506
507 static GObject *
508 tilda_terminal_constructor (GType                  type,
509                                                         guint                  n_construct_properties,
510                                                         GObjectConstructParam *construct_properties)
511 {
512         GObject *obj;
513         TildaTerminal *self;
514
515         /* Invoke parent constructor */
516         TildaTerminalClass *klass;
517         klass = TILDA_TERMINAL_CLASS (g_type_class_peek (TILDA_TYPE_TERMINAL));
518         obj = parent_class->constructor (type,
519                                                                          n_construct_properties,
520                                                                          construct_properties);
521
522         /* Do other stuff here. The object is ready to go now, and all
523          * ctor properties have been set.
524          *
525          * TODO: This is the place to do DBus-init */
526         self = TILDA_TERMINAL(obj);
527
528         /* Pack into the hbox */
529         gtk_box_pack_end (GTK_BOX(self->hbox), self->scrollbar, FALSE, FALSE, 0);
530         gtk_box_pack_end (GTK_BOX(self->hbox), self->vte_term, TRUE, TRUE, 0);
531         gtk_widget_show (self->scrollbar);
532
533
534         /* Connect Signals */
535         g_signal_connect (G_OBJECT(self->vte_term), "child-exited",
536                                           G_CALLBACK(tilda_terminal_child_exited_cb), self);
537         g_signal_connect (G_OBJECT(self->vte_term), "eof",
538                                           G_CALLBACK(tilda_terminal_child_exited_cb), self);
539         g_signal_connect (G_OBJECT(self->vte_term), "window-title-changed",
540                                           G_CALLBACK(tilda_terminal_window_title_changed_cb), self);
541
542         tilda_terminal_start_shell (self);
543         tilda_terminal_dbus_register_object (self);
544
545         return obj;
546 }
547
548 static void
549 tilda_terminal_dispose (GObject *obj)
550 {
551         TildaTerminal *self = (TildaTerminal *) obj;
552
553         /* We don't want to run dispose twice, so just return immediately */
554         if (self->dispose_has_run)
555                 return;
556
557         self->dispose_has_run = TRUE;
558
559         /*
560          * In dispose, you are supposed to free all types referenced from this
561          * object which might themselves hold a reference to self. Generally,
562          * the most simple solution is to unref all members on which you own a
563          * reference.
564          */
565
566         /* Chain up to the parent class */
567         G_OBJECT_CLASS (parent_class)->dispose (obj);
568 }
569
570 static void
571 tilda_terminal_finalize (GObject *obj)
572 {
573         TildaTerminal *self = (TildaTerminal *) obj;
574
575         /*
576          * Here, complete object destruction.
577          * You might not need to do much...
578          */
579
580         // TODO: g_free() any primitives here
581         g_free (self->background_image);
582         g_free (self->shell);
583         g_free (self->font);
584         g_free (self->title);
585         g_free (self->working_directory);
586
587
588         /* Chain up to the parent class */
589         G_OBJECT_CLASS (parent_class)->finalize (obj);
590 }
591
592 static void
593 tilda_terminal_class_init (gpointer g_class,
594                                                    gpointer g_class_data)
595 {
596         GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
597         TildaTerminalClass *klass = TILDA_TERMINAL_CLASS (g_class);
598         GParamSpec *pspec;
599
600         /* Hook our functions to this type */
601         gobject_class->set_property = tilda_terminal_set_property;
602         gobject_class->get_property = tilda_terminal_get_property;
603         gobject_class->dispose = tilda_terminal_dispose;
604         gobject_class->finalize = tilda_terminal_finalize;
605         gobject_class->constructor = tilda_terminal_constructor;
606
607         parent_class = g_type_class_peek_parent (klass);
608
609         /* Hook the TildaTerminal type into DBus */
610         dbus_g_object_type_install_info (tilda_terminal_get_type(), &dbus_glib_tilda_terminal_object_info);
611
612         /* Install all of the properties */
613         pspec = g_param_spec_int ("number",
614                                                           "Terminal number",
615                                                           "Set terminal's number",
616                                                           0,            // min value
617                                                           INT_MAX,      // max value
618                                                           0,            // def value
619                                                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
620
621         g_object_class_install_property (gobject_class,
622                                                                          TILDA_TERMINAL_NUMBER,
623                                                                          pspec);
624
625         pspec = g_param_spec_int ("window-number",
626                                                           "Number of the window to which this terminal belongs",
627                                                           "Set the number of the parent window",
628                                                           0,
629                                                           INT_MAX,
630                                                           0x0000beef,
631                                                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
632
633         g_object_class_install_property (gobject_class,
634                                                                          TILDA_TERMINAL_WINDOW_NUMBER,
635                                                                          pspec);
636
637         pspec = g_param_spec_pointer ("parent-window",
638                                                                   "Pointer to terminal's parent TildaWindow",
639                                                                   "Set the pointer to the terminal's parent TildaWindow",
640                                                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
641
642         g_object_class_install_property (gobject_class,
643                                                                          TILDA_TERMINAL_TW,
644                                                                          pspec);
645
646         pspec = g_param_spec_string ("background-image",
647                                                                  "Terminal's background image",
648                                                                  "Get/Set terminal's background image",
649                                                                  NULL,
650                                                                  G_PARAM_READWRITE);
651
652         g_object_class_install_property (gobject_class,
653                                                                          TILDA_TERMINAL_BACKGROUND_IMAGE,
654                                                                          pspec);
655
656         pspec = g_param_spec_string ("shell",
657                                                                  "Terminal's shell",
658                                                                  "Get/Set terminal's shell",
659                                                                  NULL,
660                                                                  G_PARAM_READWRITE);
661
662         g_object_class_install_property (gobject_class,
663                                                                          TILDA_TERMINAL_SHELL,
664                                                                          pspec);
665
666         pspec = g_param_spec_string ("font",
667                                                                  "Terminal's font",
668                                                                  "Get/Set terminal's font",
669                                                                  NULL,
670                                                                  G_PARAM_READWRITE);
671
672         g_object_class_install_property (gobject_class,
673                                                                          TILDA_TERMINAL_FONT,
674                                                                          pspec);
675
676         pspec = g_param_spec_string ("title",
677                                                                  "Terminal's title",
678                                                                  "Get/Set terminal's title",
679                                                                  NULL,
680                                                                  G_PARAM_READWRITE);
681
682         g_object_class_install_property (gobject_class,
683                                                                          TILDA_TERMINAL_TITLE,
684                                                                          pspec);
685
686         pspec = g_param_spec_string ("working-directory",
687                                                                  "Terminal's initial working directory",
688                                                                  "Get/Set terminal's initial working directory",
689                                                                  NULL,
690                                                                  G_PARAM_READWRITE);
691
692         g_object_class_install_property (gobject_class,
693                                                                          TILDA_TERMINAL_WORKING_DIRECTORY,
694                                                                          pspec);
695
696         pspec = g_param_spec_int ("scrollback-lines",
697                                                           "Terminal's scrollback amount (lines)",
698                                                           "Get/Set terminal's scrollback amount",
699                                                           0,
700                                                           INT_MAX, // TODO: artificially limit this?
701                                                           1000,
702                                                           G_PARAM_READWRITE);
703
704         g_object_class_install_property (gobject_class,
705                                                                          TILDA_TERMINAL_SCROLLBACK_LINES,
706                                                                          pspec);
707
708         pspec = g_param_spec_int ("transparency-percent",
709                                                           "Terminal's transparency (percent)",
710                                                           "Get/Set terminal's transparency",
711                                                           0,
712                                                           100,
713                                                           0,
714                                                           G_PARAM_READWRITE);
715
716         g_object_class_install_property (gobject_class,
717                                                                          TILDA_TERMINAL_TRANSPARENCY_PERCENT,
718                                                                          pspec);
719
720         pspec = g_param_spec_int ("backspace-binding",
721                                                           "Terminal's backspace binding",
722                                                           "Get/Set terminal's backspace key binding",
723                                                           VTE_ERASE_AUTO,
724                                                           VTE_ERASE_DELETE_SEQUENCE,
725                                                           VTE_ERASE_AUTO,
726                                                           G_PARAM_READWRITE);
727
728         g_object_class_install_property (gobject_class,
729                                                                          TILDA_TERMINAL_BACKSPACE_BINDING,
730                                                                          pspec);
731
732         pspec = g_param_spec_int ("delete-binding",
733                                                           "Terminal's delete binding",
734                                                           "Get/Set terminal's delete key binding",
735                                                           VTE_ERASE_AUTO,
736                                                           VTE_ERASE_DELETE_SEQUENCE,
737                                                           VTE_ERASE_AUTO,
738                                                           G_PARAM_READWRITE);
739
740         g_object_class_install_property (gobject_class,
741                                                                          TILDA_TERMINAL_DELETE_BINDING,
742                                                                          pspec);
743
744         pspec = g_param_spec_int ("dynamic-title",
745                                                           "Terminal's dynamic title generation method",
746                                                           "Get/Set terminal's dynamic title generation method",
747                                                           0,
748                                                           INT_MAX,
749                                                           0,
750                                                           G_PARAM_READWRITE);
751
752         g_object_class_install_property (gobject_class,
753                                                                          TILDA_TERMINAL_DYNAMIC_TITLE,
754                                                                          pspec);
755
756         pspec = g_param_spec_int ("exit-action",
757                                                           "Terminal's action upon child exit",
758                                                           "Get/Set terminal's action upon child exit",
759                                                           0,
760                                                           INT_MAX,
761                                                           0,
762                                                           G_PARAM_READWRITE);
763
764         g_object_class_install_property (gobject_class,
765                                                                          TILDA_TERMINAL_EXIT_ACTION,
766                                                                          pspec);
767
768         pspec = g_param_spec_boolean ("scroll-background",
769                                                                   "Controls terminal's scrolling behavior",
770                                                                   "Get/Set terminal's scrolling behavior",
771                                                                   FALSE,
772                                                                   G_PARAM_READWRITE);
773
774         g_object_class_install_property (gobject_class,
775                                                                          TILDA_TERMINAL_SCROLL_BACKGROUND,
776                                                                          pspec);
777
778         pspec = g_param_spec_boolean ("scroll-on-output",
779                                                                   "Controls terminal's scrolling behavior on output",
780                                                                   "Get/Set terminal's scrolling behavior on output",
781                                                                   FALSE,
782                                                                   G_PARAM_READWRITE);
783
784         g_object_class_install_property (gobject_class,
785                                                                          TILDA_TERMINAL_SCROLL_ON_OUTPUT,
786                                                                          pspec);
787
788         pspec = g_param_spec_boolean ("scroll-on-keystroke",
789                                                                   "Controls the terminal's scrolling behavior on keystroke",
790                                                                   NULL, FALSE, G_PARAM_READWRITE);
791
792         g_object_class_install_property (gobject_class,
793                                                                          TILDA_TERMINAL_SCROLL_ON_KEYSTROKE,
794                                                                          pspec);
795
796         pspec = g_param_spec_boolean ("antialiased",
797                                                                   "Attempt to antialias fonts",
798                                                                   NULL, FALSE, G_PARAM_READWRITE);
799
800         g_object_class_install_property (gobject_class,
801                                                                          TILDA_TERMINAL_ANTIALIASED,
802                                                                          pspec);
803
804         pspec = g_param_spec_boolean ("allow-bold-text",
805                                                                   "Allow bold text",
806                                                                   NULL, FALSE, G_PARAM_READWRITE);
807
808         g_object_class_install_property (gobject_class,
809                                                                          TILDA_TERMINAL_ALLOW_BOLD_TEXT,
810                                                                          pspec);
811
812         pspec = g_param_spec_boolean ("cursor-blinks",
813                                                                   NULL, NULL, FALSE, G_PARAM_READWRITE);
814
815         g_object_class_install_property (gobject_class,
816                                                                          TILDA_TERMINAL_CURSOR_BLINKS,
817                                                                          pspec);
818
819         pspec = g_param_spec_boolean ("audible-bell",
820                                                                   NULL, NULL, FALSE, G_PARAM_READWRITE);
821
822         g_object_class_install_property (gobject_class,
823                                                                          TILDA_TERMINAL_AUDIBLE_BELL,
824                                                                          pspec);
825
826         pspec = g_param_spec_boolean ("visible-bell",
827                                                                   NULL, NULL, FALSE, G_PARAM_READWRITE);
828
829         g_object_class_install_property (gobject_class,
830                                                                          TILDA_TERMINAL_VISIBLE_BELL,
831                                                                          pspec);
832
833         pspec = g_param_spec_boolean ("double-buffered",
834                                                                   NULL, NULL, FALSE, G_PARAM_READWRITE);
835
836         g_object_class_install_property (gobject_class,
837                                                                          TILDA_TERMINAL_DOUBLE_BUFFERED,
838                                                                          pspec);
839
840         pspec = g_param_spec_boolean ("mouse-autohide",
841                                                                   NULL, NULL, FALSE, G_PARAM_READWRITE);
842
843         g_object_class_install_property (gobject_class,
844                                                                          TILDA_TERMINAL_MOUSE_AUTOHIDE,
845                                                                          pspec);
846 }
847
848 GType
849 tilda_terminal_get_type (void)
850 {
851         static GType type = 0;
852
853         if (type == 0)
854         {
855                 static const GTypeInfo info = {
856                         sizeof (TildaTerminalClass),
857                         NULL,   /* base_init */
858                         NULL,   /* base_finalize */
859                         tilda_terminal_class_init,      /* class_init */
860                         NULL,   /* class_finalize */
861                         NULL,   /* class_data */
862                         sizeof (TildaTerminal),
863                         0,              /* n_preallocs */
864                         tilda_terminal_instance_init,   /* instance_init */
865                 };
866
867                 type = g_type_register_static (G_TYPE_OBJECT,
868                                                                            "TildaTerminalType",
869                                                                            &info,
870                                                                            0);
871         }
872
873         return type;
874 }
875
876 #if 0
877
878 int main (int argc, char *argv[])
879 {
880         GObject *tt;
881         gint test_number = INT_MIN;
882         gchar *test_string = NULL;
883
884         /* Initialize the GObject type system */
885         g_type_init ();
886         gtk_init (&argc, &argv);
887
888         tt = g_object_new (TILDA_TYPE_TERMINAL, "number", 10, NULL);
889         g_object_get (G_OBJECT (tt), "number", &test_number, NULL);
890         g_assert (test_number == 10);
891
892         g_object_unref (G_OBJECT (tt));
893
894         tt = g_object_new (TILDA_TYPE_TERMINAL, "number", 22, NULL);
895         g_object_get (G_OBJECT (tt), "number", &test_number, NULL);
896         g_assert (test_number == 22);
897
898         g_object_set (G_OBJECT (tt), "font", "hello I'm a font");
899         g_object_set (G_OBJECT (tt), "font", "Bitstream Vera Sans Mono 13");
900
901         g_object_get (G_OBJECT (tt), "font", &test_string, NULL);
902         g_print ("Read Font: %s\n", test_string);
903         // NOTE: you MUST free the string!!!!
904         g_free (test_string);
905
906         g_object_set (G_OBJECT (tt), "transparency-percent", 50);
907
908         g_object_unref (G_OBJECT (tt));
909
910         return 0;
911 }
912
913 #endif
914
915 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */