1 /*
2  * Copyright (c) 2008-2010 Lu, Chao-Ming (Tetralet).  All rights reserved.
3  *
4  * This file is part of LilyTerm.
5  *
6  * LilyTerm 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 3 of the License, or
9  * (at your option) any later version.
10  *
11  * LilyTerm 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 LilyTerm.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "property.h"
21 
22 extern gboolean proc_exist;
23 extern struct Command command[COMMAND];
24 extern struct Color_Theme system_color_theme[THEME];
25 
create_theme_color_data(GdkColor color[COLOR],GdkColor color_orig[COLOR],gdouble color_brightness,gboolean invert_color,gboolean default_vte_theme,gboolean dim_fg_color)26 void create_theme_color_data(GdkColor color[COLOR], GdkColor color_orig[COLOR], gdouble color_brightness, gboolean invert_color,
27 			     gboolean default_vte_theme, gboolean dim_fg_color)
28 {
29 #ifdef DETAIL
30 	g_debug("! Launch create_theme_color_data() with color = %p, color_orig = %p, color_brightness = %3f, invert_color = %d",
31 		color, color_orig, color_brightness, invert_color);
32 #endif
33 #ifdef SAFEMODE
34 	if ((color==NULL) || (color_orig==NULL)) return;
35 #endif
36 	if (! default_vte_theme)
37 	{
38 		// g_debug("Get win_data = %d when set background saturation!", win_data);
39 		color_brightness = CLAMP(color_brightness, -1, 1);
40 
41 		gint i;
42 		for (i=1; i<COLOR-1; i++)
43 		{
44 			// g_debug("adjuset the color of %d", get_color_index(invert_color, i));
45 			adjust_ansi_color(&color[i], &color_orig[get_color_index(invert_color, i)], color_brightness);
46 			// print_color(get_color_index(invert_color, i), "create_theme_color_data(): color_orig ", color_orig[i]);
47 			// print_color(i, "create_theme_color_data(): new: color ", color[i]);
48 		}
49 	}
50 
51 	// The fg_color and bg_color will not affect by color_brightness
52 	if (dim_fg_color)
53 		adjust_ansi_color(&color[COLOR-1], &color_orig[get_color_index(invert_color, COLOR-1)], color_brightness);
54 	else
55 		color[COLOR-1] = color_orig[get_color_index(invert_color, COLOR-1)];
56 	// print_color(get_color_index(invert_color, COLOR-1), "create_theme_color_data(): fg color_orig ", color_orig[COLOR-1]);
57 	// print_color(COLOR-1, "create_theme_color_data(): new: fg color ", color[COLOR-1]);
58 	color[0] = color_orig[get_color_index(invert_color, 0)];
59 	// print_color(get_color_index(invert_color, 0), "create_theme_color_data(): bg color_orig ", color_orig[0]);
60 	// print_color(0, "create_theme_color_data(): new: bg color ", color[0]);
61 }
62 
adjust_ansi_color(GdkColor * color,GdkColor * color_orig,gdouble color_brightness)63 void adjust_ansi_color(GdkColor *color, GdkColor *color_orig, gdouble color_brightness)
64 {
65 #ifdef DETAIL
66 	g_debug("! Launch adjust_ansi_color() with color = %p, color_orig = %p, color_brightness = %3f",
67 		color, color_orig, color_brightness);
68 #endif
69 #ifdef SAFEMODE
70 	if ((color==NULL) || (color_orig==NULL)) return;
71 #endif
72 	if (color_brightness>=0)
73 	{
74 		color->red = (0xffff - color_orig->red) * color_brightness + color_orig->red;
75 		color->green = (0xffff - color_orig->green) * color_brightness + color_orig->green;
76 		color->blue = (0xffff - color_orig->blue) * color_brightness + color_orig->blue;
77 	}
78 	else
79 	{
80 		color->red = (1 + color_brightness) * color_orig->red;
81 		color->green = (1 + color_brightness) * color_orig->green;
82 		color->blue = (1 + color_brightness) * color_orig->blue;
83 	}
84 }
85 
generate_all_color_datas(struct Window * win_data)86 void generate_all_color_datas(struct Window *win_data)
87 {
88 #ifdef DETAIL
89 	g_debug("! Launch generate_all_color_datas() with win_data = %p", win_data);
90 #endif
91 #ifdef SAFEMODE
92 	if (win_data==NULL) return;
93 #endif
94 	GdkColor *temp_color = get_current_color_theme(win_data);
95 
96 	gboolean default_vte_theme = use_default_vte_theme(win_data);
97 	create_theme_color_data(win_data->color, temp_color, win_data->color_brightness, win_data->invert_color, default_vte_theme, FALSE);
98 	create_theme_color_data(win_data->color_inactive, temp_color, win_data->color_brightness_inactive, win_data->invert_color, default_vte_theme, TRUE);
99 }
100 
get_current_color_theme(struct Window * win_data)101 GdkColor *get_current_color_theme(struct Window *win_data)
102 {
103 #ifdef DETAIL
104 	g_debug("! Launch current_color_theme() with win_data = %p", win_data);
105 #endif
106 #ifdef SAFEMODE
107 	if (win_data==NULL) return NULL;
108 #endif
109 	// g_debug("win_data->use_custom_theme = %d", win_data->use_custom_theme);
110 	if (win_data->use_custom_theme)
111 		return win_data->custom_color_theme[win_data->color_theme_index].color;
112 	else
113 		return system_color_theme[win_data->color_theme_index].color;
114 }
115 
116 
117 // to init a new page
init_new_page(struct Window * win_data,struct Page * page_data,glong column,glong row)118 void init_new_page(struct Window *win_data,
119 		   struct Page *page_data,
120 		   glong column,
121 		   glong row)
122 {
123 #ifdef DETAIL
124 	g_debug("! Launch init_new_page() with win_data = %p, page_data = %p, "
125 		" column = %ld, row = %ld", win_data, page_data, column, row);
126 #endif
127 #ifdef SAFEMODE
128 	if ((win_data==NULL) || (page_data==NULL) || (page_data->vte==NULL)) return;
129 #endif
130 	// g_debug("Get win_data = %d when initing new page!", win_data);
131 
132 #ifdef SAFEMODE
133 	if (page_data->font_name)
134 	{
135 #endif
136 		// set font
137 		// g_debug("Set Font AA = %d", win_data->font_anti_alias);
138 		vte_terminal_set_font_from_string_full (VTE_TERMINAL(page_data->vte),
139 							page_data->font_name,
140 							win_data->font_anti_alias);
141 #ifdef SAFEMODE
142 	}
143 #endif
144 	//g_debug("Got font size from %s: %d", font_name, pango_font_description_get_size (
145 	//	  pango_font_description_from_string(font_name))/PANGO_SCALE);
146 
147 	// set terminal size
148 	// g_debug("Set the vte size to: %dx%d", column, row);
149 #ifdef SAFEMODE
150 	if (page_data->vte)
151 #endif
152 		vte_terminal_set_size(VTE_TERMINAL(page_data->vte), column, row);
153 
154 #  ifdef GEOMETRY
155 	g_debug("@ init_new_page(for %p, vte = %p): Set win_data->keep_vte_size to %d, and column = %ld, row = %ld",
156 		win_data->window, page_data->vte, win_data->keep_vte_size, column, row);
157 #  endif
158 
159 	set_vte_color(page_data->vte, use_default_vte_theme(win_data), win_data->cursor_color, win_data->color, FALSE);
160 
161 	// set transparent
162 	set_background_saturation(NULL, 0, win_data->background_saturation, page_data->vte);
163 
164 	// other settings
165 	vte_terminal_set_word_chars(VTE_TERMINAL(page_data->vte), win_data->word_chars);
166 	vte_terminal_set_scrollback_lines(VTE_TERMINAL(page_data->vte), win_data->scrollback_lines);
167 
168 	// some fixed parameter
169 	vte_terminal_set_scroll_on_output(VTE_TERMINAL(page_data->vte), FALSE);
170 	vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(page_data->vte), TRUE);
171 	// vte_terminal_set_backspace_binding (VTE_TERMINAL(page_data->vte), VTE_ERASE_ASCII_DELETE);
172 	// vte_terminal_set_delete_binding (VTE_TERMINAL(page_data->vte), VTE_ERASE_ASCII_DELETE);
173 	// vte_terminal_set_emulation (VTE_TERMINAL(page_data->vte), "xterm");
174 #ifdef ENABLE_FIND_STRING
175 	vte_terminal_search_set_wrap_around (VTE_TERMINAL(page_data->vte), TRUE);
176 #endif
177 
178 	set_hyprelink(win_data, page_data);
179 	set_cursor_blink(win_data, page_data);
180 
181 	vte_terminal_set_audible_bell (VTE_TERMINAL(page_data->vte), win_data->audible_bell);
182 	vte_terminal_set_visible_bell (VTE_TERMINAL(page_data->vte), win_data->visible_bell);
183 	// g_debug("init_new_page(): call set_vte_urgent_bell()");
184 	set_vte_urgent_bell(win_data, page_data);
185 	vte_terminal_set_backspace_binding (VTE_TERMINAL(page_data->vte), win_data->erase_binding);
186 #ifdef ENABLE_CURSOR_SHAPE
187 	vte_terminal_set_cursor_shape(VTE_TERMINAL(page_data->vte), win_data->cursor_shape);
188 #endif
189 	vte_terminal_set_emulation (VTE_TERMINAL(page_data->vte), win_data->emulate_term);
190 }
191 
192 
set_cursor_blink(struct Window * win_data,struct Page * page_data)193 void set_cursor_blink(struct Window *win_data, struct Page *page_data)
194 {
195 #ifdef DETAIL
196 	g_debug("! Launch set_cursor_blink() with win_data = %p, page_data = %p", win_data, page_data);
197 #endif
198 #ifdef SAFEMODE
199 	if ((win_data==NULL) || (page_data==NULL) || (page_data->vte==NULL)) return;
200 #endif
201 	// g_debug("set_cursor_blink(): win_data->cursor_blinks = %d", win_data->cursor_blinks);
202 
203 
204 #ifdef USE_NEW_VTE_CURSOR_BLINKS_MODE
205 	vte_terminal_set_cursor_blink_mode (VTE_TERMINAL(page_data->vte), win_data->cursor_blinks);
206 #else
207 	vte_terminal_set_cursor_blinks (VTE_TERMINAL(page_data->vte), win_data->cursor_blinks);
208 #endif
209 }
210 
set_hyprelink(struct Window * win_data,struct Page * page_data)211 void set_hyprelink(struct Window *win_data, struct Page *page_data)
212 {
213 #ifdef DETAIL
214 	g_debug("! Launch set_hyprelink() with win_data = %p, page_data = %p", win_data, page_data);
215 #endif
216 #ifdef SAFEMODE
217 	if ((win_data==NULL) || (page_data==NULL) || (page_data->vte==NULL)) return;
218 #endif
219 	if (win_data->enable_hyperlink && win_data->enable_key_binding)
220 	{
221 		gint i;
222 		for (i=0; i<COMMAND; i++)
223 		{
224 #ifdef USE_NEW_VTE_MATCH_ADD_GREGEX
225 			GRegex *regex = g_regex_new (command[i].match, G_REGEX_CASELESS | G_REGEX_OPTIMIZE,
226 						     0, NULL);
227 			page_data->tag[i] = vte_terminal_match_add_gregex (VTE_TERMINAL(page_data->vte),
228 									   regex, 0);
229 			g_regex_unref (regex);
230 #else
231 			page_data->tag[i] = vte_terminal_match_add (VTE_TERMINAL(page_data->vte),
232 								    command[i].match);
233 #endif
234 			vte_terminal_match_set_cursor_type(VTE_TERMINAL(page_data->vte),
235 							   page_data->tag[i],
236 							   GDK_HAND2);
237 		}
238 	}
239 	else
240 		vte_terminal_match_clear_all(VTE_TERMINAL(page_data->vte));
241 }
242 
set_vte_color(GtkWidget * vte,gboolean default_vte_color,GdkColor cursor_color,GdkColor color[COLOR],gboolean update_fg_only)243 void set_vte_color(GtkWidget *vte, gboolean default_vte_color, GdkColor cursor_color, GdkColor color[COLOR], gboolean update_fg_only)
244 {
245 #ifdef DETAIL
246 	g_debug("! Launch set_vte_color() with vte = %p, default_vte_color_theme = %d,  color = %p",
247 		vte, default_vte_color, color);
248 #endif
249 #ifdef SAFEMODE
250 	if ((vte==NULL) || (color ==NULL)) return;
251 #endif
252 	// set font/background colors
253 
254 	// gint i;
255 	// for (i=0; i< COLOR; i++)
256 	//	print_color(i, "set_vte_color():", color[i]);
257 
258 	if (! update_fg_only)
259 	{
260 		vte_terminal_set_default_colors(VTE_TERMINAL(vte));
261 
262 		if (default_vte_color)
263 			vte_terminal_set_color_background(VTE_TERMINAL(vte), &(color[0]));
264 		else
265 			vte_terminal_set_colors(VTE_TERMINAL(vte), &(color[COLOR-1]), &(color[0]), color, 16);
266 
267 		vte_terminal_set_background_tint_color (VTE_TERMINAL(vte), &(color[0]));
268 	}
269 
270 	if (default_vte_color | update_fg_only)
271 		vte_terminal_set_color_foreground(VTE_TERMINAL(vte), &(color[COLOR-1]));
272 
273 	vte_terminal_set_colors(VTE_TERMINAL(vte), &(color[COLOR-1]), &(color[0]), color, 16);
274 
275 	// print_color(-1, "set_vte_color(): cursor_color", cursor_color);
276 	vte_terminal_set_color_cursor(VTE_TERMINAL(vte), &(cursor_color));
277 }
278 
use_default_vte_theme(struct Window * win_data)279 gboolean use_default_vte_theme(struct Window *win_data)
280 {
281 #ifdef DETAIL
282 	g_debug("! Launch use_default_vte_theme() with win_data = %p", win_data);
283 #endif
284 #ifdef SAFEMODE
285 	if (win_data==NULL) return TRUE;
286 #endif
287 	return ! (win_data->color_theme_index || win_data->invert_color || win_data->color_brightness || win_data->color_brightness_inactive);
288 }
289 
set_page_width(struct Window * win_data,struct Page * page_data)290 void set_page_width(struct Window *win_data, struct Page *page_data)
291 {
292 #ifdef DETAIL
293 	g_debug("! Launch set_page_width() with win_data = %p, page_data = %p", win_data, page_data);
294 #endif
295 #ifdef SAFEMODE
296 	if ((win_data==NULL) || (page_data==NULL) || (page_data->label_text==NULL)) return;
297 #endif
298 	gtk_label_set_width_chars(GTK_LABEL(page_data->label_text), win_data->page_width);
299 }
300 
pack_vte_and_scroll_bar_to_hbox(struct Window * win_data,struct Page * page_data)301 void pack_vte_and_scroll_bar_to_hbox(struct Window *win_data, struct Page *page_data)
302 {
303 #ifdef DETAIL
304 	g_debug("! Launch pack_vte_and_scroll_bar_to_hbox() with win_data = %p, page_data = %p", win_data, page_data);
305 #endif
306 #ifdef SAFEMODE
307 	if ((win_data==NULL) || (page_data==NULL) || (page_data->hbox==NULL)) return;
308 #endif
309 	if (win_data->scroll_bar_position)
310 	{
311 		gtk_box_pack_start(GTK_BOX(page_data->hbox), page_data->vte, TRUE, TRUE, 0);
312 		gtk_box_pack_start(GTK_BOX(page_data->hbox), page_data->scroll_bar, FALSE, FALSE, 0);
313 	}
314 	else
315 	{
316 		gtk_box_pack_end(GTK_BOX(page_data->hbox), page_data->vte, TRUE, TRUE, 0);
317 		gtk_box_pack_end(GTK_BOX(page_data->hbox), page_data->scroll_bar, FALSE, FALSE, 0);
318 	}
319 	if (! win_data->show_scroll_bar)
320 		gtk_widget_set_no_show_all (page_data->scroll_bar, TRUE);
321 }
322 
check_show_or_hide_scroll_bar(struct Window * win_data)323 gboolean check_show_or_hide_scroll_bar(struct Window *win_data)
324 {
325 #ifdef DETAIL
326 	g_debug("! Launch check_show_or_hide_scroll_bar() with win_data = %p", win_data);
327 #endif
328 #ifdef SAFEMODE
329 	if (win_data==NULL) return FALSE;
330 #endif
331 	gboolean show = FALSE;
332 	// g_debug("check_show_or_hide_scroll_bar(): win_data->show_scroll_bar = %d", win_data->show_scroll_bar);
333 	switch (win_data->show_scroll_bar)
334 	{
335 		case AUTOMATIC:
336 			show = ! win_data->true_fullscreen;
337 			break;
338 		case ON:
339 		case FORCE_ON:
340 			show = TRUE;
341 			break;
342 		default:
343 			break;
344 	}
345 	// g_debug("check_show_or_hide_scroll_bar(): Got win_data->show_scroll_bar = %d, show = %d",
346 	//	win_data->show_scroll_bar, show);
347 	return show;
348 }
349 
show_and_hide_scroll_bar(struct Page * page_data,gboolean show_scroll_bar)350 void show_and_hide_scroll_bar(struct Page *page_data, gboolean show_scroll_bar)
351 {
352 #ifdef DETAIL
353 	g_debug("! Launch hide_scroll_bar() with page_data = %p", page_data);
354 #endif
355 #ifdef SAFEMODE
356 	if ((page_data==NULL) || (page_data->scroll_bar==NULL)) return;
357 #endif
358 	if (show_scroll_bar)
359 		gtk_widget_show (page_data->scroll_bar);
360 	else
361 		gtk_widget_hide (page_data->scroll_bar);
362 }
363 
add_remove_page_timeout_id(struct Window * win_data,struct Page * page_data)364 void add_remove_page_timeout_id(struct Window *win_data, struct Page *page_data)
365 {
366 #ifdef DETAIL
367 	g_debug("! Launch add_remove_page_timeout_id() with win_data = %p, page_data = %p", win_data, page_data);
368 #endif
369 #ifdef SAFEMODE
370 	if ((win_data==NULL) || (page_data==NULL)) return;
371 #endif
372 	if (page_data->timeout_id)
373 	{
374 		g_source_remove (page_data->timeout_id);
375 		// get_and_update_page_name(page_data);
376 		// win_data->page_names_no++;
377 		//if ((page_data->custom_page_name == NULL) && (page_data->label_text != NULL))
378 		//	 page_data->custom_page_name = g_strdup(page_data->page_name);
379 		page_data->timeout_id = 0;
380 	}
381 	else
382 		// monitor_cmdline(page_data->monitor, page_data->pid);
383 		// monitor_cmdline(page_data->channel, page_data->pid);
384 		page_data->timeout_id = g_timeout_add_seconds (1,
385 							       (GSourceFunc)monitor_cmdline,
386 							       page_data);
387 }
388 
add_remove_window_title_changed_signal(struct Page * page_data)389 void add_remove_window_title_changed_signal(struct Page *page_data)
390 {
391 #ifdef DETAIL
392 	g_debug("! Launch add_remove_window_title_changed_signal() with page_data = %p", page_data);
393 #endif
394 #ifdef SAFEMODE
395 	if (page_data==NULL) return;
396 #endif
397 	if (page_data->page_shows_window_title)
398 		page_data->window_title_signal = g_signal_connect(page_data->vte, "window-title-changed",
399 								  G_CALLBACK(update_page_window_title), page_data);
400 	else if (page_data->window_title_signal)
401 	{
402 		g_signal_handler_disconnect(page_data->vte, page_data->window_title_signal);
403 		page_data->window_title_signal = 0;
404 	}
405 
406 }
407 
set_background_saturation(GtkRange * range,GtkScrollType scroll,gdouble value,GtkWidget * vte)408 gboolean set_background_saturation(GtkRange *range, GtkScrollType scroll, gdouble value, GtkWidget *vte)
409 {
410 #ifdef DETAIL
411 	g_debug("! Launch set_background_saturation() with value = %f, vte = %p", value, vte);
412 #endif
413 #ifdef SAFEMODE
414 	if (vte==NULL) return FALSE;
415 #endif
416 	struct Page *page_data = (struct Page *)g_object_get_data(G_OBJECT(vte), "Page_Data");
417 #ifdef SAFEMODE
418 	if (page_data==NULL || (page_data->window==NULL)) return FALSE;
419 #endif
420 	struct Window *win_data = (struct Window *)g_object_get_data(G_OBJECT(page_data->window), "Win_Data");
421 #ifdef SAFEMODE
422 	if (win_data==NULL) return FALSE;
423 #endif
424 	// g_debug("Get win_data = %d when set background saturation!", win_data);
425 
426 	value = CLAMP(value, 0, 1);
427 
428 #ifdef ENABLE_RGBA
429 	if (win_data->use_rgba == -1)
430 	{
431 		if (win_data->transparent_background)
432 			vte_terminal_set_opacity(VTE_TERMINAL(vte), (1-value) * 65535);
433 		else
434 			vte_terminal_set_opacity(VTE_TERMINAL(vte), 65535);
435 	}
436 	else
437 #endif
438 		vte_terminal_set_background_transparent(VTE_TERMINAL(vte), win_data->transparent_background);
439 
440 	// g_debug("set_background_saturation(): win_data->transparent_background = %d, value = %1.3f",
441 	//	win_data->transparent_background, value);
442 	// g_debug("set_background_saturation(): win_data->background_image = %s", win_data->background_image);
443 	if (win_data->transparent_background)
444 	{
445 		vte_terminal_set_background_image_file (VTE_TERMINAL(vte), NULL_DEVICE);
446 		vte_terminal_set_background_saturation( VTE_TERMINAL(vte), value);
447 	}
448 	else
449 	{
450 		if (compare_strings(win_data->background_image, NULL_DEVICE, TRUE))
451 		{
452 			vte_terminal_set_background_saturation( VTE_TERMINAL(vte), value);
453 			vte_terminal_set_background_image_file (VTE_TERMINAL(vte), win_data->background_image);
454 			vte_terminal_set_scroll_background(VTE_TERMINAL(vte), win_data->scroll_background);
455 		}
456 		else
457 			vte_terminal_set_background_saturation( VTE_TERMINAL(vte), 0);
458 	}
459 
460 	vte_terminal_set_background_tint_color (VTE_TERMINAL(page_data->vte), &(win_data->color[0]));
461 	return FALSE;
462 }
463 
464 #if defined(ENABLE_RGBA) || defined(UNIT_TEST)
set_window_opacity(GtkRange * range,GtkScrollType scroll,gdouble value,struct Window * win_data)465 gboolean set_window_opacity(GtkRange *range, GtkScrollType scroll, gdouble value, struct Window *win_data)
466 {
467 #ifdef DETAIL
468 	g_debug("! Launch set_window_opacity() with value = %f, win_data = %p", value, win_data);
469 #endif
470 #ifdef SAFEMODE
471 	if (win_data==NULL) return FALSE;
472 #endif
473 	// g_debug("Get win_data = %d when set window opacity!", win_data);
474 
475 	value = CLAMP(value, 0, 1);
476 	if (win_data->use_rgba == -1)
477 	{
478 #ifdef ENABLE_RGBA
479 		if (win_data->transparent_window)
480 			gtk_window_set_opacity (GTK_WINDOW(win_data->window), 1-value);
481 		else
482 			gtk_window_set_opacity (GTK_WINDOW(win_data->window), 1);
483 #endif
484 	}
485 	return FALSE;
486 }
487 #endif
488 
489 // set the window hints information
window_resizable(GtkWidget * window,GtkWidget * vte,gint set_hints_inc)490 void window_resizable(GtkWidget *window, GtkWidget *vte, gint set_hints_inc)
491 {
492 #ifdef SAFEMODE
493 	if ((window==NULL) || (vte==NULL)) return;
494 #endif
495 #ifdef DETAIL
496 	g_debug("! Launch window_resizable() with window = %p, vte = %p, set_hints_inc = %d",
497 		window, vte, set_hints_inc);
498 #endif
499 
500 	// DIRTY HACK: don't run window_resizable too much times before window is shown!
501 	if ((set_hints_inc != 1) && (gtk_widget_get_mapped(window) == FALSE)) return;
502 
503 	// vte=NULL when creating a new root window with drag & drop.
504 	// if (vte==NULL) return;
505 
506 	GdkGeometry hints = {0};
507 	// g_debug("Trying to get padding...");
508 	vte_terminal_get_padding (VTE_TERMINAL(vte), &(hints.base_width), &(hints.base_height));
509 	// g_debug("hints.base_width = %d, hints.base_height = %d", hints.base_width, hints.base_height);
510 
511 	switch (set_hints_inc)
512 	{
513 		case 1:
514 			hints.width_inc = vte_terminal_get_char_width(VTE_TERMINAL(vte));
515 			hints.height_inc = vte_terminal_get_char_height(VTE_TERMINAL(vte));
516 			break;
517 		case 2:
518 			hints.width_inc = 1;
519 			hints.height_inc = 1;
520 			break;
521 	}
522 
523 	// g_debug("hints.width_inc = %d, hints.height_inc = %d",
524 	//	hints.width_inc, hints.height_inc);
525 
526 	// // minsize = -1: the size of vte can NOT be changed.
527 	// if (minsize == -1)
528 	// {
529 	//	hints.min_width = minsize;
530 	//	hints.min_height = minsize;
531 	// }
532 	// else
533 	// {
534 		hints.min_width = hints.base_width + hints.width_inc;
535 		hints.min_height = hints.base_height + hints.height_inc;
536 	// }
537 
538 	// g_debug("Tring to set geometry on %p, and set_hints_inc = %d", vte, set_hints_inc);
539 	gtk_window_set_geometry_hints (GTK_WINDOW (window), GTK_WIDGET (vte), &hints,
540 					GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE);
541 
542 	//g_debug("current the size of vte %p whith hinting = %ld x %ld",
543 	//			vte,
544 	//			vte_terminal_get_column_count(VTE_TERMINAL(vte)),
545 	//			vte_terminal_get_row_count(VTE_TERMINAL(vte)));
546 }
547 
548 #if defined(vte_terminal_get_padding) || defined(UNIT_TEST)
fake_vte_terminal_get_padding(VteTerminal * vte,gint * width,gint * height)549 void fake_vte_terminal_get_padding(VteTerminal *vte, gint *width, gint *height)
550 {
551 #ifdef DETAIL
552 	g_debug("! Launch fake_vte_terminal_get_padding() with vte = %p", vte);
553 #endif
554 #ifdef SAFEMODE
555 	if (vte==NULL) return;
556 #endif
557 	GtkBorder *inner_border = NULL;
558 	gtk_widget_style_get(GTK_WIDGET(vte), "inner-border", &inner_border, NULL);
559 #  ifdef SAFEMODE
560 	if (inner_border)
561 	{
562 #  endif
563 #ifdef SAFEMODE
564 		if (width)
565 #endif
566 			*width = inner_border->left + inner_border->right;
567 #ifdef SAFEMODE
568 		if (height)
569 #endif
570 			*height = inner_border->top + inner_border->bottom;
571 #  ifdef SAFEMODE
572 	}
573 #  endif
574 	gtk_border_free (inner_border);
575 }
576 #endif
577 
apply_new_win_data_to_page(struct Window * win_data_orig,struct Window * win_data,struct Page * page_data)578 void apply_new_win_data_to_page (struct Window *win_data_orig,
579 				 struct Window *win_data,
580 				 struct Page *page_data)
581 {
582 #ifdef DETAIL
583 	g_debug("! Launch apply_new_win_data_to_page() with win_data_orig = %p, win_data = %p, page_data = %p",
584 		win_data_orig, win_data, page_data);
585 #endif
586 #ifdef SAFEMODE
587 	if ((win_data_orig==NULL) || (win_data==NULL) || (page_data==NULL) || (page_data->vte==NULL)) return;
588 #endif
589 	// if (win_data_orig->use_rgba != win_data->use_rgba)
590 	//	init_rgba(win_data);
591 #ifdef ENABLE_RGBA
592     	set_window_opacity (NULL, 0, win_data->window_opacity, win_data);
593 #endif
594 
595 	init_monitor_cmdline_datas(win_data, page_data);
596 
597 	if (win_data_orig->enable_hyperlink != win_data->enable_hyperlink)
598 		set_hyprelink(win_data, page_data);
599 
600 // ---- the color used in vte ---- //
601 	gboolean update_color = FALSE;
602 
603 	if (compare_color(&(win_data_orig->cursor_color), &(win_data->cursor_color)) ||
604 	    (win_data_orig->have_custom_color != win_data->have_custom_color) ||
605 	    (win_data_orig->use_custom_theme != win_data->use_custom_theme) ||
606 	    (win_data_orig->color_brightness != win_data->color_brightness))
607 	    	update_color = TRUE;
608 
609 	gint i;
610 	if (! update_color && (win_data->use_custom_theme))
611 	{
612 		for (i=0; i<COLOR; i++)
613 			if (compare_color(&(win_data_orig->color[i]), &(win_data->color[i])))
614 				update_color = TRUE;
615 	}
616 	if (update_color)
617 		set_vte_color(page_data->vte, use_default_vte_theme(win_data), win_data->cursor_color, win_data->color, FALSE);
618 
619 // ---- tabs on notebook ---- //
620 
621 	if (win_data_orig->tabs_bar_position != win_data->tabs_bar_position)
622 	{
623 		if (win_data->tabs_bar_position)
624 			gtk_notebook_set_tab_pos(GTK_NOTEBOOK(win_data->notebook), GTK_POS_BOTTOM);
625 		else
626 			gtk_notebook_set_tab_pos(GTK_NOTEBOOK(win_data->notebook), GTK_POS_TOP);
627 	}
628 
629 	// the fill_tabs_bar may not always work, so we should call set_fill_tabs_bar() every time.
630 	// if (win_data_orig->fill_tabs_bar != win_data->fill_tabs_bar)
631 		set_fill_tabs_bar(GTK_NOTEBOOK(win_data->notebook), win_data->fill_tabs_bar, page_data);
632 
633 	if (win_data_orig->page_width != win_data->page_width)
634 		set_page_width(win_data, page_data);
635 
636 	// g_debug("ORI: %d", win_data_orig->page_shows_current_cmdline ||
637 	//		   win_data_orig->page_shows_current_dir ||
638 	//		   win_data_orig->page_shows_window_title);
639 	// g_debug("NEW: %d", win_data->page_shows_current_cmdline ||
640 	//		   win_data->page_shows_current_dir ||
641 	//		   win_data->page_shows_window_title);
642 	if ((proc_exist) &&
643 	    ((page_data->page_update_method != PAGE_METHOD_NORMAL) ||
644 	    (win_data->page_shows_current_cmdline ||
645 	     win_data->page_shows_current_dir ||
646 	     win_data->page_shows_window_title)))
647 	{
648 		// FIXME: Is it necessary?
649 		if (page_data->page_update_method == PAGE_METHOD_WINDOW_TITLE) page_data->window_title_updated = 1;
650 		page_data->page_update_method = PAGE_METHOD_REFRESH;
651 	}
652 	// g_debug("page_data->page_update_method = %d", page_data->page_update_method);
653 
654 	if (win_data->page_shows_window_title != win_data_orig->page_shows_window_title)
655 		add_remove_window_title_changed_signal(page_data);
656 
657 	if (win_data->check_root_privileges != win_data_orig->check_root_privileges)
658 	{
659 		if (win_data->check_root_privileges)
660 			page_data->is_root = check_is_root(page_data->displayed_tpgid);
661 		else
662 			page_data->is_root = FALSE;
663 		// g_debug("apply_new_win_data_to_page(): page_data->is_root = %d", page_data->is_root);
664 	}
665 
666 	if (page_data->is_bold)
667 	{
668 		if (page_data->vte == win_data->current_vte)
669 		{
670 			if (win_data->bold_current_page_name == FALSE)
671 			{
672 				page_data->is_bold = page_data->should_be_bold;
673 				if (win_data->bold_action_page_name == FALSE)
674 					page_data->is_bold = FALSE;
675 			}
676 		}
677 		else
678 		{
679 			if (win_data->bold_action_page_name == FALSE)
680 				page_data->is_bold = FALSE;
681 		}
682 	}
683 	else
684 	{
685 		if (page_data->vte == win_data->current_vte)
686 			page_data->is_bold = win_data->bold_current_page_name;
687 		else if (win_data->bold_action_page_name == TRUE)
688 			page_data->is_bold = page_data->should_be_bold;
689 	}
690 
691 	if ((win_data_orig->window_title_shows_current_page != win_data->window_title_shows_current_page) ||
692 	    (win_data_orig->window_title_append_package_name != win_data->window_title_append_package_name))
693 	{
694 		check_and_update_window_title(win_data, page_data->custom_window_title,
695 					      page_data->page_no+1, page_data->custom_page_name,
696 					      page_data->page_name);
697 		// g_debug("FINAL: New window title = %s", gtk_window_get_title(GTK_WINDOW(win_data->window)));
698 	}
699 
700 	get_and_update_page_name(page_data, FALSE);
701 
702 	if ((win_data_orig->show_close_button_on_tab != win_data->show_close_button_on_tab) ||
703 	    (win_data_orig->show_close_button_on_all_tabs != win_data->show_close_button_on_all_tabs))
704 		show_close_button_on_tab(win_data, page_data);
705 
706 // ---- font ---- //
707 	if (win_data_orig->font_anti_alias != win_data->font_anti_alias)
708 		vte_terminal_set_font_from_string_full (VTE_TERMINAL(page_data->vte),
709 							page_data->font_name,
710 							win_data->font_anti_alias);
711 
712 // ---- other settings for init a vte ---- //
713 
714 	if (compare_strings(win_data_orig->word_chars, win_data->word_chars, TRUE))
715 		vte_terminal_set_word_chars(VTE_TERMINAL(page_data->vte), win_data->word_chars);
716 
717 	if (win_data_orig->show_scroll_bar != win_data->show_scroll_bar)
718 		// hide_scroll_bar(win_data, page_data);
719 		show_and_hide_scroll_bar(page_data, check_show_or_hide_scroll_bar(win_data));
720 
721 	if (win_data_orig->scroll_bar_position != win_data->scroll_bar_position)
722 	{
723 		g_object_ref(page_data->vte);
724 		gtk_container_remove (GTK_CONTAINER(page_data->hbox), page_data->vte);
725 		g_object_ref(page_data->scroll_bar);
726 		gtk_container_remove (GTK_CONTAINER(page_data->hbox), page_data->scroll_bar);
727 
728 		pack_vte_and_scroll_bar_to_hbox(win_data, page_data);
729 
730 		g_object_unref(page_data->vte);
731 		g_object_unref(page_data->scroll_bar);
732 	}
733 
734 	if (compare_color(&(win_data_orig->color[0]), &(win_data->color[0])) ||
735 	    (win_data_orig->transparent_background != win_data->transparent_background) ||
736 	    (win_data_orig->background_saturation != win_data->background_saturation) ||
737 	    (win_data_orig->scroll_background != win_data->scroll_background) ||
738 	    compare_strings (win_data_orig->background_image, win_data->background_image, TRUE))
739 		set_background_saturation (NULL, 0, win_data->background_saturation, page_data->vte);
740 
741 	if (win_data_orig->scrollback_lines != win_data->scrollback_lines)
742 		vte_terminal_set_scrollback_lines (VTE_TERMINAL(page_data->vte), win_data->scrollback_lines);
743 
744 	if (win_data_orig->cursor_blinks != win_data->cursor_blinks)
745 		set_cursor_blink(win_data, page_data);
746 
747 	if (win_data_orig->audible_bell != win_data->audible_bell)
748 		vte_terminal_set_audible_bell (VTE_TERMINAL(page_data->vte), win_data->audible_bell);
749 
750 	if (win_data_orig->visible_bell != win_data->visible_bell)
751 		vte_terminal_set_visible_bell (VTE_TERMINAL(page_data->vte), win_data->visible_bell);
752 
753 	if (win_data_orig->urgent_bell != win_data->urgent_bell)
754 		set_vte_urgent_bell(win_data, page_data);
755 
756 	if (win_data_orig->erase_binding != win_data->erase_binding)
757 		vte_terminal_set_backspace_binding (VTE_TERMINAL(page_data->vte), win_data->erase_binding);
758 #ifdef ENABLE_CURSOR_SHAPE
759 	if (win_data_orig->cursor_shape != win_data->cursor_shape)
760 		vte_terminal_set_cursor_shape(VTE_TERMINAL(page_data->vte), win_data->cursor_shape);
761 #endif
762 	if (compare_strings(win_data_orig->emulate_term, win_data->emulate_term, TRUE))
763 		vte_terminal_set_emulation (VTE_TERMINAL(page_data->vte), win_data->emulate_term);
764 }
765 
766 // Will return TRUE if a and b are NOT the same.
compare_color(GdkColor * a,GdkColor * b)767 gboolean compare_color(GdkColor *a, GdkColor *b)
768 {
769 #ifdef DETAIL
770 	g_debug("! Launch compare_color()!");
771 #endif
772 
773 #ifdef SAFEMODE
774 	if ((a==NULL) && (b==NULL)) return FALSE;
775 	if ((a==NULL) || (b==NULL)) return TRUE;
776 #endif
777 	// g_debug("compare_color(): Comparing %04X %04X %04X %04X and %04X %04X %04X %04X",
778 	//	a->pixel, a->red, a->green, a->blue, b->pixel, b->red, b->green, b->blue);
779 	if ((a->red != b->red) ||
780 	    (a->green != b->green ) ||
781 	    (a->blue != b->blue))
782 		return TRUE;
783 	else
784 		return FALSE;
785 }
786 
set_widget_thickness(GtkWidget * widget,gint thickness)787 void set_widget_thickness(GtkWidget *widget, gint thickness)
788 {
789 #ifdef DETAIL
790 	g_debug("! Launch set_widget_thickness() with widget = %p, thickness = %d!", widget, thickness);
791 #endif
792 
793 #ifdef SAFEMODE
794 	if (widget==NULL) return;
795 #endif
796 	GtkRcStyle *rc_style = gtk_rc_style_new();
797 #ifdef SAFEMODE
798 	if (rc_style)
799 	{
800 #endif
801 		rc_style->xthickness = rc_style->ythickness = thickness;
802 		gtk_widget_modify_style(widget, rc_style);
803 #ifdef SAFEMODE
804 	}
805 #endif
806 	g_object_unref(rc_style);
807 }
808