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