]> git.vomp.tv Git - vompclient-marten.git/blob - surfacewin.cc
Mouse support (part 1)
[vompclient-marten.git] / surfacewin.cc
1 /*
2     Copyright 2006 Marten Richter
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "surfacewin.h"
22 #include "osdwin.h"
23 #include <d3dx9tex.h>
24
25 SurfaceWin::SurfaceWin(int id)
26 : Surface(id)
27 {
28   d3dtexture=NULL;
29   d3dsurface=NULL;
30   sheight=swidth=0;
31   event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
32 }
33
34 SurfaceWin::~SurfaceWin()
35 {
36   if (d3dsurface) d3dsurface->Release();
37   if (d3dtexture) d3dtexture->Release();
38   CloseHandle(event);
39 }
40
41 int SurfaceWin::create(UINT width, UINT height)
42 {
43   LPDIRECT3DDEVICE9 d3ddev=((OsdWin*)(Osd::getInstance()))->getD3dDev();
44   while (true) {
45     if (screen==this) {
46       if (d3ddev->CreateTexture(1024,1024,0,0,D3DFMT_A8R8G8B8,
47         // Does every adapter with alpha blending support this?
48         D3DPOOL_DEFAULT,&d3dtexture ,NULL)!=D3D_OK) {
49           MILLISLEEP(50);//wait maybe next time it will work
50           continue;
51       }
52       if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {
53         d3dtexture->Release();
54         d3dtexture=NULL;
55         MILLISLEEP(50);
56         continue;
57       }
58     } else {
59       HRESULT hres;
60       if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,
61         D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {
62           MILLISLEEP(50);//wait maybe next time it will work
63           continue;
64       }
65
66     }
67     sheight=height;
68     swidth=width;
69     /* If someone does high performance Animations on the OSD, we have to change the types
70      of surface in order to address these performance issues, if we have only very few updates
71      per second this would be fast enough !*/
72     break;
73   }
74   SetEvent(event);
75   return 1;
76 }
77
78 void SurfaceWin::display()
79 {
80 }
81
82 int SurfaceWin::fillblt(int x, int y, int width, int height, unsigned int c)
83 {
84   WaitForSingleObject(event,INFINITE); //since this might be called before surface
85   //allocation we will wait in this case, hopefully without deadlocks
86   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
87
88   if (!d3dsurface) {
89     return 0; //why does this happen
90   }
91
92   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
93
94   if (screen==this) {
95     //This should not happen!
96     return 0;
97
98   } else {
99     osd->BeginPainting();
100     D3DLOCKED_RECT lockrect;
101     int cx,cy,cwidth,cheight;
102     cx=min(max(x,0),swidth-1);
103     cy=min(max(y,0),sheight-1);
104     cwidth=min(width,swidth-x);
105     cheight=min(height,sheight-y);
106     RECT rect={cx,cy,cwidth,cheight};
107
108     if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
109       return 0;
110     }
111     unsigned int line;
112     unsigned int column;
113     for (line=0;line<cheight;line++) {
114       unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));
115       for (column=0;column<cwidth;column++) {
116         row[column]=c;
117       }
118     }
119
120     if (d3dsurface->UnlockRect()!=D3D_OK) {
121       osd->EndPainting();
122       return 0;
123     }
124     osd->EndPainting();
125   }
126
127   return 0;
128 }
129
130 void SurfaceWin::drawPixel(int x, int y, unsigned int c)
131 {
132   //FixMe: locking for every single Pixel will be painfully slow
133   WaitForSingleObject(event,INFINITE); //since this might be called before surface
134   //allocation we will wait in this case, hopefully without deadlocks
135   if (!d3dsurface) {
136     return; //why does this happen
137   }
138   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
139   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
140   if (x>=swidth || y>=sheight) return; //do not draw outside the surface
141   if (screen==this) {
142     //This should not happen!
143     return ;
144
145   } else {
146     osd->BeginPainting();
147     D3DLOCKED_RECT lockrect;
148     RECT rect={x,y,x+1,y+1};
149     if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
150       osd->EndPainting();
151       return ;
152     }
153     unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
154     row[0]=c;
155     if (d3dsurface->UnlockRect()!=D3D_OK) {
156       osd->EndPainting();
157       return ;
158     }
159     osd->EndPainting();
160   }
161
162 }
163
164 void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c)
165 {
166    fillblt(x1, y, x2-x1, 1, c);
167 }
168
169 void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c)
170 {
171   fillblt(x, y1, 1, y2-y1, c);
172 }
173
174 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
175 {
176   WaitForSingleObject(event,INFINITE); //since this might be called before surface
177   //allocation we will wait in this case, hopefully without deadlocks
178   if (!d3dsurface) {
179     return 0; //why does this happen
180   }
181   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
182   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
183     LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();
184   if (!screensurface) return 0;
185   RECT sourcerect={sx,sy,sx+w,sy+h};
186   POINT destpoint={dx,dy};
187   osd->BeginPainting();
188   if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {
189     Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");
190     osd->EndPainting();
191     return 0;
192   }
193   osd->EndPainting();
194   return 0;
195 }
196
197 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
198 {
199   //I don't see code using this function, so I skip it, since it is a MVP specific interface
200   return 0;
201 }
202
203 void SurfaceWin::screenShot(char* fileName)
204 {
205   //Isn't this for debugging only, so I won't implement it yet
206 }
207
208 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
209 {
210   //Isn't this for debugging only, so I won't implement it yet
211 }
212 void SurfaceWin::ReleaseSurface()
213 {
214   ResetEvent(event);
215   LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
216   LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
217   d3dsurface=NULL;
218   d3dtexture=NULL;
219   sheight=swidth=0;
220   if (temp_surf) temp_surf->Release();
221   if (temp_text) temp_text->Release();
222 }
223
224 void SurfaceWin::drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height){
225   WaitForSingleObject(event,INFINITE); //since this might be called before surface
226   //allocation we will wait in this case, hopefully without deadlocks
227   if (!d3dsurface) {
228     return ; //why does this happen
229   }
230   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
231
232
233   D3DXIMAGE_INFO image_inf;
234   osd->BeginPainting();
235 //  D3DXGetImageInfoFromFile(fileName,&image_inf);
236   D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
237   RECT dest_rec={x,y,x+image_inf.Width,
238     y+image_inf.Height};
239 /*  if (D3DXLoadSurfaceFromFile(
240     d3dsurface,
241     NULL,
242     &dest_rec,
243     fileName,
244     NULL,
245     D3DX_FILTER_NONE,
246     0,
247     &image_inf)!=D3D_OK) {
248       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
249
250   }*/
251   if (D3DXLoadSurfaceFromResource(
252     d3dsurface,
253     NULL,
254     &dest_rec,
255     NULL,
256     fileName,
257     NULL,
258     D3DX_FILTER_NONE,
259     0,
260     &image_inf)!=D3D_OK) {
261       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
262
263   }
264   osd->EndPainting();
265   *width=image_inf.Width;
266   *height=image_inf.Height;
267
268 }
269
270