Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/congfx/src/console.c

    ra4e4e29 r0d62c10  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2019 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4848#include "../private/color.h"
    4949
    50 static errno_t console_gc_set_clip_rect(void *, gfx_rect_t *);
    5150static errno_t console_gc_set_color(void *, gfx_color_t *);
    5251static errno_t console_gc_fill_rect(void *, gfx_rect_t *);
    53 static errno_t console_gc_update(void *);
    5452static errno_t console_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    5553    gfx_bitmap_alloc_t *, void **);
     
    5755static errno_t console_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
    5856static errno_t console_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    59 static errno_t console_gc_cursor_get_pos(void *, gfx_coord2_t *);
    60 static errno_t console_gc_cursor_set_pos(void *, gfx_coord2_t *);
    61 static errno_t console_gc_cursor_set_visible(void *, bool);
    6257
    6358gfx_context_ops_t console_gc_ops = {
    64         .set_clip_rect = console_gc_set_clip_rect,
    6559        .set_color = console_gc_set_color,
    6660        .fill_rect = console_gc_fill_rect,
    67         .update = console_gc_update,
    6861        .bitmap_create = console_gc_bitmap_create,
    6962        .bitmap_destroy = console_gc_bitmap_destroy,
    7063        .bitmap_render = console_gc_bitmap_render,
    71         .bitmap_get_alloc = console_gc_bitmap_get_alloc,
    72         .cursor_get_pos = console_gc_cursor_get_pos,
    73         .cursor_set_pos = console_gc_cursor_set_pos,
    74         .cursor_set_visible = console_gc_cursor_set_visible
     64        .bitmap_get_alloc = console_gc_bitmap_get_alloc
    7565};
    7666
    77 /** Convert pixel value to charfield.
    78  *
    79  * On the bottom of this function lies a big big hack. In the absence
    80  * of support for different color formats (FIX ME!), here's a single
    81  * format that can represent both 3x8bit RGB and 24-bit characters
    82  * with 8-bit EGA attributes (i.e. we can specify the foreground and
    83  * background colors individually).
    84  *
    85  * A    R   G   B
    86  * 0    red grn blu  24-bit color
    87  * attr c2  c1  c0   attribute + 24-bit character
    88  */
    89 static void console_gc_pix_to_charfield(pixel_t clr, charfield_t *ch)
    90 {
    91         uint8_t attr;
    92 
    93         if ((clr >> 24) == 0xff) {
    94                 /* RGB (no text) */
    95                 ch->ch = 0;
    96                 ch->flags = CHAR_FLAG_DIRTY;
    97                 ch->attrs.type = CHAR_ATTR_RGB;
    98                 ch->attrs.val.rgb.fgcolor = clr;
    99                 ch->attrs.val.rgb.bgcolor = clr;
    100         } else {
    101                 /* EGA attributes (with text) */
    102                 attr = clr >> 24;
    103                 ch->ch = clr & 0xffffff;
    104                 ch->flags = CHAR_FLAG_DIRTY;
    105                 ch->attrs.type = CHAR_ATTR_INDEX;
    106                 ch->attrs.val.index.fgcolor = attr & 0x7;
    107                 ch->attrs.val.index.bgcolor = (attr >> 4) & 0x7;
    108                 ch->attrs.val.index.attr =
    109                     ((attr & 0x8) ? CATTR_BRIGHT : 0) +
    110                     ((attr & 0x80) ? CATTR_BLINK : 0);
    111         }
    112 }
    113 
    114 /** Set clipping rectangle on console GC.
     67/** Set color on console GC.
     68 *
     69 * Set drawing color on console GC.
     70 *
     71 * @param arg Console GC
     72 * @param color Color
     73 *
     74 * @return EOK on success or an error code
     75 */
     76static errno_t console_gc_set_color(void *arg, gfx_color_t *color)
     77{
     78        console_gc_t *cgc = (console_gc_t *) arg;
     79
     80        cgc->clr = PIXEL(0, color->r >> 8, color->g >> 8, color->b >> 8);
     81        return EOK;
     82}
     83
     84/** Fill rectangle on console GC.
    11585 *
    11686 * @param arg Console GC
     
    11989 * @return EOK on success or an error code
    12090 */
    121 static errno_t console_gc_set_clip_rect(void *arg, gfx_rect_t *rect)
     91static errno_t console_gc_fill_rect(void *arg, gfx_rect_t *rect)
    12292{
    12393        console_gc_t *cgc = (console_gc_t *) arg;
    124 
    125         if (rect != NULL)
    126                 gfx_rect_clip(rect, &cgc->rect, &cgc->clip_rect);
    127         else
    128                 cgc->clip_rect = cgc->rect;
    129 
    130         return EOK;
    131 }
    132 
    133 /** Set color on console GC.
    134  *
    135  * Set drawing color on console GC.
    136  *
    137  * @param arg Console GC
    138  * @param color Color
    139  *
    140  * @return EOK on success or an error code
    141  */
    142 static errno_t console_gc_set_color(void *arg, gfx_color_t *color)
    143 {
    144         console_gc_t *cgc = (console_gc_t *) arg;
    145 
    146         cgc->clr = PIXEL(color->attr, color->r >> 8, color->g >> 8, color->b >> 8);
    147         return EOK;
    148 }
    149 
    150 /** Fill rectangle on console GC.
    151  *
    152  * @param arg Console GC
    153  * @param rect Rectangle
    154  *
    155  * @return EOK on success or an error code
    156  */
    157 static errno_t console_gc_fill_rect(void *arg, gfx_rect_t *rect)
    158 {
    159         console_gc_t *cgc = (console_gc_t *) arg;
     94        int rv;
    16095        gfx_coord_t x, y;
    161         gfx_coord_t cols;
    162         gfx_rect_t crect;
    163         charfield_t ch;
    164 
    165         /* Make sure rectangle is clipped and sorted */
    166         gfx_rect_clip(rect, &cgc->clip_rect, &crect);
    167 
    168         cols = cgc->rect.p1.x - cgc->rect.p0.x;
    169 
    170         console_gc_pix_to_charfield(cgc->clr, &ch);
    171 
    172         for (y = crect.p0.y; y < crect.p1.y; y++) {
    173                 for (x = crect.p0.x; x < crect.p1.x; x++) {
    174                         cgc->buf[y * cols + x] = ch;
    175                 }
    176         }
    177 
    178         console_update(cgc->con, crect.p0.x, crect.p0.y,
    179             crect.p1.x, crect.p1.y);
    180 
    181         return EOK;
    182 }
    183 
    184 /** Update console GC.
    185  *
    186  * @param arg Console GC
    187  *
    188  * @return EOK on success or an error code
    189  */
    190 static errno_t console_gc_update(void *arg)
    191 {
    192         console_gc_t *cgc = (console_gc_t *) arg;
    193 
    194         /*
    195          * XXX Before actually deferring update to here (and similarly other
    196          * GC implementations) need to make sure all consumers properly
    197          * call update.
    198          */
    199         (void) cgc;
     96
     97        // XXX We should handle p0.x > p1.x and p0.y > p1.y
     98
     99        console_set_rgb_color(cgc->con, cgc->clr, cgc->clr);
     100
     101        for (y = rect->p0.y; y < rect->p1.y; y++) {
     102                console_set_pos(cgc->con, rect->p0.x, y);
     103
     104                for (x = rect->p0.x; x < rect->p1.x; x++) {
     105                        rv = fputc('X', cgc->fout);
     106                        if (rv < 0)
     107                                return EIO;
     108                }
     109
     110                console_flush(cgc->con);
     111        }
     112
    200113        return EOK;
    201114}
     
    218131        sysarg_t rows;
    219132        sysarg_t cols;
    220         charfield_t *buf = NULL;
    221133        errno_t rc;
    222134
     
    228140
    229141        rc = console_get_size(con, &cols, &rows);
    230         if (rc != EOK)
    231                 goto error;
    232 
    233         console_clear(con);
    234 
    235         rc = console_map(con, cols, rows, &buf);
    236142        if (rc != EOK)
    237143                goto error;
     
    247153        cgc->rect.p0.y = 0;
    248154        cgc->rect.p1.x = cols;
    249         cgc->rect.p1.y = rows;
    250         cgc->clip_rect = cgc->rect;
    251         cgc->buf = buf;
     155        cgc->rect.p1.y = rows - 1; /* make sure we avoid bottom-right corner */
    252156
    253157        *rgc = cgc;
    254158        return EOK;
    255159error:
    256         if (buf != NULL)
    257                 console_unmap(cgc->con, buf);
    258160        if (cgc != NULL)
    259161                free(cgc);
     
    274176                return rc;
    275177
    276         console_clear(cgc->con);
    277         console_unmap(cgc->con, cgc->buf);
    278 
    279178        free(cgc);
    280179        return EOK;
    281180}
    282 
    283 /** Free up console for other users, suspending GC operation.
    284  *
    285  * @param cgc Console GC
    286  * @return EOK on success or an error code
    287  */
    288 errno_t console_gc_suspend(console_gc_t *cgc)
    289 {
    290         console_unmap(cgc->con, cgc->buf);
    291         cgc->buf = NULL;
    292 
    293         console_clear(cgc->con);
    294         console_cursor_visibility(cgc->con, true);
    295         return EOK;
    296 }
    297 
    298 /** Resume GC operation after suspend.
    299  *
    300  * @param cgc Console GC
    301  * @return EOK on success or an error code
    302  */
    303 errno_t console_gc_resume(console_gc_t *cgc)
    304 {
    305         errno_t rc;
    306 
    307         console_clear(cgc->con);
    308 
    309         rc = console_map(cgc->con, cgc->rect.p1.x, cgc->rect.p1.y, &cgc->buf);
    310         if (rc != EOK)
    311                 return rc;
    312 
    313         return EOK;
    314 }
    315 
    316 /** Update console GC size after console resize.
    317  *
    318  * @param con Console object
    319  *
    320  * @return EOK on success or an error code
    321  */
    322 errno_t console_gc_resize(console_gc_t *cgc)
    323 {
    324         sysarg_t rows;
    325         sysarg_t cols;
    326         charfield_t *buf = NULL;
    327         errno_t rc;
    328 
    329         console_unmap(cgc->con, cgc->buf);
    330         cgc->buf = NULL;
    331 
    332         rc = console_get_size(cgc->con, &cols, &rows);
    333         if (rc != EOK)
    334                 goto error;
    335 
    336         rc = console_map(cgc->con, cols, rows, &buf);
    337         if (rc != EOK)
    338                 goto error;
    339 
    340         cgc->rect.p0.x = 0;
    341         cgc->rect.p0.y = 0;
    342         cgc->rect.p1.x = cols;
    343         cgc->rect.p1.y = rows;
    344         cgc->clip_rect = cgc->rect;
    345         cgc->buf = buf;
    346         return EOK;
    347 error:
    348         return rc;
    349 }
    350 
    351181
    352182/** Get generic graphic context from console GC.
     
    438268        console_gc_bitmap_t *cbm = (console_gc_bitmap_t *)bm;
    439269        gfx_coord_t x, y;
     270        int rv;
    440271        pixel_t clr;
    441         charfield_t ch;
    442272        pixelmap_t pixelmap;
    443273        gfx_rect_t srect;
     
    445275        gfx_rect_t crect;
    446276        gfx_coord2_t offs;
    447         gfx_coord_t cols;
    448277
    449278        if (srect0 != NULL)
     
    460289
    461290        gfx_rect_translate(&offs, &srect, &drect);
    462         gfx_rect_clip(&drect, &cbm->cgc->clip_rect, &crect);
     291        gfx_rect_clip(&drect, &cbm->cgc->rect, &crect);
    463292
    464293        pixelmap.width = cbm->rect.p1.x - cbm->rect.p0.x;
     
    466295        pixelmap.data = cbm->alloc.pixels;
    467296
    468         cols = cbm->cgc->rect.p1.x - cbm->cgc->rect.p0.x;
    469 
    470297        if ((cbm->flags & bmpf_color_key) == 0) {
    471298                /* Simple copy */
    472299                for (y = crect.p0.y; y < crect.p1.y; y++) {
     300                        console_set_pos(cbm->cgc->con, crect.p0.x, y);
     301
    473302                        for (x = crect.p0.x; x < crect.p1.x; x++) {
    474303                                clr = pixelmap_get_pixel(&pixelmap,
    475304                                    x - offs.x - cbm->rect.p0.x,
    476305                                    y - offs.y - cbm->rect.p0.y);
    477 
    478                                 console_gc_pix_to_charfield(clr, &ch);
    479                                 cbm->cgc->buf[y * cols + x] = ch;
     306                                console_set_rgb_color(cbm->cgc->con, clr, clr);
     307
     308                                rv = fputc('X', cbm->cgc->fout);
     309                                if (rv < 0)
     310                                        return EIO;
     311
     312                                console_flush(cbm->cgc->con);
    480313                        }
    481314                }
     
    488321                                    x - offs.x - cbm->rect.p0.x,
    489322                                    y - offs.y - cbm->rect.p0.y);
    490 
    491                                 console_gc_pix_to_charfield(clr, &ch);
    492 
    493                                 if (clr != cbm->key_color)
    494                                         cbm->cgc->buf[y * cols + x] = ch;
     323                                console_set_rgb_color(cbm->cgc->con, clr, clr);
     324
     325                                if (clr != cbm->key_color) {
     326                                        console_set_pos(cbm->cgc->con, x, y);
     327                                        rv = fputc('X', cbm->cgc->fout);
     328                                        if (rv < 0)
     329                                                return EIO;
     330
     331                                        console_flush(cbm->cgc->con);
     332                                }
     333
    495334                        }
    496335                }
    497336        } else {
    498337                /* Color key & colorize */
    499                 console_gc_pix_to_charfield(cbm->cgc->clr, &ch);
     338                console_set_rgb_color(cbm->cgc->con, cbm->cgc->clr,
     339                    cbm->cgc->clr);
    500340
    501341                for (y = crect.p0.y; y < crect.p1.y; y++) {
    502342                        for (x = crect.p0.x; x < crect.p1.x; x++) {
     343
    503344                                clr = pixelmap_get_pixel(&pixelmap,
    504345                                    x - offs.x - cbm->rect.p0.x,
    505346                                    y - offs.y - cbm->rect.p0.y);
    506347
    507                                 if (clr != cbm->key_color)
    508                                         cbm->cgc->buf[y * cols + x] = ch;
     348                                if (clr != cbm->key_color) {
     349                                        console_set_pos(cbm->cgc->con, x, y);
     350                                        rv = fputc('X', cbm->cgc->fout);
     351                                        if (rv < 0)
     352                                                return EIO;
     353
     354                                        console_flush(cbm->cgc->con);
     355                                }
     356
    509357                        }
    510358                }
    511359        }
    512 
    513         console_update(cbm->cgc->con, crect.p0.x, crect.p0.y, crect.p1.x,
    514             crect.p1.y);
    515360
    516361        return EOK;
     
    530375}
    531376
    532 /** Get cursor position on console GC.
    533  *
    534  * @param arg Console GC
    535  * @param pos Place to store position
    536  *
    537  * @return EOK on success or an error code
    538  */
    539 static errno_t console_gc_cursor_get_pos(void *arg, gfx_coord2_t *pos)
    540 {
    541         console_gc_t *cgc = (console_gc_t *) arg;
    542         sysarg_t col;
    543         sysarg_t row;
    544         errno_t rc;
    545 
    546         rc = console_get_pos(cgc->con, &col, &row);
    547         if (rc != EOK)
    548                 return rc;
    549 
    550         pos->x = col;
    551         pos->y = row;
    552         return EOK;
    553 }
    554 
    555 /** Set cursor position on console GC.
    556  *
    557  * @param arg Console GC
    558  * @param pos New cursor position
    559  *
    560  * @return EOK on success or an error code
    561  */
    562 static errno_t console_gc_cursor_set_pos(void *arg, gfx_coord2_t *pos)
    563 {
    564         console_gc_t *cgc = (console_gc_t *) arg;
    565 
    566         console_set_pos(cgc->con, pos->x, pos->y);
    567         return EOK;
    568 }
    569 
    570 /** Set cursor visibility on console GC.
    571  *
    572  * @param arg Console GC
    573  * @param visible @c true iff cursor should be made visible
    574  *
    575  * @return EOK on success or an error code
    576  */
    577 static errno_t console_gc_cursor_set_visible(void *arg, bool visible)
    578 {
    579         console_gc_t *cgc = (console_gc_t *) arg;
    580 
    581         console_cursor_visibility(cgc->con, visible);
    582         return EOK;
    583 }
    584 
    585377/** @}
    586378 */
Note: See TracChangeset for help on using the changeset viewer.