From 10dfb530d4d783c4e8265927038230c63a7751d6 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 18 Dec 2011 13:49:03 +0100 Subject: [PATCH] console: correctly set current position in buffer Our scrollback buffer needs to adjust the current position when being resized or when a new line is pushed. Signed-off-by: David Herrmann --- src/console_cell.c | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/console_cell.c b/src/console_cell.c index 2be4947..7c0bf9e 100644 --- a/src/console_cell.c +++ b/src/console_cell.c @@ -43,6 +43,7 @@ */ #include +#include #include #include @@ -79,6 +80,7 @@ struct kmscon_buffer { unsigned int size_x; unsigned int size_y; struct line *current; + bool stick; }; static void destroy_cell(struct cell *cell) @@ -184,7 +186,8 @@ static int push_line(struct kmscon_buffer *buf, unsigned int width) line = buf->first; buf->first = line->next; - buf->first->prev = NULL; + if (buf->first) + buf->first->prev = NULL; if (buf->current == line) buf->current = buf->first; @@ -212,6 +215,11 @@ static int push_line(struct kmscon_buffer *buf, unsigned int width) } ++buf->count; + if (!buf->current) + buf->current = buf->first; + else if (!buf->stick && buf->count > buf->size_y) + buf->current = buf->current->next; + return 0; err_free: @@ -279,13 +287,6 @@ void kmscon_buffer_unref(struct kmscon_buffer *buf) * This adjusts the x/y size of the viewable part of the buffer. It does never * modify the scroll-back buffer as this would take too long. * - * y-resize: - * We simply move the \current position up in the scroll-back buffer so resizing - * looks like scrolling up in the buffer. If there are no more scroll-back - * lines, we push empty lines to the bottom so no scrolling appears. - * If pushing a line fails we simply leave the buffer in the current position so - * only partial resizing appeared but the buffer is still fully operational. - * * x-resize: * We only resize the visible lines to have at least width \x. If resizing fails * we leave the buffer in the current state. This may make some lines shorter @@ -306,7 +307,8 @@ int kmscon_buffer_resize(struct kmscon_buffer *buf, uint32_t x, uint32_t y) if (!y) y = DEFAULT_HEIGHT; - while (buf->count < y) { + /* push at least one line into the buffer so we have \current */ + if (!buf->count) { ret = push_line(buf, x); if (ret) return ret; @@ -324,6 +326,18 @@ int kmscon_buffer_resize(struct kmscon_buffer *buf, uint32_t x, uint32_t y) buf->size_x = x; buf->size_y = y; + + /* correctly move \current to new top position */ + if (!buf->stick) { + buf->current = buf->last; + for (i = 1; i < buf->size_y; ++i) { + if (!buf->current->prev) + break; + + buf->current = buf->current->prev; + } + } + return 0; } @@ -347,9 +361,12 @@ void kmscon_buffer_draw(struct kmscon_buffer *buf, struct kmscon_font *font, xs = width / (double)buf->size_x; ys = height / (double)buf->size_y; - iter = buf->last; - cy = (buf->size_y - 1) * ys; + iter = buf->current; + cy = 0; for (i = 0; i < buf->size_y; ++i) { + if (!iter) + break; + cx = 0; for (j = 0; j < iter->num; ++j) { cell = &iter->cells[j]; @@ -358,7 +375,8 @@ void kmscon_buffer_draw(struct kmscon_buffer *buf, struct kmscon_font *font, kmscon_font_draw(font, ch, cr, cx, cy); cx += xs; } - cy -= ys; - iter = iter->prev; + + cy += ys; + iter = iter->next; } }