From 249b0f92ba53a2fe0d1d17c90c99d934769ca4e5 Mon Sep 17 00:00:00 2001
From: Joursoir <chat@joursoir.net>
Date: Sun, 24 Oct 2021 20:43:39 +0000
Subject: implement a window entity

---
 lib/tbi/win.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/tbi/win.h | 57 +++++++++++++++++++++++++++++++++++++
 2 files changed, 147 insertions(+)
 create mode 100644 lib/tbi/win.c
 create mode 100644 lib/tbi/win.h

diff --git a/lib/tbi/win.c b/lib/tbi/win.c
new file mode 100644
index 0000000..69ba895
--- /dev/null
+++ b/lib/tbi/win.c
@@ -0,0 +1,90 @@
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ShellLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include "screen.h"
+#include "win.h"
+
+struct window *newwin(struct screen *s, 
+	INT32 ncols, INT32 nlines, INT32 begin_x, INT32 begin_y)
+{
+	INTN x, y;
+	struct window *win;
+
+	ASSERT(s != NULL);
+
+	if(ncols <= 0 || nlines <= 0 || begin_x < 0 || begin_y < 0)
+		return NULL;
+
+	if((begin_x + ncols) > s->columns || (begin_y + nlines) > s->lines)
+		return NULL;
+
+	win = AllocateZeroPool(sizeof(struct window));
+	if(!win)
+		return NULL;
+
+	win->text = AllocatePool(nlines * sizeof(CHAR16 *));
+	if(!win->text) {
+		delwin(win);
+		return NULL;
+	}
+
+	win->attr = AllocatePool(nlines * sizeof(INT32 *));
+	if(!win->attr) {
+		delwin(win);
+		return NULL;
+	}
+
+	win->scr = s;
+	win->curx = 0;
+	win->cury = 0;
+	win->begx = begin_x;
+	win->begy = begin_y;
+	win->width = ncols;
+	win->height = nlines;
+	win->cur_attr = s->attr;
+
+	for(y = 0; y < nlines; y++) {
+		win->text[y] = AllocatePool((ncols + 1) * sizeof(CHAR16));
+		win->attr[y] = AllocatePool((ncols + 1) * sizeof(INT32));
+		if(!win->text[y] || !win->attr[y]) {
+			delwin(win);
+			return NULL;
+		}
+
+		for(x = 0; x < ncols; x++) {
+			win->text[y][x] = L' ';
+			win->attr[y][x] = win->cur_attr;
+		}
+		win->text[y][x] = CHAR_NULL;
+		win->attr[y][x] = win->cur_attr;
+	}
+
+	return win;
+}
+
+VOID delwin(struct window *w)
+{
+	INTN i;
+	ASSERT(w != NULL);
+
+	if(w->text) {
+		for(i = 0; i < w->height; i++) {
+			if(w->text[i])
+				FreePool(w->text[i]);
+		}
+		FreePool(w->text);
+	}
+
+	if(w->attr) {
+		for(i = 0; i < w->height; i++) {
+			if(w->attr[i])
+				FreePool(w->attr[i]);
+		}
+		FreePool(w->attr);
+	}
+
+	FreePool(w);
+}
diff --git a/lib/tbi/win.h b/lib/tbi/win.h
new file mode 100644
index 0000000..2de5310
--- /dev/null
+++ b/lib/tbi/win.h
@@ -0,0 +1,57 @@
+#ifndef UFM_TBI_WINDOW_H
+#define UFM_TBI_WINDOW_H
+
+/*
+	Window - rectangular area of the screen with which you can work as a separate
+	screen (display text, clear, etc). The output should be carried out only in
+	the specified rectangular area of the screen
+
+	NOTE: SimpleTextOut.h has defined box-drawing character ("BOXDRAW_*", for
+	example BOXDRAW_VERTICAL)
+*/
+
+#include <Uefi.h>
+
+struct screen;
+
+struct window {
+	struct screen *scr; // parent screen
+
+	INT32 curx, cury; // current cursor position
+	INT32 begx, begy; // screen coords of upper left corner
+	INT32 width, height; // window size
+
+	CHAR16 **text; // the actual text of whole screen
+	/* ATTRIBUTES:
+	Bits 0..3 are the foreground color.
+	Bits 4..6 are the background color.
+	ALl other bits are undefined and must be zero */
+	INT32 **attr;
+
+	INT32 cur_attr;
+};
+
+/*
+ * Creates a window with given parameters
+ *
+ * s: the information of the screen
+ * ncols: the number of columns
+ * nlines: the number of lines
+ * begin_x: the column coordinate (starts from 0) of upper left corner of the window
+ * begin_y: the line coordinate (starts from 0) of upper left corner of the window
+ *
+ * return: A pointer to the allocated structure or NULL if allocation fails
+*/
+struct window *newwin(struct screen *s,
+	INT32 ncols, INT32 nlines, INT32 begin_x, INT32 begin_y);
+
+/*
+ * Deletes the window, frees the structure
+ *
+ * w: the window on which to operate
+ *
+ * return: VOID
+*/
+VOID delwin(struct window *w);
+
+#endif /* UFM_TBI_WINDOW_H */
-- 
cgit v1.2.3-18-g5258