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