Changeset ddb844e in mainline for uspace/srv/hid/rfb/main.c
- Timestamp:
- 2020-07-03T23:00:34Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e79a025
- Parents:
- edb57bc6 (diff), 1a1c75e (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/rfb/main.c
redb57bc6 rddb844e 27 27 */ 28 28 29 #include <stdlib.h> 29 #include <ddev/info.h> 30 #include <ddev_srv.h> 30 31 #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> 31 40 #include <loc.h> 32 41 #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> 38 43 #include <task.h> 39 44 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 47 45 #include "rfb.h" 48 46 49 47 #define NAME "rfb" 50 48 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; 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 63 }; 64 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; 93 100 } 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 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(¶ms->rect.p1, ¶ms->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 } 141 325 142 326 static void syntax_print(void) … … 145 329 } 146 330 147 static void client_connection(ipc_call_t *call, void *data) 148 { 149 graph_visualizer_connection(vis, call, data); 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 } 150 359 } 151 360 152 361 int main(int argc, char **argv) 153 362 { 363 rfb_t rfb; 364 154 365 log_init(NAME); 155 366 … … 188 399 rfb_init(&rfb, width, height, rfb_name); 189 400 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); 218 402 219 403 errno_t rc = loc_server_register(NAME); … … 240 424 free(service_name); 241 425 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); 244 428 if (rc != EOK) { 245 fprintf(stderr, NAME ": Unable to get visualizercategory id.\n");429 fprintf(stderr, NAME ": Unable to get display device category id.\n"); 246 430 return 1; 247 431 } 248 432 249 rc = loc_service_add_to_cat(service_id, visualizer_category);433 rc = loc_service_add_to_cat(service_id, ddev_cid); 250 434 if (rc != EOK) { 251 fprintf(stderr, NAME ": Unable to add service to visualizercategory.\n");435 fprintf(stderr, NAME ": Unable to add service to display device category.\n"); 252 436 return 1; 253 437 }
Note:
See TracChangeset
for help on using the changeset viewer.