1 From 71d0022376609edba28571ee1ecab3c4ccfcc009 Mon Sep 17 00:00:00 2001
2 From: David Herrmann <dh.herrmann@googlemail.com>
3 Date: Sat, 16 Jun 2012 22:49:35 +0200
4 Subject: [PATCH 02/10] fblog: implement buffer management
6 Each available framebuffer can have a different font and buffer size
7 inside of fblog. Therefore, we need to remember all the log messages that
8 are currently printed on screen. We save them as an array of lines which
9 can be rotated and traversed very fast.
11 This also implements a very trivial way of resizing the buffer but still
12 keeping the content. As there is no need to improve this for speed, we can
15 Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
17 drivers/video/console/fblog.c | 126 +++++++++++++++++++++++++++++++++++++++++
18 1 file changed, 126 insertions(+)
20 diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c
21 index ea83643..1504ba9 100644
22 --- a/drivers/video/console/fblog.c
23 +++ b/drivers/video/console/fblog.c
25 #include <linux/font.h>
26 #include <linux/module.h>
29 + * struct fblog_buf: Console text buffer
31 + * Each framebuffer has its own text buffer which contains all characters that
32 + * are currently printed on screen. The buffers might have different sizes and
33 + * can be resized during runtime. When the buffer content changes, we redraw the
36 + * width: Width of buffer in characters
37 + * height: Height of buffer in characters
38 + * lines: Array of lines
39 + * pos_x: Cursor x-position
40 + * pos_y: Cursor y-position
50 +static void fblog_buf_resize(struct fblog_buf *buf, size_t width,
53 + char **lines = NULL;
54 + size_t i, j, minw, minh;
56 + if (buf->height == height && buf->width == width)
59 + if (width && height) {
60 + lines = kzalloc(height * sizeof(char*), GFP_KERNEL);
64 + for (i = 0; i < height; ++i) {
65 + lines[i] = kzalloc(width * sizeof(char), GFP_KERNEL);
73 + /* copy old lines */
74 + minw = min(width, buf->width);
75 + minh = min(height, buf->height);
76 + if (height >= buf->height)
79 + i = buf->height - height;
81 + for (j = 0; j < minh; ++i, ++j)
82 + memcpy(lines[j], buf->lines[i], minw * sizeof(char));
88 + for (i = 0; i < buf->height; ++i)
89 + kfree(buf->lines[i]);
94 + buf->height = height;
97 +static void fblog_buf_init(struct fblog_buf *buf)
99 + fblog_buf_resize(buf, 80, 24);
102 +static void fblog_buf_deinit(struct fblog_buf *buf)
104 + fblog_buf_resize(buf, 0, 0);
107 +static void fblog_buf_rotate(struct fblog_buf *buf)
114 + line = buf->lines[0];
115 + memset(line, 0, sizeof(char) * buf->width);
117 + memmove(buf->lines, &buf->lines[1], sizeof(char*) * (buf->height - 1));
118 + buf->lines[buf->height - 1] = line;
121 +static void fblog_buf_write(struct fblog_buf *buf, const char *str, size_t len)
133 + if (++buf->pos_y >= buf->height) {
134 + buf->pos_y = buf->height - 1;
135 + fblog_buf_rotate(buf);
137 + } else if (c == 0) {
140 + if (buf->pos_x >= buf->width) {
144 + if (buf->pos_y >= buf->height) {
145 + buf->pos_y = buf->height - 1;
146 + fblog_buf_rotate(buf);
149 + buf->lines[buf->pos_y][buf->pos_x++] = c;
154 static int __init fblog_init(void)