Rev 4347 | Rev 4389 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4347 | Rev 4348 | ||
|---|---|---|---|
| Line 46... | Line 46... | ||
| 46 | #include <async.h> |
46 | #include <async.h> |
| 47 | #include <libadt/fifo.h> |
47 | #include <libadt/fifo.h> |
| 48 | #include <screenbuffer.h> |
48 | #include <screenbuffer.h> |
| 49 | #include <sys/mman.h> |
49 | #include <sys/mman.h> |
| 50 | #include <stdio.h> |
50 | #include <stdio.h> |
| - | 51 | #include <string.h> |
|
| 51 | #include <sysinfo.h> |
52 | #include <sysinfo.h> |
| 52 | #include <event.h> |
53 | #include <event.h> |
| 53 | 54 | ||
| 54 | #include "console.h" |
55 | #include "console.h" |
| 55 | #include "gcons.h" |
56 | #include "gcons.h" |
| Line 61... | Line 62... | ||
| 61 | /** Index of currently used virtual console. |
62 | /** Index of currently used virtual console. |
| 62 | */ |
63 | */ |
| 63 | int active_console = 0; |
64 | int active_console = 0; |
| 64 | int prev_console = 0; |
65 | int prev_console = 0; |
| 65 | 66 | ||
| - | 67 | /** Phone to the keyboard driver. */ |
|
| - | 68 | static int kbd_phone; |
|
| - | 69 | ||
| 66 | /** Information about framebuffer */ |
70 | /** Information about framebuffer */ |
| 67 | struct { |
71 | struct { |
| 68 | int phone; /**< Framebuffer phone */ |
72 | int phone; /**< Framebuffer phone */ |
| 69 | ipcarg_t rows; /**< Framebuffer rows */ |
73 | ipcarg_t rows; /**< Framebuffer rows */ |
| 70 | ipcarg_t cols; /**< Framebuffer columns */ |
74 | ipcarg_t cols; /**< Framebuffer columns */ |
| Line 101... | Line 105... | ||
| 101 | #define CWRITE_BUF_SIZE 256 |
105 | #define CWRITE_BUF_SIZE 256 |
| 102 | 106 | ||
| 103 | /** Buffer for receiving data via the CONSOLE_WRITE call from the client. */ |
107 | /** Buffer for receiving data via the CONSOLE_WRITE call from the client. */ |
| 104 | static char cwrite_buf[CWRITE_BUF_SIZE]; |
108 | static char cwrite_buf[CWRITE_BUF_SIZE]; |
| 105 | 109 | ||
| 106 | static void fb_putchar(char c, int row, int col); |
110 | static void fb_putchar(wchar_t c, int row, int col); |
| 107 | 111 | ||
| 108 | 112 | ||
| 109 | /** Find unused virtual console. |
113 | /** Find unused virtual console. |
| 110 | * |
114 | * |
| 111 | */ |
115 | */ |
| Line 138... | Line 142... | ||
| 138 | static void curs_goto(int row, int col) |
142 | static void curs_goto(int row, int col) |
| 139 | { |
143 | { |
| 140 | async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col); |
144 | async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col); |
| 141 | } |
145 | } |
| 142 | 146 | ||
| - | 147 | static void screen_yield(void) |
|
| - | 148 | { |
|
| - | 149 | ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_YIELD); |
|
| - | 150 | } |
|
| - | 151 | ||
| - | 152 | static void screen_reclaim(void) |
|
| - | 153 | { |
|
| - | 154 | ipc_call_sync_0_0(fb_info.phone, FB_SCREEN_RECLAIM); |
|
| - | 155 | } |
|
| - | 156 | ||
| - | 157 | static void kbd_yield(void) |
|
| - | 158 | { |
|
| - | 159 | ipc_call_sync_0_0(kbd_phone, KBD_YIELD); |
|
| - | 160 | } |
|
| - | 161 | ||
| - | 162 | static void kbd_reclaim(void) |
|
| - | 163 | { |
|
| - | 164 | ipc_call_sync_0_0(kbd_phone, KBD_RECLAIM); |
|
| - | 165 | } |
|
| - | 166 | ||
| 143 | static void set_style(int style) |
167 | static void set_style(int style) |
| 144 | { |
168 | { |
| 145 | async_msg_1(fb_info.phone, FB_SET_STYLE, style); |
169 | async_msg_1(fb_info.phone, FB_SET_STYLE, style); |
| 146 | } |
170 | } |
| 147 | 171 | ||
| Line 195... | Line 219... | ||
| 195 | } else { |
219 | } else { |
| 196 | rc = ENOTSUP; |
220 | rc = ENOTSUP; |
| 197 | } |
221 | } |
| 198 | 222 | ||
| 199 | if (rc != 0) { |
223 | if (rc != 0) { |
| - | 224 | /* |
|
| 200 | attrs = &conn->screenbuffer.attrs; |
225 | attrs = &conn->screenbuffer.attrs; |
| 201 | 226 | ||
| 202 | for (j = 0; j < h; j++) { |
227 | for (j = 0; j < h; j++) { |
| 203 | for (i = 0; i < w; i++) { |
228 | for (i = 0; i < w; i++) { |
| 204 | field = get_field_at(&conn->screenbuffer, |
229 | field = get_field_at(&conn->screenbuffer, |
| Line 207... | Line 232... | ||
| 207 | set_attrs(&field->attrs); |
232 | set_attrs(&field->attrs); |
| 208 | attrs = &field->attrs; |
233 | attrs = &field->attrs; |
| 209 | 234 | ||
| 210 | fb_putchar(field->character, y + j, x + i); |
235 | fb_putchar(field->character, y + j, x + i); |
| 211 | } |
236 | } |
| 212 | } |
237 | }*/ |
| 213 | } |
238 | } |
| 214 | } |
239 | } |
| 215 | 240 | ||
| 216 | /** Flush pending cells to FB. */ |
241 | /** Flush pending cells to FB. */ |
| 217 | static void fb_pending_flush(void) |
242 | static void fb_pending_flush(void) |
| Line 249... | Line 274... | ||
| 249 | ++fb_pending.n; |
274 | ++fb_pending.n; |
| 250 | } |
275 | } |
| 251 | 276 | ||
| 252 | 277 | ||
| 253 | /** Print a character to the active VC with buffering. */ |
278 | /** Print a character to the active VC with buffering. */ |
| 254 | static void fb_putchar(char c, int row, int col) |
279 | static void fb_putchar(wchar_t c, int row, int col) |
| 255 | { |
280 | { |
| 256 | async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col); |
281 | async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col); |
| 257 | } |
282 | } |
| 258 | 283 | ||
| 259 | /** Process a character from the client (TTY emulation). */ |
284 | /** Process a character from the client (TTY emulation). */ |
| 260 | static void write_char(int console, char key) |
285 | static void write_char(int console, wchar_t ch) |
| 261 | { |
286 | { |
| 262 | bool flush_cursor = false; |
287 | bool flush_cursor = false; |
| 263 | screenbuffer_t *scr = &(connections[console].screenbuffer); |
288 | screenbuffer_t *scr = &(connections[console].screenbuffer); |
| 264 | 289 | ||
| 265 | switch (key) { |
290 | switch (ch) { |
| 266 | case '\n': |
291 | case '\n': |
| 267 | fb_pending_flush(); |
292 | fb_pending_flush(); |
| 268 | flush_cursor = true; |
293 | flush_cursor = true; |
| 269 | scr->position_y++; |
294 | scr->position_y++; |
| 270 | scr->position_x = 0; |
295 | scr->position_x = 0; |
| Line 285... | Line 310... | ||
| 285 | break; |
310 | break; |
| 286 | default: |
311 | default: |
| 287 | if (console == active_console) |
312 | if (console == active_console) |
| 288 | cell_mark_changed(scr->position_y, scr->position_x); |
313 | cell_mark_changed(scr->position_y, scr->position_x); |
| 289 | 314 | ||
| 290 | screenbuffer_putchar(scr, key); |
315 | screenbuffer_putchar(scr, ch); |
| 291 | scr->position_x++; |
316 | scr->position_x++; |
| 292 | } |
317 | } |
| 293 | 318 | ||
| 294 | if (scr->position_x >= scr->size_x) { |
319 | if (scr->position_x >= scr->size_x) { |
| 295 | flush_cursor = true; |
320 | flush_cursor = true; |
| Line 326... | Line 351... | ||
| 326 | 351 | ||
| 327 | if (newcons == KERNEL_CONSOLE) { |
352 | if (newcons == KERNEL_CONSOLE) { |
| 328 | async_serialize_start(); |
353 | async_serialize_start(); |
| 329 | curs_hide_sync(); |
354 | curs_hide_sync(); |
| 330 | gcons_in_kernel(); |
355 | gcons_in_kernel(); |
| - | 356 | screen_yield(); |
|
| - | 357 | kbd_yield(); |
|
| 331 | async_serialize_end(); |
358 | async_serialize_end(); |
| - | 359 | ||
| 332 | 360 | ||
| 333 | if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) { |
361 | if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) { |
| 334 | prev_console = active_console; |
362 | prev_console = active_console; |
| 335 | active_console = KERNEL_CONSOLE; |
363 | active_console = KERNEL_CONSOLE; |
| 336 | } else |
364 | } else |
| Line 338... | Line 366... | ||
| 338 | } |
366 | } |
| 339 | 367 | ||
| 340 | if (newcons != KERNEL_CONSOLE) { |
368 | if (newcons != KERNEL_CONSOLE) { |
| 341 | async_serialize_start(); |
369 | async_serialize_start(); |
| 342 | 370 | ||
| 343 | if (active_console == KERNEL_CONSOLE) |
371 | if (active_console == KERNEL_CONSOLE) { |
| - | 372 | screen_reclaim(); |
|
| - | 373 | kbd_reclaim(); |
|
| 344 | gcons_redraw_console(); |
374 | gcons_redraw_console(); |
| - | 375 | } |
|
| 345 | 376 | ||
| 346 | active_console = newcons; |
377 | active_console = newcons; |
| 347 | gcons_change_console(newcons); |
378 | gcons_change_console(newcons); |
| 348 | conn = &connections[active_console]; |
379 | conn = &connections[active_console]; |
| 349 | 380 | ||
| Line 432... | Line 463... | ||
| 432 | /* switch to another virtual console */ |
463 | /* switch to another virtual console */ |
| 433 | 464 | ||
| 434 | conn = &connections[active_console]; |
465 | conn = &connections[active_console]; |
| 435 | 466 | ||
| 436 | if ((ev.key >= KC_F1) && (ev.key < KC_F1 + |
467 | if ((ev.key >= KC_F1) && (ev.key < KC_F1 + |
| 437 | CONSOLE_COUNT)) { |
468 | CONSOLE_COUNT) && ((ev.mods & KM_CTRL) == 0)) { |
| 438 | if (ev.key == KC_F12) |
469 | if (ev.key == KC_F12) |
| 439 | change_console(KERNEL_CONSOLE); |
470 | change_console(KERNEL_CONSOLE); |
| 440 | else |
471 | else |
| 441 | change_console(ev.key - KC_F1); |
472 | change_console(ev.key - KC_F1); |
| 442 | break; |
473 | break; |
| Line 463... | Line 494... | ||
| 463 | 494 | ||
| 464 | /** Handle CONSOLE_WRITE call. */ |
495 | /** Handle CONSOLE_WRITE call. */ |
| 465 | static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request) |
496 | static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request) |
| 466 | { |
497 | { |
| 467 | ipc_callid_t callid; |
498 | ipc_callid_t callid; |
| 468 | size_t len; |
499 | size_t size; |
| - | 500 | wchar_t ch; |
|
| 469 | size_t i; |
501 | size_t off; |
| 470 | 502 | ||
| 471 | if (!ipc_data_write_receive(&callid, &len)) { |
503 | if (!ipc_data_write_receive(&callid, &size)) { |
| 472 | ipc_answer_0(callid, EINVAL); |
504 | ipc_answer_0(callid, EINVAL); |
| 473 | ipc_answer_0(rid, EINVAL); |
505 | ipc_answer_0(rid, EINVAL); |
| 474 | } |
506 | } |
| 475 | 507 | ||
| 476 | if (len > CWRITE_BUF_SIZE) |
508 | if (size > CWRITE_BUF_SIZE) |
| 477 | len = CWRITE_BUF_SIZE; |
509 | size = CWRITE_BUF_SIZE; |
| 478 | 510 | ||
| 479 | (void) ipc_data_write_finalize(callid, cwrite_buf, len); |
511 | (void) ipc_data_write_finalize(callid, cwrite_buf, size); |
| 480 | 512 | ||
| - | 513 | off = 0; |
|
| 481 | for (i = 0; i < len; i++) { |
514 | while (off < size) { |
| - | 515 | ch = str_decode(cwrite_buf, &off, size); |
|
| 482 | write_char(consnum, cwrite_buf[i]); |
516 | write_char(consnum, ch); |
| 483 | } |
517 | } |
| 484 | 518 | ||
| 485 | gcons_notify_char(consnum); |
519 | gcons_notify_char(consnum); |
| 486 | ipc_answer_1(rid, EOK, len); |
520 | ipc_answer_1(rid, EOK, size); |
| 487 | } |
521 | } |
| 488 | 522 | ||
| 489 | /** Default thread for new connections */ |
523 | /** Default thread for new connections */ |
| 490 | static void client_connection(ipc_callid_t iid, ipc_call_t *icall) |
524 | static void client_connection(ipc_callid_t iid, ipc_call_t *icall) |
| 491 | { |
525 | { |
| Line 505... | Line 539... | ||
| 505 | 539 | ||
| 506 | async_serialize_start(); |
540 | async_serialize_start(); |
| 507 | gcons_notify_connect(consnum); |
541 | gcons_notify_connect(consnum); |
| 508 | conn->client_phone = IPC_GET_ARG5(*icall); |
542 | conn->client_phone = IPC_GET_ARG5(*icall); |
| 509 | screenbuffer_clear(&conn->screenbuffer); |
543 | screenbuffer_clear(&conn->screenbuffer); |
| - | 544 | if (consnum == active_console) |
|
| - | 545 | clrscr(); |
|
| 510 | 546 | ||
| 511 | /* Accept the connection */ |
547 | /* Accept the connection */ |
| 512 | ipc_answer_0(iid, EOK); |
548 | ipc_answer_0(iid, EOK); |
| 513 | 549 | ||
| 514 | while (1) { |
550 | while (1) { |
| Line 642... | Line 678... | ||
| 642 | int main(int argc, char *argv[]) |
678 | int main(int argc, char *argv[]) |
| 643 | { |
679 | { |
| 644 | printf(NAME ": HelenOS Console service\n"); |
680 | printf(NAME ": HelenOS Console service\n"); |
| 645 | 681 | ||
| 646 | ipcarg_t phonehash; |
682 | ipcarg_t phonehash; |
| 647 | int kbd_phone; |
- | |
| 648 | size_t ib_size; |
683 | size_t ib_size; |
| 649 | int i; |
684 | int i; |
| 650 | 685 | ||
| 651 | async_set_client_connection(client_connection); |
686 | async_set_client_connection(client_connection); |
| 652 | 687 | ||