ensure cursor coordinates are always valid, 2nd version

This commit is contained in:
Boris Faure 2015-06-02 22:48:50 +02:00
parent 074eece5f7
commit 681bb029c2
4 changed files with 51 additions and 35 deletions

View File

@ -270,21 +270,14 @@ _cb_fd_read(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
static void static void
_limit_coord(Termpty *ty) _limit_coord(Termpty *ty)
{ {
ty->termstate.wrapnext = 0; TERMPTY_RESTRICT_FIELD(ty->termstate.had_cr_x, 0, ty->w);
if (ty->termstate.had_cr_x >= ty->w) TERMPTY_RESTRICT_FIELD(ty->termstate.had_cr_y, 0, ty->h);
ty->termstate.had_cr_x = ty->w - 1;
if (ty->termstate.had_cr_y >= ty->h)
ty->termstate.had_cr_y = ty->h - 1;
if (ty->cursor_state.cx >= ty->w) TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
ty->cursor_state.cx = ty->w - 1; TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
if (ty->cursor_state.cy >= ty->h)
ty->cursor_state.cy = ty->h - 1;
if (ty->cursor_save.cx >= ty->w) TERMPTY_RESTRICT_FIELD(ty->cursor_save.cx, 0, ty->w);
ty->cursor_save.cx = ty->w - 1; TERMPTY_RESTRICT_FIELD(ty->cursor_save.cy, 0, ty->h);
if (ty->cursor_save.cy >= ty->h)
ty->cursor_save.cy = ty->h - 1;
} }
Termpty * Termpty *
@ -897,7 +890,10 @@ termpty_resize(Termpty *ty, int new_w, int new_h)
ty->cursor_state.cy = (new_cy + new_h - ty->circular_offset) % new_h; ty->cursor_state.cy = (new_cy + new_h - ty->circular_offset) % new_h;
if (altbuf) termpty_screen_swap(ty); if (altbuf)
termpty_screen_swap(ty);
ty->termstate.wrapnext = 0;
_limit_coord(ty); _limit_coord(ty);

View File

@ -260,4 +260,12 @@ extern int _termpty_log_dom;
#define TERMPTY_FMTCLR(Tatt) \ #define TERMPTY_FMTCLR(Tatt) \
(Tatt).autowrapped = (Tatt).newline = (Tatt).tab = 0 (Tatt).autowrapped = (Tatt).newline = (Tatt).tab = 0
#define TERMPTY_RESTRICT_FIELD(Field, Min, Max) \
do { \
if (Field >= Max) \
Field = Max - 1; \
else if (Field < Min) \
Field = Min; \
} while (0)
#endif #endif

View File

@ -66,7 +66,7 @@ _handle_cursor_control(Termpty *ty, const Eina_Unicode *cc)
ty->termstate.had_cr = 0; ty->termstate.had_cr = 0;
ty->termstate.wrapnext = 0; ty->termstate.wrapnext = 0;
ty->cursor_state.cx--; ty->cursor_state.cx--;
if (ty->cursor_state.cx < 0) ty->cursor_state.cx = 0; TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
return; return;
case 0x09: // HT '\t' (horizontal tab) case 0x09: // HT '\t' (horizontal tab)
DBG("->HT"); DBG("->HT");
@ -75,8 +75,7 @@ _handle_cursor_control(Termpty *ty, const Eina_Unicode *cc)
ty->termstate.wrapnext = 0; ty->termstate.wrapnext = 0;
ty->cursor_state.cx += 8; ty->cursor_state.cx += 8;
ty->cursor_state.cx = (ty->cursor_state.cx / 8) * 8; ty->cursor_state.cx = (ty->cursor_state.cx / 8) * 8;
if (ty->cursor_state.cx >= ty->w) TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
ty->cursor_state.cx = ty->w - 1;
return; return;
case 0x0a: // LF '\n' (new line) case 0x0a: // LF '\n' (new line)
case 0x0b: // VT '\v' (vertical tab) case 0x0b: // VT '\v' (vertical tab)
@ -682,6 +681,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
termpty_text_append(ty, blank, 1); termpty_text_append(ty, blank, 1);
ty->termstate.insert = pi; ty->termstate.insert = pi;
ty->cursor_state.cx = cx; ty->cursor_state.cx = cx;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
} }
break; break;
case 'A': // cursor up N case 'A': // cursor up N
@ -691,6 +691,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
DBG("cursor up %d", arg); DBG("cursor up %d", arg);
ty->termstate.wrapnext = 0; ty->termstate.wrapnext = 0;
ty->cursor_state.cy = MAX(0, ty->cursor_state.cy - arg); ty->cursor_state.cy = MAX(0, ty->cursor_state.cy - arg);
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
break; break;
case 'B': // cursor down N case 'B': // cursor down N
arg = _csi_arg_get(&b); arg = _csi_arg_get(&b);
@ -698,6 +699,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
DBG("cursor down %d", arg); DBG("cursor down %d", arg);
ty->termstate.wrapnext = 0; ty->termstate.wrapnext = 0;
ty->cursor_state.cy = MIN(ty->h - 1, ty->cursor_state.cy + arg); ty->cursor_state.cy = MIN(ty->h - 1, ty->cursor_state.cy + arg);
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
break; break;
case 'D': // cursor left N case 'D': // cursor left N
arg = _csi_arg_get(&b); arg = _csi_arg_get(&b);
@ -705,10 +707,8 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
DBG("cursor left %d", arg); DBG("cursor left %d", arg);
ty->termstate.wrapnext = 0; ty->termstate.wrapnext = 0;
for (i = 0; i < arg; i++) for (i = 0; i < arg; i++)
{ ty->cursor_state.cx--;
ty->cursor_state.cx--; TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
if (ty->cursor_state.cx < 0) ty->cursor_state.cx = 0;
}
break; break;
case 'C': // cursor right N case 'C': // cursor right N
case 'a': // cursor right N case 'a': // cursor right N
@ -717,10 +717,8 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
DBG("cursor right %d", arg); DBG("cursor right %d", arg);
ty->termstate.wrapnext = 0; ty->termstate.wrapnext = 0;
for (i = 0; i < arg; i++) for (i = 0; i < arg; i++)
{ ty->cursor_state.cx++;
ty->cursor_state.cx++; TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
if (ty->cursor_state.cx >= ty->w) ty->cursor_state.cx = ty->w - 1;
}
break; break;
case 'H': // cursor pos set case 'H': // cursor pos set
case 'f': // cursor pos set case 'f': // cursor pos set
@ -740,6 +738,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
if (b) if (b)
{ {
ty->cursor_state.cy = arg; ty->cursor_state.cy = arg;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
arg = _csi_arg_get(&b); arg = _csi_arg_get(&b);
if (arg < 1) arg = 1; if (arg < 1) arg = 1;
arg--; arg--;
@ -747,9 +746,14 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
else arg = 0; else arg = 0;
if (arg >= ty->w) arg = ty->w - 1; if (arg >= ty->w) arg = ty->w - 1;
if (b) ty->cursor_state.cx = arg; if (b)
{
ty->cursor_state.cx = arg;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
}
} }
ty->cursor_state.cy += ty->termstate.margin_top; ty->cursor_state.cy += ty->termstate.margin_top;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
break; break;
case 'G': // to column N case 'G': // to column N
arg = _csi_arg_get(&b); arg = _csi_arg_get(&b);
@ -757,8 +761,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
DBG("to column %d", arg); DBG("to column %d", arg);
ty->termstate.wrapnext = 0; ty->termstate.wrapnext = 0;
ty->cursor_state.cx = arg - 1; ty->cursor_state.cx = arg - 1;
if (ty->cursor_state.cx < 0) ty->cursor_state.cx = 0; TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
else if (ty->cursor_state.cx >= ty->w) ty->cursor_state.cx = ty->w - 1;
break; break;
case 'd': // to row N case 'd': // to row N
arg = _csi_arg_get(&b); arg = _csi_arg_get(&b);
@ -766,8 +769,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
DBG("to row %d", arg); DBG("to row %d", arg);
ty->termstate.wrapnext = 0; ty->termstate.wrapnext = 0;
ty->cursor_state.cy = arg - 1; ty->cursor_state.cy = arg - 1;
if (ty->cursor_state.cy < 0) ty->cursor_state.cy = 0; TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
else if (ty->cursor_state.cy >= ty->h) ty->cursor_state.cy = ty->h - 1;
break; break;
case 'E': // down relative N rows, and to col 0 case 'E': // down relative N rows, and to col 0
arg = _csi_arg_get(&b); arg = _csi_arg_get(&b);
@ -775,8 +777,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
DBG("down relative %d rows, and to col 0", arg); DBG("down relative %d rows, and to col 0", arg);
ty->termstate.wrapnext = 0; ty->termstate.wrapnext = 0;
ty->cursor_state.cy += arg; ty->cursor_state.cy += arg;
if (ty->cursor_state.cy < 0) ty->cursor_state.cy = 0; TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
else if (ty->cursor_state.cy >= ty->h) ty->cursor_state.cy = ty->h - 1;
ty->cursor_state.cx = 0; ty->cursor_state.cx = 0;
break; break;
case 'F': // up relative N rows, and to col 0 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)
DBG("up relative %d rows, and to col 0", arg); DBG("up relative %d rows, and to col 0", arg);
ty->termstate.wrapnext = 0; ty->termstate.wrapnext = 0;
ty->cursor_state.cy -= arg; ty->cursor_state.cy -= arg;
if (ty->cursor_state.cy < 0) ty->cursor_state.cy = 0; TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
else if (ty->cursor_state.cy >= ty->h) ty->cursor_state.cy = ty->h - 1;
ty->cursor_state.cx = 0; ty->cursor_state.cx = 0;
break; break;
case 'X': // erase N chars case 'X': // erase N chars
@ -1029,7 +1029,9 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
if (!arg) if (!arg)
{ {
ty->cursor_state.cx = cx; ty->cursor_state.cx = cx;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
ty->cursor_state.cy = cy; ty->cursor_state.cy = cy;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
} }
} }
break; break;

