Rev 3739 | Rev 3767 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3739 | Rev 3744 | ||
|---|---|---|---|
| Line 69... | Line 69... | ||
| 69 | #define MAX_ANIM_LEN 8 |
69 | #define MAX_ANIM_LEN 8 |
| 70 | #define MAX_ANIMATIONS 4 |
70 | #define MAX_ANIMATIONS 4 |
| 71 | #define MAX_PIXMAPS 256 /**< Maximum number of saved pixmaps */ |
71 | #define MAX_PIXMAPS 256 /**< Maximum number of saved pixmaps */ |
| 72 | #define MAX_VIEWPORTS 128 /**< Viewport is a rectangular area on the screen */ |
72 | #define MAX_VIEWPORTS 128 /**< Viewport is a rectangular area on the screen */ |
| 73 | 73 | ||
| - | 74 | /** Function to render a pixel from a RGB value. */ |
|
| 74 | typedef void (*rgb_conv_t)(void *, uint32_t); |
75 | typedef void (*rgb_conv_t)(void *, uint32_t); |
| 75 | 76 | ||
| - | 77 | /** Function to draw a glyph. */ |
|
| - | 78 | typedef void (*dg_t)(unsigned int x, unsigned int y, bool cursor, |
|
| - | 79 | uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color); |
|
| - | 80 | ||
| 76 | struct { |
81 | struct { |
| 77 | uint8_t *fb_addr; |
82 | uint8_t *fb_addr; |
| 78 | 83 | ||
| 79 | unsigned int xres; |
84 | unsigned int xres; |
| 80 | unsigned int yres; |
85 | unsigned int yres; |
| Line 97... | Line 102... | ||
| 97 | 102 | ||
| 98 | /* Text support in window */ |
103 | /* Text support in window */ |
| 99 | unsigned int cols; |
104 | unsigned int cols; |
| 100 | unsigned int rows; |
105 | unsigned int rows; |
| 101 | 106 | ||
| - | 107 | /* |
|
| 102 | /* Style and glyphs for text printing */ |
108 | * Style and glyphs for text printing |
| - | 109 | */ |
|
| - | 110 | ||
| - | 111 | /** Current style. */ |
|
| 103 | style_t style; |
112 | style_t style; |
| - | 113 | ||
| - | 114 | /** Pre-rendered mask for rendering glyphs. Different viewports |
|
| - | 115 | * might use different drawing functions depending on whether their |
|
| - | 116 | * scanlines are aligned on a word boundary.*/ |
|
| 104 | uint8_t *glyphs; |
117 | uint8_t *glyphs; |
| - | 118 | ||
| 105 | uint8_t *bgpixel; |
119 | uint8_t *bgpixel; |
| - | 120 | ||
| - | 121 | /** Glyph drawing function for this viewport. */ |
|
| - | 122 | dg_t dglyph; |
|
| 106 | 123 | ||
| 107 | /* Auto-cursor position */ |
124 | /* Auto-cursor position */ |
| 108 | bool cursor_active; |
125 | bool cursor_active; |
| 109 | unsigned int cur_col; |
126 | unsigned int cur_col; |
| 110 | unsigned int cur_row; |
127 | unsigned int cur_row; |
| Line 137... | Line 154... | ||
| 137 | static pixmap_t pixmaps[MAX_PIXMAPS]; |
154 | static pixmap_t pixmaps[MAX_PIXMAPS]; |
| 138 | static viewport_t viewports[128]; |
155 | static viewport_t viewports[128]; |
| 139 | 156 | ||
| 140 | static bool client_connected = false; /**< Allow only 1 connection */ |
157 | static bool client_connected = false; /**< Allow only 1 connection */ |
| 141 | 158 | ||
| 142 | static void draw_glyph(unsigned int x, unsigned int y, bool cursor, |
159 | static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor, |
| - | 160 | uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color); |
|
| - | 161 | static void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor, |
|
| 143 | uint8_t *glyphs, uint8_t glyph); |
162 | uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color); |
| - | 163 | ||
| 144 | static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col, |
164 | static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col, |
| 145 | unsigned int row); |
165 | unsigned int row); |
| 146 | 166 | ||
| 147 | 167 | ||
| 148 | #define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
168 | #define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
| Line 331... | Line 351... | ||
| 331 | } |
351 | } |
| 332 | } else { |
352 | } else { |
| 333 | glyph = 0; |
353 | glyph = 0; |
| 334 | } |
354 | } |
| 335 | 355 | ||
| 336 | draw_glyph(x, y, false, vport->glyphs, glyph); |
356 | (*vport->dglyph)(x, y, false, vport->glyphs, glyph, |
| - | 357 | vport->style.fg_color, vport->style.bg_color); |
|
| 337 | x += FONT_WIDTH; |
358 | x += FONT_WIDTH; |
| 338 | } |
359 | } |
| 339 | y += FONT_SCANLINES; |
360 | y += FONT_SCANLINES; |
| 340 | } |
361 | } |
| 341 | 362 | ||
| Line 374... | Line 395... | ||
| 374 | unsigned int x; |
395 | unsigned int x; |
| 375 | 396 | ||
| 376 | for (x = 0; x < FONT_WIDTH; x++) { |
397 | for (x = 0; x < FONT_WIDTH; x++) { |
| 377 | screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes], |
398 | screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes], |
| 378 | (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) |
399 | (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) |
| 379 | ? vport->style.fg_color : vport->style.bg_color); |
- | |
| 380 | - | ||
| 381 | uint32_t curcolor; |
400 | ? 0xffffff : 0x000000); |
| 382 | 401 | ||
| 383 | if (y < FONT_SCANLINES - 2) |
402 | screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes], |
| 384 | curcolor = |
- | |
| 385 | (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) |
403 | (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) |
| 386 | ? vport->style.fg_color : vport->style.bg_color; |
- | |
| 387 | else |
- | |
| 388 | curcolor = vport->style.fg_color; |
404 | ? 0x000000 : 0xffffff); |
| 389 | - | ||
| 390 | screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes], curcolor); |
- | |
| 391 | } |
405 | } |
| 392 | } |
406 | } |
| 393 | } |
407 | } |
| 394 | 408 | ||
| 395 | screen.rgb_conv(vport->bgpixel, vport->style.bg_color); |
409 | screen.rgb_conv(vport->bgpixel, vport->style.bg_color); |
| Line 420... | Line 434... | ||
| 420 | 434 | ||
| 421 | unsigned int cols = width / FONT_WIDTH; |
435 | unsigned int cols = width / FONT_WIDTH; |
| 422 | unsigned int rows = height / FONT_SCANLINES; |
436 | unsigned int rows = height / FONT_SCANLINES; |
| 423 | unsigned int bbsize = cols * rows; |
437 | unsigned int bbsize = cols * rows; |
| 424 | unsigned int glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes; |
438 | unsigned int glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes; |
| - | 439 | unsigned int word_size = sizeof(unsigned long); |
|
| 425 | 440 | ||
| 426 | uint8_t *backbuf = (uint8_t *) malloc(bbsize); |
441 | uint8_t *backbuf = (uint8_t *) malloc(bbsize); |
| 427 | if (!backbuf) |
442 | if (!backbuf) |
| 428 | return ENOMEM; |
443 | return ENOMEM; |
| 429 | 444 | ||
| Line 455... | Line 470... | ||
| 455 | viewports[i].style.bg_color = DEFAULT_BGCOLOR; |
470 | viewports[i].style.bg_color = DEFAULT_BGCOLOR; |
| 456 | viewports[i].style.fg_color = DEFAULT_FGCOLOR; |
471 | viewports[i].style.fg_color = DEFAULT_FGCOLOR; |
| 457 | 472 | ||
| 458 | viewports[i].glyphs = glyphs; |
473 | viewports[i].glyphs = glyphs; |
| 459 | viewports[i].bgpixel = bgpixel; |
474 | viewports[i].bgpixel = bgpixel; |
| - | 475 | ||
| - | 476 | /* |
|
| - | 477 | * Conditions necessary to select aligned version: |
|
| - | 478 | * |
|
| - | 479 | * - word size is divisible by pixelbytes |
|
| - | 480 | * - cell scanline size is divisible by word size |
|
| - | 481 | * - cell scanlines are word-aligned |
|
| - | 482 | */ |
|
| - | 483 | if ((word_size % screen.pixelbytes) == 0 && |
|
| - | 484 | (FONT_WIDTH * screen.pixelbytes) % word_size == 0 && |
|
| - | 485 | (x * screen.pixelbytes) % word_size == 0 && |
|
| - | 486 | screen.scanline % word_size == 0) { |
|
| - | 487 | ||
| - | 488 | viewports[i].dglyph = draw_glyph_aligned; |
|
| - | 489 | } else { |
|
| - | 490 | viewports[i].dglyph = draw_glyph_fallback; |
|
| 460 | 491 | } |
|
| - | 492 | ||
| 461 | viewports[i].cur_col = 0; |
493 | viewports[i].cur_col = 0; |
| 462 | viewports[i].cur_row = 0; |
494 | viewports[i].cur_row = 0; |
| 463 | viewports[i].cursor_active = false; |
495 | viewports[i].cursor_active = false; |
| 464 | viewports[i].cursor_shown = false; |
496 | viewports[i].cursor_shown = false; |
| 465 | 497 | ||
| Line 532... | Line 564... | ||
| 532 | 564 | ||
| 533 | return true; |
565 | return true; |
| 534 | } |
566 | } |
| 535 | 567 | ||
| 536 | 568 | ||
| 537 | /** Draw a glyph. |
569 | /** Draw a glyph, takes advantage of alignment. |
| 538 | * |
570 | * |
| 539 | * @param x x coordinate of top-left corner on screen. |
- | |
| 540 | * @param y y coordinate of top-left corner on screen. |
571 | * This version can only be used if the following conditions are met: |
| 541 | * @param cursor Draw glyph with cursor |
- | |
| 542 | * @param glyphs Pointer to font bitmap. |
- | |
| 543 | * @param glyph Code of the glyph to draw. |
- | |
| 544 | * |
572 | * |
| - | 573 | * - word size is divisible by pixelbytes |
|
| - | 574 | * - cell scanline size is divisible by word size |
|
| - | 575 | * - cell scanlines are word-aligned |
|
| - | 576 | * |
|
| - | 577 | * It makes use of the pre-rendered mask to process (possibly) several |
|
| - | 578 | * pixels at once (word size / pixelbytes pixels at a time are processed) |
|
| - | 579 | * making it very fast. Most notably this version is not applicable at 24 bits |
|
| - | 580 | * per pixel. |
|
| - | 581 | * |
|
| - | 582 | * @param x x coordinate of top-left corner on screen. |
|
| - | 583 | * @param y y coordinate of top-left corner on screen. |
|
| - | 584 | * @param cursor Draw glyph with cursor |
|
| - | 585 | * @param glyphs Pointer to font bitmap. |
|
| - | 586 | * @param glyph Code of the glyph to draw. |
|
| - | 587 | * @param fg_color Foreground color. |
|
| - | 588 | * @param bg_color Backgroudn color. |
|
| - | 589 | */ |
|
| - | 590 | static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor, |
|
| - | 591 | uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color) |
|
| - | 592 | { |
|
| - | 593 | unsigned int i, yd; |
|
| - | 594 | unsigned long fg_buf, bg_buf; |
|
| - | 595 | unsigned long *maskp, *dp; |
|
| - | 596 | unsigned long mask; |
|
| - | 597 | unsigned int ww, d_add; |
|
| - | 598 | ||
| - | 599 | /* |
|
| - | 600 | * Prepare a pair of words, one filled with foreground-color |
|
| - | 601 | * pattern and the other filled with background-color pattern. |
|
| - | 602 | */ |
|
| - | 603 | for (i = 0; i < sizeof(unsigned long) / screen.pixelbytes; i++) { |
|
| - | 604 | screen.rgb_conv(&((uint8_t *)&fg_buf)[i * screen.pixelbytes], |
|
| - | 605 | fg_color); |
|
| - | 606 | screen.rgb_conv(&((uint8_t *)&bg_buf)[i * screen.pixelbytes], |
|
| - | 607 | bg_color); |
|
| - | 608 | } |
|
| - | 609 | ||
| - | 610 | ||
| - | 611 | /* Pointer to the current position in the mask. */ |
|
| - | 612 | maskp = (unsigned long *) &glyphs[GLYPH_POS(glyph, 0, cursor)]; |
|
| - | 613 | ||
| - | 614 | /* Pointer to the current position on the screen. */ |
|
| - | 615 | dp = (unsigned long *) &screen.fb_addr[FB_POS(x, y)]; |
|
| - | 616 | ||
| - | 617 | /* Width of the character cell in words. */ |
|
| - | 618 | ww = FONT_WIDTH * screen.pixelbytes / sizeof(unsigned long); |
|
| - | 619 | ||
| - | 620 | /* Offset to add when moving to another screen scanline. */ |
|
| - | 621 | d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes; |
|
| - | 622 | ||
| - | 623 | for (yd = 0; yd < FONT_SCANLINES; yd++) { |
|
| - | 624 | /* |
|
| - | 625 | * Now process the cell scanline, combining foreground |
|
| - | 626 | * and background color patters using the pre-rendered mask. |
|
| - | 627 | */ |
|
| - | 628 | for (i = 0; i < ww; i++) { |
|
| - | 629 | mask = *maskp++; |
|
| - | 630 | *dp++ = (fg_buf & mask) | (bg_buf & ~mask); |
|
| - | 631 | } |
|
| - | 632 | ||
| - | 633 | /* Move to the beginning of the next scanline of the cell. */ |
|
| - | 634 | dp = (unsigned long *) ((uint8_t *) dp + d_add); |
|
| - | 635 | } |
|
| - | 636 | } |
|
| - | 637 | ||
| - | 638 | /** Draw a glyph, fallback version. |
|
| - | 639 | * |
|
| - | 640 | * This version does not make use of the pre-rendered mask, it uses |
|
| - | 641 | * the font bitmap directly. It works always, but it is slower. |
|
| - | 642 | * |
|
| - | 643 | * @param x x coordinate of top-left corner on screen. |
|
| - | 644 | * @param y y coordinate of top-left corner on screen. |
|
| - | 645 | * @param cursor Draw glyph with cursor |
|
| - | 646 | * @param glyphs Pointer to font bitmap. |
|
| - | 647 | * @param glyph Code of the glyph to draw. |
|
| - | 648 | * @param fg_color Foreground color. |
|
| - | 649 | * @param bg_color Backgroudn color. |
|
| 545 | */ |
650 | */ |
| 546 | static void draw_glyph(unsigned int x, unsigned int y, bool cursor, |
651 | void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor, |
| 547 | uint8_t *glyphs, uint8_t glyph) |
652 | uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color) |
| 548 | { |
653 | { |
| - | 654 | unsigned int i, j, yd; |
|
| - | 655 | uint8_t fg_buf[4], bg_buf[4]; |
|
| - | 656 | uint8_t *dp, *sp; |
|
| 549 | unsigned int yd; |
657 | unsigned int d_add; |
| - | 658 | uint8_t b; |
|
| - | 659 | ||
| - | 660 | /* Pre-render 1x the foreground and background color pixels. */ |
|
| - | 661 | if (cursor) { |
|
| - | 662 | screen.rgb_conv(fg_buf, bg_color); |
|
| - | 663 | screen.rgb_conv(bg_buf, fg_color); |
|
| - | 664 | } else { |
|
| - | 665 | screen.rgb_conv(fg_buf, fg_color); |
|
| - | 666 | screen.rgb_conv(bg_buf, bg_color); |
|
| 550 | 667 | } |
|
| - | 668 | ||
| - | 669 | /* Pointer to the current position on the screen. */ |
|
| - | 670 | dp = (uint8_t *) &screen.fb_addr[FB_POS(x, y)]; |
|
| - | 671 | ||
| - | 672 | /* Offset to add when moving to another screen scanline. */ |
|
| - | 673 | d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes; |
|
| - | 674 | ||
| 551 | for (yd = 0; yd < FONT_SCANLINES; yd++) |
675 | for (yd = 0; yd < FONT_SCANLINES; yd++) { |
| - | 676 | /* Byte containing bits of the glyph scanline. */ |
|
| 552 | memcpy(&screen.fb_addr[FB_POS(x, y + yd)], |
677 | b = fb_font[glyph * FONT_SCANLINES + yd]; |
| - | 678 | ||
| - | 679 | for (i = 0; i < FONT_WIDTH; i++) { |
|
| - | 680 | /* Choose color based on the current bit. */ |
|
| - | 681 | sp = (b & 0x80) ? fg_buf : bg_buf; |
|
| - | 682 | ||
| - | 683 | /* Copy the pixel. */ |
|
| - | 684 | for (j = 0; j < screen.pixelbytes; j++) { |
|
| - | 685 | *dp++ = *sp++; |
|
| - | 686 | } |
|
| - | 687 | ||
| - | 688 | /* Move to the next bit. */ |
|
| - | 689 | b = b << 1; |
|
| - | 690 | } |
|
| - | 691 | ||
| 553 | &glyphs[GLYPH_POS(glyph, yd, cursor)], screen.glyphscanline); |
692 | /* Move to the beginning of the next scanline of the cell. */ |
| - | 693 | dp += d_add; |
|
| - | 694 | } |
|
| 554 | } |
695 | } |
| 555 | 696 | ||
| 556 | /** Draw glyph at specified position in viewport. |
697 | /** Draw glyph at specified position in viewport. |
| 557 | * |
698 | * |
| 558 | * @param vport Viewport identification |
699 | * @param vport Viewport identification |
| Line 567... | Line 708... | ||
| 567 | unsigned int x = vport->x + COL2X(col); |
708 | unsigned int x = vport->x + COL2X(col); |
| 568 | unsigned int y = vport->y + ROW2Y(row); |
709 | unsigned int y = vport->y + ROW2Y(row); |
| 569 | uint8_t glyph; |
710 | uint8_t glyph; |
| 570 | 711 | ||
| 571 | glyph = vport->backbuf[BB_POS(vport, col, row)]; |
712 | glyph = vport->backbuf[BB_POS(vport, col, row)]; |
| 572 | draw_glyph(x, y, cursor, vport->glyphs, glyph); |
- | |
| 573 | } |
- | |
| 574 | 713 | ||
| - | 714 | (*vport->dglyph)(x, y, cursor, vport->glyphs, glyph, |
|
| - | 715 | vport->style.fg_color, vport->style.bg_color); |
|
| - | 716 | } |
|
| 575 | 717 | ||
| 576 | /** Hide cursor if it is shown |
718 | /** Hide cursor if it is shown |
| 577 | * |
719 | * |
| 578 | */ |
720 | */ |
| 579 | static void cursor_hide(viewport_t *vport) |
721 | static void cursor_hide(viewport_t *vport) |
| Line 1336... | Line 1478... | ||
| 1336 | retval = EOK; |
1478 | retval = EOK; |
| 1337 | break; |
1479 | break; |
| 1338 | case FB_SET_STYLE: |
1480 | case FB_SET_STYLE: |
| 1339 | vport->style.fg_color = IPC_GET_ARG1(call); |
1481 | vport->style.fg_color = IPC_GET_ARG1(call); |
| 1340 | vport->style.bg_color = IPC_GET_ARG2(call); |
1482 | vport->style.bg_color = IPC_GET_ARG2(call); |
| 1341 | render_glyphs(vport); |
- | |
| 1342 | retval = EOK; |
1483 | retval = EOK; |
| 1343 | break; |
1484 | break; |
| 1344 | case FB_GET_RESOLUTION: |
1485 | case FB_GET_RESOLUTION: |
| 1345 | ipc_answer_2(callid, EOK, screen.xres, screen.yres); |
1486 | ipc_answer_2(callid, EOK, screen.xres, screen.yres); |
| 1346 | continue; |
1487 | continue; |