]> git.vomp.tv Git - vompclient.git/blob - surfacedirectfb.cc
Fix text corruption in channel number display on live tv
[vompclient.git] / surfacedirectfb.cc
1 /*
2     Copyright 2004-2005 Chris Tallon, 2009 Marten Richter
3     Portions copyright 2008 Jon Gettler
4
5     This file is part of VOMP.
6
7     VOMP is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11
12     VOMP is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with VOMP; if not, write to the Free Software
19     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21
22 #include "surfacedirectfb.h"
23
24 #include "osd.h"
25 #include "bitmap.h"
26 #include "log.h"
27
28 #include "osddirectfb.h"
29
30
31
32 SurfaceDirectFB::SurfaceDirectFB(int id)
33 : Surface(id)
34 {
35    surface=NULL;
36 }
37
38 SurfaceDirectFB::~SurfaceDirectFB()
39 {
40    if (surface) surface->Release(surface);
41
42 }
43
44 int SurfaceDirectFB::create(UINT width, UINT height)
45 {
46   int counter=0;
47   while (!Osd::getInstance()->isInitted() && counter<2000) {
48     MILLISLEEP(50); //Wait for Grafiksystem initialization
49     counter++;
50   }
51   if (!Osd::getInstance()->isInitted()) return -1;
52   
53   IDirectFB*dfb=((OsdDirectFB*)Osd::getInstance())->getDfb();
54 printf("ich bin doof");fflush(stdout);  
55   if (screen == this) 
56   {
57     IDirectFBDisplayLayer *osd_layer=((OsdDirectFB*)Osd::getInstance())->getOsdLayer();
58     if (osd_layer->GetSurface(osd_layer,&surface)!=DFB_OK) 
59     {
60
61         return 0;
62     }
63     surface->Clear(surface,0x0,0x0,0x0,0xFF);
64   } else {
65     DFBSurfaceDescription dsc;
66     memset(&dsc,0,sizeof(dsc));
67     *((int*)&dsc.flags)=DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT;
68     
69     dsc.width=width;
70     dsc.height=height;
71     dsc.caps= DSCAPS_NONE;
72     if (dfb->CreateSurface(dfb,&dsc,&surface)!=DFB_OK) 
73     {
74         return 0;
75     }
76   }
77   return 1;
78 }
79
80 void SurfaceDirectFB::display()
81 {
82 //  unsigned long fb_descriptor[2];
83 /*
84   fb_descriptor[0] = surface.sfc.handle;
85   fb_descriptor[1] = 1;
86 */
87 //  ioctl(fdOsd, GFX_FB_ATTACH, fb_descriptor);
88 }
89
90
91 // ----------------------------------------------------------------------------
92
93 // Now for the drawing functions
94
95
96 int SurfaceDirectFB::fillblt(int x, int y, int width, int height, unsigned int c)
97 {
98     int sw,sh;
99     unsigned char r,g,b,a;
100     int nx,ny,nw,nh;
101     nx=x;
102     ny=y;
103     nw=width;
104     nh=height;
105     surface->GetSize(surface,&sw,&sh);
106     
107     if (nx >sw) nx=sw-1;
108     if (ny >sh) ny=sh-1;
109     
110     if ((nx+nw) >= sw) nw=sw-nx; 
111     if ((ny+nh) >= sh) nh=sh-ny; 
112
113     if ((nx<0) || (ny < 0) || (nh <=0) || (nw <=0)) {
114         return 0;
115     }
116     
117     a= (c &0xff000000)>>24;
118     r= (c &0x00ff0000)>>16;
119     g= (c &0x0000ff00)>>8;
120     b= (c &0x000000ff);
121     
122     
123     surface->SetColor(surface,r,g,b,a);
124     surface->FillRectangle(surface,nx,ny,nw,nh);
125     return 0;
126 }
127
128 void SurfaceDirectFB::drawPixel(int x, int y, unsigned int c, bool fastdraw)
129 {
130     int sw,sh;
131     unsigned char r,g,b,a;
132     char *dst=NULL;
133     int offset=0;
134     int pitch;
135     surface->GetSize(surface,&sw,&sh);
136     if (x>=sw) return;
137     if (y>=sh) return;
138     
139
140     
141     a= (c &0xff000000)>>24;
142     r= (c &0x00ff0000)>>16;
143     g= (c &0x0000ff00)>>8;
144     b= (c &0x000000ff);
145
146     //TODO Fastdraw
147     if (surface->Lock(surface,DSLF_WRITE,(void**)(void*)&dst,&pitch) == DFB_OK) {
148         offset= y* pitch+x*4;
149         dst[offset++]=b;
150         dst[offset++]=g;
151         dst[offset++]=r;
152         dst[offset]=a;
153         surface->Unlock(surface);
154      }
155
156 }
157
158 void SurfaceDirectFB::drawPixel(int x, int y, Colour& c, bool fastdraw)
159 {
160     int sw,sh;
161     char *dst=NULL;
162     int offset=0;
163     int pitch;
164     surface->GetSize(surface,&sw,&sh);
165     if (x>=sw) return;
166     if (y>=sh) return;
167     
168     //TODO Fastdraw
169     if (surface->Lock(surface,DSLF_WRITE,(void**)(void*)&dst,&pitch) == DFB_OK) {
170         offset= y* pitch+x*4;
171         dst[offset++]=c.blue;
172         dst[offset++]=c.green;
173         dst[offset++]=c.red;
174         dst[offset]=c.alpha;
175         surface->Unlock(surface);
176      }
177
178 }
179  
180 void SurfaceDirectFB::drawHorzLine(int x1, int x2, int y, unsigned int c)
181 {
182   fillblt(x1, y, x2-x1, 1, c);
183 }
184
185 void SurfaceDirectFB::drawVertLine(int x, int y1, int y2, unsigned int c)
186 {
187   fillblt(x, y1, 1, y2-y1, c);
188 }
189
190 void SurfaceDirectFB::drawBitmap(int x, int y, const Bitmap& bm)
191 {/*
192   UINT bmw = bm.getWidth(); UINT bmh = bm.getHeight();
193   if (bmw == 0 || bmh == 0) return;
194   if ((x >= (int)surface.sfc.width) || (y >= (int)surface.sfc.height)) return;
195   int remainder = (surface.sfc.width % 4);
196   UINT line;
197   if (remainder == 0)
198     line = surface.sfc.width;
199   else
200     line = surface.sfc.width + (4 - remainder);
201   const std::vector<UCHAR>& bmdata = bm.rawData();
202   const std::vector<UCHAR>& Y = bm.palette.getYVector();
203   const std::vector<UCHAR>& Cr = bm.palette.getCrVector();
204   const std::vector<UCHAR>& Cb = bm.palette.getCbVector();
205   const std::vector<UCHAR>& A = bm.palette.getAVector();
206   UINT b_offset = 0;
207   UINT s_offset = x + y*line;
208   UINT plotWidth = bmw;
209   UINT plotHeight = bmh;
210   if (x + plotWidth - 1 > surface.sfc.width)
211     plotWidth = surface.sfc.width - x + 1;
212   if (y + plotHeight - 1 > surface.sfc.height)
213     plotHeight = surface.sfc.height - y + 1;
214   for (UINT j = 0; j < plotHeight; ++j)
215   {
216     UINT i = 0;
217     if (x & 1) // odd x - need to plot first column separately
218     {
219       UCHAR index = bmdata[b_offset];
220       *(surface.base[0] + s_offset) = Y[index];
221       *(surface.base[1] + s_offset - 1) = Cb[index];
222       *(surface.base[1] + s_offset) = Cr[index];
223       *(surface.base[2] + s_offset) = A[index];
224       i = 1;
225     }
226     // Now, plot pairs of pixels with averaged chroma values
227     while (i < plotWidth - 1)
228     {
229       UCHAR index1 = bmdata[b_offset + i];
230       UCHAR index2 = bmdata[b_offset + i + 1];
231       *(surface.base[0] + s_offset + i) = Y[index1];
232       *(surface.base[0] + s_offset + i + 1) = Y[index2];
233       *(surface.base[1] + s_offset + i) = (Cb[index1] + Cb[index2]) / 2;
234       *(surface.base[1] + s_offset + i + 1) = (Cr[index1] + Cr[index2]) / 2;
235       *(surface.base[2] + s_offset + i) = A[index1];
236       *(surface.base[2] + s_offset + i + 1) = A[index2];
237       i += 2;
238     }
239     if (i == plotWidth - 1) // One column left to do
240     {
241       UCHAR index = bmdata[b_offset + i];
242       *(surface.base[0] + s_offset + i) = Y[index];
243       *(surface.base[1] + s_offset + i) = Cb[index];
244       *(surface.base[1] + s_offset + i + 1) = Cr[index];
245       *(surface.base[2] + s_offset + i) = A[index];
246     }
247     s_offset += line;
248     b_offset += bmw;
249   }*/
250 }
251
252   /* surface update to screen needs:
253   source x distance into this surface
254   source y distance into this surface
255   width of update
256   height of update
257   destination x on screen
258   destination y on screen
259   */
260 int SurfaceDirectFB::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
261 {
262   IDirectFBSurface* screensurf=((SurfaceDirectFB*)screen)->getSurfaceDFB();
263   if (!screensurf) return 0;
264   if (this==screen) return 0;
265   
266   DFBRectangle rect;
267   int sw,sh;
268   
269   screensurf->GetSize(screensurf,&sw,&sh);
270 //  screensurf->Clear(screensurf,0x0,0x0,0x0,0xFF);
271   rect.x = sx;
272   rect.y=sy;
273   rect.w=w;
274   rect.h=h;
275   
276   DFBRectangle drect; //TODO make osd HD
277   drect.x=dx*sw/720;
278   drect.y=dy*sh/576;
279   drect.w=w*sw/720;
280   drect.h=h*sh/576;
281   
282 //  screensurf->Blit(screensurf,surface,&rect,dx,dy);
283   screensurf->StretchBlit(screensurf,surface,&rect,&drect);
284   
285   return 0;//blt(fdOsd, surface.sfc.handle, sx, sy, w, h, ((SurfaceDirectFB*)screen)->getSurfaceHandle(), dx, dy);
286 }
287
288 int SurfaceDirectFB::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
289 {//Skip it, noone uses this!
290
291   return 0;
292 }
293
294 void SurfaceDirectFB::screenShot(const char* fileName)
295 {
296   return;
297   
298 }
299
300 void SurfaceDirectFB::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
301 {
302   
303 }
304