Scrolling region.

This commit is contained in:
Nicholas Marriott 2007-08-28 09:19:50 +00:00
parent 38b752c1d8
commit fc63750d30
5 changed files with 95 additions and 52 deletions

View File

@ -1,3 +1,7 @@
28 August 2007
* Scrolling region (\e[r) support.
27 August 2007 27 August 2007
* Change screen.c to work more logically and hopefully fix heap corruption. * Change screen.c to work more logically and hopefully fix heap corruption.
@ -12,5 +16,5 @@
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. customisation.
$Id: CHANGES,v 1.3 2007-08-27 09:53:38 nicm Exp $ $Id: CHANGES,v 1.4 2007-08-28 09:19:50 nicm Exp $

View File

@ -1,4 +1,4 @@
/* $Id: input.c,v 1.3 2007-08-27 11:05:21 nicm Exp $ */ /* $Id: input.c,v 1.4 2007-08-28 09:19:50 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -449,7 +449,7 @@ input_pair_control(u_char **buf, size_t *len,
(*len) -= size + 1; (*len) -= size + 1;
break; break;
case 'M': /* RI */ case 'M': /* RI */
input_store_one(b, CODE_CURSORUPSCROLL, 1); input_store_zero(b, CODE_REVERSEINDEX);
break; break;
default: default:
log_debug("unknown control2: %c (%hhu)", ch, ch); log_debug("unknown control2: %c (%hhu)", ch, ch);

11
local.c
View File

@ -1,4 +1,4 @@
/* $Id: local.c,v 1.4 2007-07-25 23:13:18 nicm Exp $ */ /* $Id: local.c,v 1.5 2007-08-28 09:19:50 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -557,20 +557,13 @@ local_output(struct buffer *b, size_t size)
} }
local_putp(cursor_invisible); local_putp(cursor_invisible);
break; break;
case CODE_CURSORUPSCROLL: case CODE_REVERSEINDEX:
if (scroll_reverse == NULL) { if (scroll_reverse == NULL) {
log_warnx("scroll_reverse not supported"); log_warnx("scroll_reverse not supported");
break; break;
} }
local_putp(scroll_reverse); local_putp(scroll_reverse);
break; break;
case CODE_CURSORDOWNSCROLL:
if (scroll_forward == NULL) {
log_warnx("scroll_forward not supported");
break;
}
local_putp(scroll_forward);
break;
case CODE_SCROLLREGION: case CODE_SCROLLREGION:
if (size < 4) if (size < 4)
fatalx("underflow"); fatalx("underflow");

120
screen.c
View File

@ -1,4 +1,4 @@
/* $Id: screen.c,v 1.7 2007-08-27 11:21:05 nicm Exp $ */ /* $Id: screen.c,v 1.8 2007-08-28 09:19:50 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -37,8 +37,10 @@ void screen_fill_lines(
struct screen *, u_int, u_int, u_char, u_char, u_char); struct screen *, u_int, u_int, u_char, u_char, u_char);
uint16_t screen_extract(u_char *); uint16_t screen_extract(u_char *);
void screen_write_character(struct screen *, u_char); void screen_write_character(struct screen *, u_char);
void screen_cursor_up_scroll(struct screen *, u_int); void screen_cursor_up_scroll(struct screen *);
void screen_cursor_down_scroll(struct screen *, u_int); void screen_cursor_down_scroll(struct screen *);
void screen_scroll_region_up(struct screen *);
void screen_scroll_region_down(struct screen *);
void screen_scroll_up(struct screen *, u_int); void screen_scroll_up(struct screen *, u_int);
void screen_scroll_down(struct screen *, u_int); void screen_scroll_down(struct screen *, u_int);
void screen_fill_screen(struct screen *, u_char, u_char, u_char); void screen_fill_screen(struct screen *, u_char, u_char, u_char);
@ -381,7 +383,7 @@ screen_character(struct screen *s, u_char ch)
{ {
switch (ch) { switch (ch) {
case '\n': /* LF */ case '\n': /* LF */
screen_cursor_down_scroll(s, 1); screen_cursor_down_scroll(s);
break; break;
case '\r': /* CR */ case '\r': /* CR */
s->cx = 0; s->cx = 0;
@ -492,13 +494,8 @@ screen_sequence(struct screen *s, u_char *ptr)
case CODE_CURSOROFF: case CODE_CURSOROFF:
s->mode &= ~MODE_CURSOR; s->mode &= ~MODE_CURSOR;
break; break;
case CODE_CURSORDOWNSCROLL: case CODE_REVERSEINDEX:
ua = screen_extract(ptr); screen_cursor_up_scroll(s);
screen_cursor_down_scroll(s, ua);
break;
case CODE_CURSORUPSCROLL:
ua = screen_extract(ptr);
screen_cursor_up_scroll(s, ua);
break; break;
case CODE_SCROLLREGION: case CODE_SCROLLREGION:
ua = screen_extract(ptr); ua = screen_extract(ptr);
@ -623,7 +620,7 @@ screen_write_character(struct screen *s, u_char ch)
{ {
if (s->cx > screen_last_x(s)) { if (s->cx > screen_last_x(s)) {
s->cx = 0; s->cx = 0;
screen_cursor_down_scroll(s, 1); screen_cursor_down_scroll(s);
} }
s->grid_data[s->cy][s->cx] = ch; s->grid_data[s->cy][s->cx] = ch;
@ -635,48 +632,98 @@ screen_write_character(struct screen *s, u_char ch)
/* Move cursor up and scroll if necessary. */ /* Move cursor up and scroll if necessary. */
void void
screen_cursor_up_scroll(struct screen *s, u_int ny) screen_cursor_up_scroll(struct screen *s)
{ {
if (s->cy < ny) { if (s->cy == s->ry_upper)
screen_scroll_down(s, ny - s->cy); screen_scroll_region_down(s);
s->cy = 0; else if (s->cy > 0)
} else s->cy--;
s->cy -= ny;
} }
/* Move cursor down and scroll if necessary. */ /* Move cursor down and scroll if necessary. */
void void
screen_cursor_down_scroll(struct screen *s, u_int ny) screen_cursor_down_scroll(struct screen *s)
{ {
if (s->cy + ny > screen_last_y(s)) { if (s->cy == s->ry_lower)
screen_scroll_up(s, ny - (screen_last_y(s) - s->cy)); screen_scroll_region_up(s);
s->cy = screen_last_y(s); else if (s->cy < screen_last_y(s))
} else s->cy++;
s->cy += ny; }
/* Scroll region up. */
void
screen_scroll_region_up(struct screen *s)
{
log_debug("scrolling region up: %u:%u", s->ry_upper, s->ry_lower);
/*
* Scroll scrolling region up:
* - delete ry_upper
* - move ry_upper + 1 to ry_lower to ry_upper
* - make new line at ry_lower
*
* Example: region is 12 to 24.
* ry_lower = 24, ry_upper = 12
* screen_free_lines(s, 12, 1);
* screen_move_lines(s, 12, 13, 12);
* screen_make_lines(s, 24, 1);
*/
screen_free_lines(s, s->ry_upper, 1);
if (s->ry_upper != s->ry_lower) {
screen_move_lines(s,
s->ry_upper, s->ry_upper + 1, s->ry_lower - s->ry_upper);
}
screen_make_lines(s, s->ry_lower, 1);
screen_fill_lines(
s, s->ry_lower, 1, SCREEN_DEFDATA, SCREEN_DEFATTR, SCREEN_DEFCOLR);
}
/* Scroll region down. */
void
screen_scroll_region_down(struct screen *s)
{
log_debug("scrolling region down: %u:%u", s->ry_upper, s->ry_lower);
/*
* Scroll scrolling region down:
* - delete ry_lower
* - move ry_upper to ry_lower - 1 to ry_upper + 1
* - make new line at ry_upper
*
* Example: region is 12 to 24.
* ry_lower = 24, ry_upper = 12
* screen_free_lines(s, 24, 1);
* screen_move_lines(s, 13, 12, 11);
* screen_make_lines(s, 12, 1);
*/
screen_free_lines(s, s->ry_lower, 1);
if (s->ry_upper != s->ry_lower) {
screen_move_lines(s,
s->ry_upper + 1, s->ry_upper, s->ry_lower - s->ry_upper);
}
screen_make_lines(s, s->ry_upper, 1);
screen_fill_lines(
s, s->ry_upper, 1, SCREEN_DEFDATA, SCREEN_DEFATTR, SCREEN_DEFCOLR);
} }
/* Scroll screen up. */ /* Scroll screen up. */
void void
screen_scroll_up(struct screen *s, u_int ny) screen_scroll_up(struct screen *s, u_int ny)
{ {
if (s->ry_upper == 0 && s->ry_lower == screen_last_y(s)) { screen_delete_lines(s, 0, ny);
screen_delete_lines(s, 0, ny);
return;
}
fatalx("unimplemented");
} }
/* Scroll screen down. */ /* Scroll screen down. */
void void
screen_scroll_down(struct screen *s, u_int ny) screen_scroll_down(struct screen *s, u_int ny)
{ {
if (s->ry_upper == 0 && s->ry_lower == screen_last_y(s)) { screen_insert_lines(s, 0, ny);
screen_insert_lines(s, 0, ny);
return;
}
fatalx("unimplemented");
} }
/* Fill entire screen. */ /* Fill entire screen. */
@ -755,7 +802,6 @@ screen_insert_lines(struct screen *s, u_int py, u_int ny)
ny = screen_last_y(s) - py; ny = screen_last_y(s) - py;
log_debug("inserting lines: %u,%u", py, ny); log_debug("inserting lines: %u,%u", py, ny);
/* /*
* Insert range of ny lines at py: * Insert range of ny lines at py:
* - Free ny lines from end of screen. * - Free ny lines from end of screen.

6
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.6 2007-08-27 20:36:52 nicm Exp $ */ /* $Id: tmux.h,v 1.7 2007-08-28 09:19:50 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -244,8 +244,8 @@ struct buffer {
#define CODE_ATTRIBUTES 14 #define CODE_ATTRIBUTES 14
#define CODE_CURSOROFF 15 #define CODE_CURSOROFF 15
#define CODE_CURSORON 16 #define CODE_CURSORON 16
#define CODE_CURSORUPSCROLL 17 #define CODE_REVERSEINDEX 17
#define CODE_CURSORDOWNSCROLL 18 /* 18 unused */
#define CODE_SCROLLREGION 19 #define CODE_SCROLLREGION 19
#define CODE_INSERTON 20 #define CODE_INSERTON 20
#define CODE_INSERTOFF 21 #define CODE_INSERTOFF 21