source: mainline/uspace/srv/hid/rfb/main.c@ 3083c74

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3083c74 was 984a9ba, checked in by Martin Decky <martin@…>, 7 years ago

do not expose the call capability handler from the async framework

Keep the call capability handler encapsulated within the async framework
and do not expose it explicitly via its API. Use the pointer to
ipc_call_t as the sole object identifying an IPC call in the code that
uses the async framework.

This plugs a major leak in the abstraction and also simplifies both the
async framework (slightly) and all IPC servers.

  • Property mode set to 100644
File size: 6.6 KB
RevLine 
[bd0e6a1]1/*
2 * Copyright (c) 2013 Martin Sucha
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <stdlib.h>
30#include <errno.h>
31#include <loc.h>
32#include <stdio.h>
33#include <fibril_synch.h>
34#include <abi/ipc/methods.h>
35#include <inttypes.h>
[47b27b40]36#include <io/log.h>
[1d6dd2a]37#include <str.h>
[1c635d6]38#include <task.h>
[bd0e6a1]39
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#include "rfb.h"
48
49#define NAME "rfb"
50
51static vslmode_list_element_t pixel_mode;
52static visualizer_t *vis;
53static rfb_t rfb;
54
[b7fd2a0]55static errno_t rfb_claim(visualizer_t *vs)
[bd0e6a1]56{
57 return EOK;
58}
59
[b7fd2a0]60static errno_t rfb_yield(visualizer_t *vs)
[bd0e6a1]61{
62 return EOK;
63}
64
[b7fd2a0]65static errno_t rfb_suspend(visualizer_t *vs)
[bd0e6a1]66{
67 return EOK;
68}
69
[b7fd2a0]70static errno_t rfb_wakeup(visualizer_t *vs)
[bd0e6a1]71{
72 return EOK;
73}
74
[b7fd2a0]75static errno_t rfb_handle_damage_pixels(visualizer_t *vs,
[bd0e6a1]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);
[a35b458]80
[bd0e6a1]81 if (x0 + width > rfb.width || y0 + height > rfb.height) {
82 fibril_mutex_unlock(&rfb.lock);
83 return EINVAL;
84 }
[a35b458]85
[bd0e6a1]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;
[1433ecda]93 } else {
[bd0e6a1]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 }
[a35b458]113
[bd0e6a1]114 pixelmap_t *map = &vs->cells;
[a35b458]115
[bd0e6a1]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 }
[a35b458]123
[bd0e6a1]124 fibril_mutex_unlock(&rfb.lock);
125 return EOK;
126}
127
[b7fd2a0]128static errno_t rfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
[bd0e6a1]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
140};
141
142static void syntax_print(void)
143{
[0d23cc0]144 fprintf(stderr, "Usage: %s <name> <width> <height> [port]\n", NAME);
[bd0e6a1]145}
146
[984a9ba]147static void client_connection(ipc_call_t *call, void *data)
[bd0e6a1]148{
[984a9ba]149 graph_visualizer_connection(vis, call, data);
[bd0e6a1]150}
151
152int main(int argc, char **argv)
153{
[47b27b40]154 log_init(NAME);
155
[0d23cc0]156 if (argc <= 3) {
[bd0e6a1]157 syntax_print();
158 return 1;
159 }
160
[0d23cc0]161 const char *rfb_name = argv[1];
[a35b458]162
[0d23cc0]163 char *endptr;
164 unsigned long width = strtoul(argv[2], &endptr, 0);
165 if (*endptr != 0) {
166 fprintf(stderr, "Invalid width\n");
167 syntax_print();
168 return 1;
169 }
[a35b458]170
[0d23cc0]171 unsigned long height = strtoul(argv[3], &endptr, 0);
172 if (*endptr != 0) {
173 fprintf(stderr, "Invalid height\n");
174 syntax_print();
175 return 1;
176 }
[a35b458]177
[0d23cc0]178 unsigned long port = 5900;
179 if (argc > 4) {
180 port = strtoul(argv[4], &endptr, 0);
[bd0e6a1]181 if (*endptr != 0) {
182 fprintf(stderr, "Invalid port number\n");
183 syntax_print();
184 return 1;
185 }
186 }
[a35b458]187
[0d23cc0]188 rfb_init(&rfb, width, height, rfb_name);
[a35b458]189
[bd0e6a1]190 vis = malloc(sizeof(visualizer_t));
191 if (vis == NULL) {
192 fprintf(stderr, "Failed allocating visualizer struct\n");
193 return 3;
194 }
[a35b458]195
[bd0e6a1]196 graph_init_visualizer(vis);
[a35b458]197
[bd0e6a1]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;
[a35b458]208
[bd0e6a1]209 link_initialize(&pixel_mode.link);
210 list_append(&pixel_mode.link, &vis->modes);
[a35b458]211
[bd0e6a1]212 vis->def_mode_idx = 0;
[a35b458]213
[bd0e6a1]214 vis->ops = rfb_ops;
215 vis->dev_ctx = NULL;
216
[b688fd8]217 async_set_fallback_port_handler(client_connection, NULL);
[bd0e6a1]218
[b7fd2a0]219 errno_t rc = loc_server_register(NAME);
[bd0e6a1]220 if (rc != EOK) {
221 printf("%s: Unable to register server.\n", NAME);
222 return rc;
[0d23cc0]223 }
224
225 char *service_name;
226 rc = asprintf(&service_name, "rfb/%s", rfb_name);
227 if (rc < 0) {
228 printf(NAME ": Unable to create service name\n");
229 return rc;
230 }
[bd0e6a1]231
232 service_id_t service_id;
[a35b458]233
[bd0e6a1]234 rc = loc_service_register(service_name, &service_id);
235 if (rc != EOK) {
236 printf(NAME ": Unable to register service %s.\n", service_name);
237 return rc;
238 }
[a35b458]239
[0d23cc0]240 free(service_name);
[bd0e6a1]241
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 }
[a35b458]248
[bd0e6a1]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");
252 return 1;
253 }
[a35b458]254
[bd0e6a1]255 rc = rfb_listen(&rfb, port);
[47b27b40]256 if (rc != EOK) {
257 fprintf(stderr, NAME ": Unable to listen at rfb port\n");
[bd0e6a1]258 return 2;
[47b27b40]259 }
[a35b458]260
[bd0e6a1]261 printf("%s: Accepting connections\n", NAME);
262 task_retval(0);
263 async_manager();
264
265 /* Not reached */
266 return 0;
267}
Note: See TracBrowser for help on using the repository browser.