Added '\t' character support into VESA mode shell; Fixed some bugs in isofs - filename
[ZeXOS.git] / kernel / core / tty.c
blobe84c6e78ffba9db8451ad0fd42ccd778e39fcdf2
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <build.h>
22 #include <system.h>
23 #include <string.h>
24 #include <vfs.h>
27 #ifdef ARCH_i386
28 extern int attrib;
29 extern int gets (void);
30 extern int csr_x, csr_y;
31 extern void scroll (void);
32 extern void move_csr (void);
33 extern unsigned char vgagui;
34 #else
35 unsigned int attrib;
36 unsigned char vgagui;
37 #endif
39 unsigned orig_screen_len = 0;
41 tty_t tty_list;
42 tty_t *tty0, *tty1, *tty2, *tty3, *gtty;
44 bool tty_cls (tty_t *tty)
46 if (!tty)
47 return 0;
49 memset (tty->screen, 0, 4000);
51 tty->screen_len = 0;
52 tty->read_len = 0;
53 #ifdef ARCH_i386
54 if (vgagui) {
55 if (vgagui == 2)
56 gcls (0);
58 return 1;
61 csr_x = 0;
62 csr_y = 0;
64 scroll ();
65 move_csr ();
66 #endif
67 cls ();
69 return 1;
72 bool tty_refresh (tty_t *tty)
74 if (!tty)
75 return 0;
77 if (vgagui)
78 return 1;
80 /* always default colors */
81 attrib = 0x07;
83 /* clear screen*/
84 cls ();
86 /* reprint whole screen from tty buffer*/
87 unsigned l = 0;
88 while (l != tty->screen_len) {
89 attrib = tty->screen[l];
90 putch (tty->screen[l+1]);
92 l += 2;
95 return 1;
98 bool tty_lock (tty_t *tty)
100 if (!tty)
101 return 0;
103 tty->active = false;
105 return 1;
108 bool tty_unlock (tty_t *tty)
110 if (!tty)
111 return 0;
113 tty->active = true;
115 return 1;
118 bool tty_startup ()
120 tty_t *tty = tty0;
121 currtty = tty0;
123 if (tty == NULL)
124 return 0;
126 strcpy (currtty->pwd, (char *) env_get ("PWD"));
128 currtty = tty;
130 env_set ("PWD", tty->pwd);
132 tty_refresh (tty);
134 return 1;
137 bool tty_change (tty_t *tty)
139 if (tty == NULL)
140 return 0;
142 strcpy (currtty->pwd, (char *) env_get ("PWD"));
144 if (currtty->user && currtty->user->name)
145 strcpy (currtty->user->name, (char *) env_get ("USER"));
147 currtty = tty;
149 env_set ("PWD", tty->pwd);
151 if (tty->user)
152 env_set ("USER", tty->user->name);
154 tty_refresh (tty);
156 return 1;
160 tty_t *tty_find (char *name)
162 tty_t *tty;
164 for (tty = tty_list.next; tty != &tty_list; tty = tty->next) {
165 if (!strcmp (tty->name, name))
166 return tty;
169 return NULL;
172 bool tty_write (tty_t *tty, char *str, unsigned len)
174 if (!tty)
175 return 0;
177 unsigned l = 0;
178 while (l != len) {
179 tty->screen[tty->screen_len+(l*2)] = attrib;
180 tty->screen[tty->screen_len+(l*2)+1] = str[l];
182 if (!vgagui)
183 if (tty == currtty)
184 putch (str[l]);
186 l ++;
189 tty->screen_len += len*2;
191 if (tty->screen_len >= 4000)
192 tty_cls (tty);
195 int tty_read (tty_t *tty, char *str, unsigned len)
197 if (!tty || !str)
198 return 0;
200 unsigned l = 0;
201 unsigned x = tty->screen_len/2;
203 if (len+tty->read_len > x)
204 len = x-tty->read_len;
206 for (l = 0; l < len; l ++)
207 str[l] = tty->screen[((l+tty->read_len)*2)+1];
209 str[l] = '\0';
211 tty->read_len += l;
213 return l;
216 bool tty_putch (char c)
218 tty_putnch (currtty, c);
220 return 1;
223 bool tty_putnch (tty_t *tty, char c)
225 if (!c)
226 return 0;
228 tty->screen[tty->screen_len] = attrib;
229 tty->screen[tty->screen_len+1] = c;
231 if (!vgagui)
232 putch (c);
234 tty->screen_len += 2;
236 if (tty->screen_len >= 4000)
237 tty_cls (tty);
239 return 1;
242 bool tty_motd ()
244 vfs_list_add ("motd", VFS_FILEATTR_FILE | VFS_FILEATTR_READ | VFS_FILEATTR_SYSTEM, "/etc/");
246 char *motd = "\t\t\t\tWelcome !\n"
247 "This is ZeX/OS - operating system created by Tomas 'ZeXx86' Jedrzejek\n"
248 "Please visit web page www.zexos.org for more information ..\n"
249 "Latest source code is available on git repository: git://repo.or.cz/ZeXOS.git\n"
250 "You can display list of the built-in commands by \"help\".\n"
251 "Default login name is \"root\" secured by password \"root\".\n";
253 vfs_mmap ("/etc/motd", 9, motd, strlen (motd));
255 settextcolor (15, 0);
257 vfs_cat ("/etc/motd", 9);
259 settextcolor (7, 0);
261 return 1;
264 tty_t *tty_create (char *name, unsigned task_entry)
266 if (tty_find (name) && task_entry)
267 return 0;
269 unsigned name_len = strlen (name);
271 tty_t *tty;
273 /* alloc and init context */
274 tty = (tty_t *) kmalloc (sizeof (tty_t));
275 memset (tty, 0, sizeof (tty_t));
277 tty->name = (char *) kmalloc (sizeof (char) * name_len + 1);
278 memset (tty->name, 0, name_len);
279 memcpy (tty->name, name, name_len);
280 tty->name[name_len] = '\0';
282 memset (tty->screen, 0, 4000);
283 tty->screen_len = 0;
285 tty->logged = false;
287 tty->active = true;
289 tty->read_len = 0;
291 strcpy (tty->pwd, (char *) env_get ("PWD"));
293 tty->task = (task_t *) task_create (name, (unsigned) task_entry, 32);
295 /* add into list */
296 tty->next = &tty_list;
297 tty->prev = tty_list.prev;
298 tty->prev->next = tty;
299 tty->next->prev = tty;
301 return tty;
304 void task_thread (tty_t *tty)
306 schedule ();
308 if (!tty)
309 return;
311 if (tty != currtty)
312 return;
314 if (tty->active) {
315 /* handle console on kernel level */
316 int id = gets ();
318 if (id == 1)
319 if (tty->user) {
320 console (id);
321 } else
322 getlogin (id);
324 #ifdef ARCH_i386
325 /* VESA mode - graphical font */
326 if (vgagui == 2) {
327 unsigned i = 0;
328 unsigned j = 0;
329 unsigned k = 0;
331 while (i < 2000) {
332 switch (tty->screen[i*2+1]) {
333 case '\0':
334 break;
335 case '\n':
336 k ++;
338 j = 0;
340 /* When we reach 64 lines, clear screen and begin from start
341 FIXME - lets move whole text up */
342 if (k > 64)
343 tty_cls (tty);
345 break;
346 case '\t':
347 k += 4;
349 j = 0;
351 /* When we reach 64 lines, clear screen and begin from start
352 FIXME - lets move whole text up */
353 if (k > 64)
354 tty_cls (tty);
356 break;
357 case '\b':
358 j --;
359 grectfill (1+(j*5), 11+(k*9), 6+(j*5), 19+(k*9), 0x0);
360 break;
361 default:
362 gputch (1+(j*5), 11+(k*9), vesa_16cto16b (tty->screen[i*2] & 0x0F), tty->screen[i*2+1]);
364 j ++;
366 break;
369 i ++;
372 gfbswap ();
374 #endif
378 unsigned task_tty0 ()
380 tty_write (tty0, "\nlogin: ", 8);
382 while(1)
383 task_thread (tty0);
386 unsigned task_tty1 ()
388 tty_write (tty1, "\nlogin: ", 8);
390 while(1)
391 task_thread (tty1);
394 unsigned task_tty2 ()
396 tty_write (tty2, "\nlogin: ", 8);
398 while(1)
399 task_thread (tty2);
402 unsigned task_tty3 ()
404 tty_write (tty3, "\nlogin: ", 8);
406 while(1)
407 task_thread (tty3);
410 unsigned task_gtty ()
412 tty_t *tty = gtty;
414 tty_write (tty, "\nlogin: ", 8);
416 while(1)
417 task_thread (tty);
420 void currtty_pageup()
422 if (vgagui)
423 return;
425 unsigned pos;
426 unsigned rowcount=0;
427 unsigned newlines[10]; // position in tty of last newlines in reverse
429 for (pos = currtty->screen_len; pos != 0; pos --) {
430 if (!strncmp ((currtty->screen)+pos,"\n", 1)) {
431 rowcount ++;
433 if (rowcount < 10)
434 newlines[rowcount] = pos;
438 if (rowcount > 24) {
439 if (!orig_screen_len)
440 orig_screen_len = currtty->screen_len;
442 if (rowcount > 29)
443 currtty->screen_len = newlines[5];
444 else // rowcount 25 - 29
445 currtty->screen_len = newlines[((-1)*(25-rowcount))+2];
447 currtty->screen_len ++;
448 tty_refresh (currtty);
452 void currtty_pagedown()
454 if (!orig_screen_len)
455 return;
457 unsigned pos;
458 unsigned rowcount=0;
459 unsigned newlines[10];
461 for (pos=currtty->screen_len; pos!=orig_screen_len; pos ++) {
462 if (!strncmp ((currtty->screen)+pos,"\n", 1)) {
463 rowcount ++;
465 if (rowcount < 10)
466 newlines[rowcount] = pos;
470 if (rowcount) {
471 if (rowcount > 5) {
472 currtty->screen_len = newlines[5];
473 currtty->screen_len ++; //
474 tty_refresh (currtty);
475 } else {
476 currtty->screen_len = orig_screen_len;
477 tty_refresh (currtty);
478 orig_screen_len = 0;
483 void currtty_scroll_to_end ()
485 if (!orig_screen_len)
486 return;
488 currtty->screen_len = orig_screen_len;
489 orig_screen_len = 0;
491 tty_refresh (currtty);
494 void gtty_init ()
496 gtty = tty_create ("gtty", (unsigned) task_gtty);
498 tty_change (gtty);
501 unsigned int init_tty ()
503 tty_list.next = &tty_list;
504 tty_list.prev = &tty_list;
506 settextcolor (7, 0);
508 tty0 = tty_create ("tty0", (unsigned) task_tty0);
509 #ifdef ARCH_i386
510 tty1 = tty_create ("tty1", (unsigned) task_tty1);
511 tty2 = tty_create ("tty2", (unsigned) task_tty2);
512 tty3 = tty_create ("tty3", (unsigned) task_tty3);
513 #endif
514 tty_startup ();
516 tty_motd ();
518 return 1;