summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2024-08-29 00:32:28 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2024-08-29 00:32:28 +0330
commit7f7ced3f7f61d6cd31a43c5d03d606879295d624 (patch)
treeebd1c1ee0f317bb343d5ee7b10ade8c7a400f2f1
parent353546db994b2f71eeae731209f08da1a326a2f3 (diff)
added fps cap
added clang lsp configs added restrict for pointers may have added max and min width and height consts fixed bug in tui_get_cursor_pos added <ENTER> as left click behavior
-rwxr-xr-x.ccls12
-rwxr-xr-x.clang-format4
-rw-r--r--src/main.c21
-rw-r--r--src/ui/tui.c195
-rw-r--r--src/ui/tui.h68
5 files changed, 217 insertions, 83 deletions
diff --git a/.ccls b/.ccls
new file mode 100755
index 0000000..f3137a2
--- /dev/null
+++ b/.ccls
@@ -0,0 +1,12 @@
+gcc
+# compiler driver
+
+%c -std=c23
+# %cpp -std=c++23
+
+# add this to support `.hpp` files as C++ headers
+# %hpp -x
+# %hpp c++-header
+
+%h -x
+%h c-header
diff --git a/.clang-format b/.clang-format
new file mode 100755
index 0000000..5af5a7a
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,4 @@
+# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
+# To disable for a line use `// clang-format off`
+BasedOnStyle: Google # https://google.github.io/styleguide/cppguide.html
+IndentPPDirectives: BeforeHash
diff --git a/src/main.c b/src/main.c
index 1a4ce8a..c1a2563 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,10 +1,13 @@
-#include "ui/tui.h"
#include <stdio.h>
#include <unistd.h>
+#include "ui/tui.h"
+
bool is_clicked = false;
-void on_button_click(MOUSE_ACTION mouse_action) { is_clicked = !is_clicked; }
+void on_button_click(const MOUSE_ACTION *mouse_action) {
+ is_clicked = !is_clicked;
+}
WIDGET *ui_build(TUI *tui) {
if (is_clicked) {
@@ -17,10 +20,7 @@ WIDGET *ui_build(TUI *tui) {
tui_make_box(
20, 3,
tui_make_column(tui_make_widget_array(
- 2,
- tui_make_text(
- "This is the second page",
- COLOR_BLUE),
+ 2, tui_make_text("This is the second page", COLOR_BLUE),
tui_make_button(tui_make_text(" Back", COLOR_RED),
on_button_click))),
@@ -34,10 +34,9 @@ WIDGET *ui_build(TUI *tui) {
tui_make_row(tui_make_widget_array(
2, tui_make_box(50, 0, NULL, COLOR_NO_COLOR),
tui_make_button(
- tui_make_box(
- 16, 3,
- tui_make_text("\nClick here", COLOR_BLUE),
- COLOR_WHITE),
+ tui_make_box(16, 3,
+ tui_make_text("\nClick here", COLOR_BLUE),
+ COLOR_WHITE),
on_button_click))))),
COLOR_MAGENTA);
}
@@ -46,7 +45,7 @@ WIDGET *ui_build(TUI *tui) {
int main() {
TUI *tui = tui_init();
- tui_start_app(tui, ui_build);
+ tui_start_app(tui, ui_build, 144);
tui_delete(tui);
diff --git a/src/ui/tui.c b/src/ui/tui.c
index 7e044c2..e7336bf 100644
--- a/src/ui/tui.c
+++ b/src/ui/tui.c
@@ -7,12 +7,18 @@
#include <time.h>
#include <unistd.h>
+const int MAX_WIDTH = -1;
+const int MAX_HEIGHT = -1;
+
+const int MIN_WIDTH = -2;
+const int MIN_HEIGHT = -2;
+
void _tui_clear_cells(TUI *tui) {
const TERMINAL_CELL empty = {.c = ' ',
.color = COLOR_NO_COLOR,
.background_color = COLOR_NO_COLOR,
.on_click_callback = NULL};
- for (int i = 0; i < tui->cells_length; ++i) {
+ for (size_t i = 0; i < tui->cells_length; ++i) {
tui->cells[i] = empty;
}
}
@@ -56,9 +62,7 @@ TUI *tui_init() {
return tui;
}
-void tui_delete(TUI *tui) {
- const int width = tui_get_width(tui);
-
+void tui_delete(TUI *restrict tui) {
// Revert the terminal back to its original state
write(STDOUT_FILENO, "\e[?9l", 5);
write(STDOUT_FILENO, "\e[?47l", 6);
@@ -111,8 +115,8 @@ void tui_get_cursor_pos(TUI *tui, int *x, int *y) {
read(STDIN_FILENO, buf, sizeof(buf));
sscanf(buf, "\033[%d;%dR", y, x);
- --x;
- --y;
+ --*x;
+ --*y;
}
tcsetattr(0, TCSANOW, &tui->raw);
}
@@ -154,9 +158,9 @@ void _tui_set_cell_on_click_callback(TUI *tui, int x, int y,
on_click_callback;
}
-void tui_handle_mouse_action(TUI *tui, MOUSE_ACTION mouse_action) {
+void tui_handle_mouse_action(TUI *tui, const MOUSE_ACTION *mouse_action) {
const ON_CLICK_CALLBACK callback =
- tui->cells[_tui_get_cell_index(tui, mouse_action.x, mouse_action.y)]
+ tui->cells[_tui_get_cell_index(tui, mouse_action->x, mouse_action->y)]
.on_click_callback;
if (callback != NULL) {
callback(mouse_action);
@@ -191,12 +195,12 @@ bool handle_input(TUI *tui) {
read(STDIN_FILENO, &buff, 5);
switch (buff[1]) {
case 77: {
- MOUSE_ACTION mouse_action = {
+ const MOUSE_ACTION mouse_action = {
.button = buff[2],
.x = buff[3] - 32 - 1, // starts at 0
.y = buff[4] - 32 - 1, // starts at 0
};
- tui_handle_mouse_action(tui, mouse_action);
+ tui_handle_mouse_action(tui, &mouse_action);
/*printf("button:%u\n\rx:%u\n\ry:%u\n\n\r", mouse_action.button,*/
/* mouse_action.x, mouse_action.y);*/
} break;
@@ -215,22 +219,33 @@ bool handle_input(TUI *tui) {
case 'l':
tui_move_right(1);
break;
- case 'q':
+ case 'q':
return true;
+ case '\r': { // <ENTER>
+ int x, y;
+ tui_get_cursor_pos(tui, &x, &y);
+ const MOUSE_ACTION mouse_action = {
+ .button = MOUSE_BUTTON_LEFT_CLICK,
+ .x = x,
+ .y = y,
+ };
+ tui_handle_mouse_action(tui, &mouse_action);
+ } break;
case '\b':
case 127: // back space
tui_delete_before();
break;
default:
/*printf("unknown:%c,%d\n\r", buff[0], buff[0]);*/
+ /*sleep(1);*/
break;
}
}
return false;
}
-void tui_start_app(TUI *tui, WIDGET_BUILDER widget_builder) {
- tui_main_loop(tui, widget_builder);
+void tui_start_app(TUI *tui, WIDGET_BUILDER widget_builder, int fps) {
+ tui_main_loop(tui, widget_builder, fps);
}
void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin,
@@ -240,12 +255,10 @@ void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin,
case WIDGET_TYPE_TEXT: {
const TEXT_METADATA *metadata = widget->metadata;
const int width_diff = width_end - width_begin;
- const int text_len = strlen(metadata->text);
- int inserted_index = 0;
+ const size_t text_len = strlen(metadata->text);
+ size_t inserted_index = 0;
int height = height_begin;
for (; height < height_end; ++height) {
- const int begin = (height - height_begin) * width_diff;
-
for (int j = 0; j < width_diff; ++j) {
const int x = width_begin + j;
const int y = height;
@@ -286,7 +299,7 @@ void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin,
const COLUMN_METADATA *metadata = widget->metadata;
*child_width = width_begin;
*child_height = height_begin;
- for (int i = 0; i < metadata->children->size; ++i) {
+ for (size_t i = 0; i < metadata->children->size; ++i) {
const WIDGET *child = metadata->children->widgets[i];
int width_temp;
_tui_draw_widget_to_cells(tui, child, width_begin, width_end,
@@ -301,7 +314,7 @@ void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin,
const ROW_METADATA *metadata = widget->metadata;
*child_width = width_begin;
*child_height = height_begin;
- for (int i = 0; i < metadata->children->size; ++i) {
+ for (size_t i = 0; i < metadata->children->size; ++i) {
const WIDGET *child = metadata->children->widgets[i];
int height_temp;
_tui_draw_widget_to_cells(tui, child, *child_width, width_end,
@@ -315,12 +328,12 @@ void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin,
case WIDGET_TYPE_BOX: {
const BOX_METADATA *metadata = widget->metadata;
- if (metadata->width != -1) {
+ if (metadata->width != MAX_WIDTH) {
width_end = metadata->width + width_begin >= width_end
? width_end
: metadata->width + width_begin;
}
- if (metadata->height != -1) {
+ if (metadata->height != MAX_HEIGHT) {
height_end = metadata->height + height_begin >= height_end
? height_end
: metadata->height + height_begin;
@@ -372,7 +385,7 @@ void _tui_draw_cells_to_terminal(TUI *tui) {
COLOR last_color = COLOR_NO_COLOR;
COLOR last_background_color = COLOR_NO_COLOR;
- for (int i = 0; i < tui->cells_length; ++i) {
+ for (size_t i = 0; i < tui->cells_length; ++i) {
const TERMINAL_CELL cell = tui->cells[i];
if (last_color != cell.color ||
@@ -403,11 +416,94 @@ void _tui_draw_cells_to_terminal(TUI *tui) {
write(STDOUT_FILENO, str, len);
}
-void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder) {
+int kbhit() {
+ struct timeval tv = {0L, 0L};
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(0, &fds);
+ return select(1, &fds, NULL, NULL, &tv) > 0;
+}
+
+bool widget_array_eqauls(const WIDGET_ARRAY *restrict left, const WIDGET_ARRAY *restrict right) {
+ if (left->size != right->size) {
+ return false;
+ }
+ for (size_t i = 0; i < left->size; ++i) {
+ if (!widget_eqauls(left->widgets[i], right->widgets[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool widget_eqauls(const WIDGET *restrict left, const WIDGET *restrict right) {
+ if (left == NULL || right == NULL) {
+ return left == NULL && right == NULL;
+ }
+ if (left->type != right->type) {
+ return false;
+ }
+
+ switch (left->type) {
+ case WIDGET_TYPE_TEXT: {
+ const TEXT_METADATA *left_data = left->metadata;
+ const TEXT_METADATA *right_data = right->metadata;
+ return left_data->color == right_data->color &&
+ strcmp(left_data->text, right_data->text) == 0;
+ } break;
+ case WIDGET_TYPE_BUTTON: {
+ const BUTTON_METADATA *left_data = left->metadata;
+ const BUTTON_METADATA *right_data = right->metadata;
+ return left_data->callback == right_data->callback &&
+ widget_eqauls(left_data->child, right_data->child);
+ } break;
+ case WIDGET_TYPE_COLUMN: {
+ const COLUMN_METADATA *left_data = left->metadata;
+ const COLUMN_METADATA *right_data = right->metadata;
+ return widget_array_eqauls(left_data->children, right_data->children);
+ } break;
+ case WIDGET_TYPE_ROW: {
+ const ROW_METADATA *left_data = left->metadata;
+ const ROW_METADATA *right_data = right->metadata;
+ return widget_array_eqauls(left_data->children, right_data->children);
+ } break;
+ case WIDGET_TYPE_BOX: {
+ const BOX_METADATA *left_data = left->metadata;
+ const BOX_METADATA *right_data = right->metadata;
+ return left_data->width == right_data->width &&
+ left_data->height == right_data->height &&
+ left_data->color == right_data->color &&
+ widget_eqauls(left_data->child, right_data->child);
+ } break;
+ default:
+ fprintf(stderr, "Type error '%d' in tui_delete_widget\n", left->type);
+ exit(1);
+ }
+
+ return true;
+}
+
+const int NANO_TO_SECOND = 1000000000;
+
+void nano_sleep(long int nano_seconds) {
+ struct timespec remaining,
+ request = {nano_seconds / NANO_TO_SECOND, nano_seconds % NANO_TO_SECOND};
+ nanosleep(&request, &remaining);
+}
+
+long int nano_time() {
+ struct timespec t = {0, 0}, tend = {0, 0};
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return t.tv_sec * NANO_TO_SECOND + t.tv_nsec;
+}
+
+void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder, int fps) {
+ const long int frame_nano = NANO_TO_SECOND / fps;
while (1) {
+ const long int start = nano_time();
+ tui_save_cursor();
tui_refresh(tui);
WIDGET *root_widget = widget_builder(tui);
- tui_save_cursor();
_tui_clear_cells(tui);
int width, height;
@@ -416,9 +512,17 @@ void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder) {
_tui_draw_cells_to_terminal(tui);
tui_delete_widget(root_widget);
+ /*tui_move_to(0, 0);*/
+ /*printf("%ld\t%ld", last_frame_time, frame_nano);*/
tui_restore_cursor();
- if (handle_input(tui)) {
- return;
+ if (fps != -1) {
+ const long int diff = nano_time() - start;
+ nano_sleep(frame_nano-diff);
+ }
+ if (kbhit()) {
+ if (handle_input(tui)) {
+ return;
+ }
}
}
}
@@ -430,7 +534,7 @@ WIDGET *tui_new_widget(WIDGET_TYPE type, void *metadata) {
return widget;
}
-void tui_delete_widget(WIDGET *widget) {
+void tui_delete_widget(WIDGET *restrict widget) {
if (widget == NULL) {
return;
}
@@ -457,11 +561,11 @@ void tui_delete_widget(WIDGET *widget) {
free(widget);
}
-WIDGET *tui_make_text(char *text, COLOR color) {
+WIDGET *tui_make_text(char *restrict text, COLOR color) {
return tui_new_widget(WIDGET_TYPE_TEXT, _tui_make_text_metadata(text, color));
}
-TEXT_METADATA *_tui_make_text_metadata(char *text, COLOR color) {
+TEXT_METADATA *_tui_make_text_metadata(char *restrict text, COLOR color) {
TEXT_METADATA *metadata = malloc(sizeof(TEXT_METADATA));
metadata->text = malloc(strlen(text) + 1);
strcpy(metadata->text, text);
@@ -469,17 +573,17 @@ TEXT_METADATA *_tui_make_text_metadata(char *text, COLOR color) {
return metadata;
}
-void _tui_delete_text(WIDGET *text) {
+void _tui_delete_text(WIDGET *restrict text) {
free(((TEXT_METADATA *)text->metadata)->text);
free(text->metadata);
}
-WIDGET *tui_make_button(WIDGET *child, ON_CLICK_CALLBACK callback) {
+WIDGET *tui_make_button(WIDGET *restrict child, ON_CLICK_CALLBACK callback) {
return tui_new_widget(WIDGET_TYPE_BUTTON,
_tui_make_button_metadata(child, callback));
}
-BUTTON_METADATA *_tui_make_button_metadata(WIDGET *child,
+BUTTON_METADATA *_tui_make_button_metadata(WIDGET *restrict child,
ON_CLICK_CALLBACK callback) {
BUTTON_METADATA *metadata = malloc(sizeof(BUTTON_METADATA));
metadata->child = child;
@@ -487,51 +591,52 @@ BUTTON_METADATA *_tui_make_button_metadata(WIDGET *child,
return metadata;
}
-void _tui_delete_button(WIDGET *button) {
+void _tui_delete_button(WIDGET *restrict button) {
tui_delete_widget(((BUTTON_METADATA *)button->metadata)->child);
free(button->metadata);
}
-WIDGET *tui_make_column(WIDGET_ARRAY *children) {
+WIDGET *tui_make_column(WIDGET_ARRAY *restrict children) {
return tui_new_widget(WIDGET_TYPE_COLUMN,
_tui_make_column_metadata(children));
}
-COLUMN_METADATA *_tui_make_column_metadata(WIDGET_ARRAY *children) {
+COLUMN_METADATA *_tui_make_column_metadata(WIDGET_ARRAY *restrict children) {
COLUMN_METADATA *metadata = malloc(sizeof(COLUMN_METADATA));
metadata->children = children;
return metadata;
}
-void _tui_delete_column(WIDGET *column) {
+void _tui_delete_column(WIDGET *restrict column) {
COLUMN_METADATA *metadata = column->metadata;
_tui_delete_widget_array(metadata->children);
free(column->metadata);
}
-WIDGET *tui_make_row(WIDGET_ARRAY *children) {
+WIDGET *tui_make_row(WIDGET_ARRAY *restrict children) {
return tui_new_widget(WIDGET_TYPE_ROW, _tui_make_row_metadata(children));
}
-ROW_METADATA *_tui_make_row_metadata(WIDGET_ARRAY *children) {
+ROW_METADATA *_tui_make_row_metadata(WIDGET_ARRAY *restrict children) {
ROW_METADATA *metadata = malloc(sizeof(ROW_METADATA));
metadata->children = children;
return metadata;
}
-void _tui_delete_row(WIDGET *row) {
+void _tui_delete_row(WIDGET *restrict row) {
ROW_METADATA *metadata = row->metadata;
_tui_delete_widget_array(metadata->children);
free(row->metadata);
}
-WIDGET *tui_make_box(int width, int height, WIDGET *child, COLOR color) {
+WIDGET *tui_make_box(int width, int height, WIDGET *restrict child,
+ COLOR color) {
return tui_new_widget(WIDGET_TYPE_BOX,
_tui_make_box_metadata(child, width, height, color));
}
-BOX_METADATA *_tui_make_box_metadata(WIDGET *child, int width, int height,
- COLOR color) {
+BOX_METADATA *_tui_make_box_metadata(WIDGET *restrict child, int width,
+ int height, COLOR color) {
BOX_METADATA *metadata = malloc(sizeof(BOX_METADATA));
metadata->width = width;
metadata->height = height;
@@ -545,13 +650,13 @@ void _tui_delete_box(WIDGET *box) {
free(box->metadata);
}
-WIDGET_ARRAY *tui_make_widget_array(int size, ...) {
+WIDGET_ARRAY *tui_make_widget_array(size_t size, ...) {
va_list arg_pointer;
va_start(arg_pointer, size);
WIDGET **widgets = malloc(size * sizeof(WIDGET **));
- for (int i = 0; i < size; ++i) {
+ for (size_t i = 0; i < size; ++i) {
widgets[i] = va_arg(arg_pointer, WIDGET *);
}
va_end(arg_pointer);
@@ -563,7 +668,7 @@ WIDGET_ARRAY *tui_make_widget_array(int size, ...) {
return widget_array;
}
-void _tui_delete_widget_array(WIDGET_ARRAY *widget_array) {
+void _tui_delete_widget_array(WIDGET_ARRAY *restrict widget_array) {
for (size_t i = 0; i < widget_array->size; ++i) {
tui_delete_widget(widget_array->widgets[i]);
}
diff --git a/src/ui/tui.h b/src/ui/tui.h
index b21395a..0de4adb 100644
--- a/src/ui/tui.h
+++ b/src/ui/tui.h
@@ -1,17 +1,23 @@
#ifndef A404M_UI_TUI
#define A404M_UI_TUI 1
+#include <stdint.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <termios.h>
-#include <stdint.h>
+
+extern const int MAX_WIDTH;
+extern const int MAX_HEIGHT;
+
+extern const int MIN_WIDTH;
+extern const int MIN_HEIGHT;
typedef enum MOUSE_BUTTON {
MOUSE_BUTTON_LEFT_CLICK = 32,
MOUSE_BUTTON_MIDDLE_CLICK = 33,
MOUSE_BUTTON_RIGHT_CLICK = 34,
MOUSE_BUTTON_SCROLL_UP = 96,
- MOUSE_BUTTON_SCROLL_DOWN = 97
+ MOUSE_BUTTON_SCROLL_DOWN = 97,
} MOUSE_BUTTON;
typedef struct MOUSE_ACTION {
@@ -20,7 +26,7 @@ typedef struct MOUSE_ACTION {
unsigned int y;
} MOUSE_ACTION;
-typedef void (*ON_CLICK_CALLBACK)(MOUSE_ACTION mouse_action);
+typedef void (*ON_CLICK_CALLBACK)(const MOUSE_ACTION *mouse_action);
#ifndef __cplusplus
typedef enum bool : uint8_t { false = 0, true = 1 } bool;
@@ -99,7 +105,7 @@ typedef struct BOX_METADATA {
typedef WIDGET *(*WIDGET_BUILDER)(TUI *tui);
extern TUI *tui_init();
-extern void tui_delete(TUI *tui);
+extern void tui_delete(TUI *restrict tui);
extern void tui_refresh(TUI *tui);
extern int tui_get_width(TUI *tui);
@@ -110,38 +116,46 @@ extern int tui_move_to(int x, int y);
extern int tui_clear_screen();
-extern void tui_start_app(TUI *tui, WIDGET_BUILDER widget_builder);
-extern void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget, int width_begin,
- int width_end, int height_begin, int height_end,
- int *child_width, int *childHeight);
-extern void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder);
+extern void tui_start_app(TUI *tui, WIDGET_BUILDER widget_builder, int fps);
+extern void _tui_draw_widget_to_cells(TUI *tui, const WIDGET *widget,
+ int width_begin, int width_end,
+ int height_begin, int height_end,
+ int *child_width, int *childHeight);
+
+extern bool widget_eqauls(const WIDGET *restrict left, const WIDGET *restrict right);
+extern bool widget_array_eqauls(const WIDGET_ARRAY *restrict left, const WIDGET_ARRAY * restrict right);
+
+extern void tui_main_loop(TUI *tui, WIDGET_BUILDER widget_builder, int fps);
extern WIDGET *tui_new_widget(WIDGET_TYPE type, void *metadata);
-extern void tui_delete_widget(WIDGET *widget);
+extern void tui_delete_widget(WIDGET *restrict widget);
-extern WIDGET *tui_make_text(char *text, COLOR color);
-extern TEXT_METADATA *_tui_make_text_metadata(char *text, COLOR color);
-extern void _tui_delete_text(WIDGET *text);
+extern WIDGET *tui_make_text(char *restrict text, COLOR color);
+extern TEXT_METADATA *_tui_make_text_metadata(char *restrict text, COLOR color);
+extern void _tui_delete_text(WIDGET *restrict text);
-extern WIDGET *tui_make_button(WIDGET *child, ON_CLICK_CALLBACK callback);
-extern BUTTON_METADATA *_tui_make_button_metadata(WIDGET *child,
+extern WIDGET *tui_make_button(WIDGET *restrict child,
+ ON_CLICK_CALLBACK callback);
+extern BUTTON_METADATA *_tui_make_button_metadata(WIDGET *restrict child,
ON_CLICK_CALLBACK callback);
-extern void _tui_delete_button(WIDGET *button);
+extern void _tui_delete_button(WIDGET *restrict button);
-extern WIDGET *tui_make_column(WIDGET_ARRAY *children);
-extern COLUMN_METADATA *_tui_make_column_metadata(WIDGET_ARRAY *children);
-extern void _tui_delete_column(WIDGET *column);
+extern WIDGET *tui_make_column(WIDGET_ARRAY *restrict children);
+extern COLUMN_METADATA *
+_tui_make_column_metadata(WIDGET_ARRAY *restrict children);
+extern void _tui_delete_column(WIDGET *restrict column);
-extern WIDGET *tui_make_row(WIDGET_ARRAY *children);
-extern ROW_METADATA *_tui_make_row_metadata(WIDGET_ARRAY *children);
-extern void _tui_delete_row(WIDGET *row);
+extern WIDGET *tui_make_row(WIDGET_ARRAY *restrict children);
+extern ROW_METADATA *_tui_make_row_metadata(WIDGET_ARRAY *restrict children);
+extern void _tui_delete_row(WIDGET *restrict row);
-extern WIDGET *tui_make_box(int width, int height, WIDGET *child, COLOR color);
-extern BOX_METADATA *_tui_make_box_metadata(WIDGET *child, int width,
+extern WIDGET *tui_make_box(int width, int height, WIDGET *restrict child,
+ COLOR color);
+extern BOX_METADATA *_tui_make_box_metadata(WIDGET *restrict child, int width,
int height, COLOR color);
-extern void _tui_delete_box(WIDGET *box);
+extern void _tui_delete_box(WIDGET *restrict box);
-extern WIDGET_ARRAY *tui_make_widget_array(int size, ...);
-extern void _tui_delete_widget_array(WIDGET_ARRAY *widget_array);
+extern WIDGET_ARRAY *tui_make_widget_array(size_t size, ...);
+extern void _tui_delete_widget_array(WIDGET_ARRAY *restrict widget_array);
#endif