aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoursoir <chat@joursoir.net>2021-12-11 15:04:13 +0300
committerJoursoir <chat@joursoir.net>2021-12-11 15:04:13 +0300
commit5e0ac5e316a3d33610b4681f0d4f246281a90bce (patch)
tree78e9e755b1a734384d906bdbf151fc6a0ab2d384
parenta8fc36b116384d5290a0d6d5dde106b346dd97ed (diff)
downloadufm-5e0ac5e316a3d33610b4681f0d4f246281a90bce.tar.gz
ufm-5e0ac5e316a3d33610b4681f0d4f246281a90bce.tar.bz2
ufm-5e0ac5e316a3d33610b4681f0d4f246281a90bce.zip
implement the input widget
-rw-r--r--Library/UefiShellUfmCommandLib/UefiShellUfmCommandLib.inf1
-rw-r--r--Library/UefiShellUfmCommandLib/widget/input.c114
-rw-r--r--Library/UefiShellUfmCommandLib/widget/input.h74
3 files changed, 189 insertions, 0 deletions
diff --git a/Library/UefiShellUfmCommandLib/UefiShellUfmCommandLib.inf b/Library/UefiShellUfmCommandLib/UefiShellUfmCommandLib.inf
index a80d2cf..c3d623e 100644
--- a/Library/UefiShellUfmCommandLib/UefiShellUfmCommandLib.inf
+++ b/Library/UefiShellUfmCommandLib/UefiShellUfmCommandLib.inf
@@ -14,6 +14,7 @@
tbi/win.c
menu-bar.c
command-bar.c
+ widget/input.c
panel.c
dir.c
fs.c
diff --git a/Library/UefiShellUfmCommandLib/widget/input.c b/Library/UefiShellUfmCommandLib/widget/input.c
new file mode 100644
index 0000000..7531321
--- /dev/null
+++ b/Library/UefiShellUfmCommandLib/widget/input.c
@@ -0,0 +1,114 @@
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include "input.h"
+
+struct widget_input *input_alloc(struct screen *scr, INT32 x, INT32 y,
+ INT32 width, INT32 attr, CONST CHAR16 *def_text)
+{
+ struct widget_input *in;
+
+ ASSERT(scr != NULL);
+
+ in = AllocateZeroPool(sizeof(struct widget_input));
+ if(!in)
+ return NULL;
+
+ in->win = newwin(scr, width, 1, x, y);
+ if(!in->win) {
+ input_release(in);
+ return NULL;
+ }
+ wattrset(in->win, attr);
+ whline(in->win, 0, 0, 0, attr, 0);
+ mvwprintf(in->win, 0, 0, def_text);
+
+ in->point = 0;
+ in->max_size = width;
+ in->buf_len = 0;
+ in->buffer = AllocateZeroPool((in->max_size + 1) * sizeof(CHAR16));
+ if(!in->buffer) {
+ input_release(in);
+ return NULL;
+ }
+
+ return in;
+}
+
+VOID input_release(struct widget_input *in)
+{
+ ASSERT(in != NULL);
+
+ if(in->win)
+ delwin(in->win);
+ if(in->buffer)
+ FreePool(in->buffer);
+
+ FreePool(in);
+}
+
+VOID input_set_point(struct widget_input *in, INTN pos)
+{
+ in->point = pos;
+ if(pos < 0)
+ in->point = 0;
+ else if(pos > in->buf_len)
+ in->point = in->buf_len;
+
+ wmove(in->win, in->point, 0);
+ input_update(in);
+}
+
+VOID input_handle_char(struct widget_input *in, EFI_INPUT_KEY key)
+{
+ UINTN i;
+
+ if(key.ScanCode == SCAN_LEFT)
+ input_set_point(in, in->point - 1);
+ else if(key.ScanCode == SCAN_RIGHT)
+ input_set_point(in, in->point + 1);
+ else {
+ switch(key.UnicodeChar) {
+
+ case 0x0:
+ break;
+ case CHAR_BACKSPACE: {
+ if(in->buf_len == 0)
+ break;
+
+ for(i = in->point; i < in->buf_len; i++)
+ in->buffer[i - 1] = in->buffer[i];
+ in->buffer[i - 1] = CHAR_NULL;
+ mvwaddch(in->win, i - 1, 0, L' ', -1);
+ mvwprintf(in->win, in->point - 1, 0, in->buffer + in->point - 1);
+
+ in->buf_len--;
+ input_set_point(in, in->point - 1);
+ }
+ case CHAR_TAB:
+ case CHAR_LINEFEED:
+ case CHAR_CARRIAGE_RETURN:
+ break;
+ default: {
+ if(in->buf_len >= (in->max_size-1))
+ break;
+
+ for(i = in->max_size-1; i > in->point; i--)
+ in->buffer[i] = in->buffer[i - 1];
+ in->buffer[in->point] = key.UnicodeChar;
+ wprintf(in->win, in->buffer + in->point);
+
+ in->buf_len++;
+ input_set_point(in, in->point + 1);
+ }
+
+ }
+ }
+}
+
+VOID input_update(struct widget_input *in)
+{
+ wrefresh(in->win);
+}
+
diff --git a/Library/UefiShellUfmCommandLib/widget/input.h b/Library/UefiShellUfmCommandLib/widget/input.h
new file mode 100644
index 0000000..cc917df
--- /dev/null
+++ b/Library/UefiShellUfmCommandLib/widget/input.h
@@ -0,0 +1,74 @@
+#ifndef UFM_WIDGET_INPUT_H
+#define UFM_WIDGET_INPUT_H
+
+#include <Uefi.h>
+#include "tbi/screen.h"
+#include "tbi/win.h"
+
+struct widget_input {
+ struct window *win;
+ INTN point; // cursor position in the input line in chars
+ UINTN max_size; // maximum length of input line
+ UINTN buf_len; // current length of input line
+ CHAR16 *buffer;
+};
+
+/*
+ * Creates a input widget (single line of text and lets the user edit it) with
+ * given parameters.
+ *
+ * scr: the information of the screen
+ * x: the column coordinate (starts from 0) of upper left corner of the window
+ * y: the line coordinate (starts from 0) of upper left corner of the window
+ * width: the length and the maximum number of characters in the line
+ * attr: attributes of the line
+ * def_text: the pointer to initial string in the input line
+ *
+ * return: A pointer to the allocated structure or NULL if allocation fails
+*/
+struct widget_input *input_alloc(struct screen *scr, INT32 x, INT32 y,
+ INT32 width, INT32 attr, CONST CHAR16 *def_text);
+
+/*
+ * Deletes the input widget, frees the structure
+ *
+ * in: the input widget on which to operate
+ *
+ * return: VOID
+*/
+VOID input_release(struct widget_input *in);
+
+/*
+ * Moves the cursor to the specified position from 0 to current length of
+ * the input line. If the position is not in this limit, then extreme
+ * points will be used
+ *
+ * in: the input widget on which to operate
+ * pos: the coordinate (starts from 0)
+ *
+ * return: VOID
+*/
+VOID input_set_point(struct widget_input *in, INTN pos);
+
+/*
+ * Handles the given key and print it (if it's character).
+ * Supports next control characters: Backspace, left arrow, right arrow.
+ * Ignores others.
+ *
+ * in: the input widget on which to operate
+ * key: the key to handle
+ *
+ * return: VOID
+*/
+VOID input_handle_char(struct widget_input *in, EFI_INPUT_KEY key);
+
+/*
+ * Does the output of input widget to the terminal
+ *
+ * in: the input widget on which to operate
+ *
+ * return: VOID
+*/
+VOID input_update(struct widget_input *in);
+
+#endif /* UFM_WIDGET_INPUT_H */