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