summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/backlog.c226
-rw-r--r--src/bin/backlog.h30
-rw-r--r--src/bin/config.c30
-rw-r--r--src/bin/controls.c2
-rw-r--r--src/bin/main.c27
-rw-r--r--src/bin/main.h2
-rw-r--r--src/bin/media.c4
-rw-r--r--src/bin/meson.build6
-rw-r--r--src/bin/miniview.c1
-rw-r--r--src/bin/options_behavior.c27
-rw-r--r--src/bin/options_elm.c69
-rw-r--r--src/bin/sb.c13
-rw-r--r--src/bin/termcmd.c18
-rw-r--r--src/bin/termio.c55
-rw-r--r--src/bin/termiointernals.c141
-rw-r--r--src/bin/termiolink.c2
-rw-r--r--src/bin/termpty.c347
-rw-r--r--src/bin/termpty.h20
-rw-r--r--src/bin/termptyesc.c416
-rw-r--r--src/bin/termptyops.c28
-rw-r--r--src/bin/termptysave.c91
-rw-r--r--src/bin/termptysave.h12
-rw-r--r--src/bin/tyalpha.c3
-rw-r--r--src/bin/tybg.c6
-rw-r--r--src/bin/tycat.c12
-rw-r--r--src/bin/tycommon.c24
-rw-r--r--src/bin/tycommon.h1
-rw-r--r--src/bin/tyfuzz.c17
-rw-r--r--src/bin/tyls.c5
-rw-r--r--src/bin/typop.c3
-rw-r--r--src/bin/tyq.c3
-rw-r--r--src/bin/tysend.c12
-rw-r--r--src/bin/utils.c4
-rw-r--r--src/bin/utils.h18
-rw-r--r--src/bin/win.c168
35 files changed, 1111 insertions, 732 deletions
diff --git a/src/bin/backlog.c b/src/bin/backlog.c
new file mode 100644
index 0000000..b7271c8
--- /dev/null
+++ b/src/bin/backlog.c
@@ -0,0 +1,226 @@
1#include "private.h"
2#include <Elementary.h>
3#include "termpty.h"
4#include "backlog.h"
5
6
7static int ts_comp = 0;
8static int ts_uncomp = 0;
9static int ts_freeops = 0;
10static Eina_List *ptys = NULL;
11
12static int64_t _mem_used = 0;
13
14static void
15_accounting_change(int64_t diff)
16{
17 if (diff > 0)
18 {
19 diff = ((diff + 16-1) / 16) * 16;
20 }
21 else
22 {
23 diff = ((-1 * diff + 16-1) / 16) * -16;
24 }
25 _mem_used += diff;
26}
27
28int64_t
29termpty_backlog_memory_get(void)
30{
31 return _mem_used;
32}
33
34
35void
36termpty_save_register(Termpty *ty)
37{
38 termpty_backlog_lock();
39 ptys = eina_list_append(ptys, ty);
40 termpty_backlog_unlock();
41}
42
43void
44termpty_save_unregister(Termpty *ty)
45{
46 termpty_backlog_lock();
47 ptys = eina_list_remove(ptys, ty);
48 termpty_backlog_unlock();
49}
50
51Termsave *
52termpty_save_extract(Termsave *ts)
53{
54 if (!ts) return NULL;
55 return ts;
56}
57
58Termsave *
59termpty_save_new(Termpty *ty, Termsave *ts, int w)
60{
61 termpty_save_free(ty, ts);
62
63 Termcell *cells = calloc(1, w * sizeof(Termcell));
64 if (!cells ) return NULL;
65 ts->cells = cells;
66 ts->w = w;
67 _accounting_change(w * sizeof(Termcell));
68 return ts;
69}
70
71Termsave *
72termpty_save_expand(Termpty *ty, Termsave *ts, Termcell *cells, size_t delta)
73{
74 Termcell *newcells;
75
76 newcells = realloc(ts->cells, (ts->w + delta) * sizeof(Termcell));
77 if (!newcells)
78 return NULL;
79
80 memset(newcells + ts->w,
81 0, delta * sizeof(Termcell));
82 TERMPTY_CELL_COPY(ty, cells, &newcells[ts->w], (int)delta);
83
84 _accounting_change(-1 * ts->w * sizeof(Termcell));
85 ts->w += delta;
86 _accounting_change(ts->w * sizeof(Termcell));
87 ts->cells = newcells;
88 return ts;
89}
90
91void
92termpty_save_free(Termpty *ty, Termsave *ts)
93{
94 unsigned int i;
95 if (!ts) return;
96 if (ts->comp) ts_comp--;
97 else ts_uncomp--;
98 ts_freeops++;
99 for (i = 0; i < ts->w; i++)
100 {
101 if (EINA_UNLIKELY(ts->cells[i].att.link_id))
102 term_link_refcount_dec(ty, ts->cells[i].att.link_id, 1);
103 }
104 free(ts->cells);
105 ts->cells = NULL;
106 _accounting_change((-1) * (int)(ts->w * sizeof(Termcell)));
107 ts->w = 0;
108}
109
110void
111termpty_backlog_lock(void)
112{
113}
114
115void
116termpty_backlog_unlock(void)
117{
118}
119
120void
121termpty_backlog_free(Termpty *ty)
122{
123 size_t i;
124
125 if (!ty || !ty->back)
126 return;
127
128 for (i = 0; i < ty->backsize; i++)
129 termpty_save_free(ty, &ty->back[i]);
130 _accounting_change((-1) * (int)(sizeof(Termsave) * ty->backsize));
131 free(ty->back);
132 ty->back = NULL;
133}
134
135void
136termpty_clear_backlog(Termpty *ty)
137{
138 int backsize;
139
140 ty->backlog_beacon.screen_y = 0;
141 ty->backlog_beacon.backlog_y = 0;
142
143 termpty_backlog_lock();
144 termpty_backlog_free(ty);
145 ty->backpos = 0;
146 backsize = ty->backsize;
147 ty->backsize = 0;
148 termpty_backlog_size_set(ty, backsize);
149 termpty_backlog_unlock();
150}
151
152ssize_t
153termpty_backlog_length(Termpty *ty)
154{
155 int backlog_y = ty->backlog_beacon.backlog_y;
156 int screen_y = ty->backlog_beacon.screen_y;
157
158 if (!ty->backsize)
159 return 0;
160
161 for (backlog_y++; backlog_y < (int)ty->backsize; backlog_y++)
162 {
163 int nb_lines;
164 const Termsave *ts;
165
166 ts = BACKLOG_ROW_GET(ty, backlog_y);
167 if (!ts->cells)
168 goto end;
169
170 nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w;
171 screen_y += nb_lines;
172 ty->backlog_beacon.screen_y = screen_y;
173 ty->backlog_beacon.backlog_y = backlog_y;
174 }
175end:
176 return ty->backlog_beacon.screen_y;
177}
178
179
180void
181termpty_backlog_size_set(Termpty *ty, size_t size)
182{
183 Termsave *new_back;
184 size_t i;
185
186 if (ty->backsize == size)
187 return;
188
189 termpty_backlog_lock();
190
191 if (size == 0)
192 {
193 termpty_backlog_free(ty);
194 goto end;
195 }
196 if (size > ty->backsize)
197 {
198 new_back = realloc(ty->back, sizeof(Termsave) * size);
199 if (!new_back)
200 return;
201 memset(new_back + ty->backsize, 0,
202 sizeof(Termsave) * (size - ty->backsize));
203 ty->back = new_back;
204 }
205 else
206 {
207 new_back = calloc(1, sizeof(Termsave) * size);
208 if (!new_back)
209 return;
210 for (i = 0; i < size; i++)
211 new_back[i] = ty->back[i];
212 for (i = size; i < ty->backsize; i++)
213 termpty_save_free(ty, &ty->back[i]);
214 free(ty->back);
215 ty->back = new_back;
216 }
217 _accounting_change(sizeof(Termsave) * (size - ty->backsize));
218end:
219 ty->backpos = 0;
220 ty->backsize = size;
221 /* Reset beacon */
222 ty->backlog_beacon.screen_y = 0;
223 ty->backlog_beacon.backlog_y = 0;
224
225 termpty_backlog_unlock();
226}
diff --git a/src/bin/backlog.h b/src/bin/backlog.h
new file mode 100644
index 0000000..dfe0fd7
--- /dev/null
+++ b/src/bin/backlog.h
@@ -0,0 +1,30 @@
1#ifndef _BACKLOG_H__
2#define _BACKLOG_H__ 1
3
4void termpty_save_register(Termpty *ty);
5void termpty_save_unregister(Termpty *ty);
6Termsave *termpty_save_extract(Termsave *ts);
7Termsave *termpty_save_new(Termpty *ty, Termsave *ts, int w);
8void termpty_save_free(Termpty *ty, Termsave *ts);
9Termsave *termpty_save_expand(Termpty *ty, Termsave *ts,
10 Termcell *cells, size_t delta);
11
12void termpty_backlog_lock(void);
13void termpty_backlog_unlock(void);
14
15void
16termpty_clear_backlog(Termpty *ty);
17void
18termpty_backlog_free(Termpty *ty);
19void
20termpty_backlog_size_set(Termpty *ty, size_t size);
21ssize_t
22termpty_backlog_length(Termpty *ty);
23
24int64_t
25termpty_backlog_memory_get(void);
26
27#define BACKLOG_ROW_GET(Ty, Y) \
28 (&Ty->back[(Ty->backsize + ty->backpos - ((Y) - 1 )) % Ty->backsize])
29
30#endif
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/main.c b/src/bin/main.c
index 4aabc07..32e7718 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -111,7 +111,7 @@ _configure_instance(Ipc_Instance *inst)
111 config->temporary = EINA_TRUE; 111 config->temporary = EINA_TRUE;
112 } 112 }
113 113
114 if (inst->login_shell) 114 if (inst->login_shell != 0xff)
115 { 115 {
116 inst->config->login_shell = inst->login_shell; 116 inst->config->login_shell = inst->login_shell;
117 inst->config->temporary = EINA_TRUE; 117 inst->config->temporary = EINA_TRUE;
@@ -504,6 +504,8 @@ static Ecore_Getopt options = {
504 gettext_noop("Set TERM to 'xterm-256color' instead of 'xterm'.")), 504 gettext_noop("Set TERM to 'xterm-256color' instead of 'xterm'.")),
505 ECORE_GETOPT_STORE_BOOL('\0', "active-links", 505 ECORE_GETOPT_STORE_BOOL('\0', "active-links",
506 gettext_noop("Highlight links.")), 506 gettext_noop("Highlight links.")),
507 ECORE_GETOPT_STORE_BOOL('\0', "no-wizard",
508 gettext_noop("Do not display wizard on start up.")),
507 509
508 ECORE_GETOPT_VERSION ('V', "version"), 510 ECORE_GETOPT_VERSION ('V', "version"),
509 ECORE_GETOPT_COPYRIGHT ('C', "copyright"), 511 ECORE_GETOPT_COPYRIGHT ('C', "copyright"),
@@ -564,7 +566,7 @@ _log_void(const Eina_Log_Domain *_d EINA_UNUSED,
564#endif 566#endif
565 567
566static void 568static void
567_start(Ipc_Instance *instance) 569_start(Ipc_Instance *instance, Eina_Bool need_scale_wizard)
568{ 570{
569 Win *wn; 571 Win *wn;
570 Evas_Object *win; 572 Evas_Object *win;
@@ -659,7 +661,8 @@ _start(Ipc_Instance *instance)
659 661
660 controls_init(); 662 controls_init();
661 663
662 win_scale_wizard(win, term); 664 if (need_scale_wizard)
665 win_scale_wizard(win, term);
663 666
664 terminology_starting_up = EINA_FALSE; 667 terminology_starting_up = EINA_FALSE;
665 668
@@ -757,7 +760,8 @@ _instance_add_waiter(Ipc_Instance *instance,
757 760
758static Eina_Bool 761static Eina_Bool
759_start_multi(Ipc_Instance *instance, 762_start_multi(Ipc_Instance *instance,
760 char **argv) 763 char **argv,
764 Eina_Bool need_scale_wizard)
761{ 765{
762 int remote_try = 0; 766 int remote_try = 0;
763 do 767 do
@@ -782,7 +786,7 @@ _start_multi(Ipc_Instance *instance,
782 while (remote_try <= 1); 786 while (remote_try <= 1);
783 787
784normal_start: 788normal_start:
785 _start(instance); 789 _start(instance, need_scale_wizard);
786 return EINA_FALSE; 790 return EINA_FALSE;
787 791
788exit: 792exit:
@@ -796,6 +800,7 @@ elm_main(int argc, char **argv)
796 char *video_module = NULL; 800 char *video_module = NULL;
797 Eina_Bool quit_option = EINA_FALSE; 801 Eina_Bool quit_option = EINA_FALSE;
798 Eina_Bool single = EINA_FALSE; 802 Eina_Bool single = EINA_FALSE;
803 Eina_Bool no_wizard = EINA_FALSE;
799 Eina_Bool cmd_options = EINA_FALSE; 804 Eina_Bool cmd_options = EINA_FALSE;
800 Ipc_Instance instance = { 805 Ipc_Instance instance = {
801 .login_shell = 0xff, /* unset */ 806 .login_shell = 0xff, /* unset */
@@ -835,6 +840,7 @@ elm_main(int argc, char **argv)
835 ECORE_GETOPT_VALUE_BOOL(single), 840 ECORE_GETOPT_VALUE_BOOL(single),
836 ECORE_GETOPT_VALUE_BOOL(instance.xterm_256color), 841 ECORE_GETOPT_VALUE_BOOL(instance.xterm_256color),
837 ECORE_GETOPT_VALUE_BOOL(instance.active_links), 842 ECORE_GETOPT_VALUE_BOOL(instance.active_links),
843 ECORE_GETOPT_VALUE_BOOL(no_wizard),
838 844
839 ECORE_GETOPT_VALUE_BOOL(quit_option), 845 ECORE_GETOPT_VALUE_BOOL(quit_option),
840 ECORE_GETOPT_VALUE_BOOL(quit_option), 846 ECORE_GETOPT_VALUE_BOOL(quit_option),
@@ -845,6 +851,7 @@ elm_main(int argc, char **argv)
845 }; 851 };
846 int args, retval = EXIT_SUCCESS; 852 int args, retval = EXIT_SUCCESS;
847 Eina_Bool size_set = EINA_FALSE; 853 Eina_Bool size_set = EINA_FALSE;
854 Eina_Bool need_scale_wizard = utils_need_scale_wizard();
848 855
849 terminology_starting_up = EINA_TRUE; 856 terminology_starting_up = EINA_TRUE;
850 857
@@ -905,7 +912,11 @@ elm_main(int argc, char **argv)
905 goto end; 912 goto end;
906 } 913 }
907 914
908 if (quit_option) goto end; 915 if (no_wizard)
916 need_scale_wizard = EINA_FALSE;
917
918 if (quit_option)
919 goto end;
909 920
910 if (cmd_options) 921 if (cmd_options)
911 { 922 {
@@ -1041,12 +1052,12 @@ elm_main(int argc, char **argv)
1041 1052
1042 if (!instance.cd) 1053 if (!instance.cd)
1043 instance.cd = getcwd(cwdbuf, sizeof(cwdbuf)); 1054 instance.cd = getcwd(cwdbuf, sizeof(cwdbuf));
1044 if (_start_multi(&instance, argv)) 1055 if (_start_multi(&instance, argv, need_scale_wizard))
1045 goto end; 1056 goto end;
1046 } 1057 }
1047 else 1058 else
1048 { 1059 {
1049 _start(&instance); 1060 _start(&instance, need_scale_wizard);
1050 } 1061 }
1051 elm_run(); 1062 elm_run();
1052 1063
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 28bfd2b..6240445 100644
--- a/src/bin/media.c
+++ b/src/bin/media.c
@@ -964,8 +964,8 @@ _smart_del(Evas_Object *obj)
964 if (sd->realf) unlink(sd->realf); 964 if (sd->realf) unlink(sd->realf);
965 close(sd->tmpfd); 965 close(sd->tmpfd);
966 } 966 }
967 if (sd->src) eina_stringshare_del(sd->src); 967 eina_stringshare_del(sd->src);
968 if (sd->realf) eina_stringshare_del(sd->realf); 968 eina_stringshare_del(sd->realf);
969 if (sd->clip) evas_object_del(sd->clip); 969 if (sd->clip) evas_object_del(sd->clip);
970 if (sd->o_img) evas_object_del(sd->o_img); 970 if (sd->o_img) evas_object_del(sd->o_img);
971 if (sd->o_tmp) evas_object_del(sd->o_tmp); 971 if (sd->o_tmp) evas_object_del(sd->o_tmp);
diff --git a/src/bin/meson.build b/src/bin/meson.build
index dc6c2a7..6de1d17 100644
--- a/src/bin/meson.build
+++ b/src/bin/meson.build
@@ -31,7 +31,7 @@ terminology_sources = ['private.h',
31 'termptyops.c', 'termptyops.h', 31 'termptyops.c', 'termptyops.h',
32 'termptygfx.c', 'termptygfx.h', 32 'termptygfx.c', 'termptygfx.h',
33 'termptyext.c', 'termptyext.h', 33 'termptyext.c', 'termptyext.h',
34 'termptysave.c', 'termptysave.h', 34 'backlog.c', 'backlog.h',
35 'md5/md5.c', 'md5/md5.h', 35 'md5/md5.c', 'md5/md5.h',
36 'utf8.c', 'utf8.h', 36 'utf8.c', 'utf8.h',
37 'win.c', 'win.h', 37 'win.c', 'win.h',
@@ -49,7 +49,7 @@ tycat_sources = ['tycommon.c', 'tycommon.h', 'tycat.c', 'extns.c', 'extns.h']
49tyls_sources = ['extns.c', 'extns.h', 'tyls.c', 'tycommon.c', 'tycommon.h'] 49tyls_sources = ['extns.c', 'extns.h', 'tyls.c', 'tycommon.c', 'tycommon.h']
50tysend_sources = ['tycommon.c', 'tycommon.h', 'tysend.c'] 50tysend_sources = ['tycommon.c', 'tycommon.h', 'tysend.c']
51tyfuzz_sources = ['termptyesc.c', 'termptyesc.h', 51tyfuzz_sources = ['termptyesc.c', 'termptyesc.h',
52 'termptysave.c', 'termptysave.h', 52 'backlog.c', 'backlog.h',
53 'termptyops.c', 'termptyops.h', 53 'termptyops.c', 'termptyops.h',
54 'termptydbl.c', 'termptydbl.h', 54 'termptydbl.c', 'termptydbl.h',
55 'termptyext.c', 'termptyext.h', 55 'termptyext.c', 'termptyext.h',
@@ -64,7 +64,7 @@ tyfuzz_sources = ['termptyesc.c', 'termptyesc.h',
64 'utils.c', 'utils.h', 64 'utils.c', 'utils.h',
65 'tyfuzz.c'] 65 'tyfuzz.c']
66tytest_sources = ['termptyesc.c', 'termptyesc.h', 66tytest_sources = ['termptyesc.c', 'termptyesc.h',
67 'termptysave.c', 'termptysave.h', 67 'backlog.c', 'backlog.h',
68 'termptyops.c', 'termptyops.h', 68 'termptyops.c', 'termptyops.h',
69 'termptydbl.c', 'termptydbl.h', 69 'termptydbl.c', 'termptydbl.h',
70 'termptyext.c', 'termptyext.h', 70 'termptyext.c', 'termptyext.h',
diff --git a/src/bin/miniview.c b/src/bin/miniview.c
index 6149183..8eb7d55 100644
--- a/src/bin/miniview.c
+++ b/src/bin/miniview.c
@@ -12,6 +12,7 @@
12#include "miniview.h" 12#include "miniview.h"
13#include "utils.h" 13#include "utils.h"
14#include "main.h" 14#include "main.h"
15#include "backlog.h"
15 16
16/* specific log domain to help debug only miniview */ 17/* specific log domain to help debug only miniview */
17int _miniview_log_dom = -1; 18int _miniview_log_dom = -1;
diff --git a/src/bin/options_behavior.c b/src/bin/options_behavior.c
index 1fc4e4a..c945d5d 100644
--- a/src/bin/options_behavior.c
+++ b/src/bin/options_behavior.c
@@ -4,6 +4,8 @@
4#include <math.h> 4#include <math.h>
5#include <Elementary.h> 5#include <Elementary.h>
6#include <assert.h> 6#include <assert.h>
7#include "termpty.h"
8#include "backlog.h"
7#include "config.h" 9#include "config.h"
8#include "termio.h" 10#include "termio.h"
9#include "options.h" 11#include "options.h"
@@ -17,6 +19,8 @@ typedef struct _Behavior_Ctx {
17 Evas_Object *op_wh_current; 19 Evas_Object *op_wh_current;
18 Evas_Object *term; 20 Evas_Object *term;
19 Evas_Object *sld_hide_cursor; 21 Evas_Object *sld_hide_cursor;
22 Evas_Object *backlock_label;
23 char *backlog_msg;
20 Config *config; 24 Config *config;
21} Behavior_Ctx; 25} Behavior_Ctx;
22 26
@@ -86,6 +90,24 @@ sback_units_format(double d)
86} 90}
87 91
88static void 92static void
93_update_backlog_title(Behavior_Ctx *ctx)
94{
95 char *factor = " KMG";
96 double amount = termpty_backlog_memory_get();
97
98 while (amount > 1024.0 && factor[1] != '\0')
99 {
100 amount /= 1024;
101 factor++;
102 }
103 eina_stringshare_del(ctx->backlog_msg);
104 ctx->backlog_msg = (char*) eina_stringshare_printf(
105 _("Scrollback (current memory usage: %'.2f%cB):"),
106 amount, factor[0]);
107 elm_object_text_set(ctx->backlock_label, ctx->backlog_msg);
108}
109
110static void
89_cb_op_behavior_sback_chg(void *data, 111_cb_op_behavior_sback_chg(void *data,
90 Evas_Object *obj, 112 Evas_Object *obj,
91 void *_event EINA_UNUSED) 113 void *_event EINA_UNUSED)
@@ -95,6 +117,7 @@ _cb_op_behavior_sback_chg(void *data,
95 117
96 config->scrollback = (double) sback_double_to_expo_int(elm_slider_value_get(obj)); 118 config->scrollback = (double) sback_double_to_expo_int(elm_slider_value_get(obj));
97 termio_config_update(ctx->term); 119 termio_config_update(ctx->term);
120 _update_backlog_title(ctx);
98 config_save(config); 121 config_save(config);
99} 122}
100 123
@@ -187,6 +210,7 @@ _parent_del_cb(void *data,
187{ 210{
188 Behavior_Ctx *ctx = data; 211 Behavior_Ctx *ctx = data;
189 212
213 eina_stringshare_del(ctx->backlog_msg);
190 free(ctx); 214 free(ctx);
191} 215}
192 216
@@ -563,7 +587,8 @@ options_behavior(Evas_Object *opbox, Evas_Object *term)
563 o = elm_label_add(bx); 587 o = elm_label_add(bx);
564 evas_object_size_hint_weight_set(o, 0.0, 0.0); 588 evas_object_size_hint_weight_set(o, 0.0, 0.0);
565 evas_object_size_hint_align_set(o, 0.0, 0.5); 589 evas_object_size_hint_align_set(o, 0.0, 0.5);
566 elm_object_text_set(o, _("Scrollback:")); 590 ctx->backlock_label = o;
591 _update_backlog_title(ctx);
567 elm_box_pack_end(bx, o); 592 elm_box_pack_end(bx, o);
568 evas_object_show(o); 593 evas_object_show(o);
569 594
diff --git a/src/bin/options_elm.c b/src/bin/options_elm.c
index fa9689c..b68afd0 100644
--- a/src/bin/options_elm.c
+++ b/src/bin/options_elm.c
@@ -3,7 +3,9 @@
3#include <Elementary.h> 3#include <Elementary.h>
4#include "options.h" 4#include "options.h"
5#include "options_elm.h" 5#include "options_elm.h"
6#include "utils.h"
6 7
8static char *_elementary_config = NULL;
7static void 9static void
8launch_elm_config(void *_data EINA_UNUSED, 10launch_elm_config(void *_data EINA_UNUSED,
9 Evas_Object *_obj EINA_UNUSED, 11 Evas_Object *_obj EINA_UNUSED,
@@ -11,7 +13,7 @@ launch_elm_config(void *_data EINA_UNUSED,
11{ 13{
12 Ecore_Exe *exe; 14 Ecore_Exe *exe;
13 15
14 exe = ecore_exe_pipe_run("elementary_config", ECORE_EXE_NONE, NULL); 16 exe = ecore_exe_run(_elementary_config, NULL);
15 ecore_exe_free(exe); 17 ecore_exe_free(exe);
16} 18}
17 19
@@ -41,12 +43,66 @@ _scale_change(void *data EINA_UNUSED,
41 elm_config_all_flush(); 43 elm_config_all_flush();
42} 44}
43 45
46static void
47_find_binary(void)
48{
49 char *path_env = getenv("PATH");
50 char *names[] = { "elementary_config", "terminology.elementaryConfig"};
51 int i, n_names = sizeof(names) / sizeof(names[0]);
52
53 if (!path_env)
54 goto error;
55
56 for (i = 0; i < n_names; i++)
57 {
58 char *name = names[i];
59 char *start = path_env;
60 char *end = strchrnul(start, ':');
61 while (*start)
62 {
63 if (end > start)
64 {
65 struct stat st;
66 int res;
67 const char *lookup_path;
68 if (*end == '/')
69 lookup_path = eina_stringshare_printf("%.*s%s",
70 (int)(end - start),
71 start,
72 name);
73 else
74 lookup_path = eina_stringshare_printf("%.*s/%s",
75 (int)(end - start),
76 start,
77 name);
78 res = stat(lookup_path, &st);
79 eina_stringshare_del(lookup_path);
80 if (res == 0 && S_ISREG(st.st_mode) && (S_IXUSR & st.st_mode))
81 {
82 free(_elementary_config);
83 _elementary_config = strdup(name);
84 return;
85 }
86 }
87 if (!*end)
88 break;
89 start = end + 1;
90 end = strchrnul(start, ':');
91 }
92 }
93
94error:
95 _elementary_config = "elementary_config";
96}
97
44void 98void
45options_elm(Evas_Object *opbox, Evas_Object *_term EINA_UNUSED) 99options_elm(Evas_Object *opbox, Evas_Object *_term EINA_UNUSED)
46{ 100{
47 Evas_Object *o, *fr, *bx, *bt, *en, *lbl, *sl, *sp; 101 Evas_Object *o, *fr, *bx, *bt, *en, *lbl, *sl, *sp;
48 const char *txt; 102 const char *txt;
49 103
104 _find_binary();
105
50 fr = o = elm_frame_add(opbox); 106 fr = o = elm_frame_add(opbox);
51 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 107 evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
52 evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL); 108 evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
@@ -62,8 +118,11 @@ options_elm(Evas_Object *opbox, Evas_Object *_term EINA_UNUSED)
62 elm_entry_context_menu_disabled_set(en, EINA_TRUE); 118 elm_entry_context_menu_disabled_set(en, EINA_TRUE);
63 elm_entry_editable_set(en, EINA_FALSE); 119 elm_entry_editable_set(en, EINA_FALSE);
64 elm_entry_line_wrap_set(en, ELM_WRAP_MIXED); 120 elm_entry_line_wrap_set(en, ELM_WRAP_MIXED);
65 elm_object_text_set(en, _("<em>Terminology</em> uses the <hilight>elementary</hilight> toolkit.<br>" 121 txt = eina_stringshare_printf(
66 "The toolkit configuration settings can be accessed by running <keyword>elementary_config</keyword>.")); 122 _("<em>Terminology</em> uses the <hilight>elementary</hilight> toolkit.<br>"
123 "The toolkit configuration settings can be accessed by running <keyword>%s</keyword>."), _elementary_config);
124 elm_object_text_set(en, txt);
125 eina_stringshare_del(txt);
67 evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0); 126 evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, 0);
68 evas_object_size_hint_align_set(en, EVAS_HINT_FILL, 0.5); 127 evas_object_size_hint_align_set(en, EVAS_HINT_FILL, 0.5);
69 elm_box_pack_end(bx, en); 128 elm_box_pack_end(bx, en);
@@ -72,7 +131,9 @@ options_elm(Evas_Object *opbox, Evas_Object *_term EINA_UNUSED)
72 bt = elm_button_add(opbox); 131 bt = elm_button_add(opbox);
73 evas_object_smart_callback_add(bt, "clicked", launch_elm_config, NULL); 132 evas_object_smart_callback_add(bt, "clicked", launch_elm_config, NULL);
74 evas_object_propagate_events_set(bt, EINA_FALSE); 133 evas_object_propagate_events_set(bt, EINA_FALSE);
75 elm_layout_text_set(bt, NULL, _("Launch elementary_config")); 134 txt = eina_stringshare_printf(_("Launch %s"), _elementary_config);
135 elm_layout_text_set(bt, NULL, txt);
136 eina_stringshare_del(txt);
76 elm_box_pack_end(bx, bt); 137 elm_box_pack_end(bx, bt);
77 evas_object_show(bt); 138 evas_object_show(bt);
78 139
diff --git a/src/bin/sb.c b/src/bin/sb.c
index a0dd9e8..f52f9d4 100644
--- a/src/bin/sb.c
+++ b/src/bin/sb.c
@@ -108,8 +108,17 @@ void
108ty_sb_lskip(struct ty_sb *sb, int len) 108ty_sb_lskip(struct ty_sb *sb, int len)
109{ 109{
110 sb->len -= len; 110 sb->len -= len;
111 sb->gap += len; 111 if (sb->len)
112 sb->buf += len; 112 {
113 sb->gap += len;
114 sb->buf += len;
115 }
116 else
117 {
118 /* buffer is empty, get rid of gap */
119 sb->buf -= sb->gap;
120 sb->gap = 0;
121 }
113} 122}
114 123
115void 124void
diff --git a/src/bin/termcmd.c b/src/bin/termcmd.c
index 3b2e733..e038bfc 100644
--- a/src/bin/termcmd.c
+++ b/src/bin/termcmd.c
@@ -57,15 +57,27 @@ _termcmd_font_size(Evas_Object *obj,
57 eina_stringshare_del(config->font.name); 57 eina_stringshare_del(config->font.name);
58 config->font.name = eina_stringshare_add("10x20.pcf"); 58 config->font.name = eina_stringshare_add("10x20.pcf");
59 } 59 }
60 new_size = 20; 60 new_size = config->font.size * 2;
61 } 61 }
62 else if (cmd[0] == '+') // size up 62 else if (cmd[0] == '+') // size up
63 { 63 {
64 new_size = config->font.size + 1; 64 int i;
65
66 new_size = config->font.size;
67 for (i = 0; cmd[i] == '+'; i++)
68 {
69 new_size = ((double)new_size * 1.4) + 1;
70 }
65 } 71 }
66 else if (cmd[0] == '-') // size down 72 else if (cmd[0] == '-') // size down
67 { 73 {
68 new_size = config->font.size - 1; 74 int i;
75
76 new_size = config->font.size;
77 for (i = 0; cmd[i] == '-'; i++)
78 {
79 new_size = (double)(new_size - 1) / 1.4;
80 }
69 } 81 }
70 else 82 else
71 { 83 {
diff --git a/src/bin/termio.c b/src/bin/termio.c
index dea782e..2d86ea7 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -6,6 +6,7 @@
6#include "termio.h" 6#include "termio.h"
7#include "termiolink.h" 7#include "termiolink.h"
8#include "termpty.h" 8#include "termpty.h"
9#include "backlog.h"
9#include "termptyops.h" 10#include "termptyops.h"
10#include "termcmd.h" 11#include "termcmd.h"
11#include "termptydbl.h" 12#include "termptydbl.h"
@@ -175,11 +176,8 @@ termio_user_title_set(Evas_Object *obj, const char *title)
175 size_t len = 0; 176 size_t len = 0;
176 EINA_SAFETY_ON_NULL_RETURN(sd); 177 EINA_SAFETY_ON_NULL_RETURN(sd);
177 178
178 if (sd->pty->prop.user_title) 179 eina_stringshare_del(sd->pty->prop.user_title);
179 { 180 sd->pty->prop.user_title = NULL;
180 eina_stringshare_del(sd->pty->prop.user_title);
181 sd->pty->prop.user_title = NULL;
182 }
183 181
184 if (title) 182 if (title)
185 { 183 {
@@ -408,7 +406,7 @@ termio_config_update(Evas_Object *obj)
408 406
409 EINA_SAFETY_ON_NULL_RETURN(sd); 407 EINA_SAFETY_ON_NULL_RETURN(sd);
410 408
411 if (sd->font.name) eina_stringshare_del(sd->font.name); 409 eina_stringshare_del(sd->font.name);
412 sd->font.name = NULL; 410 sd->font.name = NULL;
413 411
414 if (sd->config->font.bitmap) 412 if (sd->config->font.bitmap)
@@ -871,11 +869,8 @@ _lost_selection(void *data, Elm_Sel_Type selection)
871 } 869 }
872 if (sd->have_sel) 870 if (sd->have_sel)
873 { 871 {
874 if (sd->sel_str) 872 eina_stringshare_del(sd->sel_str);
875 { 873 sd->sel_str = NULL;
876 eina_stringshare_del(sd->sel_str);
877 sd->sel_str = NULL;
878 }
879 termio_sel_set(sd, EINA_FALSE); 874 termio_sel_set(sd, EINA_FALSE);
880 elm_object_cnp_selection_clear(sd->win, selection); 875 elm_object_cnp_selection_clear(sd->win, selection);
881 termio_smart_update_queue(sd); 876 termio_smart_update_queue(sd);
@@ -905,7 +900,7 @@ termio_take_selection_text(Termio *sd, Elm_Sel_Type type, const char *text)
905 elm_cnp_selection_loss_callback_set(sd->win, type, 900 elm_cnp_selection_loss_callback_set(sd->win, type,
906 _lost_selection, sd->self); 901 _lost_selection, sd->self);
907 sd->have_sel = EINA_TRUE; 902 sd->have_sel = EINA_TRUE;
908 if (sd->sel_str) eina_stringshare_del(sd->sel_str); 903 eina_stringshare_del(sd->sel_str);
909 sd->sel_str = text; 904 sd->sel_str = text;
910} 905}
911 906
@@ -1043,8 +1038,7 @@ _getsel_cb(void *data,
1043 int prev_i = i; 1038 int prev_i = i;
1044 g = eina_unicode_utf8_next_get(s, &i); 1039 g = eina_unicode_utf8_next_get(s, &i);
1045 /* Skip escape codes as a security measure */ 1040 /* Skip escape codes as a security measure */
1046 if ((g < '\n') || 1041 if (! ((g == '\t') || (g == '\n') || (g >= ' ')))
1047 ((g > '\n') && (g < ' ')))
1048 { 1042 {
1049 continue; 1043 continue;
1050 } 1044 }
@@ -1074,9 +1068,9 @@ _getsel_cb(void *data,
1074 const char *fmt = "UNKNOWN"; 1068 const char *fmt = "UNKNOWN";
1075 switch (ev->format) 1069 switch (ev->format)
1076 { 1070 {
1077 case ELM_SEL_FORMAT_TARGETS: fmt = "TARGETS"; break; /* shouldn't happen */ 1071 case ELM_SEL_FORMAT_TARGETS: fmt = "TARGETS"; break;
1078 case ELM_SEL_FORMAT_NONE: fmt = "NONE"; break; 1072 case ELM_SEL_FORMAT_NONE: fmt = "NONE"; break;
1079 case ELM_SEL_FORMAT_TEXT: fmt = "TEXT"; break; 1073 case ELM_SEL_FORMAT_TEXT: fmt = "TEXT"; break; /* shouldn't happen */
1080 case ELM_SEL_FORMAT_MARKUP: fmt = "MARKUP"; break; 1074 case ELM_SEL_FORMAT_MARKUP: fmt = "MARKUP"; break;
1081 case ELM_SEL_FORMAT_IMAGE: fmt = "IMAGE"; break; 1075 case ELM_SEL_FORMAT_IMAGE: fmt = "IMAGE"; break;
1082 case ELM_SEL_FORMAT_VCARD: fmt = "VCARD"; break; 1076 case ELM_SEL_FORMAT_VCARD: fmt = "VCARD"; break;
@@ -1439,11 +1433,9 @@ _remove_links(Termio *sd)
1439{ 1433{
1440 Eina_Bool same_geom = EINA_FALSE; 1434 Eina_Bool same_geom = EINA_FALSE;
1441 1435
1442 if (sd->link.string) 1436 eina_stringshare_del(sd->link.string);
1443 { 1437 sd->link.string = NULL;
1444 eina_stringshare_del(sd->link.string); 1438
1445 sd->link.string = NULL;
1446 }
1447 sd->link.x1 = -1; 1439 sd->link.x1 = -1;
1448 sd->link.y1 = -1; 1440 sd->link.y1 = -1;
1449 sd->link.x2 = -1; 1441 sd->link.x2 = -1;
@@ -2383,8 +2375,7 @@ _smart_mouseover_apply(Termio *sd)
2383 goto end; 2375 goto end;
2384 } 2376 }
2385 2377
2386 if (sd->link.string) 2378 eina_stringshare_del(sd->link.string);
2387 eina_stringshare_del(sd->link.string);
2388 sd->link.string = eina_stringshare_add(s); 2379 sd->link.string = eina_stringshare_add(s);
2389 2380
2390 if ((x1 == sd->link.x1) && (y1 == sd->link.y1) && 2381 if ((x1 == sd->link.x1) && (y1 == sd->link.y1) &&
@@ -2829,13 +2820,13 @@ termio_file_send_ok(const Evas_Object *obj, const char *file)
2829 sd->sendfile.f = fopen(file, "w"); 2820 sd->sendfile.f = fopen(file, "w");
2830 if (sd->sendfile.f) 2821 if (sd->sendfile.f)
2831 { 2822 {
2832 if (sd->sendfile.file) eina_stringshare_del(sd->sendfile.file); 2823 eina_stringshare_del(sd->sendfile.file);
2833 sd->sendfile.file = eina_stringshare_add(file); 2824 sd->sendfile.file = eina_stringshare_add(file);
2834 sd->sendfile.active = EINA_TRUE; 2825 sd->sendfile.active = EINA_TRUE;
2835 termpty_write(ty, "k\n", 2); 2826 termpty_write(ty, "k\n", 2);
2836 return EINA_TRUE; 2827 return EINA_TRUE;
2837 } 2828 }
2838 if (sd->sendfile.file) eina_stringshare_del(sd->sendfile.file); 2829 eina_stringshare_del(sd->sendfile.file);
2839 sd->sendfile.file = NULL; 2830 sd->sendfile.file = NULL;
2840 sd->sendfile.active = EINA_FALSE; 2831 sd->sendfile.active = EINA_FALSE;
2841 termpty_write(ty, "n\n", 2); 2832 termpty_write(ty, "n\n", 2);
@@ -3226,10 +3217,9 @@ _smart_del(Evas_Object *obj)
3226 if (sd->link_do_timer) ecore_timer_del(sd->link_do_timer); 3217 if (sd->link_do_timer) ecore_timer_del(sd->link_do_timer);
3227 if (sd->mouse_move_job) ecore_job_del(sd->mouse_move_job); 3218 if (sd->mouse_move_job) ecore_job_del(sd->mouse_move_job);
3228 if (sd->mouseover_delay) ecore_timer_del(sd->mouseover_delay); 3219 if (sd->mouseover_delay) ecore_timer_del(sd->mouseover_delay);
3229 if (sd->font.name) eina_stringshare_del(sd->font.name); 3220 eina_stringshare_del(sd->font.name);
3230 if (sd->pty) termpty_free(sd->pty); 3221 if (sd->pty) termpty_free(sd->pty);
3231 if (sd->link.string) 3222 eina_stringshare_del(sd->link.string);
3232 eina_stringshare_del(sd->link.string);
3233 if (sd->glayer) evas_object_del(sd->glayer); 3223 if (sd->glayer) evas_object_del(sd->glayer);
3234 if (sd->win) 3224 if (sd->win)
3235 evas_object_event_callback_del_full(sd->win, EVAS_CALLBACK_DEL, 3225 evas_object_event_callback_del_full(sd->win, EVAS_CALLBACK_DEL,
@@ -3255,7 +3245,7 @@ _smart_del(Evas_Object *obj)
3255 } 3245 }
3256 sd->sendfile.active = EINA_FALSE; 3246 sd->sendfile.active = EINA_FALSE;
3257 } 3247 }
3258 if (sd->sel_str) eina_stringshare_del(sd->sel_str); 3248 eina_stringshare_del(sd->sel_str);
3259 if (sd->sel_reset_job) ecore_job_del(sd->sel_reset_job); 3249 if (sd->sel_reset_job) ecore_job_del(sd->sel_reset_job);
3260 EINA_LIST_FREE(sd->cur_chids, chid) eina_stringshare_del(chid); 3250 EINA_LIST_FREE(sd->cur_chids, chid) eina_stringshare_del(chid);
3261 sd->sel_str = NULL; 3251 sd->sel_str = NULL;
@@ -3800,11 +3790,8 @@ _smart_pty_command(void *data)
3800 { 3790 {
3801 sd->sendfile.progress = 0.0; 3791 sd->sendfile.progress = 0.0;
3802 sd->sendfile.size = 0; 3792 sd->sendfile.size = 0;
3803 if (sd->sendfile.file) 3793 eina_stringshare_del(sd->sendfile.file);
3804 { 3794 sd->sendfile.file = NULL;
3805 eina_stringshare_del(sd->sendfile.file);
3806 sd->sendfile.file = NULL;
3807 }
3808 if (sd->sendfile.f) 3795 if (sd->sendfile.f)
3809 { 3796 {
3810 fclose(sd->sendfile.f); 3797 fclose(sd->sendfile.f);
diff --git a/src/bin/termiointernals.c b/src/bin/termiointernals.c
index 555c27a..cd17b29 100644
--- a/src/bin/termiointernals.c
+++ b/src/bin/termiointernals.c
@@ -5,6 +5,7 @@
5#include "termio.h" 5#include "termio.h"
6#include "miniview.h" 6#include "miniview.h"
7#include "termpty.h" 7#include "termpty.h"
8#include "backlog.h"
8#include "termptydbl.h" 9#include "termptydbl.h"
9#include "termptyops.h" 10#include "termptyops.h"
10#include "termiointernals.h" 11#include "termiointernals.h"
@@ -21,6 +22,16 @@ termio_selection_get(Termio *sd,
21{ 22{
22 int x, y; 23 int x, y;
23 24
25#define SB_ADD(STR, LEN) do { \
26 if (ty_sb_add(sb, STR, LEN) < 0) \
27 goto err; \
28} while (0)
29
30#define RTRIM() do { \
31 if (rtrim) \
32 ty_sb_spaces_rtrim(sb); \
33} while (0)
34
24 termpty_backlog_lock(); 35 termpty_backlog_lock();
25 for (y = c1y; y <= c2y; y++) 36 for (y = c1y; y <= c2y; y++)
26 { 37 {
@@ -33,51 +44,91 @@ termio_selection_get(Termio *sd,
33 cells = termpty_cellrow_get(sd->pty, y, &w); 44 cells = termpty_cellrow_get(sd->pty, y, &w);
34 if (!cells || !w) 45 if (!cells || !w)
35 { 46 {
36 if (ty_sb_add(sb, "\n", 1) < 0) goto err; 47 SB_ADD("\n", 1);
37 continue; 48 continue;
38 } 49 }
39 if (w > sd->grid.w) w = sd->grid.w; 50
51 /* Define how much needs to be read on that line */
52 if (w > sd->grid.w)
53 w = sd->grid.w;
40 if (y == c1y && c1x >= w) 54 if (y == c1y && c1x >= w)
41 { 55 {
42 if (rtrim) 56 RTRIM();
43 ty_sb_spaces_rtrim(sb); 57 SB_ADD("\n", 1);
44 if (ty_sb_add(sb, "\n", 1) < 0) goto err;
45 continue; 58 continue;
46 } 59 }
47 start_x = c1x; 60 start_x = c1x;
48 end_x = (c2x >= w) ? w - 1 : c2x; 61 end_x = (c2x >= w) ? w - 1 : c2x;
49 if (c1y != c2y) 62 if (c1y != c2y)
50 { 63 {
51 if (y == c1y) end_x = w - 1; 64 if (y == c1y)
52 else if (y == c2y) start_x = 0; 65 end_x = w - 1;
66 else if (y == c2y)
67 start_x = 0;
53 else 68 else
54 { 69 {
55 start_x = 0; 70 start_x = 0;
56 end_x = w - 1; 71 end_x = w - 1;
57 } 72 }
58 } 73 }
74
59 for (x = start_x; x <= end_x; x++) 75 for (x = start_x; x <= end_x; x++)
60 { 76 {
61 if ((cells[x].codepoint == 0) && (cells[x].att.dblwidth)) 77 if ((cells[x].codepoint == 0) && (cells[x].att.dblwidth))
62 { 78 {
63 if (x < end_x) x++; 79 if (x < end_x)
64 else break; 80 x++;
81 else
82 break;
83 }
84 if (x >= w)
85 break;
86 if (cells[x].att.tab_inserted)
87 {
88 /* There was a tab inserted.
89 * Only output it if there were spaces/empty cells "bellow"
90 */
91 Eina_Bool is_tab = EINA_TRUE;
92 while ((is_tab) && (x < end_x))
93 {
94 if (((cells[x].codepoint == 0) ||
95 (cells[x].att.invisible == 1) ||
96 (cells[x].codepoint == ' ')))
97 {
98 x++;
99 }
100 else
101 {
102 is_tab = EINA_FALSE;
103 }
104 if (cells[x].att.tab_last)
105 {
106 SB_ADD("\t", 1);
107 if (is_tab)
108 {
109 x++;
110 is_tab = EINA_FALSE;
111 }
112 break;
113 }
114 }
65 } 115 }
66 if (x >= w) break;
67 if (cells[x].att.newline) 116 if (cells[x].att.newline)
68 { 117 {
69 last0 = -1; 118 last0 = -1;
70 if ((y != c2y) || (x != end_x)) 119 if ((y != c2y) || (x != end_x))
71 { 120 {
72 if (rtrim) 121 RTRIM();
73 ty_sb_spaces_rtrim(sb); 122 SB_ADD("\n", 1);
74 if (ty_sb_add(sb, "\n", 1) < 0) goto err;
75 } 123 }
76 break; 124 break;
77 } 125 }
78 else if (cells[x].codepoint == 0) 126 else if (cells[x].codepoint == 0)
79 { 127 {
80 if (last0 < 0) last0 = x; 128 /* empty cell, track it to know whether to replace with
129 * spaces */
130 if (last0 < 0)
131 last0 = x;
81 } 132 }
82 else 133 else
83 { 134 {
@@ -90,27 +141,28 @@ termio_selection_get(Termio *sd,
90 last0 = -1; 141 last0 = -1;
91 while (v >= 0) 142 while (v >= 0)
92 { 143 {
93 if (ty_sb_add(sb, " ", 1) < 0) goto err; 144 SB_ADD(" ", 1);
94 v--; 145 v--;
95 } 146 }
96 } 147 }
97 txtlen = codepoint_to_utf8(cells[x].codepoint, txt); 148 txtlen = codepoint_to_utf8(cells[x].codepoint, txt);
98 if (txtlen > 0) 149 if (txtlen > 0)
99 if (ty_sb_add(sb, txt, txtlen) < 0) goto err; 150 SB_ADD(txt, txtlen);
100 if ((x == (w - 1)) && 151 if ((x == (w - 1)) &&
101 ((x != c2x) || (y != c2y))) 152 ((x != c2x) || (y != c2y)))
102 { 153 {
103 if (!cells[x].att.autowrapped) 154 if (!cells[x].att.autowrapped)
104 { 155 {
105 if (rtrim) 156 RTRIM();
106 ty_sb_spaces_rtrim(sb); 157 SB_ADD("\n", 1);
107 if (ty_sb_add(sb, "\n", 1) < 0) goto err;
108 } 158 }
109 } 159 }
110 } 160 }
111 } 161 }
112 if (last0 >= 0) 162 if (last0 >= 0)
113 { 163 {
164 /* line stop by empty cell, need to know whether to insert spaces
165 * or just go to next line */
114 if (y == c2y) 166 if (y == c2y)
115 { 167 {
116 Eina_Bool have_more = EINA_FALSE; 168 Eina_Bool have_more = EINA_FALSE;
@@ -120,8 +172,10 @@ termio_selection_get(Termio *sd,
120 if ((cells[x].codepoint == 0) && 172 if ((cells[x].codepoint == 0) &&
121 (cells[x].att.dblwidth)) 173 (cells[x].att.dblwidth))
122 { 174 {
123 if (x < (w - 1)) x++; 175 if (x < (w - 1))
124 else break; 176 x++;
177 else
178 break;
125 } 179 }
126 if (((cells[x].codepoint != 0) && 180 if (((cells[x].codepoint != 0) &&
127 (cells[x].codepoint != ' ')) || 181 (cells[x].codepoint != ' ')) ||
@@ -133,9 +187,8 @@ termio_selection_get(Termio *sd,
133 } 187 }
134 if (!have_more) 188 if (!have_more)
135 { 189 {
136 if (rtrim) 190 RTRIM();
137 ty_sb_spaces_rtrim(sb); 191 SB_ADD("\n", 1);
138 if (ty_sb_add(sb, "\n", 1) < 0) goto err;
139 } 192 }
140 else 193 else
141 { 194 {
@@ -144,31 +197,34 @@ termio_selection_get(Termio *sd,
144 if ((cells[x].codepoint == 0) && 197 if ((cells[x].codepoint == 0) &&
145 (cells[x].att.dblwidth)) 198 (cells[x].att.dblwidth))
146 { 199 {
147 if (x < (w - 1)) x++; 200 if (x < (w - 1))
148 else break; 201 x++;
202 else
203 break;
149 } 204 }
150 if (x >= w) break; 205 if (x >= w)
151 if (ty_sb_add(sb, " ", 1) < 0) goto err; 206 break;
207 SB_ADD(" ", 1);
152 } 208 }
153 } 209 }
154 } 210 }
155 else 211 else
156 { 212 {
157 if (rtrim) 213 RTRIM();
158 ty_sb_spaces_rtrim(sb); 214 SB_ADD("\n", 1);
159 if (ty_sb_add(sb, "\n", 1) < 0) goto err;
160 } 215 }
161 } 216 }
162 } 217 }
163 termpty_backlog_unlock(); 218 termpty_backlog_unlock();
164 219
165 if (rtrim) 220 RTRIM();
166 ty_sb_spaces_rtrim(sb);
167 221
168 return; 222 return;
169 223
170err: 224err:
171 ty_sb_free(sb); 225 ty_sb_free(sb);
226#undef SB_ADD
227#undef RTRIM
172} 228}
173 229
174 230
@@ -359,9 +415,21 @@ termio_internal_get_selection(Termio *sd, size_t *lenp)
359 415
360 if (isb.len) 416 if (isb.len)
361 { 417 {
418 int res;
362 if (isb.buf[isb.len - 1] != '\n' && i != end_y) 419 if (isb.buf[isb.len - 1] != '\n' && i != end_y)
363 ty_sb_add(&isb, "\n", 1); 420 {
364 ty_sb_add(&sb, isb.buf, isb.len); 421 res = ty_sb_add(&isb, "\n", 1);
422 if (res < 0)
423 {
424 ERR("failure to add newline to selection buffer");
425 }
426 }
427 res = ty_sb_add(&sb, isb.buf, isb.len);
428 if (res < 0)
429 {
430 ERR("failure to add %zd characters to selection buffer",
431 isb.len);
432 }
365 } 433 }
366 ty_sb_free(&isb); 434 ty_sb_free(&isb);
367 } 435 }
@@ -1305,8 +1373,6 @@ _selection_newline_extend_fix(Termio *sd)
1305 termpty_backlog_unlock(); 1373 termpty_backlog_unlock();
1306} 1374}
1307 1375
1308/* }}} */
1309
1310void 1376void
1311termio_selection_dbl_fix(Termio *sd) 1377termio_selection_dbl_fix(Termio *sd)
1312{ 1378{
@@ -1393,6 +1459,7 @@ termio_selection_dbl_fix(Termio *sd)
1393 sd->pty->selection.end.y = end_y; 1459 sd->pty->selection.end.y = end_y;
1394} 1460}
1395 1461
1462/* }}} */
1396 1463
1397static void 1464static void
1398_handle_mouse_down_single_click(Termio *sd, 1465_handle_mouse_down_single_click(Termio *sd,
diff --git a/src/bin/termiolink.c b/src/bin/termiolink.c
index d5a3fd5..8a0696b 100644
--- a/src/bin/termiolink.c
+++ b/src/bin/termiolink.c
@@ -1,5 +1,7 @@
1#include "private.h" 1#include "private.h"
2#include <Elementary.h> 2#include <Elementary.h>
3#include "termpty.h"
4#include "backlog.h"
3#include "termiolink.h" 5#include "termiolink.h"
4#include "termio.h" 6#include "termio.h"
5#include "sb.h" 7#include "sb.h"
diff --git a/src/bin/termpty.c b/src/bin/termpty.c
index 879135f..f1fc815 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -6,7 +6,7 @@
6#include "termpty.h" 6#include "termpty.h"
7#include "termptyesc.h" 7#include "termptyesc.h"
8#include "termptyops.h" 8#include "termptyops.h"
9#include "termptysave.h" 9#include "backlog.h"
10#include "keyin.h" 10#include "keyin.h"
11#if !defined(ENABLE_FUZZING) && !defined(ENABLE_TESTS) 11#if !defined(ENABLE_FUZZING) && !defined(ENABLE_TESTS)
12# include "win.h" 12# include "win.h"
@@ -225,35 +225,13 @@ _pty_size(Termpty *ty)
225} 225}
226 226
227static Eina_Bool 227static Eina_Bool
228_fd_read_do(Termpty *ty, Ecore_Fd_Handler *fd_handler, Eina_Bool false_on_empty) 228_handle_read(Termpty *ty, Eina_Bool false_on_empty)
229{ 229{
230 char buf[4097]; 230 char buf[4097];
231 Eina_Unicode codepoint[4097]; 231 Eina_Unicode codepoint[4097];
232 int len, i, j, reads; 232 int len, i, j, reads;
233 unsigned int k; 233 unsigned int k;
234 234
235 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
236 {
237 DBG("error while reading from tty slave fd");
238 ty->hand_fd = NULL;
239 return ECORE_CALLBACK_CANCEL;
240 }
241 if (ty->fd == -1)
242 {
243 ty->hand_fd = NULL;
244 return ECORE_CALLBACK_CANCEL;
245 }
246
247/* it seems the BSDs can not read from this side of the pair if the other side
248 * is closed */
249#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__)
250 if (ty->pid == -1)
251 {
252 ty->hand_fd = NULL;
253 return ECORE_CALLBACK_CANCEL;
254 }
255#endif
256
257 // read up to 64 * 4096 bytes 235 // read up to 64 * 4096 bytes
258 for (reads = 0; reads < 64; reads++) 236 for (reads = 0; reads < 64; reads++)
259 { 237 {
@@ -268,7 +246,7 @@ _fd_read_do(Termpty *ty, Ecore_Fd_Handler *fd_handler, Eina_Bool false_on_empty)
268 } 246 }
269 errno = 0; 247 errno = 0;
270 len = read(ty->fd, rbuf, len); 248 len = read(ty->fd, rbuf, len);
271 if ((len < 0 && errno != EAGAIN) || 249 if ((len < 0 && !(errno == EAGAIN || errno == EINTR)) ||
272 (len == 0 && errno != 0)) 250 (len == 0 && errno != 0))
273 { 251 {
274 /* Do not print error if the child has exited */ 252 /* Do not print error if the child has exited */
@@ -278,7 +256,8 @@ _fd_read_do(Termpty *ty, Ecore_Fd_Handler *fd_handler, Eina_Bool false_on_empty)
278 } 256 }
279 close(ty->fd); 257 close(ty->fd);
280 ty->fd = -1; 258 ty->fd = -1;
281 if (ty->hand_fd) ecore_main_fd_handler_del(ty->hand_fd); 259 if (ty->hand_fd)
260 ecore_main_fd_handler_del(ty->hand_fd);
282 ty->hand_fd = NULL; 261 ty->hand_fd = NULL;
283 return ECORE_CALLBACK_CANCEL; 262 return ECORE_CALLBACK_CANCEL;
284 } 263 }
@@ -337,16 +316,19 @@ _fd_read_do(Termpty *ty, Ecore_Fd_Handler *fd_handler, Eina_Bool false_on_empty)
337// DBG("---------------- handle buf %i", j); 316// DBG("---------------- handle buf %i", j);
338 termpty_handle_buf(ty, codepoint, j); 317 termpty_handle_buf(ty, codepoint, j);
339 } 318 }
340 if (ty->cb.change.func) ty->cb.change.func(ty->cb.change.data); 319 if (ty->cb.change.func)
320 ty->cb.change.func(ty->cb.change.data);
341#if defined(ENABLE_FUZZING) || defined(ENABLE_TESTS) 321#if defined(ENABLE_FUZZING) || defined(ENABLE_TESTS)
342 if (len <= 0) 322 if (len <= 0)
343 { 323 {
344 ty->exit_code = 0; 324 ty->exit_code = 0;
345 ty->pid = -1; 325 ty->pid = -1;
346 326
347 if (ty->hand_exe_exit) ecore_event_handler_del(ty->hand_exe_exit); 327 if (ty->hand_exe_exit)
328 ecore_event_handler_del(ty->hand_exe_exit);
348 ty->hand_exe_exit = NULL; 329 ty->hand_exe_exit = NULL;
349 if (ty->hand_fd) ecore_main_fd_handler_del(ty->hand_fd); 330 if (ty->hand_fd)
331 ecore_main_fd_handler_del(ty->hand_fd);
350 ty->hand_fd = NULL; 332 ty->hand_fd = NULL;
351 ty->fd = -1; 333 ty->fd = -1;
352 ty->slavefd = -1; 334 ty->slavefd = -1;
@@ -355,14 +337,82 @@ _fd_read_do(Termpty *ty, Ecore_Fd_Handler *fd_handler, Eina_Bool false_on_empty)
355 return ECORE_CALLBACK_CANCEL; 337 return ECORE_CALLBACK_CANCEL;
356 } 338 }
357#endif 339#endif
358 if ((false_on_empty) && (len <= 0)) return ECORE_CALLBACK_CANCEL; 340 if ((false_on_empty) && (len <= 0))
359 return EINA_TRUE; 341 return ECORE_CALLBACK_CANCEL;
342
343 return ECORE_CALLBACK_RENEW;
344}
345
346static Eina_Bool
347_handle_write(Termpty *ty)
348{
349 struct ty_sb *sb = &ty->write_buffer;
350 ssize_t len;
351
352 if (!sb->len)
353 return ECORE_CALLBACK_RENEW;
354
355 len = write(ty->fd, sb->buf, sb->len);
356 if (len < 0 && (errno != EINTR && errno != EAGAIN))
357 {
358 ERR(_("Could not write to file descriptor %d: %s"),
359 ty->fd, strerror(errno));
360 return ECORE_CALLBACK_CANCEL;
361 }
362 ty_sb_lskip(sb, len);
363
364 if (!sb->len)
365 ecore_main_fd_handler_active_set(ty->hand_fd,
366 ECORE_FD_ERROR |
367 ECORE_FD_READ);
368
369 return ECORE_CALLBACK_RENEW;
370}
371
372static Eina_Bool
373_fd_do(Termpty *ty, Ecore_Fd_Handler *fd_handler, Eina_Bool false_on_empty)
374{
375 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
376 {
377 DBG("error while doing I/O on tty slave fd");
378 ty->hand_fd = NULL;
379 return ECORE_CALLBACK_CANCEL;
380 }
381 if (ty->fd == -1)
382 {
383 ty->hand_fd = NULL;
384 return ECORE_CALLBACK_CANCEL;
385 }
386
387/* it seems the BSDs can not read from this side of the pair if the other side
388 * is closed */
389#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__)
390 if (ty->pid == -1)
391 {
392 ty->hand_fd = NULL;
393 return ECORE_CALLBACK_CANCEL;
394 }
395#endif
396
397 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
398 {
399 if (!_handle_read(ty, false_on_empty))
400 return ECORE_CALLBACK_CANCEL;
401 }
402
403 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
404 {
405 if (!_handle_write(ty))
406 return ECORE_CALLBACK_CANCEL;
407 }
408
409 return ECORE_CALLBACK_PASS_ON;
360} 410}
361 411
362static Eina_Bool 412static Eina_Bool
363_cb_fd_read(void *data, Ecore_Fd_Handler *fd_handler) 413_cb_fd(void *data, Ecore_Fd_Handler *fd_handler)
364{ 414{
365 return _fd_read_do(data, fd_handler, EINA_FALSE); 415 return _fd_do(data, fd_handler, EINA_FALSE);
366} 416}
367 417
368static Eina_Bool 418static Eina_Bool
@@ -386,7 +436,7 @@ _cb_exe_exit(void *data,
386 res = ECORE_CALLBACK_PASS_ON; 436 res = ECORE_CALLBACK_PASS_ON;
387 while (ty->hand_fd && res != ECORE_CALLBACK_CANCEL) 437 while (ty->hand_fd && res != ECORE_CALLBACK_CANCEL)
388 { 438 {
389 res = _fd_read_do(ty, ty->hand_fd, EINA_TRUE); 439 res = _fd_do(ty, ty->hand_fd, EINA_TRUE);
390 } 440 }
391 441
392 if (ty->hand_fd) ecore_main_fd_handler_del(ty->hand_fd); 442 if (ty->hand_fd) ecore_main_fd_handler_del(ty->hand_fd);
@@ -533,7 +583,7 @@ termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd,
533 ty->fd = STDIN_FILENO; 583 ty->fd = STDIN_FILENO;
534 ty->hand_fd = ecore_main_fd_handler_add(ty->fd, 584 ty->hand_fd = ecore_main_fd_handler_add(ty->fd,
535 ECORE_FD_READ | ECORE_FD_ERROR, 585 ECORE_FD_READ | ECORE_FD_ERROR,
536 _cb_fd_read, ty, 586 _cb_fd, ty,
537 NULL, NULL); 587 NULL, NULL);
538 _pty_size(ty); 588 _pty_size(ty);
539 termpty_save_register(ty); 589 termpty_save_register(ty);
@@ -728,6 +778,9 @@ termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd,
728 snprintf(buf, sizeof(buf), "WINDOWID=%lu", window_id); 778 snprintf(buf, sizeof(buf), "WINDOWID=%lu", window_id);
729 putenv(buf); 779 putenv(buf);
730 } 780 }
781#if ((EFL_VERSION_MAJOR > 1) || (EFL_VERSION_MINOR >= 24)) || ((EFL_VERSION_MAJOR == 1) && (EFL_VERSION_MINOR == 23) && (EFL_VERSION_MICRO == 99))
782 eina_file_close_from(3, NULL);
783#endif
731 if (!login_shell) 784 if (!login_shell)
732 execvp(args[0], (char *const *)args); 785 execvp(args[0], (char *const *)args);
733 else 786 else
@@ -747,10 +800,10 @@ termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd,
747 ty->slavefd = -1; 800 ty->slavefd = -1;
748 801
749 ty->hand_fd = ecore_main_fd_handler_add(ty->fd, ECORE_FD_READ, 802 ty->hand_fd = ecore_main_fd_handler_add(ty->fd, ECORE_FD_READ,
750 _cb_fd_read, ty, 803 _cb_fd, ty,
751 NULL, NULL); 804 NULL, NULL);
752 /* ensure we're not missing a read */ 805 /* ensure we're not missing a read */
753 _cb_fd_read(ty, ty->hand_fd); 806 _cb_fd(ty, ty->hand_fd);
754 807
755 _pty_size(ty); 808 _pty_size(ty);
756 termpty_save_register(ty); 809 termpty_save_register(ty);
@@ -818,17 +871,10 @@ termpty_free(Termpty *ty)
818 } 871 }
819 if (ty->hand_exe_exit) ecore_event_handler_del(ty->hand_exe_exit); 872 if (ty->hand_exe_exit) ecore_event_handler_del(ty->hand_exe_exit);
820 if (ty->hand_fd) ecore_main_fd_handler_del(ty->hand_fd); 873 if (ty->hand_fd) ecore_main_fd_handler_del(ty->hand_fd);
821 if (ty->prop.title) eina_stringshare_del(ty->prop.title); 874 eina_stringshare_del(ty->prop.title);
822 if (ty->prop.user_title) eina_stringshare_del(ty->prop.user_title); 875 eina_stringshare_del(ty->prop.user_title);
823 if (ty->prop.icon) eina_stringshare_del(ty->prop.icon); 876 eina_stringshare_del(ty->prop.icon);
824 if (ty->back) 877 termpty_backlog_free(ty);
825 {
826 size_t i;
827
828 for (i = 0; i < ty->backsize; i++)
829 termpty_save_free(ty, &ty->back[i]);
830 free(ty->back);
831 }
832 free(ty->screen); 878 free(ty->screen);
833 free(ty->screen2); 879 free(ty->screen2);
834 if (ty->hl.links) 880 if (ty->hl.links)
@@ -846,6 +892,7 @@ termpty_free(Termpty *ty)
846 free(ty->hl.bitmap); 892 free(ty->hl.bitmap);
847 free(ty->buf); 893 free(ty->buf);
848 free(ty->tabs); 894 free(ty->tabs);
895 ty_sb_free(&ty->write_buffer);
849 free(ty); 896 free(ty);
850} 897}
851 898
@@ -901,83 +948,6 @@ termpty_line_length(const Termcell *cells, ssize_t nb_cells)
901 return 0; 948 return 0;
902} 949}
903 950
904#define BACKLOG_ROW_GET(Ty, Y) \
905 (&Ty->back[(Ty->backsize + ty->backpos - ((Y) - 1 )) % Ty->backsize])
906
907
908static inline void
909verify_beacon(const Termpty *ty EINA_UNUSED, int verbose EINA_UNUSED)
910{
911#if 0
912 Termsave *ts;
913 int nb_lines;
914 int backlog_y = ty->backlog_beacon.backlog_y;
915 int screen_y = ty->backlog_beacon.screen_y;
916
917 assert(ty->backlog_beacon.screen_y >= 0);
918 assert(ty->backlog_beacon.backlog_y >= 0);
919 assert(ty->backlog_beacon.screen_y >= ty->backlog_beacon.backlog_y);
920
921 if (verbose)
922 {
923 ERR("FROM screen_y:%d backlog_y:%d",
924 screen_y, backlog_y);
925 }
926 while (backlog_y > 0)
927 {
928 ts = BACKLOG_ROW_GET(ty, backlog_y);
929 if (!ts->cells)
930 {
931 if (verbose)
932 {
933 ERR("went too far: screen_y:%d backlog_y:%d",
934 screen_y, backlog_y);
935 }
936 return;
937 }
938
939 nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w;
940 screen_y -= nb_lines;
941 backlog_y--;
942 if (verbose)
943 {
944 ERR("nb_lines:%d screen_y:%d backlog_y:%d ts->w:%d ty->w:%d",
945 nb_lines, screen_y, backlog_y, ts->w, ty->w);
946 }
947 assert(screen_y >= backlog_y);
948
949 }
950 if (verbose)
951 {
952 ERR("TO screen_y:%d backlog_y:%d",
953 screen_y, backlog_y);
954 }
955 assert (backlog_y == 0);
956 assert (screen_y == 0);
957#endif
958}
959
960static void
961_backlog_remove_latest_nolock(Termpty *ty)
962{
963 Termsave *ts;
964 if (ty->backsize == 0)
965 return;
966 ts = BACKLOG_ROW_GET(ty, 1);
967
968 if (ty->backpos == 0)
969 ty->backpos = ty->backsize - 1;
970 else
971 ty->backpos--;
972
973 /* reset beacon */
974 ty->backlog_beacon.screen_y = 0;
975 ty->backlog_beacon.backlog_y = 0;
976 verify_beacon(ty, 0);
977
978 termpty_save_free(ty, ts);
979}
980
981 951
982void 952void
983termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max) 953termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max)
@@ -989,7 +959,6 @@ termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max)
989 return; 959 return;
990 assert(ty->back); 960 assert(ty->back);
991 961
992 verify_beacon(ty, 0);
993 termpty_backlog_lock(); 962 termpty_backlog_lock();
994 963
995 w = termpty_line_length(cells, w_max); 964 w = termpty_line_length(cells, w_max);
@@ -1009,7 +978,6 @@ termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max)
1009 termpty_save_expand(ty, ts, cells, w); 978 termpty_save_expand(ty, ts, cells, w);
1010 ty->backlog_beacon.screen_y += (ts->w + ty->w - 1) / ty->w 979 ty->backlog_beacon.screen_y += (ts->w + ty->w - 1) / ty->w
1011 - (old_len + ty->w - 1) / ty->w; 980 - (old_len + ty->w - 1) / ty->w;
1012 verify_beacon(ty, 0);
1013 return; 981 return;
1014 } 982 }
1015 } 983 }
@@ -1032,7 +1000,6 @@ add_new_ts:
1032 ty->backlog_beacon.screen_y = 0; 1000 ty->backlog_beacon.screen_y = 0;
1033 ty->backlog_beacon.backlog_y = 0; 1001 ty->backlog_beacon.backlog_y = 0;
1034 } 1002 }
1035 verify_beacon(ty, 0);
1036} 1003}
1037 1004
1038 1005
@@ -1049,42 +1016,12 @@ termpty_row_length(Termpty *ty, int y)
1049 return wret; 1016 return wret;
1050} 1017}
1051 1018
1052ssize_t
1053termpty_backlog_length(Termpty *ty)
1054{
1055 int backlog_y = ty->backlog_beacon.backlog_y;
1056 int screen_y = ty->backlog_beacon.screen_y;
1057
1058 if (!ty->backsize)
1059 return 0;
1060 verify_beacon(ty, 0);
1061
1062 for (backlog_y++; backlog_y < (int)ty->backsize; backlog_y++)
1063 {
1064 int nb_lines;
1065 const Termsave *ts;
1066
1067 ts = BACKLOG_ROW_GET(ty, backlog_y);
1068 if (!ts->cells)
1069 goto end;
1070
1071 nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w;
1072 screen_y += nb_lines;
1073 ty->backlog_beacon.screen_y = screen_y;
1074 ty->backlog_beacon.backlog_y = backlog_y;
1075 verify_beacon(ty, 0);
1076 }
1077end:
1078 return ty->backlog_beacon.screen_y;
1079}
1080
1081void 1019void
1082termpty_backscroll_adjust(Termpty *ty, int *scroll) 1020termpty_backscroll_adjust(Termpty *ty, int *scroll)
1083{ 1021{
1084 int backlog_y = ty->backlog_beacon.backlog_y; 1022 int backlog_y = ty->backlog_beacon.backlog_y;
1085 int screen_y = ty->backlog_beacon.screen_y; 1023 int screen_y = ty->backlog_beacon.screen_y;
1086 1024
1087 verify_beacon(ty, 0);
1088 if ((ty->backsize == 0) || (*scroll <= 0)) 1025 if ((ty->backsize == 0) || (*scroll <= 0))
1089 { 1026 {
1090 *scroll = 0; 1027 *scroll = 0;
@@ -1092,7 +1029,6 @@ termpty_backscroll_adjust(Termpty *ty, int *scroll)
1092 } 1029 }
1093 if (*scroll < screen_y) 1030 if (*scroll < screen_y)
1094 { 1031 {
1095 verify_beacon(ty, 0);
1096 return; 1032 return;
1097 } 1033 }
1098 1034
@@ -1106,18 +1042,15 @@ termpty_backscroll_adjust(Termpty *ty, int *scroll)
1106 if (!ts->cells || backlog_y >= (int)ty->backsize) 1042 if (!ts->cells || backlog_y >= (int)ty->backsize)
1107 { 1043 {
1108 *scroll = ty->backlog_beacon.screen_y; 1044 *scroll = ty->backlog_beacon.screen_y;
1109 verify_beacon(ty, 0);
1110 return; 1045 return;
1111 } 1046 }
1112 nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w; 1047 nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w;
1113 screen_y += nb_lines; 1048 screen_y += nb_lines;
1114 ty->backlog_beacon.screen_y = screen_y; 1049 ty->backlog_beacon.screen_y = screen_y;
1115 ty->backlog_beacon.backlog_y = backlog_y; 1050 ty->backlog_beacon.backlog_y = backlog_y;
1116 verify_beacon(ty, 0);
1117 backlog_y++; 1051 backlog_y++;
1118 if (*scroll <= screen_y) 1052 if (*scroll <= screen_y)
1119 { 1053 {
1120 verify_beacon(ty, 0);
1121 return; 1054 return;
1122 } 1055 }
1123 } 1056 }
@@ -1141,7 +1074,6 @@ _termpty_cellrow_from_beacon_get(Termpty *ty, int requested_y, ssize_t *wret)
1141 ty->backlog_beacon.backlog_y = 0; 1074 ty->backlog_beacon.backlog_y = 0;
1142 ty->backlog_beacon.screen_y = 0; 1075 ty->backlog_beacon.screen_y = 0;
1143 } 1076 }
1144 verify_beacon(ty, 0);
1145 1077
1146 /* going upward */ 1078 /* going upward */
1147 while (requested_y >= screen_y) 1079 while (requested_y >= screen_y)
@@ -1160,7 +1092,6 @@ _termpty_cellrow_from_beacon_get(Termpty *ty, int requested_y, ssize_t *wret)
1160 screen_y += nb_lines; 1092 screen_y += nb_lines;
1161 ty->backlog_beacon.screen_y = screen_y; 1093 ty->backlog_beacon.screen_y = screen_y;
1162 ty->backlog_beacon.backlog_y = backlog_y; 1094 ty->backlog_beacon.backlog_y = backlog_y;
1163 verify_beacon(ty, 0);
1164 } 1095 }
1165 1096
1166 if ((screen_y - nb_lines < requested_y) && (requested_y <= screen_y)) 1097 if ((screen_y - nb_lines < requested_y) && (requested_y <= screen_y))
@@ -1187,7 +1118,6 @@ _termpty_cellrow_from_beacon_get(Termpty *ty, int requested_y, ssize_t *wret)
1187 1118
1188 ty->backlog_beacon.screen_y = screen_y; 1119 ty->backlog_beacon.screen_y = screen_y;
1189 ty->backlog_beacon.backlog_y = backlog_y; 1120 ty->backlog_beacon.backlog_y = backlog_y;
1190 verify_beacon(ty, 0);
1191 1121
1192 if ((screen_y - nb_lines < requested_y) && (requested_y <= screen_y)) 1122 if ((screen_y - nb_lines < requested_y) && (requested_y <= screen_y))
1193 { 1123 {
@@ -1251,18 +1181,22 @@ termpty_cell_get(Termpty *ty, int y_requested, int x_requested)
1251void 1181void
1252termpty_write(Termpty *ty, const char *input, int len) 1182termpty_write(Termpty *ty, const char *input, int len)
1253{ 1183{
1254#if defined(ENABLE_TESTS)
1255 ty_sb_add(&ty->write_buffer, input, len);
1256#else
1257 int fd = ty->fd;
1258#if defined(ENABLE_FUZZING) 1184#if defined(ENABLE_FUZZING)
1259 fd = ty->fd_dev_null; 1185 return;
1260#endif
1261 if (fd < 0) return;
1262 if (write(fd, input, len) < 0)
1263 ERR(_("Could not write to file descriptor %d: %s"),
1264 fd, strerror(errno));
1265#endif 1186#endif
1187 int res = ty_sb_add(&ty->write_buffer, input, len);
1188
1189 if (res < 0)
1190 {
1191 ERR("failure to add %d characters to write buffer", len);
1192 }
1193 else
1194 {
1195 ecore_main_fd_handler_active_set(ty->hand_fd,
1196 ECORE_FD_ERROR |
1197 ECORE_FD_READ |
1198 ECORE_FD_WRITE);
1199 }
1266} 1200}
1267 1201
1268struct screen_info 1202struct screen_info
@@ -1365,6 +1299,26 @@ _termpty_line_rewrap(Termpty *ty, Termcell *src_cells, int len,
1365 } 1299 }
1366} 1300}
1367 1301
1302static void
1303_backlog_remove_latest_nolock(Termpty *ty)
1304{
1305 Termsave *ts;
1306 if (ty->backsize == 0)
1307 return;
1308 ts = BACKLOG_ROW_GET(ty, 1);
1309
1310 if (ty->backpos == 0)
1311 ty->backpos = ty->backsize - 1;
1312 else
1313 ty->backpos--;
1314
1315 /* reset beacon */
1316 ty->backlog_beacon.screen_y = 0;
1317 ty->backlog_beacon.backlog_y = 0;
1318
1319 termpty_save_free(ty, ts);
1320}
1321
1368void 1322void
1369termpty_resize(Termpty *ty, int new_w, int new_h) 1323termpty_resize(Termpty *ty, int new_w, int new_h)
1370{ 1324{
@@ -1482,7 +1436,6 @@ termpty_resize(Termpty *ty, int new_w, int new_h)
1482 ty->backlog_beacon.backlog_y = 0; 1436 ty->backlog_beacon.backlog_y = 0;
1483 ty->backlog_beacon.screen_y = 0; 1437 ty->backlog_beacon.screen_y = 0;
1484 1438
1485 verify_beacon(ty, 0);
1486 return; 1439 return;
1487 1440
1488bad: 1441bad:
@@ -1490,32 +1443,6 @@ bad:
1490 free(new_screen); 1443 free(new_screen);
1491} 1444}
1492 1445
1493void
1494termpty_backlog_size_set(Termpty *ty, size_t size)
1495{
1496 if (ty->backsize == size)
1497 return;
1498
1499 /* TODO: RESIZE: handle that case better: changing backscroll size */
1500 termpty_backlog_lock();
1501
1502 if (ty->back)
1503 {
1504 size_t i;
1505
1506 for (i = 0; i < ty->backsize; i++)
1507 termpty_save_free(ty, &ty->back[i]);
1508 free(ty->back);
1509 }
1510 if (size > 0)
1511 ty->back = calloc(1, sizeof(Termsave) * size);
1512 else
1513 ty->back = NULL;
1514 ty->backpos = 0;
1515 ty->backsize = size;
1516 termpty_backlog_unlock();
1517}
1518
1519pid_t 1446pid_t
1520termpty_pid_get(const Termpty *ty) 1447termpty_pid_get(const Termpty *ty)
1521{ 1448{
@@ -1526,11 +1453,17 @@ void
1526termpty_block_free(Termblock *tb) 1453termpty_block_free(Termblock *tb)
1527{ 1454{
1528 char *s; 1455 char *s;
1529 if (tb->path) eina_stringshare_del(tb->path); 1456
1530 if (tb->link) eina_stringshare_del(tb->link); 1457 if (!tb)
1531 if (tb->chid) eina_stringshare_del(tb->chid); 1458 return;
1532 if (tb->obj) evas_object_del(tb->obj); 1459
1533 EINA_LIST_FREE(tb->cmds, s) free(s); 1460 eina_stringshare_del(tb->path);
1461 eina_stringshare_del(tb->link);
1462 eina_stringshare_del(tb->chid);
1463 if (tb->obj)
1464 evas_object_del(tb->obj);
1465 EINA_LIST_FREE(tb->cmds, s)
1466 free(s);
1534 free(tb); 1467 free(tb);
1535} 1468}
1536 1469
diff --git a/src/bin/termpty.h b/src/bin/termpty.h
index ef07cb9..faeaa6d 100644
--- a/src/bin/termpty.h
+++ b/src/bin/termpty.h
@@ -13,6 +13,7 @@ typedef struct _Termblock Termblock;
13typedef struct _Termexp Termexp; 13typedef struct _Termexp Termexp;
14typedef struct _Termpty Termpty; 14typedef struct _Termpty Termpty;
15typedef struct _Termlink Term_Link; 15typedef struct _Termlink Term_Link;
16typedef struct _TitleIconElem TitleIconElem;
16 17
17#define COL_DEF 0 18#define COL_DEF 0
18#define COL_BLACK 1 19#define COL_BLACK 1
@@ -81,12 +82,14 @@ struct _Termatt
81 unsigned short fraktur : 1; 82 unsigned short fraktur : 1;
82 unsigned short framed : 1; 83 unsigned short framed : 1;
83 unsigned short encircled : 1; 84 unsigned short encircled : 1;
84 unsigned short overlined : 1; 85 unsigned short overlined : 1; // TODO: support it
86 unsigned short tab_inserted : 1;
87 unsigned short tab_last : 1;
85#if defined(SUPPORT_80_132_COLUMNS) 88#if defined(SUPPORT_80_132_COLUMNS)
86 unsigned short is_80_132_mode_allowed : 1; 89 unsigned short is_80_132_mode_allowed : 1;
87 unsigned short bit_padding : 11; 90 unsigned short bit_padding : 9;
88#else 91#else
89 unsigned short bit_padding : 12; 92 unsigned short bit_padding : 10;
90#endif 93#endif
91 uint16_t link_id; 94 uint16_t link_id;
92}; 95};
@@ -166,12 +169,7 @@ struct _Termpty
166 Backlog_Beacon backlog_beacon; 169 Backlog_Beacon backlog_beacon;
167 int w, h; 170 int w, h;
168 int fd, slavefd; 171 int fd, slavefd;
169#if defined(ENABLE_TESTS)
170 struct ty_sb write_buffer; 172 struct ty_sb write_buffer;
171#endif
172#if defined(ENABLE_FUZZING)
173 int fd_dev_null;
174#endif
175 struct { 173 struct {
176 int curid; 174 int curid;
177 Eina_Hash *blocks; 175 Eina_Hash *blocks;
@@ -210,6 +208,7 @@ struct _Termpty
210 uint8_t *bitmap; 208 uint8_t *bitmap;
211 uint32_t size; 209 uint32_t size;
212 } hl; 210 } hl;
211 TitleIconElem *title_icon_stack;
213}; 212};
214 213
215struct _Termcell 214struct _Termcell
@@ -279,17 +278,12 @@ Termpty *termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd,
279void termpty_free(Termpty *ty); 278void termpty_free(Termpty *ty);
280void termpty_config_update(Termpty *ty, Config *config); 279void termpty_config_update(Termpty *ty, Config *config);
281 280
282void termpty_backlog_lock(void);
283void termpty_backlog_unlock(void);
284
285Termcell *termpty_cellrow_get(Termpty *ty, int y, ssize_t *wret); 281Termcell *termpty_cellrow_get(Termpty *ty, int y, ssize_t *wret);
286Termcell * termpty_cell_get(Termpty *ty, int y_requested, int x_requested); 282Termcell * termpty_cell_get(Termpty *ty, int y_requested, int x_requested);
287ssize_t termpty_row_length(Termpty *ty, int y); 283ssize_t termpty_row_length(Termpty *ty, int y);
288void termpty_write(Termpty *ty, const char *input, int len); 284void termpty_write(Termpty *ty, const char *input, int len);
289void termpty_resize(Termpty *ty, int new_w, int new_h); 285void termpty_resize(Termpty *ty, int new_w, int new_h);
290void termpty_resize_tabs(Termpty *ty, int old_w, int new_w); 286void termpty_resize_tabs(Termpty *ty, int old_w, int new_w);
291void termpty_backlog_size_set(Termpty *ty, size_t size);
292ssize_t termpty_backlog_length(Termpty *ty);
293void termpty_backscroll_adjust(Termpty *ty, int *scroll); 287void termpty_backscroll_adjust(Termpty *ty, int *scroll);
294 288
295pid_t termpty_pid_get(const Termpty *ty); 289pid_t termpty_pid_get(const Termpty *ty);
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index a92b4db..604b23d 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -110,9 +110,9 @@ _cursor_is_within_margins(const Termpty *ty)
110 ); 110 );
111} 111}
112 112
113enum csi_arg_error { 113enum esc_arg_error {
114 CSI_ARG_NO_VALUE = 1, 114 ESC_ARG_NO_VALUE = 1,
115 CSI_ARG_ERROR = 2 115 ESC_ARG_ERROR = 2
116}; 116};
117 117
118static int 118static int
@@ -124,7 +124,7 @@ _csi_arg_get(Termpty *ty, Eina_Unicode **ptr)
124 if ((b == NULL) || (*b == '\0')) 124 if ((b == NULL) || (*b == '\0'))
125 { 125 {
126 *ptr = NULL; 126 *ptr = NULL;
127 return -CSI_ARG_NO_VALUE; 127 return -ESC_ARG_NO_VALUE;
128 } 128 }
129 129
130 /* Skip potential '?', '>'.... */ 130 /* Skip potential '?', '>'.... */
@@ -135,13 +135,13 @@ _csi_arg_get(Termpty *ty, Eina_Unicode **ptr)
135 { 135 {
136 b++; 136 b++;
137 *ptr = b; 137 *ptr = b;
138 return -CSI_ARG_NO_VALUE; 138 return -ESC_ARG_NO_VALUE;
139 } 139 }
140 140
141 if (*b == '\0') 141 if (*b == '\0')
142 { 142 {
143 *ptr = NULL; 143 *ptr = NULL;
144 return -CSI_ARG_NO_VALUE; 144 return -ESC_ARG_NO_VALUE;
145 } 145 }
146 146
147 while ((*b >= '0') && (*b <= '9')) 147 while ((*b >= '0') && (*b <= '9'))
@@ -177,7 +177,7 @@ error:
177 ERR("Invalid CSI argument"); 177 ERR("Invalid CSI argument");
178 ty->decoding_error = EINA_TRUE; 178 ty->decoding_error = EINA_TRUE;
179 *ptr = NULL; 179 *ptr = NULL;
180 return -CSI_ARG_ERROR; 180 return -ESC_ARG_ERROR;
181} 181}
182 182
183static void 183static void
@@ -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)
@@ -295,9 +301,9 @@ _handle_esc_csi_reset_mode(Termpty *ty, Eina_Unicode cc, Eina_Unicode *b,
295 // http://ttssh2.sourceforge.jp/manual/en/about/ctrlseq.html 301 // http://ttssh2.sourceforge.jp/manual/en/about/ctrlseq.html
296 switch (arg) 302 switch (arg)
297 { 303 {
298 case -CSI_ARG_ERROR: 304 case -ESC_ARG_ERROR:
299 return; 305 return;
300 /* TODO: -CSI_ARG_NO_VALUE */ 306 /* TODO: -ESC_ARG_NO_VALUE */
301 case 1: 307 case 1:
302 ty->termstate.appcursor = mode; 308 ty->termstate.appcursor = mode;
303 break; 309 break;
@@ -547,9 +553,9 @@ _handle_esc_csi_reset_mode(Termpty *ty, Eina_Unicode cc, Eina_Unicode *b,
547 553
548 switch (arg) 554 switch (arg)
549 { 555 {
550 case -CSI_ARG_ERROR: 556 case -ESC_ARG_ERROR:
551 return; 557 return;
552 /* TODO: -CSI_ARG_NO_VALUE */ 558 /* TODO: -ESC_ARG_NO_VALUE */
553 case 1: 559 case 1:
554 ty->termstate.appcursor = mode; 560 ty->termstate.appcursor = mode;
555 break; 561 break;
@@ -587,7 +593,7 @@ _csi_truecolor_arg_get(Termpty *ty, Eina_Unicode **ptr)
587 if ((b == NULL) || (*b == '\0')) 593 if ((b == NULL) || (*b == '\0'))
588 { 594 {
589 *ptr = NULL; 595 *ptr = NULL;
590 return -CSI_ARG_NO_VALUE; 596 return -ESC_ARG_NO_VALUE;
591 } 597 }
592 598
593 /* by construction, shall be the same separator as the following ones */ 599 /* by construction, shall be the same separator as the following ones */
@@ -595,26 +601,26 @@ _csi_truecolor_arg_get(Termpty *ty, Eina_Unicode **ptr)
595 if ((separator != ';') && (separator != ':')) 601 if ((separator != ';') && (separator != ':'))
596 { 602 {
597 *ptr = NULL; 603 *ptr = NULL;
598 return -CSI_ARG_NO_VALUE; 604 return -ESC_ARG_NO_VALUE;
599 } 605 }
600 606
601 if (*b == separator) 607 if (*b == separator)
602 { 608 {
603 b++; 609 b++;
604 *ptr = b; 610 *ptr = b;
605 return -CSI_ARG_NO_VALUE; 611 return -ESC_ARG_NO_VALUE;
606 } 612 }
607 613
608 if (*b == '\0') 614 if (*b == '\0')
609 { 615 {
610 *ptr = NULL; 616 *ptr = NULL;
611 return -CSI_ARG_NO_VALUE; 617 return -ESC_ARG_NO_VALUE;
612 } 618 }
613 /* invalid values */ 619 /* invalid values */
614 if ((*b < '0') || (*b > '9')) 620 if ((*b < '0') || (*b > '9'))
615 { 621 {
616 *ptr = NULL; 622 *ptr = NULL;
617 return -CSI_ARG_ERROR; 623 return -ESC_ARG_ERROR;
618 } 624 }
619 625
620 while ((*b >= '0') && (*b <= '9')) 626 while ((*b >= '0') && (*b <= '9'))
@@ -624,7 +630,7 @@ _csi_truecolor_arg_get(Termpty *ty, Eina_Unicode **ptr)
624 *ptr = NULL; 630 *ptr = NULL;
625 ERR("Invalid sequence: argument is too large"); 631 ERR("Invalid sequence: argument is too large");
626 ty->decoding_error = EINA_TRUE; 632 ty->decoding_error = EINA_TRUE;
627 return -CSI_ARG_ERROR; 633 return -ESC_ARG_ERROR;
628 } 634 }
629 sum *= 10; 635 sum *= 10;
630 sum += *b - '0'; 636 sum += *b - '0';
@@ -713,9 +719,9 @@ _handle_esc_csi_truecolor_rgb(Termpty *ty, Eina_Unicode **ptr)
713 r = _csi_truecolor_arg_get(ty, ptr); 719 r = _csi_truecolor_arg_get(ty, ptr);
714 g = _csi_truecolor_arg_get(ty, ptr); 720 g = _csi_truecolor_arg_get(ty, ptr);
715 b = _csi_truecolor_arg_get(ty, ptr); 721 b = _csi_truecolor_arg_get(ty, ptr);
716 if ((r == -CSI_ARG_ERROR) || 722 if ((r == -ESC_ARG_ERROR) ||
717 (g == -CSI_ARG_ERROR) || 723 (g == -ESC_ARG_ERROR) ||
718 (b == -CSI_ARG_ERROR)) 724 (b == -ESC_ARG_ERROR))
719 return COL_DEF; 725 return COL_DEF;
720 726
721 if (separator == ':' && *ptr) 727 if (separator == ':' && *ptr)
@@ -730,7 +736,7 @@ _handle_esc_csi_truecolor_rgb(Termpty *ty, Eina_Unicode **ptr)
730 while ((*ptr) && (**ptr != ';')) 736 while ((*ptr) && (**ptr != ';'))
731 { 737 {
732 int arg = _csi_truecolor_arg_get(ty, ptr); 738 int arg = _csi_truecolor_arg_get(ty, ptr);
733 if (arg == -CSI_ARG_ERROR) 739 if (arg == -ESC_ARG_ERROR)
734 break; 740 break;
735 } 741 }
736 } 742 }
@@ -740,11 +746,11 @@ _handle_esc_csi_truecolor_rgb(Termpty *ty, Eina_Unicode **ptr)
740 } 746 }
741 } 747 }
742 748
743 if (r == -CSI_ARG_NO_VALUE) 749 if (r == -ESC_ARG_NO_VALUE)
744 r = 0; 750 r = 0;
745 if (g == -CSI_ARG_NO_VALUE) 751 if (g == -ESC_ARG_NO_VALUE)
746 g = 0; 752 g = 0;
747 if (b == -CSI_ARG_NO_VALUE) 753 if (b == -ESC_ARG_NO_VALUE)
748 b = 0; 754 b = 0;
749 755
750 return _approximate_truecolor_rgb(ty, r, g, b); 756 return _approximate_truecolor_rgb(ty, r, g, b);
@@ -768,9 +774,9 @@ _handle_esc_csi_truecolor_cmy(Termpty *ty, Eina_Unicode **ptr)
768 m = _csi_truecolor_arg_get(ty, ptr); 774 m = _csi_truecolor_arg_get(ty, ptr);
769 y = _csi_truecolor_arg_get(ty, ptr); 775 y = _csi_truecolor_arg_get(ty, ptr);
770 776
771 if ((c == -CSI_ARG_ERROR) || 777 if ((c == -ESC_ARG_ERROR) ||
772 (m == -CSI_ARG_ERROR) || 778 (m == -ESC_ARG_ERROR) ||
773 (y == -CSI_ARG_ERROR)) 779 (y == -ESC_ARG_ERROR))
774 return COL_DEF; 780 return COL_DEF;
775 781
776 if (separator == ':' && *ptr) 782 if (separator == ':' && *ptr)
@@ -785,7 +791,7 @@ _handle_esc_csi_truecolor_cmy(Termpty *ty, Eina_Unicode **ptr)
785 while ((*ptr) && (**ptr != ';')) 791 while ((*ptr) && (**ptr != ';'))
786 { 792 {
787 int arg = _csi_truecolor_arg_get(ty, ptr); 793 int arg = _csi_truecolor_arg_get(ty, ptr);
788 if (arg == -CSI_ARG_ERROR) 794 if (arg == -ESC_ARG_ERROR)
789 break; 795 break;
790 } 796 }
791 } 797 }
@@ -795,11 +801,11 @@ _handle_esc_csi_truecolor_cmy(Termpty *ty, Eina_Unicode **ptr)
795 } 801 }
796 } 802 }
797 803
798 if (c == -CSI_ARG_NO_VALUE) 804 if (c == -ESC_ARG_NO_VALUE)
799 c = 0; 805 c = 0;
800 if (m == -CSI_ARG_NO_VALUE) 806 if (m == -ESC_ARG_NO_VALUE)
801 m = 0; 807 m = 0;
802 if (y == -CSI_ARG_NO_VALUE) 808 if (y == -ESC_ARG_NO_VALUE)
803 y = 0; 809 y = 0;
804 810
805 r = 255 - ((c * 255) / 100); 811 r = 255 - ((c * 255) / 100);
@@ -828,10 +834,10 @@ _handle_esc_csi_truecolor_cmyk(Termpty *ty, Eina_Unicode **ptr)
828 y = _csi_truecolor_arg_get(ty, ptr); 834 y = _csi_truecolor_arg_get(ty, ptr);
829 k = _csi_truecolor_arg_get(ty, ptr); 835 k = _csi_truecolor_arg_get(ty, ptr);
830 836
831 if ((c == -CSI_ARG_ERROR) || 837 if ((c == -ESC_ARG_ERROR) ||
832 (m == -CSI_ARG_ERROR) || 838 (m == -ESC_ARG_ERROR) ||
833 (y == -CSI_ARG_ERROR) || 839 (y == -ESC_ARG_ERROR) ||
834 (k == -CSI_ARG_ERROR)) 840 (k == -ESC_ARG_ERROR))
835 return COL_DEF; 841 return COL_DEF;
836 842
837 if (separator == ':' && *ptr) 843 if (separator == ':' && *ptr)
@@ -847,7 +853,7 @@ _handle_esc_csi_truecolor_cmyk(Termpty *ty, Eina_Unicode **ptr)
847 while ((*ptr) && (**ptr != ';')) 853 while ((*ptr) && (**ptr != ';'))
848 { 854 {
849 int arg = _csi_truecolor_arg_get(ty, ptr); 855 int arg = _csi_truecolor_arg_get(ty, ptr);
850 if (arg == -CSI_ARG_ERROR) 856 if (arg == -ESC_ARG_ERROR)
851 break; 857 break;
852 } 858 }
853 } 859 }
@@ -857,13 +863,13 @@ _handle_esc_csi_truecolor_cmyk(Termpty *ty, Eina_Unicode **ptr)
857 } 863 }
858 } 864 }
859 865
860 if (c == -CSI_ARG_NO_VALUE) 866 if (c == -ESC_ARG_NO_VALUE)
861 c = 0; 867 c = 0;
862 if (m == -CSI_ARG_NO_VALUE) 868 if (m == -ESC_ARG_NO_VALUE)
863 m = 0; 869 m = 0;
864 if (y == -CSI_ARG_NO_VALUE) 870 if (y == -ESC_ARG_NO_VALUE)
865 y = 0; 871 y = 0;
866 if (k == -CSI_ARG_NO_VALUE) 872 if (k == -ESC_ARG_NO_VALUE)
867 k = 0; 873 k = 0;
868 874
869 r = (255 * (100 - c) * (100 - k)) / 100 / 100; 875 r = (255 * (100 - c) * (100 - k)) / 100 / 100;
@@ -891,9 +897,9 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr,
891 int arg = _csi_arg_get(ty, &b); 897 int arg = _csi_arg_get(ty, &b);
892 switch (arg) 898 switch (arg)
893 { 899 {
894 case -CSI_ARG_ERROR: 900 case -ESC_ARG_ERROR:
895 return; 901 return;
896 case -CSI_ARG_NO_VALUE: 902 case -ESC_ARG_NO_VALUE:
897 EINA_FALLTHROUGH; 903 EINA_FALLTHROUGH;
898 case 0: // reset to normal 904 case 0: // reset to normal
899 termpty_reset_att(&(ty->termstate.att)); 905 termpty_reset_att(&(ty->termstate.att));
@@ -971,9 +977,9 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr,
971 arg = _csi_arg_get(ty, &b); 977 arg = _csi_arg_get(ty, &b);
972 switch (arg) 978 switch (arg)
973 { 979 {
974 case -CSI_ARG_ERROR: 980 case -ESC_ARG_ERROR:
975 return; 981 return;
976 /* TODO: -CSI_ARG_NO_VALUE */ 982 /* TODO: -ESC_ARG_NO_VALUE */
977 case 1: 983 case 1:
978 ty->termstate.att.fg256 = 0; 984 ty->termstate.att.fg256 = 0;
979 ty->termstate.att.fg = COL_INVIS; 985 ty->termstate.att.fg = COL_INVIS;
@@ -1002,14 +1008,14 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr,
1002 case 5: 1008 case 5:
1003 // then get next arg - should be color index 0-255 1009 // then get next arg - should be color index 0-255
1004 arg = _csi_arg_get(ty, &b); 1010 arg = _csi_arg_get(ty, &b);
1005 if (arg <= -CSI_ARG_ERROR || arg > 255) 1011 if (arg <= -ESC_ARG_ERROR || arg > 255)
1006 { 1012 {
1007 ERR("Invalid fg color %d", arg); 1013 ERR("Invalid fg color %d", arg);
1008 ty->decoding_error = EINA_TRUE; 1014 ty->decoding_error = EINA_TRUE;
1009 } 1015 }
1010 else 1016 else
1011 { 1017 {
1012 if (arg == -CSI_ARG_NO_VALUE) 1018 if (arg == -ESC_ARG_NO_VALUE)
1013 arg = 0; 1019 arg = 0;
1014 ty->termstate.att.fg256 = 1; 1020 ty->termstate.att.fg256 = 1;
1015 ty->termstate.att.fg = arg; 1021 ty->termstate.att.fg = arg;
@@ -1042,9 +1048,9 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr,
1042 arg = _csi_arg_get(ty, &b); 1048 arg = _csi_arg_get(ty, &b);
1043 switch (arg) 1049 switch (arg)
1044 { 1050 {
1045 case -CSI_ARG_ERROR: 1051 case -ESC_ARG_ERROR:
1046 return; 1052 return;
1047 /* TODO: -CSI_ARG_NO_VALUE */ 1053 /* TODO: -ESC_ARG_NO_VALUE */
1048 case 1: 1054 case 1:
1049 ty->termstate.att.bg256 = 0; 1055 ty->termstate.att.bg256 = 0;
1050 ty->termstate.att.bg = COL_INVIS; 1056 ty->termstate.att.bg = COL_INVIS;
@@ -1073,14 +1079,14 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr,
1073 case 5: 1079 case 5:
1074 // then get next arg - should be color index 0-255 1080 // then get next arg - should be color index 0-255
1075 arg = _csi_arg_get(ty, &b); 1081 arg = _csi_arg_get(ty, &b);
1076 if (arg <= -CSI_ARG_ERROR || arg > 255) 1082 if (arg <= -ESC_ARG_ERROR || arg > 255)
1077 { 1083 {
1078 ERR("Invalid bg color %d", arg); 1084 ERR("Invalid bg color %d", arg);
1079 ty->decoding_error = EINA_TRUE; 1085 ty->decoding_error = EINA_TRUE;
1080 } 1086 }
1081 else 1087 else
1082 { 1088 {
1083 if (arg == -CSI_ARG_NO_VALUE) 1089 if (arg == -ESC_ARG_NO_VALUE)
1084 arg = 0; 1090 arg = 0;
1085 ty->termstate.att.bg256 = 1; 1091 ty->termstate.att.bg256 = 1;
1086 ty->termstate.att.bg = arg; 1092 ty->termstate.att.bg = arg;
@@ -1164,7 +1170,7 @@ _handle_esc_csi_cnl(Termpty *ty, Eina_Unicode **ptr)
1164 int arg = _csi_arg_get(ty, &b); 1170 int arg = _csi_arg_get(ty, &b);
1165 int max = ty->h; 1171 int max = ty->h;
1166 1172
1167 if (arg == -CSI_ARG_ERROR) 1173 if (arg == -ESC_ARG_ERROR)
1168 return; 1174 return;
1169 if (arg < 1) 1175 if (arg < 1)
1170 arg = 1; 1176 arg = 1;
@@ -1189,7 +1195,7 @@ _handle_esc_csi_cpl(Termpty *ty, Eina_Unicode **ptr)
1189 int arg = _csi_arg_get(ty, &b); 1195 int arg = _csi_arg_get(ty, &b);
1190 int max = ty->h; 1196 int max = ty->h;
1191 1197
1192 if (arg == -CSI_ARG_ERROR) 1198 if (arg == -ESC_ARG_ERROR)
1193 return; 1199 return;
1194 if (arg < 1) 1200 if (arg < 1)
1195 arg = 1; 1201 arg = 1;
@@ -1215,7 +1221,7 @@ _handle_esc_csi_dch(Termpty *ty, Eina_Unicode **ptr)
1215 Termcell *cells; 1221 Termcell *cells;
1216 int x, lim, max; 1222 int x, lim, max;
1217 1223
1218 if (arg == -CSI_ARG_ERROR) 1224 if (arg == -ESC_ARG_ERROR)
1219 return; 1225 return;
1220 1226
1221 DBG("DCH - Delete Character: %d chars", arg); 1227 DBG("DCH - Delete Character: %d chars", arg);
@@ -1273,7 +1279,7 @@ _handle_esc_csi_dsr(Termpty *ty, Eina_Unicode *b)
1273 arg = _csi_arg_get(ty, &b); 1279 arg = _csi_arg_get(ty, &b);
1274 switch (arg) 1280 switch (arg)
1275 { 1281 {
1276 case -CSI_ARG_ERROR: 1282 case -ESC_ARG_ERROR:
1277 return; 1283 return;
1278 case 5: 1284 case 5:
1279 if (question_mark) 1285 if (question_mark)
@@ -1382,7 +1388,7 @@ _handle_esc_csi_dsr(Termpty *ty, Eina_Unicode *b)
1382 { 1388 {
1383 /* DSR-DECCKSR (Memory Checksum) */ 1389 /* DSR-DECCKSR (Memory Checksum) */
1384 int pid = _csi_arg_get(ty, &b); 1390 int pid = _csi_arg_get(ty, &b);
1385 if (pid == -CSI_ARG_NO_VALUE) 1391 if (pid == -ESC_ARG_NO_VALUE)
1386 pid = 65535; 1392 pid = 65535;
1387 len = snprintf(bf, sizeof(bf), "\033P%u!~0000\033\\", 1393 len = snprintf(bf, sizeof(bf), "\033P%u!~0000\033\\",
1388 ((unsigned int)pid) % 65536); 1394 ((unsigned int)pid) % 65536);
@@ -1408,7 +1414,7 @@ _handle_esc_csi_dsr(Termpty *ty, Eina_Unicode *b)
1408 ty->decoding_error = EINA_TRUE; 1414 ty->decoding_error = EINA_TRUE;
1409 } 1415 }
1410 break; 1416 break;
1411 /* TODO: -CSI_ARG_NO_VALUE */ 1417 /* TODO: -ESC_ARG_NO_VALUE */
1412 default: 1418 default:
1413 WRN("unhandled DSR (dec specific: %s) %d", 1419 WRN("unhandled DSR (dec specific: %s) %d",
1414 (question_mark)? "yes": "no", arg); 1420 (question_mark)? "yes": "no", arg);
@@ -1424,7 +1430,7 @@ _handle_esc_csi_decslrm(Termpty *ty, Eina_Unicode **b)
1424 int right = _csi_arg_get(ty, b); 1430 int right = _csi_arg_get(ty, b);
1425 1431
1426 DBG("DECSLRM (%d;%d) Set Left and Right Margins", left, right); 1432 DBG("DECSLRM (%d;%d) Set Left and Right Margins", left, right);
1427 if ((left == -CSI_ARG_ERROR) || (right == -CSI_ARG_ERROR)) 1433 if ((left == -ESC_ARG_ERROR) || (right == -ESC_ARG_ERROR))
1428 goto bad; 1434 goto bad;
1429 1435
1430 TERMPTY_RESTRICT_FIELD(left, 1, ty->w); 1436 TERMPTY_RESTRICT_FIELD(left, 1, ty->w);
@@ -1458,7 +1464,7 @@ _handle_esc_csi_decstbm(Termpty *ty, Eina_Unicode **b)
1458 int bottom = _csi_arg_get(ty, b); 1464 int bottom = _csi_arg_get(ty, b);
1459 1465
1460 DBG("DECSTBM (%d;%d) Set Top and Bottom Margins", top, bottom); 1466 DBG("DECSTBM (%d;%d) Set Top and Bottom Margins", top, bottom);
1461 if ((top == -CSI_ARG_ERROR) || (bottom == -CSI_ARG_ERROR)) 1467 if ((top == -ESC_ARG_ERROR) || (bottom == -ESC_ARG_ERROR))
1462 goto bad; 1468 goto bad;
1463 1469
1464 TERMPTY_RESTRICT_FIELD(top, 1, ty->h); 1470 TERMPTY_RESTRICT_FIELD(top, 1, ty->h);
@@ -1631,12 +1637,12 @@ _handle_esc_csi_decfra(Termpty *ty, Eina_Unicode **b)
1631 1637
1632 DBG("DECFRA (%d; %d;%d;%d;%d) Fill Rectangular Area", 1638 DBG("DECFRA (%d; %d;%d;%d;%d) Fill Rectangular Area",
1633 c, top, left, bottom, right); 1639 c, top, left, bottom, right);
1634 if ((c == -CSI_ARG_ERROR) || 1640 if ((c == -ESC_ARG_ERROR) ||
1635 (c == -CSI_ARG_NO_VALUE) || 1641 (c == -ESC_ARG_NO_VALUE) ||
1636 (top == -CSI_ARG_ERROR) || 1642 (top == -ESC_ARG_ERROR) ||
1637 (left == -CSI_ARG_ERROR) || 1643 (left == -ESC_ARG_ERROR) ||
1638 (bottom == -CSI_ARG_ERROR) || 1644 (bottom == -ESC_ARG_ERROR) ||
1639 (right == -CSI_ARG_ERROR)) 1645 (right == -ESC_ARG_ERROR))
1640 return; 1646 return;
1641 1647
1642 if (! ((c >= 32 && c <= 126) || (c >= 160 && c <= 255))) 1648 if (! ((c >= 32 && c <= 126) || (c >= 160 && c <= 255)))
@@ -1708,10 +1714,10 @@ _handle_esc_csi_deccara(Termpty *ty, Eina_Unicode **ptr,
1708 1714
1709 DBG("DECCARA (%d;%d;%d;%d) Change Attributes in Rectangular Area", 1715 DBG("DECCARA (%d;%d;%d;%d) Change Attributes in Rectangular Area",
1710 top, left, bottom, right); 1716 top, left, bottom, right);
1711 if ((top == -CSI_ARG_ERROR) || 1717 if ((top == -ESC_ARG_ERROR) ||
1712 (left == -CSI_ARG_ERROR) || 1718 (left == -ESC_ARG_ERROR) ||
1713 (bottom == -CSI_ARG_ERROR) || 1719 (bottom == -ESC_ARG_ERROR) ||
1714 (right == -CSI_ARG_ERROR)) 1720 (right == -ESC_ARG_ERROR))
1715 return; 1721 return;
1716 1722
1717 while (b && b < end) 1723 while (b && b < end)
@@ -1719,9 +1725,9 @@ _handle_esc_csi_deccara(Termpty *ty, Eina_Unicode **ptr,
1719 int arg = _csi_arg_get(ty, &b); 1725 int arg = _csi_arg_get(ty, &b);
1720 switch (arg) 1726 switch (arg)
1721 { 1727 {
1722 case -CSI_ARG_ERROR: 1728 case -ESC_ARG_ERROR:
1723 return; 1729 return;
1724 case -CSI_ARG_NO_VALUE: 1730 case -ESC_ARG_NO_VALUE:
1725 EINA_FALLTHROUGH; 1731 EINA_FALLTHROUGH;
1726 case 0: 1732 case 0:
1727 set_bold = set_underline = set_blink = set_inverse = EINA_FALSE; 1733 set_bold = set_underline = set_blink = set_inverse = EINA_FALSE;
@@ -1876,10 +1882,10 @@ _handle_esc_csi_decrara(Termpty *ty, Eina_Unicode **ptr,
1876 1882
1877 DBG("DECRARA (%d;%d;%d;%d) Reverse Attributes in Rectangular Area", 1883 DBG("DECRARA (%d;%d;%d;%d) Reverse Attributes in Rectangular Area",
1878 top, left, bottom, right); 1884 top, left, bottom, right);
1879 if ((top == -CSI_ARG_ERROR) || 1885 if ((top == -ESC_ARG_ERROR) ||
1880 (left == -CSI_ARG_ERROR) || 1886 (left == -ESC_ARG_ERROR) ||
1881 (bottom == -CSI_ARG_ERROR) || 1887 (bottom == -ESC_ARG_ERROR) ||
1882 (right == -CSI_ARG_ERROR)) 1888 (right == -ESC_ARG_ERROR))
1883 return; 1889 return;
1884 1890
1885 while (b && b < end) 1891 while (b && b < end)
@@ -1887,9 +1893,9 @@ _handle_esc_csi_decrara(Termpty *ty, Eina_Unicode **ptr,
1887 int arg = _csi_arg_get(ty, &b); 1893 int arg = _csi_arg_get(ty, &b);
1888 switch (arg) 1894 switch (arg)
1889 { 1895 {
1890 case -CSI_ARG_ERROR: 1896 case -ESC_ARG_ERROR:
1891 return; 1897 return;
1892 case -CSI_ARG_NO_VALUE: 1898 case -ESC_ARG_NO_VALUE:
1893 EINA_FALLTHROUGH; 1899 EINA_FALLTHROUGH;
1894 case 0: 1900 case 0:
1895 reverse_bold = reverse_underline = reverse_blink = reverse_inverse = EINA_TRUE; 1901 reverse_bold = reverse_underline = reverse_blink = reverse_inverse = EINA_TRUE;
@@ -1980,10 +1986,10 @@ _handle_esc_csi_decera(Termpty *ty, Eina_Unicode **b)
1980 DBG("DECERA (%d;%d;%d;%d) Erase Rectangular Area", 1986 DBG("DECERA (%d;%d;%d;%d) Erase Rectangular Area",
1981 top, left, bottom, right); 1987 top, left, bottom, right);
1982 1988
1983 if ((top == -CSI_ARG_ERROR) || 1989 if ((top == -ESC_ARG_ERROR) ||
1984 (left == -CSI_ARG_ERROR) || 1990 (left == -ESC_ARG_ERROR) ||
1985 (bottom == -CSI_ARG_ERROR) || 1991 (bottom == -ESC_ARG_ERROR) ||
1986 (right == -CSI_ARG_ERROR)) 1992 (right == -ESC_ARG_ERROR))
1987 return; 1993 return;
1988 1994
1989 if (_clean_up_rect_coordinates(ty, &top, &left, &bottom, &right) < 0) 1995 if (_clean_up_rect_coordinates(ty, &top, &left, &bottom, &right) < 0)
@@ -2014,14 +2020,14 @@ _handle_esc_csi_deccra(Termpty *ty, Eina_Unicode **b)
2014 2020
2015 DBG("DECFRA (%d;%d;%d;%d -> %d;%d) Copy Rectangular Area", 2021 DBG("DECFRA (%d;%d;%d;%d -> %d;%d) Copy Rectangular Area",
2016 top, left, bottom, right, to_top, to_left); 2022 top, left, bottom, right, to_top, to_left);
2017 if ((top == -CSI_ARG_ERROR) || 2023 if ((top == -ESC_ARG_ERROR) ||
2018 (left == -CSI_ARG_ERROR) || 2024 (left == -ESC_ARG_ERROR) ||
2019 (bottom == -CSI_ARG_ERROR) || 2025 (bottom == -ESC_ARG_ERROR) ||
2020 (right == -CSI_ARG_ERROR) || 2026 (right == -ESC_ARG_ERROR) ||
2021 (p1 == -CSI_ARG_ERROR) || 2027 (p1 == -ESC_ARG_ERROR) ||
2022 (to_top == -CSI_ARG_ERROR) || 2028 (to_top == -ESC_ARG_ERROR) ||
2023 (to_left == -CSI_ARG_ERROR) || 2029 (to_left == -ESC_ARG_ERROR) ||
2024 (p2 == -CSI_ARG_ERROR)) 2030 (p2 == -ESC_ARG_ERROR))
2025 return; 2031 return;
2026 2032
2027 if (_clean_up_rect_coordinates(ty, &top, &left, &bottom, &right) < 0) 2033 if (_clean_up_rect_coordinates(ty, &top, &left, &bottom, &right) < 0)
@@ -2131,7 +2137,7 @@ _handle_esc_csi_cursor_pos_set(Termpty *ty, Eina_Unicode **b,
2131 cy = _csi_arg_get(ty, b); 2137 cy = _csi_arg_get(ty, b);
2132 cx = _csi_arg_get(ty, b); 2138 cx = _csi_arg_get(ty, b);
2133 2139
2134 if ((cx == -CSI_ARG_ERROR) || (cy == -CSI_ARG_ERROR)) 2140 if ((cx == -ESC_ARG_ERROR) || (cy == -ESC_ARG_ERROR))
2135 return; 2141 return;
2136 2142
2137 DBG("cursor pos set (%s) (%d;%d)", (*cc == 'H') ? "CUP" : "HVP", 2143 DBG("cursor pos set (%s) (%d;%d)", (*cc == 'H') ? "CUP" : "HVP",
@@ -2174,9 +2180,9 @@ _handle_esc_csi_decscusr(Termpty *ty, Eina_Unicode **b)
2174 2180
2175 switch (arg) 2181 switch (arg)
2176 { 2182 {
2177 case -CSI_ARG_ERROR: 2183 case -ESC_ARG_ERROR:
2178 return; 2184 return;
2179 case -CSI_ARG_NO_VALUE: 2185 case -ESC_ARG_NO_VALUE:
2180 EINA_FALLTHROUGH; 2186 EINA_FALLTHROUGH;
2181 case 0: 2187 case 0:
2182 EINA_FALLTHROUGH; 2188 EINA_FALLTHROUGH;
@@ -2213,9 +2219,9 @@ _handle_esc_csi_decsace(Termpty *ty, Eina_Unicode **b)
2213 2219
2214 switch (arg) 2220 switch (arg)
2215 { 2221 {
2216 case -CSI_ARG_ERROR: 2222 case -ESC_ARG_ERROR:
2217 return; 2223 return;
2218 case -CSI_ARG_NO_VALUE: 2224 case -ESC_ARG_NO_VALUE:
2219 EINA_FALLTHROUGH; 2225 EINA_FALLTHROUGH;
2220 case 0: 2226 case 0:
2221 EINA_FALLTHROUGH; 2227 EINA_FALLTHROUGH;
@@ -2245,7 +2251,7 @@ _handle_esc_csi_decic(Termpty *ty, Eina_Unicode **b)
2245 2251
2246 DBG("DECIC Insert %d Column", arg); 2252 DBG("DECIC Insert %d Column", arg);
2247 2253
2248 if (arg == -CSI_ARG_ERROR) 2254 if (arg == -ESC_ARG_ERROR)
2249 return; 2255 return;
2250 if (arg < 1) 2256 if (arg < 1)
2251 arg = 1; 2257 arg = 1;
@@ -2296,7 +2302,7 @@ _handle_esc_csi_decdc(Termpty *ty, Eina_Unicode **b)
2296 2302
2297 DBG("DECDC Delete %d Column", arg); 2303 DBG("DECDC Delete %d Column", arg);
2298 2304
2299 if (arg == -CSI_ARG_ERROR) 2305 if (arg == -ESC_ARG_ERROR)
2300 return; 2306 return;
2301 if (arg < 1) 2307 if (arg < 1)
2302 arg = 1; 2308 arg = 1;
@@ -2359,7 +2365,7 @@ _handle_esc_csi_ich(Termpty *ty, Eina_Unicode **ptr)
2359 int old_cx = ty->cursor_state.cx; 2365 int old_cx = ty->cursor_state.cx;
2360 int max = ty->w; 2366 int max = ty->w;
2361 2367
2362 if (arg == -CSI_ARG_ERROR) 2368 if (arg == -ESC_ARG_ERROR)
2363 return; 2369 return;
2364 TERMPTY_RESTRICT_FIELD(arg, 1, ty->w * ty->h); 2370 TERMPTY_RESTRICT_FIELD(arg, 1, ty->w * ty->h);
2365 2371
@@ -2401,7 +2407,7 @@ _handle_esc_csi_cuu(Termpty *ty, Eina_Unicode **ptr)
2401 Eina_Unicode *b = *ptr; 2407 Eina_Unicode *b = *ptr;
2402 int arg = _csi_arg_get(ty, &b); 2408 int arg = _csi_arg_get(ty, &b);
2403 2409
2404 if (arg == -CSI_ARG_ERROR) 2410 if (arg == -ESC_ARG_ERROR)
2405 return; 2411 return;
2406 if (arg < 1) 2412 if (arg < 1)
2407 arg = 1; 2413 arg = 1;
@@ -2423,7 +2429,7 @@ _handle_esc_csi_cud_or_vpr(Termpty *ty, Eina_Unicode **ptr,
2423 Eina_Unicode *b = *ptr; 2429 Eina_Unicode *b = *ptr;
2424 int arg = _csi_arg_get(ty, &b); 2430 int arg = _csi_arg_get(ty, &b);
2425 2431
2426 if (arg == -CSI_ARG_ERROR) 2432 if (arg == -ESC_ARG_ERROR)
2427 return; 2433 return;
2428 2434
2429 if (arg < 1) 2435 if (arg < 1)
@@ -2454,7 +2460,7 @@ _handle_esc_csi_cuf(Termpty *ty, Eina_Unicode **ptr)
2454 Eina_Unicode *b = *ptr; 2460 Eina_Unicode *b = *ptr;
2455 int arg = _csi_arg_get(ty, &b); 2461 int arg = _csi_arg_get(ty, &b);
2456 2462
2457 if (arg == -CSI_ARG_ERROR) 2463 if (arg == -ESC_ARG_ERROR)
2458 return; 2464 return;
2459 if (arg < 1) 2465 if (arg < 1)
2460 arg = 1; 2466 arg = 1;
@@ -2475,7 +2481,7 @@ _handle_esc_csi_cub(Termpty *ty, Eina_Unicode **ptr)
2475 Eina_Unicode *b = *ptr; 2481 Eina_Unicode *b = *ptr;
2476 int arg = _csi_arg_get(ty, &b); 2482 int arg = _csi_arg_get(ty, &b);
2477 2483
2478 if (arg == -CSI_ARG_ERROR) 2484 if (arg == -ESC_ARG_ERROR)
2479 return; 2485 return;
2480 if (arg < 1) 2486 if (arg < 1)
2481 arg = 1; 2487 arg = 1;
@@ -2507,7 +2513,7 @@ _handle_esc_csi_cha(Termpty *ty, Eina_Unicode **ptr,
2507 { 2513 {
2508 DBG("CHA - Cursor Horizontal Absolute: %d", arg); 2514 DBG("CHA - Cursor Horizontal Absolute: %d", arg);
2509 } 2515 }
2510 if (arg == -CSI_ARG_ERROR) 2516 if (arg == -ESC_ARG_ERROR)
2511 return; 2517 return;
2512 if (arg < 1) 2518 if (arg < 1)
2513 arg = 1; 2519 arg = 1;
@@ -2533,7 +2539,7 @@ _handle_esc_csi_cht(Termpty *ty, Eina_Unicode **ptr)
2533 Eina_Unicode *b = *ptr; 2539 Eina_Unicode *b = *ptr;
2534 int arg = _csi_arg_get(ty, &b); 2540 int arg = _csi_arg_get(ty, &b);
2535 2541
2536 if (arg == -CSI_ARG_ERROR) 2542 if (arg == -ESC_ARG_ERROR)
2537 return; 2543 return;
2538 TERMPTY_RESTRICT_FIELD(arg, 1, ty->w); 2544 TERMPTY_RESTRICT_FIELD(arg, 1, ty->w);
2539 DBG("CHT - Cursor Forward Tabulation: %d", arg); 2545 DBG("CHT - Cursor Forward Tabulation: %d", arg);
@@ -2546,7 +2552,7 @@ _handle_esc_csi_ed(Termpty *ty, Eina_Unicode **ptr)
2546 Eina_Unicode *b = *ptr; 2552 Eina_Unicode *b = *ptr;
2547 int arg = _csi_arg_get(ty, &b); 2553 int arg = _csi_arg_get(ty, &b);
2548 2554
2549 if (arg == -CSI_ARG_ERROR) 2555 if (arg == -ESC_ARG_ERROR)
2550 return; 2556 return;
2551 if (arg < 1) 2557 if (arg < 1)
2552 arg = 0; 2558 arg = 0;
@@ -2586,7 +2592,7 @@ _handle_esc_csi_el(Termpty *ty, Eina_Unicode **ptr)
2586 Eina_Unicode *b = *ptr; 2592 Eina_Unicode *b = *ptr;
2587 int arg = _csi_arg_get(ty, &b); 2593 int arg = _csi_arg_get(ty, &b);
2588 2594
2589 if (arg == -CSI_ARG_ERROR) 2595 if (arg == -ESC_ARG_ERROR)
2590 return; 2596 return;
2591 if (arg < 1) 2597 if (arg < 1)
2592 arg = 0; 2598 arg = 0;
@@ -2618,7 +2624,7 @@ _handle_esc_csi_il(Termpty *ty, Eina_Unicode **ptr)
2618 int arg = _csi_arg_get(ty, &b); 2624 int arg = _csi_arg_get(ty, &b);
2619 int sy1, sy2, i; 2625 int sy1, sy2, i;
2620 2626
2621 if (arg == -CSI_ARG_ERROR) 2627 if (arg == -ESC_ARG_ERROR)
2622 return; 2628 return;
2623 2629
2624 TERMPTY_RESTRICT_FIELD(arg, 1, ty->h); 2630 TERMPTY_RESTRICT_FIELD(arg, 1, ty->h);
@@ -2656,7 +2662,7 @@ _handle_esc_csi_dl(Termpty *ty, Eina_Unicode **ptr)
2656 int arg = _csi_arg_get(ty, &b); 2662 int arg = _csi_arg_get(ty, &b);
2657 int sy1, sy2, i; 2663 int sy1, sy2, i;
2658 2664
2659 if (arg == -CSI_ARG_ERROR) 2665 if (arg == -ESC_ARG_ERROR)
2660 return; 2666 return;
2661 2667
2662 TERMPTY_RESTRICT_FIELD(arg, 1, ty->h); 2668 TERMPTY_RESTRICT_FIELD(arg, 1, ty->h);
@@ -2694,7 +2700,7 @@ _handle_esc_csi_su(Termpty *ty, Eina_Unicode **ptr)
2694 int arg = _csi_arg_get(ty, &b); 2700 int arg = _csi_arg_get(ty, &b);
2695 int i; 2701 int i;
2696 2702
2697 if (arg == -CSI_ARG_ERROR) 2703 if (arg == -ESC_ARG_ERROR)
2698 return; 2704 return;
2699 2705
2700 TERMPTY_RESTRICT_FIELD(arg, 1, ty->h); 2706 TERMPTY_RESTRICT_FIELD(arg, 1, ty->h);
@@ -2710,7 +2716,7 @@ _handle_esc_csi_sd(Termpty *ty, Eina_Unicode **ptr)
2710 int arg = _csi_arg_get(ty, &b); 2716 int arg = _csi_arg_get(ty, &b);
2711 int i; 2717 int i;
2712 2718
2713 if (arg == -CSI_ARG_ERROR) 2719 if (arg == -ESC_ARG_ERROR)
2714 return; 2720 return;
2715 if (arg == 0) 2721 if (arg == 0)
2716 { 2722 {
@@ -2746,9 +2752,9 @@ _handle_esc_csi_decst8c(Termpty *ty, Eina_Unicode **ptr)
2746 int arg = _csi_arg_get(ty, &b); 2752 int arg = _csi_arg_get(ty, &b);
2747 int i; 2753 int i;
2748 2754
2749 if (arg == -CSI_ARG_ERROR) 2755 if (arg == -ESC_ARG_ERROR)
2750 return; 2756 return;
2751 if ((arg != -CSI_ARG_NO_VALUE) && (arg != 5)) 2757 if ((arg != -ESC_ARG_NO_VALUE) && (arg != 5))
2752 { 2758 {
2753 ERR("Invalid DECST8C argument"); 2759 ERR("Invalid DECST8C argument");
2754 ty->decoding_error = EINA_TRUE; 2760 ty->decoding_error = EINA_TRUE;
@@ -2769,13 +2775,13 @@ _handle_esc_csi_ctc(Termpty *ty, Eina_Unicode **ptr)
2769 Eina_Unicode *b = *ptr; 2775 Eina_Unicode *b = *ptr;
2770 int arg = _csi_arg_get(ty, &b); 2776 int arg = _csi_arg_get(ty, &b);
2771 2777
2772 if (arg == -CSI_ARG_ERROR) 2778 if (arg == -ESC_ARG_ERROR)
2773 return; 2779 return;
2774 2780
2775 DBG("CTC - Cursor Tab Control: %d", arg); 2781 DBG("CTC - Cursor Tab Control: %d", arg);
2776 switch (arg) 2782 switch (arg)
2777 { 2783 {
2778 case -CSI_ARG_NO_VALUE: 2784 case -ESC_ARG_NO_VALUE:
2779 EINA_FALLTHROUGH; 2785 EINA_FALLTHROUGH;
2780 case 0: 2786 case 0:
2781 TAB_SET(ty, ty->cursor_state.cx); 2787 TAB_SET(ty, ty->cursor_state.cx);
@@ -2800,12 +2806,12 @@ _handle_esc_csi_tbc(Termpty *ty, Eina_Unicode **ptr)
2800 Eina_Unicode *b = *ptr; 2806 Eina_Unicode *b = *ptr;
2801 int arg = _csi_arg_get(ty, &b); 2807 int arg = _csi_arg_get(ty, &b);
2802 2808
2803 if (arg == -CSI_ARG_ERROR) 2809 if (arg == -ESC_ARG_ERROR)
2804 return; 2810 return;
2805 DBG("TBC - Tab Clear: %d", arg); 2811 DBG("TBC - Tab Clear: %d", arg);
2806 switch (arg) 2812 switch (arg)
2807 { 2813 {
2808 case -CSI_ARG_NO_VALUE: 2814 case -ESC_ARG_NO_VALUE:
2809 EINA_FALLTHROUGH; 2815 EINA_FALLTHROUGH;
2810 case 0: 2816 case 0:
2811 TAB_UNSET(ty, ty->cursor_state.cx); 2817 TAB_UNSET(ty, ty->cursor_state.cx);
@@ -2829,7 +2835,7 @@ _handle_esc_csi_ech(Termpty *ty, Eina_Unicode **ptr)
2829 Eina_Unicode *b = *ptr; 2835 Eina_Unicode *b = *ptr;
2830 int arg = _csi_arg_get(ty, &b); 2836 int arg = _csi_arg_get(ty, &b);
2831 2837
2832 if (arg == -CSI_ARG_ERROR) 2838 if (arg == -ESC_ARG_ERROR)
2833 return; 2839 return;
2834 DBG("ECH - Erase Character: %d", arg); 2840 DBG("ECH - Erase Character: %d", arg);
2835 TERMPTY_RESTRICT_FIELD(arg, 1, ty->w); 2841 TERMPTY_RESTRICT_FIELD(arg, 1, ty->w);
@@ -2843,7 +2849,7 @@ _handle_esc_csi_cbt(Termpty *ty, Eina_Unicode **ptr)
2843 int cx = ty->cursor_state.cx; 2849 int cx = ty->cursor_state.cx;
2844 int arg = _csi_arg_get(ty, &b); 2850 int arg = _csi_arg_get(ty, &b);
2845 2851
2846 if (arg == -CSI_ARG_ERROR) 2852 if (arg == -ESC_ARG_ERROR)
2847 return; 2853 return;
2848 DBG("CBT - Cursor Horizontal Backward Tabulation: %d", arg); 2854 DBG("CBT - Cursor Horizontal Backward Tabulation: %d", arg);
2849 2855
@@ -2867,7 +2873,7 @@ _handle_esc_csi_rep(Termpty *ty, Eina_Unicode **ptr)
2867 Eina_Unicode *b = *ptr; 2873 Eina_Unicode *b = *ptr;
2868 int arg = _csi_arg_get(ty, &b); 2874 int arg = _csi_arg_get(ty, &b);
2869 2875
2870 if (arg == -CSI_ARG_ERROR) 2876 if (arg == -ESC_ARG_ERROR)
2871 return; 2877 return;
2872 DBG("REP - Repeat last character %d times", arg); 2878 DBG("REP - Repeat last character %d times", arg);
2873 2879
@@ -2909,7 +2915,7 @@ _handle_esc_csi_da(Termpty *ty, Eina_Unicode **ptr)
2909 } 2915 }
2910 arg = _csi_arg_get(ty, &b); 2916 arg = _csi_arg_get(ty, &b);
2911 2917
2912 if ((arg == -CSI_ARG_ERROR) || (arg > 0)) 2918 if ((arg == -ESC_ARG_ERROR) || (arg > 0))
2913 return; 2919 return;
2914 2920
2915 DBG("DA - Device Attributes"); 2921 DBG("DA - Device Attributes");
@@ -2971,7 +2977,7 @@ _handle_esc_csi_uts(Termpty *ty, Eina_Unicode **ptr)
2971 Eina_Unicode *b = *ptr; 2977 Eina_Unicode *b = *ptr;
2972 int arg = _csi_arg_get(ty, &b); 2978 int arg = _csi_arg_get(ty, &b);
2973 2979
2974 if (arg == -CSI_ARG_ERROR) 2980 if (arg == -ESC_ARG_ERROR)
2975 return; 2981 return;
2976 DBG("UTS - Unset Tab Stop: %d", arg); 2982 DBG("UTS - Unset Tab Stop: %d", arg);
2977 TERMPTY_RESTRICT_FIELD(arg, 0, ty->w); 2983 TERMPTY_RESTRICT_FIELD(arg, 0, ty->w);
@@ -2985,7 +2991,7 @@ _handle_esc_csi_vpa(Termpty *ty, Eina_Unicode **ptr)
2985 int arg = _csi_arg_get(ty, &b); 2991 int arg = _csi_arg_get(ty, &b);
2986 int max = ty->h + 1; 2992 int max = ty->h + 1;
2987 2993
2988 if (arg == -CSI_ARG_ERROR) 2994 if (arg == -ESC_ARG_ERROR)
2989 return; 2995 return;
2990 DBG("VPA - Cursor Vertical Position Absolute: %d", arg); 2996 DBG("VPA - Cursor Vertical Position Absolute: %d", arg);
2991 if (ty->termstate.restrict_cursor && (ty->termstate.bottom_margin > 0)) 2997 if (ty->termstate.restrict_cursor && (ty->termstate.bottom_margin > 0))
@@ -3003,7 +3009,7 @@ _handle_esc_csi_decswbv(Termpty *ty, Eina_Unicode **ptr)
3003 Eina_Unicode *b = *ptr; 3009 Eina_Unicode *b = *ptr;
3004 int arg = _csi_arg_get(ty, &b); 3010 int arg = _csi_arg_get(ty, &b);
3005 3011
3006 if (arg == -CSI_ARG_ERROR) 3012 if (arg == -ESC_ARG_ERROR)
3007 return; 3013 return;
3008 DBG("DECSWBV - Set Warning Bell Volume: %d", arg); 3014 DBG("DECSWBV - Set Warning Bell Volume: %d", arg);
3009 switch (arg) 3015 switch (arg)
@@ -3032,13 +3038,13 @@ _handle_resize_by_chars(Termpty *ty, Eina_Unicode **ptr)
3032 h = _csi_arg_get(ty, &b); 3038 h = _csi_arg_get(ty, &b);
3033 w = _csi_arg_get(ty, &b); 3039 w = _csi_arg_get(ty, &b);
3034 3040
3035 if ((w == -CSI_ARG_ERROR) || (h == -CSI_ARG_ERROR)) 3041 if ((w == -ESC_ARG_ERROR) || (h == -ESC_ARG_ERROR))
3036 return; 3042 return;
3037 if (w == -CSI_ARG_NO_VALUE) 3043 if (w == -ESC_ARG_NO_VALUE)
3038 { 3044 {
3039 w = ty->w; 3045 w = ty->w;
3040 } 3046 }
3041 if (h == -CSI_ARG_NO_VALUE) 3047 if (h == -ESC_ARG_NO_VALUE)
3042 { 3048 {
3043 h = ty->h; 3049 h = ty->h;
3044 } 3050 }
@@ -3069,13 +3075,107 @@ _handle_resize_by_chars(Termpty *ty, Eina_Unicode **ptr)
3069#endif 3075#endif
3070} 3076}
3071 3077
3078struct _TitleIconElem {
3079 const char *title;
3080 const char *icon;
3081 struct _TitleIconElem *next;
3082};
3083
3084static void
3085_title_icon_stack_push(Termpty *ty, Eina_Unicode **p)
3086{
3087 int arg = _csi_arg_get(ty, p);
3088 TitleIconElem *elem = calloc(sizeof(*elem), 1);
3089
3090 if (!elem)
3091 return;
3092
3093
3094 switch (arg)
3095 {
3096 case -ESC_ARG_ERROR:
3097 free(elem);
3098 return;
3099 case -ESC_ARG_NO_VALUE:
3100 EINA_FALLTHROUGH;
3101 case 0:
3102 elem->title = eina_stringshare_ref(ty->prop.title);
3103 elem->icon = eina_stringshare_ref(ty->prop.icon);
3104 break;
3105 case 1:
3106 elem->icon = eina_stringshare_ref(ty->prop.icon);
3107 break;
3108 case 2:
3109 elem->title = eina_stringshare_ref(ty->prop.title);
3110 break;
3111 default:
3112 break;
3113 }
3114 if (!elem->title)
3115 elem->title = ty->title_icon_stack ?
3116 eina_stringshare_ref(ty->title_icon_stack->title) :
3117 eina_stringshare_ref(ty->prop.title);
3118 if (!elem->icon)
3119 elem->icon = ty->title_icon_stack ?
3120 eina_stringshare_ref(ty->title_icon_stack->icon) :
3121 eina_stringshare_ref(ty->prop.icon);
3122 elem->next = ty->title_icon_stack;
3123 ty->title_icon_stack = elem;
3124}
3125
3126static void
3127_title_icon_stack_pop(Termpty *ty, Eina_Unicode **p)
3128{
3129 int arg = _csi_arg_get(ty, p);
3130 TitleIconElem *elem = ty->title_icon_stack;
3131
3132 if (!elem)
3133 return;
3134
3135 switch (arg)
3136 {
3137 case -ESC_ARG_ERROR:
3138 return;
3139 case -ESC_ARG_NO_VALUE:
3140 EINA_FALLTHROUGH;
3141 case 0:
3142 eina_stringshare_del(ty->prop.icon);
3143 ty->prop.icon = eina_stringshare_ref(elem->icon);
3144 if (ty->cb.set_icon.func)
3145 ty->cb.set_icon.func(ty->cb.set_icon.data);
3146 eina_stringshare_del(ty->prop.title);
3147 ty->prop.title = eina_stringshare_ref(elem->title);
3148 if (ty->cb.set_title.func)
3149 ty->cb.set_title.func(ty->cb.set_title.data);
3150 break;
3151 case 1:
3152 eina_stringshare_del(ty->prop.icon);
3153 ty->prop.icon = eina_stringshare_ref(elem->icon);
3154 if (ty->cb.set_icon.func)
3155 ty->cb.set_icon.func(ty->cb.set_icon.data);
3156 break;
3157 case 2:
3158 eina_stringshare_del(ty->prop.title);
3159 ty->prop.title = eina_stringshare_ref(elem->title);
3160 if (ty->cb.set_title.func)
3161 ty->cb.set_title.func(ty->cb.set_title.data);
3162 break;
3163 default:
3164 break;
3165 }
3166 eina_stringshare_del(elem->icon);
3167 eina_stringshare_del(elem->title);
3168 ty->title_icon_stack = elem->next;
3169 free(elem);
3170}
3171
3072static void 3172static void
3073_handle_window_manipulation(Termpty *ty, Eina_Unicode **ptr) 3173_handle_window_manipulation(Termpty *ty, Eina_Unicode **ptr)
3074{ 3174{
3075 Eina_Unicode *b = *ptr; 3175 Eina_Unicode *b = *ptr;
3076 int arg = _csi_arg_get(ty, &b); 3176 int arg = _csi_arg_get(ty, &b);
3077 3177
3078 if (arg == -CSI_ARG_ERROR) 3178 if (arg == -ESC_ARG_ERROR)
3079 return; 3179 return;
3080 DBG("Window manipulation: %d", arg); 3180 DBG("Window manipulation: %d", arg);
3081 switch (arg) 3181 switch (arg)
@@ -3083,6 +3183,12 @@ _handle_window_manipulation(Termpty *ty, Eina_Unicode **ptr)
3083 case 8: 3183 case 8:
3084 _handle_resize_by_chars(ty, &b); 3184 _handle_resize_by_chars(ty, &b);
3085 break; 3185 break;
3186 case 22:
3187 _title_icon_stack_push(ty, &b);
3188 break;
3189 case 23:
3190 _title_icon_stack_pop(ty, &b);
3191 break;
3086 default: 3192 default:
3087 // many others 3193 // many others
3088 WRN("unhandled window manipulation %d", arg); 3194 WRN("unhandled window manipulation %d", arg);
@@ -3381,22 +3487,44 @@ unhandled:
3381} 3487}
3382 3488
3383static int 3489static int
3384_osc_arg_get(Eina_Unicode **ptr) 3490_osc_arg_get(Termpty *ty, Eina_Unicode **ptr)
3385{ 3491{
3386 Eina_Unicode *b = *ptr; 3492 Eina_Unicode *b = *ptr;
3387 int sum = 0; 3493 int sum = 0;
3388 3494
3495 if ((b == NULL) || (*b == '\0'))
3496 {
3497 *ptr = NULL;
3498 sum = -ESC_ARG_NO_VALUE;
3499 goto error;
3500 }
3501
3389 while (*b >= '0' && *b <= '9') 3502 while (*b >= '0' && *b <= '9')
3390 { 3503 {
3391 sum *= 10; 3504 sum *= 10;
3392 sum += *b - '0'; 3505 sum += *b - '0';
3393 b++; 3506 b++;
3507 if (sum >= 65536)
3508 {
3509 sum = -ESC_ARG_ERROR;
3510 goto error;
3511 }
3394 } 3512 }
3395 if (*b != ';') 3513 if (*b != ';')
3396 sum = -1; 3514 {
3515 sum = -ESC_ARG_ERROR;
3516 goto error;
3517 }
3397 else 3518 else
3398 b++; 3519 b++;
3399 *ptr = b; 3520 *ptr = b;
3521
3522 return sum;
3523
3524error:
3525 ERR("Invalid OSC argument");
3526 ty->decoding_error = EINA_TRUE;
3527 *ptr = NULL;
3400 return sum; 3528 return sum;
3401} 3529}
3402 3530
@@ -3412,23 +3540,6 @@ _eina_unicode_to_hex(Eina_Unicode u)
3412 return -1; 3540 return -1;
3413} 3541}
3414 3542
3415#if defined(__OpenBSD__)
3416char *
3417strchrnul(const char *s, int c)
3418{
3419 const char *p = s;
3420
3421 while (*p)
3422 {
3423 if (*p == c)
3424 return (char *)p;
3425
3426 ++p;
3427 }
3428 return (char *) (p);
3429}
3430#endif
3431
3432static int 3543static int
3433_xterm_parse_color(Termpty *ty, Eina_Unicode **ptr, 3544_xterm_parse_color(Termpty *ty, Eina_Unicode **ptr,
3434 unsigned char *r, unsigned char *g, unsigned char *b, 3545 unsigned char *r, unsigned char *g, unsigned char *b,
@@ -3722,18 +3833,20 @@ _handle_esc_osc(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce)
3722 else 3833 else
3723 return 0; 3834 return 0;
3724 3835
3725 arg = _osc_arg_get(&p); 3836 arg = _osc_arg_get(ty, &p);
3726 switch (arg) 3837 switch (arg)
3727 { 3838 {
3728 case -1: 3839 case -ESC_ARG_ERROR:
3729 goto err; 3840 goto err;
3841 case -ESC_ARG_NO_VALUE:
3842 EINA_FALLTHROUGH;
3730 case 0: 3843 case 0:
3731 // title + icon name 3844 // title + icon name
3732 if (!*p) 3845 if (!*p)
3733 goto err; 3846 goto err;
3734 s = eina_unicode_unicode_to_utf8(p, &len); 3847 s = eina_unicode_unicode_to_utf8(p, &len);
3735 if (ty->prop.title) eina_stringshare_del(ty->prop.title); 3848 eina_stringshare_del(ty->prop.title);
3736 if (ty->prop.icon) eina_stringshare_del(ty->prop.icon); 3849 eina_stringshare_del(ty->prop.icon);
3737 if (s) 3850 if (s)
3738 { 3851 {
3739 ty->prop.title = eina_stringshare_add(s); 3852 ty->prop.title = eina_stringshare_add(s);
@@ -3747,14 +3860,15 @@ _handle_esc_osc(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce)
3747 } 3860 }
3748 if (ty->cb.set_title.func) 3861 if (ty->cb.set_title.func)
3749 ty->cb.set_title.func(ty->cb.set_title.data); 3862 ty->cb.set_title.func(ty->cb.set_title.data);
3750 if (ty->cb.set_icon.func) ty->cb.set_icon.func(ty->cb.set_icon.data); 3863 if (ty->cb.set_icon.func)
3864 ty->cb.set_icon.func(ty->cb.set_icon.data);
3751 break; 3865 break;
3752 case 1: 3866 case 1:
3753 // icon name 3867 // icon name
3754 if (!*p) 3868 if (!*p)
3755 goto err; 3869 goto err;
3756 s = eina_unicode_unicode_to_utf8(p, &len); 3870 s = eina_unicode_unicode_to_utf8(p, &len);
3757 if (ty->prop.icon) eina_stringshare_del(ty->prop.icon); 3871 eina_stringshare_del(ty->prop.icon);
3758 if (s) 3872 if (s)
3759 { 3873 {
3760 ty->prop.icon = eina_stringshare_add(s); 3874 ty->prop.icon = eina_stringshare_add(s);
@@ -3771,7 +3885,7 @@ _handle_esc_osc(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce)
3771 if (!*p) 3885 if (!*p)
3772 goto err; 3886 goto err;
3773 s = eina_unicode_unicode_to_utf8(p, &len); 3887 s = eina_unicode_unicode_to_utf8(p, &len);
3774 if (ty->prop.title) eina_stringshare_del(ty->prop.title); 3888 eina_stringshare_del(ty->prop.title);
3775 if (s) 3889 if (s)
3776 { 3890 {
3777 ty->prop.title = eina_stringshare_add(s); 3891 ty->prop.title = eina_stringshare_add(s);
diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c
index dfc7558..5a95408 100644
--- a/src/bin/termptyops.c
+++ b/src/bin/termptyops.c
@@ -5,7 +5,7 @@
5#include "termptydbl.h" 5#include "termptydbl.h"
6#include "termptyops.h" 6#include "termptyops.h"
7#include "termptygfx.h" 7#include "termptygfx.h"
8#include "termptysave.h" 8#include "backlog.h"
9#include "miniview.h" 9#include "miniview.h"
10#include <assert.h> 10#include <assert.h>
11 11
@@ -317,30 +317,6 @@ termpty_clear_tabs_on_screen(Termpty *ty)
317} 317}
318 318
319void 319void
320termpty_clear_backlog(Termpty *ty)
321{
322 int backsize;
323
324 ty->backlog_beacon.screen_y = 0;
325 ty->backlog_beacon.backlog_y = 0;
326
327 termpty_backlog_lock();
328 if (ty->back)
329 {
330 size_t i;
331 for (i = 0; i < ty->backsize; i++)
332 termpty_save_free(ty, &ty->back[i]);
333 free(ty->back);
334 ty->back = NULL;
335 }
336 ty->backpos = 0;
337 backsize = ty->backsize;
338 ty->backsize = 0;
339 termpty_backlog_size_set(ty, backsize);
340 termpty_backlog_unlock();
341}
342
343void
344termpty_clear_screen(Termpty *ty, Termpty_Clear mode) 320termpty_clear_screen(Termpty *ty, Termpty_Clear mode)
345{ 321{
346 Termcell *cells; 322 Termcell *cells;
@@ -427,6 +403,8 @@ termpty_reset_att(Termatt *att)
427 att->framed = 0; 403 att->framed = 0;
428 att->encircled = 0; 404 att->encircled = 0;
429 att->overlined = 0; 405 att->overlined = 0;
406 att->tab_inserted = 0;
407 att->tab_last = 0;
430} 408}
431 409
432void 410void
diff --git a/src/bin/termptysave.c b/src/bin/termptysave.c
deleted file mode 100644
index afb9db4..0000000
--- a/src/bin/termptysave.c
+++ /dev/null
@@ -1,91 +0,0 @@
1#include "private.h"
2#include <Elementary.h>
3#include "termpty.h"
4#include "termptysave.h"
5
6
7static int ts_comp = 0;
8static int ts_uncomp = 0;
9static int ts_freeops = 0;
10static Eina_List *ptys = NULL;
11
12void
13termpty_save_register(Termpty *ty)
14{
15 termpty_backlog_lock();
16 ptys = eina_list_append(ptys, ty);
17 termpty_backlog_unlock();
18}
19
20void
21termpty_save_unregister(Termpty *ty)
22{
23 termpty_backlog_lock();
24 ptys = eina_list_remove(ptys, ty);
25 termpty_backlog_unlock();
26}
27
28Termsave *
29termpty_save_extract(Termsave *ts)
30{
31 if (!ts) return NULL;
32 return ts;
33}
34
35Termsave *
36termpty_save_new(Termpty *ty, Termsave *ts, int w)
37{
38 termpty_save_free(ty, ts);
39
40 Termcell *cells = calloc(1, w * sizeof(Termcell));
41 if (!cells ) return NULL;
42 ts->cells = cells;
43 ts->w = w;
44 return ts;
45}
46
47Termsave *
48termpty_save_expand(Termpty *ty, Termsave *ts, Termcell *cells, size_t delta)
49{
50 Termcell *newcells;
51
52 newcells = realloc(ts->cells, (ts->w + delta) * sizeof(Termcell));
53 if (!newcells)
54 return NULL;
55
56 memset(newcells + ts->w,
57 0, delta * sizeof(Termcell));
58 TERMPTY_CELL_COPY(ty, cells, &newcells[ts->w], (int)delta);
59
60 ts->w += delta;
61 ts->cells = newcells;
62 return ts;
63}
64
65void
66termpty_save_free(Termpty *ty, Termsave *ts)
67{
68 unsigned int i;
69 if (!ts) return;
70 if (ts->comp) ts_comp--;
71 else ts_uncomp--;
72 ts_freeops++;
73 for (i = 0; i < ts->w; i++)
74 {
75 if (EINA_UNLIKELY(ts->cells[i].att.link_id))
76 term_link_refcount_dec(ty, ts->cells[i].att.link_id, 1);
77 }
78 free(ts->cells);
79 ts->cells = NULL;
80 ts->w = 0;
81}
82
83void
84termpty_backlog_lock(void)
85{
86}
87
88void
89termpty_backlog_unlock(void)
90{
91}
diff --git a/src/bin/termptysave.h b/src/bin/termptysave.h
deleted file mode 100644
index 91132ef..0000000
--- a/src/bin/termptysave.h
+++ /dev/null
@@ -1,12 +0,0 @@
1#ifndef _TERMPTY_SAVE_H__
2#define _TERMPTY_SAVE_H__ 1
3
4void termpty_save_register(Termpty *ty);
5void termpty_save_unregister(Termpty *ty);
6Termsave *termpty_save_extract(Termsave *ts);
7Termsave *termpty_save_new(Termpty *ty, Termsave *ts, int w);
8void termpty_save_free(Termpty *ty, Termsave *ts);
9Termsave *termpty_save_expand(Termpty *ty, Termsave *ts,
10 Termcell *cells, size_t delta);
11
12#endif
diff --git a/src/bin/tyalpha.c b/src/bin/tyalpha.c
index 63cdfaa..ce22792 100644
--- a/src/bin/tyalpha.c
+++ b/src/bin/tyalpha.c
@@ -45,7 +45,8 @@ main(int argc, char **argv)
45 snprintf(tbuf, sizeof(tbuf), "%c}ap%s", 0x1b, argv[i]); 45 snprintf(tbuf, sizeof(tbuf), "%c}ap%s", 0x1b, argv[i]);
46 else 46 else
47 snprintf(tbuf, sizeof(tbuf), "%c}at%s", 0x1b, argv[i]); 47 snprintf(tbuf, sizeof(tbuf), "%c}at%s", 0x1b, argv[i]);
48 if (write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1)) perror("write"); 48 if (ty_write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1))
49 perror("write");
49 } 50 }
50 return 0; 51 return 0;
51} 52}
diff --git a/src/bin/tybg.c b/src/bin/tybg.c
index 53c9b02..e797466 100644
--- a/src/bin/tybg.c
+++ b/src/bin/tybg.c
@@ -29,7 +29,8 @@ main(int argc, char **argv)
29 { 29 {
30 char tbuf[32]; 30 char tbuf[32];
31 snprintf(tbuf, sizeof(tbuf), "%c}bt", 0x1b); 31 snprintf(tbuf, sizeof(tbuf), "%c}bt", 0x1b);
32 if (write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1)) perror("write"); 32 if (ty_write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1))
33 perror("write");
33 return 0; 34 return 0;
34 } 35 }
35 for (i = 1; i < argc; i++) 36 for (i = 1; i < argc; i++)
@@ -48,7 +49,8 @@ main(int argc, char **argv)
48 snprintf(tbuf, sizeof(tbuf), "%c}bp%s", 0x1b, path); 49 snprintf(tbuf, sizeof(tbuf), "%c}bp%s", 0x1b, path);
49 else 50 else
50 snprintf(tbuf, sizeof(tbuf), "%c}bt%s", 0x1b, path); 51 snprintf(tbuf, sizeof(tbuf), "%c}bt%s", 0x1b, path);
51 if (write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1)) perror("write"); 52 if (ty_write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1))
53 perror("write");
52 } 54 }
53 return 0; 55 return 0;
54} 56}
diff --git a/src/bin/tycat.c b/src/bin/tycat.c
index 4344427..1a618c0 100644
--- a/src/bin/tycat.c
+++ b/src/bin/tycat.c
@@ -96,7 +96,8 @@ prnt(const char *path, int w, int h, int mode)
96 snprintf(buf, sizeof(buf), "%c}if#%i;%i;%s", 0x1b, w, h, path); 96 snprintf(buf, sizeof(buf), "%c}if#%i;%i;%s", 0x1b, w, h, path);
97 else 97 else
98 snprintf(buf, sizeof(buf), "%c}is#%i;%i;%s", 0x1b, w, h, path); 98 snprintf(buf, sizeof(buf), "%c}is#%i;%i;%s", 0x1b, w, h, path);
99 if (write(1, buf, strlen(buf) + 1) < 0) perror("write"); 99 if (ty_write(1, buf, strlen(buf) + 1) < 0)
100 perror("write");
100 i = 0; 101 i = 0;
101 line[i++] = 0x1b; 102 line[i++] = 0x1b;
102 line[i++] = '}'; 103 line[i++] = '}';
@@ -112,7 +113,8 @@ prnt(const char *path, int w, int h, int mode)
112 line[i++] = '\n'; 113 line[i++] = '\n';
113 for (y = 0; y < h; y++) 114 for (y = 0; y < h; y++)
114 { 115 {
115 if (write(1, line, i) < 0) perror("write"); 116 if (ty_write(1, line, i) < 0)
117 perror("write");
116 } 118 }
117 free(line); 119 free(line);
118} 120}
@@ -329,11 +331,13 @@ main(int argc, char **argv)
329 emotion_init(); 331 emotion_init();
330 332
331 ee = ecore_evas_buffer_new(1, 1); 333 ee = ecore_evas_buffer_new(1, 1);
332 if (!ee) goto shutdown; 334 if (!ee)
335 goto shutdown;
333 evas = ecore_evas_get(ee); 336 evas = ecore_evas_get(ee);
334 echo_off(); 337 echo_off();
335 snprintf(buf, sizeof(buf), "%c}qs", 0x1b); 338 snprintf(buf, sizeof(buf), "%c}qs", 0x1b);
336 if (write(1, buf, strlen(buf) + 1) < 0) perror("write"); 339 if (ty_write(1, buf, strlen(buf) + 1) < 0)
340 perror("write");
337 if (scanf("%i;%i;%i;%i", &tw, &th, &cw, &ch) != 4 || 341 if (scanf("%i;%i;%i;%i", &tw, &th, &cw, &ch) != 4 ||
338 ((tw <= 0) || (th <= 0) || (cw <= 1) || (ch <= 1))) 342 ((tw <= 0) || (th <= 0) || (cw <= 1) || (ch <= 1)))
339 { 343 {
diff --git a/src/bin/tycommon.c b/src/bin/tycommon.c
index aef8a65..0c34503 100644
--- a/src/bin/tycommon.c
+++ b/src/bin/tycommon.c
@@ -1,5 +1,7 @@
1#include "private.h" 1#include "private.h"
2#include <errno.h>
2#include <stdlib.h> 3#include <stdlib.h>
4#include <unistd.h>
3#include "tycommon.h" 5#include "tycommon.h"
4 6
5 7
@@ -14,3 +16,25 @@ is_running_in_terminology(void)
14 16
15 return 1; 17 return 1;
16} 18}
19
20ssize_t
21ty_write(int fd, const void *buf, size_t count)
22{
23 const char *data = buf;
24 ssize_t len = count;
25
26 while (len > 0)
27 {
28 ssize_t res = write(fd, data, len);
29
30 if (res < 0)
31 {
32 if (errno == EINTR || errno == EAGAIN)
33 continue;
34 return res;
35 }
36 data += res;
37 len -= res;
38 }
39 return len;
40}
diff --git a/src/bin/tycommon.h b/src/bin/tycommon.h
index 2d7cabd..d5bf90e 100644
--- a/src/bin/tycommon.h
+++ b/src/bin/tycommon.h
@@ -2,6 +2,7 @@
2#define _TY_COMMON_H__ 1 2#define _TY_COMMON_H__ 1
3 3
4int is_running_in_terminology(void); 4int is_running_in_terminology(void);
5ssize_t ty_write(int fd, const void *buf, size_t count);
5 6
6#define ON_NOT_RUNNING_IN_TERMINOLOGY_EXIT_1() \ 7#define ON_NOT_RUNNING_IN_TERMINOLOGY_EXIT_1() \
7 do \ 8 do \
diff --git a/src/bin/tyfuzz.c b/src/bin/tyfuzz.c
index 0b4f00b..9901581 100644
--- a/src/bin/tyfuzz.c
+++ b/src/bin/tyfuzz.c
@@ -263,10 +263,6 @@ _termpty_init(Termpty *ty, Config *config)
263 assert(ty->screen2); 263 assert(ty->screen2);
264 ty->circular_offset = 0; 264 ty->circular_offset = 0;
265 ty->fd = STDIN_FILENO; 265 ty->fd = STDIN_FILENO;
266#if defined(ENABLE_FUZZING)
267 ty->fd_dev_null = open("/dev/null", O_WRONLY|O_APPEND);
268 assert(ty->fd_dev_null >= 0);
269#endif
270 ty->hl.bitmap = calloc(1, HL_LINKS_MAX / 8); /* bit map for 1 << 16 elements */ 266 ty->hl.bitmap = calloc(1, HL_LINKS_MAX / 8); /* bit map for 1 << 16 elements */
271 assert(ty->hl.bitmap); 267 assert(ty->hl.bitmap);
272 /* Mark id 0 as set */ 268 /* Mark id 0 as set */
@@ -275,17 +271,6 @@ _termpty_init(Termpty *ty, Config *config)
275 ty->backlog_beacon.screen_y = 0; 271 ty->backlog_beacon.screen_y = 0;
276} 272}
277 273
278static void
279_termpty_shutdown(Termpty *ty)
280{
281#if defined(ENABLE_TESTS)
282 ty_sb_free(&ty->write_buffer);
283#endif
284#if defined(ENABLE_FUZZING)
285 close(ty->fd_dev_null);
286#endif
287}
288
289int 274int
290main(int argc EINA_UNUSED, char **argv EINA_UNUSED) 275main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
291{ 276{
@@ -384,8 +369,6 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
384 _tytest_checksum(&_ty); 369 _tytest_checksum(&_ty);
385#endif 370#endif
386 371
387 _termpty_shutdown(&_ty);
388
389#ifdef TYTEST 372#ifdef TYTEST
390 tytest_shutdown(); 373 tytest_shutdown();
391#endif 374#endif
diff --git a/src/bin/tyls.c b/src/bin/tyls.c
index 86331c3..aa9a20d 100644
--- a/src/bin/tyls.c
+++ b/src/bin/tyls.c
@@ -307,6 +307,8 @@ const Cmatch fmatch[] =
307 { 2, 3, 5, 9, 9, 9, "*.MP3", "audio-x-mpeg.svg"}, 307 { 2, 3, 5, 9, 9, 9, "*.MP3", "audio-x-mpeg.svg"},
308 { 2, 3, 5, 9, 9, 9, "*.aac", "audio-x-generic.svg"}, 308 { 2, 3, 5, 9, 9, 9, "*.aac", "audio-x-generic.svg"},
309 { 2, 3, 5, 9, 9, 9, "*.AAC", "audio-x-generic.svg"}, 309 { 2, 3, 5, 9, 9, 9, "*.AAC", "audio-x-generic.svg"},
310 { 2, 3, 5, 9, 9, 9, "*.flac", "audio-x-generic.svg"},
311 { 2, 3, 5, 9, 9, 9, "*.FLAC", "audio-x-generic.svg"},
310 { 2, 3, 5, 9, 9, 9, "*.wav", "audio-x-wav.svg"}, 312 { 2, 3, 5, 9, 9, 9, "*.wav", "audio-x-wav.svg"},
311 { 2, 3, 5, 9, 9, 9, "*.WAV", "audio-x-wav.svg"}, 313 { 2, 3, 5, 9, 9, 9, "*.WAV", "audio-x-wav.svg"},
312 { 2, 3, 5, 9, 9, 9, "*.m3u", "audio-x-mp3-playlist"}, 314 { 2, 3, 5, 9, 9, 9, "*.m3u", "audio-x-mp3-playlist"},
@@ -763,7 +765,8 @@ main(int argc, char **argv)
763 echo_off(); 765 echo_off();
764 snprintf(buf, sizeof(buf), "%c}qs", 0x1b); 766 snprintf(buf, sizeof(buf), "%c}qs", 0x1b);
765 len = strlen(buf); 767 len = strlen(buf);
766 if (write(1, buf, len + 1) < (signed)len + 1) perror("write"); 768 if (ty_write(1, buf, len + 1) < (signed)len + 1)
769 perror("write");
767 if ((scanf("%i;%i;%i;%i", &tw, &th, &cw, &ch) != 4) 770 if ((scanf("%i;%i;%i;%i", &tw, &th, &cw, &ch) != 4)
768 || (tw <= 0) || (th <= 0) || (cw <= 1) || (ch <= 1)) 771 || (tw <= 0) || (th <= 0) || (cw <= 1) || (ch <= 1))
769 { 772 {
diff --git a/src/bin/typop.c b/src/bin/typop.c
index 8a9e159..6485a69 100644
--- a/src/bin/typop.c
+++ b/src/bin/typop.c
@@ -39,7 +39,8 @@ main(int argc, char **argv)
39 if (realpath(path, buf)) path = buf; 39 if (realpath(path, buf)) path = buf;
40 snprintf(tbuf, sizeof(tbuf), "%c}p%c%s", 0x1b, 40 snprintf(tbuf, sizeof(tbuf), "%c}p%c%s", 0x1b,
41 (i == 1) ? 'n': 'q', path); 41 (i == 1) ? 'n': 'q', path);
42 if (write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1)) perror("write"); 42 if (ty_write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1))
43 perror("write");
43 } 44 }
44 return 0; 45 return 0;
45} 46}
diff --git a/src/bin/tyq.c b/src/bin/tyq.c
index 1d6167f..2bcac24 100644
--- a/src/bin/tyq.c
+++ b/src/bin/tyq.c
@@ -38,7 +38,8 @@ main(int argc, char **argv)
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}pq%s", 0x1b, path); 40 snprintf(tbuf, sizeof(tbuf), "%c}pq%s", 0x1b, path);
41 if (write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1)) perror("write"); 41 if (ty_write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1))
42 perror("write");
42 } 43 }
43 return 0; 44 return 0;
44} 45}
diff --git a/src/bin/tysend.c b/src/bin/tysend.c
index 33ff5f0..ea8b291 100644
--- a/src/bin/tysend.c
+++ b/src/bin/tysend.c
@@ -69,7 +69,7 @@ main(int argc, char **argv)
69 69
70 path = argv[i]; 70 path = argv[i];
71 snprintf(tbuf, sizeof(tbuf), "%c}fr%s", 0x1b, path); 71 snprintf(tbuf, sizeof(tbuf), "%c}fr%s", 0x1b, path);
72 if (write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1)) 72 if (ty_write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1))
73 goto err; 73 goto err;
74 file_fd = open(path, O_RDONLY); 74 file_fd = open(path, O_RDONLY);
75 if (file_fd >= 0) 75 if (file_fd >= 0)
@@ -79,7 +79,7 @@ main(int argc, char **argv)
79 off = lseek(file_fd, 0, SEEK_END); 79 off = lseek(file_fd, 0, SEEK_END);
80 lseek(file_fd, 0, SEEK_SET); 80 lseek(file_fd, 0, SEEK_SET);
81 snprintf(tbuf, sizeof(tbuf), "%c}fs%llu", 0x1b, (unsigned long long)off); 81 snprintf(tbuf, sizeof(tbuf), "%c}fs%llu", 0x1b, (unsigned long long)off);
82 if (write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1)) 82 if (ty_write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1))
83 goto err; 83 goto err;
84 for (;;) 84 for (;;)
85 { 85 {
@@ -104,9 +104,9 @@ main(int argc, char **argv)
104 pksum += rawbuf2[bin]; 104 pksum += rawbuf2[bin];
105 } 105 }
106 snprintf(tbuf, sizeof(tbuf), "%c}fd%i ", 0x1b, pksum); 106 snprintf(tbuf, sizeof(tbuf), "%c}fd%i ", 0x1b, pksum);
107 if (write(1, tbuf, strlen(tbuf)) != (signed)(strlen(tbuf))) 107 if (ty_write(1, tbuf, strlen(tbuf)) != (signed)(strlen(tbuf)))
108 goto err; 108 goto err;
109 if (write(1, rawbuf2, bout + 1) != bout + 1) 109 if (ty_write(1, rawbuf2, bout + 1) != bout + 1)
110 goto err; 110 goto err;
111 } 111 }
112 else break; 112 else break;
@@ -123,10 +123,10 @@ main(int argc, char **argv)
123 close(file_fd); 123 close(file_fd);
124 } 124 }
125 snprintf(tbuf, sizeof(tbuf), "%c}fx", 0x1b); 125 snprintf(tbuf, sizeof(tbuf), "%c}fx", 0x1b);
126 if (write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1)) 126 if (ty_write(1, tbuf, strlen(tbuf) + 1) != (signed)(strlen(tbuf) + 1))
127 goto err; 127 goto err;
128 tbuf[0] = 0; 128 tbuf[0] = 0;
129 if (write(1, tbuf, 1) != 1) 129 if (ty_write(1, tbuf, 1) != 1)
130 goto err; 130 goto err;
131 } 131 }
132 echo_on(); 132 echo_on();
diff --git a/src/bin/utils.c b/src/bin/utils.c
index 3c5c2d6..e0d3896 100644
--- a/src/bin/utils.c
+++ b/src/bin/utils.c
@@ -162,11 +162,11 @@ utils_need_scale_wizard(void)
162 if (config_xdg) 162 if (config_xdg)
163 { 163 {
164 snprintf(path, sizeof(path) - 1, 164 snprintf(path, sizeof(path) - 1,
165 "%s/elementary", config_xdg); 165 "%s/elementary/config/standard/base.cfg", config_xdg);
166 } 166 }
167 else 167 else
168 { 168 {
169 const char *suffix = "/.elementary"; 169 const char *suffix = "/.elementary/config/standard/base.cfg";
170 char home[PATH_MAX - strlen(suffix)]; 170 char home[PATH_MAX - strlen(suffix)];
171 171
172 if (!homedir_get(home, sizeof(home))) 172 if (!homedir_get(home, sizeof(home)))
diff --git a/src/bin/utils.h b/src/bin/utils.h
index ca5b6e7..864db50 100644
--- a/src/bin/utils.h
+++ b/src/bin/utils.h
@@ -17,6 +17,24 @@ Eina_Bool utils_need_scale_wizard(void);
17#define casestartswith(str, constref) \ 17#define casestartswith(str, constref) \
18 (!strncasecmp(str, constref, sizeof(constref) - 1)) 18 (!strncasecmp(str, constref, sizeof(constref) - 1))
19 19
20#if !defined(HAVE_STRCHRNUL)
21static inline char *
22strchrnul(const char *s, int c)
23{
24 const char *p = s;
25
26 while (*p)
27 {
28 if (*p == c)
29 return (char *)p;
30
31 ++p;
32 }
33 return (char *) (p);
34}
35#endif
36
37
20#if (ELM_VERSION_MAJOR == 1) && (ELM_VERSION_MINOR < 20) 38#if (ELM_VERSION_MAJOR == 1) && (ELM_VERSION_MINOR < 20)
21# if __GNUC__ >= 7 39# if __GNUC__ >= 7
22# define EINA_FALLTHROUGH __attribute__ ((fallthrough)); 40# define EINA_FALLTHROUGH __attribute__ ((fallthrough));
diff --git a/src/bin/win.c b/src/bin/win.c
index f7ef9bc..f7cab8e 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;
@@ -169,7 +168,6 @@ struct _Win
169 Ecore_Job *size_job; 168 Ecore_Job *size_job;
170 Evas_Object *cmdbox; 169 Evas_Object *cmdbox;
171 Ecore_Timer *cmdbox_del_timer; 170 Ecore_Timer *cmdbox_del_timer;
172 Ecore_Timer *cmdbox_focus_timer;
173 Ecore_Timer *hide_cursor_timer; 171 Ecore_Timer *hide_cursor_timer;
174 unsigned char focused : 1; 172 unsigned char focused : 1;
175 unsigned char cmdbox_up : 1; 173 unsigned char cmdbox_up : 1;
@@ -256,8 +254,6 @@ win_scale_wizard(Evas_Object *win, Term *term)
256 Scale_Ctx *ctx; 254 Scale_Ctx *ctx;
257 255
258 EINA_SAFETY_ON_NULL_RETURN(term); 256 EINA_SAFETY_ON_NULL_RETURN(term);
259 if (!utils_need_scale_wizard())
260 return;
261 257
262 ctx = calloc(1, sizeof(*ctx)); 258 ctx = calloc(1, sizeof(*ctx));
263 if (!ctx) 259 if (!ctx)
@@ -982,11 +978,6 @@ win_free(Win *wn)
982 ecore_timer_del(wn->cmdbox_del_timer); 978 ecore_timer_del(wn->cmdbox_del_timer);
983 wn->cmdbox_del_timer = NULL; 979 wn->cmdbox_del_timer = NULL;
984 } 980 }
985 if (wn->cmdbox_focus_timer)
986 {
987 ecore_timer_del(wn->cmdbox_focus_timer);
988 wn->cmdbox_focus_timer = NULL;
989 }
990 if (wn->cmdbox) 981 if (wn->cmdbox)
991 { 982 {
992 evas_object_del(wn->cmdbox); 983 evas_object_del(wn->cmdbox);
@@ -1001,10 +992,8 @@ win_free(Win *wn)
1001 } 992 }
1002 if (wn->size_job) 993 if (wn->size_job)
1003 ecore_job_del(wn->size_job); 994 ecore_job_del(wn->size_job);
1004 if (wn->config) 995 config_del(wn->config);
1005 config_del(wn->config); 996 eina_stringshare_del(wn->preedit_str);
1006 if (wn->preedit_str)
1007 eina_stringshare_del(wn->preedit_str);
1008 keyin_compose_seq_reset(&wn->khdl); 997 keyin_compose_seq_reset(&wn->khdl);
1009 if (wn->khdl.imf) 998 if (wn->khdl.imf)