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 |