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


Ignore:
Timestamp:
2019-12-05T19:35:12Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
71cbe5c
Parents:
973efd36
Message:

Enumerate display devices for output, RFB conversion (WIP)

Currently we can only have one active output device. Bitmaps
do not work as ipcgfx does not accept alloc != NULL.
Need to fill in tests.

File:
1 edited

Legend:

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

    r973efd36 r87a7cdb  
    2727 */
    2828
    29 #include <stdlib.h>
     29#include <ddev_srv.h>
    3030#include <errno.h>
     31#include <fibril_synch.h>
     32#include <gfx/color.h>
     33#include <gfx/context.h>
     34#include <gfx/coord.h>
     35#include <inttypes.h>
     36#include <io/log.h>
     37#include <io/pixelmap.h>
     38#include <ipcgfx/server.h>
    3139#include <loc.h>
    3240#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>
     41#include <stdlib.h>
    3842#include <task.h>
    3943
    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 
    4744#include "rfb.h"
    4845
    4946#define NAME "rfb"
    5047
    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 
     48static errno_t rfb_gc_set_color(void *, gfx_color_t *);
     49static errno_t rfb_gc_fill_rect(void *, gfx_rect_t *);
     50static errno_t rfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
     51    gfx_bitmap_alloc_t *, void **);
     52static errno_t rfb_gc_bitmap_destroy(void *);
     53static errno_t rfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     54static errno_t rfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
     55
     56static ddev_ops_t rfb_ddev_ops = {
     57};
     58
     59typedef struct {
     60        rfb_t rfb;
     61        pixel_t color;
     62} rfb_gc_t;
     63
     64typedef struct {
     65        rfb_gc_t *rfb;
     66        gfx_bitmap_alloc_t alloc;
     67        gfx_rect_t rect;
     68        bool myalloc;
     69} rfb_bitmap_t;
     70
     71gfx_context_ops_t rfb_gc_ops = {
     72        .set_color = rfb_gc_set_color,
     73        .fill_rect = rfb_gc_fill_rect,
     74        .bitmap_create = rfb_gc_bitmap_create,
     75        .bitmap_destroy = rfb_gc_bitmap_destroy,
     76        .bitmap_render = rfb_gc_bitmap_render,
     77        .bitmap_get_alloc = rfb_gc_bitmap_get_alloc
     78};
     79
     80static void rfb_gc_invalidate_rect(rfb_gc_t *rfbgc, gfx_rect_t *rect)
     81{
     82        rfb_t *rfb = &rfbgc->rfb;
     83        gfx_rect_t old_rect;
     84        gfx_rect_t new_rect;
     85
     86        if (gfx_rect_is_empty(rect))
     87                return;
     88
     89        if (!rfb->damage_valid) {
     90                old_rect.p0.x = old_rect.p0.y = 0;
     91                old_rect.p1.x = old_rect.p1.y = 0;
     92        } else {
     93                old_rect.p0.x = rfb->damage_rect.x;
     94                old_rect.p0.y = rfb->damage_rect.y;
     95                old_rect.p1.x = rfb->damage_rect.x + rfb->damage_rect.width;
     96                old_rect.p1.y = rfb->damage_rect.y + rfb->damage_rect.height;
     97        }
     98
     99        gfx_rect_envelope(&old_rect, rect, &new_rect);
     100
     101        rfb->damage_rect.x = new_rect.p0.x;
     102        rfb->damage_rect.y = new_rect.p0.y;
     103        rfb->damage_rect.width = new_rect.p1.x - new_rect.p0.x;
     104        rfb->damage_rect.height = new_rect.p1.y - new_rect.p1.y;
     105}
     106
     107/** Set color on RFB.
     108 *
     109 * Set drawing color on RFB GC.
     110 *
     111 * @param arg RFB
     112 * @param color Color
     113 *
     114 * @return EOK on success or an error code
     115 */
     116static errno_t rfb_gc_set_color(void *arg, gfx_color_t *color)
     117{
     118        rfb_gc_t *rfb = (rfb_gc_t *) arg;
     119        uint16_t r, g, b;
     120
     121        gfx_color_get_rgb_i16(color, &r, &g, &b);
     122        rfb->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
     123        return EOK;
     124}
     125
     126/** Fill rectangle on RFB.
     127 *
     128 * @param arg RFB
     129 * @param rect Rectangle
     130 *
     131 * @return EOK on success or an error code
     132 */
     133static errno_t rfb_gc_fill_rect(void *arg, gfx_rect_t *rect)
     134{
     135        rfb_gc_t *rfb = (rfb_gc_t *) arg;
     136        gfx_coord_t x, y;
     137
     138        // XXX We should handle p0.x > p1.x and p0.y > p1.y
     139
     140        for (y = rect->p0.y; y < rect->p1.y; y++) {
     141                for (x = rect->p0.x; x < rect->p1.x; x++) {
     142                        pixelmap_put_pixel(&rfb->rfb.framebuffer, x, y,
     143                            rfb->color);
     144                }
     145        }
     146
     147        rfb_gc_invalidate_rect(rfb, rect);
     148
     149        return EOK;
     150}
     151
     152/** Create bitmap in RFB GC.
     153 *
     154 * @param arg RFB
     155 * @param params Bitmap params
     156 * @param alloc Bitmap allocation info or @c NULL
     157 * @param rbm Place to store pointer to new bitmap
     158 * @return EOK on success or an error code
     159 */
     160errno_t rfb_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     161    gfx_bitmap_alloc_t *alloc, void **rbm)
     162{
     163        rfb_gc_t *rfb = (rfb_gc_t *) arg;
     164        rfb_bitmap_t *rfbbm = NULL;
     165        gfx_coord2_t dim;
     166        errno_t rc;
     167
     168        rfbbm = calloc(1, sizeof(rfb_bitmap_t));
     169        if (rfbbm == NULL)
     170                return ENOMEM;
     171
     172        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
     173        rfbbm->rect = params->rect;
     174
     175        if (alloc == NULL) {
     176                rfbbm->alloc.pitch = dim.x * sizeof(uint32_t);
     177                rfbbm->alloc.off0 = 0;
     178                rfbbm->alloc.pixels = malloc(rfbbm->alloc.pitch * dim.y);
     179                rfbbm->myalloc = true;
     180
     181                if (rfbbm->alloc.pixels == NULL) {
     182                        rc = ENOMEM;
     183                        goto error;
     184                }
     185        } else {
     186                rfbbm->alloc = *alloc;
     187        }
     188
     189        rfbbm->rfb = rfb;
     190        *rbm = (void *)rfbbm;
     191        return EOK;
     192error:
     193        if (rbm != NULL)
     194                free(rfbbm);
     195        return rc;
     196}
     197
     198/** Destroy bitmap in RFB GC.
     199 *
     200 * @param bm Bitmap
     201 * @return EOK on success or an error code
     202 */
     203static errno_t rfb_gc_bitmap_destroy(void *bm)
     204{
     205        rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
     206        if (rfbbm->myalloc)
     207                free(rfbbm->alloc.pixels);
     208        free(rfbbm);
     209        return EOK;
     210}
     211
     212/** Render bitmap in RFB GC.
     213 *
     214 * @param bm Bitmap
     215 * @param srect0 Source rectangle or @c NULL
     216 * @param offs0 Offset or @c NULL
     217 * @return EOK on success or an error code
     218 */
     219static errno_t rfb_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
     220    gfx_coord2_t *offs0)
     221{
     222        rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
     223        gfx_rect_t srect;
     224        gfx_rect_t drect;
     225        gfx_coord2_t offs;
     226        gfx_coord2_t dim;
     227
     228        if (srect0 != NULL)
     229                srect = *srect0;
     230        else
     231                srect = rfbbm->rect;
     232
     233        if (offs0 != NULL) {
     234                offs = *offs0;
     235        } else {
     236                offs.x = 0;
     237                offs.y = 0;
     238        }
     239
     240        /* Destination rectangle */
     241        gfx_rect_translate(&offs, &srect, &drect);
     242
     243        gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
     244
     245        return EOK;
     246}
     247
     248/** Get allocation info for bitmap in RFB GC.
     249 *
     250 * @param bm Bitmap
     251 * @param alloc Place to store allocation info
     252 * @return EOK on success or an error code
     253 */
     254static errno_t rfb_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     255{
     256        rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
     257        *alloc = rfbbm->alloc;
     258        return EOK;
     259}
     260
     261#if 0
    75262static errno_t rfb_handle_damage_pixels(visualizer_t *vs,
    76263    sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
     
    125312        return EOK;
    126313}
    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 };
     314#endif
    141315
    142316static void syntax_print(void)
     
    145319}
    146320
    147 static void client_connection(ipc_call_t *call, void *data)
    148 {
    149         graph_visualizer_connection(vis, call, data);
     321static void client_connection(ipc_call_t *icall, void *arg)
     322{
     323        ddev_srv_t srv;
     324        sysarg_t svc_id;
     325        gfx_context_t *gc;
     326        errno_t rc;
     327
     328        svc_id = ipc_get_arg2(icall);
     329
     330        if (svc_id != 0) {
     331                /* Set up protocol structure */
     332                ddev_srv_initialize(&srv);
     333                srv.ops = &rfb_ddev_ops;
     334                srv.arg = arg;
     335
     336                /* Handle connection */
     337                ddev_conn(icall, &srv);
     338        } else {
     339                rc = gfx_context_new(&rfb_gc_ops, arg, &gc);
     340                if (rc != EOK) {
     341                        async_answer_0(icall, ENOMEM);
     342                        return;
     343                }
     344
     345                /* GC connection */
     346                gc_conn(icall, gc);
     347        }
    150348}
    151349
    152350int main(int argc, char **argv)
    153351{
     352        rfb_t rfb;
     353
    154354        log_init(NAME);
    155355
     
    188388        rfb_init(&rfb, width, height, rfb_name);
    189389
    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);
     390        async_set_fallback_port_handler(client_connection, &rfb);
    218391
    219392        errno_t rc = loc_server_register(NAME);
     
    240413        free(service_name);
    241414
    242         category_id_t visualizer_category;
    243         rc = loc_category_get_id("visualizer", &visualizer_category, IPC_FLAG_BLOCKING);
     415        category_id_t ddev_cid;
     416        rc = loc_category_get_id("display-device", &ddev_cid, IPC_FLAG_BLOCKING);
    244417        if (rc != EOK) {
    245418                fprintf(stderr, NAME ": Unable to get visualizer category id.\n");
     
    247420        }
    248421
    249         rc = loc_service_add_to_cat(service_id, visualizer_category);
     422        rc = loc_service_add_to_cat(service_id, ddev_cid);
    250423        if (rc != EOK) {
    251424                fprintf(stderr, NAME ": Unable to add service to visualizer category.\n");
Note: See TracChangeset for help on using the changeset viewer.