summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/config.c36
-rw-r--r--src/bin/config.h10
-rw-r--r--src/bin/main.c21
-rw-r--r--src/bin/media.c1
-rw-r--r--src/bin/options_background.c10
-rw-r--r--src/bin/options_behavior.c25
-rw-r--r--src/bin/options_colors.c4
-rw-r--r--src/bin/options_elm.c72
-rw-r--r--src/bin/options_font.c6
-rw-r--r--src/bin/options_helpers.c16
-rw-r--r--src/bin/options_keys.c4
-rw-r--r--src/bin/options_theme.c2
-rw-r--r--src/bin/options_video.c6
-rw-r--r--src/bin/termiolink.c55
-rw-r--r--src/bin/termiolink.h5
-rw-r--r--src/bin/termpty.c2
-rw-r--r--src/bin/termptyesc.c5
-rw-r--r--src/bin/termptyext.c126
-rw-r--r--src/bin/typop.c3
-rw-r--r--src/bin/utils.c62
-rw-r--r--src/bin/utils.h5
-rw-r--r--src/bin/win.c1010
-rw-r--r--src/bin/win.h1
23 files changed, 976 insertions, 511 deletions
diff --git a/src/bin/config.c b/src/bin/config.c
index b205b8f..52ff2d2 100644
--- a/src/bin/config.c
+++ b/src/bin/config.c
@@ -7,7 +7,8 @@
7#include "col.h" 7#include "col.h"
8#include "utils.h" 8#include "utils.h"
9 9
10#define CONF_VER 22 10#define CONF_VER 23
11#define CONFIG_KEY "config"
11 12
12#define LIM(v, min, max) {if (v >= max) v = max; else if (v <= min) v = min;} 13#define LIM(v, min, max) {if (v >= max) v = max; else if (v <= min) v = min;}
13 14
@@ -174,9 +175,11 @@ config_init(void)
174 (edd_base, Config, "keys", keys, edd_keys); 175 (edd_base, Config, "keys", keys, edd_keys);
175 EET_DATA_DESCRIPTOR_ADD_BASIC 176 EET_DATA_DESCRIPTOR_ADD_BASIC
176 (edd_base, Config, "gravatar", gravatar, EET_T_UCHAR); 177 (edd_base, Config, "gravatar", gravatar, EET_T_UCHAR);
177 EET_DATA_DESCRIPTOR_ADD_BASIC 178 EET_DATA_DESCRIPTOR_ADD_BASIC /* DEPRECATED, NO LONGER USED */
178 (edd_base, Config, "notabs", notabs, EET_T_UCHAR); 179 (edd_base, Config, "notabs", notabs, EET_T_UCHAR);
179 EET_DATA_DESCRIPTOR_ADD_BASIC 180 EET_DATA_DESCRIPTOR_ADD_BASIC
181 (edd_base, Config, "show_tabs", show_tabs, EET_T_UCHAR);
182 EET_DATA_DESCRIPTOR_ADD_BASIC
180 (edd_base, Config, "mv_always_show", mv_always_show, EET_T_UCHAR); 183 (edd_base, Config, "mv_always_show", mv_always_show, EET_T_UCHAR);
181 EET_DATA_DESCRIPTOR_ADD_BASIC 184 EET_DATA_DESCRIPTOR_ADD_BASIC
182 (edd_base, Config, "ty_escapes", ty_escapes, EET_T_UCHAR); 185 (edd_base, Config, "ty_escapes", ty_escapes, EET_T_UCHAR);
@@ -207,7 +210,7 @@ config_shutdown(void)
207} 210}
208 211
209void 212void
210config_save(Config *config, const char *key) 213config_save(Config *config)
211{ 214{
212 Eet_File *ef; 215 Eet_File *ef;
213 char buf[PATH_MAX], buf2[PATH_MAX]; 216 char buf[PATH_MAX], buf2[PATH_MAX];
@@ -221,7 +224,6 @@ config_save(Config *config, const char *key)
221 main_config_sync(config); 224 main_config_sync(config);
222 return; 225 return;
223 } 226 }
224 if (!key) key = config->config_key;
225 config->font.orig_size = config->font.size; 227 config->font.orig_size = config->font.size;
226 eina_stringshare_del(config->font.orig_name); 228 eina_stringshare_del(config->font.orig_name);
227 config->font.orig_name = NULL; 229 config->font.orig_name = NULL;
@@ -236,7 +238,7 @@ config_save(Config *config, const char *key)
236 ef = eet_open(buf, EET_FILE_MODE_WRITE); 238 ef = eet_open(buf, EET_FILE_MODE_WRITE);
237 if (ef) 239 if (ef)
238 { 240 {
239 ok = eet_data_write(ef, edd_base, key, config, 1); 241 ok = eet_data_write(ef, edd_base, CONFIG_KEY, config, 1);
240 eet_close(ef); 242 eet_close(ef);
241 if (ok) ecore_file_mv(buf, buf2); 243 if (ok) ecore_file_mv(buf, buf2);
242 } 244 }
@@ -292,7 +294,7 @@ config_sync(const Config *config_src, Config *config)
292 config->disable_focus_visuals = config_src->disable_focus_visuals; 294 config->disable_focus_visuals = config_src->disable_focus_visuals;
293 /* TODO: config->keys */ 295 /* TODO: config->keys */
294 config->gravatar = config_src->gravatar; 296 config->gravatar = config_src->gravatar;
295 config->notabs = config_src->notabs; 297 config->show_tabs = config_src->show_tabs;
296 config->mv_always_show = config_src->mv_always_show; 298 config->mv_always_show = config_src->mv_always_show;
297 config->ty_escapes = config_src->ty_escapes; 299 config->ty_escapes = config_src->ty_escapes;
298 config->changedir_to_current = config_src->changedir_to_current; 300 config->changedir_to_current = config_src->changedir_to_current;
@@ -554,7 +556,7 @@ config_new(void)
554 config->disable_focus_visuals = EINA_FALSE; 556 config->disable_focus_visuals = EINA_FALSE;
555 config->colors_use = EINA_FALSE; 557 config->colors_use = EINA_FALSE;
556 config->gravatar = EINA_TRUE; 558 config->gravatar = EINA_TRUE;
557 config->notabs = EINA_FALSE; 559 config->show_tabs = EINA_TRUE;
558 config->mv_always_show = EINA_FALSE; 560 config->mv_always_show = EINA_FALSE;
559 config->ty_escapes = EINA_TRUE; 561 config->ty_escapes = EINA_TRUE;
560 config->changedir_to_current = EINA_TRUE; 562 config->changedir_to_current = EINA_TRUE;
@@ -581,21 +583,19 @@ config_new(void)
581 583
582 584
583Config * 585Config *
584config_load(const char *key) 586config_load(void)
585{ 587{
586 Eet_File *ef; 588 Eet_File *ef;
587 char buf[PATH_MAX]; 589 char buf[PATH_MAX];
588 const char *cfgdir; 590 const char *cfgdir;
589 Config *config = NULL; 591 Config *config = NULL;
590 592
591 EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
592
593 cfgdir = _config_home_get(); 593 cfgdir = _config_home_get();
594 snprintf(buf, sizeof(buf), "%s/terminology/config/standard/base.cfg", cfgdir); 594 snprintf(buf, sizeof(buf), "%s/terminology/config/standard/base.cfg", cfgdir);
595 ef = eet_open(buf, EET_FILE_MODE_READ); 595 ef = eet_open(buf, EET_FILE_MODE_READ);
596 if (ef) 596 if (ef)
597 { 597 {
598 config = eet_data_read(ef, edd_base, key); 598 config = eet_data_read(ef, edd_base, CONFIG_KEY);
599 eet_close(ef); 599 eet_close(ef);
600 if (config) 600 if (config)
601 { 601 {
@@ -707,7 +707,11 @@ config_load(const char *key)
707 config->hide_cursor = 5.0; 707 config->hide_cursor = 5.0;
708 EINA_FALLTHROUGH; 708 EINA_FALLTHROUGH;
709 /*pass through*/ 709 /*pass through*/
710 case CONF_VER: /* 22 */ 710 case 22:
711 config->show_tabs = !config->notabs;
712 EINA_FALLTHROUGH;
713 /*pass through*/
714 case CONF_VER: /* 23 */
711 config->version = CONF_VER; 715 config->version = CONF_VER;
712 break; 716 break;
713 default: 717 default:
@@ -731,9 +735,6 @@ config_load(const char *key)
731 config->font_set = 1; 735 config->font_set = 1;
732 } 736 }
733 737
734 if (config)
735 config->config_key = eina_stringshare_add(key); /* not in eet */
736
737 return config; 738 return config;
738} 739}
739 740
@@ -804,10 +805,9 @@ config_fork(const Config *config)
804 CPY(mouse_over_focus); 805 CPY(mouse_over_focus);
805 CPY(disable_focus_visuals); 806 CPY(disable_focus_visuals);
806 CPY(temporary); 807 CPY(temporary);
807 SCPY(config_key);
808 CPY(font_set); 808 CPY(font_set);
809 CPY(gravatar); 809 CPY(gravatar);
810 CPY(notabs); 810 CPY(show_tabs);
811 CPY(mv_always_show); 811 CPY(mv_always_show);
812 CPY(ty_escapes); 812 CPY(ty_escapes);
813 CPY(changedir_to_current); 813 CPY(changedir_to_current);
@@ -851,8 +851,6 @@ config_del(Config *config)
851 eina_stringshare_del(config->helper.local.video); 851 eina_stringshare_del(config->helper.local.video);
852 eina_stringshare_del(config->helper.local.image); 852 eina_stringshare_del(config->helper.local.image);
853 853
854 eina_stringshare_del(config->config_key); /* not in eet */
855
856 EINA_LIST_FREE(config->keys, key) 854 EINA_LIST_FREE(config->keys, key)
857 { 855 {
858 eina_stringshare_del(key->keyname); 856 eina_stringshare_del(key->keyname);
diff --git a/src/bin/config.h b/src/bin/config.h
index e9e65c7..aa3027b 100644
--- a/src/bin/config.h
+++ b/src/bin/config.h
@@ -89,7 +89,8 @@ struct _Config
89 Eina_Bool disable_focus_visuals; 89 Eina_Bool disable_focus_visuals;
90 Eina_Bool colors_use; 90 Eina_Bool colors_use;
91 Eina_Bool gravatar; 91 Eina_Bool gravatar;
92 Eina_Bool notabs; 92 Eina_Bool notabs; /* DEPRECATED */
93 Eina_Bool show_tabs;
93 Eina_Bool mv_always_show; 94 Eina_Bool mv_always_show;
94 Eina_Bool ty_escapes; 95 Eina_Bool ty_escapes;
95 Eina_Bool changedir_to_current; 96 Eina_Bool changedir_to_current;
@@ -99,16 +100,15 @@ struct _Config
99 100
100 Eina_Bool temporary; /* not in EET */ 101 Eina_Bool temporary; /* not in EET */
101 Eina_Bool font_set; /* not in EET */ 102 Eina_Bool font_set; /* not in EET */
102 const char *config_key; /* not in EET, the key that config was loaded */
103}; 103};
104 104
105void config_init(void); 105void config_init(void);
106void config_shutdown(void); 106void config_shutdown(void);
107void config_sync(const Config *config_src, Config *config); 107void config_sync(const Config *config_src, Config *config);
108void config_save(Config *config, const char *key); 108void config_save(Config *config);
109Config *config_load(const char *key); 109Config *config_load(void);
110Config *config_fork(const Config *config); 110Config *config_fork(const Config *config);
111Config *config_new(); 111Config *config_new(void);
112void config_del(Config *config); 112void config_del(Config *config);
113void config_default_font_set(Config *config, Evas *evas); 113void config_default_font_set(Config *config, Evas *evas);
114void config_reset_keys(Config *config); 114void config_reset_keys(Config *config);
diff --git a/src/bin/main.c b/src/bin/main.c
index 9e77386..b50dbbe 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -94,10 +94,10 @@ main_ipc_new(Ipc_Instance *inst)
94 if (inst->xterm_256color) nargc += 1; 94 if (inst->xterm_256color) nargc += 1;
95 if (inst->active_links) nargc += 1; 95 if (inst->active_links) nargc += 1;
96 if (inst->cmd) nargc += 2; 96 if (inst->cmd) nargc += 2;
97 97
98 nargv = calloc(nargc + 1, sizeof(char *)); 98 nargv = calloc(nargc + 1, sizeof(char *));
99 if (!nargv) return; 99 if (!nargv) return;
100 100
101 i = 0; 101 i = 0;
102 nargv[i++] = pargv[0]; 102 nargv[i++] = pargv[0];
103 if (inst->cd) 103 if (inst->cd)
@@ -261,13 +261,13 @@ main_ipc_new(Ipc_Instance *inst)
261 { 261 {
262 char *fname = alloca(strlen(inst->font) + 1); 262 char *fname = alloca(strlen(inst->font) + 1);
263 char *p; 263 char *p;
264 264
265 strcpy(fname, inst->font); 265 strcpy(fname, inst->font);
266 p = strrchr(fname, '/'); 266 p = strrchr(fname, '/');
267 if (p) 267 if (p)
268 { 268 {
269 int sz; 269 int sz;
270 270
271 *p = 0; 271 *p = 0;
272 p++; 272 p++;
273 sz = atoi(p); 273 sz = atoi(p);
@@ -281,7 +281,7 @@ main_ipc_new(Ipc_Instance *inst)
281 char buf[4096], *file; 281 char buf[4096], *file;
282 Eina_List *files; 282 Eina_List *files;
283 int n = strlen(inst->font); 283 int n = strlen(inst->font);
284 284
285 snprintf(buf, sizeof(buf), "%s/fonts", elm_app_data_dir_get()); 285 snprintf(buf, sizeof(buf), "%s/fonts", elm_app_data_dir_get());
286 files = ecore_file_ls(buf); 286 files = ecore_file_ls(buf);
287 EINA_LIST_FREE(files, file) 287 EINA_LIST_FREE(files, file)
@@ -582,7 +582,7 @@ elm_main(int argc, char **argv)
582 582
583 config_init(); 583 config_init();
584 584
585 _main_config = config_load("config"); 585 _main_config = config_load();
586 if (key_bindings_load(_main_config) < 0) 586 if (key_bindings_load(_main_config) < 0)
587 { 587 {
588 CRITICAL(_("Could not initialize key bindings.")); 588 CRITICAL(_("Could not initialize key bindings."));
@@ -809,7 +809,7 @@ elm_main(int argc, char **argv)
809 pos_set = 1; 809 pos_set = 1;
810 } 810 }
811 } 811 }
812 812
813 if (!size_set) 813 if (!size_set)
814 { 814 {
815 if (config->custom_geometry) 815 if (config->custom_geometry)
@@ -839,9 +839,9 @@ remote:
839 { 839 {
840 Ipc_Instance inst; 840 Ipc_Instance inst;
841 char cwdbuf[4096]; 841 char cwdbuf[4096];
842 842
843 memset(&inst, 0, sizeof(Ipc_Instance)); 843 memset(&inst, 0, sizeof(Ipc_Instance));
844 844
845 inst.cmd = cmd; 845 inst.cmd = cmd;
846 if (cd) inst.cd = cd; 846 if (cd) inst.cd = cd;
847 else inst.cd = getcwd(cwdbuf, sizeof(cwdbuf)); 847 else inst.cd = getcwd(cwdbuf, sizeof(cwdbuf));
@@ -970,6 +970,9 @@ remote:
970 ecore_con_url_init(); 970 ecore_con_url_init();
971 971
972 controls_init(); 972 controls_init();
973
974 win_scale_wizard(win, term);
975
973 terminology_starting_up = EINA_FALSE; 976 terminology_starting_up = EINA_FALSE;
974 977
975 elm_run(); 978 elm_run();
diff --git a/src/bin/media.c b/src/bin/media.c
index bda41b4..b43eadc 100644
--- a/src/bin/media.c
+++ b/src/bin/media.c
@@ -9,6 +9,7 @@
9#include "media.h" 9#include "media.h"
10#include "config.h" 10#include "config.h"
11#include "utils.h" 11#include "utils.h"
12#include "termiolink.h"
12 13
13typedef struct _Media Media; 14typedef struct _Media Media;
14 15
diff --git a/src/bin/options_background.c b/src/bin/options_background.c
index a7d836e..530ade1 100644
--- a/src/bin/options_background.c
+++ b/src/bin/options_background.c
@@ -77,7 +77,7 @@ _cb_op_video_trans_chg(void *data,
77 config->translucent = elm_check_state_get(obj); 77 config->translucent = elm_check_state_get(obj);
78 elm_object_disabled_set(ctx->op_opacity, !config->translucent); 78 elm_object_disabled_set(ctx->op_opacity, !config->translucent);
79 main_trans_update(config); 79 main_trans_update(config);
80 config_save(config, NULL); 80 config_save(config);
81} 81}
82 82
83static void 83static void
@@ -92,7 +92,7 @@ _cb_op_video_opacity_chg(void *data,
92 if (!config->translucent) 92 if (!config->translucent)
93 return; 93 return;
94 main_trans_update(config); 94 main_trans_update(config);
95 config_save(config, NULL); 95 config_save(config);
96} 96}
97 97
98static void 98static void
@@ -227,12 +227,12 @@ _item_selected(void *data,
227 // no background 227 // no background
228 eina_stringshare_del(config->background); 228 eina_stringshare_del(config->background);
229 config->background = NULL; 229 config->background = NULL;
230 config_save(config, NULL); 230 config_save(config);
231 main_media_update(config); 231 main_media_update(config);
232 } 232 }
233 else if (eina_stringshare_replace(&(config->background), item->path)) 233 else if (eina_stringshare_replace(&(config->background), item->path))
234 { 234 {
235 config_save(config, NULL); 235 config_save(config);
236 main_media_update(config); 236 main_media_update(config);
237 } 237 }
238} 238}
@@ -505,7 +505,7 @@ _cb_grid_doubleclick(void *data,
505 if (newfile) 505 if (newfile)
506 { 506 {
507 eina_stringshare_replace(&(config->background), newfile); 507 eina_stringshare_replace(&(config->background), newfile);
508 config_save(config, NULL); 508 config_save(config);
509 main_media_update(config); 509 main_media_update(config);
510 eina_stringshare_del(newfile); 510 eina_stringshare_del(newfile);
511 _bubble_show(ctx, _("Picture imported")); 511 _bubble_show(ctx, _("Picture imported"));
diff --git a/src/bin/options_behavior.c b/src/bin/options_behavior.c
index 524ecc7..1fc4e4a 100644
--- a/src/bin/options_behavior.c
+++ b/src/bin/options_behavior.c
@@ -1,5 +1,6 @@
1#include "private.h" 1#include "private.h"
2 2
3
3#include <math.h> 4#include <math.h>
4#include <Elementary.h> 5#include <Elementary.h>
5#include <assert.h> 6#include <assert.h>
@@ -34,7 +35,7 @@ _cb_op_behavior_##_cfg_name(void *data, Evas_Object *obj, \
34 config->_cfg_name = elm_check_state_get(obj); \ 35 config->_cfg_name = elm_check_state_get(obj); \
35 termio_config_update(ctx->term); \ 36 termio_config_update(ctx->term); \
36 windows_update(); \ 37 windows_update(); \
37 config_save(config, NULL); \ 38 config_save(config); \
38} 39}
39 40
40CB(jump_on_change, 0); 41CB(jump_on_change, 0);
@@ -55,7 +56,7 @@ CB(login_shell, 0);
55CB(mouse_over_focus, 0); 56CB(mouse_over_focus, 0);
56CB(disable_focus_visuals, 1); 57CB(disable_focus_visuals, 1);
57CB(gravatar, 0); 58CB(gravatar, 0);
58CB(notabs, 1); 59CB(show_tabs, 0);
59CB(mv_always_show, 0); 60CB(mv_always_show, 0);
60CB(ty_escapes, 0); 61CB(ty_escapes, 0);
61CB(changedir_to_current, 0); 62CB(changedir_to_current, 0);
@@ -94,7 +95,7 @@ _cb_op_behavior_sback_chg(void *data,
94 95
95 config->scrollback = (double) sback_double_to_expo_int(elm_slider_value_get(obj)); 96 config->scrollback = (double) sback_double_to_expo_int(elm_slider_value_get(obj));
96 termio_config_update(ctx->term); 97 termio_config_update(ctx->term);
97 config_save(config, NULL); 98 config_save(config);
98} 99}
99 100
100static void 101static void
@@ -107,7 +108,7 @@ _cb_op_behavior_tab_zoom_slider_chg(void *data,
107 108
108 config->tab_zoom = (double)(int)round(elm_slider_value_get(obj) * 10.0) / 10.0; 109 config->tab_zoom = (double)(int)round(elm_slider_value_get(obj) * 10.0) / 10.0;
109 termio_config_update(ctx->term); 110 termio_config_update(ctx->term);
110 config_save(config, NULL); 111 config_save(config);
111} 112}
112 113
113static void 114static void
@@ -124,7 +125,7 @@ _cb_op_behavior_custom_geometry_current_set(void *data,
124 elm_spinner_value_set(ctx->op_w, config->cg_width); 125 elm_spinner_value_set(ctx->op_w, config->cg_width);
125 elm_spinner_value_set(ctx->op_h, config->cg_height); 126 elm_spinner_value_set(ctx->op_h, config->cg_height);
126 } 127 }
127 config_save(config, NULL); 128 config_save(config);
128} 129}
129 130
130static void 131static void
@@ -141,7 +142,7 @@ _cb_op_behavior_custom_geometry(void *data,
141 config->cg_width = (int) elm_spinner_value_get(ctx->op_w); 142 config->cg_width = (int) elm_spinner_value_get(ctx->op_w);
142 config->cg_height = (int) elm_spinner_value_get(ctx->op_h); 143 config->cg_height = (int) elm_spinner_value_get(ctx->op_h);
143 } 144 }
144 config_save(config, NULL); 145 config_save(config);
145 146
146 elm_object_disabled_set(ctx->op_w, !config->custom_geometry); 147 elm_object_disabled_set(ctx->op_w, !config->custom_geometry);
147 elm_object_disabled_set(ctx->op_h, !config->custom_geometry); 148 elm_object_disabled_set(ctx->op_h, !config->custom_geometry);
@@ -159,7 +160,7 @@ _cb_op_behavior_cg_width(void *data,
159 if (config->custom_geometry) 160 if (config->custom_geometry)
160 { 161 {
161 config->cg_width = (int) elm_spinner_value_get(obj); 162 config->cg_width = (int) elm_spinner_value_get(obj);
162 config_save(config, NULL); 163 config_save(config);
163 } 164 }
164} 165}
165 166
@@ -174,7 +175,7 @@ _cb_op_behavior_cg_height(void *data,
174 if (config->custom_geometry) 175 if (config->custom_geometry)
175 { 176 {
176 config->cg_height = (int) elm_spinner_value_get(obj); 177 config->cg_height = (int) elm_spinner_value_get(obj);
177 config_save(config, NULL); 178 config_save(config);
178 } 179 }
179} 180}
180 181
@@ -203,7 +204,7 @@ _cursors_changed_cb(void *data, Evas_Object *obj,
203 204
204 termio_config_update(ctx->term); 205 termio_config_update(ctx->term);
205 windows_update(); 206 windows_update();
206 config_save(config, NULL); 207 config_save(config);
207} 208}
208 209
209static void 210static void
@@ -224,7 +225,7 @@ _cb_op_hide_cursor_changed(void *data,
224 config->hide_cursor = CONFIG_CURSOR_IDLE_TIMEOUT_MAX + 1.0; 225 config->hide_cursor = CONFIG_CURSOR_IDLE_TIMEOUT_MAX + 1.0;
225 elm_object_disabled_set(ctx->sld_hide_cursor, EINA_TRUE); 226 elm_object_disabled_set(ctx->sld_hide_cursor, EINA_TRUE);
226 } 227 }
227 config_save(config, NULL); 228 config_save(config);
228} 229}
229 230
230static void 231static void
@@ -240,7 +241,7 @@ _cb_hide_cursor_slider_chg(void *data,
240 return; 241 return;
241 242
242 config->hide_cursor = value; 243 config->hide_cursor = value;
243 config_save(config, NULL); 244 config_save(config);
244} 245}
245 246
246 247
@@ -482,7 +483,7 @@ options_behavior(Evas_Object *opbox, Evas_Object *term)
482 CX(_("Focus split under the Mouse"), mouse_over_focus, 0); 483 CX(_("Focus split under the Mouse"), mouse_over_focus, 0);
483 CX(_("Focus-related visuals"), disable_focus_visuals, 1); 484 CX(_("Focus-related visuals"), disable_focus_visuals, 1);
484 CX(_("Gravatar integration"), gravatar, 0); 485 CX(_("Gravatar integration"), gravatar, 0);
485 CX(_("Show tabs"), notabs, 1); 486 CX(_("Show tabs"), show_tabs, 0);
486 CX(_("Always show miniview"), mv_always_show, 0); 487 CX(_("Always show miniview"), mv_always_show, 0);
487 CX(_("Enable special Terminology escape codes"), ty_escapes, 0); 488 CX(_("Enable special Terminology escape codes"), ty_escapes, 0);
488 CX(_("Open new terminals in current working directory"), changedir_to_current, 0); 489 CX(_("Open new terminals in current working directory"), changedir_to_current, 0);
diff --git a/src/bin/options_colors.c b/src/bin/options_colors.c
index 62b1640..4fbde83 100644
--- a/src/bin/options_colors.c
+++ b/src/bin/options_colors.c
@@ -101,7 +101,7 @@ _cb_op_color_chg(void *data,
101 config->colors[(j * 12) + i].b = b * a / 256; 101 config->colors[(j * 12) + i].b = b * a / 256;
102 config->colors[(j * 12) + i].a = a; 102 config->colors[(j * 12) + i].a = a;
103 termio_config_update(ctx->term); 103 termio_config_update(ctx->term);
104 config_save(config, NULL); 104 config_save(config);
105 return; 105 return;
106 } 106 }
107 } 107 }
@@ -184,7 +184,7 @@ _cb_op_reset(void *data,
184 elm_colorselector_palette_item_color_get(ctx->curitem, &r, &g, &b, &a); 184 elm_colorselector_palette_item_color_get(ctx->curitem, &r, &g, &b, &a);
185 elm_colorselector_color_set(ctx->colorsel, r, g, b, a); 185 elm_colorselector_color_set(ctx->colorsel, r, g, b, a);
186 termio_config_update(term); 186 termio_config_update(term);
187 config_save(config, NULL); 187 config_save(config);
188} 188}
189 189
190/* make color palettes wrap back. :) works with elm git. */ 190/* make color palettes wrap back. :) works with elm git. */
diff --git a/src/bin/options_elm.c b/src/bin/options_elm.c
index f48b6f3..fa9689c 100644
--- a/src/bin/options_elm.c
+++ b/src/bin/options_elm.c
@@ -15,10 +15,37 @@ launch_elm_config(void *_data EINA_UNUSED,
15 ecore_exe_free(exe); 15 ecore_exe_free(exe);
16} 16}
17 17
18static void
19_scale_round(void *data EINA_UNUSED,
20 Evas_Object *obj,
21 void *event_info EINA_UNUSED)
22{
23 double val = elm_slider_value_get(obj);
24 double v;
25
26 v = ((double)((int)(val * 10.0))) / 10.0;
27 if (v != val) elm_slider_value_set(obj, v);
28}
29
30static void
31_scale_change(void *data EINA_UNUSED,
32 Evas_Object *obj,
33 void *event_info EINA_UNUSED)
34{
35 double scale = elm_config_scale_get();
36 double val = elm_slider_value_get(obj);
37
38 if (scale == val)
39 return;
40 elm_config_scale_set(val);
41 elm_config_all_flush();
42}
43
18void 44void
19options_elm(Evas_Object *opbox, Evas_Object *_term EINA_UNUSED) 45options_elm(Evas_Object *opbox, Evas_Object *_term EINA_UNUSED)
20{ 46{
21 Evas_Object *o, *fr, *bx, *bt, *en; 47 Evas_Object *o, *fr, *bx, *bt, *en, *lbl, *sl, *sp;
48 const char *txt;
22 49
23 fr = o = elm_frame_add(opbox); 50 fr = o = elm_frame_add(opbox);
24 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 51 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@@ -48,4 +75,47 @@ options_elm(Evas_Object *opbox, Evas_Object *_term EINA_UNUSED)
48 elm_layout_text_set(bt, NULL, _("Launch elementary_config")); 75 elm_layout_text_set(bt, NULL, _("Launch elementary_config"));
49 elm_box_pack_end(bx, bt); 76 elm_box_pack_end(bx, bt);
50 evas_object_show(bt); 77 evas_object_show(bt);
78
79 sp = elm_separator_add(opbox);
80 evas_object_size_hint_weight_set(sp, EVAS_HINT_EXPAND, 0.0);
81 evas_object_size_hint_align_set(sp, EVAS_HINT_FILL, 0.5);
82 elm_separator_horizontal_set(sp, EINA_TRUE);
83 elm_box_pack_end(bx, sp);
84 evas_object_show(sp);
85
86 lbl = elm_label_add(opbox);
87 evas_object_size_hint_weight_set(lbl, EVAS_HINT_EXPAND, 0.0);
88 evas_object_size_hint_align_set(lbl, EVAS_HINT_FILL, 0.5);
89 txt = eina_stringshare_printf("<hilight>%s</>",_("Scale"));
90 elm_object_text_set(lbl, txt);
91 eina_stringshare_del(txt);
92 elm_box_pack_end(bx, lbl);
93 evas_object_show(lbl);
94
95 sl = elm_slider_add(opbox);
96 evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
97 evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
98 elm_slider_span_size_set(sl, 120);
99 elm_slider_unit_format_set(sl, "%1.2f");
100 elm_slider_indicator_format_set(sl, "%1.2f");
101 elm_slider_min_max_set(sl, 0.25, 5.0);
102 elm_slider_value_set(sl, elm_config_scale_get());
103 elm_box_pack_end(bx, sl);
104 evas_object_show(sl);
105 evas_object_smart_callback_add(sl, "changed", _scale_round, NULL);
106 evas_object_smart_callback_add(sl, "delay,changed", _scale_change, NULL);
107
108 lbl = elm_label_add(opbox);
109 evas_object_size_hint_weight_set(lbl, EVAS_HINT_EXPAND, 0.0);
110 evas_object_size_hint_align_set(lbl, 0.0, 0.0);
111 elm_object_text_set(lbl, _("Select prefered size so that this text is readable."));
112 elm_box_pack_end(bx, lbl);
113 evas_object_show(lbl);
114
115 lbl = elm_label_add(opbox);
116 evas_object_size_hint_weight_set(lbl, EVAS_HINT_EXPAND, 0.0);
117 evas_object_size_hint_align_set(lbl, 0.0, 0.0);
118 elm_object_text_set(lbl, _("The scale configuration can also be changed through <hilight>elementary</hilight>'s configuration panel."));
119 elm_box_pack_end(bx, lbl);
120 evas_object_show(lbl);
51} 121}
diff --git a/src/bin/options_font.c b/src/bin/options_font.c
index 407694a..d90e7e9 100644
--- a/src/bin/options_font.c
+++ b/src/bin/options_font.c
@@ -157,7 +157,7 @@ _cb_op_font_sel(void *data,
157 elm_object_disabled_set(ctx->op_fsml, f->bitmap); 157 elm_object_disabled_set(ctx->op_fsml, f->bitmap);
158 elm_object_disabled_set(ctx->op_fontslider, f->bitmap); 158 elm_object_disabled_set(ctx->op_fontslider, f->bitmap);
159 elm_object_disabled_set(ctx->op_fbig, f->bitmap); 159 elm_object_disabled_set(ctx->op_fbig, f->bitmap);
160 config_save(config, NULL); 160 config_save(config);
161 win_font_update(term); 161 win_font_update(term);
162} 162}
163 163
@@ -176,7 +176,7 @@ _cb_op_fontsize_sel(void *data,
176 config->font.size = size; 176 config->font.size = size;
177 _update_sizing(ctx); 177 _update_sizing(ctx);
178 elm_genlist_realized_items_update(ctx->op_fontlist); 178 elm_genlist_realized_items_update(ctx->op_fontlist);
179 config_save(config, NULL); 179 config_save(config);
180 win_font_update(term); 180 win_font_update(term);
181} 181}
182 182
@@ -398,7 +398,7 @@ _cb_font_bolditalic(void *data,
398 398
399 config->font.bolditalic = elm_check_state_get(obj); 399 config->font.bolditalic = elm_check_state_get(obj);
400 termio_config_update(ctx->term); 400 termio_config_update(ctx->term);
401 config_save(config, NULL); 401 config_save(config);
402} 402}
403 403
404void 404void
diff --git a/src/bin/options_helpers.c b/src/bin/options_helpers.c
index 00c29a7..c33e368 100644
--- a/src/bin/options_helpers.c
+++ b/src/bin/options_helpers.c
@@ -15,7 +15,7 @@ _cb_op_helper_inline_chg(void *data,
15 Evas_Object *term = data; 15 Evas_Object *term = data;
16 Config *config = termio_config_get(term); 16 Config *config = termio_config_get(term);
17 config->helper.inline_please = elm_check_state_get(obj); 17 config->helper.inline_please = elm_check_state_get(obj);
18 config_save(config, NULL); 18 config_save(config);
19} 19}
20 20
21static void 21static void
@@ -38,7 +38,7 @@ _cb_op_helper_email_chg(void *data,
38 config->helper.email = eina_stringshare_add(txt); 38 config->helper.email = eina_stringshare_add(txt);
39 free(txt); 39 free(txt);
40 } 40 }
41 config_save(config, NULL); 41 config_save(config);
42} 42}
43 43
44static void 44static void
@@ -61,7 +61,7 @@ _cb_op_helper_url_image_chg(void *data,
61 config->helper.url.image = eina_stringshare_add(txt); 61 config->helper.url.image = eina_stringshare_add(txt);
62 free(txt); 62 free(txt);
63 } 63 }
64 config_save(config, NULL); 64 config_save(config);
65} 65}
66 66
67static void 67static void
@@ -84,7 +84,7 @@ _cb_op_helper_url_video_chg(void *data,
84 config->helper.url.video = eina_stringshare_add(txt); 84 config->helper.url.video = eina_stringshare_add(txt);
85 free(txt); 85 free(txt);
86 } 86 }
87 config_save(config, NULL); 87 config_save(config);
88} 88}
89 89
90static void 90static void
@@ -107,7 +107,7 @@ _cb_op_helper_url_general_chg(void *data,
107 config->helper.url.general = eina_stringshare_add(txt); 107 config->helper.url.general = eina_stringshare_add(txt);
108 free(txt); 108 free(txt);
109 } 109 }
110 config_save(config, NULL); 110 config_save(config);
111} 111}
112 112
113static void 113static void
@@ -130,7 +130,7 @@ _cb_op_helper_local_image_chg(void *data,
130 config->helper.local.image = eina_stringshare_add(txt); 130 config->helper.local.image = eina_stringshare_add(txt);
131 free(txt); 131 free(txt);
132 } 132 }
133 config_save(config, NULL); 133 config_save(config);
134} 134}
135 135
136static void 136static void
@@ -153,7 +153,7 @@ _cb_op_helper_local_video_chg(void *data,
153 config->helper.local.video = eina_stringshare_add(txt); 153 config->helper.local.video = eina_stringshare_add(txt);
154 free(txt); 154 free(txt);
155 } 155 }
156 config_save(config, NULL); 156 config_save(config);
157} 157}
158 158
159static void 159static void
@@ -176,7 +176,7 @@ _cb_op_helper_local_general_chg(void *data,
176 config->helper.local.general = eina_stringshare_add(txt); 176 config->helper.local.general = eina_stringshare_add(txt);
177 free(txt); 177 free(txt);
178 } 178 }
179 config_save(config, NULL); 179 config_save(config);
180} 180}
181 181
182void 182void
diff --git a/src/bin/options_keys.c b/src/bin/options_keys.c
index 3d78477..47f088f 100644
--- a/src/bin/options_keys.c
+++ b/src/bin/options_keys.c
@@ -51,7 +51,7 @@ _shortcut_delete(void *data,
51 eina_stringshare_del(cfg_key->cb); 51 eina_stringshare_del(cfg_key->cb);
52 free(cfg_key); 52 free(cfg_key);
53 53
54 config_save(ctx->config, NULL); 54 config_save(ctx->config);
55} 55}
56 56
57static Evas_Object * 57static Evas_Object *
@@ -152,7 +152,7 @@ _cb_key_up(void *data,
152 evas_object_size_hint_min_set(bx, min_w, min_h); 152 evas_object_size_hint_min_set(bx, min_w, min_h);
153 elm_box_pack_before(bx, bt, last); 153 elm_box_pack_before(bx, bt, last);
154 154
155 config_save(ctx->config, NULL); 155 config_save(ctx->config);
156 } 156 }
157 else 157 else
158 { 158 {
diff --git a/src/bin/options_theme.c b/src/bin/options_theme.c
index fb0af9e..38fb019 100644
--- a/src/bin/options_theme.c
+++ b/src/bin/options_theme.c
@@ -79,7 +79,7 @@ _cb_op_theme_sel(void *data,
79 return; 79 return;
80 80
81 eina_stringshare_replace(&(config->theme), t->name); 81 eina_stringshare_replace(&(config->theme), t->name);
82 config_save(config, NULL); 82 config_save(config);
83 change_theme(termio_win_get(t->ctx->term), config); 83 change_theme(termio_win_get(t->ctx->term), config);
84} 84}
85 85
diff --git a/src/bin/options_video.c b/src/bin/options_video.c
index f3f83d3..c243a2c 100644
--- a/src/bin/options_video.c
+++ b/src/bin/options_video.c
@@ -17,7 +17,7 @@ _cb_op_video_mute_chg(void *data,
17 Config *config = termio_config_get(term); 17 Config *config = termio_config_get(term);
18 config->mute = elm_check_state_get(obj); 18 config->mute = elm_check_state_get(obj);
19 main_media_mute_update(config); 19 main_media_mute_update(config);
20 config_save(config, NULL); 20 config_save(config);
21} 21}
22 22
23static void 23static void
@@ -29,7 +29,7 @@ _cb_op_video_visualize_chg(void *data,
29 Config *config = termio_config_get(term); 29 Config *config = termio_config_get(term);
30 config->visualize = elm_check_state_get(obj); 30 config->visualize = elm_check_state_get(obj);
31 main_media_visualize_update(config); 31 main_media_visualize_update(config);
32 config_save(config, NULL); 32 config_save(config);
33} 33}
34 34
35static void 35static void
@@ -43,7 +43,7 @@ _cb_op_video_vidmod_chg(void *data,
43 if (v == config->vidmod) return; 43 if (v == config->vidmod) return;
44 config->vidmod = v; 44 config->vidmod = v;
45 main_media_update(config); 45 main_media_update(config);
46 config_save(config, NULL); 46 config_save(config);
47} 47}
48 48
49void 49void
diff --git a/src/bin/termiolink.c b/src/bin/termiolink.c
index 9b28648..d5a3fd5 100644
--- a/src/bin/termiolink.c
+++ b/src/bin/termiolink.c
@@ -42,8 +42,55 @@ _local_path_get(const Evas_Object *obj, const char *relpath)
42 return _cwd_path_get(obj, relpath); 42 return _cwd_path_get(obj, relpath);
43} 43}
44 44
45static Eina_Bool 45Eina_Bool
46_is_file(const char *str) 46link_is_protocol(const char *str)
47{
48 const char *p = str;
49 int c = *p;
50
51 if (!isalpha(c))
52 return EINA_FALSE;
53
54 /* Try to follow RFC3986 a bit
55 * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
56 * hier-part = "//" authority path-abempty
57 * [...] other stuff not taken into account
58 * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
59 */
60
61 do
62 {
63 p++;
64 c = *p;
65 }
66 while (isalpha(c) || (c == '.') || (c == '-') || (c == '+'));
67
68 return (p[0] == ':') && (p[1] == '/') && (p[2] == '/');
69}
70
71Eina_Bool
72link_is_url(const char *str)
73{
74 if (link_is_protocol(str) ||
75 casestartswith(str, "www.") ||
76 casestartswith(str, "ftp."))
77 return EINA_TRUE;
78 return EINA_FALSE;
79}
80
81Eina_Bool
82link_is_email(const char *str)
83{
84 const char *at = strchr(str, '@');
85 if (at && strchr(at + 1, '.'))
86 return EINA_TRUE;
87 if (casestartswith(str, "mailto:"))
88 return EINA_TRUE;
89 return EINA_FALSE;
90}
91
92Eina_Bool
93link_is_file(const char *str)
47{ 94{
48 switch (str[0]) 95 switch (str[0])
49 { 96 {
@@ -262,6 +309,8 @@ termio_link_find(const Evas_Object *obj, int cx, int cy,
262 309
263 res = _txt_at(ty, &x1, &y1, txt, &txtlen); 310 res = _txt_at(ty, &x1, &y1, txt, &txtlen);
264 if ((res != 0) || (txtlen == 0)) goto end; 311 if ((res != 0) || (txtlen == 0)) goto end;
312 if (isspace(txt[0]))
313 goto end;
265 res = ty_sb_add(&sb, txt, txtlen); 314 res = ty_sb_add(&sb, txt, txtlen);
266 if (res < 0) goto end; 315 if (res < 0) goto end;
267 316
@@ -402,7 +451,7 @@ termio_link_find(const Evas_Object *obj, int cx, int cy,
402out: 451out:
403 if (sb.len) 452 if (sb.len)
404 { 453 {
405 Eina_Bool is_file = _is_file(sb.buf); 454 Eina_Bool is_file = link_is_file(sb.buf);
406 455
407 if (is_file || 456 if (is_file ||
408 link_is_email(sb.buf) || 457 link_is_email(sb.buf) ||
diff --git a/src/bin/termiolink.h b/src/bin/termiolink.h
index bb97d90..7228119 100644
--- a/src/bin/termiolink.h
+++ b/src/bin/termiolink.h
@@ -2,5 +2,10 @@
2#define _TERMIO_LINK_H__ 1 2#define _TERMIO_LINK_H__ 1
3 3
4char *termio_link_find(const Evas_Object *obj, int cx, int cy, int *x1r, int *y1r, int *x2r, int *y2r); 4char *termio_link_find(const Evas_Object *obj, int cx, int cy, int *x1r, int *y1r, int *x2r, int *y2r);
5Eina_Bool link_is_protocol(const char *str);
6Eina_Bool link_is_file(const char *str);
7Eina_Bool link_is_url(const char *str);
8Eina_Bool link_is_email(const char *str);
9
5 10
6#endif 11#endif
diff --git a/src/bin/termpty.c b/src/bin/termpty.c
index 004bd67..879135f 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -234,7 +234,7 @@ _fd_read_do(Termpty *ty, Ecore_Fd_Handler *fd_handler, Eina_Bool false_on_empty)
234 234
235 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR)) 235 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
236 { 236 {
237 ERR("error while reading from tty slave fd"); 237 DBG("error while reading from tty slave fd");
238 ty->hand_fd = NULL; 238 ty->hand_fd = NULL;
239 return ECORE_CALLBACK_CANCEL; 239 return ECORE_CALLBACK_CANCEL;
240 } 240 }
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index 2e05684..a92b4db 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -1382,7 +1382,10 @@ _handle_esc_csi_dsr(Termpty *ty, Eina_Unicode *b)
1382 { 1382 {
1383 /* DSR-DECCKSR (Memory Checksum) */ 1383 /* DSR-DECCKSR (Memory Checksum) */
1384 int pid = _csi_arg_get(ty, &b); 1384 int pid = _csi_arg_get(ty, &b);
1385 len = snprintf(bf, sizeof(bf), "\033P%u!~0000\033\\", pid); 1385 if (pid == -CSI_ARG_NO_VALUE)
1386 pid = 65535;
1387 len = snprintf(bf, sizeof(bf), "\033P%u!~0000\033\\",
1388 ((unsigned int)pid) % 65536);
1386 termpty_write(ty, bf, len); 1389 termpty_write(ty, bf, len);
1387 } 1390 }
1388 else 1391 else
diff --git a/src/bin/termptyext.c b/src/bin/termptyext.c
index 96b3f5e..7cc41fc 100644
--- a/src/bin/termptyext.c
+++ b/src/bin/termptyext.c
@@ -1,6 +1,7 @@
1#include "private.h" 1#include "private.h"
2#include <Elementary.h> 2#include <Elementary.h>
3#include "termio.h" 3#include "termio.h"
4#include "termiolink.h"
4#include "termpty.h" 5#include "termpty.h"
5#include "termptyops.h" 6#include "termptyops.h"
6#include "termiointernals.h" 7#include "termiointernals.h"
@@ -28,28 +29,6 @@
28// EINA_TRUE), handled here first, then in termio (EINA_FALSE return) or not 29// EINA_TRUE), handled here first, then in termio (EINA_FALSE return) or not
29// handled here at all and just passed to termio to figure it out (return 30// handled here at all and just passed to termio to figure it out (return
30// EINA_FALSE). 31// EINA_FALSE).
31//
32// command strings like like this:
33// axBLAHBLAH
34// where 'a' is the major opcode char.
35// and 'x' is the minor opcode char.
36// and 'BLAHBLAH' is an optional data payload string
37
38static Eina_Bool
39_handle_op_a(Termpty *_ty EINA_UNUSED,
40 const Eina_Unicode *buf EINA_UNUSED,
41 size_t blen EINA_UNUSED)
42{
43 switch (buf[0])
44 {
45 case 'x': // command ax*
46 break;
47 // room here for more minor opcode chars like 'b', 'c' etc.
48 default:
49 break;
50 }
51 return EINA_FALSE;
52}
53 32
54#if defined(ENABLE_TESTS) || defined(ENABLE_TEST_UI) 33#if defined(ENABLE_TESTS) || defined(ENABLE_TEST_UI)
55 34
@@ -241,6 +220,88 @@ _handle_mouse_wheel(Termpty *ty,
241 termio_internal_mouse_wheel(sd, &ev, modifiers); 220 termio_internal_mouse_wheel(sd, &ev, modifiers);
242} 221}
243 222
223/*
224 * Format is:
225 * - ln : no link found under cursor
226 * - lT;X1;Y1;X2;Y2;LINK
227 * where T is
228 * e: link is an email
229 * u: link is an url
230 * p: link is a file path
231 */
232static void
233_handle_link(Termpty *ty, const Eina_Unicode *buf)
234{
235 const Eina_Unicode type = buf[0];
236 Termio *sd = termio_get_from_obj(ty->obj);
237 char *link, *c;
238 int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
239 int value;
240
241 /* highlight where the mouse is */
242 {
243 Termcell *cells = NULL;
244 ssize_t w;
245
246 cells = termpty_cellrow_get(ty, sd->mouse.cy, &w);
247 termpty_reset_att(&cells[sd->mouse.cx].att);
248 cells[sd->mouse.cx].att.bold = 1;
249 cells[sd->mouse.cx].att.fg = COL_WHITE;
250 cells[sd->mouse.cx].att.bg = COL_RED;
251 }
252
253 link = termio_link_find(ty->obj, sd->mouse.cx, sd->mouse.cy,
254 &x1, &y1, &x2, &y2);
255
256 ERR("x1:%d y1:%d x2:%d y2:%d link:'%s'", x1, y1, x2, y2, link);
257 if (type == 'n')
258 {
259 assert (link == NULL);
260 return;
261 }
262 /* skip type */
263 buf++;
264 /* Get numeric values */
265 buf += _tytest_arg_get(buf, &value);
266 assert(x1 == value);
267 buf += _tytest_arg_get(buf, &value);
268 assert(y1 == value);
269 buf += _tytest_arg_get(buf, &value);
270 assert(x2 == value);
271 buf += _tytest_arg_get(buf, &value);
272 assert(y2 == value);
273 /* skip ; */
274 buf++;
275 /* Compare strings */
276 c = link;
277 while (*buf)
278 {
279 int idx = 0;
280 Eina_Unicode u = eina_unicode_utf8_next_get(c, &idx);
281
282 ERR("%c vs %c", *buf, u);
283 assert(*buf == u && "unexpected character in selection");
284 c += idx;
285 buf++;
286 }
287
288 switch (type)
289 {
290 case 'u':
291 assert(link_is_url(link));
292 break;
293 case 'p':
294 assert(link_is_file(link));
295 break;
296 case 'e':
297 assert(link_is_email(link));
298 break;
299 default:
300 abort();
301 }
302 free(link);
303}
304
244static void 305static void
245_handle_selection_is(Termpty *ty, 306_handle_selection_is(Termpty *ty,
246 const Eina_Unicode *buf) 307 const Eina_Unicode *buf)
@@ -317,6 +378,7 @@ _handle_corner(Termpty *ty, const Eina_Unicode *buf)
317 * - 'd': mouse down: 378 * - 'd': mouse down:
318 * - 'u': mouse up; 379 * - 'u': mouse up;
319 * - 'm': mouse move; 380 * - 'm': mouse move;
381 * - 'l': assert mouse is over a link
320 * - 'r': force rendering and possibly remove selection; 382 * - 'r': force rendering and possibly remove selection;
321 * - 'n': assert there is no selection 383 * - 'n': assert there is no selection
322 * - 's': assert selection is what follows till '\0' 384 * - 's': assert selection is what follows till '\0'
@@ -333,6 +395,9 @@ tytest_handle_escape_codes(Termpty *ty,
333 case 'd': 395 case 'd':
334 _handle_mouse_down(ty, buf + 1); 396 _handle_mouse_down(ty, buf + 1);
335 break; 397 break;
398 case 'l':
399 _handle_link(ty, buf + 1);
400 break;
336 case 'm': 401 case 'm':
337 _handle_mouse_move(ty, buf + 1); 402 _handle_mouse_move(ty, buf + 1);
338 break; 403 break;
@@ -352,23 +417,25 @@ tytest_handle_escape_codes(Termpty *ty,
352 _handle_mouse_wheel(ty, buf + 1); 417 _handle_mouse_wheel(ty, buf + 1);
353 break; 418 break;
354 default: 419 default:
420 abort();
355 break; 421 break;
356 } 422 }
357} 423}
358#endif 424#endif
359 425
426#if defined(ENABLE_TESTS) || defined(ENABLE_TEST_UI)
427#define ARG_USED_FOR_TESTS
428#else
429#define ARG_USED_FOR_TESTS EINA_UNUSED
430#endif
360 431
361Eina_Bool 432Eina_Bool
362termpty_ext_handle(Termpty *ty, 433termpty_ext_handle(Termpty *ty ARG_USED_FOR_TESTS,
363 const Eina_Unicode *buf, 434 const Eina_Unicode *buf ARG_USED_FOR_TESTS,
364 size_t blen) 435 size_t blen EINA_UNUSED)
365{ 436{
366 switch (buf[0]) // major opcode 437 switch (buf[0]) // major opcode
367 { 438 {
368 case 'a': // command a*
369 return _handle_op_a(ty, buf + 1, blen - 1);
370 break;
371 // room here for more major opcode chars like 'b', 'c' etc.
372#if defined(ENABLE_TESTS) || defined(ENABLE_TEST_UI) 439#if defined(ENABLE_TESTS) || defined(ENABLE_TEST_UI)
373 case 't': 440 case 't':
374 tytest_handle_escape_codes(ty, buf + 1); 441 tytest_handle_escape_codes(ty, buf + 1);
@@ -380,3 +447,4 @@ termpty_ext_handle(Termpty *ty,
380 } 447 }
381 return EINA_FALSE; 448 return EINA_FALSE;
382} 449}
450#undef ARG_USED_FOR_TESTS
diff --git a/src/bin/typop.c b/src/bin/typop.c
index 13fe262..8a9e159 100644
--- a/src/bin/typop.c
+++ b/src/bin/typop.c
@@ -37,7 +37,8 @@ main(int argc, char **argv)
37 37
38 path = argv[i]; 38 path = argv[i];
39 if (realpath(path, buf)) path = buf; 39 if (realpath(path, buf)) path = buf;
40 snprintf(tbuf, sizeof(tbuf), "%c}pn%s", 0x1b, path); 40 snprintf(tbuf, sizeof(tbuf), "%c}p%c%s", 0x1b,
41 (i == 1) ? 'n': 'q', path);
41 if (write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1)) perror("write"); 42 if (write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1)) perror("write");
42 } 43 }
43 return 0; 44 return 0;
diff --git a/src/bin/utils.c b/src/bin/utils.c
index ecd2da3..3c5c2d6 100644
--- a/src/bin/utils.c
+++ b/src/bin/utils.c
@@ -145,48 +145,38 @@ homedir_get(char *buf, size_t size)
145} 145}
146 146
147Eina_Bool 147Eina_Bool
148link_is_protocol(const char *str) 148utils_need_scale_wizard(void)
149{ 149{
150 const char *p = str; 150 static char path[PATH_MAX] = "";
151 int c = *p; 151 struct stat st;
152 int res;
153 char *config_xdg = getenv("ELM_CONFIG_DIR_XDG");
152 154
153 if (!isalpha(c))
154 return EINA_FALSE;
155 155
156 /* Try to follow RFC3986 a bit 156 snprintf(path, sizeof(path) -1, "%s/terminology/config/",
157 * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 157 efreet_config_home_get());
158 * hier-part = "//" authority path-abempty 158 res = stat(path, &st);
159 * [...] other stuff not taken into account 159 if (res == 0)
160 * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 160 return EINA_FALSE;
161 */
162 161
163 do 162 if (config_xdg)
164 { 163 {
165 p++; 164 snprintf(path, sizeof(path) - 1,
166 c = *p; 165 "%s/elementary", config_xdg);
167 } 166 }
168 while (isalpha(c) || (c == '.') || (c == '-') || (c == '+')); 167 else
169 168 {
170 return (p[0] == ':') && (p[1] == '/') && (p[2] == '/'); 169 const char *suffix = "/.elementary";
171} 170 char home[PATH_MAX - strlen(suffix)];
172 171
173Eina_Bool 172 if (!homedir_get(home, sizeof(home)))
174link_is_url(const char *str) 173 return EINA_TRUE;
175{ 174 snprintf(path, sizeof(path) - 1,
176 if (link_is_protocol(str) || 175 "%s%s", home, suffix);
177 casestartswith(str, "www.") || 176 }
178 casestartswith(str, "ftp.")) 177 res = stat(path, &st);
179 return EINA_TRUE; 178 if (res == 0)
180 return EINA_FALSE; 179 return EINA_FALSE;
181}
182 180
183Eina_Bool 181 return EINA_TRUE;
184link_is_email(const char *str)
185{
186 const char *at = strchr(str, '@');
187 if (at && strchr(at + 1, '.'))
188 return EINA_TRUE;
189 if (casestartswith(str, "mailto:"))
190 return EINA_TRUE;
191 return EINA_FALSE;
192} 182}
diff --git a/src/bin/utils.h b/src/bin/utils.h
index 73476de..ca5b6e7 100644
--- a/src/bin/utils.h
+++ b/src/bin/utils.h
@@ -12,10 +12,7 @@ void theme_auto_reload_enable(Evas_Object *edje);
12const char *theme_path_get(const char *name); 12const char *theme_path_get(const char *name);
13 13
14Eina_Bool homedir_get(char *buf, size_t size); 14Eina_Bool homedir_get(char *buf, size_t size);
15 15Eina_Bool utils_need_scale_wizard(void);
16Eina_Bool link_is_protocol(const char *str);
17Eina_Bool link_is_url(const char *str);
18Eina_Bool link_is_email(const char *str);
19 16
20#define casestartswith(str, constref) \ 17#define casestartswith(str, constref) \
21 (!strncasecmp(str, constref, sizeof(constref) - 1)) 18 (!strncasecmp(str, constref, sizeof(constref) - 1))
diff --git a/src/bin/win.c b/src/bin/win.c
index a021351..b155676 100644
--- a/src/bin/win.c
+++ b/src/bin/win.c
@@ -199,6 +199,150 @@ static void _term_tabregion_free(Term *term);
199static void _set_trans(Config *config, Evas_Object *bg, Evas_Object *base); 199static void _set_trans(Config *config, Evas_Object *bg, Evas_Object *base);
200static void _imf_event_commit_cb(void *data, Ecore_IMF_Context *_ctx EINA_UNUSED, void *event); 200static void _imf_event_commit_cb(void *data, Ecore_IMF_Context *_ctx EINA_UNUSED, void *event);
201 201
202static void
203_scale_round(void *data EINA_UNUSED,
204 Evas_Object *obj,
205 void *event_info EINA_UNUSED)
206{
207 double val = elm_slider_value_get(obj);
208 double v;
209
210 v = ((double)((int)(val * 10.0))) / 10.0;
211 if (v != val) elm_slider_value_set(obj, v);
212}
213
214static void
215_scale_change(void *data EINA_UNUSED,
216 Evas_Object *obj,
217 void *event_info EINA_UNUSED)
218{
219 double scale = elm_config_scale_get();
220 double val = elm_slider_value_get(obj);
221
222 if (scale == val)
223 return;
224 elm_config_scale_set(val);
225 elm_config_all_flush();
226}
227
228typedef struct _Scale_Ctx
229{
230 Evas_Object *hv;
231 Term *term;
232} Scale_Ctx;
233
234static void
235_scale_done(void *data,
236 Evas_Object *obj EINA_UNUSED,
237 void *event_info EINA_UNUSED)
238{
239 Scale_Ctx *ctx = data;
240
241 evas_object_smart_callback_del_full(ctx->hv, "dismissed",
242 _scale_done, ctx);
243 evas_object_del(ctx->hv);
244 ctx->term->wn->on_popover--;
245 term_unref(ctx->term);
246 elm_config_save();
247 config_save(ctx->term->config);
248 free(ctx);
249}
250
251void
252win_scale_wizard(Evas_Object *win, Term *term)
253{
254 Evas_Object *bx, *lbl, *sl, *fr, *bt;
255 const char *txt;
256 Scale_Ctx *ctx;
257
258 EINA_SAFETY_ON_NULL_RETURN(term);
259 if (!utils_need_scale_wizard())
260 return;
261
262 ctx = calloc(1, sizeof(*ctx));
263 if (!ctx)
264 return;
265
266 ctx->term = term;
267
268 term->wn->on_popover++;
269
270 term_ref(term);
271
272 ctx->hv = elm_hover_add(win);
273 evas_object_size_hint_weight_set(ctx->hv, EVAS_HINT_EXPAND, 0.0);
274 evas_object_size_hint_align_set(ctx->hv, EVAS_HINT_FILL, 0.5);
275 elm_hover_parent_set(ctx->hv, win);
276 elm_hover_target_set(ctx->hv, win);
277 evas_object_smart_callback_add(ctx->hv, "dismissed", _scale_done, ctx);
278
279 fr = elm_frame_add(win);
280 evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0.0);
281 evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, 0.5);
282 elm_object_text_set(fr, _("Scale"));
283 elm_object_part_content_set(ctx->hv, "middle", fr);
284 evas_object_show(fr);
285
286 bx = elm_box_add(win);
287 evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
288 evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, 0.5);
289 elm_object_content_set(fr, bx);
290 evas_object_show(bx);
291
292 fr = elm_frame_add(win);
293 evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0.0);
294 evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, 0.5);
295 elm_object_style_set(fr, "pad_medium");
296 elm_box_pack_end(bx, fr);
297 evas_object_show(fr);
298
299 lbl = elm_label_add(win);
300 evas_object_size_hint_weight_set(lbl, EVAS_HINT_EXPAND, 0.0);
301 evas_object_size_hint_align_set(lbl, EVAS_HINT_FILL, 0.5);
302 txt = eina_stringshare_printf("<hilight>%s</>",_("Scale"));
303 elm_object_text_set(lbl, txt);
304 eina_stringshare_del(txt);
305 elm_object_content_set(fr, lbl);
306 elm_box_pack_end(bx, lbl);
307 evas_object_show(lbl);
308
309 sl = elm_slider_add(win);
310 evas_object_size_hint_weight_set(sl, EVAS_HINT_EXPAND, 0.0);
311 evas_object_size_hint_align_set(sl, EVAS_HINT_FILL, 0.5);
312 elm_slider_span_size_set(sl, 120);
313 elm_slider_unit_format_set(sl, "%1.2f");
314 elm_slider_indicator_format_set(sl, "%1.2f");
315 elm_slider_min_max_set(sl, 0.25, 5.0);
316 elm_slider_value_set(sl, elm_config_scale_get());
317 elm_box_pack_end(bx, sl);
318 evas_object_show(sl);
319 evas_object_smart_callback_add(sl, "changed", _scale_round, NULL);
320 evas_object_smart_callback_add(sl, "delay,changed", _scale_change, NULL);
321
322 lbl = elm_label_add(win);
323 evas_object_size_hint_weight_set(lbl, EVAS_HINT_EXPAND, 0.0);
324 evas_object_size_hint_align_set(lbl, EVAS_HINT_FILL, 0.5);
325 elm_object_text_set(lbl, _("Select prefered size so that this text is readable."));
326 elm_box_pack_end(bx, lbl);
327 evas_object_show(lbl);
328
329 lbl = elm_label_add(win);
330 evas_object_size_hint_weight_set(lbl, EVAS_HINT_EXPAND, 0.0);
331 evas_object_size_hint_align_set(lbl, EVAS_HINT_FILL, 0.5);
332 elm_object_text_set(lbl, _("The scale configuration can be changed in the Settings (right click on the terminal) → Toolkit, or by starting the command <keyword>elementary_config</keyword>."));
333 elm_box_pack_end(bx, lbl);
334 evas_object_show(lbl);
335
336 bt = elm_button_add(win);
337 elm_object_text_set(bt, _("Done"));
338 elm_box_pack_end(bx, bt);
339 evas_object_smart_callback_add(bt, "clicked", _scale_done, ctx);
340 evas_object_show(bt);
341
342 evas_object_show(ctx->hv);
343
344 elm_object_focus_set(ctx->hv, EINA_TRUE);
345}
202 346
203/* {{{ Solo */ 347/* {{{ Solo */
204 348
@@ -364,8 +508,20 @@ _solo_set_title(Term_Container *tc,
364 Term_Container *_child EINA_UNUSED, 508 Term_Container *_child EINA_UNUSED,
365 const char *title) 509 const char *title)
366{ 510{
511 Solo *solo;
512 Term *term;
513
514 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
515 solo = (Solo*) tc;
516 term = solo->term;
517
367 eina_stringshare_del(tc->title); 518 eina_stringshare_del(tc->title);
368 tc->title = eina_stringshare_add(title); 519 tc->title = eina_stringshare_add(title);
520 if (term->config->show_tabs)
521 {
522 edje_object_part_text_set(term->bg, "terminology.tab.title",
523 title);
524 }
369 tc->parent->set_title(tc->parent, tc, title); 525 tc->parent->set_title(tc->parent, tc, title);
370} 526}
371 527
@@ -380,7 +536,8 @@ _solo_bell(Term_Container *tc,
380 solo = (Solo*) tc; 536 solo = (Solo*) tc;
381 term = solo->term; 537 term = solo->term;
382 538
383 term->missed_bell = EINA_TRUE; 539 if (!tc->is_focused)
540 term->missed_bell = EINA_TRUE;
384 541
385 if (!tc->wn->config->disable_visual_bell) 542 if (!tc->wn->config->disable_visual_bell)
386 { 543 {
@@ -392,6 +549,12 @@ _solo_bell(Term_Container *tc,
392 elm_layout_signal_emit(term->base, "bell,ring", "terminology"); 549 elm_layout_signal_emit(term->base, "bell,ring", "terminology");
393 } 550 }
394 } 551 }
552 if ((term->missed_bell) && (term->config->show_tabs)
553 && (tc->parent->type == TERM_CONTAINER_TYPE_SPLIT))
554 {
555 edje_object_signal_emit(term->bg, "tab,bell,on", "terminology");
556 }
557 edje_object_message_signal_process(term->bg);
395 tc->parent->bell(tc->parent, tc); 558 tc->parent->bell(tc->parent, tc);
396} 559}
397 560
@@ -443,6 +606,11 @@ _solo_focus(Term_Container *tc, Term_Container *relative)
443 return; 606 return;
444 607
445 term->missed_bell = EINA_FALSE; 608 term->missed_bell = EINA_FALSE;
609 if ((term->config->show_tabs)
610 && (tc->parent->type == TERM_CONTAINER_TYPE_SPLIT))
611 {
612 edje_object_signal_emit(term->bg, "tab,bell,off", "terminology");
613 }
446 614
447 if (tc->parent != relative) 615 if (tc->parent != relative)
448 { 616 {
@@ -470,19 +638,89 @@ _solo_focus(Term_Container *tc, Term_Container *relative)
470 638
471 if (term->missed_bell) 639 if (term->missed_bell)
472 term->missed_bell = EINA_FALSE; 640 term->missed_bell = EINA_FALSE;
641 edje_object_message_signal_process(term->bg);
642}
643
644static Eina_Bool
645_solo_is_visible(Term_Container *tc, Term_Container *_child EINA_UNUSED)
646{
647 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
648 return tc->parent->is_visible(tc->parent, tc);
473} 649}
474 650
475static void 651static void
476_solo_update(Term_Container *tc) 652_solo_title_show(Term_Container *tc)
477{ 653{
654 Solo *solo;
655 Term *term;
656
478 assert (tc->type == TERM_CONTAINER_TYPE_SOLO); 657 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
658 solo = (Solo*) tc;
659 term = solo->term;
660
661 if (!term->tab_spacer)
662 {
663 Evas_Coord w = 0, h = 0;
664
665 term->tab_spacer = evas_object_rectangle_add(
666 evas_object_evas_get(term->bg));
667 evas_object_color_set(term->tab_spacer, 0, 0, 0, 0);
668 elm_coords_finger_size_adjust(1, &w, 1, &h);
669 evas_object_size_hint_min_set(term->tab_spacer, w, h);
670 edje_object_part_swallow(term->bg, "terminology.tab", term->tab_spacer);
671 edje_object_part_drag_value_set(term->bg, "terminology.tabl", 0.0, 0.0);
672 edje_object_part_drag_value_set(term->bg, "terminology.tabr", 1.0, 0.0);
673 edje_object_part_text_set(term->bg, "terminology.tab.title",
674 solo->tc.title);
675 edje_object_signal_emit(term->bg, "tabbar,on", "terminology");
676 edje_object_message_signal_process(term->bg);
677 }
678 else
679 {
680 edje_object_part_drag_value_set(term->bg, "terminology.tabl", 0.0, 0.0);
681 edje_object_part_drag_value_set(term->bg, "terminology.tabr", 1.0, 0.0);
682 edje_object_message_signal_process(term->bg);
683 }
479} 684}
480 685
481static Eina_Bool 686static void
482_solo_is_visible(Term_Container *tc, Term_Container *_child EINA_UNUSED) 687_solo_title_hide(Term_Container *tc)
483{ 688{
689 Solo *solo;
690 Term *term;
691
484 assert (tc->type == TERM_CONTAINER_TYPE_SOLO); 692 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
485 return tc->parent->is_visible(tc->parent, tc); 693 solo = (Solo*) tc;
694 term = solo->term;
695
696 if (term->tab_spacer)
697 {
698 edje_object_signal_emit(term->bg, "tabbar,off", "terminology");
699 edje_object_message_signal_process(term->bg);
700 edje_object_part_unswallow(term->bg, term->tab_spacer);
701 evas_object_del(term->tab_spacer);
702 term->tab_spacer = NULL;
703 }
704}
705
706static void
707_solo_update(Term_Container *tc)
708{
709 Solo *solo;
710 Term *term;
711 Term_Container *tc_parent = tc->parent;
712
713 assert (tc->type == TERM_CONTAINER_TYPE_SOLO);
714 solo = (Solo*) tc;
715 term = solo->term;
716
717 if (tc_parent->type == TERM_CONTAINER_TYPE_SPLIT)
718 {
719 if (term->config->show_tabs)
720 _solo_title_show(tc);
721 else
722 _solo_title_hide(tc);
723 }
486} 724}
487 725
488static Term_Container * 726static Term_Container *
@@ -956,6 +1194,12 @@ _win_swallow(Term_Container *tc, Term_Container *orig,
956 o = new_child->get_evas_object(new_child); 1194 o = new_child->get_evas_object(new_child);
957 elm_layout_content_set(wn->base, "terminology.content", o); 1195 elm_layout_content_set(wn->base, "terminology.content", o);
958 1196
1197 if ((new_child->type == TERM_CONTAINER_TYPE_SOLO
1198 && (wn->config->show_tabs)))
1199 {
1200 _solo_title_hide(new_child);
1201 }
1202
959 evas_object_show(o); 1203 evas_object_show(o);
960 new_child->parent = tc; 1204 new_child->parent = tc;
961 wn->child = new_child; 1205 wn->child = new_child;
@@ -1130,6 +1374,14 @@ _win_split(Term_Container *tc, Term_Container *child,
1130 elm_layout_content_unset(wn->base, "terminology.content"); 1374 elm_layout_content_unset(wn->base, "terminology.content");
1131 1375
1132 tc_split = _split_new(child, tc_solo_new, is_horizontal); 1376 tc_split = _split_new(child, tc_solo_new, is_horizontal);
1377 if (wn->config->show_tabs)
1378 {
1379 if (child->type == TERM_CONTAINER_TYPE_SOLO)
1380 {
1381 _solo_title_show(child);
1382 }
1383 _solo_title_show(tc_solo_new);
1384 }
1133 1385
1134 tc_split->is_focused = tc->is_focused; 1386 tc_split->is_focused = tc->is_focused;
1135 tc->swallow(tc, NULL, tc_split); 1387 tc->swallow(tc, NULL, tc_split);
@@ -2332,7 +2584,6 @@ _split_split(Term_Container *tc, Term_Container *child,
2332 Term_Container *tc_split, *tc_solo_new; 2584 Term_Container *tc_split, *tc_solo_new;
2333 Evas_Object *obj_split; 2585 Evas_Object *obj_split;
2334 2586
2335 DBG(" ");
2336 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT); 2587 assert (tc->type == TERM_CONTAINER_TYPE_SPLIT);
2337 split = (Split *)tc; 2588 split = (Split *)tc;
2338 wn = tc->wn; 2589 wn = tc->wn;
@@ -2369,6 +2620,11 @@ _split_split(Term_Container *tc, Term_Container *child,
2369 tc_split->is_focused = tc->is_focused; 2620 tc_split->is_focused = tc->is_focused;
2370 tc->swallow(tc, child, tc_split); 2621 tc->swallow(tc, child, tc_split);
2371 2622
2623 if (wn->config->show_tabs)
2624 {
2625 _solo_title_show(tc_solo_new);
2626 }
2627
2372 evas_object_show(obj_split); 2628 evas_object_show(obj_split);
2373} 2629}
2374 2630
@@ -2381,6 +2637,7 @@ _split_is_visible(Term_Container *tc, Term_Container *_child EINA_UNUSED)
2381 return tc->parent->is_visible(tc->parent, tc); 2637 return tc->parent->is_visible(tc->parent, tc);
2382} 2638}
2383 2639
2640/* tc1 is a new solo */
2384static Term_Container * 2641static Term_Container *
2385_split_new(Term_Container *tc1, Term_Container *tc2, 2642_split_new(Term_Container *tc1, Term_Container *tc2,
2386 Eina_Bool is_horizontal) 2643 Eina_Bool is_horizontal)
@@ -2680,6 +2937,8 @@ _tabbar_fill(Tabs *tabs)
2680 term->tabbar.r.tabs = eina_list_append(term->tabbar.r.tabs, o); 2937 term->tabbar.r.tabs = eina_list_append(term->tabbar.r.tabs, o);
2681 elm_box_pack_end(term->tabbar.r.box, o); 2938 elm_box_pack_end(term->tabbar.r.box, o);
2682 } 2939 }
2940 if (solo->term->missed_bell)
2941 edje_object_signal_emit(o, "bell", "terminology");
2683 evas_object_data_set(o, "term", term); 2942 evas_object_data_set(o, "term", term);
2684 evas_object_show(o); 2943 evas_object_show(o);
2685 edje_object_signal_callback_add(o, "tab,activate", "terminology", 2944 edje_object_signal_callback_add(o, "tab,activate", "terminology",
@@ -3025,7 +3284,7 @@ _tabs_size_eval(Term_Container *container, Sizeinfo *info)
3025 config = tc->wn->config; 3284 config = tc->wn->config;
3026 tc->size_eval(tc, info); 3285 tc->size_eval(tc, info);
3027 /* Current sizing code does not take the tab area correctly into account */ 3286 /* Current sizing code does not take the tab area correctly into account */
3028 if (!config->notabs) 3287 if (config->show_tabs)
3029 { 3288 {
3030 info->step_x = 1; 3289 info->step_x = 1;
3031 info->step_y = 1; 3290 info->step_y = 1;
@@ -3087,17 +3346,21 @@ _tabs_close(Term_Container *tc, Term_Container *child)
3087 { 3346 {
3088 Term *next_term; 3347 Term *next_term;
3089 Solo *next_solo; 3348 Solo *next_solo;
3349 Config *config;
3090 3350
3091 assert (next_child->type == TERM_CONTAINER_TYPE_SOLO); 3351 assert (next_child->type == TERM_CONTAINER_TYPE_SOLO);
3092 next_solo = (Solo*)next_child; 3352 next_solo = (Solo*)next_child;
3093 next_term = next_solo->term; 3353 next_term = next_solo->term;
3354 config = next_term->config;
3094 3355
3095 edje_object_signal_emit(next_term->bg, "tabcount,off", "terminology"); 3356 edje_object_signal_emit(next_term->bg, "tabcount,off", "terminology");
3096 if (next_term->tabcount_spacer) 3357 if (next_term->tabcount_spacer && !config->show_tabs)
3097 { 3358 {
3098 evas_object_del(next_term->tabcount_spacer); 3359 evas_object_del(next_term->tabcount_spacer);
3099 next_term->tabcount_spacer = NULL; 3360 next_term->tabcount_spacer = NULL;
3100 } 3361 }
3362 if (config->show_tabs)
3363 _solo_title_show(next_child);
3101 3364
3102 if (tabs->selector) 3365 if (tabs->selector)
3103 _tabs_restore(tabs); 3366 _tabs_restore(tabs);
@@ -3454,7 +3717,7 @@ _tabs_focus(Term_Container *tc, Term_Container *relative)
3454 Config *config = tc->wn->config; 3717 Config *config = tc->wn->config;
3455 tabs->current->tc->unfocus(tabs->current->tc, tc); 3718 tabs->current->tc->unfocus(tabs->current->tc, tc);
3456 3719
3457 if (config->tab_zoom >= 0.01 && config->notabs) 3720 if (config->tab_zoom >= 0.01 && !config->show_tabs)
3458 { 3721 {
3459 _cb_tab_selector_show(tabs, tab_item); 3722 _cb_tab_selector_show(tabs, tab_item);
3460 return; 3723 return;
@@ -3553,7 +3816,7 @@ _tabs_set_title(Term_Container *tc, Term_Container *child,
3553 solo = (Solo*)tab_item->tc; 3816 solo = (Solo*)tab_item->tc;
3554 term = solo->term; 3817 term = solo->term;
3555 3818
3556 if (!term->config->notabs) 3819 if (term->config->show_tabs)
3557 { 3820 {
3558 edje_object_part_text_set(term->bg, "terminology.tab.title", 3821 edje_object_part_text_set(term->bg, "terminology.tab.title",
3559 title); 3822 title);
@@ -3623,7 +3886,7 @@ _tabs_refresh(Tabs *tabs)
3623 edje_object_part_text_set(term->bg, "terminology.tabmissed.label", bufmissed); 3886 edje_object_part_text_set(term->bg, "terminology.tabmissed.label", bufmissed);
3624 edje_object_signal_emit(term->bg, "tabcount,on", "terminology"); 3887 edje_object_signal_emit(term->bg, "tabcount,on", "terminology");
3625 // this is all below just for tab bar at the top 3888 // this is all below just for tab bar at the top
3626 if (!term->config->notabs) 3889 if (term->config->show_tabs)
3627 { 3890 {
3628 double v1, v2; 3891 double v1, v2;
3629 3892
@@ -3757,80 +4020,11 @@ _tabs_new(Term_Container *child, Term_Container *parent)
3757 4020
3758 4021
3759/* }}} */ 4022/* }}} */
3760/* {{{ Term */ 4023/* {{{ Popup Media */
3761 4024struct Pop_Media {
3762Eina_Bool 4025 const char *src;
3763term_is_visible(Term *term) 4026 Eina_Bool from_user_interaction;
3764{ 4027};
3765 Term_Container *tc;
3766
3767 if (!term)
3768 return EINA_FALSE;
3769
3770 tc = term->container;
3771 if (!tc)
3772 return EINA_FALSE;
3773
3774 return tc->is_visible(tc, tc);
3775}
3776
3777void
3778background_set_shine(Config *config, Evas_Object *bg)
3779{
3780 Edje_Message_Int msg;
3781
3782 if (config)
3783 msg.val = config->shine;
3784 else
3785 msg.val = 255;
3786
3787 if (bg)
3788 edje_object_message_send(bg, EDJE_MESSAGE_INT, 2, &msg);
3789}
3790
3791void
3792term_apply_shine(Term *term, int shine)
3793{
3794 Config *config = term->config;
3795
3796 if (config->shine != shine)
3797 {
3798 config->shine = shine;
3799 background_set_shine(config, term->bg);
3800 config_save(config, NULL);
3801 }
3802}
3803
3804
3805static void
3806_set_trans(Config *config, Evas_Object *bg, Evas_Object *base)
3807{
3808 Edje_Message_Int msg;
3809
3810 if (config && config->translucent)
3811 msg.val = config->opacity;
3812 else
3813 msg.val = 100;
3814
3815 if (bg)
3816 edje_object_message_send(bg, EDJE_MESSAGE_INT, 1, &msg);
3817 if (base) {
3818 Evas_Object *edje = elm_layout_edje_get(base);
3819 edje_object_message_send(edje, EDJE_MESSAGE_INT, 1, &msg);
3820 }
3821}
3822
3823static void
3824_term_config_set(Term *term, Config *config)
3825{
3826 Config *old_config = term->config;
3827
3828 term->config = config;
3829 termio_config_set(term->termio, config);
3830 _term_media_update(term, term->config);
3831 if (old_config != term->wn->config)
3832 config_del(old_config);
3833}
3834 4028
3835Eina_Bool 4029Eina_Bool
3836term_has_popmedia(const Term *term) 4030term_has_popmedia(const Term *term)
@@ -3845,181 +4039,6 @@ term_popmedia_close(Term *term)
3845 edje_object_signal_emit(term->bg, "popmedia,off", "terminology"); 4039 edje_object_signal_emit(term->bg, "popmedia,off", "terminology");
3846} 4040}
3847 4041
3848
3849Eina_Bool
3850term_is_focused(Term *term)
3851{
3852 Term_Container *tc;
3853
3854 if (!term)
3855 return EINA_FALSE;
3856
3857 tc = term->container;
3858 if (!tc)
3859 return EINA_FALSE;
3860
3861 DBG("tc:%p tc->is_focused:%d", tc, tc->is_focused);
3862 return tc->is_focused;
3863}
3864
3865void change_theme(Evas_Object *win, Config *config)
3866{
3867 const Eina_List *terms, *l;
3868 Term *term;
3869
3870 terms = terms_from_win_object(win);
3871 if (!terms) return;
3872
3873 EINA_LIST_FOREACH(terms, l, term)
3874 {
3875 Evas_Object *edje = term->bg;
3876
3877 if (!theme_apply(edje, config, "terminology/background"))
3878 ERR("Couldn't find terminology theme!");
3879 colors_term_init(termio_textgrid_get(term->termio), edje, config);
3880 termio_config_set(term->termio, config);
3881 }
3882
3883 l = elm_theme_overlay_list_get(NULL);
3884 if (l) l = eina_list_last(l);
3885 if (l) elm_theme_overlay_del(NULL, l->data);
3886 elm_theme_overlay_add(NULL, config_theme_path_get(config));
3887 main_trans_update(config);
3888}
3889
3890void
3891term_focus(Term *term)
3892{
3893 Term_Container *tc;
3894
3895 DBG("is focused? tc:%p", term->container);
3896 if (term_is_focused(term))
3897 return;
3898
3899 tc = term->container;
3900 DBG("tc:%p", tc);
3901 tc->focus(tc, tc);
3902}
3903
3904void
3905term_unfocus(Term *term)
3906{
3907 Term_Container *tc;
3908
3909 DBG("is focused? tc:%p", term->container);
3910 if (!term_is_focused(term))
3911 return;
3912
3913 tc = term->container;
3914 DBG("tc:%p", tc);
3915 tc->unfocus(tc, tc);
3916}
3917
3918enum term_to_direction {
3919 TERM_TO_PREV,
3920 TERM_TO_NEXT,
3921 TERM_TO_UP,
3922 TERM_TO_DOWN,
3923 TERM_TO_LEFT,
3924 TERM_TO_RIGHT,
3925};
3926
3927static void
3928term_go_to(Term *from, enum term_to_direction dir)
3929{
3930 Term *new_term, *focused_term;
3931 Win *wn = from->wn;
3932 Term_Container *tc;
3933
3934 tc = (Term_Container *) wn;
3935
3936 focused_term = tc->focused_term_get(tc);
3937 if (!focused_term)
3938 focused_term = from;
3939 tc = focused_term->container;
3940
3941 switch (dir)
3942 {
3943 case TERM_TO_PREV:
3944 new_term = tc->term_prev(tc, tc);
3945 break;
3946 case TERM_TO_NEXT:
3947 new_term = tc->term_next(tc, tc);
3948 break;
3949 case TERM_TO_UP:
3950 new_term = tc->term_up(tc, tc);
3951 break;
3952 case TERM_TO_DOWN:
3953 new_term = tc->term_down(tc, tc);
3954 break;
3955 case TERM_TO_LEFT:
3956 new_term = tc->term_left(tc, tc);
3957 break;
3958 case TERM_TO_RIGHT:
3959 new_term = tc->term_right(tc, tc);
3960 break;
3961 }
3962
3963 if (new_term && new_term != focused_term)
3964 term_focus(new_term);
3965
3966 /* TODO: get rid of it? */
3967 _term_miniview_check(from);
3968}
3969
3970void
3971term_prev(Term *term)
3972{
3973 term_go_to(term, TERM_TO_PREV);
3974}
3975
3976void
3977term_next(Term *term)
3978{
3979 term_go_to(term, TERM_TO_NEXT);
3980}
3981
3982void
3983term_up(Term *term)
3984{
3985 term_go_to(term, TERM_TO_UP);
3986}
3987
3988void
3989term_down(Term *term)
3990{
3991 term_go_to(term, TERM_TO_DOWN);
3992}
3993
3994void
3995term_left(Term *term)
3996{
3997 term_go_to(term, TERM_TO_LEFT);
3998}
3999
4000void
4001term_right(Term *term)
4002{
4003 term_go_to(term, TERM_TO_RIGHT);
4004}
4005
4006Term *
4007term_prev_get(const Term *term)
4008{
4009 Term_Container *tc = term->container;
4010
4011 return tc->term_prev(tc, tc);
4012}
4013
4014Term *
4015term_next_get(const Term *term)
4016{
4017 Term_Container *tc = term->container;
4018
4019 return tc->term_next(tc, tc);
4020}
4021
4022
4023static void 4042static void
4024_cb_popmedia_del(void *data, 4043_cb_popmedia_del(void *data,
4025 Evas *_e EINA_UNUSED, 4044 Evas *_e EINA_UNUSED,
@@ -4071,25 +4090,61 @@ _cb_media_loop(void *data,
4071} 4090}
4072 4091
4073static void 4092static void
4093_popmedia_queue_free(Term *term)
4094{
4095 struct Pop_Media *pm;
4096 if (!term->popmedia_queue)
4097 return;
4098
4099 EINA_LIST_FREE(term->popmedia_queue, pm)
4100 {
4101 eina_stringshare_del(pm->src);
4102 free(pm);
4103 }
4104}
4105
4106static void
4107_popmedia_queue_add(Term *term, const char *src,
4108 Eina_Bool from_user_interaction)
4109{
4110 struct Pop_Media *pm = calloc(1, sizeof(struct Pop_Media));
4111
4112 if (!pm)
4113 return;
4114
4115 pm->src = eina_stringshare_add(src);
4116 pm->from_user_interaction = from_user_interaction;
4117
4118 term->popmedia_queue = eina_list_append(term->popmedia_queue, pm);
4119 if (!term->popmedia)
4120 _popmedia_queue_process(term);
4121}
4122
4123static void
4124_popmedia_now(Term *term, const char *src,
4125 Eina_Bool from_user_interaction)
4126{
4127 struct Pop_Media *pm;
4128
4129 /* Flush queue */
4130 EINA_LIST_FREE(term->popmedia_queue, pm)
4131 {
4132 eina_stringshare_del(pm->src);
4133 }
4134 edje_object_signal_emit(term->bg, "popmedia,off", "terminology");
4135
4136 _popmedia_queue_add(term, src, from_user_interaction);
4137}
4138
4139
4140static void
4074_popmedia_show(Term *term, const char *src, Media_Type type) 4141_popmedia_show(Term *term, const char *src, Media_Type type)
4075{ 4142{
4076 Evas_Object *o; 4143 Evas_Object *o;
4077 Config *config = termio_config_get(term->termio); 4144 Config *config = termio_config_get(term->termio);
4078 4145
4146 assert(!term->popmedia);
4079 EINA_SAFETY_ON_NULL_RETURN(config); 4147 EINA_SAFETY_ON_NULL_RETURN(config);
4080 if (term->popmedia)
4081 {
4082 const char *s;
4083
4084 EINA_LIST_FREE(term->popmedia_queue, s)
4085 {
4086 eina_stringshare_del(s);
4087 }
4088 term->popmedia_queue = eina_list_append(term->popmedia_queue,
4089 eina_stringshare_add(src));
4090 edje_object_signal_emit(term->bg, "popmedia,off", "terminology");
4091 return;
4092 }
4093 termio_mouseover_suspend_pushpop(term->termio, 1); 4148 termio_mouseover_suspend_pushpop(term->termio, 1);
4094 term->popmedia = o = media_add(win_evas_object_get(term->wn), 4149 term->popmedia = o = media_add(win_evas_object_get(term->wn),
4095 src, config, MEDIA_POP, type); 4150 src, config, MEDIA_POP, type);
@@ -4147,7 +4202,6 @@ _ty_http_head_delete(Ty_Http_Head *ty_head)
4147 free(ty_head); 4202 free(ty_head);
4148} 4203}
4149 4204
4150
4151static Eina_Bool 4205static Eina_Bool
4152_media_http_head_timeout(void *data) 4206_media_http_head_timeout(void *data)
4153{ 4207{
@@ -4235,7 +4289,7 @@ error:
4235#endif 4289#endif
4236 4290
4237static void 4291static void
4238_popmedia(Term *term, const char *src, Eina_Bool from_user_interaction) 4292_popmedia_unknown(Term *term, const char *src, Eina_Bool from_user_interaction)
4239{ 4293{
4240 Media_Type type; 4294 Media_Type type;
4241 Config *config = termio_config_get(term->termio); 4295 Config *config = termio_config_get(term->termio);
@@ -4293,6 +4347,316 @@ error:
4293} 4347}
4294 4348
4295static void 4349static void
4350_popmedia_queue_process(Term *term)
4351{
4352 struct Pop_Media *pm;
4353
4354 if (!term->popmedia_queue)
4355 return;
4356 pm = term->popmedia_queue->data;
4357 term->popmedia_queue = eina_list_remove_list(term->popmedia_queue,
4358 term->popmedia_queue);
4359 if (!pm)
4360 return;
4361 _popmedia_unknown(term, pm->src, pm->from_user_interaction);
4362 eina_stringshare_del(pm->src);
4363 free(pm);
4364}
4365
4366static void
4367_cb_popup(void *data,
4368 Evas_Object *_obj EINA_UNUSED,
4369 void *event)
4370{
4371 Term *term = data;
4372 const char *src = event;
4373 Eina_Bool from_user_interaction = EINA_FALSE;
4374
4375 if (!src)
4376 {
4377 /* Popup a link, there was user interaction on it. */
4378 from_user_interaction = EINA_TRUE;
4379 src = termio_link_get(term->termio, NULL);
4380 }
4381 if (!src)
4382 return;
4383 _popmedia_unknown(term, src, from_user_interaction);
4384 if (!event)
4385 free((void*)src);
4386}
4387
4388static void
4389_cb_popup_queue(void *data,
4390 Evas_Object *_obj EINA_UNUSED,
4391 void *event)
4392{
4393 Term *term = data;
4394 const char *src = event;
4395 Eina_Bool from_user_interaction = EINA_FALSE;
4396
4397 if (!src)
4398 {
4399 from_user_interaction = EINA_TRUE;
4400 src = termio_link_get(term->termio, NULL);
4401 }
4402 if (!src)
4403 return;
4404 _popmedia_queue_add(term, src, from_user_interaction);
4405 if (!event)
4406 free((void*)src);
4407}
4408
4409/* }}} */
4410/* {{{ Term */
4411
4412Eina_Bool
4413term_is_visible(Term *term)
4414{
4415 Term_Container *tc;
4416
4417 if (!term)
4418 return EINA_FALSE;
4419
4420 tc = term->container;
4421 if (!tc)
4422 return EINA_FALSE;
4423
4424 return tc->is_visible(tc, tc);
4425}
4426
4427void
4428background_set_shine(Config *config, Evas_Object *bg)
4429{
4430 Edje_Message_Int msg;
4431
4432 if (config)
4433 msg.val = config->shine;
4434 else
4435 msg.val = 255;
4436
4437 if (bg)
4438 edje_object_message_send(bg, EDJE_MESSAGE_INT, 2, &msg);
4439}
4440
4441void
4442term_apply_shine(Term *term, int shine)
4443{
4444 Config *config = term->config;
4445
4446 if (config->shine != shine)
4447 {
4448 config->shine = shine;
4449 background_set_shine(config, term->bg);
4450 config_save(config);
4451 }
4452}
4453
4454
4455static void
4456_set_trans(Config *config, Evas_Object *bg, Evas_Object *base)
4457{
4458 Edje_Message_Int msg;
4459
4460 if (config && config->translucent)
4461 msg.val = config->opacity;
4462 else
4463 msg.val = 100;
4464
4465 if (bg)
4466 edje_object_message_send(bg, EDJE_MESSAGE_INT, 1, &msg);
4467 if (base) {
4468 Evas_Object *edje = elm_layout_edje_get(base);
4469 edje_object_message_send(edje, EDJE_MESSAGE_INT, 1, &msg);
4470 }
4471}
4472
4473static void
4474_term_config_set(Term *term, Config *config)
4475{
4476 Config *old_config = term->config;
4477
4478 term->config = config;
4479 termio_config_set(term->termio, config);
4480 _term_media_update(term, term->config);
4481 if (old_config != term->wn->config)
4482 config_del(old_config);
4483}
4484
4485Eina_Bool
4486term_is_focused(Term *term)
4487{
4488 Term_Container *tc;
4489
4490 if (!term)
4491 return EINA_FALSE;
4492
4493 tc = term->container;
4494 if (!tc)
4495 return EINA_FALSE;
4496
4497 DBG("tc:%p tc->is_focused:%d", tc, tc->is_focused);
4498 return tc->is_focused;
4499}
4500
4501void change_theme(Evas_Object *win, Config *config)
4502{
4503 const Eina_List *terms, *l;
4504 Term *term;
4505
4506 terms = terms_from_win_object(win);
4507 if (!terms) return;
4508
4509 EINA_LIST_FOREACH(terms, l, term)
4510 {
4511 Evas_Object *edje = term->bg;
4512
4513 if (!theme_apply(edje, config, "terminology/background"))
4514 ERR("Couldn't find terminology theme!");
4515 colors_term_init(termio_textgrid_get(term->termio), edje, config);
4516 termio_config_set(term->termio, config);
4517 }
4518
4519 l = elm_theme_overlay_list_get(NULL);
4520 if (l) l = eina_list_last(l);
4521 if (l) elm_theme_overlay_del(NULL, l->data);
4522 elm_theme_overlay_add(NULL, config_theme_path_get(config));
4523 main_trans_update(config);
4524}
4525
4526void
4527term_focus(Term *term)
4528{
4529 Term_Container *tc;
4530
4531 DBG("is focused? tc:%p", term->container);
4532 if (term_is_focused(term))
4533 return;
4534
4535 tc = term->container;
4536 DBG("tc:%p", tc);
4537 tc->focus(tc, tc);
4538}
4539
4540void
4541term_unfocus(Term *term)
4542{
4543 Term_Container *tc;
4544
4545 DBG("is focused? tc:%p", term->container);
4546 if (!term_is_focused(term))
4547 return;
4548
4549 tc = term->container;
4550 DBG("tc:%p", tc);
4551 tc->unfocus(tc, tc);
4552}
4553
4554enum term_to_direction {
4555 TERM_TO_PREV,
4556 TERM_TO_NEXT,
4557 TERM_TO_UP,
4558 TERM_TO_DOWN,
4559 TERM_TO_LEFT,
4560 TERM_TO_RIGHT,
4561};
4562
4563static void
4564term_go_to(Term *from, enum term_to_direction dir)
4565{
4566 Term *new_term, *focused_term;
4567 Win *wn = from->wn;
4568 Term_Container *tc;
4569
4570 tc = (Term_Container *) wn;
4571
4572 focused_term = tc->focused_term_get(tc);
4573 if (!focused_term)
4574 focused_term = from;
4575 tc = focused_term->container;
4576
4577 switch (dir)
4578 {
4579 case TERM_TO_PREV:
4580 new_term = tc->term_prev(tc, tc);
4581 break;
4582 case TERM_TO_NEXT:
4583 new_term = tc->term_next(tc, tc);
4584 break;
4585 case TERM_TO_UP:
4586 new_term = tc->term_up(tc, tc);
4587 break;
4588 case TERM_TO_DOWN:
4589 new_term = tc->term_down(tc, tc);
4590 break;
4591 case TERM_TO_LEFT:
4592 new_term = tc->term_left(tc, tc);
4593 break;
4594 case TERM_TO_RIGHT:
4595 new_term = tc->term_right(tc, tc);
4596 break;
4597 }
4598
4599 if (new_term && new_term != focused_term)
4600 term_focus(new_term);
4601
4602 /* TODO: get rid of it? */
4603 _term_miniview_check(from);
4604}
4605
4606void
4607term_prev(Term *term)
4608{
4609 term_go_to(term, TERM_TO_PREV);
4610}
4611
4612void
4613term_next(Term *term)
4614{
4615 term_go_to(term, TERM_TO_NEXT);
4616}
4617
4618void
4619term_up(Term *term)
4620{
4621 term_go_to(term, TERM_TO_UP);
4622}
4623
4624void
4625term_down(Term *term)
4626{
4627 term_go_to(term, TERM_TO_DOWN);
4628}
4629
4630void
4631term_left(Term *term)
4632{
4633 term_go_to(term, TERM_TO_LEFT);
4634}
4635
4636void
4637term_right(Term *term)
4638{
4639 term_go_to(term, TERM_TO_RIGHT);
4640}
4641
4642Term *
4643term_prev_get(const Term *term)
4644{
4645 Term_Container *tc = term->container;
4646
4647 return tc->term_prev(tc, tc);
4648}
4649
4650Term *
4651term_next_get(const Term *term)
4652{
4653 Term_Container *tc = term->container;
4654
4655 return tc->term_next(tc, tc);
4656}
4657
4658
4659static void
4296_term_miniview_check(Term *term) 4660_term_miniview_check(Term *term)
4297{ 4661{
4298 Eina_List *l, *wn_list; 4662 Eina_List *l, *wn_list;
@@ -4462,88 +4826,6 @@ term_set_title(Term *term)
4462 elm_object_focus_set(o, EINA_TRUE); 4826 elm_object_focus_set(o, EINA_TRUE);
4463} 4827}
4464 4828
4465struct Pop_Media {
4466 const char *src;
4467 Eina_Bool from_user_interaction;
4468};
4469
4470static void
4471_popmedia_queue_process(Term *term)
4472{
4473 struct Pop_Media *pm;
4474
4475 if (!term->popmedia_queue)
4476 return;
4477 pm = term->popmedia_queue->data;
4478 term->popmedia_queue = eina_list_remove_list(term->popmedia_queue,
4479 term->popmedia_queue);
4480 if (!pm)
4481 return;
4482 _popmedia(term, pm->src, pm->from_user_interaction);
4483 eina_stringshare_del(pm->src);
4484 free(pm);
4485}
4486
4487static void
4488_popmedia_queue_add(Term *term, const char *src,
4489 Eina_Bool from_user_interaction)
4490{
4491 struct Pop_Media *pm = calloc(1, sizeof(struct Pop_Media));
4492
4493 if (!pm)
4494 return;
4495
4496 pm->src = eina_stringshare_add(src);
4497 pm->from_user_interaction = from_user_interaction;
4498
4499 term->popmedia_queue = eina_list_append(term->popmedia_queue, pm);
4500 if (!term->popmedia)
4501 _popmedia_queue_process(term);
4502}
4503
4504static void
4505_cb_popup(void *data,
4506 Evas_Object *_obj EINA_UNUSED,
4507 void *event)
4508{
4509 Term *term = data;
4510 const char *src = event;
4511 Eina_Bool from_user_interaction = EINA_FALSE;
4512
4513 if (!src)
4514 {
4515 /* Popup a link, there was user interaction on it. */
4516 from_user_interaction = EINA_TRUE;
4517 src = termio_link_get(term->termio, NULL);
4518 }
4519 if (!src)
4520 return;
4521 _popmedia(term, src, from_user_interaction);
4522 if (!event)
4523 free((void*)src);
4524}
4525
4526static void
4527_cb_popup_queue(void *data,
4528 Evas_Object *_obj EINA_UNUSED,
4529 void *event)
4530{
4531 Term *term = data;
4532 const char *src = event;
4533 Eina_Bool from_user_interaction = EINA_FALSE;
4534
4535 if (!src)
4536 {
4537 from_user_interaction = EINA_TRUE;
4538 src = termio_link_get(term->termio, NULL);
4539 }
4540 if (!src)
4541 return;
4542 _popmedia_queue_add(term, src, from_user_interaction);
4543 if (!event)
4544 free((void*)src);
4545}
4546
4547static void 4829static void
4548_set_alpha(Config *config, const char *val, Eina_Bool save) 4830_set_alpha(Config *config, const char *val, Eina_Bool save)
4549{ 4831{
@@ -4575,7 +4857,8 @@ _set_alpha(Config *config, const char *val, Eina_Bool save)
4575 config->translucent = EINA_FALSE; 4857 config->translucent = EINA_FALSE;
4576 main_trans_update(config); 4858 main_trans_update(config);
4577 4859
4578 if (save) config_save(config, NULL); 4860 if (save)
4861 config_save(config);
4579} 4862}
4580 4863
4581static void 4864static void
@@ -4838,7 +5121,7 @@ _cb_command(void *data,
4838 { 5121 {
4839 if (cmd[1] == 'n') // now 5122 if (cmd[1] == 'n') // now
4840 { 5123 {
4841 _popmedia(term, cmd + 2, EINA_FALSE); 5124 _popmedia_now(term, cmd + 2, EINA_FALSE);
4842 } 5125 }
4843 else if (cmd[1] == 'q') // queue it to display after current one 5126 else if (cmd[1] == 'q') // queue it to display after current one
4844 { 5127 {
@@ -4875,7 +5158,7 @@ _cb_command(void *data,
4875 else 5158 else
4876 eina_stringshare_replace(&(config->background), NULL); 5159 eina_stringshare_replace(&(config->background), NULL);
4877 main_media_update(config); 5160 main_media_update(config);
4878 config_save(config, NULL); 5161 config_save(config);
4879 } 5162 }
4880 } 5163 }
4881 } 5164 }
@@ -5324,8 +5607,6 @@ main_config_sync(const Config *config)
5324static void 5607static void
5325_term_free(Term *term) 5608_term_free(Term *term)
5326{ 5609{
5327 const char *s;
5328
5329 if (term->sendfile_request) 5610 if (term->sendfile_request)
5330 { 5611 {
5331 evas_object_del(term->sendfile_request); 5612 evas_object_del(term->sendfile_request);
@@ -5351,10 +5632,7 @@ _term_free(Term *term)
5351 eina_stringshare_del(term->sendfile_dir); 5632 eina_stringshare_del(term->sendfile_dir);
5352 term->sendfile_dir = NULL; 5633 term->sendfile_dir = NULL;
5353 } 5634 }
5354 EINA_LIST_FREE(term->popmedia_queue, s) 5635 _popmedia_queue_free(term);
5355 {
5356 eina_stringshare_del(s);
5357 }
5358 if (term->media) 5636 if (term->media)
5359 { 5637 {
5360 evas_object_event_callback_del(term->media, 5638 evas_object_event_callback_del(term->media,
diff --git a/src/bin/win.h b/src/bin/win.h
index af4bf16..2986dac 100644
--- a/src/bin/win.h
+++ b/src/bin/win.h
@@ -50,6 +50,7 @@ void win_toggle_visible_group(Win *wn);
50void win_toggle_all_group(Win *wn); 50void win_toggle_all_group(Win *wn);
51Eina_Bool win_is_group_action_handled(Win *wn); 51Eina_Bool win_is_group_action_handled(Win *wn);
52Eina_Bool win_is_group_input(Win *wn); 52Eina_Bool win_is_group_input(Win *wn);
53void win_scale_wizard(Evas_Object *win, Term *term);
53 54
54 55
55void term_ref(Term *term); 56void term_ref(Term *term);