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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9c96634 was 8d2dd7f2, checked in by Jakub Jermar <jakub@…>, 8 years ago

Reduce the number of files that include <sys/types.h>

  • Property mode set to 100644
File size: 9.7 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 <stddef.h>
41#include <stdint.h>
42#include <errno.h>
43
44#include <malloc.h>
45#include <mem.h>
46#include <as.h>
47#include <align.h>
48
49#include <sysinfo.h>
50#include <ddi.h>
51
52#include <adt/list.h>
53
54#include <io/mode.h>
55#include <io/pixelmap.h>
56#include <io/chargrid.h>
57
58#include <pixconv.h>
59
60#include <graph.h>
61
62#include "kfb.h"
63#include "port.h"
64
65#define FB_POS(x, y) ((y) * kfb.scanline + (x) * kfb.pixel_bytes)
66
67typedef struct {
68 sysarg_t width;
69 sysarg_t height;
70 size_t offset;
71 size_t scanline;
72 visual_t visual;
73
74 pixel2visual_t pixel2visual;
75 visual2pixel_t visual2pixel;
76 visual_mask_t visual_mask;
77 size_t pixel_bytes;
78
79 size_t size;
80 uint8_t *addr;
81} kfb_t;
82
83static kfb_t kfb;
84
85static vslmode_list_element_t pixel_mode;
86
87static pixel_t color_table[16] = {
88 [COLOR_BLACK] = 0x000000,
89 [COLOR_BLUE] = 0x0000f0,
90 [COLOR_GREEN] = 0x00f000,
91 [COLOR_CYAN] = 0x00f0f0,
92 [COLOR_RED] = 0xf00000,
93 [COLOR_MAGENTA] = 0xf000f0,
94 [COLOR_YELLOW] = 0xf0f000,
95 [COLOR_WHITE] = 0xf0f0f0,
96
97 [COLOR_BLACK + 8] = 0x000000,
98 [COLOR_BLUE + 8] = 0x0000ff,
99 [COLOR_GREEN + 8] = 0x00ff00,
100 [COLOR_CYAN + 8] = 0x00ffff,
101 [COLOR_RED + 8] = 0xff0000,
102 [COLOR_MAGENTA + 8] = 0xff00ff,
103 [COLOR_YELLOW + 8] = 0xffff00,
104 [COLOR_WHITE + 8] = 0xffffff,
105};
106
107static inline void attrs_rgb(char_attrs_t attrs, pixel_t *bgcolor, pixel_t *fgcolor)
108{
109 switch (attrs.type) {
110 case CHAR_ATTR_STYLE:
111 switch (attrs.val.style) {
112 case STYLE_NORMAL:
113 *bgcolor = color_table[COLOR_WHITE];
114 *fgcolor = color_table[COLOR_BLACK];
115 break;
116 case STYLE_EMPHASIS:
117 *bgcolor = color_table[COLOR_WHITE];
118 *fgcolor = color_table[COLOR_RED];
119 break;
120 case STYLE_INVERTED:
121 *bgcolor = color_table[COLOR_BLACK];
122 *fgcolor = color_table[COLOR_WHITE];
123 break;
124 case STYLE_SELECTED:
125 *bgcolor = color_table[COLOR_RED];
126 *fgcolor = color_table[COLOR_WHITE];
127 break;
128 }
129 break;
130 case CHAR_ATTR_INDEX:
131 *bgcolor = color_table[(attrs.val.index.bgcolor & 7) |
132 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)];
133 *fgcolor = color_table[(attrs.val.index.fgcolor & 7) |
134 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)];
135 break;
136 case CHAR_ATTR_RGB:
137 *bgcolor = attrs.val.rgb.bgcolor;
138 *fgcolor = attrs.val.rgb.fgcolor;
139 break;
140 }
141}
142
143static int kfb_claim(visualizer_t *vs)
144{
145 return EOK;
146}
147
148static int kfb_yield(visualizer_t *vs)
149{
150 if (vs->mode_set) {
151 vs->ops.handle_damage = NULL;
152 }
153
154 return EOK;
155}
156
157static int kfb_handle_damage_pixels(visualizer_t *vs,
158 sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
159 sysarg_t x_offset, sysarg_t y_offset)
160{
161 pixelmap_t *map = &vs->cells;
162
163 if (x_offset == 0 && y_offset == 0) {
164 /* Faster damage routine ignoring offsets. */
165 for (sysarg_t y = y0; y < height + y0; ++y) {
166 pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
167 for (sysarg_t x = x0; x < width + x0; ++x) {
168 kfb.pixel2visual(kfb.addr + FB_POS(x, y), *pixel++);
169 }
170 }
171 } else {
172 for (sysarg_t y = y0; y < height + y0; ++y) {
173 for (sysarg_t x = x0; x < width + x0; ++x) {
174 kfb.pixel2visual(kfb.addr + FB_POS(x, y),
175 *pixelmap_pixel_at(map,
176 (x + x_offset) % map->width,
177 (y + y_offset) % map->height));
178 }
179 }
180 }
181
182 return EOK;
183}
184
185static int kfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
186{
187 vs->ops.handle_damage = kfb_handle_damage_pixels;
188 return EOK;
189}
190
191static int kfb_suspend(visualizer_t *vs)
192{
193 return EOK;
194}
195
196static int kfb_wakeup(visualizer_t *vs)
197{
198 return EOK;
199}
200
201static visualizer_ops_t kfb_ops = {
202 .claim = kfb_claim,
203 .yield = kfb_yield,
204 .change_mode = kfb_change_mode,
205 .handle_damage = NULL,
206 .suspend = kfb_suspend,
207 .wakeup = kfb_wakeup
208};
209
210static void graph_vsl_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
211{
212 visualizer_t *vsl;
213
214 vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg);
215 graph_visualizer_connection(vsl, iid, icall, NULL);
216}
217
218int port_init(ddf_dev_t *dev)
219{
220 sysarg_t present;
221 int rc = sysinfo_get_value("fb", &present);
222 if (rc != EOK)
223 present = false;
224
225 if (!present)
226 return ENOENT;
227
228 sysarg_t kind;
229 rc = sysinfo_get_value("fb.kind", &kind);
230 if (rc != EOK)
231 kind = (sysarg_t) -1;
232
233 if (kind != 1)
234 return EINVAL;
235
236 sysarg_t paddr;
237 rc = sysinfo_get_value("fb.address.physical", &paddr);
238 if (rc != EOK)
239 return rc;
240
241 sysarg_t offset;
242 rc = sysinfo_get_value("fb.offset", &offset);
243 if (rc != EOK)
244 offset = 0;
245
246 sysarg_t width;
247 rc = sysinfo_get_value("fb.width", &width);
248 if (rc != EOK)
249 return rc;
250
251 sysarg_t height;
252 rc = sysinfo_get_value("fb.height", &height);
253 if (rc != EOK)
254 return rc;
255
256 sysarg_t scanline;
257 rc = sysinfo_get_value("fb.scanline", &scanline);
258 if (rc != EOK)
259 return rc;
260
261 sysarg_t visual;
262 rc = sysinfo_get_value("fb.visual", &visual);
263 if (rc != EOK)
264 return rc;
265
266 kfb.width = width;
267 kfb.height = height;
268 kfb.offset = offset;
269 kfb.scanline = scanline;
270 kfb.visual = visual;
271
272 switch (visual) {
273 case VISUAL_INDIRECT_8:
274 kfb.pixel2visual = pixel2bgr_323;
275 kfb.visual2pixel = bgr_323_2pixel;
276 kfb.visual_mask = visual_mask_323;
277 kfb.pixel_bytes = 1;
278 break;
279 case VISUAL_RGB_5_5_5_LE:
280 kfb.pixel2visual = pixel2rgb_555_le;
281 kfb.visual2pixel = rgb_555_le_2pixel;
282 kfb.visual_mask = visual_mask_555;
283 kfb.pixel_bytes = 2;
284 break;
285 case VISUAL_RGB_5_5_5_BE:
286 kfb.pixel2visual = pixel2rgb_555_be;
287 kfb.visual2pixel = rgb_555_be_2pixel;
288 kfb.visual_mask = visual_mask_555;
289 kfb.pixel_bytes = 2;
290 break;
291 case VISUAL_RGB_5_6_5_LE:
292 kfb.pixel2visual = pixel2rgb_565_le;
293 kfb.visual2pixel = rgb_565_le_2pixel;
294 kfb.visual_mask = visual_mask_565;
295 kfb.pixel_bytes = 2;
296 break;
297 case VISUAL_RGB_5_6_5_BE:
298 kfb.pixel2visual = pixel2rgb_565_be;
299 kfb.visual2pixel = rgb_565_be_2pixel;
300 kfb.visual_mask = visual_mask_565;
301 kfb.pixel_bytes = 2;
302 break;
303 case VISUAL_RGB_8_8_8:
304 kfb.pixel2visual = pixel2rgb_888;
305 kfb.visual2pixel = rgb_888_2pixel;
306 kfb.visual_mask = visual_mask_888;
307 kfb.pixel_bytes = 3;
308 break;
309 case VISUAL_BGR_8_8_8:
310 kfb.pixel2visual = pixel2bgr_888;
311 kfb.visual2pixel = bgr_888_2pixel;
312 kfb.visual_mask = visual_mask_888;
313 kfb.pixel_bytes = 3;
314 break;
315 case VISUAL_RGB_8_8_8_0:
316 kfb.pixel2visual = pixel2rgb_8880;
317 kfb.visual2pixel = rgb_8880_2pixel;
318 kfb.visual_mask = visual_mask_8880;
319 kfb.pixel_bytes = 4;
320 break;
321 case VISUAL_RGB_0_8_8_8:
322 kfb.pixel2visual = pixel2rgb_0888;
323 kfb.visual2pixel = rgb_0888_2pixel;
324 kfb.visual_mask = visual_mask_0888;
325 kfb.pixel_bytes = 4;
326 break;
327 case VISUAL_BGR_0_8_8_8:
328 kfb.pixel2visual = pixel2bgr_0888;
329 kfb.visual2pixel = bgr_0888_2pixel;
330 kfb.visual_mask = visual_mask_0888;
331 kfb.pixel_bytes = 4;
332 break;
333 case VISUAL_BGR_8_8_8_0:
334 kfb.pixel2visual = pixel2bgr_8880;
335 kfb.visual2pixel = bgr_8880_2pixel;
336 kfb.visual_mask = visual_mask_8880;
337 kfb.pixel_bytes = 4;
338 break;
339 default:
340 return EINVAL;
341 }
342
343 kfb.size = scanline * height;
344 kfb.addr = AS_AREA_ANY;
345
346 rc = physmem_map(paddr + offset,
347 ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
348 AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
349 if (rc != EOK)
350 return rc;
351
352 ddf_fun_t *fun_vs = ddf_fun_create(dev, fun_exposed, "vsl0");
353 if (fun_vs == NULL) {
354 as_area_destroy(kfb.addr);
355 return ENOMEM;
356 }
357 ddf_fun_set_conn_handler(fun_vs, &graph_vsl_connection);
358
359 visualizer_t *vs = ddf_fun_data_alloc(fun_vs, sizeof(visualizer_t));
360 if (vs == NULL) {
361 as_area_destroy(kfb.addr);
362 return ENOMEM;
363 }
364 graph_init_visualizer(vs);
365
366 pixel_mode.mode.index = 0;
367 pixel_mode.mode.version = 0;
368 pixel_mode.mode.refresh_rate = 0;
369 pixel_mode.mode.screen_aspect.width = width;
370 pixel_mode.mode.screen_aspect.height = height;
371 pixel_mode.mode.screen_width = width;
372 pixel_mode.mode.screen_height = height;
373 pixel_mode.mode.cell_aspect.width = 1;
374 pixel_mode.mode.cell_aspect.height = 1;
375 pixel_mode.mode.cell_visual.pixel_visual = visual;
376
377 link_initialize(&pixel_mode.link);
378 list_append(&pixel_mode.link, &vs->modes);
379
380 vs->def_mode_idx = 0;
381
382 vs->ops = kfb_ops;
383 vs->dev_ctx = NULL;
384
385 rc = ddf_fun_bind(fun_vs);
386 if (rc != EOK) {
387 list_remove(&pixel_mode.link);
388 ddf_fun_destroy(fun_vs);
389 as_area_destroy(kfb.addr);
390 return rc;
391 }
392
393 vs->reg_svc_handle = ddf_fun_get_handle(fun_vs);
394 ddf_fun_add_to_category(fun_vs, "visualizer");
395
396 return EOK;
397}
398
399/** @}
400 */
Note: See TracBrowser for help on using the repository browser.