From 25e0c2e7b952e0115354ec3e2f7a88693230e180 Mon Sep 17 00:00:00 2001
From: sbosse <sbosse@uni-bremen.de>
Date: Mon, 14 Oct 2024 23:07:15 +0200
Subject: [PATCH] Mon 14 Oct 23:06:38 CEST 2024

---
 kernel/console.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 217 insertions(+)
 create mode 100644 kernel/console.c

diff --git a/kernel/console.c b/kernel/console.c
new file mode 100644
index 0000000..91ff7ba
--- /dev/null
+++ b/kernel/console.c
@@ -0,0 +1,217 @@
+/*
+Copyright (C) 2015-2019 The University of Notre Dame
+This software is distributed under the GNU General Public License.
+See the file LICENSE for details.
+*/
+
+#include "console.h"
+#include "serial.h"
+#include "graphics.h"
+#include "kmalloc.h"
+#include "string.h"
+
+struct console {
+	struct window *window;
+	struct graphics *gx;
+	int xsize;
+	int ysize;
+	int xpos;
+	int ypos;
+	int onoff;
+	int refcount;
+};
+
+struct console console_root = {0};
+
+static struct graphics_color bgcolor = { 0, 0, 0 };
+static struct graphics_color fgcolor = { 255, 255, 255 };
+
+struct console * console_create_root()
+{
+	console_root.window = window_create_root();
+	console_root.gx = window_graphics(console_root.window);
+	console_reset(&console_root);
+	console_putstring(&console_root,"\nconsole: initialized\n");
+	return &console_root;
+}
+
+void console_reset( struct console *d )
+{
+	if(!d || !d->gx) return;
+	d->xpos = d->ypos = 0;
+	d->xsize = graphics_width(d->gx) / 8;
+	d->ysize = graphics_height(d->gx) / 8;
+	d->onoff = 0;
+	graphics_fgcolor(d->gx, fgcolor);
+	graphics_bgcolor(d->gx, bgcolor);
+	graphics_clear(d->gx, 0, 0, graphics_width(d->gx), graphics_height(d->gx));
+}
+
+void console_heartbeat( struct console *d )
+{
+	char c = d->onoff ? ' ' : '_';
+	graphics_char(d->gx, d->xpos * 8, d->ypos * 8, c );
+	d->onoff = !d->onoff;
+}
+
+int console_post( struct console *c, const char *data, int size )
+{
+	int total = 0;
+
+	struct event e;
+	e.type = EVENT_KEY_DOWN;
+	e.x = 0;
+	e.y = 0;
+
+	while(size>0) {
+		e.code = *data;
+		window_post_events(c->window,&e,sizeof(e));
+		size--;
+		data++;
+		total++;
+	}
+
+	return total;
+}
+
+int console_write( struct console *d, const char *data, int size )
+{
+	graphics_char(d->gx, d->xpos * 8, d->ypos * 8, ' ');
+
+	int i;
+	for(i = 0; i < size; i++) {
+		char c = data[i];
+		switch (c) {
+		case 13:
+		case 10:
+			d->xpos = 0;
+			d->ypos++;
+			break;
+		case '\f':
+			d->xpos = d->ypos = 0;
+			d->xsize = graphics_width(d->gx) / 8;
+			d->ysize = graphics_height(d->gx) / 8;
+			graphics_fgcolor(d->gx, fgcolor);
+			graphics_bgcolor(d->gx, bgcolor);
+			graphics_clear(d->gx, 0, 0, graphics_width(d->gx), graphics_height(d->gx));
+			break;
+		case '\b':
+			d->xpos--;
+			break;
+		default:
+			graphics_char(d->gx, d->xpos * 8, d->ypos * 8, c);
+			d->xpos++;
+			break;
+		}
+
+		if(d->xpos < 0) {
+			d->xpos = d->xsize - 1;
+			d->ypos--;
+		}
+
+		if(d->xpos >= d->xsize) {
+			d->xpos = 0;
+			d->ypos++;
+		}
+
+		if(d->ypos >= d->ysize) {
+			d->xpos = d->ypos = 0;
+			d->xsize = graphics_width(d->gx) / 8;
+			d->ysize = graphics_height(d->gx) / 8;
+			graphics_fgcolor(d->gx, fgcolor);
+			graphics_bgcolor(d->gx, bgcolor);
+			graphics_clear(d->gx, 0, 0, graphics_width(d->gx), graphics_height(d->gx));
+		}
+
+	}
+	graphics_char(d->gx, d->xpos * 8, d->ypos * 8, '_');
+	return i;
+}
+
+int console_read( struct console *c, char *data, int length )
+{
+	int total=0;
+
+	struct event e;
+	while(length>0 && window_read_events(c->window,&e,sizeof(e))) {
+		if(e.type==EVENT_KEY_DOWN) {
+			*data = e.code;
+			length--;
+			total++;
+			data++;
+		}
+	}
+
+	return total;
+}
+
+int console_read_nonblock( struct console *c, char *data, int length )
+{
+	int total=0;
+
+	struct event e;
+	while(length>0 && window_read_events_nonblock(c->window,&e,sizeof(e))) {
+		if(e.type==EVENT_KEY_DOWN) {
+			*data = e.code;
+			length--;
+			total++;
+			data++;
+		}
+	}
+
+	return total;
+}
+
+int console_getchar( struct console *c )
+{
+	char ch;
+	if(console_read(c,&ch,1)>0) {
+		return ch;
+	} else {
+		return 0;
+	}
+}
+
+void console_putchar( struct console *c, char ch )
+{
+	console_write(c,&ch,1);
+}
+
+void console_putstring( struct console *c, const char *str)
+{
+	console_write(c,str,strlen(str));
+}
+
+struct console *console_create( struct window *w )
+{
+	struct console *c = kmalloc(sizeof(*c));
+	c->window = window_addref(w);
+	c->gx = window_graphics(w);
+	c->refcount = 1;
+	console_reset(c);
+	return c;
+}
+
+struct console *console_addref( struct console *c )
+{
+	c->refcount++;
+	return c;
+}
+
+void console_delete( struct console *c )
+{
+	if(c==&console_root) return;
+
+	c->refcount--;
+	if(c->refcount==0) {
+		window_delete(c->window);
+		kfree(c);
+	}
+}
+
+void console_size( struct console *c, int *xsize, int *ysize )
+{
+	*xsize = c->xsize;
+	*ysize = c->ysize;
+}
+