2 * pslash - a lightweight framebuffer splashscreen for embedded devices.
4 * Copyright (c) 2006 Matthew Allum <mallum@o-hand.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
20 psplash_fb_destroy (PSplashFB *fb)
31 struct fb_var_screeninfo fb_var;
32 struct fb_fix_screeninfo fb_fix;
38 fbdev = getenv("FBDEV");
42 if ((fb = malloc (sizeof(PSplashFB))) == NULL)
44 perror ("Error no memory");
48 memset (fb, 0, sizeof(PSplashFB));
52 if ((fb->fd = open (fbdev, O_RDWR)) < 0)
54 perror ("Error opening /dev/fb0");
58 if (ioctl (fb->fd, FBIOGET_FSCREENINFO, &fb_fix) == -1
59 || ioctl (fb->fd, FBIOGET_VSCREENINFO, &fb_var) == -1)
61 perror ("Error getting framebuffer info");
65 if (fb_var.bits_per_pixel < 16)
68 "Error, no support currently for %i bpp frame buffers\n",
69 fb_var.bits_per_pixel);
72 fb->width = fb_var.xres;
73 fb->height = fb_var.yres;
74 fb->bpp = fb_var.bits_per_pixel;
75 fb->stride = fb_fix.line_length;
76 fb->type = fb_fix.type;
77 fb->visual = fb_fix.visual;
79 DBG("width: %i, height: %i, bpp: %i, stride: %i",
80 fb->width, fb->height, fb->bpp, fb->stride);
83 fb->base = (char *) mmap ((caddr_t) NULL,
85 fb->stride * fb->height,
90 if (fb->base == (char *)-1)
92 perror("Error cannot mmap framebuffer ");
96 off = (unsigned long) fb_fix.smem_start % (unsigned long) getpagesize();
98 fb->data = fb->base + off;
101 /* FIXME: No support for 8pp as yet */
102 if (visual == FB_VISUAL_PSEUDOCOLOR
103 || visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
105 static struct fb_cmap cmap;
109 cmap.red = saved_red;
110 cmap.green = saved_green;
111 cmap.blue = saved_blue;
114 ioctl (fb, FBIOGETCMAP, &cmap);
127 psplash_fb_destroy (fb);
133 psplash_fb_plot_pixel (PSplashFB *fb,
142 if (x < 0 || x > fb->width-1 || y < 0 || y > fb->height-1)
145 off = (y * fb->stride) + (x * (fb->bpp >> 3));
147 /* FIXME: handle no RGB orderings */
152 *(fb->data + off) = red;
153 *(fb->data + off + 1) = green;
154 *(fb->data + off + 2) = blue;
157 *(volatile uint16 *) (fb->data + off)
158 = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
161 /* depth not supported yet */
168 psplash_fb_draw_rect (PSplashFB *fb,
179 for (dy=0; dy < height; dy++)
180 for (dx=0; dx < width; dx++)
181 psplash_fb_plot_pixel (fb, x+dx, y+dy, red, green, blue);
185 psplash_fb_draw_image (PSplashFB *fb,
190 int img_bytes_per_pixel,
194 int dx = 0, dy = 0, total_len;
197 total_len = img_width * img_height * img_bytes_per_pixel;
199 /* FIXME: Optimise, check for over runs ... */
200 while ((p - rle_data) < total_len)
212 psplash_fb_plot_pixel (fb, x+dx, y+dy, *p, *(p+1), *(p+2));
213 if (++dx >= img_width) { dx=0; dy++; }
215 while (--len && (p - rle_data) < total_len);
217 p += img_bytes_per_pixel;
225 psplash_fb_plot_pixel (fb, x+dx, y+dy, *p, *(p+1), *(p+2));
226 if (++dx >= img_width) { dx=0; dy++; }
227 p += img_bytes_per_pixel;
229 while (--len && (p - rle_data) < total_len);
234 /* Font rendering code based on BOGL by Ben Pfaff */
237 psplash_font_glyph (const PSplashFont *font, wchar_t wc, u_int32_t **bitmap)
239 int mask = font->index_mask;
244 for (i = font->offset[wc & mask]; font->index[i]; i += 2)
246 if ((font->index[i] & ~mask) == (wc & ~mask))
249 *bitmap = &font->content[font->index[i+1]];
250 return font->index[i] & mask;
258 psplash_fb_text_size (PSplashFB *fb,
261 const PSplashFont *font,
264 char *c = (char*)text;
272 for (; (k = mbtowc (&wc, c, n)) > 0; c += k, n -= k)
282 w += psplash_font_glyph (font, wc, NULL);
285 *width = (w > mw) ? w : mw;
286 *height = (h == 0) ? font->height : h;
290 psplash_fb_draw_text (PSplashFB *fb,
296 const PSplashFont *font,
299 int h, w, k, n, cx, cy, dx, dy;
300 char *c = (char*)text;
308 for (; (k = mbtowc (&wc, c, n)) > 0; c += k, n -= k)
310 u_int32_t *glyph = NULL;
319 w = psplash_font_glyph (font, wc, &glyph);
324 for (cy = 0; cy < h; cy++)
326 u_int32_t g = *glyph++;
328 for (cx = 0; cx < w; cx++)
331 psplash_fb_plot_pixel (fb, x+dx+cx, y+dy+cy,