typedef uint16_t text_t; // saves lots of memory
#endif
typedef uint32_t rend_t;
-typedef int16_t tlen_t;
+typedef int32_t tlen_t; // was int16_t, but this result sin smaller code and memory use
#define LINE_CONT -1
};
/*
- * TermWin elements limits
- * width : 1 <= width
- * height : 1 <= height
- * ncol : 1 <= ncol <= MAX(int16_t)
- * nrow : 1 <= nrow <= MAX(int16_t)
- * saveLines : 0 <= saveLines <= MAX(int16_t)
- * nlines : nrow + saveLines
- * nsaved : 0 <= nsaved <= saveLines
- * term_start: 0 <= term_start < saveLines
- * view_start: 0 <= view_start < saveLines
+ * terminal limits:
+ *
+ * width : 1 <= width
+ * height : 1 <= height
+ * ncol : 1 <= ncol <= MAX(int16_t)
+ * nrow : 1 <= nrow <= MAX(int16_t)
+ * saveLines : 0 <= saveLines <= MAX(int16_t)
+ * total_rows : nrow + saveLines
+ * nsaved : 0 <= nsaved <= saveLines
+ * term_start : 0 <= term_start < saveLines
+ * view_start : 0 <= view_start < saveLines
+ *
+ * | most coordinates are stored relative to term_start,
+ * ROW_BUF | which is the first line of the terminal screen
+ * |························= row_buf[0]
+ * |························= row_buf[1]
+ * |························= row_buf[2] etc.
+ * |
+ * +------------+···········= term_start - nsaved
+ * | scrollback |
+ * | scrollback +---------+·= term_start - view_start
+ * | scrollback | display |
+ * | scrollback | display |
+ * +------------+·display·+·= term_start
+ * | terminal | display |
+ * | terminal +---------+
+ * | terminal |
+ * | terminal |
+ * +------------+···········= term_stat + nrow - 1
+ * |
+ * |
+ * END······················= total_rows
*/
struct TermWin_t {
int height; /* window height [pixels] */
int fwidth; /* font width [pixels] */
int fheight; /* font height [pixels] */
- int fweight, fslant;
int fbase; /* font ascent (baseline) [pixels] */
int ncol; /* window columns [characters] */
int nrow; /* window rows [characters] */
/*
* screen accounting:
* screen_t elements
- * text: Contains all text information including the scrollback buffer.
- * Each line is length ncol
- * tlen: The length of the line or -1 for wrapped lines.
- * rend: Contains rendition information: font, bold, colour, etc.
- * * Note: Each line for both text and rend are only allocated on demand, and
- * text[x] is allocated <=> rend[x] is allocated for all x.
* row: Cursor row position : 0 <= row < nrow
* col: Cursor column position : 0 <= col < ncol
* tscroll: Scrolling region top row inclusive : 0 <= row < nrow
* * Note: -nsaved <= beg.row <= mark.row <= end.row < nrow
* * Note: col == -1 ==> we're left of screen
*
- * Layout of text/rend information in the screen_t text/rend structures:
- * Rows [0] ... [saveLines - 1]
- * scrollback region : we're only here if view_start != 0
- * Rows [saveLines] ... [saveLines + nrow - 1]
- * normal `unsaved' screen region
*/
typedef struct {
- line_t **line;
-
- row_col_t cur; /* cursor position on the screen */
- unsigned int tscroll; /* top of settable scroll region */
- unsigned int bscroll; /* bottom of settable scroll region */
+ row_col_t cur; /* cursor position on the screen */
+ int tscroll; /* top of settable scroll region */
+ int bscroll; /* bottom of settable scroll region */
unsigned int charset; /* character set number [0..3] */
unsigned int flags; /* see below */
row_col_t s_cur; /* saved cursor position */
int sb_shadow; /* scrollbar shadow width */
rxvt_ptytty pty;
int numlock_state;
- line_t *save; // all lines, scorllback + terminal, circular
- line_t *drawn; // text on screen
- line_t *buf; // temporary buffer
- line_t *swap_save; // lines for swap buffer
+ line_t *row_buf; // all lines, scrollback + terminal, circular
+ line_t *drawn_buf; // text on screen
+ line_t *temp_buf; // temporary buffer
+ line_t *swap_buf; // lines for swap buffer
char *tabs; /* per location: 1 == tab-stop */
screen_t screen;
screen_t swap;
/* ------------------------------------------------------------------------- *
* SCREEN INITIALISATION *
* ------------------------------------------------------------------------- */
+
void
rxvt_term::scr_reset ()
{
- unsigned int p, q;
- int k;
-
#if ENABLE_OVERLAY
scr_overlay_off ();
#endif
// we need at least two lines for wrapping to work correctly
if (nrow + saveLines < 2)
{
+ //TODO//FIXME
saveLines++;
prev_nrow--;
nsaved++;
screen.tscroll = 0;
screen.bscroll = nrow - 1;
- if (!save)
+ if (!row_buf)
{
/*
* first time called so just malloc everything: don't rely on realloc
talloc = new rxvt_salloc (ncol * sizeof (text_t));
ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
- save = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
- buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
- drawn = (line_t *)rxvt_calloc (nrow, sizeof (line_t));
- swap_save = (line_t *)rxvt_calloc (nrow, sizeof (line_t));
+ row_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
+ temp_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
+ drawn_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t));
+ swap_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t));
- for (p = nrow; p--; )
+ for (int row = nrow; row--; )
{
- scr_blank_screen_mem (ROW(p), DEFAULT_RSTYLE);
- scr_blank_screen_mem (swap_save[p], DEFAULT_RSTYLE);
- scr_blank_screen_mem (drawn[p], DEFAULT_RSTYLE);
+ scr_blank_screen_mem (ROW (row), DEFAULT_RSTYLE);
+ scr_blank_screen_mem (swap_buf [row], DEFAULT_RSTYLE);
+ scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE);
}
memset (charsets, 'B', sizeof (charsets));
* add or delete rows as appropriate
*/
- rxvt_salloc *old_ta;
- rxvt_salloc *old_ra;
+ printf ("resize %d:%d => %d:%d\n", prev_nrow, prev_ncol, nrow, ncol);//D
+ rxvt_salloc *old_ta = talloc; talloc = new rxvt_salloc (ncol * sizeof (text_t));
+ rxvt_salloc *old_ra = ralloc; ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
+
+#if 0
if (nrow < prev_nrow)
{
- /* delete rows */
- k = min (nsaved, prev_nrow - nrow);
- // k = max (0, - ( (nrow - 1) - r->screen.cur.row)); // mmc's http://maruska.dyndns.org/wiki/scrolling-bug //make configurable? //D TODO
- scr_scroll_text (0, (int)prev_nrow - 1, k);
-
- for (p = nrow; p < prev_nrow; p++)
+ for (int row = nrow; row < prev_nrow; row++)
{
- lfree (ROW(p));
- lfree (swap_save[p]);
- lfree (drawn[p]);
+ lfree (swap_buf [row]);
+ lfree (drawn_buf[row]);
}
-
- /* we have fewer rows so fix up cursor position */
- min_it (screen.cur.row, (int32_t)nrow - 1);
-
- scr_reset_realloc (); /* realloc _last_ */
}
- else if (nrow > prev_nrow)
- {
- /* add rows */
- scr_reset_realloc (); /* realloc _first_ */
-
- int ocol = ncol;
- ncol = prev_ncol; // save b/c scr_blank_screen_mem uses this
-
- k = min (nsaved, nrow - prev_nrow);
-
- for (p = prev_total_rows; p < total_rows; p++)
- save[p].clear ();
-
- for (p = prev_total_rows; p < total_rows - k; p++)
- scr_blank_screen_mem (save[p], DEFAULT_RSTYLE);
-
- for (p = prev_nrow; p < nrow; p++)
- {
- swap_save[p].clear (); scr_blank_screen_mem (swap_save[p], DEFAULT_RSTYLE);
- drawn[p].clear (); scr_blank_screen_mem (drawn[p], DEFAULT_RSTYLE);
- }
+#endif
- if (k > 0)
- {
- scr_scroll_text (0, (int)nrow - 1, -k);
- screen.cur.row += k;
- screen.s_cur.row += k;
- nsaved -= k;
- }
+ drawn_buf = (line_t *) rxvt_realloc (drawn_buf, nrow * sizeof (line_t));
+ temp_buf = (line_t *) rxvt_realloc (temp_buf , nrow * sizeof (line_t));
+ swap_buf = (line_t *) rxvt_realloc (swap_buf , nrow * sizeof (line_t));
-#ifdef DEBUG_STRICT
- assert (screen.cur.row < nrow);
-#else /* drive with your eyes closed */
- min_it (screen.cur.row, nrow - 1);
-#endif
- ncol = ocol; // save b/c scr_blank_screen_mem uses this
+ for (int row = min (nrow, prev_nrow); row--; )
+ {
+ lresize (drawn_buf[row]);
+ lresize (swap_buf [row]);
}
- /* resize columns */
- if (ncol != prev_ncol)
+ for (int row = prev_nrow; row < nrow; row++)
{
- old_ta = talloc; talloc = new rxvt_salloc (ncol * sizeof (text_t));
- old_ra = ralloc; ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
-
- for (p = total_rows; p--; )
- lresize (save[p]);
-
- for (p = nrow; p--; )
- {
- lresize (drawn[p]);
- lresize (swap_save[p]);
- }
-
- min_it (screen.cur.col, (int16_t)ncol - 1);
-
- delete old_ta;
- delete old_ra;
+ swap_buf [row].clear (); scr_blank_screen_mem (swap_buf [row], DEFAULT_RSTYLE);
+ drawn_buf[row].clear (); scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE);
}
-#if 0
+ line_t *old_buf = row_buf; row_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
+
// re-wrap lines, this is rather ugly, possibly because I am too dumb
// to come up with a lean and mean algorithm.
- rxvt_salloc *ta = new rxvt_salloc (ncol * sizeof (text_t));
- rxvt_salloc *ra = new rxvt_salloc (ncol * sizeof (rend_t));
-
- text_t **tp = (text_t **)rxvt_calloc (total_rows, sizeof (text_t *));
- rend_t **rp = (rend_t **)rxvt_calloc (total_rows, sizeof (rend_t *));
- tlen_t *tl = (tlen_t *) rxvt_calloc (total_rows, sizeof (tlen_t));
- for (p = 0; p < prev_total_rows; p++) printf ("P %p %d\n", save[p].t, save[p].l);//D
+ int p = MOD (term_start + nrow , prev_total_rows); // previous row
+ int pend = MOD (term_start - nsaved, prev_total_rows);
+ int q = total_rows; // rewrapped row
- p = prev_total_rows;
- q = total_rows;
-
- while (p > 0 && q > 0)
+ while (p != pend && q > 0)
{
- --p;
+ p = MOD (p - 1, prev_total_rows);
- printf ("pq %d:%d\n", p, q);
- if (save[p].t)
- {
- int llen = save[p].l;
+ assert (old_buf [MOD (p, prev_total_rows)].t);
+ assert (!old_buf [MOD (p, prev_total_rows)].is_longer ());
- assert (llen >= 0);
+ int llen = old_buf [MOD (p, prev_total_rows)].l;
- while (p && save[p - 1].l < 0)
- {
- --p;
- llen += prev_ncol;
- }
+ while (p != pend && old_buf [MOD (p - 1, prev_total_rows)].is_longer ())
+ {
+ p = MOD (p - 1, prev_total_rows);
- int qlines = llen / ncol + 1;
- int lofs = 0;
+ llen += prev_ncol;
+ }
+
+ int qlines = llen / ncol + 1;
+ int lofs = 0;
- q -= qlines;
+ q -= qlines;
- int qrow = q;
+ int qrow = q;
- printf ("QL %d llen %d\n", qlines, llen);//D
- for (; qlines--; qrow++)
+ for (; qlines--; qrow++)
+ {
+ if (qrow >= 0)
{
- if (qrow >= 0)
- {
- tp [qrow] = (text_t *)ta->alloc ();
- rp [qrow] = (rend_t *)ra->alloc ();
- tl [qrow] = LINE_CONT1;
+ line_t &qline = row_buf [qrow];
- int qcol = 0;
+ lalloc (qline);
+ qline.set_is_longer ();
- for (;;)
- {
- int prow = lofs / prev_ncol + p;
- int pcol = lofs % prev_ncol;
+ int qcol = 0;
- int len = min (min (prev_ncol - pcol, ncol - qcol), llen - lofs);
+ for (;;)
+ {
+ int prow = lofs / prev_ncol + p;
+ int pcol = lofs % prev_ncol;
- printf ("q %d lofs %d>%d len %d pq %d:%d p %d:%d q :%d\n", q, llen, lofs, len, prev_ncol, ncol, prow, pcol, qcol);
+ line_t &pline = old_buf [p];
- if (len <= 0)
- {
- tl [qrow] = qcol;
+ int len = min (min (prev_ncol - pcol, ncol - qcol), llen - lofs);
- TODO
- scr_blank_line (tp [qrow] + qcol, rp [qrow] + qcol,
- ncol - qcol, DEFAULT_RSTYLE);
+ printf ("q %d lofs %d>%d len %d pq %d:%d p %d:%d q :%d\n", q, llen, lofs, len, prev_ncol, ncol, prow, pcol, qcol);
- break;
- }
+ if (len <= 0)
+ {
+ qline.l = qcol;
+ scr_blank_line (qline, qcol, ncol - qcol, DEFAULT_RSTYLE);
+ break;
+ }
- assert (lofs < 1000);
+ assert (lofs < 1000);
- memcpy (tp [qrow] + qcol, save[prow].t + pcol, len * sizeof (text_t));
- memcpy (rp [qrow] + qcol, save[prow].r + pcol, len * sizeof (rend_t));
+ memcpy (qline.t + qcol, pline.t + pcol, len * sizeof (text_t));
+ memcpy (qline.r + qcol, pline.r + pcol, len * sizeof (rend_t));
- lofs += len;
- qcol += len;
+ lofs += len;
+ qcol += len;
- if (qcol == ncol)
- break;
- }
+ if (qcol == ncol)
+ break;
}
- else
- lofs += ncol;
}
+ else
+ lofs += ncol;
}
}
- free (screen.text); screen.text = tp;
- free (screen.rend); screen.rend = rp;
- free (screen.tlen); screen.tlen = tl;
+ free (old_buf);
+ delete old_ta;
+ delete old_ra;
- for (p = 0; p < total_rows; p++) printf ("P %p %d\n", save[p].t, save[p].l);//D
-#endif
+ min_it (screen.cur.row, nrow - 1);
+ min_it (screen.cur.col, ncol - 1);
if (tabs)
free (tabs);
tabs = (char *)rxvt_malloc (ncol * sizeof (char));
- for (p = 0; p < ncol; p++)
- tabs[p] = (p % TABSIZE == 0) ? 1 : 0;
+ for (int col = ncol; col--; )
+ tabs [col] = col % TABSIZE == 0;
tt_winch ();
}
-void
-rxvt_term::scr_reset_realloc ()
-{
- swap_save = (line_t *) rxvt_realloc (swap_save , nrow * sizeof (line_t));
- drawn = (line_t *) rxvt_realloc (drawn , nrow * sizeof (line_t));
- buf = (line_t *) rxvt_realloc (buf , nrow * sizeof (line_t));
- save = (line_t *) rxvt_realloc (save , total_rows * sizeof (line_t));
-}
-
/* ------------------------------------------------------------------------- */
/*
* Free everything. That way malloc debugging can find leakage.
delete talloc; talloc = 0;
delete ralloc; ralloc = 0;
- free (save);
- free (swap_save);
- free (drawn);
- free (buf);
+ free (row_buf);
+ free (swap_buf);
+ free (drawn_buf);
+ free (temp_buf);
free (tabs);
}
num_scr = 0;
for (int i = nrow; i--; )
- ::swap (ROW(i), swap_save[i]);
+ ::swap (ROW(i), swap_buf [i]);
::swap (screen.charset, swap.charset);
::swap (screen.flags, swap.flags);
int rows = row2 - row1 + 1;
+ min_it (count, rows);
+
for (int row = 0; row < rows; row++)
{
- buf [row] = ROW(row1 + (row + count + rows) % rows);
+ temp_buf [row] = ROW(row1 + (row + count + rows) % rows);
if (!IN_RANGE_EXC (row + count, 0, rows))
- scr_blank_screen_mem (buf [row], rstyle);
+ scr_blank_screen_mem (temp_buf [row], rstyle);
}
for (int row = 0; row < rows; row++)
- ROW(row1 + row) = buf [row];
+ ROW(row1 + row) = temp_buf [row];
}
return count;
if (nlines > 0)
{
nlines += screen.cur.row - screen.bscroll;
- if ((nlines > 0)
- && (screen.tscroll == 0)
- && (screen.bscroll == (nrow - 1)))
+ if (nlines > 0
+ && screen.tscroll == 0
+ && screen.bscroll == (nrow - 1))
{
/* _at least_ this many lines need to be scrolled */
scr_scroll_text (screen.tscroll, screen.bscroll, nlines);
#ifdef DEBUG_STRICT
assert (screen.cur.col < last_col);
- assert ((screen.cur.row < nrow)
- && (screen.cur.row >= - (int32_t)nsaved));
+ assert (screen.cur.row < nrow
+ && screen.cur.row >= -nsaved);
#else /* drive with your eyes closed */
min_it (screen.cur.col, last_col - 1);
- min_it (screen.cur.row, (int32_t)nrow - 1);
- max_it (screen.cur.row, - (int32_t)nsaved);
+ clamp_it (screen.cur.row, -nsaved, nrow - 1);
#endif
row = screen.cur.row;
ZERO_SCROLLBACK ();
screen.cur.col = relative & C_RELATIVE ? screen.cur.col + col : col;
- max_it (screen.cur.col, 0);
- min_it (screen.cur.col, (int32_t)ncol - 1);
+ clamp_it (screen.cur.col, 0, ncol - 1);
screen.flags &= ~Screen_WrapNext;
screen.cur.row = row;
}
- max_it (screen.cur.row, 0);
- min_it (screen.cur.row, (int32_t)nrow - 1);
+ clamp_it (screen.cur.row, 0, nrow - 1);
}
/* ------------------------------------------------------------------------- */
else
screen.cur.row += dirn;
- max_it (screen.cur.row, 0);
- min_it (screen.cur.row, (int32_t)nrow - 1);
+ clamp_it (screen.cur.row, 0, nrow - 1);
selection_check (0);
}
case 0: /* erase to end of line */
col = screen.cur.col;
num = ncol - col;
- min_it (ROW(row).l, (int16_t)col);
+ min_it (ROW(row).l, col);
if (ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur)
|| ROWCOL_IN_ROW_AT_OR_AFTER (selection.end, screen.cur))
CLEAR_SELECTION ();
if (row >= nrow) /* Out Of Bounds */
return;
- min_it (num, (nrow - row));
+ min_it (num, nrow - row);
if (rstyle & (RS_RVid | RS_Uline))
ren = (rend_t) ~RS_None;
{
scr_blank_screen_mem (ROW (row), rstyle);
ROW (row).l = 0;
- scr_blank_line (drawn[row], 0, ncol, ren);
+ scr_blank_line (drawn_buf [row], 0, ncol, ren);
}
}
scr_do_wrap ();
selection_check (1);
- min_it (count, (ncol - screen.cur.col));
+ min_it (count, ncol - screen.cur.col);
row = screen.cur.row;
rxvt_term::scr_scroll_region (int top, int bot)
{
max_it (top, 0);
- min_it (bot, (int)nrow - 1);
+ min_it (bot, nrow - 1);
if (top > bot)
return;
for (int i = 0; i < nrow; i++)
{
int col = 0;
- rend_t *drp = drawn[i].r;
+ rend_t *drp = drawn_buf[i].r;
for (; col < ncol; col++, drp++)
if ((*drp & mask) == value)
int i;
row_col_t rc[RC_COUNT];
- if (!drawn) /* sanity check */
+ if (!drawn_buf) /* sanity check */
return;
#ifndef NO_SLOW_LINK_SUPPORT
}
for (i = rc[PART_BEG].row; i <= rc[PART_END].row; i++)
- fill_text (&drawn[i].t[rc[PART_BEG].col], 0, rc[PART_END].col - rc[PART_BEG].col + 1);
+ fill_text (&drawn_buf[i].t[rc[PART_BEG].col], 0, rc[PART_END].col - rc[PART_BEG].col + 1);
if (refresh)
scr_refresh (SLOW_REFRESH);
{
if (ocrow < nrow
&& oldcursor.col < ncol)
- drawn[ocrow].r[oldcursor.col] ^= (RS_RVid | RS_Uline);
+ drawn_buf[ocrow].r[oldcursor.col] ^= (RS_RVid | RS_Uline);
if (focus || !showcursor)
oldcursor.row = -1;
if (row + i >= 0 && row + i < nrow && row + i != ocrow)
{
line_t s = ROW(row - view_start);
- line_t d = drawn[row];
- line_t d2 = drawn[row + i];
+ line_t d = drawn_buf[row];
+ line_t d2 = drawn_buf[row + i];
for (nits = 0, col = ncol; col--; )
if (s.t[col] != d2.t[col] || s.r[col] != d2.r[col])
{
text_t *stp = ROW(row - view_start).t;
rend_t *srp = ROW(row - view_start).r;
- text_t *dtp = drawn[row].t;
- rend_t *drp = drawn[row].r;
+ text_t *dtp = drawn_buf[row].t;
+ rend_t *drp = drawn_buf[row].r;
/*
* E2: OK, now the real pass
col--;
while (col + cursorwidth < ncol
- && drawn[oldcursor.row].t[col + cursorwidth] == NOCHAR)
+ && drawn_buf[oldcursor.row].t[col + cursorwidth] == NOCHAR)
cursorwidth++;
#ifndef NO_CURSORCOLOR
rxvt_term::scr_remap_chars ()
{
for (int i = total_rows; i--; )
- scr_remap_chars (save[i]);
+ scr_remap_chars (row_buf [i]);
for (int i = nrow; i--; )
{
- scr_remap_chars (drawn[i]);
- scr_remap_chars (swap_save[i]);
+ scr_remap_chars (drawn_buf [i]);
+ scr_remap_chars (swap_buf [i]);
}
}
for (row = saveLines - nsaved;
row < saveLines + nrow - 1; row++)
{
- width = save[row].l >= 0 ? save[row].l
+ width = row_buf[row].l >= 0 ? row_buf[row].l
: ncol;
for (towrite = width; towrite; towrite -= wrote)
{
- wrote = write (fd, & (save[row].t[width - towrite]),
+ wrote = write (fd, & (row_buf[row].t[width - towrite]),
towrite);
if (wrote < 0)
return; /* XXX: death, no report */
}
- if (save[row].l >= 0)
+ if (row_buf[row].l >= 0)
if (write (fd, r1, 1) <= 0)
return; /* XXX: death, no report */
}
w += 2; min_it (w, ncol);
h += 2; min_it (h, nrow);
- x -= 1; max_it (x, 0);
- y -= 1; max_it (y, 0);
-
- min_it (x, ncol - w);
- min_it (y, nrow - h);
+ x -= 1; clamp_it (x, 0, ncol - w);
+ y -= 1; clamp_it (y, 0, nrow - h);
ov_x = x; ov_y = y;
ov_w = w; ov_h = h;