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