Added the DFCS_{HOT,TRANSPARENT} definitions.
[wine/gsoc_dplay.git] / dlls / msvideo / drawdib.c
blobabf20bd650baf773118c0380b0e7a5b70b25b904
1 /*
2 * Copyright 2000 Bradley Baetz
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * FIXME: Some flags are ignored
20 * Handle palettes
23 #include <string.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "wine/winbase16.h"
29 #include "wine/debug.h"
30 #include "vfw.h"
31 #include "vfw16.h"
32 #include "windef.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
36 typedef struct {
37 HDC hdc;
38 INT dxDst;
39 INT dyDst;
40 LPBITMAPINFOHEADER lpbi;
41 INT dxSrc;
42 INT dySrc;
43 HPALETTE hpal; /* Palette to use for the DIB */
44 BOOL begun; /* DrawDibBegin has been called */
45 LPBITMAPINFOHEADER lpbiOut; /* Output format */
46 HIC hic; /* HIC for decompression */
47 HDC hMemDC; /* DC for buffering */
48 HBITMAP hOldDib; /* Original Dib */
49 HBITMAP hDib; /* DibSection */
50 LPVOID lpvbits; /* Buffer for holding decompressed dib */
51 } WINE_HDD;
53 /***********************************************************************
54 * DrawDibOpen [MSVFW32.@]
56 HDRAWDIB VFWAPI DrawDibOpen(void) {
57 HDRAWDIB hdd;
59 TRACE("(void)\n");
60 hdd = GlobalAlloc16(GHND,sizeof(WINE_HDD));
61 TRACE("=> %d\n",hdd);
62 return hdd;
65 /***********************************************************************
66 * DrawDibOpen [MSVIDEO.102]
68 HDRAWDIB16 VFWAPI DrawDibOpen16(void) {
69 return (HDRAWDIB16)DrawDibOpen();
72 /***********************************************************************
73 * DrawDibClose [MSVFW32.@]
75 BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) {
76 WINE_HDD *whdd = GlobalLock16(hdd);
78 TRACE("(0x%08lx)\n",(DWORD)hdd);
80 if (!whdd)
81 return FALSE;
83 if (whdd->begun)
84 DrawDibEnd(hdd);
86 GlobalUnlock16(hdd);
87 GlobalFree16(hdd);
88 return TRUE;
91 /***********************************************************************
92 * DrawDibClose [MSVIDEO.103]
94 BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd) {
95 return DrawDibClose(hdd);
98 /***********************************************************************
99 * DrawDibEnd [MSVFW32.@]
101 BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) {
102 BOOL ret = TRUE;
103 WINE_HDD *whdd = GlobalLock16(hdd);
105 TRACE("(0x%08lx)\n",(DWORD)hdd);
107 whdd->hpal = 0; /* Do not free this */
108 whdd->hdc = 0;
109 if (whdd->lpbi) {
110 HeapFree(GetProcessHeap(),0,whdd->lpbi);
111 whdd->lpbi = NULL;
113 if (whdd->lpbiOut) {
114 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
115 whdd->lpbiOut = NULL;
118 whdd->begun = FALSE;
120 /*if (whdd->lpvbits)
121 HeapFree(GetProcessHeap(),0,whdd->lpvbuf);*/
123 if (whdd->hMemDC) {
124 SelectObject(whdd->hMemDC,whdd->hOldDib);
125 DeleteDC(whdd->hMemDC);
128 if (whdd->hDib)
129 DeleteObject(whdd->hDib);
131 if (whdd->hic) {
132 ICDecompressEnd(whdd->hic);
133 ICClose(whdd->hic);
136 whdd->lpvbits = NULL;
138 GlobalUnlock16(hdd);
139 return ret;
142 /***********************************************************************
143 * DrawDibEnd [MSVIDEO.105]
145 BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd) {
146 return DrawDibEnd(hdd);
149 /***********************************************************************
150 * DrawDibBegin [MSVFW32.@]
152 BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
153 HDC hdc,
154 INT dxDst,
155 INT dyDst,
156 LPBITMAPINFOHEADER lpbi,
157 INT dxSrc,
158 INT dySrc,
159 UINT wFlags) {
160 BOOL ret = TRUE;
161 WINE_HDD *whdd;
163 TRACE("(%d,0x%lx,%d,%d,%p,%d,%d,0x%08lx)\n",
164 hdd,(DWORD)hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
166 TRACE("lpbi: %ld,%ld/%ld,%d,%d,%ld,%ld,%ld,%ld,%ld,%ld\n",
167 lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes,
168 lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage,
169 lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed,
170 lpbi->biClrImportant);
172 if (wFlags & ~(DDF_BUFFER))
173 FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
175 whdd = (WINE_HDD*)GlobalLock16(hdd);
176 if (!whdd) return FALSE;
178 if (whdd->begun)
179 DrawDibEnd(hdd);
181 if (lpbi->biCompression) {
182 DWORD size = 0;
184 whdd->hic = ICOpen(ICTYPE_VIDEO,lpbi->biCompression,ICMODE_DECOMPRESS);
185 if (!whdd->hic) {
186 WARN("Could not open IC. biCompression == 0x%08lx\n",lpbi->biCompression);
187 ret = FALSE;
190 if (ret) {
191 size = ICDecompressGetFormat(whdd->hic,lpbi,NULL);
192 if (size == ICERR_UNSUPPORTED) {
193 WARN("Codec doesn't support GetFormat, giving up.\n");
194 ret = FALSE;
198 if (ret) {
199 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,size);
201 if (ICDecompressGetFormat(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
202 ret = FALSE;
205 if (ret) {
206 /* FIXME: Use Ex functions if available? */
207 if (ICDecompressBegin(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
208 ret = FALSE;
210 TRACE("biSizeImage == %ld\n",whdd->lpbiOut->biSizeImage);
211 TRACE("biCompression == %ld\n",whdd->lpbiOut->biCompression);
212 TRACE("biBitCount == %d\n",whdd->lpbiOut->biBitCount);
214 } else {
215 DWORD dwSize;
216 /* No compression */
217 TRACE("Not compressed!\n");
218 dwSize = lpbi->biSize + lpbi->biClrUsed*sizeof(RGBQUAD);
219 whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,dwSize);
220 memcpy(whdd->lpbiOut,lpbi,dwSize);
223 if (ret) {
224 /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(),0,whdd->lpbiOut->biSizeImage);*/
226 whdd->hMemDC = CreateCompatibleDC(hdc);
227 TRACE("Creating: %ld,%p\n",whdd->lpbiOut->biSize,whdd->lpvbits);
228 whdd->hDib = CreateDIBSection(whdd->hMemDC,(BITMAPINFO *)whdd->lpbiOut,DIB_RGB_COLORS,&(whdd->lpvbits),0,0);
229 if (!whdd->hDib) {
230 TRACE("Error: %ld\n",GetLastError());
232 TRACE("Created: %d,%p\n",whdd->hDib,whdd->lpvbits);
233 whdd->hOldDib = SelectObject(whdd->hMemDC,whdd->hDib);
236 if (ret) {
237 whdd->hdc = hdc;
238 whdd->dxDst = dxDst;
239 whdd->dyDst = dyDst;
240 whdd->lpbi = HeapAlloc(GetProcessHeap(),0,lpbi->biSize);
241 memcpy(whdd->lpbi,lpbi,lpbi->biSize);
242 whdd->dxSrc = dxSrc;
243 whdd->dySrc = dySrc;
244 whdd->begun = TRUE;
245 whdd->hpal = 0;
246 } else {
247 if (whdd->hic)
248 ICClose(whdd->hic);
249 if (whdd->lpbiOut) {
250 HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
251 whdd->lpbiOut = NULL;
255 GlobalUnlock16(hdd);
257 return ret;
260 /************************************************************************
261 * DrawDibBegin [MSVIDEO.104]
263 BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd,
264 HDC16 hdc,
265 INT16 dxDst,
266 INT16 dyDst,
267 LPBITMAPINFOHEADER lpbi,
268 INT16 dxSrc,
269 INT16 dySrc,
270 UINT16 wFlags) {
271 return DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,wFlags);
274 /**********************************************************************
275 * DrawDibDraw [MSVFW32.@]
277 BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc,
278 INT xDst, INT yDst, INT dxDst, INT dyDst,
279 LPBITMAPINFOHEADER lpbi,
280 LPVOID lpBits,
281 INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
282 UINT wFlags
284 WINE_HDD *whdd;
285 BOOL ret = TRUE;
287 TRACE("(%d,0x%lx,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08lx)\n",
288 hdd,(DWORD)hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,(DWORD)wFlags
291 if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME |
292 DDF_UPDATE | DDF_DONTDRAW))
293 FIXME("wFlags == 0x%08lx not handled\n",(DWORD)wFlags);
295 if (!lpBits) {
296 /* Undocumented? */
297 lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(lpbi->biClrUsed*sizeof(RGBQUAD));
300 whdd = GlobalLock16(hdd);
302 #define CHANGED(x) (whdd->x != x)
304 if ((!whdd->begun) || (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) || (!(wFlags & DDF_SAME_DRAW) &&
305 (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst)))) {
306 TRACE("Something changed!\n");
307 ret = DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,0);
310 #undef CHANGED
312 if ((dxDst == -1) && (dyDst == -1)) {
313 dxDst = dxSrc;
314 dyDst = dySrc;
317 if (!(wFlags & DDF_UPDATE)) {
318 /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */
319 if ((lpbi->biCompression == BI_RGB) && (lpbi->biSizeImage == 0))
320 lpbi->biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;
322 if (lpbi->biCompression) {
323 DWORD flags = 0;
325 TRACE("Compression == 0x%08lx\n",lpbi->biCompression);
327 if (wFlags & DDF_NOTKEYFRAME)
328 flags |= ICDECOMPRESS_NOTKEYFRAME;
330 ICDecompress(whdd->hic,flags,lpbi,lpBits,whdd->lpbiOut,whdd->lpvbits);
331 } else {
332 memcpy(whdd->lpvbits,lpBits,lpbi->biSizeImage);
335 if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
336 SelectPalette(hdc,whdd->hpal,FALSE);
338 if (!(StretchBlt(whdd->hdc,xDst,yDst,dxDst,dyDst,whdd->hMemDC,xSrc,ySrc,dxSrc,dySrc,SRCCOPY)))
339 ret = FALSE;
341 GlobalUnlock16(hdd);
342 return ret;
345 /**********************************************************************
346 * DrawDibDraw [MSVIDEO.106]
348 BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd,
349 HDC16 hdc,
350 INT16 xDst,
351 INT16 yDst,
352 INT16 dxDst,
353 INT16 dyDst,
354 LPBITMAPINFOHEADER lpbi,
355 LPVOID lpBits,
356 INT16 xSrc,
357 INT16 ySrc,
358 INT16 dxSrc,
359 INT16 dySrc,
360 UINT16 wFlags) {
361 return DrawDibDraw(hdd,hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,wFlags);
364 /*************************************************************************
365 * DrawDibStart [MSVFW32.@]
367 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
368 FIXME("(0x%08lx,%ld), stub\n",(DWORD)hdd,rate);
369 return TRUE;
372 /*************************************************************************
373 * DrawDibStart [MSVIDEO.118]
375 BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate) {
376 return DrawDibStart(hdd,rate);
379 /*************************************************************************
380 * DrawDibStop [MSVFW32.@]
382 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
383 FIXME("(0x%08lx), stub\n",(DWORD)hdd);
384 return TRUE;
387 /*************************************************************************
388 * DrawDibStop [MSVIDEO.119]
390 BOOL16 DrawDibStop16(HDRAWDIB16 hdd) {
391 return DrawDibStop(hdd);
394 /***********************************************************************
395 * DrawDibSetPalette [MSVFW32.@]
397 BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) {
398 WINE_HDD *whdd;
400 TRACE("(0x%08lx,0x%08lx)\n",(DWORD)hdd,(DWORD)hpal);
402 whdd = GlobalLock16(hdd);
403 whdd->hpal = hpal;
405 if (whdd->begun) {
406 SelectPalette(whdd->hdc,hpal,0);
407 RealizePalette(whdd->hdc);
409 GlobalUnlock16(hdd);
410 return TRUE;
413 /***********************************************************************
414 * DrawDibSetPalette [MSVIDEO.110]
416 BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal) {
417 return DrawDibSetPalette(hdd,hpal);
420 /***********************************************************************
421 * DrawDibGetPalette [MSVFW32.@]
423 HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) {
424 WINE_HDD *whdd;
425 HPALETTE ret;
427 TRACE("(0x%08lx)\n",(DWORD)hdd);
429 whdd = GlobalLock16(hdd);
430 ret = whdd->hpal;
431 GlobalUnlock16(hdd);
432 return ret;
435 /***********************************************************************
436 * DrawDibGetPalette [MSVIDEO.108]
438 HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd) {
439 return (HPALETTE16)DrawDibGetPalette(hdd);
442 /***********************************************************************
443 * DrawDibRealize [MSVFW32.@]
445 UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) {
446 WINE_HDD *whdd;
447 HPALETTE oldPal;
448 UINT ret = 0;
450 FIXME("(%d,0x%08lx,%d), stub\n",hdd,(DWORD)hdc,fBackground);
452 whdd = GlobalLock16(hdd);
454 if (!whdd || !(whdd->begun)) {
455 ret = 0;
456 goto out;
459 if (!whdd->hpal)
460 whdd->hpal = CreateHalftonePalette(hdc);
462 oldPal = SelectPalette(hdc,whdd->hpal,fBackground);
463 ret = RealizePalette(hdc);
465 out:
466 GlobalUnlock16(hdd);
468 TRACE("=> %u\n",ret);
469 return ret;
472 /***********************************************************************
473 * DrawDibRealize [MSVIDEO.112]
475 UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc, BOOL16 fBackground) {
476 return (UINT16)DrawDibRealize(hdd,hdc,fBackground);