Rev 1547 | Rev 1555 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1547 | Rev 1552 | ||
|---|---|---|---|
| Line 81... | Line 81... | ||
| 81 | /* Auto-cursor position */ |
81 | /* Auto-cursor position */ |
| 82 | int cursor_active, cur_col, cur_row; |
82 | int cursor_active, cur_col, cur_row; |
| 83 | int cursor_shown; |
83 | int cursor_shown; |
| 84 | } viewport_t; |
84 | } viewport_t; |
| 85 | 85 | ||
| - | 86 | /** Maximum number of saved pixmaps |
|
| - | 87 | * Pixmap is a saved rectangle |
|
| - | 88 | */ |
|
| - | 89 | #define MAX_PIXMAPS 256 |
|
| - | 90 | typedef struct { |
|
| - | 91 | unsigned int width; |
|
| - | 92 | unsigned int height; |
|
| - | 93 | void *data; |
|
| - | 94 | } pixmap_t; |
|
| - | 95 | static pixmap_t pixmaps[MAX_PIXMAPS]; |
|
| - | 96 | ||
| - | 97 | /* Viewport is a rectangular area on the screen */ |
|
| 86 | #define MAX_VIEWPORTS 128 |
98 | #define MAX_VIEWPORTS 128 |
| 87 | static viewport_t viewports[128]; |
99 | static viewport_t viewports[128]; |
| 88 | 100 | ||
| 89 | /* Allow only 1 connection */ |
101 | /* Allow only 1 connection */ |
| 90 | static int client_connected = 0; |
102 | static int client_connected = 0; |
| Line 284... | Line 296... | ||
| 284 | for (x = 0; x < COL_WIDTH; x++) |
296 | for (x = 0; x < COL_WIDTH; x++) |
| 285 | for (y = 0; y < FONT_SCANLINES; y++) |
297 | for (y = 0; y < FONT_SCANLINES; y++) |
| 286 | invert_pixel(vp, col * COL_WIDTH + x, row * FONT_SCANLINES + y); |
298 | invert_pixel(vp, col * COL_WIDTH + x, row * FONT_SCANLINES + y); |
| 287 | } |
299 | } |
| 288 | 300 | ||
| 289 | static void draw_logo(int vp,unsigned int startx, unsigned int starty) |
- | |
| 290 | { |
- | |
| 291 | unsigned int x; |
- | |
| 292 | unsigned int y; |
- | |
| 293 | unsigned int byte; |
- | |
| 294 | unsigned int rowbytes; |
- | |
| 295 | - | ||
| 296 | rowbytes = (helenos_width - 1) / 8 + 1; |
- | |
| 297 | - | ||
| 298 | for (y = 0; y < helenos_height; y++) |
- | |
| 299 | for (x = 0; x < helenos_width; x++) { |
- | |
| 300 | byte = helenos_bits[rowbytes * y + x / 8]; |
- | |
| 301 | byte >>= x % 8; |
- | |
| 302 | if (byte & 1) |
- | |
| 303 | putpixel(vp ,startx + x, starty + y, viewports[vp].style.fg_color); |
- | |
| 304 | } |
- | |
| 305 | } |
- | |
| 306 | - | ||
| 307 | /***************************************************************/ |
301 | /***************************************************************/ |
| 308 | /* Stdout specific functions */ |
302 | /* Stdout specific functions */ |
| 309 | 303 | ||
| 310 | 304 | ||
| 311 | /** Create new viewport |
305 | /** Create new viewport |
| Line 393... | Line 387... | ||
| 393 | 387 | ||
| 394 | /* Create first viewport */ |
388 | /* Create first viewport */ |
| 395 | viewport_create(0,0,xres,yres); |
389 | viewport_create(0,0,xres,yres); |
| 396 | } |
390 | } |
| 397 | 391 | ||
| - | 392 | /** Hide cursor if it is shown */ |
|
| 398 | static void cursor_hide(int vp) |
393 | static void cursor_hide(int vp) |
| 399 | { |
394 | { |
| 400 | viewport_t *vport = &viewports[vp]; |
395 | viewport_t *vport = &viewports[vp]; |
| 401 | 396 | ||
| 402 | if (vport->cursor_active && vport->cursor_shown) { |
397 | if (vport->cursor_active && vport->cursor_shown) { |
| 403 | invert_char(vp, vport->cur_row, vport->cur_col); |
398 | invert_char(vp, vport->cur_row, vport->cur_col); |
| 404 | vport->cursor_shown = 0; |
399 | vport->cursor_shown = 0; |
| 405 | } |
400 | } |
| 406 | } |
401 | } |
| 407 | 402 | ||
| - | 403 | /** Show cursor if cursor showing is enabled */ |
|
| 408 | static void cursor_print(int vp) |
404 | static void cursor_print(int vp) |
| 409 | { |
405 | { |
| 410 | viewport_t *vport = &viewports[vp]; |
406 | viewport_t *vport = &viewports[vp]; |
| 411 | 407 | ||
| 412 | /* Do not check for cursor_shown */ |
408 | /* Do not check for cursor_shown */ |
| Line 414... | Line 410... | ||
| 414 | invert_char(vp, vport->cur_row, vport->cur_col); |
410 | invert_char(vp, vport->cur_row, vport->cur_col); |
| 415 | vport->cursor_shown = 1; |
411 | vport->cursor_shown = 1; |
| 416 | } |
412 | } |
| 417 | } |
413 | } |
| 418 | 414 | ||
| - | 415 | /** Invert cursor, if it is enabled */ |
|
| 419 | static void cursor_blink(int vp) |
416 | static void cursor_blink(int vp) |
| 420 | { |
417 | { |
| 421 | viewport_t *vport = &viewports[vp]; |
418 | viewport_t *vport = &viewports[vp]; |
| 422 | 419 | ||
| 423 | if (vport->cursor_shown) |
420 | if (vport->cursor_shown) |
| Line 455... | Line 452... | ||
| 455 | vport->cur_row--; |
452 | vport->cur_row--; |
| 456 | } |
453 | } |
| 457 | cursor_print(vp); |
454 | cursor_print(vp); |
| 458 | } |
455 | } |
| 459 | 456 | ||
| - | 457 | /** Draw text data to viewport |
|
| - | 458 | * |
|
| - | 459 | * @param vp Viewport id |
|
| - | 460 | * @param data Text data fitting exactly into viewport |
|
| - | 461 | */ |
|
| 460 | static void draw_text_data(int vp, keyfield_t *data) |
462 | static void draw_text_data(int vp, keyfield_t *data) |
| 461 | { |
463 | { |
| 462 | viewport_t *vport = &viewports[vp]; |
464 | viewport_t *vport = &viewports[vp]; |
| 463 | int i; |
465 | int i; |
| 464 | char c; |
466 | char c; |
| Line 473... | Line 475... | ||
| 473 | draw_glyph(vp, data[i].character, col * COL_WIDTH, row * FONT_SCANLINES, data[i].style); |
475 | draw_glyph(vp, data[i].character, col * COL_WIDTH, row * FONT_SCANLINES, data[i].style); |
| 474 | } |
476 | } |
| 475 | cursor_print(vp); |
477 | cursor_print(vp); |
| 476 | } |
478 | } |
| 477 | 479 | ||
| - | 480 | /** Handle shared memory communication calls |
|
| - | 481 | * |
|
| - | 482 | * Protocol for drawing pixmaps: |
|
| - | 483 | * - FB_PREPARE_SHM(client shm identification) |
|
| - | 484 | * - IPC_M_SEND_AS_AREA |
|
| - | 485 | * - FB_DRAW_PPM(startx,starty) |
|
| - | 486 | * - FB_DROP_SHM |
|
| - | 487 | * |
|
| - | 488 | * Protocol for text drawing |
|
| - | 489 | * - IPC_M_SEND_AS_AREA |
|
| - | 490 | * - FB_DRAW_TEXT_DATA |
|
| - | 491 | * |
|
| - | 492 | * @param callid Callid of the current call |
|
| - | 493 | * @param call Current call data |
|
| - | 494 | * @param vp Active viewport |
|
| - | 495 | * @return 0 if the call was not handled byt this function, 1 otherwise |
|
| - | 496 | * |
|
| - | 497 | * note: this function is not threads safe, you would have |
|
| - | 498 | * to redefine static variables with __thread |
|
| - | 499 | */ |
|
| 478 | static int shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp) |
500 | static int shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp) |
| 479 | { |
501 | { |
| 480 | static keyfield_t *interbuffer = NULL; |
502 | static keyfield_t *interbuffer = NULL; |
| 481 | static size_t intersize = 0; |
503 | static size_t intersize = 0; |
| 482 | 504 | ||
| Line 556... | Line 578... | ||
| 556 | if (handled) |
578 | if (handled) |
| 557 | ipc_answer_fast(callid, retval, 0, 0); |
579 | ipc_answer_fast(callid, retval, 0, 0); |
| 558 | return handled; |
580 | return handled; |
| 559 | } |
581 | } |
| 560 | 582 | ||
| - | 583 | /** Return first free pixmap */ |
|
| - | 584 | static int find_free_pixmap(void) |
|
| - | 585 | { |
|
| - | 586 | int i; |
|
| - | 587 | ||
| - | 588 | for (i=0;i < MAX_PIXMAPS;i++) |
|
| - | 589 | if (!pixmaps[i].data) |
|
| - | 590 | return i; |
|
| - | 591 | return -1; |
|
| - | 592 | } |
|
| - | 593 | ||
| - | 594 | /** Save viewport to pixmap */ |
|
| - | 595 | static int save_vp_to_pixmap(int vp) |
|
| - | 596 | { |
|
| - | 597 | int pm; |
|
| - | 598 | pixmap_t *pmap; |
|
| - | 599 | viewport_t *vport = &viewports[vp]; |
|
| - | 600 | int x,y; |
|
| - | 601 | int rowsize; |
|
| - | 602 | int tmp; |
|
| - | 603 | ||
| - | 604 | pm = find_free_pixmap(); |
|
| - | 605 | if (pm == -1) |
|
| - | 606 | return ELIMIT; |
|
| - | 607 | ||
| - | 608 | pmap = &pixmaps[pm]; |
|
| - | 609 | pmap->data = malloc(screen.pixelbytes * vport->width * vport->height); |
|
| - | 610 | if (!pmap->data) |
|
| - | 611 | return ENOMEM; |
|
| - | 612 | ||
| - | 613 | pmap->width = vport->width; |
|
| - | 614 | pmap->height = vport->height; |
|
| - | 615 | ||
| - | 616 | rowsize = vport->width * screen.pixelbytes; |
|
| - | 617 | for (y=0;y < vport->height; y++) { |
|
| - | 618 | tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes; |
|
| - | 619 | memcpy(pmap->data + rowsize*y, screen.fbaddress + tmp, rowsize); |
|
| - | 620 | } |
|
| - | 621 | return pm; |
|
| - | 622 | } |
|
| - | 623 | ||
| - | 624 | /** Draw pixmap on screen |
|
| - | 625 | * |
|
| - | 626 | * @param vp Viewport to draw on |
|
| - | 627 | * @param pm Pixmap identifier |
|
| - | 628 | */ |
|
| - | 629 | static int draw_pixmap(int vp, int pm) |
|
| - | 630 | { |
|
| - | 631 | pixmap_t *pmap = &pixmaps[pm]; |
|
| - | 632 | viewport_t *vport = &viewports[vp]; |
|
| - | 633 | int x,y; |
|
| - | 634 | int tmp, srcrowsize; |
|
| - | 635 | int realwidth, realheight, realrowsize; |
|
| - | 636 | ||
| - | 637 | if (!pmap->data) |
|
| - | 638 | return EINVAL; |
|
| - | 639 | ||
| - | 640 | realwidth = pmap->width <= vport->width ? pmap->width : vport->width; |
|
| - | 641 | realheight = pmap->height <= vport->height ? pmap->height : vport->height; |
|
| - | 642 | ||
| - | 643 | srcrowsize = vport->width * screen.pixelbytes; |
|
| - | 644 | realrowsize = realwidth * screen.pixelbytes; |
|
| - | 645 | ||
| - | 646 | for (y=0; y < realheight; y++) { |
|
| - | 647 | tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes; |
|
| - | 648 | memcpy(screen.fbaddress + tmp, pmap->data + y * srcrowsize, realrowsize); |
|
| - | 649 | } |
|
| - | 650 | } |
|
| - | 651 | ||
| - | 652 | /** Handler for messages concerning pixmap handling */ |
|
| - | 653 | static int pixmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp) |
|
| - | 654 | { |
|
| - | 655 | int handled = 1; |
|
| - | 656 | int retval = 0; |
|
| - | 657 | int i,nvp; |
|
| - | 658 | ||
| - | 659 | switch (IPC_GET_METHOD(*call)) { |
|
| - | 660 | case FB_VP_DRAW_PIXMAP: |
|
| - | 661 | nvp = IPC_GET_ARG1(*call); |
|
| - | 662 | if (nvp == -1) |
|
| - | 663 | nvp = vp; |
|
| - | 664 | if (nvp < 0 || nvp >= MAX_VIEWPORTS || !viewports[nvp].initialized) { |
|
| - | 665 | retval = EINVAL; |
|
| - | 666 | break; |
|
| - | 667 | } |
|
| - | 668 | i = IPC_GET_ARG2(*call); |
|
| - | 669 | retval = draw_pixmap(nvp, i); |
|
| - | 670 | break; |
|
| - | 671 | case FB_VP2PIXMAP: |
|
| - | 672 | nvp = IPC_GET_ARG1(*call); |
|
| - | 673 | if (nvp == -1) |
|
| - | 674 | nvp = vp; |
|
| - | 675 | if (nvp < 0 || nvp >= MAX_VIEWPORTS || !viewports[nvp].initialized) |
|
| - | 676 | retval = EINVAL; |
|
| - | 677 | else |
|
| - | 678 | retval = save_vp_to_pixmap(nvp); |
|
| - | 679 | break; |
|
| - | 680 | case FB_DROP_PIXMAP: |
|
| - | 681 | i = IPC_GET_ARG1(*call); |
|
| - | 682 | if (i >= MAX_PIXMAPS) { |
|
| - | 683 | retval = EINVAL; |
|
| - | 684 | break; |
|
| - | 685 | } |
|
| - | 686 | if (pixmaps[i].data) { |
|
| - | 687 | free(pixmaps[i].data); |
|
| - | 688 | pixmaps[i].data = NULL; |
|
| - | 689 | } |
|
| - | 690 | break; |
|
| - | 691 | default: |
|
| - | 692 | handled = 0; |
|
| - | 693 | } |
|
| - | 694 | ||
| - | 695 | if (handled) |
|
| - | 696 | ipc_answer_fast(callid, retval, 0, 0); |
|
| - | 697 | return handled; |
|
| - | 698 | ||
| - | 699 | } |
|
| - | 700 | ||
| 561 | /** Function for handling connections to FB |
701 | /** Function for handling connections to FB |
| 562 | * |
702 | * |
| 563 | */ |
703 | */ |
| 564 | static void fb_client_connection(ipc_callid_t iid, ipc_call_t *icall) |
704 | static void fb_client_connection(ipc_callid_t iid, ipc_call_t *icall) |
| 565 | { |
705 | { |
| Line 586... | Line 726... | ||
| 586 | cursor_blink(vp); |
726 | cursor_blink(vp); |
| 587 | continue; |
727 | continue; |
| 588 | } |
728 | } |
| 589 | if (shm_handle(callid, &call, vp)) |
729 | if (shm_handle(callid, &call, vp)) |
| 590 | continue; |
730 | continue; |
| - | 731 | if (pixmap_handle(callid, &call, vp)) |
|
| - | 732 | continue; |
|
| 591 | 733 | ||
| 592 | switch (IPC_GET_METHOD(call)) { |
734 | switch (IPC_GET_METHOD(call)) { |
| 593 | case IPC_M_PHONE_HUNGUP: |
735 | case IPC_M_PHONE_HUNGUP: |
| 594 | client_connected = 0; |
736 | client_connected = 0; |
| 595 | /* cleanup other viewports */ |
737 | /* cleanup other viewports */ |