missing files and previous update were fixed
[ZeXOS.git] / kernel / core / tty.c
blobb95c907017d2411507a7a0eae9ed167a5d468353
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <build.h>
23 #include <system.h>
24 #include <string.h>
25 #include <vfs.h>
27 #ifdef ARCH_i386 /* i386 specific things */
28 extern int attrib;
29 extern int gets (void);
30 extern int csr_x, csr_y;
31 extern unsigned char vgagui;
32 extern unsigned short *textmemptr;
33 #else /* fake things for other archs */
34 unsigned int attrib;
35 unsigned char vgagui;
36 #endif
38 static char con_screen[TTY_CON_BUF]; /* console buffer for image of screen */
39 static unsigned short tty_count; /* number of created ttys */
40 tty_font_t tty_font; /* global font settings */
41 tty_char_t tty_char; /* global character array settings */
43 tty_t tty_list; /* list for all created ttys */
44 tty_t *tty0, *tty1; /* structures for default ttys (0, 1) */
46 static unsigned task_tty ();
48 /* setup of font */
49 bool tty_font_set (char *c, unsigned char x, unsigned char y)
51 if (!c || !x || !y)
52 return 0;
54 tty_font.c = c;
55 tty_font.x = x;
56 tty_font.y = y;
58 return 1;
61 /* setup of character array */
62 bool tty_char_set (unsigned short x, unsigned short y)
64 if ((x * y * 2) > TTY_CON_BUF)
65 return 0;
67 tty_char.x = x;
68 tty_char.y = y;
70 return 1;
73 /* clear selected screen */
74 bool tty_cls (tty_t *tty)
76 if (!tty)
77 return 0;
79 if (!tty->screen)
80 return 0;
82 memset (tty->screen, 0, tty_char.x * tty_char.y * 2);
84 tty->screen_x = 0;
85 tty->screen_y = 0;
86 tty->read_len = 0;
88 if (tty != currtty)
89 return 1;
91 #ifdef ARCH_i386
92 if (vgagui) {
93 if (vgagui == 2)
94 video_gfx_cls (0);
96 return 1;
99 csr_x = 0;
100 csr_y = 0;
102 video_scroll ();
103 video_move_csr ();
104 #endif
105 video_cls ();
107 return 1;
110 /* lock manipulation with selected tty */
111 bool tty_lock (tty_t *tty)
113 if (!tty)
114 return 0;
116 tty->active = false;
118 return 1;
121 /* unlock manipulation with selected tty */
122 bool tty_unlock (tty_t *tty)
124 if (!tty)
125 return 0;
127 tty->active = true;
129 return 1;
132 /* startup function for tty init */
133 bool tty_startup ()
135 tty_t *tty = tty0;
137 if (tty == NULL)
138 return 0;
140 currtty = tty;
142 strcpy (currtty->pwd, (char *) env_get ("PWD"));
144 currtty = tty;
146 env_set ("PWD", tty->pwd);
148 /* always default colors */
149 attrib = 0x07;
151 /* clear screen*/
152 video_cls ();
154 return 1;
157 /* change current tty to selected one */
158 bool tty_change (tty_t *tty)
160 #ifndef ARCH_i386
161 return 0;
162 #endif
163 if (tty == NULL)
164 return 0;
166 #ifdef ARCH_i386
167 /* redraw screen with selected tty */
168 memcpy (textmemptr, tty->screen, tty_char.x * tty_char.y * 2);
170 csr_x = tty->screen_x;
171 csr_y = tty->screen_y;
173 video_move_csr ();
174 #endif
175 strcpy (currtty->pwd, (char *) env_get ("PWD"));
177 if (currtty->user && currtty->user->name)
178 strcpy (currtty->user->name, (char *) env_get ("USER"));
180 currtty = tty;
182 env_set ("PWD", tty->pwd);
184 if (tty->user)
185 env_set ("USER", tty->user->name);
187 return 1;
190 /* move cursor position to selected place */
191 bool tty_gotoxy (tty_t *tty, unsigned char x, unsigned char y)
193 if (tty == NULL)
194 return 0;
196 if (x >= tty_char.x || y >= tty_char.y)
197 return 0;
199 video_gotoxy (x, y);
201 tty->screen_x = x;
202 tty->screen_y = y;
204 return 1;
207 /* find wanted tty by name */
208 tty_t *tty_find (char *name)
210 tty_t *tty;
212 for (tty = tty_list.next; tty != &tty_list; tty = tty->next) {
213 if (!strcmp (tty->name, name))
214 return tty;
217 return NULL;
220 /* find tty by task */
221 tty_t *tty_findbytask (task_t *task)
223 tty_t *tty;
225 for (tty = tty_list.next; tty != &tty_list; tty = tty->next) {
226 if (tty->task == task)
227 return tty;
230 return NULL;
233 /* display list of created tty consoles */
234 void tty_listview ()
236 unsigned short id = 1;
238 tty_t *tty;
240 for (tty = tty_list.next; tty != &tty_list; tty = tty->next) {
241 printf ("%d.\t%s\t%s\n", id, tty->name, currtty == tty ? "<- current" : "");
243 id ++;
247 /* main function for print strings into selected tty */
248 bool tty_write (tty_t *tty, char *str, unsigned len)
250 if (!tty)
251 return 0;
253 unsigned l = 0;
254 while (l != len) {
255 if (!tty_putnch (tty, str[l]))
256 break;
258 l ++;
261 return 1;
264 /* read strings from selected tty */
265 int tty_read (tty_t *tty, char *str, unsigned len)
267 if (!tty || !str)
268 return 0;
270 char *p = (char *) tty->screen;
272 unsigned l = 0;
273 unsigned n = 2000;
275 unsigned x = 0;
276 unsigned y = 0;
278 if (len+tty->read_len > n)
279 len = n-tty->read_len;
281 for (l = 0; l < len; l ++) {
282 if (p[((l+tty->read_len)*2)+1])
283 str[l] = p[((l+tty->read_len)*2)+1];
285 x ++;
287 if (x >= tty_char.x) {
288 x = 0;
289 y ++;
290 str[l] = '\n';
294 str[l] = '\0';
296 tty->read_len += l;
298 return l;
301 /* print character to current tty */
302 bool tty_putch (char c)
304 tty_putnch (currtty, c);
306 return 1;
309 /* print character to selected tty */
310 bool tty_putnch (tty_t *tty, char c)
312 /* we wont null character */
313 if (!c)
314 return 0;
316 switch (c) {
317 case '\n':
318 tty->screen_y ++;
319 tty->screen_x = 0;
320 break;
321 case '\b':
322 if (tty->screen_x)
323 tty->screen_x --;
325 /* save font attributes (colors) */
326 tty->screen[(tty->screen_x+(tty->screen_y*tty_char.x))*2] = ' ';
327 /* save character into buffer */
328 tty->screen[((tty->screen_x+(tty->screen_y*tty_char.x))*2)+1] = attrib;
329 break;
330 case '\t':
331 tty->screen_x = (tty->screen_x + 8) & ~(8 - 1);
332 break;
333 default:
334 /* save font attributes (colors) */
335 tty->screen[(tty->screen_x+(tty->screen_y*tty_char.x))*2] = c;
336 /* save character into buffer */
337 tty->screen[((tty->screen_x+(tty->screen_y*tty_char.x))*2)+1] = attrib;
338 tty->screen_x ++;
339 break;
342 if (tty->screen_x >= tty_char.x) {
343 tty->screen_x -= tty_char.x;
344 tty->screen_y ++;
347 if (tty->screen_y >= tty_char.y) {
348 unsigned i;
349 /* save old screen, but with one line offset */
350 for (i = 0; i < (tty_char.x * tty_char.y * 2) - (tty_char.x * 2); i ++)
351 con_screen[i] = tty->screen[i+(tty_char.x * 2)];
352 /* copy new image into tty screen */
353 for (i = 0; i < (tty_char.x * tty_char.y * 2); i ++)
354 tty->screen[i] = con_screen[i];
356 tty->read_len += tty_char.x;
358 tty->screen_y = tty_char.y - 1;
361 if (!vgagui)
362 if (tty == currtty)
363 video_putch (c);
365 return 1;
368 /* create Message Of The Day in /etc/motd */
369 bool tty_motd ()
371 vfs_list_add ("motd", VFS_FILEATTR_FILE | VFS_FILEATTR_READ | VFS_FILEATTR_SYSTEM, "/etc/");
373 char *motd = "\t\t\t\tWelcome !\n"
374 "This is ZeX/OS - operating system created by Tomas 'ZeXx86' Jedrzejek\n"
375 "Please visit web page www.zexos.org for more information ..\n"
376 "Latest source code is available on git repository: git://repo.or.cz/ZeXOS.git\n"
377 "You can display list of the built-in commands by \"help\".\n"
378 "Default login name is \"root\" secured by password \"root\".\n";
380 vfs_mmap ("/etc/motd", 9, motd, strlen (motd));
382 video_color (15, 0);
384 vfs_cat ("/etc/motd", 9);
386 video_color (7, 0);
388 return 1;
391 /* create new tty console */
392 tty_t *tty_create ()
394 /* Software limit - max. 1K of ttys */
395 if (tty_count > TTY_COUNT_MAX)
396 return 0;
398 char name[8];
399 sprintf (name, "tty%d", tty_count);
401 unsigned name_len = strlen (name);
403 /* alloc and init context */
404 tty_t *tty = (tty_t *) kmalloc (sizeof (tty_t));
406 if (!tty)
407 return 0;
409 memset (tty, 0, sizeof (tty_t));
411 tty->screen = (char *) kmalloc (tty_char.x * tty_char.y * 2);
413 if (!tty->screen) {
414 kfree (tty);
415 return 0;
418 tty->name = (char *) kmalloc (sizeof (char) * name_len + 1);
420 if (!tty->name) {
421 kfree (tty->screen);
422 kfree (tty);
423 return 0;
426 memcpy (tty->name, name, name_len);
427 tty->name[name_len] = '\0';
429 memset (tty->screen, 0, tty_char.x * tty_char.y * 2);
431 tty->screen_x = 0;
432 tty->screen_y = 0;
434 tty->logged = false;
436 tty->active = true;
438 tty->read_len = 0;
440 strcpy (tty->pwd, (char *) env_get ("PWD"));
442 tty->task = (task_t *) task_create (name, (unsigned) task_tty, 32);
444 /* add into list */
445 tty->next = &tty_list;
446 tty->prev = tty_list.prev;
447 tty->prev->next = tty;
448 tty->next->prev = tty;
450 tty_count ++;
452 return tty;
455 /* thread for running tty consoles - handle selected console */
456 void task_thread (tty_t *tty)
458 schedule ();
460 if (!tty)
461 return;
463 if (tty != currtty)
464 return;
466 if (tty->active) {
467 /* handle console on kernel level */
468 int id = gets ();
470 if (id == 1)
471 if (tty->user) {
472 console (id);
473 } else
474 getlogin (id);
476 #ifdef ARCH_i386
477 /* VESA mode - graphical font */
478 if (vgagui == 2) {
479 unsigned i = 0;
480 unsigned j = 0;
481 unsigned k = 0;
482 unsigned m = tty_char.x * tty_char.y; //tty->screen_x + (tty->screen_y*80);
484 while (i < m) {
485 gputch (1+(j*tty_font.x), 11+(k*(tty_font.y+1)), vesa_16cto16b (tty->screen[i*2+1] & 0x0F), tty->screen[i*2]);
487 j ++;
489 if (j >= tty_char.x) {
490 j = 0;
491 k ++;
494 i ++;
497 video_gfx_fbswap ();
499 #endif
503 /* startup function for created tty console */
504 static unsigned task_tty ()
506 tty_t *tty = tty_findbytask (_curr_task);
508 if (!tty)
509 return 0;
511 while (1)
512 task_thread (tty);
515 /* change tty console to next (+) or previous (-) in list */
516 void tty_switch (char act)
518 switch (act) {
519 case '+':
521 tty_t *tty = currtty->next;
523 if (tty == &tty_list)
524 tty = tty_list.next;
526 if (tty)
527 tty_change (tty);
529 break;
531 case '-':
533 tty_t *tty = currtty->prev;
535 if (tty == &tty_list)
536 tty = tty_list.prev;
538 if (tty)
539 tty_change (tty);
541 break;
546 /* special function for initialization of graphical tty */
547 tty_t *gtty_init ()
549 tty_t *tty = tty_create ();
551 tty_change (tty);
553 return tty;
556 /* initialization of tty */
557 unsigned int init_tty ()
559 /* pre-set tty list */
560 tty_list.next = &tty_list;
561 tty_list.prev = &tty_list;
563 /* default values */
564 tty_count = 0;
566 tty_font_set ((char *) font5x8, 5, 8);
568 switch (vgagui) {
569 case 0: /* VGA-Textual console */
570 tty_char_set (80, 25);
571 break;
572 case 1: /* VGA console */
573 tty_char_set (53, 18);
574 break;
575 case 2: /* VESA concole */
576 tty_char_set (80, 65);
577 break;
580 video_color (7, 0);
582 /* create consoles */
583 tty0 = tty_create ();
585 if (!tty0)
586 return 0;
588 #ifdef ARCH_i386
589 tty1 = tty_create ();
591 if (!tty1)
592 return 0;
593 #endif
594 tty_startup ();
596 /* printf MOTD into TTY0 console */
597 tty_motd ();
599 /* then print login messages */
600 tty_write (tty0, "\nlogin: ", 8);
601 tty_write (tty1, "\nlogin: ", 8);
603 return 1;