source: mainline/uspace/srv/hid/output/port/kfb.c@ 46f7b64

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 46f7b64 was 3bacee1, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Make ccheck-fix again and commit more good files.

  • Property mode set to 100644
File size: 20.0 KB
Line 
1/*
2 * Copyright (c) 2008 Martin Decky
3 * Copyright (c) 2006 Jakub Vana
4 * Copyright (c) 2006 Ondrej Palkovsky
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/** @file
32 */
33
34#include <abi/fb/visuals.h>
35#include <sys/types.h>
36#include <inttypes.h>
37#include <screenbuffer.h>
38#include <imgmap.h>
39#include <errno.h>
40#include <bool.h>
41#include <sysinfo.h>
42#include <ddi.h>
43#include <stdlib.h>
44#include <mem.h>
45#include <as.h>
46#include <align.h>
47#include "../gfx/font-8x16.h"
48#include "../fb.h"
49#include "kfb.h"
50
51#define DEFAULT_BGCOLOR 0xffffff
52#define DEFAULT_FGCOLOR 0x000000
53
54#define FB_POS(x, y) ((y) * kfb.scanline + (x) * kfb.pixel_bytes)
55
56#define COL2X(col) ((col) * FONT_WIDTH)
57#define ROW2Y(row) ((row) * FONT_SCANLINES)
58#define X2COL(x) ((x) / FONT_WIDTH)
59#define Y2ROW(y) ((y) / FONT_SCANLINES)
60
61#define GLYPH_POS(glyph, y, inverted) \
62 (((glyph) + (inverted) * FONT_GLYPHS) * (kfb.glyph_bytes) + (y) * (kfb.glyph_scanline))
63
64#define POINTER_WIDTH 11
65#define POINTER_HEIGHT 18
66
67static uint8_t pointer[] = {
68 0x01, 0x00, 0x03, 0x00, 0x05, 0x00, 0x09, 0x00, 0x11, 0x00, 0x21, 0x00,
69 0x41, 0x00, 0x81, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x04, 0x01, 0x03,
70 0x81, 0x00, 0x89, 0x00, 0x15, 0x01, 0x23, 0x01, 0x21, 0x01, 0xc0, 0x00
71};
72
73static uint8_t pointer_mask[] = {
74 0x01, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x3f, 0x00,
75 0x7f, 0x00, 0xff, 0x00, 0xff, 0x01, 0xff, 0x03, 0xff, 0x07, 0xff, 0x03,
76 0xff, 0x00, 0xff, 0x00, 0xf7, 0x01, 0xe3, 0x01, 0xe1, 0x01, 0xc0, 0x00
77};
78
79/** Function to draw a character. */
80typedef void (*draw_char_t)(sysarg_t, sysarg_t, bool, wchar_t, pixel_t,
81 pixel_t);
82
83typedef struct {
84 sysarg_t width;
85 sysarg_t height;
86 size_t offset;
87 size_t scanline;
88 visual_t visual;
89
90 size_t size;
91 uint8_t *addr;
92
93 pixel2visual_t pixel2visual;
94 visual2pixel_t visual2pixel;
95 visual_mask_t visual_mask;
96 size_t pixel_bytes;
97
98 sysarg_t pointer_x;
99 sysarg_t pointer_y;
100 bool pointer_visible;
101 imgmap_t *pointer_imgmap;
102
103 /*
104 * Pre-rendered mask for rendering
105 * glyphs. Specific for the framebuffer
106 * visual.
107 */
108
109 size_t glyph_scanline;
110 size_t glyph_bytes;
111 uint8_t *glyphs;
112
113 uint8_t *backbuf;
114} kfb_t;
115
116typedef struct {
117 /**
118 * Character drawing function for this viewport.
119 * Different viewports might use different drawing
120 * functions depending on whether their scanlines
121 * are aligned on a word boundary.
122 */
123 draw_char_t draw_char;
124} kfb_vp_t;
125
126static kfb_t kfb;
127
128static pixel_t color_table[16] = {
129 [COLOR_BLACK] = 0x000000,
130 [COLOR_BLUE] = 0x0000f0,
131 [COLOR_GREEN] = 0x00f000,
132 [COLOR_CYAN] = 0x00f0f0,
133 [COLOR_RED] = 0xf00000,
134 [COLOR_MAGENTA] = 0xf000f0,
135 [COLOR_YELLOW] = 0xf0f000,
136 [COLOR_WHITE] = 0xf0f0f0,
137
138 [COLOR_BLACK + 8] = 0x000000,
139 [COLOR_BLUE + 8] = 0x0000ff,
140 [COLOR_GREEN + 8] = 0x00ff00,
141 [COLOR_CYAN + 8] = 0x00ffff,
142 [COLOR_RED + 8] = 0xff0000,
143 [COLOR_MAGENTA + 8] = 0xff00ff,
144 [COLOR_YELLOW + 8] = 0xffff00,
145 [COLOR_WHITE + 8] = 0xffffff,
146};
147
148static void put_pixel(sysarg_t x, sysarg_t y, pixel_t pixel)
149{
150 if ((x >= kfb.width) || (y >= kfb.height))
151 return;
152
153 kfb.pixel2visual(kfb.addr + FB_POS(x, y), pixel);
154}
155
156static pixel_t get_pixel(sysarg_t x, sysarg_t y)
157{
158 if ((x >= kfb.width) || (y >= kfb.height))
159 return 0;
160
161 return kfb.visual2pixel(kfb.addr + FB_POS(x, y));
162}
163
164static void pointer_show(void)
165{
166 if (kfb.pointer_visible) {
167 for (sysarg_t y = 0; y < POINTER_HEIGHT; y++) {
168 for (sysarg_t x = 0; x < POINTER_WIDTH; x++) {
169 sysarg_t dx = kfb.pointer_x + x;
170 sysarg_t dy = kfb.pointer_y + y;
171
172 pixel_t pixel = get_pixel(dx, dy);
173 imgmap_put_pixel(kfb.pointer_imgmap, x, y, pixel);
174
175 size_t offset = y * ((POINTER_WIDTH - 1) / 8 + 1) + x / 8;
176 bool visible = pointer_mask[offset] & (1 << (x % 8));
177
178 if (visible) {
179 pixel = (pointer[offset] & (1 << (x % 8))) ?
180 0x000000 : 0xffffff;
181 put_pixel(dx, dy, pixel);
182 }
183 }
184 }
185 }
186}
187
188static void pointer_hide(void)
189{
190 if (kfb.pointer_visible) {
191 for (sysarg_t y = 0; y < POINTER_HEIGHT; y++) {
192 for (sysarg_t x = 0; x < POINTER_WIDTH; x++) {
193 sysarg_t dx = kfb.pointer_x + x;
194 sysarg_t dy = kfb.pointer_y + y;
195
196 pixel_t pixel =
197 imgmap_get_pixel(kfb.pointer_imgmap, x, y);
198 put_pixel(dx, dy, pixel);
199 }
200 }
201 }
202}
203
204/** Draw a filled rectangle.
205 *
206 */
207static void draw_filled_rect(sysarg_t x1, sysarg_t y1, sysarg_t x2, sysarg_t y2,
208 pixel_t color)
209{
210 if ((y1 >= y2) || (x1 >= x2))
211 return;
212
213 uint8_t cbuf[4];
214 kfb.pixel2visual(cbuf, color);
215
216 for (sysarg_t y = y1; y < y2; y++) {
217 uint8_t *dst = kfb.addr + FB_POS(x1, y);
218
219 for (sysarg_t x = x1; x < x2; x++) {
220 memcpy(dst, cbuf, kfb.pixel_bytes);
221 dst += kfb.pixel_bytes;
222 }
223 }
224}
225
226static void vp_put_pixel(fbvp_t *vp, sysarg_t x, sysarg_t y, pixel_t pixel)
227{
228 put_pixel(vp->x + x, vp->y + y, pixel);
229}
230
231static void attrs_rgb(char_attrs_t attrs, pixel_t *bgcolor, pixel_t *fgcolor)
232{
233 switch (attrs.type) {
234 case CHAR_ATTR_STYLE:
235 switch (attrs.val.style) {
236 case STYLE_NORMAL:
237 *bgcolor = color_table[COLOR_WHITE];
238 *fgcolor = color_table[COLOR_BLACK];
239 break;
240 case STYLE_EMPHASIS:
241 *bgcolor = color_table[COLOR_WHITE];
242 *fgcolor = color_table[COLOR_RED];
243 break;
244 case STYLE_INVERTED:
245 *bgcolor = color_table[COLOR_BLACK];
246 *fgcolor = color_table[COLOR_WHITE];
247 break;
248 case STYLE_SELECTED:
249 *bgcolor = color_table[COLOR_RED];
250 *fgcolor = color_table[COLOR_WHITE];
251 break;
252 }
253 break;
254 case CHAR_ATTR_INDEX:
255 *bgcolor = color_table[(attrs.val.index.bgcolor & 7) |
256 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)];
257 *fgcolor = color_table[(attrs.val.index.fgcolor & 7) |
258 ((attrs.val.index.attr & CATTR_BRIGHT) ? 8 : 0)];
259 break;
260 case CHAR_ATTR_RGB:
261 *bgcolor = attrs.val.rgb.bgcolor;
262 *fgcolor = attrs.val.rgb.fgcolor;
263 break;
264 }
265}
266
267/** Draw a character, takes advantage of alignment.
268 *
269 * This version can only be used if the following conditions are met:
270 *
271 * - word size is divisible by pixel_bytes
272 * - cell scanline size is divisible by word size
273 * - cell scanlines are word-aligned
274 *
275 * It makes use of the pre-rendered mask to process (possibly) several
276 * pixels at once (word size / pixel_bytes pixels at a time are processed)
277 * making it very fast. Most notably this version is not applicable at 24 bits
278 * per pixel.
279 *
280 * @param x X coordinate of top-left corner on screen.
281 * @param y Y coordinate of top-left corner on screen.
282 * @param inverted Draw inverted character.
283 * @param ch Character to draw.
284 * @param bgcolor Background color.
285 * @param fbgcolor Foreground color.
286 *
287 */
288static void draw_char_aligned(sysarg_t x, sysarg_t y, bool inverted, wchar_t ch,
289 pixel_t bgcolor, pixel_t fgcolor)
290{
291 size_t word_size = sizeof(unsigned long);
292
293 /*
294 * Prepare a pair of words, one filled with foreground-color
295 * pattern and the other filled with background-color pattern.
296 */
297 unsigned long fg_buf;
298 unsigned long bg_buf;
299
300 for (size_t i = 0; i < word_size / kfb.pixel_bytes; i++) {
301 kfb.pixel2visual(&((uint8_t *) &bg_buf)[i * kfb.pixel_bytes],
302 bgcolor);
303 kfb.pixel2visual(&((uint8_t *) &fg_buf)[i * kfb.pixel_bytes],
304 fgcolor);
305 }
306
307 /* Pointer to the current position in the mask. */
308 unsigned long *maskp =
309 (unsigned long *) &kfb.glyphs[GLYPH_POS(
310 fb_font_glyph(ch), 0, inverted)];
311
312 /* Pointer to the current position on the screen. */
313 unsigned long *dst =
314 (unsigned long *) &kfb.addr[FB_POS(x, y)];
315
316 /* Width of the character cell in words. */
317 size_t ww = FONT_WIDTH * kfb.pixel_bytes / word_size;
318
319 /* Offset to add when moving to another screen scanline. */
320 size_t d_add = kfb.scanline - FONT_WIDTH * kfb.pixel_bytes;
321
322 for (size_t yd = 0; yd < FONT_SCANLINES; yd++) {
323 /*
324 * Now process the cell scanline, combining foreground
325 * and background color patters using the pre-rendered mask.
326 */
327 for (size_t i = 0; i < ww; i++) {
328 unsigned long mask = *maskp++;
329 *dst++ = (fg_buf & mask) | (bg_buf & ~mask);
330 }
331
332 /* Move to the beginning of the next scanline of the cell. */
333 dst = (unsigned long *) ((uint8_t *) dst + d_add);
334 }
335}
336
337/** Draw a character, fallback version.
338 *
339 * This version does not make use of the pre-rendered mask, it uses
340 * the font bitmap directly. It works always, but it is slower.
341 *
342 * @param x X coordinate of top-left corner on screen.
343 * @param y Y coordinate of top-left corner on screen.
344 * @param inverted Draw inverted character.
345 * @param ch Character to draw.
346 * @param bgcolor Background color.
347 * @param fgcolor Foreground color.
348 *
349 */
350static void draw_char_fallback(sysarg_t x, sysarg_t y, bool inverted,
351 wchar_t ch, pixel_t bgcolor, pixel_t fgcolor)
352{
353 /* Character glyph */
354 uint16_t glyph = fb_font_glyph(ch);
355
356 /* Pre-render the foreground and background color pixels. */
357 uint8_t fg_buf[4];
358 uint8_t bg_buf[4];
359
360 if (inverted) {
361 kfb.pixel2visual(bg_buf, fgcolor);
362 kfb.pixel2visual(fg_buf, bgcolor);
363 } else {
364 kfb.pixel2visual(bg_buf, bgcolor);
365 kfb.pixel2visual(fg_buf, fgcolor);
366 }
367
368 /* Pointer to the current position on the screen. */
369 uint8_t *dst = (uint8_t *) &kfb.addr[FB_POS(x, y)];
370
371 /* Offset to add when moving to another screen scanline. */
372 size_t d_add = kfb.scanline - FONT_WIDTH * kfb.pixel_bytes;
373
374 for (size_t yd = 0; yd < FONT_SCANLINES; yd++) {
375 /* Byte containing bits of the glyph scanline. */
376 uint8_t byte = fb_font[glyph][yd];
377
378 for (size_t i = 0; i < FONT_WIDTH; i++) {
379 /* Choose color based on the current bit. */
380 uint8_t *src = (byte & 0x80) ? fg_buf : bg_buf;
381
382 /* Copy the pixel. */
383 for (size_t j = 0; j < kfb.pixel_bytes; j++)
384 *dst++ = *src++;
385
386 /* Move to the next bit. */
387 byte <<= 1;
388 }
389
390 /* Move to the beginning of the next scanline of the cell. */
391 dst += d_add;
392 }
393}
394
395/** Draw the character at the specified position in viewport.
396 *
397 * @param vp Viewport.
398 * @param col Screen position relative to viewport.
399 * @param row Screen position relative to viewport.
400 *
401 */
402static void draw_vp_char(fbvp_t *vp, sysarg_t col, sysarg_t row)
403{
404 kfb_vp_t *kfb_vp = (kfb_vp_t *) vp->data;
405
406 sysarg_t x = vp->x + COL2X(col);
407 sysarg_t y = vp->y + ROW2Y(row);
408
409 charfield_t *field = screenbuffer_field_at(vp->backbuf, col, row);
410
411 pixel_t bgcolor = 0;
412 pixel_t fgcolor = 0;
413 attrs_rgb(field->attrs, &bgcolor, &fgcolor);
414
415 bool inverted = (vp->cursor_flash) &&
416 screenbuffer_cursor_at(vp->backbuf, col, row);
417
418 (*kfb_vp->draw_char)(x, y, inverted, field->ch, bgcolor, fgcolor);
419}
420
421static errno_t kfb_yield(fbdev_t *dev)
422{
423 if (kfb.backbuf == NULL) {
424 kfb.backbuf =
425 malloc(kfb.width * kfb.height * kfb.pixel_bytes);
426 if (kfb.backbuf == NULL)
427 return ENOMEM;
428 }
429
430 for (sysarg_t y = 0; y < kfb.height; y++)
431 memcpy(kfb.backbuf + y * kfb.width * kfb.pixel_bytes,
432 kfb.addr + FB_POS(0, y), kfb.width * kfb.pixel_bytes);
433
434 return EOK;
435}
436
437static errno_t kfb_claim(fbdev_t *dev)
438{
439 if (kfb.backbuf == NULL)
440 return ENOENT;
441
442 for (sysarg_t y = 0; y < kfb.height; y++)
443 memcpy(kfb.addr + FB_POS(0, y),
444 kfb.backbuf + y * kfb.width * kfb.pixel_bytes,
445 kfb.width * kfb.pixel_bytes);
446
447 return EOK;
448}
449
450static void kfb_pointer_update(struct fbdev *dev, sysarg_t x, sysarg_t y,
451 bool visible)
452{
453 pointer_hide();
454
455 kfb.pointer_x = x;
456 kfb.pointer_y = y;
457 kfb.pointer_visible = visible;
458
459 pointer_show();
460}
461
462static errno_t kfb_get_resolution(fbdev_t *dev, sysarg_t *width, sysarg_t *height)
463{
464 *width = kfb.width;
465 *height = kfb.height;
466 return EOK;
467}
468
469static void kfb_font_metrics(fbdev_t *dev, sysarg_t width, sysarg_t height,
470 sysarg_t *cols, sysarg_t *rows)
471{
472 *cols = X2COL(width);
473 *rows = Y2ROW(height);
474}
475
476static errno_t kfb_vp_create(fbdev_t *dev, fbvp_t *vp)
477{
478 kfb_vp_t *kfb_vp = malloc(sizeof(kfb_vp_t));
479 if (kfb_vp == NULL)
480 return ENOMEM;
481
482 /*
483 * Conditions necessary to select aligned glyph
484 * drawing variants:
485 * - word size is divisible by number of bytes per pixel
486 * - cell scanline size is divisible by word size
487 * - cell scanlines are word-aligned
488 *
489 */
490 size_t word_size = sizeof(unsigned long);
491
492 if (((word_size % kfb.pixel_bytes) == 0) &&
493 ((FONT_WIDTH * kfb.pixel_bytes) % word_size == 0) &&
494 ((vp->x * kfb.pixel_bytes) % word_size == 0) &&
495 (kfb.scanline % word_size == 0))
496 kfb_vp->draw_char = draw_char_aligned;
497 else
498 kfb_vp->draw_char = draw_char_fallback;
499
500 vp->attrs.type = CHAR_ATTR_RGB;
501 vp->attrs.val.rgb.bgcolor = DEFAULT_BGCOLOR;
502 vp->attrs.val.rgb.fgcolor = DEFAULT_FGCOLOR;
503 vp->data = (void *) kfb_vp;
504
505 return EOK;
506}
507
508static void kfb_vp_destroy(fbdev_t *dev, fbvp_t *vp)
509{
510 free(vp->data);
511}
512
513static void kfb_vp_clear(fbdev_t *dev, fbvp_t *vp)
514{
515 pointer_hide();
516
517 for (sysarg_t row = 0; row < vp->rows; row++) {
518 for (sysarg_t col = 0; col < vp->cols; col++) {
519 charfield_t *field =
520 screenbuffer_field_at(vp->backbuf, col, row);
521
522 field->ch = 0;
523 field->attrs = vp->attrs;
524 }
525 }
526
527 pixel_t bgcolor = 0;
528 pixel_t fgcolor = 0;
529 attrs_rgb(vp->attrs, &bgcolor, &fgcolor);
530
531 draw_filled_rect(vp->x, vp->y, vp->x + vp->width,
532 vp->y + vp->height, bgcolor);
533
534 pointer_show();
535}
536
537static console_caps_t kfb_vp_get_caps(fbdev_t *dev, fbvp_t *vp)
538{
539 return (CONSOLE_CAP_STYLE | CONSOLE_CAP_INDEXED | CONSOLE_CAP_RGB);
540}
541
542static void kfb_vp_cursor_update(fbdev_t *dev, fbvp_t *vp, sysarg_t prev_col,
543 sysarg_t prev_row, sysarg_t col, sysarg_t row, bool visible)
544{
545 pointer_hide();
546 draw_vp_char(vp, prev_col, prev_row);
547 draw_vp_char(vp, col, row);
548 pointer_show();
549}
550
551static void kfb_vp_cursor_flash(fbdev_t *dev, fbvp_t *vp, sysarg_t col,
552 sysarg_t row)
553{
554 pointer_hide();
555 draw_vp_char(vp, col, row);
556 pointer_show();
557}
558
559static void kfb_vp_char_update(fbdev_t *dev, fbvp_t *vp, sysarg_t col,
560 sysarg_t row)
561{
562 pointer_hide();
563 draw_vp_char(vp, col, row);
564 pointer_show();
565}
566
567static void kfb_vp_imgmap_damage(fbdev_t *dev, fbvp_t *vp, imgmap_t *imgmap,
568 sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height)
569{
570 pointer_hide();
571
572 for (sysarg_t y = 0; y < height; y++) {
573 for (sysarg_t x = 0; x < width; x++) {
574 pixel_t pixel = imgmap_get_pixel(imgmap, x0 + x, y0 + y);
575 vp_put_pixel(vp, x0 + x, y0 + y, pixel);
576 }
577 }
578
579 pointer_show();
580}
581
582static fbdev_ops_t kfb_ops = {
583 .yield = kfb_yield,
584 .claim = kfb_claim,
585 .pointer_update = kfb_pointer_update,
586 .get_resolution = kfb_get_resolution,
587 .font_metrics = kfb_font_metrics,
588 .vp_create = kfb_vp_create,
589 .vp_destroy = kfb_vp_destroy,
590 .vp_clear = kfb_vp_clear,
591 .vp_get_caps = kfb_vp_get_caps,
592 .vp_cursor_update = kfb_vp_cursor_update,
593 .vp_cursor_flash = kfb_vp_cursor_flash,
594 .vp_char_update = kfb_vp_char_update,
595 .vp_imgmap_damage = kfb_vp_imgmap_damage
596};
597
598/** Render glyphs
599 *
600 * Convert glyphs from device independent font
601 * description to current visual representation.
602 *
603 */
604static void render_glyphs(size_t sz)
605{
606 memset(kfb.glyphs, 0, sz);
607
608 for (unsigned int glyph = 0; glyph < FONT_GLYPHS; glyph++) {
609 for (unsigned int y = 0; y < FONT_SCANLINES; y++) {
610 for (unsigned int x = 0; x < FONT_WIDTH; x++) {
611 kfb.visual_mask(
612 &kfb.glyphs[GLYPH_POS(glyph, y, false) + x * kfb.pixel_bytes],
613 (fb_font[glyph][y] & (1 << (7 - x))) ? true : false);
614 kfb.visual_mask(
615 &kfb.glyphs[GLYPH_POS(glyph, y, true) + x * kfb.pixel_bytes],
616 (fb_font[glyph][y] & (1 << (7 - x))) ? false : true);
617 }
618 }
619 }
620}
621
622errno_t kfb_init(void)
623{
624 sysarg_t present;
625 errno_t rc = sysinfo_get_value("fb", &present);
626 if (rc != EOK)
627 present = false;
628
629 if (!present)
630 return ENOENT;
631
632 sysarg_t kind;
633 rc = sysinfo_get_value("fb.kind", &kind);
634 if (rc != EOK)
635 kind = (sysarg_t) -1;
636
637 if (kind != 1)
638 return EINVAL;
639
640 sysarg_t paddr;
641 rc = sysinfo_get_value("fb.address.physical", &paddr);
642 if (rc != EOK)
643 return rc;
644
645 sysarg_t offset;
646 rc = sysinfo_get_value("fb.offset", &offset);
647 if (rc != EOK)
648 offset = 0;
649
650 sysarg_t width;
651 rc = sysinfo_get_value("fb.width", &width);
652 if (rc != EOK)
653 return rc;
654
655 sysarg_t height;
656 rc = sysinfo_get_value("fb.height", &height);
657 if (rc != EOK)
658 return rc;
659
660 sysarg_t scanline;
661 rc = sysinfo_get_value("fb.scanline", &scanline);
662 if (rc != EOK)
663 return rc;
664
665 sysarg_t visual;
666 rc = sysinfo_get_value("fb.visual", &visual);
667 if (rc != EOK)
668 return rc;
669
670 kfb.width = width;
671 kfb.height = height;
672 kfb.offset = offset;
673 kfb.scanline = scanline;
674 kfb.visual = visual;
675
676 switch (visual) {
677 case VISUAL_INDIRECT_8:
678 kfb.pixel2visual = pixel2bgr_323;
679 kfb.visual2pixel = bgr_323_2pixel;
680 kfb.visual_mask = visual_mask_323;
681 kfb.pixel_bytes = 1;
682 break;
683 case VISUAL_RGB_5_5_5_LE:
684 kfb.pixel2visual = pixel2rgb_555_le;
685 kfb.visual2pixel = rgb_555_le_2pixel;
686 kfb.visual_mask = visual_mask_555;
687 kfb.pixel_bytes = 2;
688 break;
689 case VISUAL_RGB_5_5_5_BE:
690 kfb.pixel2visual = pixel2rgb_555_be;
691 kfb.visual2pixel = rgb_555_be_2pixel;
692 kfb.visual_mask = visual_mask_555;
693 kfb.pixel_bytes = 2;
694 break;
695 case VISUAL_RGB_5_6_5_LE:
696 kfb.pixel2visual = pixel2rgb_565_le;
697 kfb.visual2pixel = rgb_565_le_2pixel;
698 kfb.visual_mask = visual_mask_565;
699 kfb.pixel_bytes = 2;
700 break;
701 case VISUAL_RGB_5_6_5_BE:
702 kfb.pixel2visual = pixel2rgb_565_be;
703 kfb.visual2pixel = rgb_565_be_2pixel;
704 kfb.visual_mask = visual_mask_565;
705 kfb.pixel_bytes = 2;
706 break;
707 case VISUAL_RGB_8_8_8:
708 kfb.pixel2visual = pixel2rgb_888;
709 kfb.visual2pixel = rgb_888_2pixel;
710 kfb.visual_mask = visual_mask_888;
711 kfb.pixel_bytes = 3;
712 break;
713 case VISUAL_BGR_8_8_8:
714 kfb.pixel2visual = pixel2bgr_888;
715 kfb.visual2pixel = bgr_888_2pixel;
716 kfb.visual_mask = visual_mask_888;
717 kfb.pixel_bytes = 3;
718 break;
719 case VISUAL_RGB_8_8_8_0:
720 kfb.pixel2visual = pixel2rgb_8880;
721 kfb.visual2pixel = rgb_8880_2pixel;
722 kfb.visual_mask = visual_mask_8880;
723 kfb.pixel_bytes = 4;
724 break;
725 case VISUAL_RGB_0_8_8_8:
726 kfb.pixel2visual = pixel2rgb_0888;
727 kfb.visual2pixel = rgb_0888_2pixel;
728 kfb.visual_mask = visual_mask_0888;
729 kfb.pixel_bytes = 4;
730 break;
731 case VISUAL_BGR_0_8_8_8:
732 kfb.pixel2visual = pixel2bgr_0888;
733 kfb.visual2pixel = bgr_0888_2pixel;
734 kfb.visual_mask = visual_mask_0888;
735 kfb.pixel_bytes = 4;
736 break;
737 case VISUAL_BGR_8_8_8_0:
738 kfb.pixel2visual = pixel2bgr_8880;
739 kfb.visual2pixel = bgr_8880_2pixel;
740 kfb.visual_mask = visual_mask_8880;
741 kfb.pixel_bytes = 4;
742 break;
743 default:
744 return EINVAL;
745 }
746
747 kfb.glyph_scanline = FONT_WIDTH * kfb.pixel_bytes;
748 kfb.glyph_bytes = kfb.glyph_scanline * FONT_SCANLINES;
749
750 size_t sz = 2 * FONT_GLYPHS * kfb.glyph_bytes;
751 kfb.glyphs = (uint8_t *) malloc(sz);
752 if (kfb.glyphs == NULL)
753 return EINVAL;
754
755 render_glyphs(sz);
756
757 kfb.size = scanline * height;
758
759 rc = physmem_map((void *) paddr + offset,
760 ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
761 AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
762 if (rc != EOK) {
763 free(kfb.glyphs);
764 return rc;
765 }
766
767 kfb.pointer_x = 0;
768 kfb.pointer_y = 0;
769 kfb.pointer_visible = false;
770 kfb.pointer_imgmap = imgmap_create(POINTER_WIDTH, POINTER_HEIGHT,
771 VISUAL_RGB_0_8_8_8, IMGMAP_FLAG_NONE);
772
773 kfb.backbuf = NULL;
774
775 fbdev_t *dev = fbdev_register(&kfb_ops, (void *) &kfb);
776 if (dev == NULL) {
777 free(kfb.glyphs);
778 as_area_destroy(kfb.addr);
779 return EINVAL;
780 }
781
782 return EOK;
783}
784
785/**
786 * @}
787 */
Note: See TracBrowser for help on using the repository browser.