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