49b52e2f1138035b6850d98d5d3272fa4cdf9175
[tilda-gobject.git] / tilda-terminal.c
1 #include "tilda.h"
2 #include "tilda-terminal.h"
3 #include "tilda-config.h"
4 #include "tilda-terminal-dbus-glue.h"
5
6 #include <stdlib.h>
7
8 #define DINGUS1 "(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+(:[0-9]*)?"
9 #define DINGUS2 "(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+(:[0-9]*)?/[-A-Za-z0-9_\\$\\.\\+\\!\\*\\(\\),;:@&=\\?/~\\#\\%]*[^]'\\.}>\\) ,\\\"]"
10
11 /*******************************************************************************
12  * All popup-menu code is below
13  ******************************************************************************/
14
15 static void
16 menu_add_term_cb (GtkWidget *widget, gpointer data)
17 {
18         debug_enter  ();
19         debug_assert (TILDA_IS_TERMINAL(data));
20
21         TildaTerminal *self = TILDA_TERMINAL(data);
22         TildaWindow *parent_window = TILDA_WINDOW(self->parent_window);
23
24         tilda_window_add_terminal (parent_window);
25 }
26
27 static void
28 menu_remove_term_cb (GtkWidget *widget, gpointer data)
29 {
30         debug_enter  ();
31         debug_assert (TILDA_IS_TERMINAL(data));
32
33         TildaTerminal *self = TILDA_TERMINAL(data);
34         TildaWindow *parent_window = TILDA_WINDOW(self->parent_window);
35
36         tilda_window_remove_terminal (parent_window, self->number);
37 }
38
39 static void
40 menu_copy_cb (GtkWidget *widget, gpointer data)
41 {
42         debug_enter  ();
43         debug_assert (TILDA_IS_TERMINAL(data));
44
45         TildaTerminal *self = TILDA_TERMINAL(data);
46
47         vte_terminal_copy_clipboard (VTE_TERMINAL(self->vte_term));
48 }
49
50 static void
51 menu_paste_cb (GtkWidget *widget, gpointer data)
52 {
53         debug_enter  ();
54         debug_assert (TILDA_IS_TERMINAL(data));
55
56         TildaTerminal *self = TILDA_TERMINAL(data);
57
58         vte_terminal_paste_clipboard (VTE_TERMINAL(self->vte_term));
59 }
60
61 static void
62 menu_preferences_cb (GtkWidget *widget, gpointer data)
63 {
64         debug_enter  ();
65         debug_assert (TILDA_IS_TERMINAL(data));
66
67         TildaTerminal *self = TILDA_TERMINAL(data);
68         TildaWindow *parent_window = TILDA_WINDOW(self->parent_window);
69
70         /* TODO:
71          *
72          * Note that this lends interesting possibilities for the tilda-wizard
73          * command line interface. Maybe a --window --terminal option, which will
74          * auto-set the preferences to a current window and term :) Neat.
75          */
76
77         g_print ("FIXME: show wizard here\n");
78 }
79
80 static void
81 menu_quit_cb (GtkWidget *widget, gpointer data)
82 {
83         debug_enter  ();
84         debug_assert (TILDA_IS_TERMINAL(data));
85
86         TildaTerminal *self = TILDA_TERMINAL(data);
87         TildaWindow *parent_window = TILDA_WINDOW(self->parent_window);
88         TildaController *controller = TILDA_CONTROLLER(parent_window->controller);
89
90         tilda_controller_remove_window (controller, parent_window->number);
91 }
92
93 static void
94 tilda_terminal_popup_menu (TildaTerminal *self)
95 {
96         debug_enter  ();
97         debug_assert (TILDA_IS_TERMINAL(self));
98
99         GtkAction *action;
100         GtkActionGroup *action_group;
101         GtkUIManager *ui_manager;
102         GError *error = NULL;
103         GtkWidget *menu;
104
105         /* Just use a static string here to initialize the GtkUIManager,
106          * rather than installing and reading from a file all the time. */
107         static const gchar menu_str[] =
108                 "<ui>"
109                         "<popup name=\"popup-menu\">"
110                                 "<menuitem action=\"add-term\" />"
111                                 "<menuitem action=\"remove-term\" />"
112                                 "<separator />"
113                                 "<menuitem action=\"copy\" />"
114                                 "<menuitem action=\"paste\" />"
115                                 "<separator />"
116                                 "<menuitem action=\"preferences\" />"
117                                 "<separator />"
118                                 "<menuitem action=\"quit\" />"
119                         "</popup>"
120                 "</ui>";
121
122         TildaWindow *parent_window = TILDA_WINDOW(self->parent_window);
123
124         /* Create the action group */
125         action_group = gtk_action_group_new ("popup-menu-action-group");
126
127         /* Add Actions and connect callbacks */
128         action = gtk_action_new ("add-term", _("_Add Terminal"), NULL, GTK_STOCK_ADD);
129         gtk_action_group_add_action_with_accel (action_group, action, parent_window->accel_add_term);
130         g_signal_connect (G_OBJECT(action), "activate", G_CALLBACK(menu_add_term_cb), self);
131
132         action = gtk_action_new ("remove-term", _("_Remove Terminal"), NULL, GTK_STOCK_CLOSE);
133         gtk_action_group_add_action_with_accel (action_group, action, parent_window->accel_remove_term);
134         g_signal_connect (G_OBJECT(action), "activate", G_CALLBACK(menu_remove_term_cb), self);
135
136         action = gtk_action_new ("copy", NULL, NULL, GTK_STOCK_COPY);
137         gtk_action_group_add_action_with_accel (action_group, action, parent_window->accel_copy);
138         g_signal_connect (G_OBJECT(action), "activate", G_CALLBACK(menu_copy_cb), self);
139
140         action = gtk_action_new ("paste", NULL, NULL, GTK_STOCK_PASTE);
141         gtk_action_group_add_action_with_accel (action_group, action, parent_window->accel_paste);
142         g_signal_connect (G_OBJECT(action), "activate", G_CALLBACK(menu_paste_cb), self);
143
144         action = gtk_action_new ("preferences", NULL, NULL, GTK_STOCK_PREFERENCES);
145         gtk_action_group_add_action (action_group, action);
146         g_signal_connect (G_OBJECT(action), "activate", G_CALLBACK(menu_preferences_cb), self);
147
148         action = gtk_action_new ("quit", NULL, NULL, GTK_STOCK_QUIT);
149         gtk_action_group_add_action_with_accel (action_group, action, parent_window->accel_quit);
150         g_signal_connect (G_OBJECT(action), "activate", G_CALLBACK(menu_quit_cb), self);
151
152         /* Create and add actions to the GtkUIManager */
153         ui_manager = gtk_ui_manager_new ();
154         gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
155         gtk_ui_manager_add_ui_from_string (ui_manager, menu_str, -1, &error);
156
157         /* Check for an error (REALLY REALLY unlikely, unless the developers screwed up */
158         if (error)
159         {
160                 g_critical ("GtkUIManager problem: %s\n", error->message);
161                 g_error_free (error);
162         }
163
164         /* Get the popup menu out of the GtkUIManager */
165         menu = gtk_ui_manager_get_widget (ui_manager, "/ui/popup-menu");
166
167         /* Display the menu */
168         gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time());
169         gtk_widget_show_all(menu);
170 }
171
172 /*******************************************************************************
173  * All TildaTerminal functions below
174  ******************************************************************************/
175
176 static void
177 tilda_terminal_dbus_register_object (TildaTerminal *tt)
178 {
179         debug_enter  ();
180         debug_assert (TILDA_IS_TERMINAL(tt));
181
182         TildaWindow *parent_window = TILDA_WINDOW(tt->parent_window);
183         gchar *object_path;
184
185         // Register this object with DBus
186         object_path = g_strdup_printf ("/net/sourceforge/Tilda/Window%d/Terminal%d",
187                                                                    parent_window->number, tt->number);
188         dbus_g_connection_register_g_object (dbus_connection, object_path, G_OBJECT(tt));
189         g_free (object_path);
190 }
191
192 gboolean
193 tilda_terminal_run_command (TildaTerminal *self, gchar *command, GError **error)
194 {
195         debug_enter  ();
196         debug_assert (TILDA_IS_TERMINAL(self));
197
198         vte_terminal_feed_child (VTE_TERMINAL(self->vte_term), command, -1);
199         vte_terminal_feed_child (VTE_TERMINAL(self->vte_term), "\n", -1);
200
201         return TRUE;
202 }
203
204 gboolean
205 tilda_terminal_close (TildaTerminal *self, GError **error)
206 {
207         debug_enter  ();
208         debug_assert (TILDA_IS_TERMINAL(self));
209
210         TildaWindow *parent_window = TILDA_WINDOW(self->parent_window);
211
212         tilda_window_remove_terminal (parent_window, self->number);
213
214         return TRUE;
215 }
216
217 /**
218  * Start the current tt->shell in the given TildaTerminal
219  * NOTE: this will kill whatever is running in the terminal,
220  * NOTE: and run the current tt->shell instead :)
221  * Return: TRUE if ok, FALSE otherwise
222  */
223 static gboolean
224 tilda_terminal_start_shell (TildaTerminal *tt)
225 {
226         debug_enter  ();
227         debug_assert (TILDA_IS_TERMINAL(tt));
228
229         gint ret;
230         gint argc;
231         gchar **argv;
232         GError *error = NULL;
233
234         /* Launch a custom command if tt->shell is set (not NULL) */
235         if (tt->shell)
236         {
237                 /* Try to parse the user's custom command */
238                 ret = g_shell_parse_argv (tt->shell, &argc, &argv, &error);
239
240                 if (ret == FALSE)
241                 {
242                         g_printerr (_("Problem parsing custom command: %s\n"), error->message);
243                         g_printerr (_("Launching default shell instead\n"));
244
245                         g_error_free (error);
246                         goto launch_default_shell;
247                 }
248
249                 /* Try to start the user's custom command */
250                 ret = vte_terminal_fork_command (VTE_TERMINAL(tt->vte_term),
251                                                                                  argv[0], /* Command */
252                                                                                  argv,    /* Arg Vector */
253                                                                                  NULL,    /* Env Vector */
254                                                                                  tt->working_directory, /* Start directory */
255                                                                                  TRUE,    /* Add to lastlog */
256                                                                                  TRUE,    /* Add to utmp */
257                                                                                  TRUE);   /* Add to wtmp */
258
259                 g_strfreev (argv);
260
261                 /* Check for error */
262                 if (ret == -1)
263                 {
264                         g_printerr (_("Unable to launch custom command: %s\n"), tt->shell);
265                         g_printerr (_("Launching default shell instead\n"));
266
267                         goto launch_default_shell;
268                 }
269
270                 return TRUE; /* SUCCESS: the early way out */
271         }
272
273 launch_default_shell:
274
275     ret = vte_terminal_fork_command (VTE_TERMINAL(tt->vte_term),
276                                                                          NULL, /* Command -- VTE will figure it out */
277                                                                          NULL, /* Arg Vector */
278                                                                          NULL, /* Env Vector */
279                                                                          tt->working_directory, /* Start Directory */
280                                                                          TRUE, /* Add to lastlog */
281                                                                          TRUE, /* Add to utmp */
282                                                                          TRUE);/* Add to wtmp */
283
284         if (ret == -1)
285         {
286                 g_printerr (_("Unable to launch default shell\n"));
287                 return FALSE;
288         }
289
290         return TRUE;
291 }
292
293 /**
294  * Called when the child process running in the VteTerminal exits.
295  */
296 static void
297 tilda_terminal_child_exited_cb (GtkWidget *widget, gpointer data)
298 {
299         debug_enter  ();
300         debug_assert (GTK_IS_WIDGET(widget));
301         debug_assert (TILDA_IS_TERMINAL(data));
302
303         TildaTerminal *self = TILDA_TERMINAL(data);
304
305         /* Check the user's preference for what to do when the child terminal
306          * is closed. Take the appropriate action */
307         switch (self->exit_action)
308         {
309                 case TILDA_CHILD_EXIT_ACTION_EXIT:
310                         tilda_window_remove_terminal (TILDA_WINDOW(self->parent_window), self->number);
311                         break;
312                 case TILDA_CHILD_EXIT_ACTION_RESTART:
313                         vte_terminal_feed (VTE_TERMINAL(self->vte_term), "\r\n\r\n", 4);
314                         tilda_terminal_start_shell (self);
315                         break;
316                 case TILDA_CHILD_EXIT_ACTION_HOLD_OPEN:
317                         break;
318                 default:
319                         g_warning ("Bad value in self->exit_action\n");
320                         break;
321         }
322 }
323
324 /**
325  * Called when the child window title changes. Determines if a new
326  * title needs to be put into the notebook's tab label.
327  */
328 static void
329 tilda_terminal_window_title_changed_cb (GtkWidget *widget, gpointer data)
330 {
331         debug_enter  ();
332         debug_assert (GTK_IS_WIDGET(widget));
333         debug_assert (TILDA_IS_TERMINAL(data));
334
335         TildaTerminal *self = TILDA_TERMINAL(data);
336         TildaWindow *parent_window = TILDA_WINDOW(self->parent_window);
337         GtkWidget *label;
338         const gchar *vte_title = NULL;
339         gchar *new_title = NULL;
340
341         vte_title = vte_terminal_get_window_title (VTE_TERMINAL (widget));
342         label = gtk_notebook_get_tab_label (GTK_NOTEBOOK(parent_window->notebook), self->hbox);
343
344         switch (self->dynamic_title)
345         {
346                 case TILDA_DYNAMIC_TITLE_DISABLED:
347                         new_title = g_strdup (self->title);
348                         break;
349
350                 case TILDA_DYNAMIC_TITLE_AFTER_INITIAL:
351                         new_title = g_strdup_printf ("%s - %s", self->title, vte_title);
352                         break;
353
354                 case TILDA_DYNAMIC_TITLE_BEFORE_INITIAL:
355                         new_title = g_strdup_printf ("%s - %s", vte_title, self->title);
356                         break;
357
358                 case TILDA_DYNAMIC_TITLE_REPLACE_INITIAL:
359                         new_title = g_strdup (self->title);
360                         break;
361
362                 default:
363                         g_warning ("Bad value in self->dynamic-title\n");
364                         break;
365         }
366
367         gtk_label_set_text (GTK_LABEL(label), new_title);
368         g_free (new_title);
369 }
370
371 /**
372  * Gets called whenever there is a button-press event in the VteTerminal. It
373  * is used to open the user's web browser, for example.
374  */
375 static gint
376 tilda_terminal_button_press_cb (GtkWidget      *widget,
377                                                                 GdkEventButton *event,
378                                                                 gpointer        data)
379 {
380         debug_enter  ();
381         debug_assert (GTK_IS_WIDGET(widget));
382         debug_assert (TILDA_IS_TERMINAL(data));
383         debug_printf ("event->button = %d\n", event->button);
384
385         GError *error = NULL;
386         TildaTerminal *self = TILDA_TERMINAL(data);
387         VteTerminal *terminal = VTE_TERMINAL(self->vte_term);
388         gint tag, xpad, ypad;
389         gchar *match, *cmd, *web_browser_cmd;
390         gboolean ret = FALSE;
391
392         switch (event->button)
393         {
394                 case 3: /* Right Click */
395                         tilda_terminal_popup_menu (self);
396                         break;
397
398                 case 2: /* Middle Click */
399                         break;
400
401                 case 1: /* Left Click */
402                         vte_terminal_get_padding (terminal, &xpad, &ypad);
403                         match = vte_terminal_match_check (terminal,
404                                         (event->x - ypad) / terminal->char_width,
405                                         (event->y - ypad) / terminal->char_height,
406                                         &tag);
407
408                         /* Check if we can launch a web browser, and do so if possible */
409                         if ((event->state & GDK_CONTROL_MASK) && match != NULL)
410                         {
411                                 web_browser_cmd = g_strescape (self->web_browser, NULL);
412                                 cmd = g_strdup_printf ("%s %s", web_browser_cmd, match);
413
414                                 debug_printf ("Got a Ctrl+Left-Click -- match: '%s' tag: %d\n", match, tag);
415                                 debug_printf ("Launching command: '%s'\n", cmd);
416
417                                 ret = g_spawn_command_line_async(cmd, &error);
418
419                                 /* Check that the command launched */
420                                 if (!ret)
421                                 {
422                                         g_printerr (_("Failed to launch web browser command: `%s'\n"), cmd);
423                                         g_printerr (_("Error message: %s\n"), error->message);
424                                 }
425
426                                 /* Free allocated memory */
427                                 g_free (web_browser_cmd);
428                                 g_free (cmd);
429                         }
430
431                         /* Always free match if it is non NULL */
432                         g_free (match);
433                         break;
434
435                 default:
436                         break;
437         }
438
439         return FALSE;
440 }
441
442 /**
443  * Set the given TildaTerminal to the appropriate transparency level
444  * based on the self->transparency_percent member. */
445 static void
446 tilda_terminal_set_transparent (TildaTerminal *self)
447 {
448         debug_enter  ();
449         debug_assert (TILDA_IS_TERMINAL(self));
450
451         TildaWindow *parent_window = TILDA_WINDOW(self->parent_window);
452         gdouble temp;
453
454         /* Convert the transparency to VTE's format */
455         temp = ((gdouble) self->transparency_percent) / 100.0;
456
457         if (self->transparency_percent > 0)
458         {
459                 vte_terminal_set_background_saturation (VTE_TERMINAL(self->vte_term), temp);
460                 vte_terminal_set_opacity (VTE_TERMINAL(self->vte_term), (1.0 - temp) * 0xffff);
461
462                 /* Use fake transparency if necessary */
463                 vte_terminal_set_background_transparent (VTE_TERMINAL(self->vte_term),
464                                                                                                  !parent_window->have_real_transparency);
465                 return;
466         }
467
468         /* Turn off transparency */
469         vte_terminal_set_background_saturation (VTE_TERMINAL(self->vte_term), 0);
470         vte_terminal_set_opacity (VTE_TERMINAL(self->vte_term), 0xffff);
471         vte_terminal_set_background_transparent (VTE_TERMINAL(self->vte_term), FALSE);
472 }
473
474 /**
475  * Set the scrollbar position of the given TildaTerminal to
476  * the value in self->scrollbar_position.
477  */
478 static void
479 tilda_terminal_set_scrollbar_position (TildaTerminal *self)
480 {
481         debug_enter  ();
482         debug_assert (TILDA_IS_TERMINAL(self));
483
484         switch (self->scrollbar_position)
485         {
486                 case TILDA_SCROLLBAR_RIGHT:
487                         gtk_box_reorder_child (GTK_BOX(self->hbox), self->scrollbar, 0);
488                         gtk_widget_show (self->scrollbar);
489                         break;
490
491                 case TILDA_SCROLLBAR_LEFT:
492                         gtk_box_reorder_child (GTK_BOX(self->hbox), self->scrollbar, 1);
493                         gtk_widget_show (self->scrollbar);
494                         break;
495
496                 case TILDA_SCROLLBAR_DISABLED:
497                         gtk_widget_hide (self->scrollbar);
498                         break;
499
500                 default:
501                         g_warning ("Bad value in self->scrollbar_position\n");
502                         break;
503         }
504 }
505
506 /*******************************************************************************
507  * All GObject stuff is below. You probably don't need to change this...
508  ******************************************************************************/
509
510 static GObjectClass *parent_class = NULL;
511
512 enum tilda_terminal_properties {
513         TILDA_TERMINAL_NUMBER = 1,
514         TILDA_TERMINAL_PARENT_WINDOW,
515
516         /* All non-constructor-only properties */
517         TILDA_TERMINAL_BACKGROUND_IMAGE,
518         TILDA_TERMINAL_SHELL,
519         TILDA_TERMINAL_FONT,
520         TILDA_TERMINAL_TITLE,
521         TILDA_TERMINAL_WORKING_DIRECTORY,
522         TILDA_TERMINAL_WEB_BROWSER,
523
524         TILDA_TERMINAL_SCROLLBACK_LINES,
525         TILDA_TERMINAL_TRANSPARENCY_PERCENT,
526
527         TILDA_TERMINAL_BACKSPACE_BINDING,
528         TILDA_TERMINAL_DELETE_BINDING,
529         TILDA_TERMINAL_DYNAMIC_TITLE,
530         TILDA_TERMINAL_EXIT_ACTION,
531         TILDA_TERMINAL_SCROLLBAR_POSITION,
532
533         TILDA_TERMINAL_SCROLL_BACKGROUND,
534         TILDA_TERMINAL_SCROLL_ON_OUTPUT,
535         TILDA_TERMINAL_SCROLL_ON_KEYSTROKE,
536         TILDA_TERMINAL_ANTIALIASED,
537         TILDA_TERMINAL_ALLOW_BOLD_TEXT,
538         TILDA_TERMINAL_CURSOR_BLINKS,
539         TILDA_TERMINAL_AUDIBLE_BELL,
540         TILDA_TERMINAL_VISIBLE_BELL,
541         TILDA_TERMINAL_DOUBLE_BUFFERED,
542         TILDA_TERMINAL_MOUSE_AUTOHIDE,
543 };
544
545 static void
546 tilda_terminal_instance_init (GTypeInstance *instance,
547                                                           gpointer       g_class)
548 {
549         debug_enter ();
550
551         TildaTerminal *self = (TildaTerminal *) instance;
552
553         /* Initialize instance members and allocate any necessary memory here.
554          * NOTE: any constructor-time values will be set later. */
555         self->dispose_has_run = FALSE;
556         self->number = 0;
557
558         self->vte_term = vte_terminal_new ();
559         self->scrollbar = gtk_vscrollbar_new (VTE_TERMINAL(self->vte_term)->adjustment);
560         self->hbox = gtk_hbox_new (FALSE, 0);
561 }
562
563 static void
564 tilda_terminal_set_property (GObject      *object,
565                                                          guint         property_id,
566                                                          const GValue *value,
567                                                          GParamSpec   *pspec)
568 {
569         TildaTerminal *self = (TildaTerminal *) object;
570
571         switch (property_id) {
572
573                 case TILDA_TERMINAL_NUMBER:
574                         self->number = g_value_get_int (value);
575                         debug_printf ("terminal number: %d\n", self->number);
576                         break;
577
578                 case TILDA_TERMINAL_PARENT_WINDOW:
579                         self->parent_window = g_value_get_pointer (value);
580                         debug_printf ("terminal parent window: 0x%x\n", self->parent_window);
581                         break;
582
583                 case TILDA_TERMINAL_BACKGROUND_IMAGE:
584                         g_free (self->background_image);
585                         self->background_image = g_value_dup_string (value);
586                         vte_terminal_set_background_image_file (VTE_TERMINAL(self->vte_term), self->background_image);
587                         debug_printf ("terminal back img: %s\n", self->background_image);
588                         break;
589
590                 case TILDA_TERMINAL_SHELL:
591                         g_free (self->shell);
592                         self->shell = g_value_dup_string (value);
593                         tilda_terminal_start_shell (self);
594                         debug_printf ("terminal shell: %s\n", self->shell);
595                         break;
596
597                 case TILDA_TERMINAL_FONT:
598                         g_free (self->font);
599                         self->font = g_value_dup_string (value);
600                         vte_terminal_set_font_from_string_full (VTE_TERMINAL(self->vte_term),
601                                                                                                         self->font,
602                                                                                                         self->antialiased);
603                         debug_printf ("terminal font: %s\n", self->font);
604                         break;
605
606                 case TILDA_TERMINAL_TITLE:
607                         g_free (self->title);
608                         self->title = g_value_dup_string (value);
609                         debug_printf ("terminal title: %s\n", self->title);
610                         break;
611
612                 case TILDA_TERMINAL_WORKING_DIRECTORY:
613                         g_free (self->working_directory);
614                         self->working_directory = g_value_dup_string (value);
615                         debug_printf ("terminal wrk dir: %s\n", self->working_directory);
616                         break;
617
618                 case TILDA_TERMINAL_WEB_BROWSER:
619                         g_free (self->web_browser);
620                         self->web_browser = g_value_dup_string (value);
621                         debug_printf ("terminal web browser: %s\n", self->web_browser);
622                         break;
623
624                 case TILDA_TERMINAL_SCROLLBACK_LINES:
625                         self->scrollback_lines = g_value_get_int (value);
626                         vte_terminal_set_scrollback_lines (VTE_TERMINAL(self->vte_term), self->scrollback_lines);
627                         debug_printf ("terminal scrollback lines: %d\n", self->scrollback_lines);
628                         break;
629
630                 case TILDA_TERMINAL_TRANSPARENCY_PERCENT:
631                         self->transparency_percent = g_value_get_int (value);
632                         tilda_terminal_set_transparent (self);
633                         debug_printf ("terminal transp percent: %d\n", self->transparency_percent);
634                         break;
635
636                 case TILDA_TERMINAL_BACKSPACE_BINDING:
637                         self->backspace_binding = g_value_get_enum (value);
638                         vte_terminal_set_backspace_binding (VTE_TERMINAL(self->vte_term), self->backspace_binding);
639                         debug_printf ("terminal backspace key: %d\n", self->backspace_binding);
640                         break;
641
642                 case TILDA_TERMINAL_DELETE_BINDING:
643                         self->delete_binding = g_value_get_enum (value);
644                         vte_terminal_set_delete_binding (VTE_TERMINAL(self->vte_term), self->delete_binding);
645                         debug_printf ("terminal delete key: %d\n", self->delete_binding);
646                         break;
647
648                 case TILDA_TERMINAL_DYNAMIC_TITLE:
649                         self->dynamic_title = g_value_get_enum (value);
650                         debug_printf ("terminal dynamic title: %d\n", self->dynamic_title);
651                         break;
652
653                 case TILDA_TERMINAL_EXIT_ACTION:
654                         self->exit_action = g_value_get_enum (value);
655                         debug_printf ("terminal exit action: %d\n", self->exit_action);
656                         break;
657
658                 case TILDA_TERMINAL_SCROLLBAR_POSITION:
659                         self->scrollbar_position = g_value_get_enum (value);
660                         tilda_terminal_set_scrollbar_position (self);
661                         debug_printf ("terminal scrollbar position: %d\n", self->scrollbar_position);
662                         break;
663
664                 case TILDA_TERMINAL_SCROLL_BACKGROUND:
665                         self->scroll_background = g_value_get_boolean (value);
666                         vte_terminal_set_scroll_background (VTE_TERMINAL(self->vte_term), self->scroll_background);
667                         debug_printf ("terminal scroll background: %d\n", self->scroll_background);
668                         break;
669
670                 case TILDA_TERMINAL_SCROLL_ON_OUTPUT:
671                         self->scroll_on_output = g_value_get_boolean (value);
672                         vte_terminal_set_scroll_on_output (VTE_TERMINAL(self->vte_term), self->scroll_on_output);
673                         debug_printf ("terminal scroll on output: %d\n", self->scroll_on_output);
674                         break;
675
676                 case TILDA_TERMINAL_SCROLL_ON_KEYSTROKE:
677                         self->scroll_on_keystroke = g_value_get_boolean (value);
678                         vte_terminal_set_scroll_on_keystroke (VTE_TERMINAL(self->vte_term), self->scroll_on_keystroke);
679                         debug_printf ("terminal scroll on keystroke: %d\n", self->scroll_on_keystroke);
680                         break;
681
682                 case TILDA_TERMINAL_ANTIALIASED:
683                         self->antialiased = g_value_get_boolean (value);
684                         vte_terminal_set_font_from_string_full (VTE_TERMINAL(self->vte_term),
685                                                                                                         self->font,
686                                                                                                         self->antialiased);
687                         debug_printf ("terminal antialiased: %d\n", self->antialiased);
688                         break;
689
690                 case TILDA_TERMINAL_ALLOW_BOLD_TEXT:
691                         self->allow_bold_text = g_value_get_boolean (value);
692                         vte_terminal_set_allow_bold (VTE_TERMINAL(self->vte_term), self->allow_bold_text);
693                         debug_printf ("terminal allow bold text: %d\n", self->allow_bold_text);
694                         break;
695
696                 case TILDA_TERMINAL_CURSOR_BLINKS:
697                         self->cursor_blinks = g_value_get_boolean (value);
698                         vte_terminal_set_cursor_blinks (VTE_TERMINAL(self->vte_term), self->cursor_blinks);
699                         debug_printf ("terminal cursor blinks: %d\n", self->cursor_blinks);
700                         break;
701
702                 case TILDA_TERMINAL_AUDIBLE_BELL:
703                         self->audible_bell = g_value_get_boolean (value);
704                         vte_terminal_set_audible_bell (VTE_TERMINAL(self->vte_term), self->audible_bell);
705                         debug_printf ("terminal audible bell: %d\n", self->audible_bell);
706                         break;
707
708                 case TILDA_TERMINAL_VISIBLE_BELL:
709                         self->visible_bell = g_value_get_boolean (value);
710                         vte_terminal_set_visible_bell (VTE_TERMINAL(self->vte_term), self->visible_bell);
711                         debug_printf ("terminal visible bell: %d\n", self->visible_bell);
712                         break;
713
714                 case TILDA_TERMINAL_DOUBLE_BUFFERED:
715                         self->double_buffered = g_value_get_boolean (value);
716                         gtk_widget_set_double_buffered (GTK_WIDGET(self->vte_term), self->double_buffered);
717                         debug_printf ("terminal double buffered: %d\n", self->double_buffered);
718                         break;
719
720                 case TILDA_TERMINAL_MOUSE_AUTOHIDE:
721                         self->mouse_autohide = g_value_get_boolean (value);
722                         vte_terminal_set_mouse_autohide (VTE_TERMINAL(self->vte_term), self->mouse_autohide);
723                         debug_printf ("terminal mouse autohide: %d\n", self->mouse_autohide);
724                         break;
725
726                 default:
727                         /* We don't have this property... */
728                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
729                         break;
730         }
731 }
732
733 static void
734 tilda_terminal_get_property (GObject    *object,
735                                                          guint       property_id,
736                                                          GValue     *value,
737                                                          GParamSpec *pspec)
738 {
739         TildaTerminal *self = (TildaTerminal *) object;
740
741         switch (property_id) {
742
743                 case TILDA_TERMINAL_NUMBER:
744                         g_value_set_int (value, self->number);
745                         break;
746
747                 case TILDA_TERMINAL_PARENT_WINDOW:
748                         g_value_set_pointer (value, self->parent_window);
749                         break;
750
751                 case TILDA_TERMINAL_BACKGROUND_IMAGE:
752                         g_value_set_string (value, self->background_image);
753                         break;
754
755                 case TILDA_TERMINAL_SHELL:
756                         g_value_set_string (value, self->shell);
757                         break;
758
759                 case TILDA_TERMINAL_FONT:
760                         g_value_set_string (value, self->font);
761                         break;
762
763                 case TILDA_TERMINAL_TITLE:
764                         g_value_set_string (value, self->title);
765                         break;
766
767                 case TILDA_TERMINAL_WORKING_DIRECTORY:
768                         g_value_set_string (value, self->working_directory);
769                         break;
770
771                 case TILDA_TERMINAL_WEB_BROWSER:
772                         g_value_set_string (value, self->web_browser);
773                         break;
774
775                 case TILDA_TERMINAL_SCROLLBACK_LINES:
776                         g_value_set_int (value, self->scrollback_lines);
777                         break;
778
779                 case TILDA_TERMINAL_TRANSPARENCY_PERCENT:
780                         g_value_set_int (value, self->transparency_percent);
781                         break;
782
783                 case TILDA_TERMINAL_BACKSPACE_BINDING:
784                         g_value_set_enum (value, self->backspace_binding);
785                         break;
786
787                 case TILDA_TERMINAL_DELETE_BINDING:
788                         g_value_set_enum (value, self->delete_binding);
789                         break;
790
791                 case TILDA_TERMINAL_DYNAMIC_TITLE:
792                         g_value_set_enum (value, self->dynamic_title);
793                         break;
794
795                 case TILDA_TERMINAL_EXIT_ACTION:
796                         g_value_set_enum (value, self->exit_action);
797                         break;
798
799                 case TILDA_TERMINAL_SCROLLBAR_POSITION:
800                         g_value_set_enum (value, self->scrollbar_position);
801                         break;
802
803                 case TILDA_TERMINAL_SCROLL_BACKGROUND:
804                         g_value_set_boolean (value, self->scroll_background);
805                         break;
806
807                 case TILDA_TERMINAL_SCROLL_ON_OUTPUT:
808                         g_value_set_boolean (value, self->scroll_on_output);
809                         break;
810
811                 case TILDA_TERMINAL_SCROLL_ON_KEYSTROKE:
812                         g_value_set_boolean (value, self->scroll_on_keystroke);
813                         break;
814
815                 case TILDA_TERMINAL_ANTIALIASED:
816                         g_value_set_boolean (value, self->antialiased);
817                         break;
818
819                 case TILDA_TERMINAL_ALLOW_BOLD_TEXT:
820                         g_value_set_boolean (value, self->allow_bold_text);
821                         break;
822
823                 case TILDA_TERMINAL_CURSOR_BLINKS:
824                         g_value_set_boolean (value, self->cursor_blinks);
825                         break;
826
827                 case TILDA_TERMINAL_AUDIBLE_BELL:
828                         g_value_set_boolean (value, self->audible_bell);
829                         break;
830
831                 case TILDA_TERMINAL_VISIBLE_BELL:
832                         g_value_set_boolean (value, self->visible_bell);
833                         break;
834
835                 case TILDA_TERMINAL_DOUBLE_BUFFERED:
836                         g_value_set_boolean (value, self->double_buffered);
837                         break;
838
839                 case TILDA_TERMINAL_MOUSE_AUTOHIDE:
840                         g_value_set_boolean (value, self->mouse_autohide);
841
842                 default:
843                         /* We don't have this property... */
844                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
845                         break;
846         }
847 }
848
849 static GObject *
850 tilda_terminal_constructor (GType                  type,
851                                                         guint                  n_construct_properties,
852                                                         GObjectConstructParam *construct_properties)
853 {
854         debug_enter ();
855
856         GObject *obj;
857         TildaTerminal *self;
858         gint ret;
859
860         /* Invoke parent constructor */
861         TildaTerminalClass *klass;
862         klass = TILDA_TERMINAL_CLASS (g_type_class_peek (TILDA_TYPE_TERMINAL));
863         obj = parent_class->constructor (type,
864                                                                          n_construct_properties,
865                                                                          construct_properties);
866
867         /* Do other stuff here. The object is ready to go now, and all
868          * ctor properties have been set. */
869         self = TILDA_TERMINAL(obj);
870
871         /* Pack into the hbox */
872         gtk_box_pack_end (GTK_BOX(self->hbox), self->scrollbar, FALSE, FALSE, 0);
873         gtk_box_pack_end (GTK_BOX(self->hbox), self->vte_term, TRUE, TRUE, 0);
874         gtk_widget_show (self->scrollbar);
875         gtk_widget_show (self->vte_term);
876         gtk_widget_show (self->hbox);
877
878         /* Match URL's, etc */
879         ret = vte_terminal_match_add (VTE_TERMINAL(self->vte_term), DINGUS1);
880         vte_terminal_match_set_cursor_type (VTE_TERMINAL(self->vte_term), ret, GDK_HAND2);
881         ret = vte_terminal_match_add(VTE_TERMINAL(self->vte_term), DINGUS2);
882         vte_terminal_match_set_cursor_type (VTE_TERMINAL(self->vte_term), ret, GDK_HAND2);
883
884         /* Connect Signals */
885         g_signal_connect (G_OBJECT(self->vte_term), "child-exited",
886                                           G_CALLBACK(tilda_terminal_child_exited_cb), self);
887         g_signal_connect (G_OBJECT(self->vte_term), "eof",
888                                           G_CALLBACK(tilda_terminal_child_exited_cb), self);
889         g_signal_connect (G_OBJECT(self->vte_term), "window-title-changed",
890                                           G_CALLBACK(tilda_terminal_window_title_changed_cb), self);
891         g_signal_connect (G_OBJECT(self->vte_term), "button-press-event",
892                                           G_CALLBACK(tilda_terminal_button_press_cb), self);
893
894         /* Setup all of the defaults from the config file */
895         tilda_terminal_set_property_from_config (self, "background-image");
896         tilda_terminal_set_property_from_config (self, "shell");
897         tilda_terminal_set_property_from_config (self, "font");
898         tilda_terminal_set_property_from_config (self, "title");
899         tilda_terminal_set_property_from_config (self, "working-directory");
900         tilda_terminal_set_property_from_config (self, "web-browser");
901
902         tilda_terminal_set_property_from_config (self, "scrollback-lines");
903         tilda_terminal_set_property_from_config (self, "transparency-percent");
904
905         tilda_terminal_set_property_from_config (self, "backspace-binding");
906         tilda_terminal_set_property_from_config (self, "delete-binding");
907         tilda_terminal_set_property_from_config (self, "dynamic-title");
908         tilda_terminal_set_property_from_config (self, "exit-action");
909         tilda_terminal_set_property_from_config (self, "scrollbar-position");
910
911         tilda_terminal_set_property_from_config (self, "scroll-background");
912         tilda_terminal_set_property_from_config (self, "scroll-on-output");
913         tilda_terminal_set_property_from_config (self, "scroll-on-keystroke");
914         tilda_terminal_set_property_from_config (self, "antialiased");
915         tilda_terminal_set_property_from_config (self, "allow-bold-text");
916         tilda_terminal_set_property_from_config (self, "cursor-blinks");
917         tilda_terminal_set_property_from_config (self, "audible-bell");
918         tilda_terminal_set_property_from_config (self, "visible-bell");
919         tilda_terminal_set_property_from_config (self, "double-buffered");
920         tilda_terminal_set_property_from_config (self, "mouse-autohide");
921
922         /* All right! We're all ready to go, so register with DBus, and lets start! */
923         tilda_terminal_dbus_register_object (self);
924
925         return obj;
926 }
927
928 static void
929 tilda_terminal_dispose (GObject *obj)
930 {
931         debug_enter ();
932
933         TildaTerminal *self = (TildaTerminal *) obj;
934
935         /* We don't want to run dispose twice, so just return immediately */
936         if (self->dispose_has_run)
937                 return;
938
939         self->dispose_has_run = TRUE;
940
941         /*
942          * In dispose, you are supposed to free all types referenced from this
943          * object which might themselves hold a reference to self. Generally,
944          * the most simple solution is to unref all members on which you own a
945          * reference.
946          */
947
948         /* Chain up to the parent class */
949         G_OBJECT_CLASS (parent_class)->dispose (obj);
950 }
951
952 static void
953 tilda_terminal_finalize (GObject *obj)
954 {
955         debug_enter ();
956
957         TildaTerminal *self = (TildaTerminal *) obj;
958
959         /*
960          * Here, complete object destruction.
961          * You might not need to do much...
962          */
963         g_free (self->background_image);
964         g_free (self->shell);
965         g_free (self->font);
966         g_free (self->title);
967         g_free (self->working_directory);
968
969
970         /* Chain up to the parent class */
971         G_OBJECT_CLASS (parent_class)->finalize (obj);
972 }
973
974 static void
975 tilda_terminal_class_init (gpointer g_class,
976                                                    gpointer g_class_data)
977 {
978         debug_enter ();
979
980         GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
981         TildaTerminalClass *klass = TILDA_TERMINAL_CLASS (g_class);
982         GParamSpec *pspec;
983
984         /* Hook our functions to this type */
985         gobject_class->set_property = tilda_terminal_set_property;
986         gobject_class->get_property = tilda_terminal_get_property;
987         gobject_class->dispose = tilda_terminal_dispose;
988         gobject_class->finalize = tilda_terminal_finalize;
989         gobject_class->constructor = tilda_terminal_constructor;
990
991         parent_class = g_type_class_peek_parent (klass);
992
993         /* Hook the TildaTerminal type into DBus */
994         dbus_g_object_type_install_info (tilda_terminal_get_type(), &dbus_glib_tilda_terminal_object_info);
995
996         /* Install all of the properties */
997         pspec = g_param_spec_int ("number",
998                                                           _("Terminal number"),
999                                                           NULL,
1000                                                           0,            // min value
1001                                                           INT_MAX,      // max value
1002                                                           0,            // def value
1003                                                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
1004
1005         g_object_class_install_property (gobject_class,
1006                                                                          TILDA_TERMINAL_NUMBER,
1007                                                                          pspec);
1008
1009         pspec = g_param_spec_pointer ("parent-window",
1010                                                                   _("Pointer to terminal's parent TildaWindow"),
1011                                                                   NULL,
1012                                                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
1013
1014         g_object_class_install_property (gobject_class,
1015                                                                          TILDA_TERMINAL_PARENT_WINDOW,
1016                                                                          pspec);
1017
1018         pspec = g_param_spec_string ("background-image",
1019                                                                  _("Terminal's background image"),
1020                                                                  NULL,
1021                                                                  NULL,
1022                                                                  G_PARAM_READWRITE);
1023
1024         g_object_class_install_property (gobject_class,
1025                                                                          TILDA_TERMINAL_BACKGROUND_IMAGE,
1026                                                                          pspec);
1027
1028         pspec = g_param_spec_string ("shell",
1029                                                                  _("Terminal's shell"),
1030                                                                  NULL,
1031                                                                  NULL,
1032                                                                  G_PARAM_READWRITE);
1033
1034         g_object_class_install_property (gobject_class,
1035                                                                          TILDA_TERMINAL_SHELL,
1036                                                                          pspec);
1037
1038         pspec = g_param_spec_string ("font",
1039                                                                  _("Terminal's font"),
1040                                                                  NULL,
1041                                                                  NULL,
1042                                                                  G_PARAM_READWRITE);
1043
1044         g_object_class_install_property (gobject_class,
1045                                                                          TILDA_TERMINAL_FONT,
1046                                                                          pspec);
1047
1048         pspec = g_param_spec_string ("title",
1049                                                                  _("Terminal's title"),
1050                                                                  NULL,
1051                                                                  NULL,
1052                                                                  G_PARAM_READWRITE);
1053
1054         g_object_class_install_property (gobject_class,
1055                                                                          TILDA_TERMINAL_TITLE,
1056                                                                          pspec);
1057
1058         pspec = g_param_spec_string ("working-directory",
1059                                                                  _("Terminal's initial working directory"),
1060                                                                  NULL,
1061                                                                  NULL,
1062                                                                  G_PARAM_READWRITE);
1063
1064         g_object_class_install_property (gobject_class,
1065                                                                          TILDA_TERMINAL_WORKING_DIRECTORY,
1066                                                                          pspec);
1067
1068         pspec = g_param_spec_string ("web-browser",
1069                                                                  _("Terminal's web browser command"),
1070                                                                  NULL,
1071                                                                  NULL,
1072                                                                  G_PARAM_READWRITE);
1073
1074         g_object_class_install_property (gobject_class,
1075                                                                          TILDA_TERMINAL_WEB_BROWSER,
1076                                                                          pspec);
1077
1078         pspec = g_param_spec_int ("scrollback-lines",
1079                                                           _("Terminal's scrollback amount (lines)"),
1080                                                           NULL,
1081                                                           0,
1082                                                           INT_MAX, // TODO: artificially limit this?
1083                                                           1000,
1084                                                           G_PARAM_READWRITE);
1085
1086         g_object_class_install_property (gobject_class,
1087                                                                          TILDA_TERMINAL_SCROLLBACK_LINES,
1088                                                                          pspec);
1089
1090         pspec = g_param_spec_int ("transparency-percent",
1091                                                           _("Terminal's transparency (percent)"),
1092                                                           NULL,
1093                                                           0,
1094                                                           100,
1095                                                           0,
1096                                                           G_PARAM_READWRITE);
1097
1098         g_object_class_install_property (gobject_class,
1099                                                                          TILDA_TERMINAL_TRANSPARENCY_PERCENT,
1100                                                                          pspec);
1101
1102         pspec = g_param_spec_enum ("backspace-binding",
1103                                                            _("Terminal's backspace binding"),
1104                                                            NULL,
1105                                                            vte_terminal_erase_binding_get_type(),
1106                                                            VTE_ERASE_AUTO,
1107                                                            G_PARAM_READWRITE);
1108
1109         g_object_class_install_property (gobject_class,
1110                                                                          TILDA_TERMINAL_BACKSPACE_BINDING,
1111                                                                          pspec);
1112
1113         pspec = g_param_spec_enum ("delete-binding",
1114                                                            _("Terminal's delete binding"),
1115                                                            NULL,
1116                                                            vte_terminal_erase_binding_get_type(),
1117                                                            VTE_ERASE_AUTO,
1118                                                            G_PARAM_READWRITE);
1119
1120         g_object_class_install_property (gobject_class,
1121                                                                          TILDA_TERMINAL_DELETE_BINDING,
1122                                                                          pspec);
1123
1124         pspec = g_param_spec_enum ("dynamic-title",
1125                                                            _("Terminal's dynamic title generation method"),
1126                                                            NULL,
1127                                                            tilda_dynamic_title_get_type(),
1128                                                            TILDA_DYNAMIC_TITLE_DISABLED,
1129                                                            G_PARAM_READWRITE);
1130
1131         g_object_class_install_property (gobject_class,
1132                                                                          TILDA_TERMINAL_DYNAMIC_TITLE,
1133                                                                          pspec);
1134
1135         pspec = g_param_spec_enum ("exit-action",
1136                                                            _("Terminal's action upon child exit"),
1137                                                            NULL,
1138                                                            tilda_child_exit_action_get_type(),
1139                                                            TILDA_CHILD_EXIT_ACTION_EXIT,
1140                                                            G_PARAM_READWRITE);
1141
1142         g_object_class_install_property (gobject_class,
1143                                                                          TILDA_TERMINAL_EXIT_ACTION,
1144                                                                          pspec);
1145
1146         pspec = g_param_spec_enum ("scrollbar-position",
1147                                                            _("Terminal's scrollbar position"),
1148                                                            NULL,
1149                                                            tilda_scrollbar_position_get_type(),
1150                                                            TILDA_SCROLLBAR_RIGHT,
1151                                                            G_PARAM_READWRITE);
1152
1153         g_object_class_install_property (gobject_class,
1154                                                                          TILDA_TERMINAL_SCROLLBAR_POSITION,
1155                                                                          pspec);
1156
1157         pspec = g_param_spec_boolean ("scroll-background",
1158                                                                   _("Controls terminal's scrolling behavior"),
1159                                                                   NULL,
1160                                                                   FALSE,
1161                                                                   G_PARAM_READWRITE);
1162
1163         g_object_class_install_property (gobject_class,
1164                                                                          TILDA_TERMINAL_SCROLL_BACKGROUND,
1165                                                                          pspec);
1166
1167         pspec = g_param_spec_boolean ("scroll-on-output",
1168                                                                   _("Controls terminal's scrolling behavior on output"),
1169                                                                   NULL,
1170                                                                   FALSE,
1171                                                                   G_PARAM_READWRITE);
1172
1173         g_object_class_install_property (gobject_class,
1174                                                                          TILDA_TERMINAL_SCROLL_ON_OUTPUT,
1175                                                                          pspec);
1176
1177         pspec = g_param_spec_boolean ("scroll-on-keystroke",
1178                                                                   _("Controls the terminal's scrolling behavior on keystroke"),
1179                                                                   NULL, FALSE, G_PARAM_READWRITE);
1180
1181         g_object_class_install_property (gobject_class,
1182                                                                          TILDA_TERMINAL_SCROLL_ON_KEYSTROKE,
1183                                                                          pspec);
1184
1185         pspec = g_param_spec_boolean ("antialiased",
1186                                                                   _("Attempt to antialias fonts"),
1187                                                                   NULL, FALSE, G_PARAM_READWRITE);
1188
1189         g_object_class_install_property (gobject_class,
1190                                                                          TILDA_TERMINAL_ANTIALIASED,
1191                                                                          pspec);
1192
1193         pspec = g_param_spec_boolean ("allow-bold-text",
1194                                                                   _("Allow bold text"),
1195                                                                   NULL, FALSE, G_PARAM_READWRITE);
1196
1197         g_object_class_install_property (gobject_class,
1198                                                                          TILDA_TERMINAL_ALLOW_BOLD_TEXT,
1199                                                                          pspec);
1200
1201         pspec = g_param_spec_boolean ("cursor-blinks",
1202                                                                   _("Enable cursor blinking"),
1203                                                                   NULL, FALSE, G_PARAM_READWRITE);
1204
1205         g_object_class_install_property (gobject_class,
1206                                                                          TILDA_TERMINAL_CURSOR_BLINKS,
1207                                                                          pspec);
1208
1209         pspec = g_param_spec_boolean ("audible-bell",
1210                                                                   _("Enable the audible bell"),
1211                                                                   NULL, FALSE, G_PARAM_READWRITE);
1212
1213         g_object_class_install_property (gobject_class,
1214                                                                          TILDA_TERMINAL_AUDIBLE_BELL,
1215                                                                          pspec);
1216
1217         pspec = g_param_spec_boolean ("visible-bell",
1218                                                                   _("Enable the visible bell"),
1219                                                                   NULL, FALSE, G_PARAM_READWRITE);
1220
1221         g_object_class_install_property (gobject_class,
1222                                                                          TILDA_TERMINAL_VISIBLE_BELL,
1223                                                                          pspec);
1224
1225         pspec = g_param_spec_boolean ("double-buffered",
1226                                                                   _("Double buffer the terminal"),
1227                                                                   NULL, FALSE, G_PARAM_READWRITE);
1228
1229         g_object_class_install_property (gobject_class,
1230                                                                          TILDA_TERMINAL_DOUBLE_BUFFERED,
1231                                                                          pspec);
1232
1233         pspec = g_param_spec_boolean ("mouse-autohide",
1234                                                                   _("Hide the mouse cursor while typing"),
1235                                                                   NULL, FALSE, G_PARAM_READWRITE);
1236
1237         g_object_class_install_property (gobject_class,
1238                                                                          TILDA_TERMINAL_MOUSE_AUTOHIDE,
1239                                                                          pspec);
1240 }
1241
1242 GType
1243 tilda_terminal_get_type (void)
1244 {
1245         static GType type = 0;
1246
1247         if (type == 0)
1248         {
1249                 static const GTypeInfo info = {
1250                         sizeof (TildaTerminalClass),
1251                         NULL,   /* base_init */
1252                         NULL,   /* base_finalize */
1253                         tilda_terminal_class_init,      /* class_init */
1254                         NULL,   /* class_finalize */
1255                         NULL,   /* class_data */
1256                         sizeof (TildaTerminal),
1257                         0,              /* n_preallocs */
1258                         tilda_terminal_instance_init,   /* instance_init */
1259                 };
1260
1261                 type = g_type_register_static (G_TYPE_OBJECT,
1262                                                                            "TildaTerminalType",
1263                                                                            &info,
1264                                                                            0);
1265         }
1266
1267         return type;
1268 }
1269
1270 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */