Changeset e79a025 in mainline for uspace/srv/hid/rfb/main.c


Ignore:
Timestamp:
2020-07-03T23:41:46Z (4 years ago)
Author:
GitHub <noreply@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fd11144
Parents:
edb57bc6 (diff), ddb844e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
jxsvoboda <5887334+jxsvoboda@…> (2020-07-03 23:41:46)
git-committer:
GitHub <noreply@…> (2020-07-03 23:41:46)
Message:

Merge pull request #200 from jxsvoboda/gfx

Display server

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/rfb/main.c

    redb57bc6 re79a025  
    2727 */
    2828
    29 #include <stdlib.h>
     29#include <ddev/info.h>
     30#include <ddev_srv.h>
    3031#include <errno.h>
     32#include <fibril_synch.h>
     33#include <gfx/color.h>
     34#include <gfx/context.h>
     35#include <gfx/coord.h>
     36#include <inttypes.h>
     37#include <io/log.h>
     38#include <io/pixelmap.h>
     39#include <ipcgfx/server.h>
    3140#include <loc.h>
    3241#include <stdio.h>
    33 #include <fibril_synch.h>
    34 #include <abi/ipc/methods.h>
    35 #include <inttypes.h>
    36 #include <io/log.h>
    37 #include <str.h>
     42#include <stdlib.h>
    3843#include <task.h>
    3944
    40 #include <abi/fb/visuals.h>
    41 #include <adt/list.h>
    42 #include <io/mode.h>
    43 #include <io/pixelmap.h>
    44 #include <io/chargrid.h>
    45 #include <graph.h>
    46 
    4745#include "rfb.h"
    4846
    4947#define NAME "rfb"
    5048
    51 static vslmode_list_element_t pixel_mode;
    52 static visualizer_t *vis;
    53 static rfb_t rfb;
    54 
    55 static errno_t rfb_claim(visualizer_t *vs)
    56 {
    57         return EOK;
    58 }
    59 
    60 static errno_t rfb_yield(visualizer_t *vs)
    61 {
    62         return EOK;
    63 }
    64 
    65 static errno_t rfb_suspend(visualizer_t *vs)
    66 {
    67         return EOK;
    68 }
    69 
    70 static errno_t rfb_wakeup(visualizer_t *vs)
    71 {
    72         return EOK;
    73 }
    74 
    75 static errno_t rfb_handle_damage_pixels(visualizer_t *vs,
    76     sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
    77     sysarg_t x_offset, sysarg_t y_offset)
    78 {
    79         fibril_mutex_lock(&rfb.lock);
    80 
    81         if (x0 + width > rfb.width || y0 + height > rfb.height) {
    82                 fibril_mutex_unlock(&rfb.lock);
    83                 return EINVAL;
    84         }
    85 
    86         /* TODO update surface_t and use it */
    87         if (!rfb.damage_valid) {
    88                 rfb.damage_rect.x = x0;
    89                 rfb.damage_rect.y = y0;
    90                 rfb.damage_rect.width = width;
    91                 rfb.damage_rect.height = height;
    92                 rfb.damage_valid = true;
     49static errno_t rfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
     50static errno_t rfb_ddev_get_info(void *, ddev_info_t *);
     51
     52static errno_t rfb_gc_set_color(void *, gfx_color_t *);
     53static errno_t rfb_gc_fill_rect(void *, gfx_rect_t *);
     54static errno_t rfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
     55    gfx_bitmap_alloc_t *, void **);
     56static errno_t rfb_gc_bitmap_destroy(void *);
     57static errno_t rfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     58static errno_t rfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
     59
     60static ddev_ops_t rfb_ddev_ops = {
     61        .get_gc = rfb_ddev_get_gc,
     62        .get_info = rfb_ddev_get_info
     63};
     64
     65typedef struct {
     66        rfb_t rfb;
     67        pixel_t color;
     68} rfb_gc_t;
     69
     70typedef struct {
     71        rfb_gc_t *rfb;
     72        gfx_bitmap_alloc_t alloc;
     73        gfx_rect_t rect;
     74        gfx_bitmap_flags_t flags;
     75        pixel_t key_color;
     76        bool myalloc;
     77} rfb_bitmap_t;
     78
     79static gfx_context_ops_t rfb_gc_ops = {
     80        .set_color = rfb_gc_set_color,
     81        .fill_rect = rfb_gc_fill_rect,
     82        .bitmap_create = rfb_gc_bitmap_create,
     83        .bitmap_destroy = rfb_gc_bitmap_destroy,
     84        .bitmap_render = rfb_gc_bitmap_render,
     85        .bitmap_get_alloc = rfb_gc_bitmap_get_alloc
     86};
     87
     88static void rfb_gc_invalidate_rect(rfb_gc_t *rfbgc, gfx_rect_t *rect)
     89{
     90        rfb_t *rfb = &rfbgc->rfb;
     91        gfx_rect_t old_rect;
     92        gfx_rect_t new_rect;
     93
     94        if (gfx_rect_is_empty(rect))
     95                return;
     96
     97        if (!rfb->damage_valid) {
     98                old_rect.p0.x = old_rect.p0.y = 0;
     99                old_rect.p1.x = old_rect.p1.y = 0;
    93100        } else {
    94                 if (x0 < rfb.damage_rect.x) {
    95                         rfb.damage_rect.width += rfb.damage_rect.x - x0;
    96                         rfb.damage_rect.x = x0;
    97                 }
    98                 if (y0 < rfb.damage_rect.y) {
    99                         rfb.damage_rect.height += rfb.damage_rect.y - y0;
    100                         rfb.damage_rect.y = y0;
    101                 }
    102                 sysarg_t x1 = x0 + width;
    103                 sysarg_t dx1 = rfb.damage_rect.x + rfb.damage_rect.width;
    104                 if (x1 > dx1) {
    105                         rfb.damage_rect.width += x1 - dx1;
    106                 }
    107                 sysarg_t y1 = y0 + height;
    108                 sysarg_t dy1 = rfb.damage_rect.y + rfb.damage_rect.height;
    109                 if (y1 > dy1) {
    110                         rfb.damage_rect.height += y1 - dy1;
    111                 }
    112         }
    113 
    114         pixelmap_t *map = &vs->cells;
    115 
    116         for (sysarg_t y = y0; y < height + y0; ++y) {
    117                 for (sysarg_t x = x0; x < width + x0; ++x) {
    118                         pixel_t pix = pixelmap_get_pixel(map, (x + x_offset) % map->width,
    119                             (y + y_offset) % map->height);
    120                         pixelmap_put_pixel(&rfb.framebuffer, x, y, pix);
    121                 }
    122         }
    123 
    124         fibril_mutex_unlock(&rfb.lock);
    125         return EOK;
    126 }
    127 
    128 static errno_t rfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
    129 {
    130         return EOK;
    131 }
    132 
    133 static visualizer_ops_t rfb_ops = {
    134         .claim = rfb_claim,
    135         .yield = rfb_yield,
    136         .change_mode = rfb_change_mode,
    137         .handle_damage = rfb_handle_damage_pixels,
    138         .suspend = rfb_suspend,
    139         .wakeup = rfb_wakeup
    140 };
     101                old_rect.p0.x = rfb->damage_rect.x;
     102                old_rect.p0.y = rfb->damage_rect.y;
     103                old_rect.p1.x = rfb->damage_rect.x + rfb->damage_rect.width;
     104                old_rect.p1.y = rfb->damage_rect.y + rfb->damage_rect.height;
     105        }
     106
     107        gfx_rect_envelope(&old_rect, rect, &new_rect);
     108
     109        rfb->damage_rect.x = new_rect.p0.x;
     110        rfb->damage_rect.y = new_rect.p0.y;
     111        rfb->damage_rect.width = new_rect.p1.x - new_rect.p0.x;
     112        rfb->damage_rect.height = new_rect.p1.y - new_rect.p0.y;
     113}
     114
     115static errno_t rfb_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
     116{
     117        *arg2 = 0;
     118        *arg3 = 42;
     119        return EOK;
     120}
     121
     122static errno_t rfb_ddev_get_info(void *arg, ddev_info_t *info)
     123{
     124        rfb_t *rfb = (rfb_t *) arg;
     125
     126        ddev_info_init(info);
     127
     128        info->rect.p0.x = 0;
     129        info->rect.p0.y = 0;
     130        info->rect.p1.x = rfb->width;
     131        info->rect.p1.y = rfb->height;
     132
     133        return EOK;
     134}
     135
     136/** Set color on RFB.
     137 *
     138 * Set drawing color on RFB GC.
     139 *
     140 * @param arg RFB
     141 * @param color Color
     142 *
     143 * @return EOK on success or an error code
     144 */
     145static errno_t rfb_gc_set_color(void *arg, gfx_color_t *color)
     146{
     147        rfb_gc_t *rfb = (rfb_gc_t *) arg;
     148        uint16_t r, g, b;
     149
     150        gfx_color_get_rgb_i16(color, &r, &g, &b);
     151        rfb->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
     152        return EOK;
     153}
     154
     155/** Fill rectangle on RFB.
     156 *
     157 * @param arg RFB
     158 * @param rect Rectangle
     159 *
     160 * @return EOK on success or an error code
     161 */
     162static errno_t rfb_gc_fill_rect(void *arg, gfx_rect_t *rect)
     163{
     164        rfb_gc_t *rfb = (rfb_gc_t *) arg;
     165        gfx_coord_t x, y;
     166
     167        // XXX We should handle p0.x > p1.x and p0.y > p1.y
     168
     169        for (y = rect->p0.y; y < rect->p1.y; y++) {
     170                for (x = rect->p0.x; x < rect->p1.x; x++) {
     171                        pixelmap_put_pixel(&rfb->rfb.framebuffer, x, y,
     172                            rfb->color);
     173                }
     174        }
     175
     176        rfb_gc_invalidate_rect(rfb, rect);
     177
     178        return EOK;
     179}
     180
     181/** Create bitmap in RFB GC.
     182 *
     183 * @param arg RFB
     184 * @param params Bitmap params
     185 * @param alloc Bitmap allocation info or @c NULL
     186 * @param rbm Place to store pointer to new bitmap
     187 * @return EOK on success or an error code
     188 */
     189errno_t rfb_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     190    gfx_bitmap_alloc_t *alloc, void **rbm)
     191{
     192        rfb_gc_t *rfb = (rfb_gc_t *) arg;
     193        rfb_bitmap_t *rfbbm = NULL;
     194        gfx_coord2_t dim;
     195        errno_t rc;
     196
     197        /* Check that we support all required flags */
     198        if ((params->flags & ~bmpf_color_key) != 0)
     199                return ENOTSUP;
     200
     201        rfbbm = calloc(1, sizeof(rfb_bitmap_t));
     202        if (rfbbm == NULL)
     203                return ENOMEM;
     204
     205        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
     206        rfbbm->rect = params->rect;
     207        rfbbm->flags = params->flags;
     208        rfbbm->key_color = params->key_color;
     209
     210        if (alloc == NULL) {
     211                rfbbm->alloc.pitch = dim.x * sizeof(uint32_t);
     212                rfbbm->alloc.off0 = 0;
     213                rfbbm->alloc.pixels = malloc(rfbbm->alloc.pitch * dim.y);
     214                rfbbm->myalloc = true;
     215
     216                if (rfbbm->alloc.pixels == NULL) {
     217                        rc = ENOMEM;
     218                        goto error;
     219                }
     220        } else {
     221                rfbbm->alloc = *alloc;
     222        }
     223
     224        rfbbm->rfb = rfb;
     225        *rbm = (void *)rfbbm;
     226        return EOK;
     227error:
     228        if (rbm != NULL)
     229                free(rfbbm);
     230        return rc;
     231}
     232
     233/** Destroy bitmap in RFB GC.
     234 *
     235 * @param bm Bitmap
     236 * @return EOK on success or an error code
     237 */
     238static errno_t rfb_gc_bitmap_destroy(void *bm)
     239{
     240        rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
     241        if (rfbbm->myalloc)
     242                free(rfbbm->alloc.pixels);
     243        free(rfbbm);
     244        return EOK;
     245}
     246
     247/** Render bitmap in RFB GC.
     248 *
     249 * @param bm Bitmap
     250 * @param srect0 Source rectangle or @c NULL
     251 * @param offs0 Offset or @c NULL
     252 * @return EOK on success or an error code
     253 */
     254static errno_t rfb_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
     255    gfx_coord2_t *offs0)
     256{
     257        rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
     258        gfx_rect_t srect;
     259        gfx_rect_t drect;
     260        gfx_coord2_t offs;
     261        gfx_coord2_t bmdim;
     262        gfx_coord2_t dim;
     263        gfx_coord_t x, y;
     264        pixelmap_t pbm;
     265        pixel_t color;
     266
     267        if (srect0 != NULL)
     268                srect = *srect0;
     269        else
     270                srect = rfbbm->rect;
     271
     272        if (offs0 != NULL) {
     273                offs = *offs0;
     274        } else {
     275                offs.x = 0;
     276                offs.y = 0;
     277        }
     278
     279        /* Destination rectangle */
     280        gfx_rect_translate(&offs, &srect, &drect);
     281        gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
     282        gfx_coord2_subtract(&rfbbm->rect.p1, &rfbbm->rect.p0, &bmdim);
     283
     284        pbm.width = bmdim.x;
     285        pbm.height = bmdim.y;
     286        pbm.data = rfbbm->alloc.pixels;
     287
     288        if ((rfbbm->flags & bmpf_color_key) == 0) {
     289                for (y = srect.p0.y; y < srect.p1.y; y++) {
     290                        for (x = srect.p0.x; x < srect.p1.x; x++) {
     291                                color = pixelmap_get_pixel(&pbm, x, y);
     292                                pixelmap_put_pixel(&rfbbm->rfb->rfb.framebuffer,
     293                                    x + offs.x, y + offs.y, color);
     294                        }
     295                }
     296        } else {
     297                for (y = srect.p0.y; y < srect.p1.y; y++) {
     298                        for (x = srect.p0.x; x < srect.p1.x; x++) {
     299                                color = pixelmap_get_pixel(&pbm, x, y);
     300                                if (color != rfbbm->key_color) {
     301                                        pixelmap_put_pixel(&rfbbm->rfb->rfb.framebuffer,
     302                                            x + offs.x, y + offs.y, color);
     303                                }
     304                        }
     305                }
     306        }
     307
     308        rfb_gc_invalidate_rect(rfbbm->rfb, &drect);
     309
     310        return EOK;
     311}
     312
     313/** Get allocation info for bitmap in RFB GC.
     314 *
     315 * @param bm Bitmap
     316 * @param alloc Place to store allocation info
     317 * @return EOK on success or an error code
     318 */
     319static errno_t rfb_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     320{
     321        rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
     322        *alloc = rfbbm->alloc;
     323        return EOK;
     324}
    141325
    142326static void syntax_print(void)
     
    145329}
    146330
    147 static void client_connection(ipc_call_t *call, void *data)
    148 {
    149         graph_visualizer_connection(vis, call, data);
     331static void client_connection(ipc_call_t *icall, void *arg)
     332{
     333        rfb_t *rfb = (rfb_t *) arg;
     334        ddev_srv_t srv;
     335        sysarg_t svc_id;
     336        gfx_context_t *gc;
     337        errno_t rc;
     338
     339        svc_id = ipc_get_arg2(icall);
     340
     341        if (svc_id != 0) {
     342                /* Set up protocol structure */
     343                ddev_srv_initialize(&srv);
     344                srv.ops = &rfb_ddev_ops;
     345                srv.arg = (void *) rfb;
     346
     347                /* Handle connection */
     348                ddev_conn(icall, &srv);
     349        } else {
     350                rc = gfx_context_new(&rfb_gc_ops, (void *) rfb, &gc);
     351                if (rc != EOK) {
     352                        async_answer_0(icall, ENOMEM);
     353                        return;
     354                }
     355
     356                /* GC connection */
     357                gc_conn(icall, gc);
     358        }
    150359}
    151360
    152361int main(int argc, char **argv)
    153362{
     363        rfb_t rfb;
     364
    154365        log_init(NAME);
    155366
     
    188399        rfb_init(&rfb, width, height, rfb_name);
    189400
    190         vis = malloc(sizeof(visualizer_t));
    191         if (vis == NULL) {
    192                 fprintf(stderr, "Failed allocating visualizer struct\n");
    193                 return 3;
    194         }
    195 
    196         graph_init_visualizer(vis);
    197 
    198         pixel_mode.mode.index = 0;
    199         pixel_mode.mode.version = 0;
    200         pixel_mode.mode.refresh_rate = 0;
    201         pixel_mode.mode.screen_aspect.width = rfb.width;
    202         pixel_mode.mode.screen_aspect.height = rfb.height;
    203         pixel_mode.mode.screen_width = rfb.width;
    204         pixel_mode.mode.screen_height = rfb.height;
    205         pixel_mode.mode.cell_aspect.width = 1;
    206         pixel_mode.mode.cell_aspect.height = 1;
    207         pixel_mode.mode.cell_visual.pixel_visual = VISUAL_RGB_8_8_8;
    208 
    209         link_initialize(&pixel_mode.link);
    210         list_append(&pixel_mode.link, &vis->modes);
    211 
    212         vis->def_mode_idx = 0;
    213 
    214         vis->ops = rfb_ops;
    215         vis->dev_ctx = NULL;
    216 
    217         async_set_fallback_port_handler(client_connection, NULL);
     401        async_set_fallback_port_handler(client_connection, &rfb);
    218402
    219403        errno_t rc = loc_server_register(NAME);
     
    240424        free(service_name);
    241425
    242         category_id_t visualizer_category;
    243         rc = loc_category_get_id("visualizer", &visualizer_category, IPC_FLAG_BLOCKING);
     426        category_id_t ddev_cid;
     427        rc = loc_category_get_id("display-device", &ddev_cid, IPC_FLAG_BLOCKING);
    244428        if (rc != EOK) {
    245                 fprintf(stderr, NAME ": Unable to get visualizer category id.\n");
     429                fprintf(stderr, NAME ": Unable to get display device category id.\n");
    246430                return 1;
    247431        }
    248432
    249         rc = loc_service_add_to_cat(service_id, visualizer_category);
     433        rc = loc_service_add_to_cat(service_id, ddev_cid);
    250434        if (rc != EOK) {
    251                 fprintf(stderr, NAME ": Unable to add service to visualizer category.\n");
     435                fprintf(stderr, NAME ": Unable to add service to display device category.\n");
    252436                return 1;
    253437        }
Note: See TracChangeset for help on using the changeset viewer.