View File

@ -7,6 +7,7 @@
#include "termptygfx.h" #include "termptygfx.h"
#include "termptysave.h" #include "termptysave.h"
#include "miniview.h" #include "miniview.h"
#include <assert.h>
#undef CRITICAL #undef CRITICAL
#undef ERR #undef ERR
@ -151,6 +152,7 @@ termpty_text_scroll_test(Termpty *ty, Eina_Bool clear)
{ {
termpty_text_scroll(ty, clear); termpty_text_scroll(ty, clear);
ty->cursor_state.cy = e - 1; ty->cursor_state.cy = e - 1;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
} }
} }
@ -164,6 +166,7 @@ termpty_text_scroll_rev_test(Termpty *ty, Eina_Bool clear)
{ {
termpty_text_scroll_rev(ty, clear); termpty_text_scroll_rev(ty, clear);
ty->cursor_state.cy = b; ty->cursor_state.cy = b;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
} }
} }
@ -220,7 +223,10 @@ termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len)
if (EINA_UNLIKELY(ty->cursor_state.cx >= (ty->w - offset))) if (EINA_UNLIKELY(ty->cursor_state.cx >= (ty->w - offset)))
ty->termstate.wrapnext = 1; ty->termstate.wrapnext = 1;
else else
ty->cursor_state.cx += offset; {
ty->cursor_state.cx += offset;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
}
} }
else else
{ {
@ -235,8 +241,10 @@ termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len)
if (ty->cursor_state.cx > (ty->w - offset)) if (ty->cursor_state.cx > (ty->w - offset))
{ {
ty->cursor_state.cx = ty->w - offset; ty->cursor_state.cx = ty->w - offset;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
return; return;
} }
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
} }
} }
} }
@ -248,6 +256,8 @@ termpty_clear_line(Termpty *ty, Termpty_Clear mode, int limit)
int n = 0; int n = 0;
Evas_Coord x = 0, y = ty->cursor_state.cy; Evas_Coord x = 0, y = ty->cursor_state.cy;
assert (y >= 0 && y < ty->h);
switch (mode) switch (mode)
{ {
case TERMPTY_CLR_END: case TERMPTY_CLR_END: