aboutsummaryrefslogtreecommitdiffstats
path: root/Library/UefiShellUfmCommandLib
diff options
context:
space:
mode:
Diffstat (limited to 'Library/UefiShellUfmCommandLib')
-rw-r--r--Library/UefiShellUfmCommandLib/menu-bar.c25
-rw-r--r--Library/UefiShellUfmCommandLib/menu-bar.h17
-rw-r--r--Library/UefiShellUfmCommandLib/tbi/screen.c36
-rw-r--r--Library/UefiShellUfmCommandLib/tbi/screen.h36
-rw-r--r--Library/UefiShellUfmCommandLib/tbi/win.c290
-rw-r--r--Library/UefiShellUfmCommandLib/tbi/win.h186
6 files changed, 590 insertions, 0 deletions
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 */