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 | { |