source: mainline/uspace/drv/fb/kfb/port.c@ 0683992

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 0683992 was 8e4a408, checked in by Jiri Svoboda <jiri@…>, 11 years ago

Visualizer should use a custom connection handler instead of a single-method devman interface. This fixes rfb, which was broken.

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/*
2 * Copyright (c) 2006 Jakub Vana
3 * Copyright (c) 2006 Ondrej Palkovsky
4 * Copyright (c) 2008 Martin Decky
5 * Copyright (c) 2011 Petr Koupy
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * - Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * - The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/** @addtogroup kfb
33 * @{
34 */
35/**
36 * @file
37 */
38
39#include <abi/fb/visuals.h>
40#include <sys/types.h>
41#include <errno.h>
42
43#include <malloc.h>
44#include <mem.h>
45#include <as.h>
46#include <align.h>
47
48#include <sysinfo.h>
49#include <ddi.h>
50
51#include <adt/list.h>
52
53#include <io/mode.h>
54#include <io/pixelmap.h>
55#include <io/chargrid.h>
56
57#include <pixconv.h>
58
59#include <graph.h>
60
61#include "kfb.h"
62#include "port.h"
63
64#define FB_POS(x, y) ((y) * kfb.scanline + (x) * kfb.pixel_bytes)
65
66typedef struct {
67 sysarg_t width;
68 sysarg_t height;
69 size_t offset;
70 size_t scanline;
71 visual_t visual;
72
73 pixel2visual_t pixel2visual;
74 visual2pixel_t visual2pixel;
75 visual_mask_t visual_mask;
76 size_t pixel_bytes;
77
78 size_t size;
79 uint8_t *addr;
80} kfb_t;
81
82static kfb_t kfb;
83
84static vslmode_list_element_t pixel_mode;
85
86static pixel_t color_table[16] = {
87 [COLOR_BLACK] = 0x000000,
88 [COLOR_BLUE] = 0x0000f0,
89 [COLOR_GREEN] = 0x00f000,
90 [COLOR_CYAN] = 0x00f0f0,
91 [COLOR_RED] = 0xf00000,
92 [COLOR_MAGENTA] = 0xf000f0,
93 [COLOR_YELLOW] = 0xf0f000,
94 [COLOR_WHITE] = 0xf0f0f0,
95
96 [COLOR_BLACK + 8] = 0x000000,
97 [COLOR_BLUE + 8] = 0x0000ff,
98 [COLOR_GREEN + 8] = 0x00ff00,
99 [COLOR_CYAN + 8] = 0x00ffff,
100 [COLOR_RED + 8] = 0xff0000,
101 [COLOR_MAGENTA + 8] = 0xff00ff,
102 [COLOR_YELLOW + 8] = 0xffff00,
103 [COLOR_WHITE + 8] = 0xffffff,
104};
105
106static inline void attrs_rgb(char_attrs_t attrs, pixel_t *bgcolor, pixel_t *fgcolor)
107{
108 switch (attrs.type) {
109 case CHAR_ATTR_STYLE:
110 switch (attrs.val.style) {
111 case STYLE_NORMAL:
112 *bgcolor = color_table[COLOR_WHITE];
113 *fgcolor = color_table[COLOR_BLACK];
114 break;
115 case STYLE_EMPHASIS:
116 *bgcolor = color_table[COLOR_WHITE];
117 *fgcolor = color_table[COLOR_RED];
118 break;
119 case STYLE_INVERTED:
120 *bgcolor = color_table[COLOR_BLACK];
121 *fgcolor = color_table[COLOR_WHITE];
122 break;
123 case STYLE_SELECTED:
124 *bgcolor = color_table[COLOR_RED];
125 *fgcolor = color_table[COLOR_WHITE];
126 break;
127 }
128 break;
129 case CHAR_ATTR_INDEX:
130 *bgcolor = color_table[(attrs.val.index.bgcolor & 7) |
131 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)];
132 *fgcolor = color_table[(attrs.val.index.fgcolor & 7) |
133 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)];
134 break;
135 case CHAR_ATTR_RGB:
136 *bgcolor = attrs.val.rgb.bgcolor;
137 *fgcolor = attrs.val.rgb.fgcolor;
138 break;
139 }
140}
141
142static int kfb_claim(visualizer_t *vs)
143{
144 return EOK;
145}
146
147static int kfb_yield(visualizer_t *vs)
148{
149 if (vs->mode_set) {
150 vs->ops.handle_damage = NULL;
151 }
152
153 return EOK;
154}
155
156static int kfb_handle_damage_pixels(visualizer_t *vs,
157 sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
158 sysarg_t x_offset, sysarg_t y_offset)
159{
160 pixelmap_t *map = &vs->cells;
161
162 if (x_offset == 0 && y_offset == 0) {
163 /* Faster damage routine ignoring offsets. */
164 for (sysarg_t y = y0; y < height + y0; ++y) {
165 pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
166 for (sysarg_t x = x0; x < width + x0; ++x) {
167 kfb.pixel2visual(kfb.addr + FB_POS(x, y), *pixel++);
168 }
169 }
170 } else {
171 for (sysarg_t y = y0; y < height + y0; ++y) {
172 for (sysarg_t x = x0; x < width + x0; ++x) {
173 kfb.pixel2visual(kfb.addr + FB_POS(x, y),
174 *pixelmap_pixel_at(map,
175 (x + x_offset) % map->width,
176 (y + y_offset) % map->height));
177 }
178 }
179 }
180
181 return EOK;
182}
183
184static int kfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
185{
186 vs->ops.handle_damage = kfb_handle_damage_pixels;
187 return EOK;
188}
189
190static int kfb_suspend(visualizer_t *vs)
191{
192 return EOK;
193}
194
195static int kfb_wakeup(visualizer_t *vs)
196{
197 return EOK;
198}
199
200static visualizer_ops_t kfb_ops = {
201 .claim = kfb_claim,
202 .yield = kfb_yield,
203 .change_mode = kfb_change_mode,
204 .handle_damage = NULL,
205 .suspend = kfb_suspend,
206 .wakeup = kfb_wakeup
207};
208
209static void graph_vsl_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
210{
211 visualizer_t *vsl;
212
213 vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg);
214 graph_visualizer_connection(vsl, iid, icall, NULL);
215}
216
217int port_init(ddf_dev_t *dev)
218{
219 sysarg_t present;
220 int rc = sysinfo_get_value("fb", &present);
221 if (rc != EOK)
222 present = false;
223
224 if (!present)
225 return ENOENT;
226
227 sysarg_t kind;
228 rc = sysinfo_get_value("fb.kind", &kind);
229 if (rc != EOK)
230 kind = (sysarg_t) -1;
231
232 if (kind != 1)
233 return EINVAL;
234
235 sysarg_t paddr;
236 rc = sysinfo_get_value("fb.address.physical", &paddr);
237 if (rc != EOK)
238 return rc;
239
240 sysarg_t offset;
241 rc = sysinfo_get_value("fb.offset", &offset);
242 if (rc != EOK)
243 offset = 0;
244
245 sysarg_t width;
246 rc = sysinfo_get_value("fb.width", &width);
247 if (rc != EOK)
248 return rc;
249
250 sysarg_t height;
251 rc = sysinfo_get_value("fb.height", &height);
252 if (rc != EOK)
253 return rc;
254
255 sysarg_t scanline;
256 rc = sysinfo_get_value("fb.scanline", &scanline);
257 if (rc != EOK)
258 return rc;
259
260 sysarg_t visual;
261 rc = sysinfo_get_value("fb.visual", &visual);
262 if (rc != EOK)
263 return rc;
264
265 kfb.width = width;
266 kfb.height = height;
267 kfb.offset = offset;
268 kfb.scanline = scanline;
269 kfb.visual = visual;
270
271 switch (visual) {
272 case VISUAL_INDIRECT_8:
273 kfb.pixel2visual = pixel2bgr_323;
274 kfb.visual2pixel = bgr_323_2pixel;
275 kfb.visual_mask = visual_mask_323;
276 kfb.pixel_bytes = 1;
277 break;
278 case VISUAL_RGB_5_5_5_LE:
279 kfb.pixel2visual = pixel2rgb_555_le;
280 kfb.visual2pixel = rgb_555_le_2pixel;
281 kfb.visual_mask = visual_mask_555;
282 kfb.pixel_bytes = 2;
283 break;
284 case VISUAL_RGB_5_5_5_BE:
285 kfb.pixel2visual = pixel2rgb_555_be;
286 kfb.visual2pixel = rgb_555_be_2pixel;
287 kfb.visual_mask = visual_mask_555;
288 kfb.pixel_bytes = 2;
289 break;
290 case VISUAL_RGB_5_6_5_LE:
291 kfb.pixel2visual = pixel2rgb_565_le;
292 kfb.visual2pixel = rgb_565_le_2pixel;
293 kfb.visual_mask = visual_mask_565;
294 kfb.pixel_bytes = 2;
295 break;
296 case VISUAL_RGB_5_6_5_BE:
297 kfb.pixel2visual = pixel2rgb_565_be;
298 kfb.visual2pixel = rgb_565_be_2pixel;
299 kfb.visual_mask = visual_mask_565;
300 kfb.pixel_bytes = 2;
301 break;
302 case VISUAL_RGB_8_8_8:
303 kfb.pixel2visual = pixel2rgb_888;
304 kfb.visual2pixel = rgb_888_2pixel;
305 kfb.visual_mask = visual_mask_888;
306 kfb.pixel_bytes = 3;
307 break;
308 case VISUAL_BGR_8_8_8:
309 kfb.pixel2visual = pixel2bgr_888;
310 kfb.visual2pixel = bgr_888_2pixel;
311 kfb.visual_mask = visual_mask_888;
312 kfb.pixel_bytes = 3;
313 break;
314 case VISUAL_RGB_8_8_8_0:
315 kfb.pixel2visual = pixel2rgb_8880;
316 kfb.visual2pixel = rgb_8880_2pixel;
317 kfb.visual_mask = visual_mask_8880;
318 kfb.pixel_bytes = 4;
319 break;
320 case VISUAL_RGB_0_8_8_8:
321 kfb.pixel2visual = pixel2rgb_0888;
322 kfb.visual2pixel = rgb_0888_2pixel;
323 kfb.visual_mask = visual_mask_0888;
324 kfb.pixel_bytes = 4;
325 break;
326 case VISUAL_BGR_0_8_8_8:
327 kfb.pixel2visual = pixel2bgr_0888;
328 kfb.visual2pixel = bgr_0888_2pixel;
329 kfb.visual_mask = visual_mask_0888;
330 kfb.pixel_bytes = 4;
331 break;
332 case VISUAL_BGR_8_8_8_0:
333 kfb.pixel2visual = pixel2bgr_8880;
334 kfb.visual2pixel = bgr_8880_2pixel;
335 kfb.visual_mask = visual_mask_8880;
336 kfb.pixel_bytes = 4;
337 break;
338 default:
339 return EINVAL;
340 }
341
342 kfb.size = scanline * height;
343 kfb.addr = AS_AREA_ANY;
344
345 rc = physmem_map(paddr + offset,
346 ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
347 AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
348 if (rc != EOK)
349 return rc;
350
351 ddf_fun_t *fun_vs = ddf_fun_create(dev, fun_exposed, "vsl0");
352 if (fun_vs == NULL) {
353 as_area_destroy(kfb.addr);
354 return ENOMEM;
355 }
356 ddf_fun_set_conn_handler(fun_vs, &graph_vsl_connection);
357
358 visualizer_t *vs = ddf_fun_data_alloc(fun_vs, sizeof(visualizer_t));
359 if (vs == NULL) {
360 as_area_destroy(kfb.addr);
361 return ENOMEM;
362 }
363 graph_init_visualizer(vs);
364
365 pixel_mode.mode.index = 0;
366 pixel_mode.mode.version = 0;
367 pixel_mode.mode.refresh_rate = 0;
368 pixel_mode.mode.screen_aspect.width = width;
369 pixel_mode.mode.screen_aspect.height = height;
370 pixel_mode.mode.screen_width = width;
371 pixel_mode.mode.screen_height = height;
372 pixel_mode.mode.cell_aspect.width = 1;
373 pixel_mode.mode.cell_aspect.height = 1;
374 pixel_mode.mode.cell_visual.pixel_visual = visual;
375
376 link_initialize(&pixel_mode.link);
377 list_append(&pixel_mode.link, &vs->modes);
378
379 vs->def_mode_idx = 0;
380
381 vs->ops = kfb_ops;
382 vs->dev_ctx = NULL;
383
384 rc = ddf_fun_bind(fun_vs);
385 if (rc != EOK) {
386 list_remove(&pixel_mode.link);
387 ddf_fun_destroy(fun_vs);
388 as_area_destroy(kfb.addr);
389 return rc;
390 }
391
392 vs->reg_svc_handle = ddf_fun_get_handle(fun_vs);
393 ddf_fun_add_to_category(fun_vs, "visualizer");
394
395 return EOK;
396}
397
398/** @}
399 */
Note: See TracBrowser for help on using the repository browser.