diff options
author | Marcus Brinkmann <marcus@gnu.org> | 2002-09-09 22:04:25 +0000 |
---|---|---|
committer | Marcus Brinkmann <marcus@gnu.org> | 2002-09-09 22:04:25 +0000 |
commit | 80a243f5e1ce1a023cb45c6ecfa9ccc2b83312d7 (patch) | |
tree | 21f975420d18143021535ac9af55184c15fa5377 /libcons/file-changed.c | |
parent | 18cfa8b70ce9a6a3572908115f98211f3fa9a367 (diff) |
libcons/
2002-09-09 Marcus Brinkmann <marcus@gnu.org>
* Makefile (SRCS): Add vcons-scrollback.c.
* vcons-scrollback.c: New file.
* cons.h (struct vcons): Add SCROLLING member.
* file-changed.c: Include <assert.h>.
(cons_S_file_changed): Be careful to take VCONS->scrolling into
account when doing clipping and scrolling.
* cons-switch.c: Roll back to earlier version with vcons ->
vcons_entry adjustments. The user is now expected to hold a
reference to the VCONS.
* cons.h: Fix prototype, too.
* vcons-open.c (cons_vcons_open): Initialize VCONS->lock,
VCONS->input and VCONS->display.
utils/
2002-09-09 Marcus Brinkmann <marcus@gnu.org>
* console-ncurses.c (console_switch): Keep a reference to the port
instead refering to it by number.
Diffstat (limited to 'libcons/file-changed.c')
-rw-r--r-- | libcons/file-changed.c | 116 |
1 files changed, 85 insertions, 31 deletions
diff --git a/libcons/file-changed.c b/libcons/file-changed.c index 9d7a066b..b4372ed9 100644 --- a/libcons/file-changed.c +++ b/libcons/file-changed.c @@ -18,8 +18,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ -#include <mach.h> #include <errno.h> +#include <assert.h> + +#include <mach.h> #include "cons.h" #include "fs_notify_S.h" @@ -70,10 +72,27 @@ cons_S_file_changed (cons_notify_t notify, natural_t tickno, { if (change.what.cursor_pos) { + uint32_t old_row = vcons->state.cursor.row; + uint32_t height = vcons->state.screen.height; + uint32_t row; + vcons->state.cursor.col = vcons->display->cursor.col; - vcons->state.cursor.row = vcons->display->cursor.row; - cons_vcons_set_cursor_pos (vcons, vcons->state.cursor.col, - vcons->state.cursor.row); + row = vcons->state.cursor.row = vcons->display->cursor.row; + + if (row + vcons->scrolling < height) + { + cons_vcons_set_cursor_pos (vcons, + vcons->state.cursor.col, + row + vcons->scrolling); + if (old_row + vcons->scrolling >= height) + /* The cursor was invisible before. */ + cons_vcons_set_cursor_status (vcons, + vcons->state.cursor.status); + } + else if (old_row + vcons->scrolling < height) + /* The cursor was visible before. */ + cons_vcons_set_cursor_status (vcons, CONS_CURSOR_INVISIBLE); + cons_vcons_update (vcons); } if (change.what.cursor_status) @@ -86,8 +105,9 @@ cons_S_file_changed (cons_notify_t notify, natural_t tickno, if (change.what.screen_cur_line) { uint32_t new_cur_line; - + new_cur_line = vcons->display->screen.cur_line; + if (new_cur_line != vcons->state.screen.cur_line) { off_t size = vcons->state.screen.width @@ -103,30 +123,57 @@ cons_S_file_changed (cons_notify_t notify, natural_t tickno, else scrolling = UINT32_MAX - vcons->state.screen.cur_line + 1 + new_cur_line; - if (scrolling > vcons->state.screen.height) - scrolling = vcons->state.screen.height; - if (scrolling < vcons->state.screen.height) - cons_vcons_scroll (vcons, scrolling); - vis_start = vcons->state.screen.width - * (new_cur_line % vcons->state.screen.lines); - start = (((new_cur_line % vcons->state.screen.lines) - + vcons->state.screen.height - scrolling) - * vcons->state.screen.width) % size; - end = start + scrolling * vcons->state.screen.width - 1; - cons_vcons_write (vcons, - vcons->state.screen.matrix + start, - end < size - ? end - start + 1 - : size - start, - 0, vcons->state.screen.height - - scrolling); - if (end >= size) - cons_vcons_write (vcons, - vcons->state.screen.matrix, - end - size + 1, - 0, (size - vis_start) - / vcons->state.screen.width); - cons_vcons_update (vcons); + + /* If we are scrollbacking, defer scrolling + until absolutely necessary. */ + if (vcons->scrolling) + { + if (vcons->scrolling + scrolling <= vcons->state.screen.scr_lines) + { + vcons->scrolling += scrolling; + scrolling = 0; + } + else + { + scrolling -= vcons->state.screen.scr_lines - vcons->scrolling; + vcons->scrolling = vcons->state.screen.scr_lines; + } + } + + if (scrolling) + { + uint32_t cur_disp_line; + + if (new_cur_line >= vcons->scrolling) + cur_disp_line = new_cur_line - vcons->scrolling; + else + cur_disp_line = (UINT32_MAX - (vcons->scrolling - new_cur_line)) + 1; + + if (scrolling > vcons->state.screen.height) + scrolling = vcons->state.screen.height; + if (scrolling < vcons->state.screen.height) + cons_vcons_scroll (vcons, scrolling); + vis_start = vcons->state.screen.width + * (cur_disp_line % vcons->state.screen.lines); + start = (((cur_disp_line % vcons->state.screen.lines) + + vcons->state.screen.height - scrolling) + * vcons->state.screen.width) % size; + end = start + scrolling * vcons->state.screen.width - 1; + cons_vcons_write (vcons, + vcons->state.screen.matrix + start, + end < size + ? end - start + 1 + : size - start, + 0, vcons->state.screen.height + - scrolling); + if (end >= size) + cons_vcons_write (vcons, + vcons->state.screen.matrix, + end - size + 1, + 0, (size - vis_start) + / vcons->state.screen.width); + cons_vcons_update (vcons); + } vcons->state.screen.cur_line = new_cur_line; } } @@ -134,6 +181,8 @@ cons_S_file_changed (cons_notify_t notify, natural_t tickno, { vcons->state.screen.scr_lines = vcons->display->screen.scr_lines; + if (vcons->state.screen.scr_lines < vcons->scrolling) + assert (!"Implement shrinking scrollback buffer! XXX"); } if (change.what.bell_audible) { @@ -158,8 +207,7 @@ cons_S_file_changed (cons_notify_t notify, natural_t tickno, { /* For clipping. */ off_t size = vcons->state.screen.width*vcons->state.screen.lines; - off_t rotate = vcons->state.screen.width - * (vcons->state.screen.cur_line % vcons->state.screen.lines); + off_t rotate; off_t vis_end = vcons->state.screen.height * vcons->state.screen.width - 1; off_t end2 = -1; @@ -167,6 +215,12 @@ cons_S_file_changed (cons_notify_t notify, natural_t tickno, off_t start = change.matrix.start; off_t end = change.matrix.end; + if (vcons->state.screen.cur_line >= vcons->scrolling) + rotate = vcons->state.screen.cur_line - vcons->scrolling; + else + rotate = (UINT32_MAX - (vcons->scrolling - vcons->state.screen.cur_line)) + 1; + rotate = vcons->state.screen.width * (rotate % vcons->state.screen.lines); + /* Rotate the buffer. */ start -= rotate; if (start < 0) |