diff options
author | Boris Faure <billiob@gmail.com> | 2015-06-02 22:48:50 +0200 |
---|---|---|
committer | Boris Faure <billiob@gmail.com> | 2015-06-03 23:02:31 +0200 |
commit | 681bb029c232fd162a7be9acea1d60074808f2f8 (patch) | |
tree | 7814fa6e19a9325d63b25b21ce1f5fb7d7338055 /src | |
parent | 074eece5f7d1f749f96bd03a77e82156d551941a (diff) |
ensure cursor coordinates are always valid, 2nd version
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/termpty.c | 28 | ||||
-rw-r--r-- | src/bin/termpty.h | 8 | ||||
-rw-r--r-- | src/bin/termptyesc.c | 42 | ||||
-rw-r--r-- | src/bin/termptyops.c | 12 |
4 files changed, 53 insertions, 37 deletions
diff --git a/src/bin/termpty.c b/src/bin/termpty.c index c9b8b7d..5e49ba4 100644 --- a/src/bin/termpty.c +++ b/src/bin/termpty.c | |||
@@ -270,21 +270,14 @@ _cb_fd_read(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED) | |||
270 | static void | 270 | static void |
271 | _limit_coord(Termpty *ty) | 271 | _limit_coord(Termpty *ty) |
272 | { | 272 | { |
273 | ty->termstate.wrapnext = 0; | 273 | TERMPTY_RESTRICT_FIELD(ty->termstate.had_cr_x, 0, ty->w); |
274 | if (ty->termstate.had_cr_x >= ty->w) | 274 | TERMPTY_RESTRICT_FIELD(ty->termstate.had_cr_y, 0, ty->h); |
275 | ty->termstate.had_cr_x = ty->w - 1; | 275 | |
276 | if (ty->termstate.had_cr_y >= ty->h) | 276 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); |
277 | ty->termstate.had_cr_y = ty->h - 1; | 277 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); |
278 | 278 | ||
279 | if (ty->cursor_state.cx >= ty->w) | 279 | TERMPTY_RESTRICT_FIELD(ty->cursor_save.cx, 0, ty->w); |
280 | ty->cursor_state.cx = ty->w - 1; | 280 | TERMPTY_RESTRICT_FIELD(ty->cursor_save.cy, 0, ty->h); |
281 | if (ty->cursor_state.cy >= ty->h) | ||
282 | ty->cursor_state.cy = ty->h - 1; | ||
283 | |||
284 | if (ty->cursor_save.cx >= ty->w) | ||
285 | ty->cursor_save.cx = ty->w - 1; | ||
286 | if (ty->cursor_save.cy >= ty->h) | ||
287 | ty->cursor_save.cy = ty->h - 1; | ||
288 | } | 281 | } |
289 | 282 | ||
290 | Termpty * | 283 | Termpty * |
@@ -897,7 +890,10 @@ termpty_resize(Termpty *ty, int new_w, int new_h) | |||
897 | 890 | ||
898 | ty->cursor_state.cy = (new_cy + new_h - ty->circular_offset) % new_h; | 891 | ty->cursor_state.cy = (new_cy + new_h - ty->circular_offset) % new_h; |
899 | 892 | ||
900 | if (altbuf) termpty_screen_swap(ty); | 893 | if (altbuf) |
894 | termpty_screen_swap(ty); | ||
895 | |||
896 | ty->termstate.wrapnext = 0; | ||
901 | 897 | ||
902 | _limit_coord(ty); | 898 | _limit_coord(ty); |
903 | 899 | ||
diff --git a/src/bin/termpty.h b/src/bin/termpty.h index d5aad70..7aba97a 100644 --- a/src/bin/termpty.h +++ b/src/bin/termpty.h | |||
@@ -260,4 +260,12 @@ extern int _termpty_log_dom; | |||
260 | #define TERMPTY_FMTCLR(Tatt) \ | 260 | #define TERMPTY_FMTCLR(Tatt) \ |
261 | (Tatt).autowrapped = (Tatt).newline = (Tatt).tab = 0 | 261 | (Tatt).autowrapped = (Tatt).newline = (Tatt).tab = 0 |
262 | 262 | ||
263 | #define TERMPTY_RESTRICT_FIELD(Field, Min, Max) \ | ||
264 | do { \ | ||
265 | if (Field >= Max) \ | ||
266 | Field = Max - 1; \ | ||
267 | else if (Field < Min) \ | ||
268 | Field = Min; \ | ||
269 | } while (0) | ||
270 | |||
263 | #endif | 271 | #endif |
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c index 14dbbb7..94831c9 100644 --- a/src/bin/termptyesc.c +++ b/src/bin/termptyesc.c | |||
@@ -66,7 +66,7 @@ _handle_cursor_control(Termpty *ty, const Eina_Unicode *cc) | |||
66 | ty->termstate.had_cr = 0; | 66 | ty->termstate.had_cr = 0; |
67 | ty->termstate.wrapnext = 0; | 67 | ty->termstate.wrapnext = 0; |
68 | ty->cursor_state.cx--; | 68 | ty->cursor_state.cx--; |
69 | if (ty->cursor_state.cx < 0) ty->cursor_state.cx = 0; | 69 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); |
70 | return; | 70 | return; |
71 | case 0x09: // HT '\t' (horizontal tab) | 71 | case 0x09: // HT '\t' (horizontal tab) |
72 | DBG("->HT"); | 72 | DBG("->HT"); |
@@ -75,8 +75,7 @@ _handle_cursor_control(Termpty *ty, const Eina_Unicode *cc) | |||
75 | ty->termstate.wrapnext = 0; | 75 | ty->termstate.wrapnext = 0; |
76 | ty->cursor_state.cx += 8; | 76 | ty->cursor_state.cx += 8; |
77 | ty->cursor_state.cx = (ty->cursor_state.cx / 8) * 8; | 77 | ty->cursor_state.cx = (ty->cursor_state.cx / 8) * 8; |
78 | if (ty->cursor_state.cx >= ty->w) | 78 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); |
79 | ty->cursor_state.cx = ty->w - 1; | ||
80 | return; | 79 | return; |
81 | case 0x0a: // LF '\n' (new line) | 80 | case 0x0a: // LF '\n' (new line) |
82 | case 0x0b: // VT '\v' (vertical tab) | 81 | case 0x0b: // VT '\v' (vertical tab) |
@@ -682,6 +681,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
682 | termpty_text_append(ty, blank, 1); | 681 | termpty_text_append(ty, blank, 1); |
683 | ty->termstate.insert = pi; | 682 | ty->termstate.insert = pi; |
684 | ty->cursor_state.cx = cx; | 683 | ty->cursor_state.cx = cx; |
684 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); | ||
685 | } | 685 | } |
686 | break; | 686 | break; |
687 | case 'A': // cursor up N | 687 | case 'A': // cursor up N |
@@ -691,6 +691,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
691 | DBG("cursor up %d", arg); | 691 | DBG("cursor up %d", arg); |
692 | ty->termstate.wrapnext = 0; | 692 | ty->termstate.wrapnext = 0; |
693 | ty->cursor_state.cy = MAX(0, ty->cursor_state.cy - arg); | 693 | ty->cursor_state.cy = MAX(0, ty->cursor_state.cy - arg); |
694 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); | ||
694 | break; | 695 | break; |
695 | case 'B': // cursor down N | 696 | case 'B': // cursor down N |
696 | arg = _csi_arg_get(&b); | 697 | arg = _csi_arg_get(&b); |
@@ -698,6 +699,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
698 | DBG("cursor down %d", arg); | 699 | DBG("cursor down %d", arg); |
699 | ty->termstate.wrapnext = 0; | 700 | ty->termstate.wrapnext = 0; |
700 | ty->cursor_state.cy = MIN(ty->h - 1, ty->cursor_state.cy + arg); | 701 | ty->cursor_state.cy = MIN(ty->h - 1, ty->cursor_state.cy + arg); |
702 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); | ||
701 | break; | 703 | break; |
702 | case 'D': // cursor left N | 704 | case 'D': // cursor left N |
703 | arg = _csi_arg_get(&b); | 705 | arg = _csi_arg_get(&b); |
@@ -705,10 +707,8 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
705 | DBG("cursor left %d", arg); | 707 | DBG("cursor left %d", arg); |
706 | ty->termstate.wrapnext = 0; | 708 | ty->termstate.wrapnext = 0; |
707 | for (i = 0; i < arg; i++) | 709 | for (i = 0; i < arg; i++) |
708 | { | 710 | ty->cursor_state.cx--; |
709 | ty->cursor_state.cx--; | 711 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); |
710 | if (ty->cursor_state.cx < 0) ty->cursor_state.cx = 0; | ||
711 | } | ||
712 | break; | 712 | break; |
713 | case 'C': // cursor right N | 713 | case 'C': // cursor right N |
714 | case 'a': // cursor right N | 714 | case 'a': // cursor right N |
@@ -717,10 +717,8 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
717 | DBG("cursor right %d", arg); | 717 | DBG("cursor right %d", arg); |
718 | ty->termstate.wrapnext = 0; | 718 | ty->termstate.wrapnext = 0; |
719 | for (i = 0; i < arg; i++) | 719 | for (i = 0; i < arg; i++) |
720 | { | 720 | ty->cursor_state.cx++; |
721 | ty->cursor_state.cx++; | 721 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); |
722 | if (ty->cursor_state.cx >= ty->w) ty->cursor_state.cx = ty->w - 1; | ||
723 | } | ||
724 | break; | 722 | break; |
725 | case 'H': // cursor pos set | 723 | case 'H': // cursor pos set |
726 | case 'f': // cursor pos set | 724 | case 'f': // cursor pos set |
@@ -740,6 +738,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
740 | if (b) | 738 | if (b) |
741 | { | 739 | { |
742 | ty->cursor_state.cy = arg; | 740 | ty->cursor_state.cy = arg; |
741 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); | ||
743 | arg = _csi_arg_get(&b); | 742 | arg = _csi_arg_get(&b); |
744 | if (arg < 1) arg = 1; | 743 | if (arg < 1) arg = 1; |
745 | arg--; | 744 | arg--; |
@@ -747,9 +746,14 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
747 | else arg = 0; | 746 | else arg = 0; |
748 | 747 | ||
749 | if (arg >= ty->w) arg = ty->w - 1; | 748 | if (arg >= ty->w) arg = ty->w - 1; |
750 | if (b) ty->cursor_state.cx = arg; | 749 | if (b) |
750 | { | ||
751 | ty->cursor_state.cx = arg; | ||
752 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); | ||
753 | } | ||
751 | } | 754 | } |
752 | ty->cursor_state.cy += ty->termstate.margin_top; | 755 | ty->cursor_state.cy += ty->termstate.margin_top; |
756 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); | ||
753 | break; | 757 | break; |
754 | case 'G': // to column N | 758 | case 'G': // to column N |
755 | arg = _csi_arg_get(&b); | 759 | arg = _csi_arg_get(&b); |
@@ -757,8 +761,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
757 | DBG("to column %d", arg); | 761 | DBG("to column %d", arg); |
758 | ty->termstate.wrapnext = 0; | 762 | ty->termstate.wrapnext = 0; |
759 | ty->cursor_state.cx = arg - 1; | 763 | ty->cursor_state.cx = arg - 1; |
760 | if (ty->cursor_state.cx < 0) ty->cursor_state.cx = 0; | 764 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); |
761 | else if (ty->cursor_state.cx >= ty->w) ty->cursor_state.cx = ty->w - 1; | ||
762 | break; | 765 | break; |
763 | case 'd': // to row N | 766 | case 'd': // to row N |
764 | arg = _csi_arg_get(&b); | 767 | arg = _csi_arg_get(&b); |
@@ -766,8 +769,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
766 | DBG("to row %d", arg); | 769 | DBG("to row %d", arg); |
767 | ty->termstate.wrapnext = 0; | 770 | ty->termstate.wrapnext = 0; |
768 | ty->cursor_state.cy = arg - 1; | 771 | ty->cursor_state.cy = arg - 1; |
769 | if (ty->cursor_state.cy < 0) ty->cursor_state.cy = 0; | 772 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); |
770 | else if (ty->cursor_state.cy >= ty->h) ty->cursor_state.cy = ty->h - 1; | ||
771 | break; | 773 | break; |
772 | case 'E': // down relative N rows, and to col 0 | 774 | case 'E': // down relative N rows, and to col 0 |
773 | arg = _csi_arg_get(&b); | 775 | arg = _csi_arg_get(&b); |
@@ -775,8 +777,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
775 | DBG("down relative %d rows, and to col 0", arg); | 777 | DBG("down relative %d rows, and to col 0", arg); |
776 | ty->termstate.wrapnext = 0; | 778 | ty->termstate.wrapnext = 0; |
777 | ty->cursor_state.cy += arg; | 779 | ty->cursor_state.cy += arg; |
778 | if (ty->cursor_state.cy < 0) ty->cursor_state.cy = 0; | 780 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); |
779 | else if (ty->cursor_state.cy >= ty->h) ty->cursor_state.cy = ty->h - 1; | ||
780 | ty->cursor_state.cx = 0; | 781 | ty->cursor_state.cx = 0; |
781 | break; | 782 | break; |
782 | case 'F': // up relative N rows, and to col 0 | 783 | case 'F': // up relative N rows, and to col 0 |
@@ -785,8 +786,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
785 | DBG("up relative %d rows, and to col 0", arg); | 786 | DBG("up relative %d rows, and to col 0", arg); |
786 | ty->termstate.wrapnext = 0; | 787 | ty->termstate.wrapnext = 0; |
787 | ty->cursor_state.cy -= arg; | 788 | ty->cursor_state.cy -= arg; |
788 | if (ty->cursor_state.cy < 0) ty->cursor_state.cy = 0; | 789 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); |
789 | else if (ty->cursor_state.cy >= ty->h) ty->cursor_state.cy = ty->h - 1; | ||
790 | ty->cursor_state.cx = 0; | 790 | ty->cursor_state.cx = 0; |
791 | break; | 791 | break; |
792 | case 'X': // erase N chars | 792 | case 'X': // erase N chars |
@@ -1029,7 +1029,9 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce) | |||
1029 | if (!arg) | 1029 | if (!arg) |
1030 | { | 1030 | { |
1031 | ty->cursor_state.cx = cx; | 1031 | ty->cursor_state.cx = cx; |
1032 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); | ||
1032 | ty->cursor_state.cy = cy; | 1033 | ty->cursor_state.cy = cy; |
1034 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); | ||
1033 | } | 1035 | } |
1034 | } | 1036 | } |
1035 | break; | 1037 | break; |
diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c index e9d93f8..f4ef69d 100644 --- a/src/bin/termptyops.c +++ b/src/bin/termptyops.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include "termptygfx.h" | 7 | #include "termptygfx.h" |
8 | #include "termptysave.h" | 8 | #include "termptysave.h" |
9 | #include "miniview.h" | 9 | #include "miniview.h" |
10 | #include <assert.h> | ||
10 | 11 | ||
11 | #undef CRITICAL | 12 | #undef CRITICAL |
12 | #undef ERR | 13 | #undef ERR |
@@ -151,6 +152,7 @@ termpty_text_scroll_test(Termpty *ty, Eina_Bool clear) | |||
151 | { | 152 | { |
152 | termpty_text_scroll(ty, clear); | 153 | termpty_text_scroll(ty, clear); |
153 | ty->cursor_state.cy = e - 1; | 154 | ty->cursor_state.cy = e - 1; |
155 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); | ||
154 | } | 156 | } |
155 | } | 157 | } |
156 | 158 | ||
@@ -164,6 +166,7 @@ termpty_text_scroll_rev_test(Termpty *ty, Eina_Bool clear) | |||
164 | { | 166 | { |
165 | termpty_text_scroll_rev(ty, clear); | 167 | termpty_text_scroll_rev(ty, clear); |
166 | ty->cursor_state.cy = b; | 168 | ty->cursor_state.cy = b; |
169 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h); | ||
167 | } | 170 | } |
168 | } | 171 | } |
169 | 172 | ||
@@ -220,7 +223,10 @@ termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len) | |||
220 | if (EINA_UNLIKELY(ty->cursor_state.cx >= (ty->w - offset))) | 223 | if (EINA_UNLIKELY(ty->cursor_state.cx >= (ty->w - offset))) |
221 | ty->termstate.wrapnext = 1; | 224 | ty->termstate.wrapnext = 1; |
222 | else | 225 | else |
223 | ty->cursor_state.cx += offset; | 226 | { |
227 | ty->cursor_state.cx += offset; | ||
228 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); | ||
229 | } | ||
224 | } | 230 | } |
225 | else | 231 | else |
226 | { | 232 | { |
@@ -235,8 +241,10 @@ termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len) | |||
235 | if (ty->cursor_state.cx > (ty->w - offset)) | 241 | if (ty->cursor_state.cx > (ty->w - offset)) |
236 | { | 242 | { |
237 | ty->cursor_state.cx = ty->w - offset; | 243 | ty->cursor_state.cx = ty->w - offset; |
244 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); | ||
238 | return; | 245 | return; |
239 | } | 246 | } |
247 | TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); | ||
240 | } | 248 | } |
241 | } | 249 | } |
242 | } | 250 | } |
@@ -248,6 +256,8 @@ termpty_clear_line(Termpty *ty, Termpty_Clear mode, int limit) | |||
248 | int n = 0; | 256 | int n = 0; |
249 | Evas_Coord x = 0, y = ty->cursor_state.cy; | 257 | Evas_Coord x = 0, y = ty->cursor_state.cy; |
250 | 258 | ||
259 | assert (y >= 0 && y < ty->h); | ||
260 | |||
251 | switch (mode) | 261 | switch (mode) |
252 | { | 262 | { |
253 | case TERMPTY_CLR_END: | 263 | case TERMPTY_CLR_END: |