Rev 2479 | Rev 2566 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2479 | Rev 2539 | ||
|---|---|---|---|
| Line 65... | Line 65... | ||
| 65 | int phone; /**< Framebuffer phone */ |
65 | int phone; /**< Framebuffer phone */ |
| 66 | ipcarg_t rows; /**< Framebuffer rows */ |
66 | ipcarg_t rows; /**< Framebuffer rows */ |
| 67 | ipcarg_t cols; /**< Framebuffer columns */ |
67 | ipcarg_t cols; /**< Framebuffer columns */ |
| 68 | } fb_info; |
68 | } fb_info; |
| 69 | 69 | ||
| 70 | - | ||
| 71 | typedef struct { |
70 | typedef struct { |
| 72 | keybuffer_t keybuffer; /**< Buffer for incoming keys. */ |
71 | keybuffer_t keybuffer; /**< Buffer for incoming keys. */ |
| 73 | /** Buffer for unsatisfied request for keys. */ |
72 | /** Buffer for unsatisfied request for keys. */ |
| 74 | FIFO_CREATE_STATIC(keyrequests, ipc_callid_t, |
73 | FIFO_CREATE_STATIC(keyrequests, ipc_callid_t, |
| 75 | MAX_KEYREQUESTS_BUFFERED); |
74 | MAX_KEYREQUESTS_BUFFERED); |
| Line 122... | Line 121... | ||
| 122 | } |
121 | } |
| 123 | 122 | ||
| 124 | static void set_style(style_t *style) |
123 | static void set_style(style_t *style) |
| 125 | { |
124 | { |
| 126 | async_msg_2(fb_info.phone, FB_SET_STYLE, style->fg_color, |
125 | async_msg_2(fb_info.phone, FB_SET_STYLE, style->fg_color, |
| 127 | style->bg_color); |
126 | style->bg_color); |
| 128 | } |
127 | } |
| 129 | 128 | ||
| 130 | static void set_style_col(int fgcolor, int bgcolor) |
129 | static void set_style_col(int fgcolor, int bgcolor) |
| 131 | { |
130 | { |
| 132 | async_msg_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor); |
131 | async_msg_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor); |
| Line 258... | Line 257... | ||
| 258 | 257 | ||
| 259 | set_style(&conn->screenbuffer.style); |
258 | set_style(&conn->screenbuffer.style); |
| 260 | curs_visibility(0); |
259 | curs_visibility(0); |
| 261 | if (interbuffer) { |
260 | if (interbuffer) { |
| 262 | for (i = 0; i < conn->screenbuffer.size_x; i++) |
261 | for (i = 0; i < conn->screenbuffer.size_x; i++) |
| 263 | for (j = 0; j < conn->screenbuffer.size_y; j++) |
262 | for (j = 0; j < conn->screenbuffer.size_y; j++) { |
| - | 263 | unsigned int size_x; |
|
| - | 264 | ||
| 264 | interbuffer[i + j * conn->screenbuffer.size_x] = |
265 | size_x = conn->screenbuffer.size_x; |
| - | 266 | interbuffer[i + j * size_x] = |
|
| 265 | *get_field_at(&(conn->screenbuffer), |
267 | *get_field_at(&conn->screenbuffer, i, j); |
| 266 | i, j); |
268 | } |
| 267 | /* This call can preempt, but we are already at the end */ |
269 | /* This call can preempt, but we are already at the end */ |
| 268 | rc = async_req_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, |
270 | rc = async_req_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, |
| 269 | NULL); |
271 | NULL); |
| 270 | }; |
272 | } |
| 271 | 273 | ||
| 272 | if ((!interbuffer) || (rc != 0)) { |
274 | if ((!interbuffer) || (rc != 0)) { |
| 273 | set_style(&conn->screenbuffer.style); |
275 | set_style(&conn->screenbuffer.style); |
| 274 | clrscr(); |
276 | clrscr(); |
| 275 | style = &conn->screenbuffer.style; |
277 | style = &conn->screenbuffer.style; |
| 276 | 278 | ||
| 277 | for (j = 0; j < conn->screenbuffer.size_y; j++) |
279 | for (j = 0; j < conn->screenbuffer.size_y; j++) |
| 278 | for (i = 0; i < conn->screenbuffer.size_x; i++) { |
280 | for (i = 0; i < conn->screenbuffer.size_x; i++) { |
| 279 | field = get_field_at(&(conn->screenbuffer), i, |
281 | field = get_field_at(&conn->screenbuffer, i, |
| 280 | j); |
282 | j); |
| 281 | if (!style_same(*style, field->style)) |
283 | if (!style_same(*style, field->style)) |
| 282 | set_style(&field->style); |
284 | set_style(&field->style); |
| 283 | style = &field->style; |
285 | style = &field->style; |
| 284 | if ((field->character == ' ') && |
286 | if ((field->character == ' ') && |
| 285 | (style_same(field->style, |
287 | (style_same(field->style, |
| 286 | conn->screenbuffer.style))) |
288 | conn->screenbuffer.style))) |
| 287 | continue; |
289 | continue; |
| 288 | 290 | ||
| 289 | prtchr(field->character, j, i); |
291 | prtchr(field->character, j, i); |
| 290 | } |
292 | } |
| 291 | } |
293 | } |
| 292 | 294 | ||
| 293 | curs_goto(conn->screenbuffer.position_y, |
295 | curs_goto(conn->screenbuffer.position_y, |
| 294 | conn->screenbuffer.position_x); |
296 | conn->screenbuffer.position_x); |
| 295 | curs_visibility(conn->screenbuffer.is_cursor_visible); |
297 | curs_visibility(conn->screenbuffer.is_cursor_visible); |
| 296 | 298 | ||
| 297 | async_serialize_end(); |
299 | async_serialize_end(); |
| 298 | } |
300 | } |
| 299 | 301 | ||
| Line 320... | Line 322... | ||
| 320 | change_console(newcon); |
322 | change_console(newcon); |
| 321 | retval = 0; |
323 | retval = 0; |
| 322 | break; |
324 | break; |
| 323 | case KBD_MS_MOVE: |
325 | case KBD_MS_MOVE: |
| 324 | gcons_mouse_move(IPC_GET_ARG1(call), |
326 | gcons_mouse_move(IPC_GET_ARG1(call), |
| 325 | IPC_GET_ARG2(call)); |
327 | IPC_GET_ARG2(call)); |
| 326 | retval = 0; |
328 | retval = 0; |
| 327 | break; |
329 | break; |
| 328 | case KBD_PUSHCHAR: |
330 | case KBD_PUSHCHAR: |
| 329 | /* got key from keyboard driver */ |
331 | /* got key from keyboard driver */ |
| 330 | 332 | ||
| Line 347... | Line 349... | ||
| 347 | 349 | ||
| 348 | /* if client is awaiting key, send it */ |
350 | /* if client is awaiting key, send it */ |
| 349 | if (conn->keyrequest_counter > 0) { |
351 | if (conn->keyrequest_counter > 0) { |
| 350 | conn->keyrequest_counter--; |
352 | conn->keyrequest_counter--; |
| 351 | ipc_answer_fast(fifo_pop(conn->keyrequests), 0, |
353 | ipc_answer_fast(fifo_pop(conn->keyrequests), 0, |
| 352 | c, 0); |
354 | c, 0); |
| 353 | break; |
355 | break; |
| 354 | } |
356 | } |
| 355 | 357 | ||
| 356 | keybuffer_push(&conn->keybuffer, c); |
358 | keybuffer_push(&conn->keybuffer, c); |
| 357 | retval = 0; |
359 | retval = 0; |
| Line 400... | Line 402... | ||
| 400 | 402 | ||
| 401 | /* Answer all pending requests */ |
403 | /* Answer all pending requests */ |
| 402 | while (conn->keyrequest_counter > 0) { |
404 | while (conn->keyrequest_counter > 0) { |
| 403 | conn->keyrequest_counter--; |
405 | conn->keyrequest_counter--; |
| 404 | ipc_answer_fast(fifo_pop(conn->keyrequests), |
406 | ipc_answer_fast(fifo_pop(conn->keyrequests), |
| 405 | ENOENT, 0, 0); |
407 | ENOENT, 0, 0); |
| 406 | break; |
408 | break; |
| 407 | } |
409 | } |
| 408 | conn->used = 0; |
410 | conn->used = 0; |
| 409 | return; |
411 | return; |
| 410 | case CONSOLE_PUTCHAR: |
412 | case CONSOLE_PUTCHAR: |
| Line 420... | Line 422... | ||
| 420 | screenbuffer_clear(&conn->screenbuffer); |
422 | screenbuffer_clear(&conn->screenbuffer); |
| 421 | 423 | ||
| 422 | break; |
424 | break; |
| 423 | case CONSOLE_GOTO: |
425 | case CONSOLE_GOTO: |
| 424 | screenbuffer_goto(&conn->screenbuffer, |
426 | screenbuffer_goto(&conn->screenbuffer, |
| 425 | IPC_GET_ARG2(call), IPC_GET_ARG1(call)); |
427 | IPC_GET_ARG2(call), IPC_GET_ARG1(call)); |
| 426 | if (consnum == active_console) |
428 | if (consnum == active_console) |
| 427 | curs_goto(IPC_GET_ARG1(call), |
429 | curs_goto(IPC_GET_ARG1(call), |
| 428 | IPC_GET_ARG2(call)); |
430 | IPC_GET_ARG2(call)); |
| 429 | break; |
431 | break; |
| 430 | case CONSOLE_GETSIZE: |
432 | case CONSOLE_GETSIZE: |
| 431 | arg1 = fb_info.rows; |
433 | arg1 = fb_info.rows; |
| 432 | arg2 = fb_info.cols; |
434 | arg2 = fb_info.cols; |
| 433 | break; |
435 | break; |
| 434 | case CONSOLE_FLUSH: |
436 | case CONSOLE_FLUSH: |
| 435 | if (consnum == active_console) |
437 | if (consnum == active_console) |
| 436 | async_req_2(fb_info.phone, FB_FLUSH, 0, 0, |
438 | async_req_2(fb_info.phone, FB_FLUSH, 0, 0, |
| 437 | NULL, NULL); |
439 | NULL, NULL); |
| 438 | break; |
440 | break; |
| 439 | case CONSOLE_SET_STYLE: |
441 | case CONSOLE_SET_STYLE: |
| 440 | arg1 = IPC_GET_ARG1(call); |
442 | arg1 = IPC_GET_ARG1(call); |
| 441 | arg2 = IPC_GET_ARG2(call); |
443 | arg2 = IPC_GET_ARG2(call); |
| 442 | screenbuffer_set_style(&conn->screenbuffer, arg1, arg2); |
444 | screenbuffer_set_style(&conn->screenbuffer, arg1, |
| - | 445 | arg2); |
|
| 443 | if (consnum == active_console) |
446 | if (consnum == active_console) |
| 444 | set_style_col(arg1, arg2); |
447 | set_style_col(arg1, arg2); |
| 445 | break; |
448 | break; |
| 446 | case CONSOLE_CURSOR_VISIBILITY: |
449 | case CONSOLE_CURSOR_VISIBILITY: |
| 447 | arg1 = IPC_GET_ARG1(call); |
450 | arg1 = IPC_GET_ARG1(call); |
| Line 508... | Line 511... | ||
| 508 | /* Synchronize, the gcons can have something in queue */ |
511 | /* Synchronize, the gcons can have something in queue */ |
| 509 | async_req(fb_info.phone, FB_FLUSH, 0, NULL); |
512 | async_req(fb_info.phone, FB_FLUSH, 0, NULL); |
| 510 | /* Enable double buffering */ |
513 | /* Enable double buffering */ |
| 511 | async_msg_2(fb_info.phone, FB_VIEWPORT_DB, (sysarg_t) -1, 1); |
514 | async_msg_2(fb_info.phone, FB_VIEWPORT_DB, (sysarg_t) -1, 1); |
| 512 | 515 | ||
| 513 | async_req_2(fb_info.phone, FB_GET_CSIZE, 0, 0, &(fb_info.rows), |
516 | async_req_2(fb_info.phone, FB_GET_CSIZE, 0, 0, &fb_info.rows, |
| 514 | &(fb_info.cols)); |
517 | &fb_info.cols); |
| 515 | set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
518 | set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
| 516 | clrscr(); |
519 | clrscr(); |
| 517 | 520 | ||
| 518 | /* Init virtual consoles */ |
521 | /* Init virtual consoles */ |
| 519 | for (i = 0; i < CONSOLE_COUNT; i++) { |
522 | for (i = 0; i < CONSOLE_COUNT; i++) { |
| 520 | connections[i].used = 0; |
523 | connections[i].used = 0; |
| 521 | keybuffer_init(&(connections[i].keybuffer)); |
524 | keybuffer_init(&connections[i].keybuffer); |
| 522 | 525 | ||
| 523 | connections[i].keyrequests.head = |
526 | connections[i].keyrequests.head = 0; |
| 524 | connections[i].keyrequests.tail = 0; |
527 | connections[i].keyrequests.tail = 0; |
| 525 | connections[i].keyrequests.items = MAX_KEYREQUESTS_BUFFERED; |
528 | connections[i].keyrequests.items = MAX_KEYREQUESTS_BUFFERED; |
| 526 | connections[i].keyrequest_counter = 0; |
529 | connections[i].keyrequest_counter = 0; |
| 527 | 530 | ||
| 528 | if (screenbuffer_init(&(connections[i].screenbuffer), |
531 | if (screenbuffer_init(&connections[i].screenbuffer, |
| 529 | fb_info.cols, fb_info.rows) == NULL) { |
532 | fb_info.cols, fb_info.rows) == NULL) { |
| 530 | /* FIXME: handle error */ |
533 | /* FIXME: handle error */ |
| 531 | return -1; |
534 | return -1; |
| 532 | } |
535 | } |
| 533 | } |
536 | } |
| 534 | connections[KERNEL_CONSOLE].used = 1; |
537 | connections[KERNEL_CONSOLE].used = 1; |
| 535 | 538 | ||
| 536 | interbuffer = mmap(NULL, |
539 | interbuffer = mmap(NULL, |
| 537 | sizeof(keyfield_t) * fb_info.cols * fb_info.rows, |
540 | sizeof(keyfield_t) * fb_info.cols * fb_info.rows, |
| 538 | PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
541 | PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
| 539 | if (!interbuffer) { |
542 | if (!interbuffer) { |
| 540 | if (async_req_3(fb_info.phone, IPC_M_AS_AREA_SEND, (ipcarg_t) |
543 | if (async_req_3(fb_info.phone, IPC_M_AS_AREA_SEND, |
| 541 | interbuffer, 0, AS_AREA_READ, NULL, NULL, NULL) != 0) { |
544 | (ipcarg_t) interbuffer, 0, AS_AREA_READ, NULL, NULL, |
| - | 545 | NULL) != 0) { |
|
| 542 | munmap(interbuffer, sizeof(keyfield_t) * fb_info.cols |
546 | munmap(interbuffer, |
| 543 | * fb_info.rows); |
547 | sizeof(keyfield_t) * fb_info.cols * fb_info.rows); |
| 544 | interbuffer = NULL; |
548 | interbuffer = NULL; |
| 545 | } |
549 | } |
| 546 | } |
550 | } |
| 547 | 551 | ||
| 548 | curs_goto(0, 0); |
552 | curs_goto(0, 0); |
| - | 553 | curs_visibility( |
|
| 549 | curs_visibility(connections[active_console].screenbuffer.is_cursor_visible); |
554 | connections[active_console].screenbuffer.is_cursor_visible); |
| 550 | 555 | ||
| 551 | /* Register at NS */ |
556 | /* Register at NS */ |
| 552 | if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, &phonehash) != 0) { |
557 | if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, &phonehash) != 0) { |
| 553 | return -1; |
558 | return -1; |
| 554 | } |
559 | } |