Subversion Repositories HelenOS

Rev

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;