Subversion Repositories HelenOS

Rev

Rev 3742 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3742 Rev 3745
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
 
-
 
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,
-
 
162
    uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color);
-
 
163
 
-
 
164
static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col,
-
 
165
    unsigned int row);
-
 
166
 
-
 
167
 
142
#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))
143
#define GREEN(x, bits)               ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
169
#define GREEN(x, bits)               ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
144
#define BLUE(x, bits)                ((x >> (8 - bits)) & ((1 << bits) - 1))
170
#define BLUE(x, bits)                ((x >> (8 - bits)) & ((1 << bits) - 1))
145
 
171
 
146
#define COL2X(col)                   ((col) * FONT_WIDTH)
172
#define COL2X(col)                   ((col) * FONT_WIDTH)
Line 217... Line 243...
217
{
243
{
218
    *((uint8_t *) dst)
244
    *((uint8_t *) dst)
219
        = ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
245
        = ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
220
}
246
}
221
 
247
 
-
 
248
/** Draw a filled rectangle.
-
 
249
 *
-
 
250
 * @note Need real implementation that does not access VRAM twice.
-
 
251
 */
-
 
252
static void draw_filled_rect(unsigned int x0, unsigned int y0, unsigned int x1,
-
 
253
    unsigned int y1, uint32_t color)
-
 
254
{
-
 
255
    unsigned int x, y;
-
 
256
    unsigned int copy_bytes;
-
 
257
 
-
 
258
    uint8_t *sp, *dp;
-
 
259
    uint8_t cbuf[4];
-
 
260
 
-
 
261
    if (y0 >= y1 || x0 >= x1) return;
-
 
262
    screen.rgb_conv(cbuf, color);
222
 
263
 
-
 
264
    sp = &screen.fb_addr[FB_POS(x0, y0)];
-
 
265
    dp = sp;
-
 
266
 
-
 
267
    /* Draw the first line. */
-
 
268
    for (x = x0; x < x1; x++) {
-
 
269
        memcpy(dp, cbuf, screen.pixelbytes);
-
 
270
        dp += screen.pixelbytes;
-
 
271
    }
-
 
272
 
-
 
273
    dp = sp + screen.scanline;
-
 
274
    copy_bytes = (x1 - x0) * screen.pixelbytes;
-
 
275
 
-
 
276
    /* Draw the remaining lines by copying. */
-
 
277
    for (y = y0 + 1; y < y1; y++) {
-
 
278
        memcpy(dp, sp, copy_bytes);
-
 
279
        dp += screen.scanline;
-
 
280
    }
-
 
281
}
-
 
282
 
223
/** Redraw viewport
283
/** Redraw viewport.
224
 *
284
 *
225
 * @param vport Viewport to redraw
285
 * @param vport Viewport to redraw
226
 *
286
 *
227
 */
287
 */
228
static void vport_redraw(viewport_t *vport)
288
static void vport_redraw(viewport_t *vport)
229
{
289
{
230
    unsigned int row;
290
    unsigned int row, col;
231
   
291
 
232
    for (row = 0; row < vport->rows; row++) {
292
    for (row = 0; row < vport->rows; row++) {
233
        unsigned int y = vport->y + ROW2Y(row);
-
 
234
        unsigned int yd;
-
 
235
       
-
 
236
        for (yd = 0; yd < FONT_SCANLINES; yd++) {
293
        for (col = 0; col < vport->cols; col++) {
237
            unsigned int x;
-
 
238
            unsigned int col;
-
 
239
           
-
 
240
            for (col = 0, x = vport->x; col < vport->cols; col++, x += FONT_WIDTH)
-
 
241
                memcpy(&screen.fb_addr[FB_POS(x, y + yd)],
-
 
242
                &vport->glyphs[GLYPH_POS(vport->backbuf[BB_POS(vport, col, row)], yd, false)],
-
 
243
                screen.glyphscanline);
294
            draw_vp_glyph(vport, false, col, row);
244
        }
295
        }
245
    }
296
    }
246
   
297
 
247
    if (COL2X(vport->cols) < vport->width) {
298
    if (COL2X(vport->cols) < vport->width) {
248
        unsigned int y;
299
        draw_filled_rect(
249
       
-
 
250
        for (y = 0; y < vport->height; y++) {
300
            vport->x + COL2X(vport->cols), vport->y,
251
            unsigned int x;
-
 
252
           
-
 
253
            for (x = COL2X(vport->cols); x < vport->width; x++)
301
            vport->x + vport->width, vport->y + vport->height,
254
                memcpy(&screen.fb_addr[FB_POS(x, y)], vport->bgpixel, screen.pixelbytes);
302
            vport->style.bg_color);
255
        }
-
 
256
    }
303
    }
257
   
304
 
258
    if (ROW2Y(vport->rows) < vport->height) {
305
    if (ROW2Y(vport->rows) < vport->height) {
259
        unsigned int y;
306
        draw_filled_rect(
260
       
-
 
261
        for (y = ROW2Y(vport->rows); y < vport->height; y++) {
307
            vport->x, vport->y + ROW2Y(vport->rows),
262
            unsigned int x;
-
 
263
           
-
 
264
            for (x = 0; x < vport->width; x++)
308
            vport->x + vport->width, vport->y + vport->height,
265
                memcpy(&screen.fb_addr[FB_POS(x, y)], vport->bgpixel, screen.pixelbytes);
309
            vport->style.bg_color);
266
        }
-
 
267
    }
310
    }
268
}
311
}
269
 
312
 
270
 
313
 
271
/** Clear viewport
314
/** Clear viewport.
272
 *
315
 *
273
 * @param vport Viewport to clear
316
 * @param vport Viewport to clear
274
 *
317
 *
275
 */
318
 */
276
static void vport_clear(viewport_t *vport)
319
static void vport_clear(viewport_t *vport)
277
{
320
{
278
    memset(vport->backbuf, 0, vport->bbsize);
321
    memset(vport->backbuf, 0, vport->bbsize);
279
    vport_redraw(vport);
322
    vport_redraw(vport);
280
}
323
}
281
 
324
 
282
 
-
 
283
/** Scroll viewport by given number of lines
325
/** Scroll viewport by the specified number of lines.
284
 *
326
 *
285
 * @param vport Viewport to scroll
327
 * @param vport Viewport to scroll
286
 * @param lines Number of lines to scroll
328
 * @param lines Number of lines to scroll
287
 *
329
 *
288
 */
330
 */
289
static void vport_scroll(viewport_t *vport, int lines)
331
static void vport_scroll(viewport_t *vport, int lines)
290
{
332
{
-
 
333
    unsigned int row, col;
291
    unsigned int row;
334
    unsigned int x, y;
-
 
335
    uint8_t glyph;
-
 
336
 
-
 
337
    /*
-
 
338
     * Redraw.
-
 
339
     */
292
   
340
 
-
 
341
    y = vport->y;
293
    for (row = 0; row < vport->rows; row++) {
342
    for (row = 0; row < vport->rows; row++) {
294
        unsigned int y = vport->y + ROW2Y(row);
-
 
295
        unsigned int yd;
343
        x = vport->x;
296
       
-
 
297
        for (yd = 0; yd < FONT_SCANLINES; yd++) {
344
        for (col = 0; col < vport->cols; col++) {
298
            unsigned int x;
345
            if ((row + lines >= 0) && (row + lines < vport->rows)) {
299
            unsigned int col;
346
                glyph = vport->backbuf[BB_POS(vport, col, row + lines)];
300
           
347
 
301
            for (col = 0, x = vport->x; col < vport->cols; col++, x += FONT_WIDTH) {
348
                if (vport->backbuf[BB_POS(vport, col, row)] == glyph) {
302
                uint8_t glyph;
349
                    x += FONT_WIDTH;
303
               
-
 
304
                if ((row + lines >= 0) && (row + lines < vport->rows)) {
-
 
305
                    if (vport->backbuf[BB_POS(vport, col, row)] == vport->backbuf[BB_POS(vport, col, row + lines)])
-
 
306
                        continue;
350
                    continue;
307
                   
351
                }
308
                    glyph = vport->backbuf[BB_POS(vport, col, row + lines)];
-
 
309
                } else
352
            } else {
310
                    glyph = 0;
353
                glyph = 0;
311
               
-
 
312
                memcpy(&screen.fb_addr[FB_POS(x, y + yd)],
-
 
313
                    &vport->glyphs[GLYPH_POS(glyph, yd, false)], screen.glyphscanline);
-
 
314
            }
354
            }
-
 
355
 
-
 
356
            (*vport->dglyph)(x, y, false, vport->glyphs, glyph,
-
 
357
                vport->style.fg_color, vport->style.bg_color);
-
 
358
            x += FONT_WIDTH;
315
        }
359
        }
-
 
360
        y += FONT_SCANLINES;
316
    }
361
    }
-
 
362
 
-
 
363
    /*
-
 
364
     * Scroll backbuffer.
-
 
365
     */
317
   
366
 
318
    if (lines > 0) {
367
    if (lines > 0) {
319
        memcpy(vport->backbuf, vport->backbuf + vport->cols * lines, vport->cols * (vport->rows - lines));
368
        memmove(vport->backbuf, vport->backbuf + vport->cols * lines,
-
 
369
            vport->cols * (vport->rows - lines));
320
        memset(&vport->backbuf[BB_POS(vport, 0, vport->rows - lines)], 0, vport->cols * lines);
370
        memset(&vport->backbuf[BB_POS(vport, 0, vport->rows - lines)],
-
 
371
            0, vport->cols * lines);
321
    } else {
372
    } else {
322
        memcpy(vport->backbuf - vport->cols * lines, vport->backbuf, vport->cols * (vport->rows + lines));
373
        memmove(vport->backbuf - vport->cols * lines, vport->backbuf,
-
 
374
            vport->cols * (vport->rows + lines));
323
        memset(vport->backbuf, 0, - vport->cols * lines);
375
        memset(vport->backbuf, 0, - vport->cols * lines);
324
    }
376
    }
325
}
377
}
326
 
