Extrenal srt problem gst-1 solved.
[openblackhole/openblackhole-enigma2.git] / lib / gdi / fblcd.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/fblcd.h>
11
12 #ifndef FBIO_BLIT
13 #define FBIO_SET_MANUAL_BLIT _IOW('F', 0x21, __u8)
14 #define FBIO_BLIT 0x22
15 #endif
16
17 eFbLCD::eFbLCD(const char *fb)
18 {
19         m_manual_blit = -1;
20         instance = this;
21         locked = 0;
22         _buffer = 0;
23         m_available = 0;
24         m_cmap.start = 0;
25         m_cmap.len = 256;
26         m_cmap.red = m_red;
27         m_cmap.green = m_green;
28         m_cmap.blue = m_blue;
29         m_cmap.transp = m_trans;
30         m_alpha = 255;
31         m_gamma = 128;
32         m_brightness = 128;
33
34         lcdfd = open(fb, O_RDWR);
35         if (lcdfd < 0)
36         {
37                 eDebug("[eFbLCD] %s: %m", fb);
38                 goto nolfb;
39         }
40
41         if (ioctl(lcdfd, FBIOGET_VSCREENINFO, &m_screeninfo) < 0)
42         {
43                 eDebug("[eFbLCD] FBIOGET_VSCREENINFO: %m");
44                 goto nolfb;
45         }
46
47         fb_fix_screeninfo fix;
48         if (ioctl(lcdfd, FBIOGET_FSCREENINFO, &fix) < 0)
49         {
50                 eDebug("[eFbLCD] FBIOGET_FSCREENINFO: %m");
51                 goto nolfb;
52         }
53
54         m_available = fix.smem_len;
55         m_phys_mem = fix.smem_start;
56         eDebug("[eFbLCD] %dk video mem", m_available / 1024);
57         _buffer=(unsigned char*)mmap(0, m_available, PROT_WRITE|PROT_READ, MAP_SHARED, lcdfd, 0);
58         if (!_buffer)
59         {
60                 eDebug("[eFbLCD] mmap: %m");
61                 goto nolfb;
62         }
63
64         lcd_type = 4;
65         calcRamp();
66         getMode();
67         setMode(m_xRes, m_yRes, m_bpp);
68         enableManualBlit();
69
70         return;
71 nolfb:
72         if (lcdfd >= 0)
73         {
74                 ::close(lcdfd);
75                 lcdfd = -1;
76         }
77         eDebug("[eFbLCD] framebuffer not available");
78         return;
79 }
80
81 eFbLCD::~eFbLCD()
82 {
83         if (_buffer)
84         {
85                 msync(_buffer, m_available, MS_SYNC);
86                 munmap(_buffer, m_available);
87                 _buffer = 0;
88         }
89         if (lcdfd >= 0)
90         {
91                 ::close(lcdfd);
92                 lcdfd = -1;
93         }
94 }
95
96 int eFbLCD::setMode(int nxRes, int nyRes, int nbpp)
97 {
98         m_screeninfo.xres_virtual = m_screeninfo.xres = nxRes;
99         m_screeninfo.yres_virtual = (m_screeninfo.yres = nyRes) * 2;
100         m_screeninfo.height = 0;
101         m_screeninfo.width = 0;
102         m_screeninfo.xoffset = m_screeninfo.yoffset = 0;
103         m_screeninfo.bits_per_pixel = nbpp;
104
105         switch (nbpp) {
106         case 16:
107                 // ARGB 1555
108                 m_screeninfo.transp.offset = 15;
109                 m_screeninfo.transp.length = 1;
110                 m_screeninfo.red.offset = 10;
111                 m_screeninfo.red.length = 5;
112                 m_screeninfo.green.offset = 5;
113                 m_screeninfo.green.length = 5;
114                 m_screeninfo.blue.offset = 0;
115                 m_screeninfo.blue.length = 5;
116                 break;
117         case 32:
118                 // ARGB 8888
119                 m_screeninfo.transp.offset = 24;
120                 m_screeninfo.transp.length = 8;
121                 m_screeninfo.red.offset = 16;
122                 m_screeninfo.red.length = 8;
123                 m_screeninfo.green.offset = 8;
124                 m_screeninfo.green.length = 8;
125                 m_screeninfo.blue.offset = 0;
126                 m_screeninfo.blue.length = 8;
127                 break;
128         }
129
130         if (ioctl(lcdfd, FBIOPUT_VSCREENINFO, &m_screeninfo) < 0)
131         {
132                 // try single buffering
133                 m_screeninfo.yres_virtual = m_screeninfo.yres=nyRes;
134
135                 if (ioctl(lcdfd, FBIOPUT_VSCREENINFO, &m_screeninfo) < 0)
136                 {
137                         eDebug("[eFbLCD] FBIOPUT_VSCREENINFO: %m");
138                         return -1;
139                 }
140                 eDebug("[eFbLCD] double buffering not available.");
141         }
142         else
143                 eDebug("[eFbLCD] double buffering available!");
144
145         ioctl(lcdfd, FBIOGET_VSCREENINFO, &m_screeninfo);
146
147         if ((m_screeninfo.xres != nxRes) && (m_screeninfo.yres != nyRes) && (m_screeninfo.bits_per_pixel != nbpp))
148         {
149                 eDebug("[eFbLCD] SetMode failed: wanted: %dx%dx%d, got %dx%dx%d",
150                         nxRes, nyRes, nbpp,
151                         m_screeninfo.xres, m_screeninfo.yres, m_screeninfo.bits_per_pixel);
152         }
153         m_xRes = m_screeninfo.xres;
154         m_yRes = m_screeninfo.yres;
155         m_bpp = m_screeninfo.bits_per_pixel;
156         fb_fix_screeninfo fix;
157         if (ioctl(lcdfd, FBIOGET_FSCREENINFO, &fix) < 0)
158         {
159                 eDebug("[eFbLCD] FBIOGET_FSCREENINFO: %m");
160         }
161         _stride = fix.line_length;
162         memset(_buffer, 0, _stride * m_yRes);
163         update();
164         return 0;
165 }
166
167 void eFbLCD::getMode()
168 {
169         m_xRes = m_screeninfo.xres;
170         m_yRes = m_screeninfo.yres;
171         m_bpp = m_screeninfo.bits_per_pixel;
172 }
173
174 int eFbLCD::waitVSync()
175 {
176         int c = 0;
177         return ioctl(lcdfd, FBIO_WAITFORVSYNC, &c);
178 }
179
180 void eFbLCD::update() // blit
181 {
182         if (m_manual_blit == 1)
183         {
184                 if (ioctl(lcdfd, FBIO_BLIT) < 0)
185                         eDebug("[eFbLCD] FBIO_BLIT: %m");
186         }
187 }
188
189 int eFbLCD::putCMAP()
190 {
191         return ioctl(lcdfd, FBIOPUTCMAP, &m_cmap);
192 }
193
194 int eFbLCD::lock()
195 {
196         if (locked)
197                 return -1;
198         if (m_manual_blit == 1)
199         {
200                 locked = 2;
201                 disableManualBlit();
202         }
203         else
204                 locked = 1;
205         return lcdfd;
206 }
207
208 void eFbLCD::unlock()
209 {
210         if (!locked)
211                 return;
212         if (locked == 2)  // re-enable manualBlit
213                 enableManualBlit();
214         locked = 0;
215         setMode(m_xRes, m_yRes, m_bpp);
216         putCMAP();
217 }
218
219 void eFbLCD::calcRamp()
220 {
221         for (int i = 0; i < 256; i++)
222         {
223                 int d;
224                 d = i;
225                 d = (d-128)*(m_gamma+64)/(128+64)+128;
226                 d += m_brightness-128; // brightness correction
227                 if (d < 0)
228                         d = 0;
229                 if (d > 255)
230                         d = 255;
231                 m_ramp[i] = d;
232
233                 m_rampalpha[i] = i*m_alpha/256;
234         }
235
236         m_rampalpha[255] = 255; // transparent BLEIBT bitte so.
237 }
238
239 void eFbLCD::setPalette(gUnmanagedSurface surface)
240 {
241         if (!surface.clut.data)
242                 return;
243
244         for (int i=0; i < 256; ++i)
245         {
246                 m_cmap.red[i] = m_ramp[surface.clut.data[i].r]<<8;
247                 m_cmap.green[i] = m_ramp[surface.clut.data[i].g]<<8;
248                 m_cmap.blue[i] = m_ramp[surface.clut.data[i].b]<<8;
249                 m_cmap.transp[i] = m_rampalpha[surface.clut.data[i].a]<<8;
250         }
251         putCMAP();
252 }
253
254 void eFbLCD::enableManualBlit()
255 {
256         unsigned char tmp = 1;
257         if (ioctl(lcdfd, FBIO_SET_MANUAL_BLIT, &tmp) < 0)
258                 eDebug("[eFbLCD] enable FBIO_SET_MANUAL_BLIT: %m");
259         else
260                 m_manual_blit = 1;
261 }
262
263 void eFbLCD::disableManualBlit()
264 {
265         unsigned char tmp = 0;
266         if (ioctl(lcdfd, FBIO_SET_MANUAL_BLIT, &tmp) < 0)
267                 eDebug("[eFbLCD] disable FBIO_SET_MANUAL_BLIT: %m");
268         else
269                 m_manual_blit = 0;
270 }
271
272 int eFbLCD::setLCDBrightness(int brightness)
273 {
274         eDebug("[eFbLCD] setLCDBrightness %d", brightness);
275         FILE *f = fopen("/proc/stb/lcd/oled_brightness", "w");
276         if (f)
277         {
278                 if (fprintf(f, "%d", brightness) == 0)
279                         eDebug("[eFbLCD] write /proc/stb/lcd/oled_brightness failed: %m");
280                 fclose(f);
281         }
282         return 0;
283 }