1 #include "dragonfail.h"
2 #include "termbox.h"
3 #include "ctypes.h"
4 
5 #include "inputs.h"
6 #include "config.h"
7 
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/mman.h>
11 
handle_desktop(void * input_struct,struct tb_event * event)12 void handle_desktop(void* input_struct, struct tb_event* event)
13 {
14 	struct desktop* target = (struct desktop*) input_struct;
15 
16 	if ((event != NULL) && (event->type == TB_EVENT_KEY))
17 	{
18 		if (event->key == TB_KEY_ARROW_LEFT)
19 		{
20 			input_desktop_right(target);
21 		}
22 		else if (event->key == TB_KEY_ARROW_RIGHT)
23 		{
24 			input_desktop_left(target);
25 		}
26 	}
27 
28 	tb_set_cursor(target->x + 2, target->y);
29 }
30 
handle_text(void * input_struct,struct tb_event * event)31 void handle_text(void* input_struct, struct tb_event* event)
32 {
33 	struct text* target = (struct text*) input_struct;
34 
35 	if ((event != NULL) && (event->type == TB_EVENT_KEY))
36 	{
37 		if (event->key == TB_KEY_ARROW_LEFT)
38 		{
39 			input_text_left(target);
40 		}
41 		else if (event->key == TB_KEY_ARROW_RIGHT)
42 		{
43 			input_text_right(target);
44 		}
45 		else if (event->key == TB_KEY_DELETE)
46 		{
47 			input_text_delete(target);
48 		}
49 		else if ((event->key == TB_KEY_BACKSPACE)
50 			|| (event->key == TB_KEY_BACKSPACE2))
51 		{
52 			input_text_backspace(target);
53 		}
54 		else if (((event->ch > 31) && (event->ch < 127))
55 			|| (event->key == TB_KEY_SPACE))
56 		{
57 			char buf[7] = {0};
58 
59 			if (event->key == TB_KEY_SPACE)
60 			{
61 				buf[0] = ' ';
62 			}
63 			else
64 			{
65 				utf8_unicode_to_char(buf, event->ch);
66 			}
67 
68 			input_text_write(target, buf[0]);
69 		}
70 	}
71 
72 	tb_set_cursor(
73 		target->x + (target->cur - target->visible_start),
74 		target->y);
75 }
76 
input_desktop(struct desktop * target)77 void input_desktop(struct desktop* target)
78 {
79 	target->list = NULL;
80 	target->cmd = NULL;
81 	target->display_server = NULL;
82 	target->cur = 0;
83 	target->len = 0;
84 
85 	input_desktop_add(target, strdup(lang.shell), strdup(""), DS_SHELL);
86 	input_desktop_add(target, strdup(lang.xinitrc), strdup("~/.xinitrc"), DS_XINITRC);
87 #if 0
88 	input_desktop_add(target, strdup(lang.wayland), strdup(""), DS_WAYLAND);
89 #endif
90 }
91 
input_text(struct text * target,u64 len)92 void input_text(struct text* target, u64 len)
93 {
94 	target->text = malloc(len + 1);
95 
96 	if (target->text == NULL)
97 	{
98 		dgn_throw(DGN_ALLOC);
99 		return;
100 	}
101 	else
102 	{
103 		int ok = mlock(target->text, len + 1);
104 
105 		if (ok < 0)
106 		{
107 			dgn_throw(DGN_MLOCK);
108 			return;
109 		}
110 
111 		memset(target->text, 0, len + 1);
112 	}
113 
114 	target->cur = target->text;
115 	target->end = target->text;
116 	target->visible_start = target->text;
117 	target->len = len;
118 	target->x = 0;
119 	target->y = 0;
120 }
121 
input_desktop_free(struct desktop * target)122 void input_desktop_free(struct desktop* target)
123 {
124 	if (target != NULL)
125 	{
126 		for (u16 i = 0; i < target->len; ++i)
127 		{
128 			if (target->list[i] != NULL)
129 			{
130 				free(target->list[i]);
131 			}
132 
133 			if (target->cmd[i] != NULL)
134 			{
135 				free(target->cmd[i]);
136 			}
137 		}
138 
139 		free(target->list);
140 		free(target->cmd);
141 		free(target->display_server);
142 	}
143 }
144 
input_text_free(struct text * target)145 void input_text_free(struct text* target)
146 {
147 	memset(target->text, 0, target->len);
148 	munlock(target->text, target->len + 1);
149 	free(target->text);
150 }
151 
input_desktop_right(struct desktop * target)152 void input_desktop_right(struct desktop* target)
153 {
154 	++(target->cur);
155 
156 	if (target->cur >= target->len)
157 	{
158 		target->cur = 0;
159 	}
160 }
161 
input_desktop_left(struct desktop * target)162 void input_desktop_left(struct desktop* target)
163 {
164 	--(target->cur);
165 
166 	if (target->cur >= target->len)
167 	{
168 		target->cur = target->len - 1;
169 	}
170 }
171 
input_desktop_add(struct desktop * target,char * name,char * cmd,enum display_server display_server)172 void input_desktop_add(
173 	struct desktop* target,
174 	char* name,
175 	char* cmd,
176 	enum display_server display_server)
177 {
178 	++(target->len);
179 	target->list = realloc(target->list, target->len * (sizeof (char*)));
180 	target->cmd = realloc(target->cmd, target->len * (sizeof (char*)));
181 	target->display_server = realloc(
182 		target->display_server,
183 		target->len * (sizeof (enum display_server)));
184 	target->cur = target->len - 1;
185 
186 	if ((target->list == NULL)
187 		|| (target->cmd == NULL)
188 		|| (target->display_server == NULL))
189 	{
190 		dgn_throw(DGN_ALLOC);
191 		return;
192 	}
193 
194 	target->list[target->cur] = name;
195 	target->cmd[target->cur] = cmd;
196 	target->display_server[target->cur] = display_server;
197 }
198 
input_text_right(struct text * target)199 void input_text_right(struct text* target)
200 {
201 	if (target->cur < target->end)
202 	{
203 		++(target->cur);
204 
205 		if ((target->cur - target->visible_start) > target->visible_len)
206 		{
207 			++(target->visible_start);
208 		}
209 	}
210 }
211 
input_text_left(struct text * target)212 void input_text_left(struct text* target)
213 {
214 	if (target->cur > target->text)
215 	{
216 		--(target->cur);
217 
218 		if ((target->cur - target->visible_start) < 0)
219 		{
220 			--(target->visible_start);
221 		}
222 	}
223 }
224 
input_text_write(struct text * target,char ascii)225 void input_text_write(struct text* target, char ascii)
226 {
227 	if (ascii <= 0)
228 	{
229 		return; // unices do not support usernames and passwords other than ascii
230 	}
231 
232 	if ((target->end - target->text + 1) < target->len)
233 	{
234 		// moves the text to the right to add space for the new ascii char
235 		memcpy(target->cur + 1, target->cur, target->end - target->cur);
236 		++(target->end);
237 		// adds the new char and moves the cursor to the right
238 		*(target->cur) = ascii;
239 		input_text_right(target);
240 	}
241 }
242 
input_text_delete(struct text * target)243 void input_text_delete(struct text* target)
244 {
245 	if (target->cur < target->end)
246 	{
247 		// moves the text on the right to overwrite the currently pointed char
248 		memcpy(target->cur, target->cur + 1, target->end - target->cur + 1);
249 		--(target->end);
250 	}
251 }
252 
input_text_backspace(struct text * target)253 void input_text_backspace(struct text* target)
254 {
255 	if (target->cur > target->text)
256 	{
257 		input_text_left(target);
258 		input_text_delete(target);
259 	}
260 }
261 
input_text_clear(struct text * target)262 void input_text_clear(struct text* target)
263 {
264 	memset(target->text, 0, target->len + 1);
265 	target->cur = target->text;
266 	target->end = target->text;
267 	target->visible_start = target->text;
268 }
269