fix string-length to correctly display the frontend type
[enigma2.git] / lib / gdi / fb.cpp
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>
9
10 #include <lib/base/econfig.h>
11 #include <lib/gdi/fb.h>
12
13 #ifndef FBIO_WAITFORVSYNC
14 #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
15 #endif
16
17
18 fbClass *fbClass::instance;
19
20 fbClass *fbClass::getInstance()
21 {
22         return instance;
23 }
24
25 fbClass::fbClass(const char *fb)
26 {
27         instance=this;
28         locked=0;
29         available=0;
30         cmap.start=0;
31         cmap.len=256;
32         cmap.red=red;
33         cmap.green=green;
34         cmap.blue=blue;
35         cmap.transp=trans;
36
37         fd=open(fb, O_RDWR);
38         if (fd<0)
39         {
40                 perror(fb);
41                 goto nolfb;
42         }
43         if (ioctl(fd, FBIOGET_VSCREENINFO, &screeninfo)<0)
44         {
45                 perror("FBIOGET_VSCREENINFO");
46                 goto nolfb;
47         }
48         
49         memcpy(&oldscreen, &screeninfo, sizeof(screeninfo));
50
51         fb_fix_screeninfo fix;
52         if (ioctl(fd, FBIOGET_FSCREENINFO, &fix)<0)
53         {
54                 perror("FBIOGET_FSCREENINFO");
55                 goto nolfb;
56         }
57
58         available=fix.smem_len;
59         eDebug("%dk video mem", available/1024);
60         lfb=(unsigned char*)mmap(0, available, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
61         if (!lfb)
62         {
63                 perror("mmap");
64                 goto nolfb;
65         }
66
67         showConsole(0);
68         return;
69 nolfb:
70         lfb=0;
71         printf("framebuffer not available.\n");
72         return;
73 }
74
75 int fbClass::showConsole(int state)
76 {
77         int fd=open("/dev/vc/0", O_RDWR);
78         if(fd>=0)
79         {
80                 if(ioctl(fd, KDSETMODE, state?KD_TEXT:KD_GRAPHICS)<0)
81                 {
82                         eDebug("setting /dev/vc/0 status failed.");
83                 }
84                 close(fd);
85         }
86         return 0;
87 }
88
89 int fbClass::SetMode(unsigned int nxRes, unsigned int nyRes, unsigned int nbpp)
90 {
91         screeninfo.xres_virtual=screeninfo.xres=nxRes;
92         screeninfo.yres_virtual=(screeninfo.yres=nyRes)*2;
93         screeninfo.height=0;
94         screeninfo.width=0;
95         screeninfo.xoffset=screeninfo.yoffset=0;
96         screeninfo.bits_per_pixel=nbpp;
97         
98         if (ioctl(fd, FBIOPUT_VSCREENINFO, &screeninfo)<0)
99         {
100                 // try single buffering
101                 screeninfo.yres_virtual=screeninfo.yres=nyRes;
102                 
103                 if (ioctl(fd, FBIOPUT_VSCREENINFO, &screeninfo)<0)
104                 {
105                         perror("FBIOPUT_VSCREENINFO");
106                         printf("fb failed\n");
107                         return -1;
108                 }
109                 eDebug(" - double buffering not available.");
110         } else
111                 eDebug(" - double buffering available!");
112         
113         m_number_of_pages = screeninfo.yres_virtual / nyRes;
114         
115         if ((screeninfo.xres!=nxRes) && (screeninfo.yres!=nyRes) && (screeninfo.bits_per_pixel!=nbpp))
116         {
117                 eDebug("SetMode failed: wanted: %dx%dx%d, got %dx%dx%d",
118                         nxRes, nyRes, nbpp,
119                         screeninfo.xres, screeninfo.yres, screeninfo.bits_per_pixel);
120         }
121         xRes=screeninfo.xres;
122         yRes=screeninfo.yres;
123         bpp=screeninfo.bits_per_pixel;
124         fb_fix_screeninfo fix;
125         if (ioctl(fd, FBIOGET_FSCREENINFO, &fix)<0)
126         {
127                 perror("FBIOGET_FSCREENINFO");
128                 printf("fb failed\n");
129         }
130         stride=fix.line_length;
131         memset(lfb, 0, stride*yRes);
132         return 0;
133 }
134
135 int fbClass::setOffset(int off)
136 {
137         screeninfo.xoffset = 0;
138         screeninfo.yoffset = off;
139         return ioctl(fd, FBIOPAN_DISPLAY, &screeninfo);
140 }
141
142 int fbClass::waitVSync()
143 {
144         int c = 0;
145         return ioctl(fd, FBIO_WAITFORVSYNC, &c);
146 }
147
148 fbClass::~fbClass()
149 {
150         if (available)
151                 ioctl(fd, FBIOPUT_VSCREENINFO, &oldscreen);
152         if (lfb)
153                 munmap(lfb, available);
154         showConsole(1);
155 }
156
157 int fbClass::PutCMAP()
158 {
159         return ioctl(fd, FBIOPUTCMAP, &cmap);
160 }
161
162 int fbClass::lock()
163 {
164         if (locked)
165                 return -1;
166         locked=1;
167         return fd;
168 }
169
170 void fbClass::unlock()
171 {
172         if (!locked)
173                 return;
174         locked=0;
175         SetMode(xRes, yRes, bpp);
176         PutCMAP();
177 }