linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Herrmann <dh.herrmann@googlemail.com>
To: linux-serial@vger.kernel.org
Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>,
	linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	David Herrmann <dh.herrmann@googlemail.com>
Subject: [PATCH 02/10] fblog: implement buffer management
Date: Sat, 16 Jun 2012 22:04:18 +0000	[thread overview]
Message-ID: <1339884266-9201-3-git-send-email-dh.herrmann@googlemail.com> (raw)
In-Reply-To: <1339884266-9201-1-git-send-email-dh.herrmann@googlemail.com>

Each available framebuffer can have a different font and buffer size
inside of fblog. Therefore, we need to remember all the log messages that
are currently printed on screen. We save them as an array of lines which
can be rotated and traversed very fast.

This also implements a very trivial way of resizing the buffer but still
keeping the content. As there is no need to improve this for speed, we can
keep it this way.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
 drivers/video/console/fblog.c |  126 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)

diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c
index ea83643..1504ba9 100644
--- a/drivers/video/console/fblog.c
+++ b/drivers/video/console/fblog.c
@@ -39,6 +39,132 @@
 #include <linux/font.h>
 #include <linux/module.h>
 
+/**
+ * struct fblog_buf: Console text buffer
+ *
+ * Each framebuffer has its own text buffer which contains all characters that
+ * are currently printed on screen. The buffers might have different sizes and
+ * can be resized during runtime. When the buffer content changes, we redraw the
+ * screen.
+ *
+ * width: Width of buffer in characters
+ * height: Height of buffer in characters
+ * lines: Array of lines
+ * pos_x: Cursor x-position
+ * pos_y: Cursor y-position
+ */
+struct fblog_buf {
+	size_t width;
+	size_t height;
+	char **lines;
+	size_t pos_x;
+	size_t pos_y;
+};
+
+static void fblog_buf_resize(struct fblog_buf *buf, size_t width,
+			     size_t height)
+{
+	char **lines = NULL;
+	size_t i, j, minw, minh;
+
+	if (buf->height = height && buf->width = width)
+		return;
+
+	if (width && height) {
+		lines = kzalloc(height * sizeof(char*), GFP_KERNEL);
+		if (!lines)
+			return;
+
+		for (i = 0; i < height; ++i) {
+			lines[i] = kzalloc(width * sizeof(char), GFP_KERNEL);
+			if (!lines[i]) {
+				while (i--)
+					kfree(lines[i]);
+				return;
+			}
+		}
+
+		/* copy old lines */
+		minw = min(width, buf->width);
+		minh = min(height, buf->height);
+		if (height >= buf->height)
+			i = 0;
+		else
+			i = buf->height - height;
+
+		for (j = 0; j < minh; ++i, ++j)
+			memcpy(lines[j], buf->lines[i], minw * sizeof(char));
+	} else {
+		width = 0;
+		height = 0;
+	}
+
+	for (i = 0; i < buf->height; ++i)
+		kfree(buf->lines[i]);
+	kfree(buf->lines);
+
+	buf->lines = lines;
+	buf->width = width;
+	buf->height = height;
+}
+
+static void fblog_buf_init(struct fblog_buf *buf)
+{
+	fblog_buf_resize(buf, 80, 24);
+}
+
+static void fblog_buf_deinit(struct fblog_buf *buf)
+{
+	fblog_buf_resize(buf, 0, 0);
+}
+
+static void fblog_buf_rotate(struct fblog_buf *buf)
+{
+	char *line;
+
+	if (!buf->height)
+		return;
+
+	line = buf->lines[0];
+	memset(line, 0, sizeof(char) * buf->width);
+
+	memmove(buf->lines, &buf->lines[1], sizeof(char*) * (buf->height - 1));
+	buf->lines[buf->height - 1] = line;
+}
+
+static void fblog_buf_write(struct fblog_buf *buf, const char *str, size_t len)
+{
+	char c;
+
+	if (!buf->height)
+		return;
+
+	while (len--) {
+		c = *str++;
+
+		if (c = '\n') {
+			buf->pos_x = 0;
+			if (++buf->pos_y >= buf->height) {
+				buf->pos_y = buf->height - 1;
+				fblog_buf_rotate(buf);
+			}
+		} else if (c = 0) {
+			/* ignore */
+		} else {
+			if (buf->pos_x >= buf->width) {
+				buf->pos_x = 0;
+				++buf->pos_y;
+			}
+			if (buf->pos_y >= buf->height) {
+				buf->pos_y = buf->height - 1;
+				fblog_buf_rotate(buf);
+			}
+
+			buf->lines[buf->pos_y][buf->pos_x++] = c;
+		}
+	}
+}
+
 static int __init fblog_init(void)
 {
 	return 0;
-- 
1.7.10.4


  parent reply	other threads:[~2012-06-16 22:04 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-16 22:04 [RFC 00/10] fblog: framebuffer kernel log driver David Herrmann
2012-06-16 22:04 ` [PATCH 01/10] fblog: new framebuffer kernel log dummy driver David Herrmann
2012-06-16 22:04 ` David Herrmann [this message]
2012-06-16 22:04 ` [PATCH 03/10] fblog: register framebuffer objects David Herrmann
2012-06-16 22:04 ` [PATCH 04/10] fblog: implement fblog_redraw() David Herrmann
2012-06-16 22:35   ` Alan Cox
2012-06-18 18:36     ` David Herrmann
2012-06-16 22:04 ` [PATCH 05/10] fblog: add framebuffer helpers David Herrmann
2012-06-16 22:33   ` Bruno Prémont
2012-06-18 18:50     ` David Herrmann
2012-06-16 22:04 ` [PATCH 06/10] fblog: allow enabling/disabling fblog on runtime David Herrmann
2012-06-16 22:04 ` [PATCH 07/10] fblog: forward kernel log messages to all framebuffers David Herrmann
2012-06-16 22:04 ` [PATCH 08/10] fblog: react on framebuffer events David Herrmann
2012-06-16 22:04 ` [PATCH 09/10] fblog: register all handlers on module-init David Herrmann
2012-06-16 22:04 ` [PATCH 10/10] fblog: add "activate" module parameter David Herrmann
2012-06-18 19:06 ` [RFC 00/10] fblog: framebuffer kernel log driver David Herrmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1339884266-9201-3-git-send-email-dh.herrmann@googlemail.com \
    --to=dh.herrmann@googlemail.com \
    --cc=FlorianSchandinat@gmx.de \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).