aboutsummaryrefslogtreecommitdiffstats
path: root/lib/tbi/win.c
blob: 9129403b5b60a9ffc59bed21cfed9073d53d547d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#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"

#define CHECK_POSITION(win, x, y) \
	if(x < 0 || y < 0 || x >= w->width || y >= w->height) \
		return FALSE

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;
}