summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/config.c30
-rw-r--r--src/bin/controls.c2
-rw-r--r--src/bin/ipc.c33
-rw-r--r--src/bin/ipc.h48
-rw-r--r--src/bin/main.c870
-rw-r--r--src/bin/main.h2
-rw-r--r--src/bin/media.c1
-rw-r--r--src/bin/termio.c7
-rw-r--r--src/bin/termiointernals.c124
-rw-r--r--src/bin/termpty.h8
-rw-r--r--src/bin/termptyesc.c8
-rw-r--r--src/bin/termptyops.c2
-rw-r--r--src/bin/win.c128
13 files changed, 729 insertions, 534 deletions
diff --git a/src/bin/config.c b/src/bin/config.c
index 52ff2d2..97e10a9 100644
--- a/src/bin/config.c
+++ b/src/bin/config.c
@@ -216,6 +216,7 @@ config_save(Config *config)
216 char buf[PATH_MAX], buf2[PATH_MAX]; 216 char buf[PATH_MAX], buf2[PATH_MAX];
217 const char *cfgdir; 217 const char *cfgdir;
218 int ok; 218 int ok;
219 Eet_Error err;
219 220
220 EINA_SAFETY_ON_NULL_RETURN(config); 221 EINA_SAFETY_ON_NULL_RETURN(config);
221 222
@@ -236,11 +237,28 @@ config_save(Config *config)
236 snprintf(buf, sizeof(buf), "%s/terminology/config/standard/base.cfg.tmp", cfgdir); 237 snprintf(buf, sizeof(buf), "%s/terminology/config/standard/base.cfg.tmp", cfgdir);
237 snprintf(buf2, sizeof(buf2), "%s/terminology/config/standard/base.cfg", cfgdir); 238 snprintf(buf2, sizeof(buf2), "%s/terminology/config/standard/base.cfg", cfgdir);
238 ef = eet_open(buf, EET_FILE_MODE_WRITE); 239 ef = eet_open(buf, EET_FILE_MODE_WRITE);
239 if (ef) 240 if (!ef)
241 {
242 ERR("error opening file '%s' for writing", buf);
243 return;
244 }
245 ok = eet_data_write(ef, edd_base, CONFIG_KEY, config, 1);
246 if (!ok)
240 { 247 {
241 ok = eet_data_write(ef, edd_base, CONFIG_KEY, config, 1);
242 eet_close(ef); 248 eet_close(ef);
243 if (ok) ecore_file_mv(buf, buf2); 249 ERR("error writing to file '%s'", buf);
250 return;
251 }
252 err = eet_close(ef);
253 if (err != EET_ERROR_NONE)
254 {
255 ERR("error #%d closing file '%s'", err, buf);
256 return;
257 }
258 if (!ecore_file_mv(buf, buf2))
259 {
260 ERR("error moving file '%s' to '%s'", buf, buf2);
261 return;
244 } 262 }
245 main_config_sync(config); 263 main_config_sync(config);
246} 264}
@@ -718,10 +736,12 @@ config_load(void)
718 if (config->version < CONF_VER) 736 if (config->version < CONF_VER)
719 { 737 {
720 // currently no upgrade path so reset config. 738 // currently no upgrade path so reset config.
739 ERR("config is from a newer Terminology, discard it");
721 config_del(config); 740 config_del(config);
722 config = NULL; 741 config = config_new();
742 config->temporary = EINA_TRUE;
723 } 743 }
724 /* do no thing in case the config is from a newer 744 /* do nothing in case the config is from a newer
725 * terminology, we don't want to remove it. */ 745 * terminology, we don't want to remove it. */
726 } 746 }
727 } 747 }
diff --git a/src/bin/controls.c b/src/bin/controls.c
index 279fea3..255eb6b 100644
--- a/src/bin/controls.c
+++ b/src/bin/controls.c
@@ -101,7 +101,7 @@ _cb_ct_new(void *data,
101 void *_event EINA_UNUSED) 101 void *_event EINA_UNUSED)
102{ 102{
103 Controls_Ctx *ctx = data; 103 Controls_Ctx *ctx = data;
104 main_new(ctx->win, ctx->term); 104 main_new(ctx->term);
105} 105}
106 106
107static void 107static void
diff --git a/src/bin/ipc.c b/src/bin/ipc.c
index c9b9ee7..c848e4f 100644
--- a/src/bin/ipc.c
+++ b/src/bin/ipc.c
@@ -1,6 +1,7 @@
1#include "private.h" 1#include "private.h"
2 2
3#include <Ecore.h> 3#include <Ecore.h>
4#include <Ecore_Con.h>
4#include <Ecore_Ipc.h> 5#include <Ecore_Ipc.h>
5#include <Eet.h> 6#include <Eet.h>
6#include "ipc.h" 7#include "ipc.h"
@@ -93,6 +94,8 @@ ipc_init(void)
93 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance, 94 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
94 "name", name, EET_T_STRING); 95 "name", name, EET_T_STRING);
95 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance, 96 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
97 "theme", theme, EET_T_STRING);
98 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
96 "role", role, EET_T_STRING); 99 "role", role, EET_T_STRING);
97 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance, 100 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
98 "title", title, EET_T_STRING); 101 "title", title, EET_T_STRING);
@@ -128,6 +131,16 @@ ipc_init(void)
128 "hold", hold, EET_T_INT); 131 "hold", hold, EET_T_INT);
129 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance, 132 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
130 "nowm", nowm, EET_T_INT); 133 "nowm", nowm, EET_T_INT);
134 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
135 "xterm_256color", xterm_256color, EET_T_INT);
136 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
137 "active_links", active_links, EET_T_INT);
138 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
139 "video_mute", active_links, EET_T_INT);
140 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
141 "cursor_blink", active_links, EET_T_INT);
142 EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
143 "visual_bell", active_links, EET_T_INT);
131} 144}
132 145
133Eina_Bool 146Eina_Bool
@@ -171,6 +184,19 @@ ipc_instance_new_func_set(void (*func) (Ipc_Instance *inst))
171 func_new_inst = func; 184 func_new_inst = func;
172} 185}
173 186
187void
188ipc_instance_conn_free(void)
189{
190 char *hash = _ipc_hash_get();
191 char *address = ecore_con_local_path_new(EINA_FALSE,
192 hash,
193 0);
194 errno = 0;
195 unlink(address);
196 ERR("unlinking: '%s': %s", address, strerror(errno));
197 free(address);
198}
199
174Eina_Bool 200Eina_Bool
175ipc_instance_add(Ipc_Instance *inst) 201ipc_instance_add(Ipc_Instance *inst)
176{ 202{
@@ -178,7 +204,7 @@ ipc_instance_add(Ipc_Instance *inst)
178 void *data; 204 void *data;
179 char *hash = _ipc_hash_get(); 205 char *hash = _ipc_hash_get();
180 Ecore_Ipc_Server *ipcsrv; 206 Ecore_Ipc_Server *ipcsrv;
181 207
182 if (!hash) return EINA_FALSE; 208 if (!hash) return EINA_FALSE;
183 data = eet_data_descriptor_encode(new_inst_edd, inst, &size); 209 data = eet_data_descriptor_encode(new_inst_edd, inst, &size);
184 if (!data) 210 if (!data)
@@ -186,6 +212,7 @@ ipc_instance_add(Ipc_Instance *inst)
186 free(hash); 212 free(hash);
187 return EINA_FALSE; 213 return EINA_FALSE;
188 } 214 }
215
189 ipcsrv = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, hash, 0, NULL); 216 ipcsrv = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, hash, 0, NULL);
190 if (ipcsrv) 217 if (ipcsrv)
191 { 218 {
@@ -196,6 +223,10 @@ ipc_instance_add(Ipc_Instance *inst)
196 ecore_ipc_server_del(ipcsrv); 223 ecore_ipc_server_del(ipcsrv);
197 return EINA_TRUE; 224 return EINA_TRUE;
198 } 225 }
226 else
227 {
228 DBG("connect failed");
229 }
199 free(data); 230 free(data);
200 free(hash); 231 free(hash);
201 return EINA_FALSE; 232 return EINA_FALSE;
diff --git a/src/bin/ipc.h b/src/bin/ipc.h
index 4ade907..0aa4775 100644
--- a/src/bin/ipc.h
+++ b/src/bin/ipc.h
@@ -7,28 +7,33 @@ typedef struct _Ipc_Instance Ipc_Instance;
7 7
8struct _Ipc_Instance 8struct _Ipc_Instance
9{ 9{
10 const char *cmd; 10 char *cmd;
11 const char *cd; 11 char *cd;
12 const char *background; 12 char *background;
13 const char *name; 13 char *name;
14 const char *role; 14 char *theme;
15 const char *title; 15 char *role;
16 const char *icon_name; 16 char *title;
17 const char *font; 17 char *icon_name;
18 const char *startup_id; 18 char *font;
19 const char *startup_split; 19 char *startup_id;
20 char *startup_split;
20 int x, y, w, h; 21 int x, y, w, h;
21 int pos; 22 Eina_Bool pos;
22 int login_shell; 23 Eina_Bool login_shell;
23 int fullscreen; 24 Eina_Bool fullscreen;
24 int iconic; 25 Eina_Bool iconic;
25 int borderless; 26 Eina_Bool borderless;
26 int override; 27 Eina_Bool override;
27 int maximized; 28 Eina_Bool maximized;
28 int hold; 29 Eina_Bool hold;
29 int nowm; 30 Eina_Bool nowm;
30 int xterm_256color; 31 Eina_Bool xterm_256color;
31 int active_links; 32 Eina_Bool video_mute;
33 Eina_Bool active_links;
34 Eina_Bool cursor_blink;
35 Eina_Bool visual_bell;
36 Config *config;
32}; 37};
33 38
34void ipc_init(void); 39void ipc_init(void);
@@ -36,5 +41,6 @@ void ipc_shutdown(void);
36Eina_Bool ipc_serve(void); 41Eina_Bool ipc_serve(void);
37void ipc_instance_new_func_set(void (*func) (Ipc_Instance *inst)); 42void ipc_instance_new_func_set(void (*func) (Ipc_Instance *inst));
38Eina_Bool ipc_instance_add(Ipc_Instance *inst); 43Eina_Bool ipc_instance_add(Ipc_Instance *inst);
44void ipc_instance_conn_free(void);
39 45
40#endif 46#endif
diff --git a/src/bin/main.c b/src/bin/main.c
index b50dbbe..4aabc07 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -27,6 +27,129 @@ Eina_Bool multisense_available = EINA_TRUE;
27static Config *_main_config = NULL; 27static Config *_main_config = NULL;
28 28
29static void 29static void
30_set_instance_theme(Ipc_Instance *inst)
31{
32 char path[PATH_MAX];
33 char theme_name[PATH_MAX];
34 const char *theme_path = (const char *)&path;
35
36 if (!inst->theme)
37 return;
38
39 if (eina_str_has_suffix(inst->theme, ".edj"))
40 eina_strlcpy(theme_name, inst->theme, sizeof(theme_name));
41 else
42 snprintf(theme_name, sizeof(theme_name), "%s.edj", inst->theme);
43
44 if (strchr(theme_name, '/'))
45 eina_strlcpy(path, theme_name, sizeof(path));
46 else
47 theme_path = theme_path_get(theme_name);
48
49 eina_stringshare_replace(&(inst->config->theme), theme_path);
50 inst->config->temporary = EINA_TRUE;
51}
52
53static void
54_configure_instance(Ipc_Instance *inst)
55{
56 Config *config = inst->config;
57
58 _set_instance_theme(inst);
59
60 if (inst->background)
61 {
62 eina_stringshare_replace(&(config->background), inst->background);
63 config->temporary = EINA_TRUE;
64 }
65
66 if (inst->font)
67 {
68 char *p = strchr(inst->font, '/');
69 if (p)
70 {
71 int sz;
72 char *fname = alloca(p - inst->font + 1);
73
74 strncpy(fname, inst->font, p - inst->font);
75 fname[p - inst->font] = '\0';
76 sz = atoi(p+1);
77 if (sz > 0)
78 inst->config->font.size = sz;
79 eina_stringshare_replace(&(inst->config->font.name), fname);
80 inst->config->font.bitmap = EINA_FALSE;
81 }
82 else
83 {
84 char buf[4096], *file;
85 Eina_List *files;
86 int n = strlen(inst->font);
87 Eina_Bool found = EINA_FALSE;
88
89 snprintf(buf, sizeof(buf), "%s/fonts", elm_app_data_dir_get());
90 files = ecore_file_ls(buf);
91 EINA_LIST_FREE(files, file)
92 {
93 if (n > 0)
94 {
95 if (!strncasecmp(file, inst->font, n))
96 {
97 n = -1;
98 eina_stringshare_replace(&(inst->config->font.name), file);
99 inst->config->font.bitmap = EINA_TRUE;
100 found = EINA_TRUE;
101 }
102 }
103 free(file);
104 }
105 if (!found)
106 {
107 ERR("font '%s' not found in %s", inst->font, buf);
108 }
109 }
110 config->font_set = EINA_TRUE;
111 config->temporary = EINA_TRUE;
112 }
113
114 if (inst->login_shell)
115 {
116 inst->config->login_shell = inst->login_shell;
117 inst->config->temporary = EINA_TRUE;
118 }
119 inst->login_shell = inst->config->login_shell;
120
121 if (inst->xterm_256color)
122 {
123 inst->config->xterm_256color = EINA_TRUE;
124 inst->config->temporary = EINA_TRUE;
125 }
126 if (inst->video_mute != 0xff)
127 {
128 config->mute = inst->video_mute;
129 config->temporary = EINA_TRUE;
130 }
131 if (inst->cursor_blink != 0xff)
132 {
133 config->disable_cursor_blink = !inst->cursor_blink;
134 config->temporary = EINA_TRUE;
135 }
136 if (inst->visual_bell != 0xff)
137 {
138 config->disable_visual_bell = !inst->visual_bell;
139 config->temporary = EINA_TRUE;
140 }
141 if (inst->active_links != 0xff)
142 {
143 config->active_links = !!inst->active_links;
144 config->active_links_email = inst->config->active_links;
145 config->active_links_file = inst->config->active_links;
146 config->active_links_url = inst->config->active_links;
147 config->active_links_escape = inst->config->active_links;
148 config->temporary = EINA_TRUE;
149 }
150}
151
152static void
30_check_multisense(void) 153_check_multisense(void)
31{ 154{
32 int enabled; 155 int enabled;
@@ -70,7 +193,7 @@ main_ipc_new(Ipc_Instance *inst)
70 char buf[4096]; 193 char buf[4096];
71 194
72 snprintf(buf, sizeof(buf), "DESKTOP_STARTUP_ID=%s", inst->startup_id); 195 snprintf(buf, sizeof(buf), "DESKTOP_STARTUP_ID=%s", inst->startup_id);
73 putenv(buf); 196 putenv(strdup(buf));
74 } 197 }
75 ecore_app_args_get(&pargc, &pargv); 198 ecore_app_args_get(&pargc, &pargv);
76 nargc = 1; 199 nargc = 1;
@@ -93,7 +216,11 @@ main_ipc_new(Ipc_Instance *inst)
93 if (inst->nowm) nargc += 1; 216 if (inst->nowm) nargc += 1;
94 if (inst->xterm_256color) nargc += 1; 217 if (inst->xterm_256color) nargc += 1;
95 if (inst->active_links) nargc += 1; 218 if (inst->active_links) nargc += 1;
219 if (inst->video_mute) nargc += 1;
220 if (inst->cursor_blink) nargc += 1;
221 if (inst->visual_bell) nargc += 1;
96 if (inst->cmd) nargc += 2; 222 if (inst->cmd) nargc += 2;
223 if (inst->theme) nargc += 2;
97 224
98 nargv = calloc(nargc + 1, sizeof(char *)); 225 nargv = calloc(nargc + 1, sizeof(char *));
99 if (!nargv) return; 226 if (!nargv) return;
@@ -115,6 +242,11 @@ main_ipc_new(Ipc_Instance *inst)
115 nargv[i++] = "-n"; 242 nargv[i++] = "-n";
116 nargv[i++] = (char *)inst->name; 243 nargv[i++] = (char *)inst->name;
117 } 244 }
245 if (inst->theme)
246 {
247 nargv[i++] = "-t";
248 nargv[i++] = (char *)inst->theme;
249 }
118 if (inst->role) 250 if (inst->role)
119 { 251 {
120 nargv[i++] = "-r"; 252 nargv[i++] = "-r";
@@ -232,6 +364,19 @@ main_ipc_new(Ipc_Instance *inst)
232 nargv[i++] = "-e"; 364 nargv[i++] = "-e";
233 nargv[i++] = (char *)inst->cmd; 365 nargv[i++] = (char *)inst->cmd;
234 } 366 }
367 if (inst->video_mute)
368 {
369 nargv[i++] = "-m";
370 }
371 if (inst->cursor_blink)
372 {
373 nargv[i++] = "-c";
374 }
375 if (inst->visual_bell)
376 {
377 nargv[i++] = "-G";
378 }
379
235 380
236 ecore_app_args_set(nargc, (const char **)nargv); 381 ecore_app_args_set(nargc, (const char **)nargv);
237 wn = win_new(inst->name, inst->role, inst->title, inst->icon_name, 382 wn = win_new(inst->name, inst->role, inst->title, inst->icon_name,
@@ -247,60 +392,9 @@ main_ipc_new(Ipc_Instance *inst)
247 392
248 win = win_evas_object_get(wn); 393 win = win_evas_object_get(wn);
249 config = win_config_get(wn); 394 config = win_config_get(wn);
395 inst->config = config;
250 396
251 unsetenv("DESKTOP_STARTUP_ID"); 397 _configure_instance(inst);
252 if (inst->background)
253 {
254 eina_stringshare_replace(&(config->background), inst->background);
255 config->temporary = EINA_TRUE;
256 }
257
258 if (inst->font)
259 {
260 if (strchr(inst->font, '/'))
261 {
262 char *fname = alloca(strlen(inst->font) + 1);
263 char *p;
264
265 strcpy(fname, inst->font);
266 p = strrchr(fname, '/');
267 if (p)
268 {
269 int sz;
270
271 *p = 0;
272 p++;
273 sz = atoi(p);
274 if (sz > 0) config->font.size = sz;
275 eina_stringshare_replace(&(config->font.name), fname);
276 }
277 config->font.bitmap = 0;
278 }
279 else
280 {
281 char buf[4096], *file;
282 Eina_List *files;
283 int n = strlen(inst->font);
284
285 snprintf(buf, sizeof(buf), "%s/fonts", elm_app_data_dir_get());
286 files = ecore_file_ls(buf);
287 EINA_LIST_FREE(files, file)
288 {
289 if (n > 0)
290 {
291 if (!strncasecmp(file, inst->font, n))
292 {
293 n = -1;
294 eina_stringshare_replace(&(config->font.name), file);
295 config->font.bitmap = 1;
296 }
297 }
298 free(file);
299 }
300 }
301 config->font_set = EINA_TRUE;
302 config->temporary = EINA_TRUE;
303 }
304 398
305 if (inst->w <= 0) inst->w = 80; 399 if (inst->w <= 0) inst->w = 80;
306 if (inst->h <= 0) inst->h = 24; 400 if (inst->h <= 0) inst->h = 24;
@@ -337,6 +431,7 @@ main_ipc_new(Ipc_Instance *inst)
337 (ecore_evas_ecore_evas_get(evas_object_evas_get(win)), 1); 431 (ecore_evas_ecore_evas_get(evas_object_evas_get(win)), 1);
338 ecore_app_args_set(pargc, (const char **)pargv); 432 ecore_app_args_set(pargc, (const char **)pargv);
339 free(nargv); 433 free(nargv);
434 unsetenv("DESKTOP_STARTUP_ID");
340} 435}
341 436
342static const char *emotion_choices[] = { 437static const char *emotion_choices[] = {
@@ -468,65 +563,278 @@ _log_void(const Eina_Log_Domain *_d EINA_UNUSED,
468} 563}
469#endif 564#endif
470 565
566static void
567_start(Ipc_Instance *instance)
568{
569 Win *wn;
570 Evas_Object *win;
571 Term *term;
572 Config *config;
573
574 wn = win_new(instance->name, instance->role, instance->title,
575 instance->icon_name, instance->config,
576 instance->fullscreen, instance->iconic, instance->borderless,
577 instance->override, instance->maximized);
578 // set an env so terminal apps can detect they are in terminology :)
579 putenv("TERMINOLOGY=1");
580
581 config_del(instance->config);
582 config = NULL;
583 if (!wn)
584 {
585 CRITICAL(_("Could not create window."));
586 goto exit;
587 }
588
589 config = win_config_get(wn);
590
591 term = term_new(wn, config, instance->cmd, instance->login_shell,
592 instance->cd,
593 instance->w, instance->h, instance->hold, instance->title);
594 if (!term)
595 {
596 CRITICAL(_("Could not create terminal widget."));
597 config = NULL;
598 goto exit;
599 }
600
601 if (win_term_set(wn, term) < 0)
602 {
603 goto exit;
604 }
605
606 main_trans_update(config);
607 main_media_update(config);
608 win_sizing_handle(wn);
609 win = win_evas_object_get(wn);
610 evas_object_show(win);
611 if (instance->startup_split)
612 {
613 unsigned int i = 0;
614 Eina_List *cmds_list = NULL;
615 Term *next = term;
616
617 for (i = 0; i < strlen(instance->startup_split); i++)
618 {
619 char *cmd = NULL;
620
621 if (instance->startup_split[i] == 'v')
622 {
623 cmd = cmds_list ? cmds_list->data : NULL;
624 split_vertically(win_evas_object_get(term_win_get(next)),
625 term_termio_get(next), cmd);
626 cmds_list = eina_list_remove_list(cmds_list, cmds_list);
627 }
628 else if (instance->startup_split[i] == 'h')
629 {
630 cmd = cmds_list ? cmds_list->data : NULL;
631 split_horizontally(win_evas_object_get(term_win_get(next)),
632 term_termio_get(next), cmd);
633 cmds_list = eina_list_remove_list(cmds_list, cmds_list);
634 }
635 else if (instance->startup_split[i] == '-')
636 next = term_next_get(next);
637 else
638 {
639 CRITICAL(_("invalid argument found for option -S/--split."
640 " See --help."));
641 goto end;
642 }
643 }
644 if (cmds_list)
645 eina_list_free(cmds_list);
646 }
647 if (instance->pos)
648 {
649 int screen_w, screen_h;
650
651 elm_win_screen_size_get(win, NULL, NULL, &screen_w, &screen_h);
652 if (instance->x < 0) instance->x = screen_w + instance->x;
653 if (instance->y < 0) instance->y = screen_h + instance->y;
654 evas_object_move(win, instance->x, instance->y);
655 }
656 if (instance->nowm)
657 ecore_evas_focus_set(ecore_evas_ecore_evas_get(
658 evas_object_evas_get(win)), 1);
659
660 controls_init();
661
662 win_scale_wizard(win, term);
663
664 terminology_starting_up = EINA_FALSE;
665
666
667end:
668 return;
669exit:
670 ecore_main_loop_quit();
671}
672
673struct Instance_Add {
674 Ipc_Instance *instance;
675 char **argv;
676 Eina_Bool result;
677 Eina_Bool timedout;
678 Eina_Bool done;
679 pthread_mutex_t lock;
680};
681
682static void
683_instance_add_free(struct Instance_Add *add)
684{
685 if (!add)
686 return;
687
688 pthread_mutex_destroy(&add->lock);
689 free(add);
690}
691
692
693static void *
694_instance_sleep(void *data)
695{
696 struct Instance_Add *add = data;
697 Eina_Bool timedout = EINA_FALSE;
698
699 sleep(2);
700 pthread_mutex_lock(&add->lock);
701 if (!add->done)
702 timedout = add->timedout = EINA_TRUE;
703 pthread_mutex_unlock(&add->lock);
704 if (timedout)
705 {
706 /* ok, we waited 2 seconds without any answer,
707 * remove the unix socket and restart terminology from scratch in a
708 * better state */
709 ipc_instance_conn_free();
710 errno = 0;
711 execv(add->argv[0], add->argv);
712 ERR("execv failed on '%s': %s", add->argv[0], strerror(errno));
713 }
714 else
715 {
716 _instance_add_free(add);
717 }
718
719 return NULL;
720}
721
722static Eina_Bool
723_instance_add_waiter(Ipc_Instance *instance,
724 char **argv)
725{
726 struct Instance_Add *add;
727 Eina_Bool timedout = EINA_FALSE;
728 Eina_Bool result = EINA_TRUE;
729 pthread_t thr;
730
731 add = calloc(1, sizeof(*add));
732 if (!add)
733 return EINA_FALSE;
734
735 add->instance = instance;
736 add->argv = argv;
737 pthread_mutex_init(&add->lock, NULL);
738
739 pthread_create(&thr, NULL, &_instance_sleep, add);
740
741 /* If the unix socket is stalled, this might block */
742 result = ipc_instance_add(add->instance);
743 pthread_mutex_lock(&add->lock);
744 /* Hoora, it did not block! */
745 add->done = EINA_TRUE;
746 if (add->timedout)
747 {
748 timedout = add->timedout = EINA_TRUE;
749 result = EINA_FALSE;
750 }
751 pthread_mutex_unlock(&add->lock);
752 if (timedout)
753 _instance_add_free(add);
754
755 return result;
756}
757
758static Eina_Bool
759_start_multi(Ipc_Instance *instance,
760 char **argv)
761{
762 int remote_try = 0;
763 do
764 {
765 if (_instance_add_waiter(instance, argv))
766 {
767 goto exit;
768 }
769 /* Could not start a new window remotely,
770 * let's start our own server */
771 ipc_instance_new_func_set(main_ipc_new);
772 if (ipc_serve())
773 {
774 goto normal_start;
775 }
776 else
777 {
778 DBG("IPC server: failure");
779 }
780 remote_try++;
781 }
782 while (remote_try <= 1);
783
784normal_start:
785 _start(instance);
786 return EINA_FALSE;
787
788exit:
789 return EINA_TRUE;
790}
791
471EAPI_MAIN int 792EAPI_MAIN int
472elm_main(int argc, char **argv) 793elm_main(int argc, char **argv)
473{ 794{
474 char *cmd = NULL;
475 char *cd = NULL;
476 char *theme = NULL;
477 char *background = NULL;
478 char *geometry = NULL; 795 char *geometry = NULL;
479 char *name = NULL;
480 char *role = NULL;
481 char *title = NULL;
482 char *icon_name = NULL;
483 char *font = NULL;
484 char *startup_split = NULL;
485 char *video_module = NULL; 796 char *video_module = NULL;
486 Eina_Bool login_shell = 0xff; /* unset */
487 Eina_Bool video_mute = 0xff; /* unset */
488 Eina_Bool cursor_blink = 0xff; /* unset */
489 Eina_Bool visual_bell = 0xff; /* unset */
490 Eina_Bool active_links = 0xff; /* unset */
491 Eina_Bool fullscreen = EINA_FALSE;
492 Eina_Bool iconic = EINA_FALSE;
493 Eina_Bool borderless = EINA_FALSE;
494 Eina_Bool override = EINA_FALSE;
495 Eina_Bool maximized = EINA_FALSE;
496 Eina_Bool nowm = EINA_FALSE;
497 Eina_Bool quit_option = EINA_FALSE; 797 Eina_Bool quit_option = EINA_FALSE;
498 Eina_Bool hold = EINA_FALSE;
499 Eina_Bool single = EINA_FALSE; 798 Eina_Bool single = EINA_FALSE;
500 Eina_Bool cmd_options = EINA_FALSE; 799 Eina_Bool cmd_options = EINA_FALSE;
501 Eina_Bool xterm_256color = EINA_FALSE; 800 Ipc_Instance instance = {
801 .login_shell = 0xff, /* unset */
802 .active_links = 0xff, /* unset */
803 .video_mute = 0xff, /* unset */
804 .cursor_blink = 0xff, /* unset */
805 .visual_bell = 0xff, /* unset */
806 .startup_id = getenv("DESKTOP_STARTUP_ID"),
807 .w = 1,
808 .h = 1,
809 };
502 Ecore_Getopt_Value values[] = { 810 Ecore_Getopt_Value values[] = {
503 ECORE_GETOPT_VALUE_BOOL(cmd_options), 811 ECORE_GETOPT_VALUE_BOOL(cmd_options),
504 ECORE_GETOPT_VALUE_STR(cd), 812 ECORE_GETOPT_VALUE_STR(instance.cd),
505 ECORE_GETOPT_VALUE_STR(theme), 813 ECORE_GETOPT_VALUE_STR(instance.theme),
506 ECORE_GETOPT_VALUE_STR(background), 814 ECORE_GETOPT_VALUE_STR(instance.background),
507 ECORE_GETOPT_VALUE_STR(geometry), 815 ECORE_GETOPT_VALUE_STR(geometry),
508 ECORE_GETOPT_VALUE_STR(name), 816 ECORE_GETOPT_VALUE_STR(instance.name),
509 ECORE_GETOPT_VALUE_STR(role), 817 ECORE_GETOPT_VALUE_STR(instance.role),
510 ECORE_GETOPT_VALUE_STR(title), 818 ECORE_GETOPT_VALUE_STR(instance.title),
511 ECORE_GETOPT_VALUE_STR(icon_name), 819 ECORE_GETOPT_VALUE_STR(instance.icon_name),
512 ECORE_GETOPT_VALUE_STR(font), 820 ECORE_GETOPT_VALUE_STR(instance.font),
513 ECORE_GETOPT_VALUE_STR(startup_split), 821 ECORE_GETOPT_VALUE_STR(instance.startup_split),
514 ECORE_GETOPT_VALUE_STR(video_module), 822 ECORE_GETOPT_VALUE_STR(video_module),
515 823
516 ECORE_GETOPT_VALUE_BOOL(login_shell), 824 ECORE_GETOPT_VALUE_BOOL(instance.login_shell),
517 ECORE_GETOPT_VALUE_BOOL(video_mute), 825 ECORE_GETOPT_VALUE_BOOL(instance.video_mute),
518 ECORE_GETOPT_VALUE_BOOL(cursor_blink), 826 ECORE_GETOPT_VALUE_BOOL(instance.cursor_blink),
519 ECORE_GETOPT_VALUE_BOOL(visual_bell), 827 ECORE_GETOPT_VALUE_BOOL(instance.visual_bell),
520 ECORE_GETOPT_VALUE_BOOL(fullscreen), 828 ECORE_GETOPT_VALUE_BOOL(instance.fullscreen),
521 ECORE_GETOPT_VALUE_BOOL(iconic), 829 ECORE_GETOPT_VALUE_BOOL(instance.iconic),
522 ECORE_GETOPT_VALUE_BOOL(borderless), 830 ECORE_GETOPT_VALUE_BOOL(instance.borderless),
523 ECORE_GETOPT_VALUE_BOOL(override), 831 ECORE_GETOPT_VALUE_BOOL(instance.override),
524 ECORE_GETOPT_VALUE_BOOL(maximized), 832 ECORE_GETOPT_VALUE_BOOL(instance.maximized),
525 ECORE_GETOPT_VALUE_BOOL(nowm), 833 ECORE_GETOPT_VALUE_BOOL(instance.nowm),
526 ECORE_GETOPT_VALUE_BOOL(hold), 834 ECORE_GETOPT_VALUE_BOOL(instance.hold),
527 ECORE_GETOPT_VALUE_BOOL(single), 835 ECORE_GETOPT_VALUE_BOOL(single),
528 ECORE_GETOPT_VALUE_BOOL(xterm_256color), 836 ECORE_GETOPT_VALUE_BOOL(instance.xterm_256color),
529 ECORE_GETOPT_VALUE_BOOL(active_links), 837 ECORE_GETOPT_VALUE_BOOL(instance.active_links),
530 838
531 ECORE_GETOPT_VALUE_BOOL(quit_option), 839 ECORE_GETOPT_VALUE_BOOL(quit_option),
532 ECORE_GETOPT_VALUE_BOOL(quit_option), 840 ECORE_GETOPT_VALUE_BOOL(quit_option),
@@ -535,16 +843,8 @@ elm_main(int argc, char **argv)
535 843
536 ECORE_GETOPT_VALUE_NONE 844 ECORE_GETOPT_VALUE_NONE
537 }; 845 };
538 Win *wn;
539 Term *term;
540 Config *config = NULL;
541 Evas_Object *win;
542 int args, retval = EXIT_SUCCESS; 846 int args, retval = EXIT_SUCCESS;
543 int remote_try = 0; 847 Eina_Bool size_set = EINA_FALSE;
544 int pos_set = 0, size_set = 0;
545 int pos_x = 0, pos_y = 0;
546 int size_w = 1, size_h = 1;
547 Eina_List *cmds_list = NULL;
548 848
549 terminology_starting_up = EINA_TRUE; 849 terminology_starting_up = EINA_TRUE;
550 850
@@ -590,9 +890,12 @@ elm_main(int argc, char **argv)
590 goto end; 890 goto end;
591 } 891 }
592 892
893 ecore_con_init();
894 ecore_con_url_init();
895
593 ipc_init(); 896 ipc_init();
594 897
595 config = config_fork(_main_config); 898 instance.config = config_fork(_main_config);
596 899
597 args = ecore_getopt_parse(&options, values, argc, argv); 900 args = ecore_getopt_parse(&options, values, argc, argv);
598 if (args < 0) 901 if (args < 0)
@@ -606,6 +909,7 @@ elm_main(int argc, char **argv)
606 909
607 if (cmd_options) 910 if (cmd_options)
608 { 911 {
912 Eina_List *cmds_list = NULL;
609 int i; 913 int i;
610 914
611 if (args == argc) 915 if (args == argc)
@@ -615,11 +919,11 @@ elm_main(int argc, char **argv)
615 goto end; 919 goto end;
616 } 920 }
617 921
618 if (startup_split) 922 if (instance.startup_split)
619 { 923 {
620 for(i = args+1; i < argc; i++) 924 for(i = args+1; i < argc; i++)
621 cmds_list = eina_list_append(cmds_list, argv[i]); 925 cmds_list = eina_list_append(cmds_list, argv[i]);
622 cmd = argv[args]; 926 instance.cmd = argv[args];
623 } 927 }
624 else 928 else
625 { 929 {
@@ -631,86 +935,15 @@ elm_main(int argc, char **argv)
631 eina_strbuf_append_char(strb, ' '); 935 eina_strbuf_append_char(strb, ' ');
632 eina_strbuf_append(strb, argv[i]); 936 eina_strbuf_append(strb, argv[i]);
633 } 937 }
634 cmd = eina_strbuf_string_steal(strb); 938 instance.cmd = eina_strbuf_string_steal(strb);
635 eina_strbuf_free(strb); 939 eina_strbuf_free(strb);
636 } 940 }
637 } 941 }
638 942
639 _check_multisense(); 943 _check_multisense();
640 944
641 if (theme) 945 _configure_instance(&instance);
642 {
643 char path[PATH_MAX];
644 char theme_name[PATH_MAX];
645 const char *theme_path = (const char *)&path;
646
647 if (eina_str_has_suffix(theme, ".edj"))
648 eina_strlcpy(theme_name, theme, sizeof(theme_name));
649 else
650 snprintf(theme_name, sizeof(theme_name), "%s.edj", theme);
651
652 if (strchr(theme_name, '/'))
653 eina_strlcpy(path, theme_name, sizeof(path));
654 else
655 theme_path = theme_path_get(theme_name);
656 946
657 eina_stringshare_replace(&(config->theme), theme_path);
658 config->temporary = EINA_TRUE;
659 }
660
661 if (background)
662 {
663 eina_stringshare_replace(&(config->background), background);
664 config->temporary = EINA_TRUE;
665 }
666
667 if (font)
668 {
669 char *p = strchr(font, '/');
670 if (p)
671 {
672 int sz;
673 char *fname = alloca(p - font + 1);
674
675 strncpy(fname, font, p - font);
676 fname[p - font] = '\0';
677 sz = atoi(p+1);
678 if (sz > 0) config->font.size = sz;
679 eina_stringshare_replace(&(config->font.name), fname);
680 config->font.bitmap = 0;
681 config->font_set = 1;
682 }
683 else
684 {
685 char buf[4096], *file;
686 Eina_List *files;
687 int n = strlen(font);
688 Eina_Bool found = EINA_FALSE;
689
690 snprintf(buf, sizeof(buf), "%s/fonts", elm_app_data_dir_get());
691 files = ecore_file_ls(buf);
692 EINA_LIST_FREE(files, file)
693 {
694 if (n > 0)
695 {
696 if (!strncasecmp(file, font, n))
697 {
698 n = -1;
699 eina_stringshare_replace(&(config->font.name), file);
700 config->font.bitmap = 1;
701 config->font_set = 1;
702 found = EINA_TRUE;
703 }
704 }
705 free(file);
706 }
707 if (!found)
708 {
709 ERR("font '%s' not found in %s", font, buf);
710 }
711 }
712 config->temporary = EINA_TRUE;
713 }
714 947
715 if (video_module) 948 if (video_module)
716 { 949 {
@@ -723,270 +956,109 @@ elm_main(int argc, char **argv)
723 956
724 if (i == EINA_C_ARRAY_LENGTH(emotion_choices)) 957 if (i == EINA_C_ARRAY_LENGTH(emotion_choices))
725 i = 0; /* ecore getopt shouldn't let this happen, but... */ 958 i = 0; /* ecore getopt shouldn't let this happen, but... */
726 config->vidmod = i; 959 instance.config->vidmod = i;
727 config->temporary = EINA_TRUE; 960 instance.config->temporary = EINA_TRUE;
728 } 961 }
729 962
730 if (video_mute != 0xff)
731 {
732 config->mute = video_mute;
733 config->temporary = EINA_TRUE;
734 }
735 if (cursor_blink != 0xff)
736 {
737 config->disable_cursor_blink = !cursor_blink;
738 config->temporary = EINA_TRUE;
739 }
740 if (visual_bell != 0xff)
741 {
742 config->disable_visual_bell = !visual_bell;
743 config->temporary = EINA_TRUE;
744 }
745 if (active_links != 0xff)
746 {
747 config->active_links = !!active_links;
748 config->active_links_email = config->active_links;
749 config->active_links_file = config->active_links;
750 config->active_links_url = config->active_links;
751 config->active_links_escape = config->active_links;
752 config->temporary = EINA_TRUE;
753 }
754
755 if (xterm_256color)
756 {
757 config->xterm_256color = EINA_TRUE;
758 config->temporary = EINA_TRUE;
759 }
760 963
761 if (geometry) 964 if (geometry)
762 { 965 {
763 if (sscanf(geometry,"%ix%i+%i+%i", &size_w, &size_h, &pos_x, &pos_y) == 4) 966 if (sscanf(geometry,"%ix%i+%i+%i", &instance.w, &instance.h,
967 &instance.x, &instance.y) == 4)
764 { 968 {
765 pos_set = 1; 969 instance.pos = EINA_TRUE;
766 size_set = 1; 970 size_set = EINA_TRUE;
767 } 971 }
768 else if (sscanf(geometry,"%ix%i-%i+%i", &size_w, &size_h, &pos_x, &pos_y) == 4) 972 else if (sscanf(geometry,"%ix%i-%i+%i", &instance.w, &instance.h,
973 &instance.x, &instance.y) == 4)
769 { 974 {
770 pos_x = -pos_x; 975 instance.x = -instance.x;
771 pos_set = 1; 976 instance.pos = EINA_TRUE;
772 size_set = 1; 977 size_set = EINA_TRUE;
773 } 978 }
774 else if (sscanf(geometry,"%ix%i-%i-%i", &size_w, &size_h, &pos_x, &pos_y) == 4) 979 else if (sscanf(geometry,"%ix%i-%i-%i", &instance.w, &instance.h,
980 &instance.x, &instance.y) == 4)
775 { 981 {
776 pos_x = -pos_x; 982 instance.x = -instance.x;
777 pos_y = -pos_y; 983 instance.y = -instance.y;
778 pos_set = 1; 984 instance.pos = EINA_TRUE;
779 size_set = 1; 985 size_set = EINA_TRUE;
780 } 986 }
781 else if (sscanf(geometry,"%ix%i+%i-%i", &size_w, &size_h, &pos_x, &pos_y) == 4) 987 else if (sscanf(geometry,"%ix%i+%i-%i", &instance.w, &instance.h,
988 &instance.x, &instance.y) == 4)
782 { 989 {
783 pos_y = -pos_y; 990 instance.y = -instance.y;
784 pos_set = 1; 991 instance.pos = EINA_TRUE;
785 size_set = 1; 992 size_set = EINA_TRUE;
786 } 993 }
787 else if (sscanf(geometry,"%ix%i", &size_w, &size_h) == 2) 994 else if (sscanf(geometry,"%ix%i", &instance.w, &instance.h) == 2)
788 { 995 {
789 size_set = 1; 996 size_set = EINA_TRUE;
790 } 997 }
791 else if (sscanf(geometry,"+%i+%i", &pos_x, &pos_y) == 2) 998 else if (sscanf(geometry,"+%i+%i", &instance.x, &instance.y) == 2)
792 { 999 {
793 pos_set = 1; 1000 instance.pos = EINA_TRUE;
794 } 1001 }
795 else if (sscanf(geometry,"-%i+%i", &pos_x, &pos_y) == 2) 1002 else if (sscanf(geometry,"-%i+%i", &instance.x, &instance.y) == 2)
796 { 1003 {
797 pos_x = -pos_x; 1004 instance.x = -instance.x;
798 pos_set = 1; 1005 instance.pos = EINA_TRUE;
799 } 1006 }
800 else if (sscanf(geometry,"+%i-%i", &pos_x, &pos_y) == 2) 1007 else if (sscanf(geometry,"+%i-%i", &instance.x, &instance.y) == 2)
801 { 1008 {
802 pos_y = -pos_y; 1009 instance.y = -instance.y;
803 pos_set = 1; 1010 instance.pos = EINA_TRUE;
804 } 1011 }
805 else if (sscanf(geometry,"-%i-%i", &pos_x, &pos_y) == 2) 1012 else if (sscanf(geometry,"-%i-%i", &instance.x, &instance.y) == 2)
806 { 1013 {
807 pos_x = -pos_x; 1014 instance.x = -instance.x;
808 pos_y = -pos_y; 1015 instance.y = -instance.y;
809 pos_set = 1; 1016 instance.pos = EINA_TRUE;
810 } 1017 }
811 } 1018 }
812 1019
813 if (!size_set) 1020 if (!size_set)
814 { 1021 {
815 if (config->custom_geometry) 1022 if (instance.config->custom_geometry)
816 { 1023 {
817 size_w = config->cg_width; 1024 instance.w = instance.config->cg_width;
818 size_h = config->cg_height; 1025 instance.h = instance.config->cg_height;
819 } 1026 }
820 else 1027 else
821 { 1028 {
822 size_w = 80; 1029 instance.w = 80;
823 size_h = 24; 1030 instance.h = 24;
824 } 1031 }
825 } 1032 }
826 1033
827 if (login_shell != 0xff) 1034 elm_theme_overlay_add(NULL,
828 { 1035 config_theme_path_default_get(instance.config));
829 config->login_shell = login_shell; 1036 elm_theme_overlay_add(NULL, config_theme_path_get(instance.config));
830 config->temporary = EINA_TRUE;
831 }
832 login_shell = config->login_shell;
833
834 elm_theme_overlay_add(NULL, config_theme_path_default_get(config));
835 elm_theme_overlay_add(NULL, config_theme_path_get(config));
836 1037
837remote: 1038 if ((!single) && (instance.config->multi_instance))
838 if ((!single) && (config->multi_instance))
839 { 1039 {
840 Ipc_Instance inst;
841 char cwdbuf[4096]; 1040 char cwdbuf[4096];
842 1041
843 memset(&inst, 0, sizeof(Ipc_Instance)); 1042 if (!instance.cd)
844 1043 instance.cd = getcwd(cwdbuf, sizeof(cwdbuf));
845 inst.cmd = cmd; 1044 if (_start_multi(&instance, argv))
846 if (cd) inst.cd = cd;
847 else inst.cd = getcwd(cwdbuf, sizeof(cwdbuf));
848 inst.background = background;
849 inst.name = name;
850 inst.role = role;
851 inst.title = title;
852 inst.icon_name = icon_name;
853 inst.font = font;
854 inst.startup_id = getenv("DESKTOP_STARTUP_ID");
855 inst.x = pos_x;
856 inst.y = pos_y;
857 inst.w = size_w;
858 inst.h = size_h;
859 inst.pos = pos_set;
860 inst.login_shell = login_shell;
861 inst.fullscreen = fullscreen;
862 inst.iconic = iconic;
863 inst.borderless = borderless;
864 inst.override = override;
865 inst.maximized = maximized;
866 inst.hold = hold;
867 inst.nowm = nowm;
868 inst.startup_split = startup_split;
869 if (ipc_instance_add(&inst))
870 goto end; 1045 goto end;
871 } 1046 }
872 if ((!single) && (config->multi_instance)) 1047 else
873 {
874 ipc_instance_new_func_set(main_ipc_new);
875 if (!ipc_serve())
876 {
877 if (remote_try < 1)
878 {
879 remote_try++;
880 goto remote;
881 }
882 }
883 }
884
885 wn = win_new(name, role, title, icon_name, config,
886 fullscreen, iconic, borderless, override, maximized);
887 // set an env so terminal apps can detect they are in terminology :)
888 putenv("TERMINOLOGY=1");
889 unsetenv("DESKTOP_STARTUP_ID");
890
891 config_del(config);
892 config = NULL;
893 if (!wn)
894 {
895 CRITICAL(_("Could not create window."));
896 retval = EXIT_FAILURE;
897 goto end;
898 }
899
900 config = win_config_get(wn);
901
902 term = term_new(wn, config, cmd, login_shell, cd,
903 size_w, size_h, hold, title);
904 if (!term)
905 { 1048 {
906 CRITICAL(_("Could not create terminal widget.")); 1049 _start(&instance);
907 config = NULL;
908 retval = EXIT_FAILURE;
909 goto end;
910 }
911
912 if (win_term_set(wn, term) < 0)
913 {
914 retval = EXIT_FAILURE;
915 goto end;
916 } 1050 }
917
918 main_trans_update(config);
919 main_media_update(config);
920 win_sizing_handle(wn);
921 win = win_evas_object_get(wn);
922 evas_object_show(win);
923 if (startup_split)
924 {
925 unsigned int i = 0;
926 Term *next = term;
927
928 for (i = 0; i < strlen(startup_split); i++)
929 {
930 if (startup_split[i] == 'v')
931 {
932 cmd = cmds_list ? cmds_list->data : NULL;
933 split_vertically(win_evas_object_get(term_win_get(next)),
934 term_termio_get(next), cmd);
935 cmds_list = eina_list_remove_list(cmds_list, cmds_list);
936 }
937 else if (startup_split[i] == 'h')
938 {
939 cmd = cmds_list ? cmds_list->data : NULL;
940 split_horizontally(win_evas_object_get(term_win_get(next)),
941 term_termio_get(next), cmd);
942 cmds_list = eina_list_remove_list(cmds_list, cmds_list);
943 }
944 else if (startup_split[i] == '-')
945 next = term_next_get(next);
946 else
947 {
948 CRITICAL(_("invalid argument found for option -S/--split."
949 " See --help."));
950 goto end;
951 }
952 }
953 if (cmds_list)
954 eina_list_free(cmds_list);
955 }
956 if (pos_set)
957 {
958 int screen_w, screen_h;
959
960 elm_win_screen_size_get(win, NULL, NULL, &screen_w, &screen_h);
961 if (pos_x < 0) pos_x = screen_w + pos_x;
962 if (pos_y < 0) pos_y = screen_h + pos_y;
963 evas_object_move(win, pos_x, pos_y);
964 }
965 if (nowm)
966 ecore_evas_focus_set(ecore_evas_ecore_evas_get(
967 evas_object_evas_get(win)), 1);
968
969 ecore_con_init();
970 ecore_con_url_init();
971
972 controls_init();
973
974 win_scale_wizard(win, term);
975
976 terminology_starting_up = EINA_FALSE;
977
978 elm_run(); 1051 elm_run();
979 1052
980 ecore_con_url_shutdown(); 1053 ecore_con_url_shutdown();
981 ecore_con_shutdown(); 1054 ecore_con_shutdown();
982 1055
983 config = NULL; 1056 instance.config = NULL;
984 end: 1057 end:
985 if (!startup_split) free(cmd); 1058 if (instance.config)
986 if (config)
987 { 1059 {
988 config_del(config); 1060 config_del(instance.config);
989 config = NULL; 1061 instance.config = NULL;
990 } 1062 }
991 1063
992 ipc_shutdown(); 1064 ipc_shutdown();
diff --git a/src/bin/main.h b/src/bin/main.h
index 1a961d4..e870b32 100644
--- a/src/bin/main.h
+++ b/src/bin/main.h
@@ -4,7 +4,7 @@
4#include "config.h" 4#include "config.h"
5 5
6Config * main_config_get(void); 6Config * main_config_get(void);
7void main_new(Evas_Object *win, Evas_Object *term); 7void main_new(Evas_Object *term);
8void main_new_with_dir(Evas_Object *win, Evas_Object *term, const char *wdir); 8void main_new_with_dir(Evas_Object *win, Evas_Object *term, const char *wdir);
9void main_split_h(Evas_Object *win, Evas_Object *term, const char *cmd); 9void main_split_h(Evas_Object *win, Evas_Object *term, const char *cmd);
10void main_split_v(Evas_Object *win, Evas_Object *term, const char *cmd); 10void main_split_v(Evas_Object *win, Evas_Object *term, const char *cmd);
diff --git a/src/bin/media.c b/src/bin/media.c
index b43eadc..28bfd2b 100644
--- a/src/bin/media.c
+++ b/src/bin/media.c
@@ -1248,7 +1248,6 @@ media_add(Evas_Object *parent, const char *src, const Config *config, int mode,
1248 if (!_smart) _smart_init(); 1248 if (!_smart) _smart_init();
1249 obj = evas_object_smart_add(e, _smart); 1249 obj = evas_object_smart_add(e, _smart);
1250 sd = evas_object_smart_data_get(obj); 1250 sd = evas_object_smart_data_get(obj);
1251 if (!sd) return obj;
1252 1251
1253 sd->src = eina_stringshare_add(src); 1252 sd->src = eina_stringshare_add(src);
1254 sd->config = config; 1253 sd->config = config;
diff --git a/src/bin/termio.c b/src/bin/termio.c
index dea782e..f366cb5 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -1043,8 +1043,7 @@ _getsel_cb(void *data,
1043 int prev_i = i; 1043 int prev_i = i;
1044 g = eina_unicode_utf8_next_get(s, &i); 1044 g = eina_unicode_utf8_next_get(s, &i);
1045 /* Skip escape codes as a security measure */ 1045 /* Skip escape codes as a security measure */
1046 if ((g < '\n') || 1046 if (! ((g == '\t') || (g == '\n') || (g >= ' ')))
1047 ((g > '\n') && (g < ' ')))
1048 { 1047 {
1049 continue; 1048 continue;
1050 } 1049 }
@@ -1074,9 +1073,9 @@ _getsel_cb(void *data,
1074 const char *fmt = "UNKNOWN"; 1073 const char *fmt = "UNKNOWN";
1075 switch (ev->format) 1074 switch (ev->format)
1076 { 1075 {
1077 case ELM_SEL_FORMAT_TARGETS: fmt = "TARGETS"; break; /* shouldn't happen */ 1076 case ELM_SEL_FORMAT_TARGETS: fmt = "TARGETS"; break;
1078 case ELM_SEL_FORMAT_NONE: fmt = "NONE"; break; 1077 case ELM_SEL_FORMAT_NONE: fmt = "NONE"; break;
1079 case ELM_SEL_FORMAT_TEXT: fmt = "TEXT"; break; 1078 case ELM_SEL_FORMAT_TEXT: fmt = "TEXT"; break; /* shouldn't happen */
1080 case ELM_SEL_FORMAT_MARKUP: fmt = "MARKUP"; break; 1079 case ELM_SEL_FORMAT_MARKUP: fmt = "MARKUP"; break;
1081 case ELM_SEL_FORMAT_IMAGE: fmt = "IMAGE"; break; 1080 case ELM_SEL_FORMAT_IMAGE: fmt = "IMAGE"; break;
1082 case ELM_SEL_FORMAT_VCARD: fmt = "VCARD"; break; 1081 case ELM_SEL_FORMAT_VCARD: fmt = "VCARD"; break;
diff --git a/src/bin/termiointernals.c b/src/bin/termiointernals.c
index 555c27a..598c724 100644
--- a/src/bin/termiointernals.c
+++ b/src/bin/termiointernals.c
@@ -21,6 +21,16 @@ termio_selection_get(Termio *sd,
21{ 21{
22 int x, y; 22 int x, y;
23 23
24#define SB_ADD(STR, LEN) do { \
25 if (ty_sb_add(sb, STR, LEN) < 0) \
26 goto err; \
27} while (0)
28
29#define RTRIM() do { \
30 if (rtrim) \
31 ty_sb_spaces_rtrim(sb); \
32} while (0)
33
24 termpty_backlog_lock(); 34 termpty_backlog_lock();
25 for (y = c1y; y <= c2y; y++) 35 for (y = c1y; y <= c2y; y++)
26 { 36 {
@@ -33,51 +43,91 @@ termio_selection_get(Termio *sd,
33 cells = termpty_cellrow_get(sd->pty, y, &w); 43 cells = termpty_cellrow_get(sd->pty, y, &w);
34 if (!cells || !w) 44 if (!cells || !w)
35 { 45 {
36 if (ty_sb_add(sb, "\n", 1) < 0) goto err; 46 SB_ADD("\n", 1);
37 continue; 47 continue;
38 } 48 }
39 if (w > sd->grid.w) w = sd->grid.w; 49
50 /* Define how much needs to be read on that line */
51 if (w > sd->grid.w)
52 w = sd->grid.w;
40 if (y == c1y && c1x >= w) 53 if (y == c1y && c1x >= w)
41 { 54 {
42 if (rtrim) 55 RTRIM();
43 ty_sb_spaces_rtrim(sb); 56 SB_ADD("\n", 1);
44 if (ty_sb_add(sb, "\n", 1) < 0) goto err;
45 continue; 57 continue;
46 } 58 }
47 start_x = c1x; 59 start_x = c1x;
48 end_x = (c2x >= w) ? w - 1 : c2x; 60 end_x = (c2x >= w) ? w - 1 : c2x;
49 if (c1y != c2y) 61 if (c1y != c2y)
50 { 62 {
51 if (y == c1y) end_x = w - 1; 63 if (y == c1y)
52 else if (y == c2y) start_x = 0; 64 end_x = w - 1;
65 else if (y == c2y)
66 start_x = 0;
53 else 67 else
54 { 68 {
55 start_x = 0; 69 start_x = 0;
56 end_x = w - 1; 70 end_x = w - 1;
57 } 71 }
58 } 72 }
73
59 for (x = start_x; x <= end_x; x++) 74 for (x = start_x; x <= end_x; x++)
60 { 75 {
61 if ((cells[x].codepoint == 0) && (cells[x].att.dblwidth)) 76 if ((cells[x].codepoint == 0) && (cells[x].att.dblwidth))
62 { 77 {
63 if (x < end_x) x++; 78 if (x < end_x)
64 else break; 79 x++;
80 else
81 break;
82 }
83 if (x >= w)
84 break;
85 if (cells[x].att.tab_inserted)
86 {
87 /* There was a tab inserted.
88 * Only output it if there were spaces/empty cells "bellow"
89 */
90 Eina_Bool is_tab = EINA_TRUE;
91 while ((is_tab) && (x < end_x))
92 {
93 if (((cells[x].codepoint == 0) ||
94 (cells[x].att.invisible == 1) ||
95 (cells[x].codepoint == ' ')))
96 {
97 x++;
98 }
99 else
100 {
101 is_tab = EINA_FALSE;
102 }
103 if (cells[x].att.tab_last)
104 {
105 SB_ADD("\t", 1);
106 if (is_tab)
107 {
108 x++;
109 is_tab = EINA_FALSE;
110 }
111 break;
112 }
113 }
65 } 114 }
66 if (x >= w) break;
67 if (cells[x].att.newline) 115 if (cells[x].att.newline)
68 { 116 {
69 last0 = -1; 117 last0 = -1;
70 if ((y != c2y) || (x != end_x)) 118 if ((y != c2y) || (x != end_x))
71 { 119 {
72 if (rtrim) 120 RTRIM();
73 ty_sb_spaces_rtrim(sb); 121 SB_ADD("\n", 1);
74 if (ty_sb_add(sb, "\n", 1) < 0) goto err;
75 } 122 }
76 break; 123 break;
77 } 124 }
78 else if (cells[x].codepoint == 0) 125 else if (cells[x].codepoint == 0)
79 { 126 {
80 if (last0 < 0) last0 = x; 127 /* empty cell, track it to know whether to replace with
128 * spaces */
129 if (last0 < 0)
130 last0 = x;
81 } 131 }
82 else 132 else
83 { 133 {
@@ -90,27 +140,28 @@ termio_selection_get(Termio *sd,
90 last0 = -1; 140 last0 = -1;
91 while (v >= 0) 141 while (v >= 0)
92 { 142 {
93 if (ty_sb_add(sb, " ", 1) < 0) goto err; 143 SB_ADD(" ", 1);
94 v--; 144 v--;
95 } 145 }
96 } 146 }
97 txtlen = codepoint_to_utf8(cells[x].codepoint, txt); 147 txtlen = codepoint_to_utf8(cells[x].codepoint, txt);
98 if (txtlen > 0) 148 if (txtlen > 0)
99 if (ty_sb_add(sb, txt, txtlen) < 0) goto err; 149 SB_ADD(txt, txtlen);
100 if ((x == (w - 1)) && 150 if ((x == (w - 1)) &&
101 ((x != c2x) || (y != c2y))) 151 ((x != c2x) || (y != c2y)))
102 { 152 {
103 if (!cells[x].att.autowrapped) 153 if (!cells[x].att.autowrapped)
104 { 154 {
105 if (rtrim) 155 RTRIM();
106 ty_sb_spaces_rtrim(sb); 156 SB_ADD("\n", 1);
107 if (ty_sb_add(sb, "\n", 1) < 0) goto err;
108 } 157 }
109 } 158 }
110 } 159 }
111 } 160 }
112 if (last0 >= 0) 161 if (last0 >= 0)
113 { 162 {
163 /* line stop by empty cell, need to know whether to insert spaces
164 * or just go to next line */
114 if (y == c2y) 165 if (y == c2y)
115 { 166 {
116 Eina_Bool have_more = EINA_FALSE; 167 Eina_Bool have_more = EINA_FALSE;
@@ -120,8 +171,10 @@ termio_selection_get(Termio *sd,
120 if ((cells[x].codepoint == 0) && 171 if ((cells[x].codepoint == 0) &&
121 (cells[x].att.dblwidth)) 172 (cells[x].att.dblwidth))
122 { 173 {
123 if (x < (w - 1)) x++; 174 if (x < (w - 1))
124 else break; 175 x++;
176 else
177 break;
125 } 178 }
126 if (((cells[x].codepoint != 0) && 179 if (((cells[x].codepoint != 0) &&
127 (cells[x].codepoint != ' ')) || 180 (cells[x].codepoint != ' ')) ||
@@ -133,9 +186,8 @@ termio_selection_get(Termio *sd,
133 } 186 }
134 if (!have_more) 187 if (!have_more)
135 { 188 {
136 if (rtrim) 189 RTRIM();
137 ty_sb_spaces_rtrim(sb); 190 SB_ADD("\n", 1);
138 if (ty_sb_add(sb, "\n", 1) < 0) goto err;
139 } 191 }
140 else 192 else
141 { 193 {
@@ -144,31 +196,34 @@ termio_selection_get(Termio *sd,
144 if ((cells[x].codepoint == 0) && 196 if ((cells[x].codepoint == 0) &&
145 (cells[x].att.dblwidth)) 197 (cells[x].att.dblwidth))
146 { 198 {
147 if (x < (w - 1)) x++; 199 if (x < (w - 1))
148 else break; 200 x++;
201 else
202 break;
149 } 203 }
150 if (x >= w) break; 204 if (x >= w)
151 if (ty_sb_add(sb, " ", 1) < 0) goto err; 205 break;
206 SB_ADD(" ", 1);
152 } 207 }
153 } 208 }
154 } 209 }
155 else 210 else
156 { 211 {
157 if (rtrim) 212 RTRIM();
158 ty_sb_spaces_rtrim(sb); 213 SB_ADD("\n", 1);
159 if (ty_sb_add(sb, "\n", 1) < 0) goto err;
160 } 214 }
161 } 215 }
162 } 216 }
163 termpty_backlog_unlock(); 217 termpty_backlog_unlock();
164 218
165 if (rtrim) 219 RTRIM();
166 ty_sb_spaces_rtrim(sb);
167 220
168 return; 221 return;
169 222
170err: 223err:
171 ty_sb_free(sb); 224 ty_sb_free(sb);
225#undef SB_ADD
226#undef RTRIM
172} 227}
173 228
174 229
@@ -1305,8 +1360,6 @@ _selection_newline_extend_fix(Termio *sd)
1305 termpty_backlog_unlock(); 1360 termpty_backlog_unlock();
1306} 1361}
1307 1362
1308/* }}} */
1309
1310void 1363void
1311termio_selection_dbl_fix(Termio *sd) 1364termio_selection_dbl_fix(Termio *sd)
1312{ 1365{
@@ -1393,6 +1446,7 @@ termio_selection_dbl_fix(Termio *sd)
1393 sd->pty->selection.end.y = end_y; 1446 sd->pty->selection.end.y = end_y;
1394} 1447}
1395 1448
1449/* }}} */
1396 1450
1397static void 1451static void
1398_handle_mouse_down_single_click(Termio *sd, 1452_handle_mouse_down_single_click(Termio *sd,
diff --git a/src/bin/termpty.h b/src/bin/termpty.h
index ef07cb9..ca1605c 100644
--- a/src/bin/termpty.h
+++ b/src/bin/termpty.h
@@ -81,12 +81,14 @@ struct _Termatt
81 unsigned short fraktur : 1; 81 unsigned short fraktur : 1;
82 unsigned short framed : 1; 82 unsigned short framed : 1;
83 unsigned short encircled : 1; 83 unsigned short encircled : 1;
84 unsigned short overlined : 1; 84 unsigned short overlined : 1; // TODO: support it
85 unsigned short tab_inserted : 1;
86 unsigned short tab_last : 1;
85#if defined(SUPPORT_80_132_COLUMNS) 87#if defined(SUPPORT_80_132_COLUMNS)
86 unsigned short is_80_132_mode_allowed : 1; 88 unsigned short is_80_132_mode_allowed : 1;
87 unsigned short bit_padding : 11; 89 unsigned short bit_padding : 9;
88#else 90#else
89 unsigned short bit_padding : 12; 91 unsigned short bit_padding : 10;
90#endif 92#endif
91 uint16_t link_id; 93 uint16_t link_id;
92}; 94};
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index a92b4db..25da608 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -207,6 +207,8 @@ _cursor_to_start_of_line(Termpty *ty)
207static void 207static void
208_handle_cursor_control(Termpty *ty, const Eina_Unicode *cc) 208_handle_cursor_control(Termpty *ty, const Eina_Unicode *cc)
209{ 209{
210 Termcell *cell;
211
210 switch (*cc) 212 switch (*cc)
211 { 213 {
212 case 0x07: // BEL '\a' (bell) 214 case 0x07: // BEL '\a' (bell)
@@ -220,7 +222,11 @@ _handle_cursor_control(Termpty *ty, const Eina_Unicode *cc)
220 return; 222 return;
221 case 0x09: // HT '\t' (horizontal tab) 223 case 0x09: // HT '\t' (horizontal tab)
222 DBG("->HT"); 224 DBG("->HT");
225 cell = &(TERMPTY_SCREEN(ty, ty->cursor_state.cx, ty->cursor_state.cy));
226 cell->att.tab_inserted = 1;
223 _tab_forward(ty, 1); 227 _tab_forward(ty, 1);
228 cell = &(TERMPTY_SCREEN(ty, ty->cursor_state.cx -1, ty->cursor_state.cy));
229 cell->att.tab_last = 1;
224 return; 230 return;
225 case 0x0a: // LF '\n' (new line) 231 case 0x0a: // LF '\n' (new line)
226 case 0x0b: // VT '\v' (vertical tab) 232 case 0x0b: // VT '\v' (vertical tab)
@@ -3412,7 +3418,7 @@ _eina_unicode_to_hex(Eina_Unicode u)
3412 return -1; 3418 return -1;
3413} 3419}
3414 3420
3415#if defined(__OpenBSD__) 3421#if !defined(HAVE_STRCHRNUL)
3416char * 3422char *
3417strchrnul(const char *s, int c) 3423strchrnul(const char *s, int c)
3418{ 3424{
diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c
index dfc7558..27c4399 100644
--- a/src/bin/termptyops.c
+++ b/src/bin/termptyops.c
@@ -427,6 +427,8 @@ termpty_reset_att(Termatt *att)
427 att->framed = 0; 427 att->framed = 0;
428 att->encircled = 0; 428 att->encircled = 0;
429 att->overlined = 0; 429 att->overlined = 0;
430 att->tab_inserted = 0;
431 att->tab_last = 0;
430} 432}
431 433
432void 434void
diff --git a/src/bin/win.c b/src/bin/win.c
index b155676..56d44a8 100644
--- a/src/bin/win.c
+++ b/src/bin/win.c
@@ -91,7 +91,6 @@ struct _Term
91 Evas_Object *sendfile_request; 91 Evas_Object *sendfile_request;
92 Evas_Object *sendfile_progress; 92 Evas_Object *sendfile_progress;
93 Evas_Object *sendfile_progress_bar; 93 Evas_Object *sendfile_progress_bar;
94 Evas_Object *tabcount_spacer;
95 Evas_Object *tab_spacer; 94 Evas_Object *tab_spacer;
96 Evas_Object *tab_region_base; 95 Evas_Object *tab_region_base;
97 Evas_Object *tab_region_bg; 96 Evas_Object *tab_region_bg;
@@ -3324,6 +3323,7 @@ _tabs_close(Term_Container *tc, Term_Container *child)
3324 3323
3325 l = _tab_item_find(tabs, child); 3324 l = _tab_item_find(tabs, child);
3326 item = l->data; 3325 item = l->data;
3326 tabs->tabs = eina_list_remove_list(tabs->tabs, l);
3327 3327
3328 next = eina_list_next(l); 3328 next = eina_list_next(l);
3329 if (!next) 3329 if (!next)
@@ -3331,7 +3331,6 @@ _tabs_close(Term_Container *tc, Term_Container *child)
3331 next_item = next->data; 3331 next_item = next->data;
3332 next_child = next_item->tc; 3332 next_child = next_item->tc;
3333 assert (next_child->type == TERM_CONTAINER_TYPE_SOLO); 3333 assert (next_child->type == TERM_CONTAINER_TYPE_SOLO);
3334 tabs->tabs = eina_list_remove_list(tabs->tabs, l);
3335 3334
3336 assert (child->type == TERM_CONTAINER_TYPE_SOLO); 3335 assert (child->type == TERM_CONTAINER_TYPE_SOLO);
3337 solo = (Solo*)child; 3336 solo = (Solo*)child;
@@ -3353,11 +3352,13 @@ _tabs_close(Term_Container *tc, Term_Container *child)
3353 next_term = next_solo->term; 3352 next_term = next_solo->term;
3354 config = next_term->config; 3353 config = next_term->config;
3355 3354
3356 edje_object_signal_emit(next_term->bg, "tabcount,off", "terminology"); 3355 edje_object_signal_emit(term->bg, "tab_btn,off", "terminology");
3357 if (next_term->tabcount_spacer && !config->show_tabs) 3356 evas_object_del(term->tab_spacer);
3357 term->tab_spacer = NULL;
3358 if (next_term->tab_spacer && !config->show_tabs)
3358 { 3359 {
3359 evas_object_del(next_term->tabcount_spacer); 3360 evas_object_del(next_term->tab_spacer);
3360 next_term->tabcount_spacer = NULL; 3361 next_term->tab_spacer = NULL;
3361 } 3362 }
3362 if (config->show_tabs) 3363 if (config->show_tabs)
3363 _solo_title_show(next_child); 3364 _solo_title_show(next_child);
@@ -3563,10 +3564,10 @@ _tabs_swallow(Term_Container *tc, Term_Container *orig,
3563 solo = (Solo*)orig; 3564 solo = (Solo*)orig;
3564 term = solo->term; 3565 term = solo->term;
3565 edje_object_signal_emit(term->bg, "tabcount,off", "terminology"); 3566 edje_object_signal_emit(term->bg, "tabcount,off", "terminology");
3566 if (term->tabcount_spacer) 3567 if (term->tab_spacer)
3567 { 3568 {
3568 evas_object_del(term->tabcount_spacer); 3569 evas_object_del(term->tab_spacer);
3569 term->tabcount_spacer = NULL; 3570 term->tab_spacer = NULL;
3570 } 3571 }
3571 3572
3572 o = orig->get_evas_object(orig); 3573 o = orig->get_evas_object(orig);
@@ -3668,8 +3669,7 @@ _cb_close(void *data,
3668} 3669}
3669 3670
3670void 3671void
3671main_new(Evas_Object *_win EINA_UNUSED, 3672main_new(Evas_Object *term)
3672 Evas_Object *term)
3673{ 3673{
3674 Term *tm; 3674 Term *tm;
3675 3675
@@ -3873,56 +3873,48 @@ _tabs_refresh(Tabs *tabs)
3873 3873
3874 _tabbar_clear(term); 3874 _tabbar_clear(term);
3875 3875
3876 if (!term->tabcount_spacer) 3876 if (!term->tab_spacer)
3877 { 3877 {
3878 term->tabcount_spacer = evas_object_rectangle_add(evas_object_evas_get(term->bg)); 3878 term->tab_spacer = evas_object_rectangle_add(evas_object_evas_get(term->bg));
3879 evas_object_color_set(term->tabcount_spacer, 0, 0, 0, 0); 3879 evas_object_color_set(term->tab_spacer, 0, 0, 0, 0);
3880 } 3880 }
3881 elm_coords_finger_size_adjust(1, &w, 1, &h); 3881 elm_coords_finger_size_adjust(1, &w, 1, &h);
3882 evas_object_size_hint_min_set(term->tabcount_spacer, w, h); 3882 evas_object_size_hint_min_set(term->tab_spacer, w, h);
3883 edje_object_part_swallow(term->bg, "terminology.tabcount.control",
3884 term->tabcount_spacer);
3885 edje_object_part_text_set(term->bg, "terminology.tabcount.label", buf);
3886 edje_object_part_text_set(term->bg, "terminology.tabmissed.label", bufmissed);
3887 edje_object_signal_emit(term->bg, "tabcount,on", "terminology");
3888 // this is all below just for tab bar at the top 3883 // this is all below just for tab bar at the top
3889 if (term->config->show_tabs) 3884 if (term->config->show_tabs)
3890 { 3885 {
3891 double v1, v2; 3886 double v1, v2;
3892 3887
3888 edje_object_part_swallow(term->bg, "terminology.tab_btn",
3889 term->tab_spacer);
3890
3893 v1 = (double)(i-1) / (double)n; 3891 v1 = (double)(i-1) / (double)n;
3894 v2 = (double)i / (double)n; 3892 v2 = (double)i / (double)n;
3895 if (!term->tab_spacer) 3893 edje_object_signal_emit(term->bg, "tabcount,off", "terminology");
3896 { 3894
3897 term->tab_spacer = evas_object_rectangle_add( 3895 edje_object_part_swallow(term->bg, "terminology.tab", term->tab_spacer);
3898 evas_object_evas_get(term->bg)); 3896 edje_object_part_drag_value_set(term->bg, "terminology.tabl", v1, 0.0);
3899 evas_object_color_set(term->tab_spacer, 0, 0, 0, 0); 3897 edje_object_part_drag_value_set(term->bg, "terminology.tabr", v2, 0.0);
3900 elm_coords_finger_size_adjust(1, &w, 1, &h); 3898 edje_object_part_text_set(term->bg, "terminology.tab.title",
3901 evas_object_size_hint_min_set(term->tab_spacer, w, h); 3899 solo->tc.title);
3902 edje_object_part_swallow(term->bg, "terminology.tab", term->tab_spacer); 3900 edje_object_signal_emit(term->bg, "tabbar,on", "terminology");
3903 edje_object_part_drag_value_set(term->bg, "terminology.tabl", v1, 0.0); 3901 edje_object_signal_emit(term->bg, "tab_btn,on", "terminology");
3904 edje_object_part_drag_value_set(term->bg, "terminology.tabr", v2, 0.0);
3905 edje_object_part_text_set(term->bg, "terminology.tab.title",
3906 solo->tc.title);
3907 edje_object_signal_emit(term->bg, "tabbar,on", "terminology");
3908 edje_object_message_signal_process(term->bg);
3909 }
3910 else
3911 {
3912 edje_object_part_drag_value_set(term->bg, "terminology.tabl", v1, 0.0);
3913 edje_object_part_drag_value_set(term->bg, "terminology.tabr", v2, 0.0);
3914 edje_object_message_signal_process(term->bg);
3915 }
3916 _tabbar_fill(tabs); 3902 _tabbar_fill(tabs);
3917 } 3903 }
3918 else 3904 else
3919 { 3905 {
3906 edje_object_part_swallow(term->bg, "terminology.tabcount.control",
3907 term->tab_spacer);
3908 edje_object_part_text_set(term->bg, "terminology.tabcount.label", buf);
3909 edje_object_part_text_set(term->bg, "terminology.tabmissed.label", bufmissed);
3910 edje_object_signal_emit(term->bg, "tabcount,on", "terminology");
3920 _tabbar_clear(term); 3911 _tabbar_clear(term);
3912 if (missed > 0)
3913 edje_object_signal_emit(term->bg, "tabmissed,on", "terminology");
3914 else
3915 edje_object_signal_emit(term->bg, "tabmissed,off", "terminology");
3921 } 3916 }
3922 if (missed > 0) 3917 edje_object_message_signal_process(term->bg);
3923 edje_object_signal_emit(term->bg, "tabmissed,on", "terminology");
3924 else
3925 edje_object_signal_emit(term->bg, "tabmissed,off", "terminology");
3926} 3918}
3927 3919
3928static Tab_Item* 3920static Tab_Item*
@@ -5185,15 +5177,25 @@ _cb_command(void *data,
5185} 5177}
5186 5178
5187static void 5179static void
5188_cb_tabcount_go(void *data, 5180_cb_tab_go(void *data,
5189 Evas_Object *_obj EINA_UNUSED, 5181 Evas_Object *_obj EINA_UNUSED,
5190 const char *_sig EINA_UNUSED, 5182 const char *_sig EINA_UNUSED,
5191 const char *_src EINA_UNUSED) 5183 const char *_src EINA_UNUSED)
5192{ 5184{
5193 _cb_select(data, NULL, NULL); 5185 _cb_select(data, NULL, NULL);
5194} 5186}
5195 5187
5196static void 5188static void
5189_cb_tab_new(void *data,
5190 Evas_Object *_obj EINA_UNUSED,
5191 const char *_sig EINA_UNUSED,
5192 const char *_src EINA_UNUSED)
5193{
5194 Term *term = data;
5195 main_new(term->termio);
5196}
5197
5198static void
5197_cb_prev(void *data, 5199_cb_prev(void *data,
5198 Evas_Object *_obj EINA_UNUSED, 5200 Evas_Object *_obj EINA_UNUSED,
5199 void *_event EINA_UNUSED) 5201 void *_event EINA_UNUSED)
@@ -5660,16 +5662,16 @@ _term_free(Term *term)
5660 5662
5661 _term_tabregion_free(term); 5663 _term_tabregion_free(term);
5662 5664
5663 if (term->tabcount_spacer) 5665 if (term->tab_spacer)
5664 { 5666 {
5665 evas_object_del(term->tabcount_spacer); 5667 evas_object_del(term->tab_spacer);
5666 term->tabcount_spacer = NULL; 5668 term->tab_spacer = NULL;
5667 } 5669 }
5668 free(term); 5670 free(term);
5669} 5671}
5670 5672
5671static void 5673static void
5672_cb_tabcount_prev(void *data, 5674_cb_tab_prev(void *data,
5673 Evas_Object *_obj EINA_UNUSED, 5675 Evas_Object *_obj EINA_UNUSED,
5674 const char *_sig EINA_UNUSED, 5676 const char *_sig EINA_UNUSED,
5675 const char *_src EINA_UNUSED) 5677 const char *_src EINA_UNUSED)
@@ -5678,7 +5680,7 @@ _cb_tabcount_prev(void *data,
5678} 5680}
5679 5681
5680static void 5682static void
5681_cb_tabcount_next(void *data, 5683_cb_tab_next(void *data,
5682 Evas_Object *_obj EINA_UNUSED, 5684 Evas_Object *_obj EINA_UNUSED,
5683 const char *_sig EINA_UNUSED, 5685 const char *_sig EINA_UNUSED,
5684 const char *_src EINA_UNUSED) 5686 const char *_src EINA_UNUSED)
@@ -5696,12 +5698,14 @@ _term_bg_config(Term *term)
5696 termio_theme_set(term->termio, term->bg); 5698 termio_theme_set(term->termio, term->bg);
5697 edje_object_signal_callback_add(term->bg, "popmedia,done", "terminology", 5699 edje_object_signal_callback_add(term->bg, "popmedia,done", "terminology",
5698 _cb_popmedia_done, term); 5700 _cb_popmedia_done, term);
5699 edje_object_signal_callback_add(term->bg, "tabcount,go", "terminology", 5701 edje_object_signal_callback_add(term->bg, "tab,go", "terminology",
5700 _cb_tabcount_go, term); 5702 _cb_tab_go, term);
5701 edje_object_signal_callback_add(term->bg, "tabcount,prev", "terminology", 5703 edje_object_signal_callback_add(term->bg, "tab,new", "terminology",
5702 _cb_tabcount_prev, term); 5704 _cb_tab_new, term);
5703 edje_object_signal_callback_add(term->bg, "tabcount,next", "terminology", 5705 edje_object_signal_callback_add(term->bg, "tab,prev", "terminology",
5704 _cb_tabcount_next, term); 5706 _cb_tab_prev, term);
5707 edje_object_signal_callback_add(term->bg, "tab,next", "terminology",
5708 _cb_tab_next, term);
5705 edje_object_signal_callback_add(term->bg, "tab,close", "terminology", 5709 edje_object_signal_callback_add(term->bg, "tab,close", "terminology",
5706 _cb_tab_close, term); 5710 _cb_tab_close, term);
5707 edje_object_signal_callback_add(term->bg, "tab,title", "terminology", 5711 edje_object_signal_callback_add(term->bg, "tab,title", "terminology",
@@ -6060,11 +6064,11 @@ win_font_update(Term *term)
6060void 6064void
6061windows_free(void) 6065windows_free(void)
6062{ 6066{
6067 Eina_List *l, *l_next;
6063 Win *wn; 6068 Win *wn;
6064 6069
6065 while (wins) 6070 EINA_LIST_FOREACH_SAFE(wins, l, l_next, wn)
6066 { 6071 {
6067 wn = eina_list_data_get(wins);
6068 win_free(wn); 6072 win_free(wn);
6069 } 6073 }
6070 6074