378
 
327
 
-
 
328
/** Render glyphs
379
/** Render glyphs
329
 *
380
 *
330
 * Convert glyphs from device independent font
381
 * Convert glyphs from device independent font
331
 * description to current visual representation.
382
 * description to current visual representation.
332
 *
383
 *
Line 344... Line 395...
344
            unsigned int x;
395
            unsigned int x;
345
           
396
           
346
            for (x = 0; x < FONT_WIDTH; x++) {
397
            for (x = 0; x < FONT_WIDTH; x++) {
347
                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],
348
                    (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x)))
399
                    (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x)))
349
                    ? vport->style.fg_color : vport->style.bg_color);
-
 
350
               
-
 
351
                uint32_t curcolor;
400
                    ? 0xffffff : 0x000000);
352
               
401
               
353
                if (y < FONT_SCANLINES - 2)
402
                screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes],
354
                    curcolor =
-
 
355
                        (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x)))
403
                    (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x)))
356
                        ? vport->style.fg_color : vport->style.bg_color;
-
 
357
                else
-
 
358
                    curcolor = vport->style.fg_color;
404
                    ? 0x000000 : 0xffffff);
359
               
-
 
360
                screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes], curcolor);
-
 
361
            }
405
            }
362
        }
406
        }
363
    }
407
    }
364
   
408
   
365
    screen.rgb_conv(vport->bgpixel, vport->style.bg_color);
409
    screen.rgb_conv(vport->bgpixel, vport->style.bg_color);
Line 390... Line 434...
390
   
434
   
391
    unsigned int cols = width / FONT_WIDTH;
435
    unsigned int cols = width / FONT_WIDTH;
392
    unsigned int rows = height / FONT_SCANLINES;
436
    unsigned int rows = height / FONT_SCANLINES;
393
    unsigned int bbsize = cols * rows;
437
    unsigned int bbsize = cols * rows;
394
    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);
395
   
440
   
396
    uint8_t *backbuf = (uint8_t *) malloc(bbsize);
441
    uint8_t *backbuf = (uint8_t *) malloc(bbsize);
397
    if (!backbuf)
442
    if (!backbuf)
398
        return ENOMEM;
443
        return ENOMEM;
399
   
444
   
Line 425... Line 470...
425
    viewports[i].style.bg_color = DEFAULT_BGCOLOR;
470
    viewports[i].style.bg_color = DEFAULT_BGCOLOR;
426
    viewports[i].style.fg_color = DEFAULT_FGCOLOR;
471
    viewports[i].style.fg_color = DEFAULT_FGCOLOR;
427
   
472
   
428
    viewports[i].glyphs = glyphs;
473
    viewports[i].glyphs = glyphs;
429
    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;
430
   
491
    }
-
 
492
 
431
    viewports[i].cur_col = 0;
493
    viewports[i].cur_col = 0;
432
    viewports[i].cur_row = 0;
494
    viewports[i].cur_row = 0;
433
    viewports[i].cursor_active = false;
495
    viewports[i].cursor_active = false;
434
    viewports[i].cursor_shown = false;
496
    viewports[i].cursor_shown = false;
435
   
497
   
Line 502... Line 564...
502
   
564
   
503
    return true;
565
    return true;
504
}
566
}
505
 
567
 
506
 
568
 
-
 
569
/** Draw a glyph, takes advantage of alignment.
-
 
570
 *
-
 
571
 * This version can only be used if the following conditions are met:
-
 
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.
-
 
650
 */
