aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin/termptyops.c
diff options
context:
space:
mode:
authorCarsten Haitzler <raster@rasterman.com>2012-07-13 08:46:33 +0000
committerCarsten Haitzler <raster@rasterman.com>2012-07-13 08:46:33 +0000
commit197e0bbf46d74b622f43315f0daa9b0f6105a93d (patch)
tree4ce8a1831db77a7e7c3fcc6d1f45cef56e0ceaea /src/bin/termptyops.c
parentmouve doublewidth checking to its own file to not "pollute" termpty.c. (diff)
downloadterminology-197e0bbf46d74b622f43315f0daa9b0f6105a93d.tar.gz
splut up termpty a lot. still escape handling is the largest bit -
1200 lines or so, but not a lot that canbe done about that as its the smallest really logical unit there. SVN revision: 73798
Diffstat (limited to 'src/bin/termptyops.c')
-rw-r--r--src/bin/termptyops.c354
1 files changed, 354 insertions, 0 deletions
diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c
new file mode 100644
index 0000000..d7c2dbc
--- /dev/null
+++ b/src/bin/termptyops.c
@@ -0,0 +1,354 @@
+#include "private.h"
+#include <Elementary.h>
+#include "termpty.h"
+#include "termptydbl.h"
+#include "termptyops.h"
+#include "termptygfx.h"
+
+#undef CRITICAL
+#undef ERR
+#undef WRN
+#undef INF
+#undef DBG
+
+#define CRITICAL(...) EINA_LOG_DOM_CRIT(_termpty_log_dom, __VA_ARGS__)
+#define ERR(...) EINA_LOG_DOM_ERR(_termpty_log_dom, __VA_ARGS__)
+#define WRN(...) EINA_LOG_DOM_WARN(_termpty_log_dom, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_termpty_log_dom, __VA_ARGS__)
+#define DBG(...) EINA_LOG_DOM_DBG(_termpty_log_dom, __VA_ARGS__)
+
+static void
+_text_clear(Termpty *ty, Termcell *cells, int count, int val, Eina_Bool inherit_att)
+{
+ int i;
+ Termatt clear;
+
+ memset(&clear, 0, sizeof(clear));
+ if (inherit_att)
+ {
+ for (i = 0; i < count; i++)
+ {
+ cells[i].codepoint = val;
+ cells[i].att = ty->state.att;
+ }
+ }
+ else
+ {
+ for (i = 0; i < count; i++)
+ {
+ cells[i].codepoint = val;
+ cells[i].att = clear;
+ }
+ }
+}
+
+static void
+_text_save_top(Termpty *ty)
+{
+ Termsave *ts;
+
+ if (ty->backmax <= 0) return;
+ ts = malloc(sizeof(Termsave) + ((ty->w - 1) * sizeof(Termcell)));
+ ts->w = ty->w;
+ _termpty_text_copy(ty, ty->screen, ts->cell, ty->w);
+ if (!ty->back) ty->back = calloc(1, sizeof(Termsave *) * ty->backmax);
+ if (ty->back[ty->backpos]) free(ty->back[ty->backpos]);
+ ty->back[ty->backpos] = ts;
+ ty->backpos++;
+ if (ty->backpos >= ty->backmax) ty->backpos = 0;
+ ty->backscroll_num++;
+ if (ty->backscroll_num >= ty->backmax) ty->backscroll_num = ty->backmax - 1;
+}
+
+void
+_termpty_text_copy(Termpty *ty __UNUSED__, Termcell *cells, Termcell *dest, int count)
+{
+ memcpy(dest, cells, sizeof(*(cells)) * count);
+}
+
+void
+_termpty_text_scroll(Termpty *ty)
+{
+ Termcell *cells = NULL, *cells2;
+ int y, start_y = 0, end_y = ty->h - 1;
+
+ if (ty->state.scroll_y2 != 0)
+ {
+ start_y = ty->state.scroll_y1;
+ end_y = ty->state.scroll_y2 - 1;
+ }
+ else
+ {
+ if (!ty->altbuf)
+ {
+ _text_save_top(ty);
+ if (ty->cb.scroll.func) ty->cb.scroll.func(ty->cb.scroll.data);
+ }
+ else
+ if (ty->cb.cancel_sel.func)
+ ty->cb.cancel_sel.func(ty->cb.cancel_sel.data);
+ }
+ DBG("... scroll!!!!! [%i->%i]", start_y, end_y);
+ cells2 = &(ty->screen[end_y * ty->w]);
+ for (y = start_y; y < end_y; y++)
+ {
+ cells = &(ty->screen[y * ty->w]);
+ cells2 = &(ty->screen[(y + 1) * ty->w]);
+ _termpty_text_copy(ty, cells2, cells, ty->w);
+ }
+ _text_clear(ty, cells2, ty->w, ' ', EINA_TRUE);
+}
+
+void
+_termpty_text_scroll_rev(Termpty *ty)
+{
+ Termcell *cells, *cells2 = NULL;
+ int y, start_y = 0, end_y = ty->h - 1;
+
+ if (ty->state.scroll_y2 != 0)
+ {
+ start_y = ty->state.scroll_y1;
+ end_y = ty->state.scroll_y2 - 1;
+ }
+ DBG("... scroll rev!!!!! [%i->%i]", start_y, end_y);
+ cells = &(ty->screen[end_y * ty->w]);
+ for (y = end_y; y > start_y; y--)
+ {
+ cells = &(ty->screen[(y - 1) * ty->w]);
+ cells2 = &(ty->screen[y * ty->w]);
+ _termpty_text_copy(ty, cells, cells2, ty->w);
+ }
+ _text_clear(ty, cells, ty->w, ' ', EINA_TRUE);
+}
+
+void
+_termpty_text_scroll_test(Termpty *ty)
+{
+ int e = ty->h;
+
+ if (ty->state.scroll_y2 != 0) e = ty->state.scroll_y2;
+ if (ty->state.cy >= e)
+ {
+ _termpty_text_scroll(ty);
+ ty->state.cy = e - 1;
+ }
+}
+
+void
+_termpty_text_scroll_rev_test(Termpty *ty)
+{
+ int b = 0;
+
+ if (ty->state.scroll_y2 != 0) b = ty->state.scroll_y1;
+ if (ty->state.cy < b)
+ {
+ _termpty_text_scroll_rev(ty);
+ ty->state.cy = b;
+ }
+}
+
+void
+_termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len)
+{
+ Termcell *cells;
+ int i, j;
+
+ cells = &(ty->screen[ty->state.cy * ty->w]);
+ for (i = 0; i < len; i++)
+ {
+ Eina_Unicode g;
+
+ if (ty->state.wrapnext)
+ {
+ cells[ty->state.cx].att.autowrapped = 1;
+ ty->state.wrapnext = 0;
+ ty->state.cx = 0;
+ ty->state.cy++;
+ _termpty_text_scroll_test(ty);
+ cells = &(ty->screen[ty->state.cy * ty->w]);
+ }
+ if (ty->state.insert)
+ {
+ for (j = ty->w - 1; j > ty->state.cx; j--)
+ cells[j] = cells[j - 1];
+ }
+
+ g = _termpty_charset_trans(codepoints[i], ty->state.charsetch);
+
+ cells[ty->state.cx].codepoint = g;
+ cells[ty->state.cx].att = ty->state.att;
+#if defined(SUPPORT_DBLWIDTH)
+ cells[ty->state.cx].att.dblwidth = _termpty_is_dblwidth_get(ty, g);
+ if ((cells[ty->state.cx].att.dblwidth) && (ty->state.cx < (ty->w - 1)))
+ {
+ cells[ty->state.cx + 1].codepoint = 0;
+ cells[ty->state.cx + 1].att = cells[ty->state.cx].att;
+ }
+#endif
+ if (ty->state.wrap)
+ {
+ ty->state.wrapnext = 0;
+#if defined(SUPPORT_DBLWIDTH)
+ if (cells[ty->state.cx].att.dblwidth)
+ {
+ if (ty->state.cx >= (ty->w - 2)) ty->state.wrapnext = 1;
+ else ty->state.cx += 2;
+ }
+ else
+ {
+ if (ty->state.cx >= (ty->w - 1)) ty->state.wrapnext = 1;
+ else ty->state.cx++;
+ }
+#else
+ if (ty->state.cx >= (ty->w - 1)) ty->state.wrapnext = 1;
+ else ty->state.cx++;
+#endif
+ }
+ else
+ {
+ ty->state.wrapnext = 0;
+ ty->state.cx++;
+#if defined(SUPPORT_DBLWIDTH)
+ if (cells[ty->state.cx].att.dblwidth)
+ {
+ ty->state.cx++;
+ if (ty->state.cx >= (ty->w - 1))
+ ty->state.cx = ty->w - 2;
+ }
+ else
+ {
+ if (ty->state.cx >= ty->w)
+ ty->state.cx = ty->w - 1;
+ }
+#else
+ if (ty->state.cx >= ty->w)
+ ty->state.cx = ty->w - 1;
+#endif
+ }
+ }
+}
+
+void
+_termpty_clear_line(Termpty *ty, Termpty_Clear mode, int limit)
+{
+ Termcell *cells;
+ int n = 0;
+
+ cells = &(ty->screen[ty->state.cy * ty->w]);
+ switch (mode)
+ {
+ case TERMPTY_CLR_END:
+ n = ty->w - ty->state.cx;
+ cells = &(cells[ty->state.cx]);
+ break;
+ case TERMPTY_CLR_BEGIN:
+ n = ty->state.cx + 1;
+ break;
+ case TERMPTY_CLR_ALL:
+ n = ty->w;
+ break;
+ default:
+ return;
+ }
+ if (n > limit) n = limit;
+ _text_clear(ty, cells, n, 0, EINA_TRUE);
+}
+
+void
+_termpty_clear_screen(Termpty *ty, Termpty_Clear mode)
+{
+ Termcell *cells;
+
+ cells = ty->screen;
+ switch (mode)
+ {
+ case TERMPTY_CLR_END:
+ _termpty_clear_line(ty, mode, ty->w);
+ if (ty->state.cy < (ty->h - 1))
+ {
+ cells = &(ty->screen[(ty->state.cy + 1) * ty->w]);
+ _text_clear(ty, cells, ty->w * (ty->h - ty->state.cy - 1), 0, EINA_TRUE);
+ }
+ break;
+ case TERMPTY_CLR_BEGIN:
+ if (ty->state.cy > 0)
+ _text_clear(ty, cells, ty->w * ty->state.cy, 0, EINA_TRUE);
+ _termpty_clear_line(ty, mode, ty->w);
+ break;
+ case TERMPTY_CLR_ALL:
+ _text_clear(ty, cells, ty->w * ty->h, 0, EINA_TRUE);
+ break;
+ default:
+ break;
+ }
+ if (ty->cb.cancel_sel.func)
+ ty->cb.cancel_sel.func(ty->cb.cancel_sel.data);
+}
+
+void
+_termpty_clear_all(Termpty *ty)
+{
+ if (!ty->screen) return;
+ memset(ty->screen, 0, sizeof(*(ty->screen)) * ty->w * ty->h);
+}
+
+void
+_termpty_reset_att(Termatt *att)
+{
+ att->fg = COL_DEF;
+ att->bg = COL_DEF;
+ att->bold = 0;
+ att->faint = 0;
+#if defined(SUPPORT_ITALIC)
+ att->italic = 0;
+#elif defined(SUPPORT_DBLWIDTH)
+ att->dblwidth = 0;
+#endif
+ att->underline = 0;
+ att->blink = 0;
+ att->blink2 = 0;
+ att->inverse = 0;
+ att->invisible = 0;
+ att->strike = 0;
+ att->fg256 = 0;
+ att->bg256 = 0;
+ att->fgintense = 0;
+ att->bgintense = 0;
+ att->autowrapped = 0;
+ att->newline = 0;
+ att->tab = 0;
+}
+
+void
+_termpty_reset_state(Termpty *ty)
+{
+ ty->state.cx = 0;
+ ty->state.cy = 0;
+ ty->state.scroll_y1 = 0;
+ ty->state.scroll_y2 = 0;
+ ty->state.had_cr_x = 0;
+ ty->state.had_cr_y = 0;
+ _termpty_reset_att(&(ty->state.att));
+ ty->state.charset = 0;
+ ty->state.charsetch = 'B';
+ ty->state.chset[0] = 'B';
+ ty->state.chset[1] = 'B';
+ ty->state.chset[2] = 'B';
+ ty->state.chset[3] = 'B';
+ ty->state.multibyte = 0;
+ ty->state.alt_kp = 0;
+ ty->state.insert = 0;
+ ty->state.appcursor = 0;
+ ty->state.wrap = 1;
+ ty->state.wrapnext = 0;
+ ty->state.hidecursor = 0;
+ ty->state.crlf = 0;
+ ty->state.had_cr = 0;
+}
+
+void
+_termpty_cursor_copy(Termstate *state, Termstate *dest)
+{
+ dest->cx = state->cx;
+ dest->cy = state->cy;
+}