Changes in uspace/srv/hid/rfb/main.c [de19d4a:984a9ba] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/rfb/main.c
rde19d4a r984a9ba 27 27 */ 28 28 29 #include <ddev/info.h> 30 #include <ddev_srv.h> 29 #include <stdlib.h> 31 30 #include <errno.h> 31 #include <loc.h> 32 #include <stdio.h> 32 33 #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> 36 35 #include <inttypes.h> 37 36 #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> 38 43 #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> 44 46 45 47 #include "rfb.h" … … 47 49 #define NAME "rfb" 48 50 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 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; 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 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 63 140 }; 64 141 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_alloc86 };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 RFB141 * @param color Color142 *143 * @return EOK on success or an error code144 */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 RFB158 * @param rect Rectangle159 *160 * @return EOK on success or an error code161 */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.y168 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 RFB184 * @param params Bitmap params185 * @param alloc Bitmap allocation info or @c NULL186 * @param rbm Place to store pointer to new bitmap187 * @return EOK on success or an error code188 */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 Bitmap236 * @return EOK on success or an error code237 */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 Bitmap250 * @param srect0 Source rectangle or @c NULL251 * @param offs0 Offset or @c NULL252 * @return EOK on success or an error code253 */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 else270 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 Bitmap316 * @param alloc Place to store allocation info317 * @return EOK on success or an error code318 */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 326 142 static void syntax_print(void) 327 143 { … … 329 145 } 330 146 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 } 147 static void client_connection(ipc_call_t *call, void *data) 148 { 149 graph_visualizer_connection(vis, call, data); 359 150 } 360 151 361 152 int main(int argc, char **argv) 362 153 { 363 rfb_t rfb;364 365 154 log_init(NAME); 366 155 … … 399 188 rfb_init(&rfb, width, height, rfb_name); 400 189 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); 402 218 403 219 errno_t rc = loc_server_register(NAME); … … 424 240 free(service_name); 425 241 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 devicecategory 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 devicecategory.\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"); 436 252 return 1; 437 253 }
Note:
See TracChangeset
for help on using the changeset viewer.