trunk 20080912
[gitenigma.git] / lib / gdi / fb.cpp
blobddc67106e84305ce2884152de23b55b0d79106fe
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <sys/ioctl.h>
5 #include <unistd.h>
6 #include <sys/mman.h>
7 #include <memory.h>
8 #include <linux/kd.h>
10 #include <lib/system/econfig.h>
11 #include <lib/gdi/fb.h>
12 #include <lib/gdi/grc.h>
14 #include <config.h>
15 #if HAVE_DVB_API_VERSION >= 3
16 #include <dbox/fb.h>
17 #endif
19 fbClass *fbClass::instance;
21 fbClass *fbClass::getInstance()
23 return instance;
26 fbClass::fbClass(const char *fb)
28 instance=this;
29 locked=0;
30 available=0;
31 cmap.start=0;
32 cmap.len=256;
33 cmap.red=red;
34 cmap.green=green;
35 cmap.blue=blue;
36 cmap.transp=trans;
38 int state=0;
39 eConfig::getInstance()->getKey("/ezap/osd/showConsoleOnFB", state);
41 fd=open(fb, O_RDWR);
42 if (fd<0)
44 perror(fb);
45 goto nolfb;
47 if (ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo)<0)
49 perror("FBIOGET_VSCREENINFO");
50 goto nolfb;
53 memcpy(&oldscreen, &screeninfo, sizeof(screeninfo));
55 fb_fix_screeninfo fix;
56 if (ioctl(fd, FBIOGET_FSCREENINFO, &fix)<0)
58 perror("FBIOGET_FSCREENINFO");
59 goto nolfb;
62 available=fix.smem_len;
63 eDebug("%dk video mem", available/1024);
64 lfb=(unsigned char*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
65 if (!lfb)
67 perror("mmap");
68 goto nolfb;
71 showConsole(state);
72 return;
73 nolfb:
74 lfb=0;
75 printf("framebuffer not available.\n");
76 return;
79 int fbClass::showConsole(int state)
81 int fd=open("/dev/vc/0", O_RDWR);
82 if(fd>=0)
84 if(ioctl(fd, KDSETMODE, state?KD_TEXT:KD_GRAPHICS)<0)
86 eDebug("setting /dev/vc/0 status failed.");
88 close(fd);
90 return 0;
93 int fbClass::SetMode(unsigned int nxRes, unsigned int nyRes, unsigned int nbpp)
95 screeninfo.xres_virtual=screeninfo.xres=nxRes;
96 screeninfo.yres_virtual=screeninfo.yres=nyRes;
97 screeninfo.height=0;
98 screeninfo.width=0;
99 screeninfo.xoffset=screeninfo.yoffset=0;
100 screeninfo.bits_per_pixel=nbpp;
101 if (ioctl(fd, FBIOPUT_VSCREENINFO, &screeninfo)<0)
103 perror("FBIOPUT_VSCREENINFO");
104 printf("fb failed\n");
105 return -1;
107 if ((screeninfo.xres!=nxRes) && (screeninfo.yres!=nyRes) && (screeninfo.bits_per_pixel!=nbpp))
109 eDebug("SetMode failed: wanted: %dx%dx%d, got %dx%dx%d",
110 nxRes, nyRes, nbpp,
111 screeninfo.xres, screeninfo.yres, screeninfo.bits_per_pixel);
113 xRes=screeninfo.xres;
114 yRes=screeninfo.yres;
115 bpp=screeninfo.bits_per_pixel;
116 fb_fix_screeninfo fix;
117 if (ioctl(fd, FBIOGET_FSCREENINFO, &fix)<0)
119 perror("FBIOGET_FSCREENINFO");
120 printf("fb failed\n");
122 stride=fix.line_length;
123 memset(lfb, 0, stride*yRes);
124 return 0;
127 fbClass::~fbClass()
129 if (available)
130 ioctl(fd, FBIOPUT_VSCREENINFO, &oldscreen);
131 if (lfb)
132 munmap(lfb, available);
135 int fbClass::PutCMAP()
137 return ioctl(fd, FBIOPUTCMAP, &cmap);
140 void fbClass::Box(int x, int y, int width, int height, int color, int backcolor)
142 if (width<=2 || locked)
143 return;
144 int offset=y*stride+x/2;
145 int first=0xF0|((color&0xF0)>>4);
146 int last= 0xF0|((backcolor&0xF0)>>4);
147 color=(color&0xF)*0x11;
148 int halfwidth=width/2;
149 for (int ay=y; ay<(y+height); ay++)
151 lfb[offset]=first;
152 memset(lfb+offset+1, color, halfwidth-2);
153 lfb[offset+halfwidth-1]=last;
154 offset+=stride;
158 void fbClass::NBox(int x, int y, int width, int height, int color)
160 if (locked)
161 return;
162 int offset=y*stride+x/2;
163 int halfwidth=width/2;
164 for (int ay=y; ay<(y+height); ay++)
166 memset(lfb+offset, color, halfwidth);
167 offset+=stride;
171 void fbClass::VLine(int x, int y, int sy, int color)
173 if (locked)
174 return;
175 int offset=y*stride+x/2;
176 while (sy--)
178 lfb[offset]=color;
179 offset+=stride;
183 int fbClass::lock()
185 if (locked)
186 return -1;
187 while (gRC::getInstance().mustDraw())
188 usleep(1000);
189 locked=1;
190 return fd;
193 void fbClass::unlock()
195 if (!locked)
196 return;
197 locked=0;
198 SetMode(xRes, yRes, bpp);
199 PutCMAP();
202 void fbClass::paletteSet(struct fb_cmap *map)
204 if (locked)
205 return;
207 if (map == NULL)
208 map = &cmap;
210 ioctl(fd, FBIOPUTCMAP, map);
213 #if HAVE_DVB_API_VERSION >= 3
214 void fbClass::setTransparency(int tr)
216 if (tr > 8)
217 tr = 8;
219 int val = (tr << 8) | tr;
220 if (ioctl(fd, AVIA_GT_GV_SET_BLEV, val))
221 perror("AVIA_GT_GV_SET_BLEV");
223 #endif