]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/drivers/scr_rtems.c
Cleanup CVS ipmorted branch
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / drivers / scr_rtems.c
1 /*
2  * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
3  *
4  * Microwindows Screen Driver for RTEMS (uses Microframebuffer api)
5  *
6  * Portions used from Ben Pfaff's BOGL <pfaffben@debian.org>
7  * 
8  * Note: modify select_fb_driver() to add new framebuffer subdrivers
9  */
10 #define _GNU_SOURCE 1
11 #include <assert.h>
12 #include <sys/time.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15 #include <stdio.h>
16 #include <fcntl.h>
17 #include <limits.h>
18 #include <stdarg.h>
19 #include <stdlib.h>
20 #include "device.h"
21 #include "genfont.h"
22 #include "genmem.h"
23 #include "fb.h"
24 #include <rtems/mw_fb.h>
25
26 #ifndef FB_TYPE_VGA_PLANES
27 #define FB_TYPE_VGA_PLANES 4
28 #endif
29
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);
34
35 SCREENDEVICE    scrdev = {
36         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
37         fb_open,
38         fb_close,
39         gen_getscreeninfo,
40         fb_setpalette,
41         NULL,                   /* DrawPixel subdriver*/
42         NULL,                   /* ReadPixel subdriver*/
43         NULL,                   /* DrawHorzLine subdriver*/
44         NULL,                   /* DrawVertLine subdriver*/
45         NULL,                   /* FillRect subdriver*/
46         gen_fonts,
47         NULL,                   /* Blit subdriver*/
48         NULL,                   /* PreSelect*/
49         NULL,                   /* DrawArea subdriver*/
50         NULL,                   /* SetIOPermissions*/
51         gen_allocatememgc,
52         fb_mapmemgc,
53         gen_freememgc
54 };
55
56 /* static variables*/
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];
62
63 /* local functions*/
64 static void     set_directcolor_palette(PSD psd);
65 #if 0
66 static void     ioctl_getpalette(int start, int len, short *red, short *green,
67                         short *blue);
68 static void     ioctl_setpalette(int start, int len, short *red, short *green,
69                         short *blue);
70 #endif
71
72 /* init framebuffer*/
73 static PSD
74 fb_open(PSD psd)
75 {
76         char *  env;
77         int     type, visual;
78         int     tty;
79         PSUBDRIVER subdriver;
80         struct fb_screeninfo fb_info;
81
82         assert(status < 2);
83   
84         /* locate and open framebuffer, get info*/
85         if(!(env = getenv("FRAMEBUFFER")))
86                 env = "/dev/fb0";
87         fb = open( env, O_RDWR);
88         if(fb < 0) {
89                 EPRINTF("Error opening %s: %m\n", env);
90       return NULL;
91    }
92    
93    if( ufb_get_screen_info( fb, &fb_info ) )
94    {
95       EPRINTF("Error getting screen info\n" );
96       return NULL;
97    }
98         /* setup screen device from framebuffer info*/
99         type = fb_info.type;
100         visual = fb_info.visual;
101
102         psd->xres = psd->xvirtres = fb_info.xres;
103         psd->yres = psd->yvirtres = fb_info.yres;
104
105         /* set planes from fb type*/
106         if (type == FB_TYPE_VGA_PLANES)
107                 psd->planes = 4;
108         else if (type == FB_TYPE_PACKED_PIXELS)
109                 psd->planes = 1;
110         else psd->planes = 0;   /* force error later*/
111
112         psd->bpp = fb_info.bits_per_pixel;
113         psd->ncolors = (psd->bpp >= 24)? (1 << 24): (1 << psd->bpp);
114
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*/
118
119 #if HAVEBLIT
120         psd->flags = PSF_SCREEN | PSF_HAVEBLIT;
121 #else
122         psd->flags = PSF_SCREEN;
123 #endif
124         if (psd->bpp == 16)
125                 psd->flags |= PSF_HAVEOP_COPY;
126
127         /* set pixel format*/
128         if(visual == FB_VISUAL_TRUECOLOR || visual == FB_VISUAL_DIRECTCOLOR) {
129                 switch(psd->bpp) {
130                 case 8:
131                         psd->pixtype = MWPF_TRUECOLOR332;
132                         break;
133                 case 16:
134                         psd->pixtype = MWPF_TRUECOLOR565;
135                         break;
136                 case 24:
137                         psd->pixtype = MWPF_TRUECOLOR888;
138                         break;
139                 case 32:
140                         psd->pixtype = MWPF_TRUECOLOR0888;
141                         break;
142                 default:
143                         EPRINTF(
144                         "Unsupported %d color (%d bpp) truecolor framebuffer\n",
145                                 psd->ncolors, psd->bpp);
146                         goto fail;
147                 }
148         } else psd->pixtype = MWPF_PALETTE;
149
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 ) )
154    {
155       EPRINTF("Error mapping FB memory to user space\n" );
156       goto fail;
157    }
158
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,
161                 psd->bpp);*/
162
163         /* select a framebuffer subdriver based on planes and bpp*/
164         subdriver = select_fb_subdriver(psd);
165         if (!subdriver) {
166                 EPRINTF("No driver for screen type %d visual %d bpp %d\n",
167                         type, visual, psd->bpp);
168                 goto fail;
169         }
170
171    if( ufb_enter_graphics( fb, 0 ) )
172    {
173       EPRINTF("Error entering graphics\n");
174       return NULL;
175    }
176
177         /*
178          * set and initialize subdriver into screen driver
179          * psd->size is calculated by subdriver init
180          */
181         if(!set_subdriver(psd, subdriver, TRUE )) 
182         {
183                 EPRINTF("Driver initialize failed type %d visual %d bpp %d\n",
184                         type, visual, psd->bpp);
185                 goto fail;
186         }
187
188         /* save original palette*/
189         ioctl_getpalette(0, 16, saved_red, saved_green, saved_blue);
190
191         /* setup direct color palette if required (ATI cards)*/
192         if(visual == FB_VISUAL_DIRECTCOLOR)
193                 set_directcolor_palette(psd);
194
195         status = 2;
196         return psd;     /* success*/
197
198 fail:
199         close( fb );
200    return NULL;
201 }
202
203 /* close framebuffer*/
204 static void
205 fb_close(PSD psd)
206 {
207         /* if not opened, return*/
208         if(status != 2)
209                 return;
210         status = 1;
211
212         /* reset hw palette*/
213         ioctl_setpalette(0, 16, saved_red, saved_green, saved_blue);
214
215    /* unmaps memory from user's space */
216    ufb_unmmap_from_user_space( fb, psd->addr );
217
218    /* restore TEXT mode */
219    ufb_exit_graphics( fb );
220   
221         /* close tty and framebuffer*/
222         close( fb );
223 }
224
225 /* setup directcolor palette - required for ATI cards*/
226 static void
227 set_directcolor_palette(PSD psd)
228 {
229         int i;
230         short r[256], g[256], b[256];
231
232         /* 16bpp uses 32 palette entries*/
233         if(psd->bpp == 16) {
234                 /* FIXME: this still doesn't work*/
235                 for(i=0; i<32; ++i) {
236 #if 0
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;
240 #endif
241                         r[i] = g[i] = b[i] = (i<<11) | (i<<3);
242                 }
243                 ioctl_setpalette(0, 32, r, g, b);
244         } else {
245                 /* 32bpp uses 256 entries*/
246                 for(i=0; i<256; ++i)
247                         r[i] = i<<8;
248                 ioctl_setpalette(0, 256, r, r, r);
249         }
250 }
251
252 static int fade = 100;
253
254 /* convert Microwindows palette to framebuffer format and set it*/
255 static void
256 fb_setpalette(PSD psd,int first, int count, MWPALENTRY *palette)
257 {
258         int     i;
259         unsigned short  red[count];
260         unsigned short  green[count];
261         unsigned short  blue[count];
262
263         /* convert palette to framebuffer format*/
264         for(i=0; i < count; i++) {
265                 MWPALENTRY *p = &palette[i];
266
267                 /* grayscale computation:
268                  * red[i] = green[i] = blue[i] =
269                  *      (p->r * 77 + p->g * 151 + p->b * 28);
270                  */
271                 red[i] = (p->r * fade / 100) << 8;
272                 green[i] = (p->g * fade / 100) << 8;
273                 blue[i] = (p->b * fade / 100) << 8;
274         }
275         ioctl_setpalette(first, count, red, green, blue);
276 }
277
278 /* get framebuffer palette*/
279 static void
280 ioctl_getpalette(int start, int len, short *red, short *green, short *blue)
281 {
282         struct fb_cmap cmap;
283
284         cmap.start = start;
285         cmap.len = len;
286         cmap.red = red;
287         cmap.green = green;
288         cmap.blue = blue;
289         cmap.transp = NULL;
290
291    ufb_get_palette( fb, &cmap );
292 }
293
294 /* set framebuffer palette*/
295 static void
296 ioctl_setpalette(int start, int len, short *red, short *green, short *blue)
297 {
298         struct fb_cmap cmap;
299
300         cmap.start = start;
301         cmap.len = len;
302         cmap.red = red;
303         cmap.green = green;
304         cmap.blue = blue;
305         cmap.transp = NULL;
306
307    ufb_set_palette( fb, &cmap );
308 }
309
310 static void
311 gen_getscreeninfo(PSD psd,PMWSCREENINFO psi)
312 {
313         psi->rows = psd->yvirtres;
314         psi->cols = psd->xvirtres;
315         psi->planes = psd->planes;
316         psi->bpp = psd->bpp;
317         psi->ncolors = psd->ncolors;
318         psi->pixtype = psd->pixtype;
319         psi->fonts = NUMBER_FONTS;
320
321         if(psd->yvirtres > 480) {
322                 /* SVGA 800x600*/
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) {
326                 /* VGA 640x480*/
327                 psi->xdpcm = 27;        /* assumes screen width of 24 cm*/
328                 psi->ydpcm = 27;        /* assumes screen height of 18 cm*/
329         } else {
330                 /* EGA 640x350*/
331                 psi->xdpcm = 27;        /* assumes screen width of 24 cm*/
332                 psi->ydpcm = 19;        /* assumes screen height of 18 cm*/
333         }
334 }
335
336 /* experimental palette animation*/
337 void
338 setfadelevel(PSD psd, int f)
339 {
340         int             i;
341         unsigned short  r[256], g[256], b[256];
342         extern MWPALENTRY gr_palette[256];
343
344         if(psd->pixtype != MWPF_PALETTE)
345                 return;
346
347         fade = f;
348         if(fade > 100)
349                 fade = 100;
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;
354         }
355         ioctl_setpalette(0, 256, r, g, b);
356 }