2 * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
4 * Microwindows Screen Driver for RTEMS (uses Microframebuffer api)
6 * Portions used from Ben Pfaff's BOGL <pfaffben@debian.org>
8 * Note: modify select_fb_driver() to add new framebuffer subdrivers
13 #include <sys/types.h>
24 #include <rtems/mw_fb.h>
26 #ifndef FB_TYPE_VGA_PLANES
27 #define FB_TYPE_VGA_PLANES 4
30 static PSD fb_open(PSD psd);
31 static void fb_close(PSD psd);
32 static void fb_setpalette(PSD psd,int first, int count, MWPALENTRY *palette);
33 static void gen_getscreeninfo(PSD psd,PMWSCREENINFO psi);
35 SCREENDEVICE scrdev = {
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
41 NULL, /* DrawPixel subdriver*/
42 NULL, /* ReadPixel subdriver*/
43 NULL, /* DrawHorzLine subdriver*/
44 NULL, /* DrawVertLine subdriver*/
45 NULL, /* FillRect subdriver*/
47 NULL, /* Blit subdriver*/
49 NULL, /* DrawArea subdriver*/
50 NULL, /* SetIOPermissions*/
57 static int fb; /* Framebuffer file handle. */
58 static int status; /* 0=never inited, 1=once inited, 2=inited. */
59 static short saved_red[16]; /* original hw palette*/
60 static short saved_green[16];
61 static short saved_blue[16];
64 static void set_directcolor_palette(PSD psd);
66 static void ioctl_getpalette(int start, int len, short *red, short *green,
68 static void ioctl_setpalette(int start, int len, short *red, short *green,
80 struct fb_screeninfo fb_info;
84 /* locate and open framebuffer, get info*/
85 if(!(env = getenv("FRAMEBUFFER")))
87 fb = open( env, O_RDWR);
89 EPRINTF("Error opening %s: %m\n", env);
93 if( ufb_get_screen_info( fb, &fb_info ) )
95 EPRINTF("Error getting screen info\n" );
98 /* setup screen device from framebuffer info*/
100 visual = fb_info.visual;
102 psd->xres = psd->xvirtres = fb_info.xres;
103 psd->yres = psd->yvirtres = fb_info.yres;
105 /* set planes from fb type*/
106 if (type == FB_TYPE_VGA_PLANES)
108 else if (type == FB_TYPE_PACKED_PIXELS)
110 else psd->planes = 0; /* force error later*/
112 psd->bpp = fb_info.bits_per_pixel;
113 psd->ncolors = (psd->bpp >= 24)? (1 << 24): (1 << psd->bpp);
115 /* set linelen to byte length, possibly converted later*/
116 psd->linelen = fb_info.line_length;
117 psd->size = 0; /* force subdriver init of size*/
120 psd->flags = PSF_SCREEN | PSF_HAVEBLIT;
122 psd->flags = PSF_SCREEN;
125 psd->flags |= PSF_HAVEOP_COPY;
127 /* set pixel format*/
128 if(visual == FB_VISUAL_TRUECOLOR || visual == FB_VISUAL_DIRECTCOLOR) {
131 psd->pixtype = MWPF_TRUECOLOR332;
134 psd->pixtype = MWPF_TRUECOLOR565;
137 psd->pixtype = MWPF_TRUECOLOR888;
140 psd->pixtype = MWPF_TRUECOLOR0888;
144 "Unsupported %d color (%d bpp) truecolor framebuffer\n",
145 psd->ncolors, psd->bpp);
148 } else psd->pixtype = MWPF_PALETTE;
150 psd->size = fb_info.smem_len;
151 /* maps FB memory to user space */
152 if( ufb_mmap_to_user_space( fb, &psd->addr,
153 ( void *)fb_info.smem_start, fb_info.smem_len ) )
155 EPRINTF("Error mapping FB memory to user space\n" );
159 /*DPRINTF("%dx%dx%d linelen %d type %d visual %d bpp %d\n", psd->xres,
160 psd->yres, psd->ncolors, psd->linelen, type, visual,
163 /* select a framebuffer subdriver based on planes and bpp*/
164 subdriver = select_fb_subdriver(psd);
166 EPRINTF("No driver for screen type %d visual %d bpp %d\n",
167 type, visual, psd->bpp);
171 if( ufb_enter_graphics( fb, 0 ) )
173 EPRINTF("Error entering graphics\n");
178 * set and initialize subdriver into screen driver
179 * psd->size is calculated by subdriver init
181 if(!set_subdriver(psd, subdriver, TRUE ))
183 EPRINTF("Driver initialize failed type %d visual %d bpp %d\n",
184 type, visual, psd->bpp);
188 /* save original palette*/
189 ioctl_getpalette(0, 16, saved_red, saved_green, saved_blue);
191 /* setup direct color palette if required (ATI cards)*/
192 if(visual == FB_VISUAL_DIRECTCOLOR)
193 set_directcolor_palette(psd);
196 return psd; /* success*/
203 /* close framebuffer*/
207 /* if not opened, return*/
212 /* reset hw palette*/
213 ioctl_setpalette(0, 16, saved_red, saved_green, saved_blue);
215 /* unmaps memory from user's space */
216 ufb_unmmap_from_user_space( fb, psd->addr );
218 /* restore TEXT mode */
219 ufb_exit_graphics( fb );
221 /* close tty and framebuffer*/
225 /* setup directcolor palette - required for ATI cards*/
227 set_directcolor_palette(PSD psd)
230 short r[256], g[256], b[256];
232 /* 16bpp uses 32 palette entries*/
234 /* FIXME: this still doesn't work*/
235 for(i=0; i<32; ++i) {
237 r[i] = g[i] = b[i] = ((i<<11)|(i<<6)|i)<<8;
238 r[i] = g[i] = b[i] = ((i<<5)|i)<<10;
239 r[i] = g[i] = b[i] = i<<11;
241 r[i] = g[i] = b[i] = (i<<11) | (i<<3);
243 ioctl_setpalette(0, 32, r, g, b);
245 /* 32bpp uses 256 entries*/
248 ioctl_setpalette(0, 256, r, r, r);
252 static int fade = 100;
254 /* convert Microwindows palette to framebuffer format and set it*/
256 fb_setpalette(PSD psd,int first, int count, MWPALENTRY *palette)
259 unsigned short red[count];
260 unsigned short green[count];
261 unsigned short blue[count];
263 /* convert palette to framebuffer format*/
264 for(i=0; i < count; i++) {
265 MWPALENTRY *p = &palette[i];
267 /* grayscale computation:
268 * red[i] = green[i] = blue[i] =
269 * (p->r * 77 + p->g * 151 + p->b * 28);
271 red[i] = (p->r * fade / 100) << 8;
272 green[i] = (p->g * fade / 100) << 8;
273 blue[i] = (p->b * fade / 100) << 8;
275 ioctl_setpalette(first, count, red, green, blue);
278 /* get framebuffer palette*/
280 ioctl_getpalette(int start, int len, short *red, short *green, short *blue)
291 ufb_get_palette( fb, &cmap );
294 /* set framebuffer palette*/
296 ioctl_setpalette(int start, int len, short *red, short *green, short *blue)
307 ufb_set_palette( fb, &cmap );
311 gen_getscreeninfo(PSD psd,PMWSCREENINFO psi)
313 psi->rows = psd->yvirtres;
314 psi->cols = psd->xvirtres;
315 psi->planes = psd->planes;
317 psi->ncolors = psd->ncolors;
318 psi->pixtype = psd->pixtype;
319 psi->fonts = NUMBER_FONTS;
321 if(psd->yvirtres > 480) {
323 psi->xdpcm = 33; /* assumes screen width of 24 cm*/
324 psi->ydpcm = 33; /* assumes screen height of 18 cm*/
325 } else if(psd->yvirtres > 350) {
327 psi->xdpcm = 27; /* assumes screen width of 24 cm*/
328 psi->ydpcm = 27; /* assumes screen height of 18 cm*/
331 psi->xdpcm = 27; /* assumes screen width of 24 cm*/
332 psi->ydpcm = 19; /* assumes screen height of 18 cm*/
336 /* experimental palette animation*/
338 setfadelevel(PSD psd, int f)
341 unsigned short r[256], g[256], b[256];
342 extern MWPALENTRY gr_palette[256];
344 if(psd->pixtype != MWPF_PALETTE)
350 for(i=0; i<256; ++i) {
351 r[i] = (gr_palette[i].r * fade / 100) << 8;
352 g[i] = (gr_palette[i].g * fade / 100) << 8;
353 b[i] = (gr_palette[i].b * fade / 100) << 8;
355 ioctl_setpalette(0, 256, r, g, b);