-
 
651
void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor,
-
 
652
    uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color)
-
 
653
{
-
 
654
    unsigned int i, j, yd;
-
 
655
    uint8_t fg_buf[4], bg_buf[4];
-
 
656
    uint8_t *dp, *sp;
-
 
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);
-
 
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
 
-
 
675
    for (yd = 0; yd < FONT_SCANLINES; yd++) {
-
 
676
        /* Byte containing bits of the glyph scanline. */
-
 
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
       
-
 
692
        /* Move to the beginning of the next scanline of the cell. */
-
 
693
        dp += d_add;
-
 
694
    }
-
 
695
}
-
 
696
 
507
/** Draw glyph at given position relative to viewport
697
/** Draw glyph at specified position in viewport.
508
 *
698
 *
509
 * @param vport  Viewport identification
699
 * @param vport  Viewport identification
510
 * @param cursor Draw glyph with cursor
700
 * @param cursor Draw glyph with cursor
511
 * @param col    Screen position relative to viewport
701
 * @param col    Screen position relative to viewport
512
 * @param row    Screen position relative to viewport
702
 * @param row    Screen position relative to viewport
513
 *
703
 *
514
 */
704
 */
515
static void draw_glyph(viewport_t *vport, bool cursor, unsigned int col, unsigned int row)
705
static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col,
-
 
706
    unsigned int row)
516
{
707
{
517
    unsigned int x = vport->x + COL2X(col);
708
    unsigned int x = vport->x + COL2X(col);
518
    unsigned int y = vport->y + ROW2Y(row);
709
    unsigned int y = vport->y + ROW2Y(row);
519
    unsigned int yd;
710
    uint8_t glyph;
520
   
711
   
521
    uint8_t glyph = vport->backbuf[BB_POS(vport, col, row)];
712
    glyph = vport->backbuf[BB_POS(vport, col, row)];
522
   
-
 
523
    for (yd = 0; yd < FONT_SCANLINES; yd++)
-
 
524
        memcpy(&screen.fb_addr[FB_POS(x, y + yd)],
-
 
525
            &vport->glyphs[GLYPH_POS(glyph, yd, cursor)], screen.glyphscanline);
-
 
526
}
-
 
527
 
713
 
-
 
714
    (*vport->dglyph)(x, y, cursor, vport->glyphs, glyph,
-
 
715
        vport->style.fg_color, vport->style.bg_color);
-
 
716
}
528
 
717
 
529
/** Hide cursor if it is shown
718
/** Hide cursor if it is shown
530
 *
719
 *
531
 */
720
 */
532
static void cursor_hide(viewport_t *vport)
721
static void cursor_hide(viewport_t *vport)
533
{
722
{
534
    if ((vport->cursor_active) && (vport->cursor_shown)) {
723
    if ((vport->cursor_active) && (vport->cursor_shown)) {
535
        draw_glyph(vport, false, vport->cur_col, vport->cur_row);
724
        draw_vp_glyph(vport, false, vport->cur_col, vport->cur_row);
536
        vport->cursor_shown = false;
725
        vport->cursor_shown = false;
537
    }
726
    }
538
}
727
}
539
 
728
 
540
 
729
 
Line 543... Line 732...
543
 */
732
 */
544
static void cursor_show(viewport_t *vport)
733
static void cursor_show(viewport_t *vport)
545
{
734
{
546
    /* Do not check for cursor_shown */
735
    /* Do not check for cursor_shown */
547
    if (vport->cursor_active) {
736
    if (vport->cursor_active) {
548
        draw_glyph(vport, true, vport->cur_col, vport->cur_row);
737
        draw_vp_glyph(vport, true, vport->cur_col, vport->cur_row);
549
        vport->cursor_shown = true;
738
        vport->cursor_shown = true;
550
    }
739
    }
551
}
740
}
552
 
741
 
553
 
742
 
Line 577... Line 766...
577
    if ((vport->cursor_active) && (vport->cursor_shown) &&
766
    if ((vport->cursor_active) && (vport->cursor_shown) &&
578
        ((vport->cur_col != col) || (vport->cur_row != row)))
767
        ((vport->cur_col != col) || (vport->cur_row != row)))
579
        cursor_hide(vport);
768
        cursor_hide(vport);
580
   
769
   
581
    vport->backbuf[BB_POS(vport, col, row)] = c;
770
    vport->backbuf[BB_POS(vport, col, row)] = c;
582
    draw_glyph(vport, false, col, row);
771
    draw_vp_glyph(vport, false, col, row);
583
   
772
   
