1/*
2 * terminal.vala - This file is part of the Geany MultiTerm plugin
3 *
4 * Copyright (c) 2012 Matthew Brush <matt@geany.org>.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22using Gtk;
23using Gdk;
24using Vte;
25
26namespace MultiTerm
27{
28	public class Terminal : Frame
29	{
30		public Vte.Terminal terminal;
31		private ShellConfig sh;
32
33		public signal bool right_click_event(EventButton event);
34
35		private void on_window_title_changed()
36		{
37			tab_label_text = terminal.window_title;
38		}
39
40		public string tab_label_text
41		{
42			get
43			{
44				TabLabel label = this.get_data<TabLabel>("label");
45				return label.text;
46			}
47			set
48			{
49				TabLabel label = this.get_data<TabLabel>("label");
50				label.text = value;
51			}
52		}
53
54		public string background_color
55		{
56			set
57			{
58				Gdk.Color color = Gdk.Color();
59				Gdk.Colormap.get_system().alloc_color(color, true, true);
60				Gdk.Color.parse(value, out color);
61				terminal.set_color_background(color);
62			}
63		}
64
65		public string foreground_color
66		{
67			set
68			{
69				Gdk.Color color = Gdk.Color();
70				Gdk.Colormap.get_system().alloc_color(color, true, true);
71				Gdk.Color.parse(value, out color);
72				terminal.set_color_foreground(color);
73			}
74		}
75
76		public void run_command(string command)
77		{
78			Pid pid;
79			string[] argv = { command, null };
80			try
81			{
82				terminal.fork_command_full(PtyFlags.DEFAULT, null, argv, null,
83					SpawnFlags.SEARCH_PATH, null, out pid);
84				//debug("Started terminal with pid of '%d'", pid);
85			}
86			catch (Error err)
87			{
88				warning(_("Unable to run command: %s"), err.message);
89			}
90		}
91
92		private void on_vte_realize()
93		{
94			if (sh.cfg != null)
95			{
96				background_color = sh.background_color;
97				foreground_color = sh.foreground_color;
98			}
99			else
100			{
101				background_color = "#ffffff";
102				foreground_color = "#000000";
103			}
104
105			/* Start receiving events for mouse clicks */
106			terminal.add_events(EventMask.BUTTON_PRESS_MASK);
107			terminal.button_press_event.connect(on_button_press);
108		}
109
110		private void on_child_exited()
111		{
112			run_command(this.sh.command);
113		}
114
115		private bool on_button_press(EventButton event)
116		{
117			if (event.button == 3)
118				return right_click_event(event);
119			return false;
120		}
121
122		public void send_command(string command)
123		{
124			terminal.feed_child("%s\n".printf(command), -1);
125		}
126
127		public Terminal(ShellConfig sh)
128		{
129			VScrollbar vsb;
130			HBox hbox;
131
132			this.sh = sh;
133			if (this.sh.command.strip() == "")
134				this.sh.command = "sh";
135
136			terminal = new Vte.Terminal();
137			terminal.set_size_request(100, 100); // stupid
138			terminal.show_all();
139
140			vsb = new VScrollbar(terminal.get_adjustment());
141			hbox = new HBox(false, 0);
142
143			hbox.pack_start(terminal, true, true, 0);
144			hbox.pack_start(vsb, false, false, 0);
145
146			this.add(hbox);
147
148			if (this.sh.track_title)
149				terminal.window_title_changed.connect(on_window_title_changed);
150
151			terminal.child_exited.connect(on_child_exited);
152
153			if (this.sh.cfg != null)
154			{
155				terminal.set_font_from_string(this.sh.font);
156				terminal.set_allow_bold(this.sh.allow_bold);
157				terminal.set_audible_bell(this.sh.audible_bell);
158				terminal.set_cursor_blink_mode(this.sh.cursor_blink_mode);
159				terminal.set_cursor_shape(this.sh.cursor_shape);
160				terminal.set_backspace_binding(this.sh.backspace_binding);
161				terminal.set_mouse_autohide(this.sh.pointer_autohide);
162				terminal.set_scroll_on_keystroke(this.sh.scroll_on_keystroke);
163				terminal.set_scroll_on_output(this.sh.scroll_on_output);
164				terminal.set_scrollback_lines(this.sh.scrollback_lines);
165				terminal.set_visible_bell(this.sh.visible_bell);
166				terminal.set_word_chars(this.sh.word_chars);
167			}
168			else
169			{
170				terminal.set_font_from_string("Monospace 9");
171				terminal.set_allow_bold(true);
172				terminal.set_audible_bell(true);
173				terminal.set_cursor_blink_mode(TerminalCursorBlinkMode.SYSTEM);
174				terminal.set_cursor_shape(TerminalCursorShape.BLOCK);
175				terminal.set_backspace_binding(TerminalEraseBinding.AUTO);
176				terminal.set_mouse_autohide(false);
177				terminal.set_scroll_on_keystroke(true);
178				terminal.set_scroll_on_output(false);
179				terminal.set_scrollback_lines(512);
180				terminal.set_visible_bell(false);
181				terminal.set_word_chars("");
182			}
183
184			terminal.realize.connect(on_vte_realize); /* colors can only be set on realize (lame) */
185			run_command(this.sh.command);
186		}
187
188	}
189}
190