Ignore:
File:
1 edited

Legend:

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

    rde19d4a r984a9ba  
    2727 */
    2828
    29 #include <ddev/info.h>
    30 #include <ddev_srv.h>
     29#include <stdlib.h>
    3130#include <errno.h>
     31#include <loc.h>
     32#include <stdio.h>
    3233#include <fibril_synch.h>
    33 #include <gfx/color.h>
    34 #include <gfx/context.h>
    35 #include <gfx/coord.h>
     34#include <abi/ipc/methods.h>
    3635#include <inttypes.h>
    3736#include <io/log.h>
     37#include <str.h>
     38#include <task.h>
     39
     40#include <abi/fb/visuals.h>
     41#include <adt/list.h>
     42#include <io/mode.h>
    3843#include <io/pixelmap.h>
    39 #include <ipcgfx/server.h>
    40 #include <loc.h>
    41 #include <stdio.h>
    42 #include <stdlib.h>
    43 #include <task.h>
     44#include <io/chargrid.h>
     45#include <graph.h>
    4446
    4547#include "rfb.h"
     
    4749#define NAME "rfb"
    4850
    49 static errno_t rfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
    50 static errno_t rfb_ddev_get_info(void *, ddev_info_t *);
    51 
    52 static errno_t rfb_gc_set_color(void *, gfx_color_t *);
    53 static errno_t rfb_gc_fill_rect(void *, gfx_rect_t *);
    54 static errno_t rfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    55     gfx_bitmap_alloc_t *, void **);
    56 static errno_t rfb_gc_bitmap_destroy(void *);
    57 static errno_t rfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
    58 static errno_t rfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    59 
    60 static ddev_ops_t rfb_ddev_ops = {
    61         .get_gc = rfb_ddev_get_gc,
    62         .get_info = rfb_ddev_get_info
     51static vslmode_list_element_t pixel_mode;
     52static visualizer_t *vis;
     53static rfb_t rfb;
     54
     55static errno_t rfb_claim(visualizer_t *vs)
     56{
     57        return EOK;
     58}
     59
     60static errno_t rfb_yield(visualizer_t *vs)
     61{
     62        return EOK;
     63}
     64
     65static errno_t rfb_suspend(visualizer_t *vs)
     66{
     67        return EOK;
     68}
     69
     70static errno_t rfb_wakeup(visualizer_t *vs)
     71{
     72        return EOK;
     73}
     74
     75static 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;
     93        } 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
     128static errno_t rfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
     129{
     130        return EOK;
     131}
     132
     133static 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
    63140};
    64141
    65 typedef struct {
    66         rfb_t rfb;
    67         pixel_t color;
    68 } rfb_gc_t;
    69 
    70 typedef 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 
    79 static 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 
    88 static 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;
    100         } else {
    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 
    115 static 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 
    122 static 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  */
    145 static 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  */
    162 static 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  */
    189 errno_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;
    227 error:
    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  */
    238 static 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  */
    254 static 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  */
    319 static 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 }
    325 
    326142static void syntax_print(void)
    327143{
     
    329145}
    330146
    331 static 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         }
     147static void client_connection(ipc_call_t *call, void *data)
     148{
     149        graph_visualizer_connection(vis, call, data);
    359150}
    360151
    361152int main(int argc, char **argv)
    362153{
    363         rfb_t rfb;
    364 
    365154        log_init(NAME);
    366155
     
    399188        rfb_init(&rfb, width, height, rfb_name);
    400189
    401         async_set_fallback_port_handler(client_connection, &rfb);
     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);
    402218
    403219        errno_t rc = loc_server_register(NAME);
     
    424240        free(service_name);
    425241
    426         category_id_t ddev_cid;
    427         rc = loc_category_get_id("display-device", &ddev_cid, IPC_FLAG_BLOCKING);
    428         if (rc != EOK) {
    429                 fprintf(stderr, NAME ": Unable to get display device category id.\n");
    430                 return 1;
    431         }
    432 
    433         rc = loc_service_add_to_cat(service_id, ddev_cid);
    434         if (rc != EOK) {
    435                 fprintf(stderr, NAME ": Unable to add service to display device category.\n");
     242        category_id_t visualizer_category;
     243        rc = loc_category_get_id("visualizer", &visualizer_category, IPC_FLAG_BLOCKING);
     244        if (rc != EOK) {
     245                fprintf(stderr, NAME ": Unable to get visualizer category id.\n");
     246                return 1;
     247        }
     248
     249        rc = loc_service_add_to_cat(service_id, visualizer_category);
     250        if (rc != EOK) {
     251                fprintf(stderr, NAME ": Unable to add service to visualizer category.\n");
    436252                return 1;
    437253        }
Note: See TracChangeset for help on using the changeset viewer.