584
    vport->cur_col = col;
773
    vport->cur_col = col;
585
    vport->cur_row = row;
774
    vport->cur_row = row;
586
   
775
   
587
    vport->cur_col++;
776
    vport->cur_col++;
Line 614... Line 803...
614
       
803
       
615
        // TODO: use data[i].style
804
        // TODO: use data[i].style
616
       
805
       
617
        if (glyph != data[i].character) {
806
        if (glyph != data[i].character) {
618
            vport->backbuf[BB_POS(vport, col, row)] = data[i].character;
807
            vport->backbuf[BB_POS(vport, col, row)] = data[i].character;
619
            draw_glyph(vport, false, col, row);
808
            draw_vp_glyph(vport, false, col, row);
620
        }
809
        }
621
    }
810
    }
622
    cursor_show(vport);
811
    cursor_show(vport);
623
}
812
}
624
 
813
 
Line 928... Line 1117...
928
    int bytepos;
1117
    int bytepos;
929
   
1118
   
930
    if ((pointer_shown) || (!pointer_enabled))
1119
    if ((pointer_shown) || (!pointer_enabled))
931
        return;
1120
        return;
932
   
1121
   
933
    /* Save image under the cursor */
1122
    /* Save image under the pointer. */
934
    if (pointer_vport == -1) {
1123
    if (pointer_vport == -1) {
935
        pointer_vport = vport_create(pointer_x, pointer_y, pointer_width, pointer_height);
1124
        pointer_vport = vport_create(pointer_x, pointer_y, pointer_width, pointer_height);
936
        if (pointer_vport < 0)
1125
        if (pointer_vport < 0)
937
            return;
1126
            return;
938
    } else {
1127
    } else {
Line 943... Line 1132...
943
    if (pointer_pixmap == -1)
1132
    if (pointer_pixmap == -1)
944
        pointer_pixmap = save_vp_to_pixmap(&viewports[pointer_vport]);
1133
        pointer_pixmap = save_vp_to_pixmap(&viewports[pointer_vport]);
945
    else
1134
    else
946
        copy_vp_to_pixmap(&viewports[pointer_vport], &pixmaps[pointer_pixmap]);
1135
        copy_vp_to_pixmap(&viewports[pointer_vport], &pixmaps[pointer_pixmap]);
947
   
1136
   
948
    /* Draw cursor */
1137
    /* Draw mouse pointer. */
949
    for (i = 0; i < pointer_height; i++)
1138
    for (i = 0; i < pointer_height; i++)
950
        for (j = 0; j < pointer_width; j++) {
1139
        for (j = 0; j < pointer_width; j++) {
951
            bytepos = i * ((pointer_width - 1) / 8 + 1) + j / 8;
1140
            bytepos = i * ((pointer_width - 1) / 8 + 1) + j / 8;
952
            visibility = pointer_mask_bits[bytepos] &
1141
            visibility = pointer_mask_bits[bytepos] &
953
                (1 << (j % 8));
1142
                (1 << (j % 8));
Line 964... Line 1153...
964
}
1153
}
965
 
1154
 
966
 
1155
 
967
static void mouse_hide(void)
1156
static void mouse_hide(void)
968
{
1157
{
969
    /* Restore image under the cursor */
1158
    /* Restore image under the pointer. */
970
    if (pointer_shown) {
1159
    if (pointer_shown) {
971
        draw_pixmap(pointer_vport, pointer_pixmap);
1160
        draw_pixmap(pointer_vport, pointer_pixmap);
972
        pointer_shown = 0;
1161
        pointer_shown = 0;
973
    }
1162
    }
974
}
1163
}
Line 1289... Line 1478...
1289
            retval = EOK;
1478
            retval = EOK;
1290
            break;
1479
            break;
1291
        case FB_SET_STYLE:
1480
        case FB_SET_STYLE:
1292
            vport->style.fg_color = IPC_GET_ARG1(call);
1481
            vport->style.fg_color = IPC_GET_ARG1(call);
1293
            vport->style.bg_color = IPC_GET_ARG2(call);
1482
            vport->style.bg_color = IPC_GET_ARG2(call);
1294
            render_glyphs(vport);
-
 
1295
            retval = EOK;
1483
            retval = EOK;
1296
            break;
1484
            break;
1297
        case FB_GET_RESOLUTION:
1485
        case FB_GET_RESOLUTION:
1298
            ipc_answer_2(callid, EOK, screen.xres, screen.yres);
1486
            ipc_answer_2(callid, EOK, screen.xres, screen.yres);
1299
            continue;
1487
            continue;