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 */ |