From edd62f8e7d00b56bd19217b56d0d2cdf3ef6c945 Mon Sep 17 00:00:00 2001
From: Joursoir <chat@joursoir.net>
Date: Mon, 15 Nov 2021 19:12:06 +0300
Subject: move all sources to the right place

---
 Library/UefiShellUfmCommandLib/menu-bar.c   |  25 +++
 Library/UefiShellUfmCommandLib/menu-bar.h   |  17 ++
 Library/UefiShellUfmCommandLib/tbi/screen.c |  36 ++++
 Library/UefiShellUfmCommandLib/tbi/screen.h |  36 ++++
 Library/UefiShellUfmCommandLib/tbi/win.c    | 290 ++++++++++++++++++++++++++++
 Library/UefiShellUfmCommandLib/tbi/win.h    | 186 ++++++++++++++++++
 6 files changed, 590 insertions(+)
 create mode 100644 Library/UefiShellUfmCommandLib/menu-bar.c
 create mode 100644 Library/UefiShellUfmCommandLib/menu-bar.h
 create mode 100644 Library/UefiShellUfmCommandLib/tbi/screen.c
 create mode 100644 Library/UefiShellUfmCommandLib/tbi/screen.h
 create mode 100644 Library/UefiShellUfmCommandLib/tbi/win.c
 create mode 100644 Library/UefiShellUfmCommandLib/tbi/win.h

(limited to 'Library/UefiShellUfmCommandLib')

diff --git a/Library/UefiShellUfmCommandLib/menu-bar.c b/Library/UefiShellUfmCommandLib/menu-bar.c
new file mode 100644
index 0000000..db7af38
--- /dev/null
+++ b/Library/UefiShellUfmCommandLib/menu-bar.c
@@ -0,0 +1,25 @@
+#include <Library/DebugLib.h>
+
+#include "lib/tbi/screen.h"
+#include "lib/tbi/win.h"
+#include "menu-bar.h"
+
+struct window *menubar = NULL;
+
+BOOLEAN init_menubar(struct screen *scr)
+{
+	menubar = newwin(scr, scr->columns, 1, 0, 0);
+	if(!menubar)
+		return FALSE;
+
+	wrefresh(menubar);
+	return TRUE;
+}
+
+VOID free_menubar(VOID)
+{
+	ASSERT(menubar != NULL);
+
+	delwin(menubar);
+	menubar = NULL;
+}
diff --git a/Library/UefiShellUfmCommandLib/menu-bar.h b/Library/UefiShellUfmCommandLib/menu-bar.h
new file mode 100644
index 0000000..9012f9f
--- /dev/null
+++ b/Library/UefiShellUfmCommandLib/menu-bar.h
@@ -0,0 +1,17 @@
+#ifndef UFM_MENU_BAR_H
+#define UFM_MENU_BAR_H
+
+/*
+ * Menu bar: 
+ * Located on the first line, occupies its entire length.
+ * At the moment, nothing is planned here, a reserve for the future
+*/
+
+#include <Uefi.h>
+
+struct screen;
+
+BOOLEAN init_menubar(struct screen *scr);
+VOID free_menubar(VOID);
+
+#endif /* UFM_MENU_BAR_H */
diff --git a/Library/UefiShellUfmCommandLib/tbi/screen.c b/Library/UefiShellUfmCommandLib/tbi/screen.c
new file mode 100644
index 0000000..ae4f2be
--- /dev/null
+++ b/Library/UefiShellUfmCommandLib/tbi/screen.c
@@ -0,0 +1,36 @@
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include "screen.h"
+
+struct screen *prepare_screen(VOID)
+{
+	struct screen *scr;
+	scr = AllocateZeroPool(sizeof(struct screen));
+	if(!scr)
+		return NULL;
+
+	scr->stdin = gST->ConIn;
+	scr->stdout = gST->ConOut;
+	scr->stderr = gST->StdErr;
+
+	gST->ConOut->QueryMode(
+		gST->ConOut,
+		gST->ConOut->Mode->Mode,
+		&(scr->columns),
+		&(scr->lines)
+	);
+	scr->attr = gST->ConOut->Mode->Attribute;
+
+	return scr;
+}
+
+VOID forget_screen(struct screen *scr)
+{
+	ASSERT(scr != NULL);
+
+	FreePool(scr);
+}
diff --git a/Library/UefiShellUfmCommandLib/tbi/screen.h b/Library/UefiShellUfmCommandLib/tbi/screen.h
new file mode 100644
index 0000000..e97bf64
--- /dev/null
+++ b/Library/UefiShellUfmCommandLib/tbi/screen.h
@@ -0,0 +1,36 @@
+#ifndef UFM_TBI_SCREEN_H
+#define UFM_TBI_SCREEN_H
+
+/*
+	EDK2 NOTE: All devices that support the Simple Text Output Protocol must
+	minimally support an 80x25 character mode. Additional modes are optional
+*/
+
+#include <Uefi.h>
+
+struct screen
+{
+	EFI_SIMPLE_TEXT_INPUT_PROTOCOL *stdin;
+	EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *stdout;
+	EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *stderr;
+	UINTN columns, lines; // current screen size
+	INT32 attr; // main screen attributes
+};
+
+/*
+ * Prepares a structure with information about screen
+ *
+ * return: A pointer to the allocated structure or NULL if allocation fails
+*/
+struct screen *prepare_screen(VOID);
+
+/*
+ * Frees the structure of the screen
+ *
+ * scr: the screen on which to operate
+ *
+ * return: VOID
+*/
+VOID forget_screen(struct screen *scr);
+
+#endif /* UFM_TBI_SCREEN_H */
diff --git a/Library/UefiShellUfmCommandLib/tbi/win.c b/Library/UefiShellUfmCommandLib/tbi/win.c
new file mode 100644
index 0000000..3d82e58
--- /dev/null
+++ b/Library/UefiShellUfmCommandLib/tbi/win.c
@@ -0,0 +1,290 @@
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ShellLib.h>
+#include <Library/PrintLib.h> // UnicodeVSPrint()
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include "screen.h"
+#include "win.h"
+
+#define CHECK_POSITION(win, x, y) \
+	if(x < 0 || y < 0 || x >= win->width || y >= win->height) \
+		return FALSE
+
+#define SET_WINDOW_CHAR(win, col, row, character, attrib) \
+	win->text[row][col] = character; \
+	win->attr[row][col] = attrib
+
+#define SET_WINDOW_CHAR2(win, col, row, character) \
+	SET_WINDOW_CHAR(win, col, row, character, win->cur_attr)
+
+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);
+}
+
+VOID wattrset(struct window *w, INT32 attr)
+{
+	ASSERT(w != NULL);
+
+	w->cur_attr = attr;
+}
+
+VOID wattroff(struct window *w)
+{
+	ASSERT(w != NULL);
+
+	w->cur_attr = w->scr->attr;
+}
+
+BOOLEAN wmove(struct window *w, INT32 x, INT32 y)
+{
+	ASSERT(w != NULL);
+	CHECK_POSITION(w, x, y);
+
+	w->curx = x;
+	w->cury = y;
+	return TRUE;
+}
+
+BOOLEAN wborder(struct window *w, CHAR16 ls, CHAR16 rs, CHAR16 ts,
+	CHAR16 bs, CHAR16 tl, CHAR16 tr, CHAR16 bl, CHAR16 br)
+{
+	INT32 i, endx, endy;
+	ASSERT(w != NULL);
+
+	endx = w->width - 1;
+	endy = w->height - 1;
+
+	for(i = 0; i <= endx; i++) {
+		SET_WINDOW_CHAR2(w, i, 0, ts);
+		SET_WINDOW_CHAR2(w, i, endy, bs);
+	}
+
+	for(i = 0; i <= endy; i++) {
+		SET_WINDOW_CHAR2(w, 0, i, ls);
+		SET_WINDOW_CHAR2(w, endx, i, rs);
+	}
+
+	SET_WINDOW_CHAR2(w, 0, 0, tl);
+	SET_WINDOW_CHAR2(w, endx, 0, tr);
+	SET_WINDOW_CHAR2(w, 0, endy, bl);
+	SET_WINDOW_CHAR2(w, endx, endy, br);
+	return TRUE;
+}
+
+BOOLEAN mvwhline(struct window *w, INT32 x, INT32 y, CHAR16 ch, INT32 n)
+{
+	UINTN i, length;
+	ASSERT(w != NULL);
+	CHECK_POSITION(w, x, y);
+
+	length = w->width - x;
+	if(length > n)
+		length = n;
+
+	length += x;
+	for(i = x; i < length; i++) {
+		w->text[y][i] = ch;
+		w->attr[y][i] = w->cur_attr;
+	}
+	return TRUE;
+}
+
+BOOLEAN mvwvline(struct window *w, INT32 x, INT32 y, CHAR16 ch, INT32 n)
+{
+	UINTN i, length;
+	ASSERT(w != NULL);
+	CHECK_POSITION(w, x, y);
+
+	length = w->height - y;
+	if(length > n)
+		length = n;
+
+	length += y;
+	for(i = y; i < length; i++) {
+		w->text[i][x] = ch;
+		w->attr[i][x] = w->cur_attr;
+	}
+	return TRUE;
+}
+
+UINTN EFIAPI wprintf(struct window *w, CONST CHAR16 *fmt, ...)
+{
+	VA_LIST arg;
+	UINTN retval;
+
+	VA_START(arg, fmt);
+	retval = wvprintf(w, fmt, arg);
+	VA_END(arg);
+	return retval;
+}
+
+UINTN EFIAPI mvwprintf(struct window *w, INT32 x, INT32 y, CONST CHAR16 *fmt, ...)
+{
+	VA_LIST arg;
+	UINTN retval;
+	BOOLEAN moved;
+
+	moved = wmove(w, x, y);
+	if(moved == FALSE)
+		return 0;
+
+	VA_START(arg, fmt);
+	retval = wvprintf(w, fmt, arg);
+	VA_END(arg);
+	return retval;
+}
+
+UINTN EFIAPI wvprintf(struct window *w, CONST CHAR16 *fmt, VA_LIST args)
+{
+	INT32 x, y;
+	UINTN i, length, max_length, walker_size;
+	CHAR16 *fmt_walker;
+
+	ASSERT(w != NULL);
+	ASSERT(fmt != NULL);
+
+	x = w->curx;
+	y = w->cury;
+
+	walker_size = w->width * sizeof(CHAR16);
+	fmt_walker = AllocateZeroPool(walker_size);
+	if(!fmt_walker)
+		return 0;
+
+	UnicodeVSPrint(fmt_walker, walker_size, fmt, args);
+	length = StrLen(fmt_walker);
+	max_length = w->width - x;
+	if(length >= max_length) {
+		length = max_length;
+
+		w->curx = 0;
+		if(++w->cury >= w->height)
+			w->cury = 0;
+	}
+	else
+		w->curx += length;
+
+	CopyMem(w->text[y] + x, fmt_walker, length * 2); // multiply by 2 because CHAR16
+	for(i = 0; i < length; i++)
+		w->attr[y][x + i] = w->cur_attr;
+	FreePool(fmt_walker);
+	return length;
+}
+
+VOID wrefresh(struct window *w)
+{
+	UINTN x, y;
+	INT32 attributes;
+	CHAR16 tmp_ch, *print_ptr;
+	EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *stdout;
+
+	ASSERT(w != NULL);
+
+	attributes = w->attr[0][0];
+	stdout = w->scr->stdout;
+	stdout->SetAttribute(stdout, attributes);
+
+	for(y = 0; y < w->height; y++) {
+		stdout->SetCursorPosition(stdout, w->begx, w->begy + y);
+		print_ptr = w->text[y];
+
+		for(x = 0; x <= (w->width); x++) {
+			if(w->text[y][x] == CHAR_NULL || attributes != w->attr[y][x])
+			{
+				tmp_ch = w->text[y][x];
+				w->text[y][x] = CHAR_NULL;
+				stdout->OutputString(stdout, print_ptr);
+				w->text[y][x] = tmp_ch;
+
+				print_ptr = &(w->text[y][x]);
+				if(w->text[y][x] != CHAR_NULL) {
+					attributes = w->attr[y][x];
+					stdout->SetAttribute(stdout, attributes);
+				}
+			}
+		}
+	}
+
+	stdout->SetAttribute(stdout, w->scr->attr);
+}
diff --git a/Library/UefiShellUfmCommandLib/tbi/win.h b/Library/UefiShellUfmCommandLib/tbi/win.h
new file mode 100644
index 0000000..76be2d8
--- /dev/null
+++ b/Library/UefiShellUfmCommandLib/tbi/win.h
@@ -0,0 +1,186 @@
+#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);
+
+/*
+ * Sets the current attributes of the given window
+ *
+ * w: the window on which to operate
+ * attr: the attributes
+ *
+ * return: VOID
+*/
+VOID wattrset(struct window *w, INT32 attr);
+
+/*
+ * Resets the current attributes of the given window to standard screen
+ * attributes
+ *
+ * w: the window on which to operate
+ *
+ * return: VOID
+*/
+VOID wattroff(struct window *w);
+
+/*
+ * Moves cursor position to specified coordinates
+ *
+ * w: the window on which to operate
+ * x: the X(column) coordinate
+ * y: the Y(row) coordinate
+ *
+ * return: FALSE upon failure and TRUE upon successful completion
+*/
+BOOLEAN wmove(struct window *w, INT32 x, INT32 y);
+
+/*
+ * Draws a box around the edges of a window
+ *
+ * w: the window on which to operate
+ * ls: the left side character
+ * rs: the right side character
+ * ts: the top side character
+ * bs: the bottom side character
+ * tl: the top left corner character
+ * tr: the top right corner character
+ * bl: the bottom left corner character
+ * br: the bottom right corner character
+ *
+ * return: FALSE upon failure and TRUE upon successful completion
+*/
+BOOLEAN wborder(struct window *w, CHAR16 ls, CHAR16 rs, CHAR16 ts,
+	CHAR16 bs, CHAR16 tl, CHAR16 tr, CHAR16 bl, CHAR16 br);
+
+/*
+ * Moves to specified coordinates, draws a horizontal line using ch
+ * starting at (x, y) in the window. The current cursor position is 
+ * not changed.
+ *
+ * w: the window on which to operate
+ * x: the X(column) coordinate for the start of the line
+ * y: the Y(row) coordinate for the start of the line
+ * ch: the character used to draw the line
+ * n: the maximum number of chars in the line
+ *
+ * return: FALSE upon failure and TRUE upon successful completion
+*/
+BOOLEAN mvwhline(struct window *w, INT32 x, INT32 y, CHAR16 ch, INT32 n);
+
+/*
+ * Moves to specified coordinates, draws a vertical line using ch
+ * starting at (x, y) in the window. The current cursor position is 
+ * not changed.
+ *
+ * w: the window on which to operate
+ * x: the X(column) coordinate for the start of the line
+ * y: the Y(row) coordinate for the start of the line
+ * ch: the character used to draw the line
+ * n: the maximum number of chars in the line
+ *
+ * return: FALSE upon failure and TRUE upon successful completion
+*/
+BOOLEAN mvwvline(struct window *w, INT32 x, INT32 y, CHAR16 ch, INT32 n);
+
+/*
+ * Prints formatted output on the cursor coordinates
+ *
+ * w: the window on which to operate
+ * fmt: a null-terminated unicode format string
+ * ...: variable arguments list whose contents are accessed based on the
+        fmt string specified by FormatString
+ *
+ * return: the number of unicode chars in the produced output buffer
+           not including the null-terminator
+*/
+UINTN EFIAPI wprintf(struct window *w, CONST CHAR16 *fmt, ...);
+
+/*
+ * Moves to specified coordinates, prints formatted output
+ *
+ * w: the window on which to operate
+ * x: the X(column) coordinate to move
+ * y: the Y(row) coordinate to move
+ * fmt: a null-terminated unicode format string
+ * ...: variable arguments list whose contents are accessed based on the
+        fmt string specified by FormatString
+ *
+ * return: the number of unicode chars in the produced output buffer
+           not including the null-terminator
+*/
+UINTN EFIAPI mvwprintf(struct window *w, INT32 x, INT32 y, CONST CHAR16 *fmt, ...);
+
+/*
+ * Prints output based on a null-terminated unicode format string
+   and a arguments list
+ *
+ * w: the window on which to operate
+ * fmt: a null-terminated unicode format string
+ * arg: the variable argument list
+ *
+ * return: the number of unicode chars in the produced output buffer
+           not including the null-terminator
+*/
+UINTN EFIAPI wvprintf(struct window *w, CONST CHAR16 *fmt, VA_LIST args);
+
+/*
+ * Does the output of window to the terminal
+ *
+ * w: the window on which to operate
+ *
+ * return: VOID
+*/
+VOID wrefresh(struct window *w);
+
+#endif /* UFM_TBI_WINDOW_H */
-- 
cgit v1.2.3-18-g5258