Rev 4537 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4537 | Rev 4668 | ||
---|---|---|---|
Line 49... | Line 49... | ||
49 | #include <stdio.h> |
49 | #include <stdio.h> |
50 | #include <string.h> |
50 | #include <string.h> |
51 | #include <sysinfo.h> |
51 | #include <sysinfo.h> |
52 | #include <event.h> |
52 | #include <event.h> |
53 | #include <devmap.h> |
53 | #include <devmap.h> |
- | 54 | #include <fibril_sync.h> |
|
54 | 55 | ||
55 | #include "console.h" |
56 | #include "console.h" |
56 | #include "gcons.h" |
57 | #include "gcons.h" |
57 | #include "screenbuffer.h" |
58 | #include "screenbuffer.h" |
58 | 59 | ||
Line 66... | Line 67... | ||
66 | /** Information about framebuffer */ |
67 | /** Information about framebuffer */ |
67 | struct { |
68 | struct { |
68 | int phone; /**< Framebuffer phone */ |
69 | int phone; /**< Framebuffer phone */ |
69 | ipcarg_t cols; /**< Framebuffer columns */ |
70 | ipcarg_t cols; /**< Framebuffer columns */ |
70 | ipcarg_t rows; /**< Framebuffer rows */ |
71 | ipcarg_t rows; /**< Framebuffer rows */ |
- | 72 | int color_cap; /**< Color capabilities (FB_CCAP_xxx) */ |
|
71 | } fb_info; |
73 | } fb_info; |
72 | 74 | ||
73 | typedef struct { |
75 | typedef struct { |
74 | size_t index; /**< Console index */ |
76 | size_t index; /**< Console index */ |
75 | size_t refcount; /**< Connection reference count */ |
77 | size_t refcount; /**< Connection reference count */ |
Line 95... | Line 97... | ||
95 | size_t col; /**< Leftmost column of the span. */ |
97 | size_t col; /**< Leftmost column of the span. */ |
96 | size_t row; /**< Row where the span lies. */ |
98 | size_t row; /**< Row where the span lies. */ |
97 | size_t cnt; /**< Width of the span. */ |
99 | size_t cnt; /**< Width of the span. */ |
98 | } fb_pending; |
100 | } fb_pending; |
99 | 101 | ||
100 | /** Pending input structure. */ |
- | |
101 | typedef struct { |
- | |
102 | link_t link; |
- | |
103 | console_t *cons; /**< Console waiting for input */ |
- | |
104 | ipc_callid_t rid; /**< Call ID waiting for input */ |
- | |
105 | ipc_callid_t callid; /**< Call ID waiting for IPC_DATA_READ */ |
- | |
106 | - | ||
107 | size_t pos; /**< Position of the last stored data */ |
- | |
108 | size_t size; /**< Size of ther buffer */ |
- | |
109 | char *data; /**< Already stored data */ |
- | |
110 | } pending_input_t; |
- | |
111 | - | ||
112 | LIST_INITIALIZE(pending_input); |
102 | static FIBRIL_MUTEX_INITIALIZE(input_mutex); |
113 | - | ||
114 | /** Process pending input requests */ |
- | |
115 | static void process_pending_input(void) |
103 | static FIBRIL_CONDVAR_INITIALIZE(input_cv); |
116 | { |
- | |
117 | async_serialize_start(); |
- | |
118 | - | ||
119 | link_t *cur; |
- | |
120 | - | ||
121 | loop: |
- | |
122 | for (cur = pending_input.next; cur != &pending_input; cur = cur->next) { |
- | |
123 | pending_input_t *pr = list_get_instance(cur, pending_input_t, link); |
- | |
124 | - | ||
125 | console_event_t ev; |
- | |
126 | if (keybuffer_pop(&pr->cons->keybuffer, &ev)) { |
- | |
127 | - | ||
128 | if (pr->data != NULL) { |
- | |
129 | if (ev.type == KEY_PRESS) { |
- | |
130 | pr->data[pr->pos] = ev.c; |
- | |
131 | pr->pos++; |
- | |
132 | } |
- | |
133 | } else { |
- | |
134 | ipc_answer_4(pr->rid, EOK, ev.type, ev.key, ev.mods, ev.c); |
- | |
135 | - | ||
136 | list_remove(cur); |
- | |
137 | free(pr); |
- | |
138 | - | ||
139 | goto loop; |
- | |
140 | } |
- | |
141 | } |
- | |
142 | - | ||
143 | if ((pr->data != NULL) && (pr->pos == pr->size)) { |
- | |
144 | (void) ipc_data_read_finalize(pr->callid, pr->data, pr->size); |
- | |
145 | ipc_answer_1(pr->rid, EOK, pr->size); |
- | |
146 | - | ||
147 | free(pr->data); |
- | |
148 | list_remove(cur); |
- | |
149 | free(pr); |
- | |
150 | - | ||
151 | goto loop; |
- | |
152 | } |
- | |
153 | } |
- | |
154 | - | ||
155 | async_serialize_end(); |
- | |
156 | } |
- | |
157 | 104 | ||
158 | static void curs_visibility(bool visible) |
105 | static void curs_visibility(bool visible) |
159 | { |
106 | { |
160 | async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible); |
107 | async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible); |
161 | } |
108 | } |
Line 224... | Line 171... | ||
224 | set_rgb_color(attrs->a.r.fg_color, attrs->a.r.bg_color); |
171 | set_rgb_color(attrs->a.r.fg_color, attrs->a.r.bg_color); |
225 | break; |
172 | break; |
226 | } |
173 | } |
227 | } |
174 | } |
228 | 175 | ||
- | 176 | int ccap_fb_to_con(int ccap_fb, int *ccap_con) |
|
- | 177 | { |
|
- | 178 | switch (ccap_fb) { |
|
- | 179 | case FB_CCAP_NONE: *ccap_con = CONSOLE_CCAP_NONE; break; |
|
- | 180 | case FB_CCAP_STYLE: *ccap_con = CONSOLE_CCAP_STYLE; break; |
|
- | 181 | case FB_CCAP_INDEXED: *ccap_con = CONSOLE_CCAP_INDEXED; break; |
|
- | 182 | case FB_CCAP_RGB: *ccap_con = CONSOLE_CCAP_RGB; break; |
|
- | 183 | default: return EINVAL; |
|
- | 184 | } |
|
- | 185 | ||
- | 186 | return EOK; |
|
- | 187 | } |
|
- | 188 | ||
229 | /** Send an area of screenbuffer to the FB driver. */ |
189 | /** Send an area of screenbuffer to the FB driver. */ |
230 | static void fb_update_area(console_t *cons, ipcarg_t x0, ipcarg_t y0, ipcarg_t width, ipcarg_t height) |
190 | static void fb_update_area(console_t *cons, ipcarg_t x0, ipcarg_t y0, ipcarg_t width, ipcarg_t height) |
231 | { |
191 | { |
232 | if (interbuffer) { |
192 | if (interbuffer) { |
233 | ipcarg_t x; |
193 | ipcarg_t x; |
Line 285... | Line 245... | ||
285 | } |
245 | } |
286 | 246 | ||
287 | /** Process a character from the client (TTY emulation). */ |
247 | /** Process a character from the client (TTY emulation). */ |
288 | static void write_char(console_t *cons, wchar_t ch) |
248 | static void write_char(console_t *cons, wchar_t ch) |
289 | { |
249 | { |
- | 250 | bool flush_cursor = false; |
|
- | 251 | ||
290 | switch (ch) { |
252 | switch (ch) { |
291 | case '\n': |
253 | case '\n': |
292 | fb_pending_flush(); |
254 | fb_pending_flush(); |
- | 255 | flush_cursor = true; |
|
293 | cons->scr.position_y++; |
256 | cons->scr.position_y++; |
294 | cons->scr.position_x = 0; |
257 | cons->scr.position_x = 0; |
295 | break; |
258 | break; |
296 | case '\r': |
259 | case '\r': |
297 | break; |
260 | break; |
Line 313... | Line 276... | ||
313 | 276 | ||
314 | screenbuffer_putchar(&cons->scr, ch); |
277 | screenbuffer_putchar(&cons->scr, ch); |
315 | cons->scr.position_x++; |
278 | cons->scr.position_x++; |
316 | } |
279 | } |
317 | 280 | ||
318 | if (cons->scr.position_x >= cons->scr.size_x) |
281 | if (cons->scr.position_x >= cons->scr.size_x) { |
- | 282 | flush_cursor = true; |
|
319 | cons->scr.position_y++; |
283 | cons->scr.position_y++; |
- | 284 | } |
|
320 | 285 | ||
321 | if (cons->scr.position_y >= cons->scr.size_y) { |
286 | if (cons->scr.position_y >= cons->scr.size_y) { |
322 | fb_pending_flush(); |
287 | fb_pending_flush(); |
323 | cons->scr.position_y = cons->scr.size_y - 1; |
288 | cons->scr.position_y = cons->scr.size_y - 1; |
324 | screenbuffer_clear_line(&cons->scr, cons->scr.top_line); |
289 | screenbuffer_clear_line(&cons->scr, cons->scr.top_line); |
325 | cons->scr.top_line = (cons->scr.top_line + 1) % cons->scr.size_y; |
290 | cons->scr.top_line = (cons->scr.top_line + 1) % cons->scr.size_y; |
326 | 291 | ||
327 | if (cons == active_console) |
292 | if (cons == active_console) |
328 | async_msg_1(fb_info.phone, FB_SCROLL, 1); |
293 | async_msg_1(fb_info.phone, FB_SCROLL, 1); |
329 | } |
294 | } |
330 | 295 | ||
- | 296 | if (cons == active_console && flush_cursor) |
|
- | 297 | curs_goto(cons->scr.position_x, cons->scr.position_y); |
|
331 | cons->scr.position_x = cons->scr.position_x % cons->scr.size_x; |
298 | cons->scr.position_x = cons->scr.position_x % cons->scr.size_x; |
332 | } |
299 | } |
333 | 300 | ||
334 | /** Switch to new console */ |
301 | /** Switch to new console */ |
335 | static void change_console(console_t *cons) |
302 | static void change_console(console_t *cons) |
Line 444... | Line 411... | ||
444 | else |
411 | else |
445 | change_console(&consoles[ev.key - KC_F1]); |
412 | change_console(&consoles[ev.key - KC_F1]); |
446 | break; |
413 | break; |
447 | } |
414 | } |
448 | 415 | ||
- | 416 | fibril_mutex_lock(&input_mutex); |
|
449 | keybuffer_push(&active_console->keybuffer, &ev); |
417 | keybuffer_push(&active_console->keybuffer, &ev); |
- | 418 | fibril_condvar_broadcast(&input_cv); |
|
- | 419 | fibril_mutex_unlock(&input_mutex); |
|
450 | break; |
420 | break; |
451 | default: |
421 | default: |
452 | retval = ENOENT; |
422 | retval = ENOENT; |
453 | } |
423 | } |
454 | ipc_answer_0(callid, retval); |
424 | ipc_answer_0(callid, retval); |
Line 480... | Line 450... | ||
480 | while (off < size) { |
450 | while (off < size) { |
481 | wchar_t ch = str_decode(buf, &off, size); |
451 | wchar_t ch = str_decode(buf, &off, size); |
482 | write_char(cons, ch); |
452 | write_char(cons, ch); |
483 | } |
453 | } |
484 | 454 | ||
485 | if (cons == active_console) |
- | |
486 | curs_goto(cons->scr.position_x, cons->scr.position_y); |
- | |
487 | - | ||
488 | async_serialize_end(); |
455 | async_serialize_end(); |
489 | 456 | ||
490 | gcons_notify_char(cons->index); |
457 | gcons_notify_char(cons->index); |
491 | ipc_answer_1(rid, EOK, size); |
458 | ipc_answer_1(rid, EOK, size); |
492 | 459 | ||
Line 508... | Line 475... | ||
508 | ipc_answer_0(callid, ENOMEM); |
475 | ipc_answer_0(callid, ENOMEM); |
509 | ipc_answer_0(rid, ENOMEM); |
476 | ipc_answer_0(rid, ENOMEM); |
510 | return; |
477 | return; |
511 | } |
478 | } |
512 | 479 | ||
513 | async_serialize_start(); |
- | |
514 | - | ||
515 | size_t pos = 0; |
480 | size_t pos = 0; |
516 | console_event_t ev; |
481 | console_event_t ev; |
- | 482 | fibril_mutex_lock(&input_mutex); |
|
- | 483 | recheck: |
|
517 | while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) { |
484 | while ((keybuffer_pop(&cons->keybuffer, &ev)) && (pos < size)) { |
518 | if (ev.type == KEY_PRESS) { |
485 | if (ev.type == KEY_PRESS) { |
519 | buf[pos] = ev.c; |
486 | buf[pos] = ev.c; |
520 | pos++; |
487 | pos++; |
521 | } |
488 | } |
Line 524... | Line 491... | ||
524 | if (pos == size) { |
491 | if (pos == size) { |
525 | (void) ipc_data_read_finalize(callid, buf, size); |
492 | (void) ipc_data_read_finalize(callid, buf, size); |
526 | ipc_answer_1(rid, EOK, size); |
493 | ipc_answer_1(rid, EOK, size); |
527 | free(buf); |
494 | free(buf); |
528 | } else { |
495 | } else { |
529 | pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t)); |
- | |
530 | if (!pr) { |
- | |
531 | ipc_answer_0(callid, ENOMEM); |
496 | fibril_condvar_wait(&input_cv, &input_mutex); |
532 | ipc_answer_0(rid, ENOMEM); |
- | |
533 | free(buf); |
497 | goto recheck; |
534 | async_serialize_end(); |
- | |
535 | return; |
- | |
536 | } |
- | |
537 | - | ||
538 | pr->cons = cons; |
- | |
539 | pr->rid = rid; |
- | |
540 | pr->callid = callid; |
- | |
541 | pr->pos = pos; |
- | |
542 | pr->size = size; |
- | |
543 | pr->data = buf; |
- | |
544 | list_append(&pr->link, &pending_input); |
- | |
545 | } |
498 | } |
546 | - | ||
547 | async_serialize_end(); |
499 | fibril_mutex_unlock(&input_mutex); |
548 | } |
500 | } |
549 | 501 | ||
550 | static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request) |
502 | static void cons_get_event(console_t *cons, ipc_callid_t rid, ipc_call_t *request) |
551 | { |
503 | { |
552 | async_serialize_start(); |
- | |
553 | - | ||
554 | console_event_t ev; |
504 | console_event_t ev; |
- | 505 | ||
- | 506 | fibril_mutex_lock(&input_mutex); |
|
- | 507 | recheck: |
|
555 | if (keybuffer_pop(&cons->keybuffer, &ev)) { |
508 | if (keybuffer_pop(&cons->keybuffer, &ev)) { |
556 | ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c); |
509 | ipc_answer_4(rid, EOK, ev.type, ev.key, ev.mods, ev.c); |
557 | } else { |
510 | } else { |
558 | pending_input_t *pr = (pending_input_t *) malloc(sizeof(pending_input_t)); |
- | |
559 | if (!pr) { |
- | |
560 | ipc_answer_0(rid, ENOMEM); |
511 | fibril_condvar_wait(&input_cv, &input_mutex); |
561 | async_serialize_end(); |
- | |
562 | return; |
512 | goto recheck; |
563 | } |
- | |
564 | - | ||
565 | pr->cons = cons; |
- | |
566 | pr->rid = rid; |
- | |
567 | pr->callid = 0; |
- | |
568 | pr->data = NULL; |
- | |
569 | list_append(&pr->link, &pending_input); |
- | |
570 | } |
513 | } |
571 | - | ||
572 | async_serialize_end(); |
514 | fibril_mutex_unlock(&input_mutex); |
573 | } |
515 | } |
574 | 516 | ||
575 | /** Default thread for new connections */ |
517 | /** Default thread for new connections */ |
576 | static void client_connection(ipc_callid_t iid, ipc_call_t *icall) |
518 | static void client_connection(ipc_callid_t iid, ipc_call_t *icall) |
577 | { |
519 | { |
Line 596... | Line 538... | ||
596 | ipc_callid_t callid; |
538 | ipc_callid_t callid; |
597 | ipc_call_t call; |
539 | ipc_call_t call; |
598 | ipcarg_t arg1; |
540 | ipcarg_t arg1; |
599 | ipcarg_t arg2; |
541 | ipcarg_t arg2; |
600 | ipcarg_t arg3; |
542 | ipcarg_t arg3; |
- | 543 | ||
- | 544 | int cons_ccap; |
|
- | 545 | int rc; |
|
601 | 546 | ||
602 | async_serialize_start(); |
547 | async_serialize_start(); |
603 | if (cons->refcount == 0) |
548 | if (cons->refcount == 0) |
604 | gcons_notify_connect(cons->index); |
549 | gcons_notify_connect(cons->index); |
605 | 550 | ||
Line 621... | Line 566... | ||
621 | case IPC_M_PHONE_HUNGUP: |
566 | case IPC_M_PHONE_HUNGUP: |
622 | cons->refcount--; |
567 | cons->refcount--; |
623 | if (cons->refcount == 0) |
568 | if (cons->refcount == 0) |
624 | gcons_notify_disconnect(cons->index); |
569 | gcons_notify_disconnect(cons->index); |
625 | return; |
570 | return; |
626 | case VFS_READ: |
571 | case VFS_OUT_READ: |
627 | async_serialize_end(); |
572 | async_serialize_end(); |
628 | cons_read(cons, callid, &call); |
573 | cons_read(cons, callid, &call); |
629 | async_serialize_start(); |
574 | async_serialize_start(); |
630 | continue; |
575 | continue; |
631 | case VFS_WRITE: |
576 | case VFS_OUT_WRITE: |
632 | async_serialize_end(); |
577 | async_serialize_end(); |
633 | cons_write(cons, callid, &call); |
578 | cons_write(cons, callid, &call); |
634 | async_serialize_start(); |
579 | async_serialize_start(); |
635 | continue; |
580 | continue; |
636 | case VFS_SYNC: |
581 | case VFS_OUT_SYNC: |
637 | fb_pending_flush(); |
582 | fb_pending_flush(); |
638 | if (cons == active_console) { |
583 | if (cons == active_console) { |
639 | async_req_0_0(fb_info.phone, FB_FLUSH); |
584 | async_req_0_0(fb_info.phone, FB_FLUSH); |
640 | 585 | ||
641 | curs_goto(cons->scr.position_x, cons->scr.position_y); |
586 | curs_goto(cons->scr.position_x, cons->scr.position_y); |
Line 658... | Line 603... | ||
658 | break; |
603 | break; |
659 | case CONSOLE_GET_SIZE: |
604 | case CONSOLE_GET_SIZE: |
660 | arg1 = fb_info.cols; |
605 | arg1 = fb_info.cols; |
661 | arg2 = fb_info.rows; |
606 | arg2 = fb_info.rows; |
662 | break; |
607 | break; |
- | 608 | case CONSOLE_GET_COLOR_CAP: |
|
- | 609 | rc = ccap_fb_to_con(fb_info.color_cap, &cons_ccap); |
|
- | 610 | if (rc != EOK) { |
|
- | 611 | ipc_answer_0(callid, rc); |
|
- | 612 | continue; |
|
- | 613 | } |
|
- | 614 | arg1 = cons_ccap; |
|
- | 615 | break; |
|
663 | case CONSOLE_SET_STYLE: |
616 | case CONSOLE_SET_STYLE: |
664 | fb_pending_flush(); |
617 | fb_pending_flush(); |
665 | arg1 = IPC_GET_ARG1(call); |
618 | arg1 = IPC_GET_ARG1(call); |
666 | screenbuffer_set_style(&cons->scr, arg1); |
619 | screenbuffer_set_style(&cons->scr, arg1); |
667 | if (cons == active_console) |
620 | if (cons == active_console) |
Line 709... | Line 662... | ||
709 | change_console(prev_console); |
662 | change_console(prev_console); |
710 | } |
663 | } |
711 | 664 | ||
712 | static bool console_init(void) |
665 | static bool console_init(void) |
713 | { |
666 | { |
714 | async_serialize_start(); |
667 | ipcarg_t color_cap; |
715 | 668 | ||
716 | /* Connect to keyboard driver */ |
669 | /* Connect to keyboard driver */ |
717 | kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0); |
670 | kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0); |
718 | if (kbd_phone < 0) { |
671 | if (kbd_phone < 0) { |
719 | printf(NAME ": Failed to connect to keyboard service\n"); |
672 | printf(NAME ": Failed to connect to keyboard service\n"); |
720 | async_serialize_end(); |
- | |
721 | return false; |
673 | return false; |
722 | } |
674 | } |
723 | 675 | ||
724 | ipcarg_t phonehash; |
676 | ipcarg_t phonehash; |
725 | if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) { |
677 | if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) { |
726 | printf(NAME ": Failed to create callback from keyboard service\n"); |
678 | printf(NAME ": Failed to create callback from keyboard service\n"); |
727 | async_serialize_end(); |
- | |
728 | return false; |
679 | return false; |
729 | } |
680 | } |
730 | 681 | ||
731 | async_set_pending(process_pending_input); |
- | |
732 | async_new_connection(phonehash, 0, NULL, keyboard_events); |
682 | async_new_connection(phonehash, 0, NULL, keyboard_events); |
733 | 683 | ||
734 | /* Connect to framebuffer driver */ |
684 | /* Connect to framebuffer driver */ |
735 | fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0); |
685 | fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0); |
736 | if (fb_info.phone < 0) { |
686 | if (fb_info.phone < 0) { |
737 | printf(NAME ": Failed to connect to video service\n"); |
687 | printf(NAME ": Failed to connect to video service\n"); |
738 | async_serialize_end(); |
- | |
739 | return -1; |
688 | return -1; |
740 | } |
689 | } |
741 | 690 | ||
742 | /* Register driver */ |
691 | /* Register driver */ |
743 | int rc = devmap_driver_register(NAME, client_connection); |
692 | int rc = devmap_driver_register(NAME, client_connection); |
744 | if (rc < 0) { |
693 | if (rc < 0) { |
745 | printf(NAME ": Unable to register driver (%d)\n", rc); |
694 | printf(NAME ": Unable to register driver (%d)\n", rc); |
746 | async_serialize_end(); |
- | |
747 | return false; |
695 | return false; |
748 | } |
696 | } |
749 | 697 | ||
750 | /* Initialize gcons */ |
698 | /* Initialize gcons */ |
751 | gcons_init(fb_info.phone); |
699 | gcons_init(fb_info.phone); |
752 | 700 | ||
753 | /* Synchronize, the gcons could put something in queue */ |
701 | /* Synchronize, the gcons could put something in queue */ |
754 | async_req_0_0(fb_info.phone, FB_FLUSH); |
702 | async_req_0_0(fb_info.phone, FB_FLUSH); |
755 | async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows); |
703 | async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.cols, &fb_info.rows); |
- | 704 | async_req_0_1(fb_info.phone, FB_GET_COLOR_CAP, &color_cap); |
|
- | 705 | fb_info.color_cap = color_cap; |
|
756 | 706 | ||
757 | /* Set up shared memory buffer. */ |
707 | /* Set up shared memory buffer. */ |
758 | size_t ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows; |
708 | size_t ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows; |
759 | interbuffer = as_get_mappable_page(ib_size); |
709 | interbuffer = as_get_mappable_page(ib_size); |
760 | 710 | ||
Line 777... | Line 727... | ||
777 | for (i = 0; i < CONSOLE_COUNT; i++) { |
727 | for (i = 0; i < CONSOLE_COUNT; i++) { |
778 | if (i != KERNEL_CONSOLE) { |
728 | if (i != KERNEL_CONSOLE) { |
779 | if (screenbuffer_init(&consoles[i].scr, |
729 | if (screenbuffer_init(&consoles[i].scr, |
780 | fb_info.cols, fb_info.rows) == NULL) { |
730 | fb_info.cols, fb_info.rows) == NULL) { |
781 | printf(NAME ": Unable to allocate screen buffer %u\n", i); |
731 | printf(NAME ": Unable to allocate screen buffer %u\n", i); |
782 | async_serialize_end(); |
- | |
783 | return false; |
732 | return false; |
784 | } |
733 | } |
785 | screenbuffer_clear(&consoles[i].scr); |
734 | screenbuffer_clear(&consoles[i].scr); |
786 | keybuffer_init(&consoles[i].keybuffer); |
735 | keybuffer_init(&consoles[i].keybuffer); |
787 | consoles[i].index = i; |
736 | consoles[i].index = i; |
Line 791... | Line 740... | ||
791 | snprintf(vc, MAX_DEVICE_NAME, "vc%u", i); |
740 | snprintf(vc, MAX_DEVICE_NAME, "vc%u", i); |
792 | 741 | ||
793 | if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) { |
742 | if (devmap_device_register(vc, &consoles[i].dev_handle) != EOK) { |
794 | devmap_hangup_phone(DEVMAP_DRIVER); |
743 | devmap_hangup_phone(DEVMAP_DRIVER); |
795 | printf(NAME ": Unable to register device %s\n", vc); |
744 | printf(NAME ": Unable to register device %s\n", vc); |
796 | async_serialize_end(); |
- | |
797 | return false; |
745 | return false; |
798 | } |
746 | } |
799 | } |
747 | } |
800 | } |
748 | } |
801 | 749 | ||
802 | /* Disable kernel output to the console */ |
750 | /* Disable kernel output to the console */ |
803 | __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE); |
751 | __SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE); |
804 | 752 | ||
805 | /* Initialize the screen */ |
753 | /* Initialize the screen */ |
- | 754 | async_serialize_start(); |
|
806 | gcons_redraw_console(); |
755 | gcons_redraw_console(); |
807 | set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
756 | set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
808 | screen_clear(); |
757 | screen_clear(); |
809 | curs_goto(0, 0); |
758 | curs_goto(0, 0); |
810 | curs_visibility(active_console->scr.is_cursor_visible); |
759 | curs_visibility(active_console->scr.is_cursor_visible); |
- | 760 | async_serialize_end(); |
|
811 | 761 | ||
812 | /* Receive kernel notifications */ |
762 | /* Receive kernel notifications */ |
813 | if (event_subscribe(EVENT_KCONSOLE, 0) != EOK) |
763 | if (event_subscribe(EVENT_KCONSOLE, 0) != EOK) |
814 | printf(NAME ": Error registering kconsole notifications\n"); |
764 | printf(NAME ": Error registering kconsole notifications\n"); |
815 | 765 | ||
816 | async_set_interrupt_received(interrupt_received); |
766 | async_set_interrupt_received(interrupt_received); |
817 | 767 | ||
818 | async_serialize_end(); |
- | |
819 | return true; |
768 | return true; |
820 | } |
769 | } |
821 | 770 | ||
822 | int main(int argc, char *argv[]) |
771 | int main(int argc, char *argv[]) |
823 | { |
772 | { |