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

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

gradually introduce async ports, initial phase

The initial phase is to reimplement the traditional async client connections as an untyped fallback port. This creates the possibility to introduce ports typed by interface type gradually in later changesets.

  • Property mode set to 100644
File size: 6.6 KB
Line 
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>
36#include <io/log.h>
37#include <task.h>
38
39#include <abi/fb/visuals.h>
40#include <adt/list.h>
41#include <io/mode.h>
42#include <io/pixelmap.h>
43#include <io/chargrid.h>
44#include <graph.h>
45
46#include "rfb.h"
47
48#define NAME "rfb"
49
50static vslmode_list_element_t pixel_mode;
51static visualizer_t *vis;
52static rfb_t rfb;
53
54static int rfb_claim(visualizer_t *vs)
55{
56 return EOK;
57}
58
59static int rfb_yield(visualizer_t *vs)
60{
61 return EOK;
62}
63
64static int rfb_suspend(visualizer_t *vs)
65{
66 return EOK;
67}
68
69static int rfb_wakeup(visualizer_t *vs)
70{
71 return EOK;
72}
73
74static int rfb_handle_damage_pixels(visualizer_t *vs,
75 sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
76 sysarg_t x_offset, sysarg_t y_offset)
77{
78 fibril_mutex_lock(&rfb.lock);
79
80 if (x0 + width > rfb.width || y0 + height > rfb.height) {
81 fibril_mutex_unlock(&rfb.lock);
82 return EINVAL;
83 }
84
85 /* TODO update surface_t and use it */
86 if (!rfb.damage_valid) {
87 rfb.damage_rect.x = x0;
88 rfb.damage_rect.y = y0;
89 rfb.damage_rect.width = width;
90 rfb.damage_rect.height = height;
91 rfb.damage_valid = true;
92 }
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 int 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
140};
141
142static void syntax_print(void)
143{
144 fprintf(stderr, "Usage: %s <name> <width> <height> [port]\n", NAME);
145}
146
147static void client_connection(ipc_callid_t callid, ipc_call_t *call, void *data)
148{
149 graph_visualizer_connection(vis, callid, call, data);
150}
151
152int main(int argc, char **argv)
153{
154 log_init(NAME);
155
156 if (argc <= 3) {
157 syntax_print();
158 return 1;
159 }
160
161 const char *rfb_name = argv[1];
162
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 }
170
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 }
177
178 unsigned long port = 5900;
179 if (argc > 4) {
180 port = strtoul(argv[4], &endptr, 0);
181 if (*endptr != 0) {
182 fprintf(stderr, "Invalid port number\n");
183 syntax_print();
184 return 1;
185 }
186 }
187
188 rfb_init(&rfb, width, height, rfb_name);
189
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);
218
219 int rc = loc_server_register(NAME);
220 if (rc != EOK) {
221 printf("%s: Unable to register server.\n", NAME);
222 return rc;
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 }
231
232 service_id_t service_id;
233
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 }
239
240 free(service_name);
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 }
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");
252 return 1;
253 }
254
255 rc = rfb_listen(&rfb, port);
256 if (rc != EOK) {
257 fprintf(stderr, NAME ": Unable to listen at rfb port\n");
258 return 2;
259 }
260
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.