1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
19 #ifndef X_DISPLAY_MISSING
25 #include <sys/types.h>
29 #endif /* defined(HAVE_LIBXXSHM) */
31 #ifdef HAVE_LIBXXF86DGA
32 #include "ts_xf86dga.h"
33 #endif /* defined(HAVE_LIBXXF86DGA) */
35 #ifdef HAVE_LIBXXF86VM
36 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
37 this is a crude hack to get around it */
40 #include "ts_xf86vmode.h"
41 #endif /* defined(HAVE_LIBXXF86VM) */
47 #include <sys/signal.h>
66 /* This for all the enumeration and creation of D3D-related objects */
67 #include "d3d_private.h"
69 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
72 /* Restore signal handlers overwritten by XF86DGA
74 #define RESTORE_SIGNALS
76 /* Where do these GUIDs come from? mkuuid.
77 * They exist solely to distinguish between the targets Wine support,
78 * and should be different than any other GUIDs in existence.
80 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
84 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
87 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
91 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
94 static struct IDirectDrawSurface4_VTable dga_dds4vt, xlib_dds4vt;
95 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
96 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
97 static struct IDirectDraw4_VTable dga_dd4vt, xlib_dd4vt;
98 static struct IDirectDrawClipper_VTable ddclipvt;
99 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
100 static struct IDirect3D_VTable d3dvt;
101 static struct IDirect3D2_VTable d3d2vt;
103 #ifdef HAVE_LIBXXF86VM
104 static XF86VidModeModeInfo *orig_mode = NULL;
108 static int XShmErrorFlag = 0;
112 DDRAW_DGA_Available(void)
114 #ifdef HAVE_LIBXXF86DGA
115 int evbase, evret, fd;
120 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
121 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
122 /* others. --stephenc */
123 if ((fd = open("/dev/mem", O_RDWR)) != -1)
126 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
127 #else /* defined(HAVE_LIBXXF86DGA) */
129 #endif /* defined(HAVE_LIBXXF86DGA) */
132 /**********************************************************************/
137 } DirectDrawEnumerateProcData;
139 /***********************************************************************
140 * DirectDrawEnumerateExA (DDRAW.*)
142 HRESULT WINAPI DirectDrawEnumerateExA(
143 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
145 TRACE(ddraw, "(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
147 if (TRACE_ON(ddraw)) {
149 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
150 DUMP("DDENUM_ATTACHEDSECONDARYDEVICES ");
151 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
152 DUMP("DDENUM_DETACHEDSECONDARYDEVICES ");
153 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
154 DUMP("DDENUM_NONDISPLAYDEVICES ");
158 if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
159 /* For the moment, Wine does not support any 3D only accelerators */
163 if (DDRAW_DGA_Available()) {
164 TRACE(ddraw, "Enumerating DGA interface\n");
165 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, NULL))
169 TRACE(ddraw, "Enumerating Xlib interface\n");
170 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, NULL))
173 TRACE(ddraw, "Enumerating Default interface\n");
174 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, NULL))
180 /***********************************************************************
181 * DirectDrawEnumerateExW (DDRAW.*)
184 static BOOL CALLBACK DirectDrawEnumerateExProcW(
185 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
186 LPVOID lpContext, HMONITOR hm)
188 DirectDrawEnumerateProcData *pEPD =
189 (DirectDrawEnumerateProcData *) lpContext;
190 LPWSTR lpDriverDescriptionW =
191 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
192 LPWSTR lpDriverNameW =
193 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
195 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
196 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
198 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
199 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
204 /**********************************************************************/
206 HRESULT WINAPI DirectDrawEnumerateExW(
207 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
209 DirectDrawEnumerateProcData epd;
210 epd.lpCallback = lpCallback;
211 epd.lpContext = lpContext;
213 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
217 /***********************************************************************
218 * DirectDrawEnumerateA (DDRAW.*)
221 static BOOL CALLBACK DirectDrawEnumerateProcA(
222 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
223 LPVOID lpContext, HMONITOR hm)
225 DirectDrawEnumerateProcData *pEPD =
226 (DirectDrawEnumerateProcData *) lpContext;
228 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
229 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
232 /**********************************************************************/
234 HRESULT WINAPI DirectDrawEnumerateA(
235 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
237 DirectDrawEnumerateProcData epd;
238 epd.lpCallback = lpCallback;
239 epd.lpContext = lpContext;
241 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
245 /***********************************************************************
246 * DirectDrawEnumerateW (DDRAW.*)
249 static BOOL DirectDrawEnumerateProcW(
250 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
251 LPVOID lpContext, HMONITOR hm)
253 DirectDrawEnumerateProcData *pEPD =
254 (DirectDrawEnumerateProcData *) lpContext;
256 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
257 lpGUID, lpDriverDescription, lpDriverName,
261 /**********************************************************************/
263 HRESULT WINAPI DirectDrawEnumerateW(
264 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
266 DirectDrawEnumerateProcData epd;
267 epd.lpCallback = lpCallback;
268 epd.lpContext = lpContext;
270 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
274 /***********************************************************************
275 * DSoundHelp (DDRAW.?)
278 /* What is this doing here? */
280 DSoundHelp(DWORD x,DWORD y,DWORD z) {
281 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
285 /******************************************************************************
286 * internal helper functions
288 static void _dump_DDBLTFX(DWORD flagmask) {
294 #define FE(x) { x, #x},
295 FE(DDBLTFX_ARITHSTRETCHY)
296 FE(DDBLTFX_MIRRORLEFTRIGHT)
297 FE(DDBLTFX_MIRRORUPDOWN)
298 FE(DDBLTFX_NOTEARING)
299 FE(DDBLTFX_ROTATE180)
300 FE(DDBLTFX_ROTATE270)
302 FE(DDBLTFX_ZBUFFERRANGE)
303 FE(DDBLTFX_ZBUFFERBASEDEST)
305 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
306 if (flags[i].mask & flagmask) {
307 DUMP("%s ",flags[i].name);
314 static void _dump_DDBLTFAST(DWORD flagmask) {
320 #define FE(x) { x, #x},
321 FE(DDBLTFAST_NOCOLORKEY)
322 FE(DDBLTFAST_SRCCOLORKEY)
323 FE(DDBLTFAST_DESTCOLORKEY)
326 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
327 if (flags[i].mask & flagmask)
328 DUMP("%s ",flags[i].name);
332 static void _dump_DDBLT(DWORD flagmask) {
338 #define FE(x) { x, #x},
340 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
341 FE(DDBLT_ALPHADESTNEG)
342 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
343 FE(DDBLT_ALPHAEDGEBLEND)
345 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
346 FE(DDBLT_ALPHASRCNEG)
347 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
353 FE(DDBLT_KEYDESTOVERRIDE)
355 FE(DDBLT_KEYSRCOVERRIDE)
357 FE(DDBLT_ROTATIONANGLE)
359 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
360 FE(DDBLT_ZBUFFERDESTOVERRIDE)
361 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
362 FE(DDBLT_ZBUFFERSRCOVERRIDE)
366 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
367 if (flags[i].mask & flagmask)
368 DUMP("%s ",flags[i].name);
372 static void _dump_DDSCAPS(DWORD flagmask) {
378 #define FE(x) { x, #x},
379 FE(DDSCAPS_RESERVED1)
381 FE(DDSCAPS_BACKBUFFER)
384 FE(DDSCAPS_FRONTBUFFER)
385 FE(DDSCAPS_OFFSCREENPLAIN)
388 FE(DDSCAPS_PRIMARYSURFACE)
389 FE(DDSCAPS_PRIMARYSURFACELEFT)
390 FE(DDSCAPS_SYSTEMMEMORY)
393 FE(DDSCAPS_VIDEOMEMORY)
395 FE(DDSCAPS_WRITEONLY)
398 FE(DDSCAPS_LIVEVIDEO)
402 FE(DDSCAPS_RESERVED2)
403 FE(DDSCAPS_ALLOCONLOAD)
404 FE(DDSCAPS_VIDEOPORT)
405 FE(DDSCAPS_LOCALVIDMEM)
406 FE(DDSCAPS_NONLOCALVIDMEM)
407 FE(DDSCAPS_STANDARDVGAMODE)
408 FE(DDSCAPS_OPTIMIZED)
410 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
411 if (flags[i].mask & flagmask)
412 DUMP("%s ",flags[i].name);
416 static void _dump_DDSD(DWORD flagmask) {
426 FE(DDSD_BACKBUFFERCOUNT)
427 FE(DDSD_ZBUFFERBITDEPTH)
428 FE(DDSD_ALPHABITDEPTH)
430 FE(DDSD_CKDESTOVERLAY)
432 FE(DDSD_CKSRCOVERLAY)
439 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
440 if (flags[i].mask & flagmask)
441 DUMP("%s ",flags[i].name);
445 static void _dump_DDCOLORKEY(DWORD flagmask) {
451 #define FE(x) { x, #x},
455 FE(DDPF_PALETTEINDEXED4)
456 FE(DDPF_PALETTEINDEXEDTO8)
457 FE(DDPF_PALETTEINDEXED8)
463 FE(DDPF_PALETTEINDEXED1)
464 FE(DDPF_PALETTEINDEXED2)
467 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
468 if (flags[i].mask & flagmask)
469 DUMP("%s ",flags[i].name);
473 static void _dump_paletteformat(DWORD dwFlags) {
479 #define FE(x) { x, #x},
481 FE(DDPCAPS_8BITENTRIES)
483 FE(DDPCAPS_INITIALIZE)
484 FE(DDPCAPS_PRIMARYSURFACE)
485 FE(DDPCAPS_PRIMARYSURFACELEFT)
492 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
493 if (flags[i].mask & dwFlags)
494 DUMP("%s ",flags[i].name);
498 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
499 DUMP("Size : %ld\n", pf->dwSize);
501 _dump_DDCOLORKEY(pf->dwFlags);
502 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
503 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
504 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
505 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
508 /******************************************************************************
509 * IDirectDrawSurface methods
511 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
512 * DDS and DDS2 use those functions. (Function calls did not change (except
513 * using different DirectDrawSurfaceX version), just added flags and functions)
515 static HRESULT WINAPI IDirectDrawSurface4_Lock(
516 LPDIRECTDRAWSURFACE4 this,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
518 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
519 this,lprect,lpddsd,flags,(DWORD)hnd);
520 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
521 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
522 this,lprect,lpddsd,flags,(DWORD)hnd);
524 /* First, copy the Surface description */
525 *lpddsd = this->s.surface_desc;
526 TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
527 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
529 /* If asked only for a part, change the surface pointer */
531 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
532 lprect->top,lprect->left,lprect->bottom,lprect->right
534 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
535 (lprect->top*this->s.surface_desc.lPitch) +
536 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
538 assert(this->s.surface_desc.y.lpSurface);
543 static HRESULT WINAPI DGA_IDirectDrawSurface4_Unlock(
544 LPDIRECTDRAWSURFACE4 this,LPVOID surface
546 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
550 static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4 this) {
551 if (this->s.ddraw->d.pixel_convert != NULL)
552 this->s.ddraw->d.pixel_convert(this->s.surface_desc.y.lpSurface,
553 this->t.xlib.image->data,
554 this->s.surface_desc.dwWidth,
555 this->s.surface_desc.dwHeight,
556 this->s.surface_desc.lPitch,
560 if (this->s.ddraw->e.xlib.xshm_active)
561 TSXShmPutImage(display,
562 this->s.ddraw->d.drawable,
563 DefaultGCOfScreen(X11DRV_GetXScreen()),
566 this->t.xlib.image->width,
567 this->t.xlib.image->height,
571 TSXPutImage( display,
572 this->s.ddraw->d.drawable,
573 DefaultGCOfScreen(X11DRV_GetXScreen()),
576 this->t.xlib.image->width,
577 this->t.xlib.image->height);
580 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Unlock(
581 LPDIRECTDRAWSURFACE4 this,LPVOID surface)
583 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
585 if (!this->s.ddraw->d.paintable)
588 /* Only redraw the screen when unlocking the buffer that is on screen */
589 if ((this->t.xlib.image != NULL) &&
590 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
591 Xlib_copy_surface_on_screen(this);
593 if (this->s.palette && this->s.palette->cm)
594 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
600 static HRESULT WINAPI DGA_IDirectDrawSurface4_Flip(
601 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
603 #ifdef HAVE_LIBXXF86DGA
604 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
606 if (this->s.backbuffer)
607 flipto = this->s.backbuffer;
611 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
613 if (flipto->s.palette && flipto->s.palette->cm) {
614 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
616 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
622 tmp = this->t.dga.fb_height;
623 this->t.dga.fb_height = flipto->t.dga.fb_height;
624 flipto->t.dga.fb_height = tmp;
626 ptmp = this->s.surface_desc.y.lpSurface;
627 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
628 flipto->s.surface_desc.y.lpSurface = ptmp;
631 #else /* defined(HAVE_LIBXXF86DGA) */
633 #endif /* defined(HAVE_LIBXXF86DGA) */
636 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Flip(
637 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
639 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
640 if (!this->s.ddraw->d.paintable)
644 if (this->s.backbuffer)
645 flipto = this->s.backbuffer;
650 Xlib_copy_surface_on_screen(this);
652 if (flipto->s.palette && flipto->s.palette->cm) {
653 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,flipto->s.palette->cm);
658 tmp = this->t.xlib.image;
659 this->t.xlib.image = flipto->t.xlib.image;
660 flipto->t.xlib.image = tmp;
661 surf = this->s.surface_desc.y.lpSurface;
662 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
663 flipto->s.surface_desc.y.lpSurface = surf;
669 /* The IDirectDrawSurface4::SetPalette method attaches the specified
670 * DirectDrawPalette object to a surface. The surface uses this palette for all
671 * subsequent operations. The palette change takes place immediately.
673 static HRESULT WINAPI Xlib_IDirectDrawSurface4_SetPalette(
674 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
677 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
680 if( this->s.palette != NULL )
681 this->s.palette->lpvtbl->fnRelease( this->s.palette );
682 this->s.palette = pal;
687 if( !(pal->cm) && (this->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
689 pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,
690 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
692 if (!Options.managed)
693 TSXInstallColormap(display,pal->cm);
695 for (i=0;i<256;i++) {
698 xc.red = pal->palents[i].peRed<<8;
699 xc.blue = pal->palents[i].peBlue<<8;
700 xc.green = pal->palents[i].peGreen<<8;
701 xc.flags = DoRed|DoBlue|DoGreen;
703 TSXStoreColor(display,pal->cm,&xc);
705 TSXInstallColormap(display,pal->cm);
708 /* According to spec, we are only supposed to
709 * AddRef if this is not the same palette.
711 if( this->s.palette != pal )
714 pal->lpvtbl->fnAddRef( pal );
715 if( this->s.palette != NULL )
716 this->s.palette->lpvtbl->fnRelease( this->s.palette );
717 this->s.palette = pal;
719 /* I think that we need to attach it to all backbuffers...*/
720 if( this->s.backbuffer ) {
721 if( this->s.backbuffer->s.palette )
722 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
723 this->s.backbuffer->s.palette );
724 this->s.backbuffer->s.palette = pal;
726 pal->lpvtbl->fnAddRef( pal );
728 /* Perform the refresh */
729 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
734 static HRESULT WINAPI DGA_IDirectDrawSurface4_SetPalette(
735 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
737 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
738 #ifdef HAVE_LIBXXF86DGA
739 /* According to spec, we are only supposed to
740 * AddRef if this is not the same palette.
742 if( this->s.palette != pal )
745 pal->lpvtbl->fnAddRef( pal );
746 if( this->s.palette != NULL )
747 this->s.palette->lpvtbl->fnRelease( this->s.palette );
748 this->s.palette = pal;
750 /* I think that we need to attach it to all backbuffers...*/
751 if( this->s.backbuffer ) {
752 if( this->s.backbuffer->s.palette )
753 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
754 this->s.backbuffer->s.palette = pal;
755 if( pal ) pal->lpvtbl->fnAddRef( pal );
757 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
760 #else /* defined(HAVE_LIBXXF86DGA) */
762 #endif /* defined(HAVE_LIBXXF86DGA) */
767 static HRESULT WINAPI IDirectDrawSurface4_Blt(
768 LPDIRECTDRAWSURFACE4 this,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
771 DDSURFACEDESC ddesc,sdesc;
774 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
775 this,rdst,src,rsrc,dwFlags,lpbltfx);
778 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
779 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
781 if (TRACE_ON(ddraw)) {
782 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
783 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
784 TRACE(ddraw,"\tflags: "); _dump_DDBLT(dwFlags);
785 if (dwFlags & DDBLT_DDFX) {
786 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
791 memcpy(&xdst,rdst,sizeof(xdst));
794 xdst.bottom = ddesc.dwHeight;
796 xdst.right = ddesc.dwWidth;
800 memcpy(&xsrc,rsrc,sizeof(xsrc));
804 xsrc.bottom = sdesc.dwHeight;
806 xsrc.right = sdesc.dwWidth;
808 memset(&xsrc,0,sizeof(xsrc));
812 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
814 /* First, all the 'source-less' blits */
815 if (dwFlags & DDBLT_COLORFILL) {
816 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
819 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
820 for (i=xdst.top;i<xdst.bottom;i++) {
821 xpixel = xline+bpp*xdst.left;
823 for (j=xdst.left;j<xdst.right;j++) {
824 /* FIXME: this only works on little endian
825 * architectures, where DWORD starts with low
828 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
831 xline += ddesc.lPitch;
833 dwFlags &= ~(DDBLT_COLORFILL);
836 if (dwFlags & DDBLT_DEPTHFILL) {
840 /* Clears the screen */
841 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
842 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
843 glGetBooleanv(GL_DEPTH_TEST, &ztest);
844 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
845 glClear(GL_DEPTH_BUFFER_BIT);
848 dwFlags &= ~(DDBLT_DEPTHFILL);
854 TRACE(ddraw,"\t(src=NULL):Unsupported flags: "); _dump_DDBLT(dwFlags);
856 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
860 /* Now the 'with source' blits */
862 /* Standard 'full-surface' blit without special effects */
863 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
864 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
865 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
866 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
869 memcpy(ddesc.y.lpSurface,
871 ddesc.dwHeight * ddesc.lPitch);
873 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
874 int srcheight = xsrc.bottom - xsrc.top;
875 int srcwidth = xsrc.right - xsrc.left;
876 int dstheight = xdst.bottom - xdst.top;
877 int dstwidth = xdst.right - xdst.left;
878 int width = (xsrc.right - xsrc.left) * bpp;
881 /* Sanity check for rectangle sizes */
882 if ((srcheight != dstheight) || (srcwidth != dstwidth)) {
885 /* I think we should do a Blit with 'stretching' here....
886 Tomb Raider II uses this to display the background during the menu selection
887 when the screen resolution is != than 640x480 */
888 TRACE(ddraw, "Blt with stretching\n");
890 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
892 /* In this case, we cannot do any anti-aliasing */
893 if(dwFlags & DDBLT_KEYSRC) {
894 for (y = xdst.top; y < xdst.bottom; y++) {
895 for (x = xdst.left; x < xdst.right; x++) {
898 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
899 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
901 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
902 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
904 tmp = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
906 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
907 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
908 dbuf[(y * ddesc.lPitch) + x] = tmp;
912 for (y = xdst.top; y < xdst.bottom; y++) {
913 for (x = xdst.left; x < xdst.right; x++) {
915 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
916 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
918 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
919 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
921 dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
926 FIXME(ddraw, "Not done yet for depth != 8\n");
929 /* Same size => fast blit */
930 if (dwFlags & DDBLT_KEYSRC) {
933 unsigned char tmp,*psrc,*pdst;
936 for (h = 0; h < srcheight; h++) {
937 psrc=sdesc.y.lpSurface +
938 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
939 pdst=ddesc.y.lpSurface +
940 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
941 for(i=0;i<srcwidth;i++) {
943 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
944 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
948 dwFlags&=~(DDBLT_KEYSRC);
952 unsigned short tmp,*psrc,*pdst;
955 for (h = 0; h < srcheight; h++) {
956 psrc=sdesc.y.lpSurface +
957 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
958 pdst=ddesc.y.lpSurface +
959 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
960 for(i=0;i<srcwidth;i++) {
962 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
963 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
967 dwFlags&=~(DDBLT_KEYSRC);
971 FIXME(ddraw, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
974 /* Non-stretching Blt without color keying */
975 for (h = 0; h < srcheight; h++) {
976 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
977 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
984 if (dwFlags && FIXME_ON(ddraw)) {
985 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
988 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
989 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
994 static HRESULT WINAPI IDirectDrawSurface4_BltFast(
995 LPDIRECTDRAWSURFACE4 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
998 DDSURFACEDESC ddesc,sdesc;
1000 if (1 || TRACE_ON(ddraw)) {
1001 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1002 this,dstx,dsty,src,rsrc,trans
1004 FIXME(ddraw," trans:");
1005 if (FIXME_ON(ddraw))
1006 _dump_DDBLTFAST(trans);
1007 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1009 /* We need to lock the surfaces, or we won't get refreshes when done. */
1010 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1011 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1012 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
1013 h=rsrc->bottom-rsrc->top;
1014 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1015 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1017 w=rsrc->right-rsrc->left;
1018 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1019 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1023 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
1024 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
1028 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
1029 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
1033 static HRESULT WINAPI IDirectDrawSurface4_BltBatch(
1034 LPDIRECTDRAWSURFACE4 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1036 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1042 static HRESULT WINAPI IDirectDrawSurface4_GetCaps(
1043 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS caps
1045 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
1046 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1050 static HRESULT WINAPI IDirectDrawSurface4_GetSurfaceDesc(
1051 LPDIRECTDRAWSURFACE4 this,LPDDSURFACEDESC ddsd
1053 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
1056 /* Simply copy the surface description stored in the object */
1057 *ddsd = this->s.surface_desc;
1059 if (TRACE_ON(ddraw)) {
1061 _dump_DDSD(ddsd->dwFlags);
1062 if (ddsd->dwFlags & DDSD_CAPS) {
1064 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
1066 if (ddsd->dwFlags & DDSD_PIXELFORMAT) {
1067 DUMP(" pixel format : \n");
1068 _dump_pixelformat(&(ddsd->ddpfPixelFormat));
1075 static ULONG WINAPI IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4 this) {
1076 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1078 return ++(this->ref);
1081 static ULONG WINAPI DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1082 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1084 #ifdef HAVE_LIBXXF86DGA
1085 if (!--(this->ref)) {
1086 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1087 /* clear out of surface list */
1088 if (this->t.dga.fb_height == -1) {
1089 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1091 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
1094 /* Free the backbuffer */
1095 if (this->s.backbuffer)
1096 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1098 HeapFree(GetProcessHeap(),0,this);
1101 #endif /* defined(HAVE_LIBXXF86DGA) */
1105 static ULONG WINAPI Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1106 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1108 if (!--(this->ref)) {
1109 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1111 if( this->s.backbuffer )
1112 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1114 if (this->t.xlib.image != NULL) {
1115 if (this->s.ddraw->d.pixel_convert != NULL) {
1116 /* In pixel conversion mode, there are two buffers to release... */
1117 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1119 #ifdef HAVE_LIBXXSHM
1120 if (this->s.ddraw->e.xlib.xshm_active) {
1121 TSXShmDetach(display, &(this->t.xlib.shminfo));
1122 TSXDestroyImage(this->t.xlib.image);
1123 shmdt(this->t.xlib.shminfo.shmaddr);
1126 HeapFree(GetProcessHeap(),0,this->t.xlib.image->data);
1127 this->t.xlib.image->data = NULL;
1128 TSXDestroyImage(this->t.xlib.image);
1129 #ifdef HAVE_LIBXXSHM
1134 this->t.xlib.image->data = NULL;
1136 #ifdef HAVE_LIBXXSHM
1137 if (this->s.ddraw->e.xlib.xshm_active) {
1138 TSXShmDetach(display, &(this->t.xlib.shminfo));
1139 TSXDestroyImage(this->t.xlib.image);
1140 shmdt(this->t.xlib.shminfo.shmaddr);
1143 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1144 TSXDestroyImage(this->t.xlib.image);
1145 #ifdef HAVE_LIBXXSHM
1150 this->t.xlib.image = 0;
1152 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1155 if (this->s.palette)
1156 this->s.palette->lpvtbl->fnRelease(this->s.palette);
1158 HeapFree(GetProcessHeap(),0,this);
1165 static HRESULT WINAPI IDirectDrawSurface4_GetAttachedSurface(
1166 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1168 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1169 this, lpddsd, lpdsf);
1171 if (TRACE_ON(ddraw)) {
1172 TRACE(ddraw," caps ");
1173 _dump_DDSCAPS(lpddsd->dwCaps);
1176 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1177 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1181 /* FIXME: should handle more than one backbuffer */
1182 *lpdsf = this->s.backbuffer;
1184 if( this->s.backbuffer )
1185 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
1190 static HRESULT WINAPI IDirectDrawSurface4_Initialize(
1191 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1193 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
1195 return DDERR_ALREADYINITIALIZED;
1198 static HRESULT WINAPI IDirectDrawSurface4_GetPixelFormat(
1199 LPDIRECTDRAWSURFACE4 this,LPDDPIXELFORMAT pf
1201 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
1203 *pf = this->s.surface_desc.ddpfPixelFormat;
1208 static HRESULT WINAPI IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4 this,DWORD dwFlags) {
1209 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
1213 static HRESULT WINAPI IDirectDrawSurface4_GetOverlayPosition(
1214 LPDIRECTDRAWSURFACE4 this,LPLONG x1,LPLONG x2
1216 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
1220 static HRESULT WINAPI IDirectDrawSurface4_SetClipper(
1221 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWCLIPPER clipper
1223 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
1227 static HRESULT WINAPI IDirectDrawSurface4_AddAttachedSurface(
1228 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 surf
1230 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
1232 this->lpvtbl->fnAddRef(this);
1234 /* This hack will be enough for the moment */
1235 if (this->s.backbuffer == NULL)
1236 this->s.backbuffer = surf;
1240 static HRESULT WINAPI IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4 this,HDC* lphdc) {
1241 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
1242 *lphdc = BeginPaint(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1246 static HRESULT WINAPI IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4 this,HDC hdc) {
1250 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
1251 EndPaint(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1253 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1254 I fill it with 'dummy' values to have something on the screen */
1255 this->lpvtbl->fnLock(this,NULL,&desc,0,0);
1256 for (y = 0; y < desc.dwHeight; y++) {
1257 for (x = 0; x < desc.dwWidth; x++) {
1258 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) this + x + y;
1261 this->lpvtbl->fnUnlock(this,NULL);
1267 static HRESULT WINAPI IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4 this,REFIID refiid,LPVOID *obj) {
1270 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1271 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1273 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1274 * the same interface. And IUnknown does that too of course.
1276 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1277 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1278 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1279 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1280 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1283 this->lpvtbl->fnAddRef(this);
1285 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1289 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1291 /* Texture interface */
1292 *obj = d3dtexture2_create(this);
1293 this->lpvtbl->fnAddRef(this);
1295 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1299 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1301 /* Texture interface */
1302 *obj = d3dtexture_create(this);
1303 this->lpvtbl->fnAddRef(this);
1305 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1309 else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj))
1311 /* It is the OpenGL Direct3D Device */
1312 this->lpvtbl->fnAddRef(this);
1314 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1319 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1320 return OLE_E_ENUM_NOMORE;
1323 static HRESULT WINAPI IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4 this) {
1324 TRACE(ddraw,"(%p)->(), stub!\n",this);
1325 return DD_OK; /* hmm */
1328 static HRESULT WINAPI IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1329 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
1333 static HRESULT WINAPI IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4 this) {
1334 FIXME(ddraw,"(%p)->(),stub!\n",this);
1338 static HRESULT WINAPI IDirectDrawSurface4_SetColorKey(
1339 LPDIRECTDRAWSURFACE4 this, DWORD dwFlags, LPDDCOLORKEY ckey )
1341 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);
1343 if( dwFlags & DDCKEY_SRCBLT )
1345 dwFlags &= ~DDCKEY_SRCBLT;
1346 this->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1347 memcpy( &(this->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1350 if( dwFlags & DDCKEY_DESTBLT )
1352 dwFlags &= ~DDCKEY_DESTBLT;
1353 this->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1354 memcpy( &(this->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1357 if( dwFlags & DDCKEY_SRCOVERLAY )
1359 dwFlags &= ~DDCKEY_SRCOVERLAY;
1360 this->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1361 memcpy( &(this->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1364 if( dwFlags & DDCKEY_DESTOVERLAY )
1366 dwFlags &= ~DDCKEY_DESTOVERLAY;
1367 this->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1368 memcpy( &(this->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1373 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1380 static HRESULT WINAPI IDirectDrawSurface4_AddOverlayDirtyRect(
1381 LPDIRECTDRAWSURFACE4 this,
1384 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
1389 static HRESULT WINAPI IDirectDrawSurface4_DeleteAttachedSurface(
1390 LPDIRECTDRAWSURFACE4 this,
1392 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1394 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1399 static HRESULT WINAPI IDirectDrawSurface4_EnumOverlayZOrders(
1400 LPDIRECTDRAWSURFACE4 this,
1403 LPDDENUMSURFACESCALLBACK lpfnCallback )
1405 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1406 lpContext, lpfnCallback );
1411 static HRESULT WINAPI IDirectDrawSurface4_GetClipper(
1412 LPDIRECTDRAWSURFACE4 this,
1413 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1415 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1420 static HRESULT WINAPI IDirectDrawSurface4_GetColorKey(
1421 LPDIRECTDRAWSURFACE4 this,
1423 LPDDCOLORKEY lpDDColorKey )
1425 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);
1427 if( dwFlags & DDCKEY_SRCBLT ) {
1428 dwFlags &= ~DDCKEY_SRCBLT;
1429 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1432 if( dwFlags & DDCKEY_DESTBLT )
1434 dwFlags &= ~DDCKEY_DESTBLT;
1435 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1438 if( dwFlags & DDCKEY_SRCOVERLAY )
1440 dwFlags &= ~DDCKEY_SRCOVERLAY;
1441 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1444 if( dwFlags & DDCKEY_DESTOVERLAY )
1446 dwFlags &= ~DDCKEY_DESTOVERLAY;
1447 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1452 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1458 static HRESULT WINAPI IDirectDrawSurface4_GetFlipStatus(
1459 LPDIRECTDRAWSURFACE4 this,
1462 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1467 static HRESULT WINAPI IDirectDrawSurface4_GetPalette(
1468 LPDIRECTDRAWSURFACE4 this,
1469 LPDIRECTDRAWPALETTE* lplpDDPalette )
1471 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1476 static HRESULT WINAPI IDirectDrawSurface4_SetOverlayPosition(
1477 LPDIRECTDRAWSURFACE4 this,
1481 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1486 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlay(
1487 LPDIRECTDRAWSURFACE4 this,
1489 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1492 LPDDOVERLAYFX lpDDOverlayFx )
1494 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1495 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1500 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayDisplay(
1501 LPDIRECTDRAWSURFACE4 this,
1504 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1509 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayZOrder(
1510 LPDIRECTDRAWSURFACE4 this,
1512 LPDIRECTDRAWSURFACE4 lpDDSReference )
1514 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1519 static HRESULT WINAPI IDirectDrawSurface4_GetDDInterface(
1520 LPDIRECTDRAWSURFACE4 this,
1523 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1525 /* Not sure about that... */
1526 *lplpDD = (void *) this->s.ddraw;
1531 static HRESULT WINAPI IDirectDrawSurface4_PageLock(
1532 LPDIRECTDRAWSURFACE4 this,
1535 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1540 static HRESULT WINAPI IDirectDrawSurface4_PageUnlock(
1541 LPDIRECTDRAWSURFACE4 this,
1544 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1549 static HRESULT WINAPI IDirectDrawSurface4_SetSurfaceDesc(
1550 LPDIRECTDRAWSURFACE4 this,
1551 LPDDSURFACEDESC lpDDSD,
1554 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1559 static HRESULT WINAPI IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4 this,
1564 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag, lpData, cbSize, dwFlags);
1569 static HRESULT WINAPI IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4 this,
1572 LPDWORD lpcbBufferSize) {
1573 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", this, guidTag, lpBuffer, lpcbBufferSize);
1578 static HRESULT WINAPI IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4 this,
1580 FIXME(ddraw, "(%p)->(%p)\n", this, guidTag);
1585 static HRESULT WINAPI IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4 this,
1587 FIXME(ddraw, "(%p)->(%p)\n", this, lpValue);
1592 static HRESULT WINAPI IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 this) {
1593 FIXME(ddraw, "(%p)\n", this);
1598 static struct IDirectDrawSurface4_VTable dga_dds4vt = {
1599 IDirectDrawSurface4_QueryInterface,
1600 IDirectDrawSurface4_AddRef,
1601 DGA_IDirectDrawSurface4_Release,
1602 IDirectDrawSurface4_AddAttachedSurface,
1603 IDirectDrawSurface4_AddOverlayDirtyRect,
1604 IDirectDrawSurface4_Blt,
1605 IDirectDrawSurface4_BltBatch,
1606 IDirectDrawSurface4_BltFast,
1607 IDirectDrawSurface4_DeleteAttachedSurface,
1608 IDirectDrawSurface4_EnumAttachedSurfaces,
1609 IDirectDrawSurface4_EnumOverlayZOrders,
1610 DGA_IDirectDrawSurface4_Flip,
1611 IDirectDrawSurface4_GetAttachedSurface,
1612 IDirectDrawSurface4_GetBltStatus,
1613 IDirectDrawSurface4_GetCaps,
1614 IDirectDrawSurface4_GetClipper,
1615 IDirectDrawSurface4_GetColorKey,
1616 IDirectDrawSurface4_GetDC,
1617 IDirectDrawSurface4_GetFlipStatus,
1618 IDirectDrawSurface4_GetOverlayPosition,
1619 IDirectDrawSurface4_GetPalette,
1620 IDirectDrawSurface4_GetPixelFormat,
1621 IDirectDrawSurface4_GetSurfaceDesc,
1622 IDirectDrawSurface4_Initialize,
1623 IDirectDrawSurface4_IsLost,
1624 IDirectDrawSurface4_Lock,
1625 IDirectDrawSurface4_ReleaseDC,
1626 IDirectDrawSurface4_Restore,
1627 IDirectDrawSurface4_SetClipper,
1628 IDirectDrawSurface4_SetColorKey,
1629 IDirectDrawSurface4_SetOverlayPosition,
1630 DGA_IDirectDrawSurface4_SetPalette,
1631 DGA_IDirectDrawSurface4_Unlock,
1632 IDirectDrawSurface4_UpdateOverlay,
1633 IDirectDrawSurface4_UpdateOverlayDisplay,
1634 IDirectDrawSurface4_UpdateOverlayZOrder,
1635 IDirectDrawSurface4_GetDDInterface,
1636 IDirectDrawSurface4_PageLock,
1637 IDirectDrawSurface4_PageUnlock,
1638 IDirectDrawSurface4_SetSurfaceDesc,
1639 IDirectDrawSurface4_SetPrivateData,
1640 IDirectDrawSurface4_GetPrivateData,
1641 IDirectDrawSurface4_FreePrivateData,
1642 IDirectDrawSurface4_GetUniquenessValue,
1643 IDirectDrawSurface4_ChangeUniquenessValue
1646 static struct IDirectDrawSurface4_VTable xlib_dds4vt = {
1647 IDirectDrawSurface4_QueryInterface,
1648 IDirectDrawSurface4_AddRef,
1649 Xlib_IDirectDrawSurface4_Release,
1650 IDirectDrawSurface4_AddAttachedSurface,
1651 IDirectDrawSurface4_AddOverlayDirtyRect,
1652 IDirectDrawSurface4_Blt,
1653 IDirectDrawSurface4_BltBatch,
1654 IDirectDrawSurface4_BltFast,
1655 IDirectDrawSurface4_DeleteAttachedSurface,
1656 IDirectDrawSurface4_EnumAttachedSurfaces,
1657 IDirectDrawSurface4_EnumOverlayZOrders,
1658 Xlib_IDirectDrawSurface4_Flip,
1659 IDirectDrawSurface4_GetAttachedSurface,
1660 IDirectDrawSurface4_GetBltStatus,
1661 IDirectDrawSurface4_GetCaps,
1662 IDirectDrawSurface4_GetClipper,
1663 IDirectDrawSurface4_GetColorKey,
1664 IDirectDrawSurface4_GetDC,
1665 IDirectDrawSurface4_GetFlipStatus,
1666 IDirectDrawSurface4_GetOverlayPosition,
1667 IDirectDrawSurface4_GetPalette,
1668 IDirectDrawSurface4_GetPixelFormat,
1669 IDirectDrawSurface4_GetSurfaceDesc,
1670 IDirectDrawSurface4_Initialize,
1671 IDirectDrawSurface4_IsLost,
1672 IDirectDrawSurface4_Lock,
1673 IDirectDrawSurface4_ReleaseDC,
1674 IDirectDrawSurface4_Restore,
1675 IDirectDrawSurface4_SetClipper,
1676 IDirectDrawSurface4_SetColorKey,
1677 IDirectDrawSurface4_SetOverlayPosition,
1678 Xlib_IDirectDrawSurface4_SetPalette,
1679 Xlib_IDirectDrawSurface4_Unlock,
1680 IDirectDrawSurface4_UpdateOverlay,
1681 IDirectDrawSurface4_UpdateOverlayDisplay,
1682 IDirectDrawSurface4_UpdateOverlayZOrder,
1683 IDirectDrawSurface4_GetDDInterface,
1684 IDirectDrawSurface4_PageLock,
1685 IDirectDrawSurface4_PageUnlock,
1686 IDirectDrawSurface4_SetSurfaceDesc,
1687 IDirectDrawSurface4_SetPrivateData,
1688 IDirectDrawSurface4_GetPrivateData,
1689 IDirectDrawSurface4_FreePrivateData,
1690 IDirectDrawSurface4_GetUniquenessValue,
1691 IDirectDrawSurface4_ChangeUniquenessValue
1694 /******************************************************************************
1695 * DirectDrawCreateClipper (DDRAW.7)
1697 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1698 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1699 LPUNKNOWN pUnkOuter)
1701 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1703 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1704 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1705 (*lplpDDClipper)->ref = 1;
1710 /******************************************************************************
1711 * IDirectDrawClipper
1713 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1714 LPDIRECTDRAWCLIPPER this,DWORD x,HWND hwnd
1716 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1720 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1721 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1726 HeapFree(GetProcessHeap(),0,this);
1730 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1731 LPDIRECTDRAWCLIPPER this,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
1733 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1738 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1739 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1741 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1745 static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
1746 LPDIRECTDRAWCLIPPER this,
1750 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
1751 return OLE_E_ENUM_NOMORE;
1754 static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
1756 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1757 return ++(this->ref);
1760 static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
1761 LPDIRECTDRAWCLIPPER this,
1764 FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
1768 static HRESULT WINAPI IDirectDrawClipper_Initialize(
1769 LPDIRECTDRAWCLIPPER this,
1773 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
1777 static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
1778 LPDIRECTDRAWCLIPPER this,
1781 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
1785 static struct IDirectDrawClipper_VTable ddclipvt = {
1786 IDirectDrawClipper_QueryInterface,
1787 IDirectDrawClipper_AddRef,
1788 IDirectDrawClipper_Release,
1789 IDirectDrawClipper_GetClipList,
1790 IDirectDrawClipper_GetHWnd,
1791 IDirectDrawClipper_Initialize,
1792 IDirectDrawClipper_IsClipListChanged,
1793 IDirectDrawClipper_SetClipList,
1794 IDirectDrawClipper_SetHwnd
1798 /******************************************************************************
1799 * IDirectDrawPalette
1801 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1802 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1806 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1807 this,x,start,count,palent);
1809 if (!this->cm) /* should not happen */ {
1810 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1811 return DDERR_GENERIC;
1813 for (i=0;i<count;i++) {
1814 palent[i].peRed = this->palents[start+i].peRed;
1815 palent[i].peBlue = this->palents[start+i].peBlue;
1816 palent[i].peGreen = this->palents[start+i].peGreen;
1817 palent[i].peFlags = this->palents[start+i].peFlags;
1823 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1824 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1829 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1830 this,x,start,count,palent
1832 for (i=0;i<count;i++) {
1833 xc.red = palent[i].peRed<<8;
1834 xc.blue = palent[i].peBlue<<8;
1835 xc.green = palent[i].peGreen<<8;
1836 xc.flags = DoRed|DoBlue|DoGreen;
1840 TSXStoreColor(display,this->cm,&xc);
1842 this->palents[start+i].peRed = palent[i].peRed;
1843 this->palents[start+i].peBlue = palent[i].peBlue;
1844 this->palents[start+i].peGreen = palent[i].peGreen;
1845 this->palents[start+i].peFlags = palent[i].peFlags;
1848 /* Now, if we are in 'depth conversion mode', update the screen palette */
1849 if (this->ddraw->d.palette_convert != NULL)
1850 this->ddraw->d.palette_convert(palent, this->screen_palents, start, count);
1855 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1856 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1858 #ifdef HAVE_LIBXXF86DGA
1863 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1864 this,x,start,count,palent
1866 if (!this->cm) /* should not happen */ {
1867 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1868 return DDERR_GENERIC;
1870 /* FIXME: free colorcells instead of freeing whole map */
1872 this->cm = TSXCopyColormapAndFree(display,this->cm);
1873 TSXFreeColormap(display,cm);
1875 for (i=0;i<count;i++) {
1876 xc.red = palent[i].peRed<<8;
1877 xc.blue = palent[i].peBlue<<8;
1878 xc.green = palent[i].peGreen<<8;
1879 xc.flags = DoRed|DoBlue|DoGreen;
1882 TSXStoreColor(display,this->cm,&xc);
1884 this->palents[start+i].peRed = palent[i].peRed;
1885 this->palents[start+i].peBlue = palent[i].peBlue;
1886 this->palents[start+i].peGreen = palent[i].peGreen;
1887 this->palents[start+i].peFlags = palent[i].peFlags;
1889 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1891 #else /* defined(HAVE_LIBXXF86DGA) */
1892 return E_UNEXPECTED;
1893 #endif /* defined(HAVE_LIBXXF86DGA) */
1896 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1897 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1898 if (!--(this->ref)) {
1900 TSXFreeColormap(display,this->cm);
1903 HeapFree(GetProcessHeap(),0,this);
1909 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1911 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1912 return ++(this->ref);
1915 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1916 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1918 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1920 return DDERR_ALREADYINITIALIZED;
1923 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1924 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1926 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1930 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1931 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1935 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1936 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1941 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1942 IDirectDrawPalette_QueryInterface,
1943 IDirectDrawPalette_AddRef,
1944 IDirectDrawPalette_Release,
1945 IDirectDrawPalette_GetCaps,
1946 IDirectDrawPalette_GetEntries,
1947 IDirectDrawPalette_Initialize,
1948 DGA_IDirectDrawPalette_SetEntries
1951 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1952 IDirectDrawPalette_QueryInterface,
1953 IDirectDrawPalette_AddRef,
1954 IDirectDrawPalette_Release,
1955 IDirectDrawPalette_GetCaps,
1956 IDirectDrawPalette_GetEntries,
1957 IDirectDrawPalette_Initialize,
1958 Xlib_IDirectDrawPalette_SetEntries
1961 /*******************************************************************************
1964 static HRESULT WINAPI IDirect3D_QueryInterface(
1965 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1967 /* FIXME: Not sure if this is correct */
1970 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1971 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1972 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1974 this->lpvtbl->fnAddRef(this);
1976 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
1980 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1983 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1985 d3d->ddraw = (LPDIRECTDRAW)this;
1986 this->lpvtbl->fnAddRef(this);
1987 d3d->lpvtbl = &d3dvt;
1990 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
1994 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
1997 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1999 d3d->ddraw = (LPDIRECTDRAW)this;
2000 this->lpvtbl->fnAddRef(this);
2001 d3d->lpvtbl = &d3d2vt;
2004 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2008 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
2009 return OLE_E_ENUM_NOMORE;
2012 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
2013 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2015 return ++(this->ref);
2018 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
2020 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2022 if (!--(this->ref)) {
2023 this->ddraw->lpvtbl->fnRelease(this->ddraw);
2024 HeapFree(GetProcessHeap(),0,this);
2030 static HRESULT WINAPI IDirect3D_Initialize(
2031 LPDIRECT3D this, REFIID refiid )
2033 /* FIXME: Not sure if this is correct */
2036 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2037 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
2039 return DDERR_ALREADYINITIALIZED;
2042 static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this,
2043 LPD3DENUMDEVICESCALLBACK cb,
2045 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
2047 /* Call functions defined in d3ddevices.c */
2048 if (!d3d_OpenGL_dx3(cb, context))
2054 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,
2055 LPDIRECT3DLIGHT *lplight,
2058 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
2060 /* Call the creation function that is located in d3dlight.c */
2061 *lplight = d3dlight_create_dx3(this);
2066 static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this,
2067 LPDIRECT3DMATERIAL *lpmaterial,
2070 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2072 /* Call the creation function that is located in d3dviewport.c */
2073 *lpmaterial = d3dmaterial_create(this);
2078 static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this,
2079 LPDIRECT3DVIEWPORT *lpviewport,
2082 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2084 /* Call the creation function that is located in d3dviewport.c */
2085 *lpviewport = d3dviewport_create(this);
2090 static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this,
2091 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2092 LPD3DFINDDEVICERESULT lpfinddevrst)
2094 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2099 static struct IDirect3D_VTable d3dvt = {
2100 IDirect3D_QueryInterface,
2103 IDirect3D_Initialize,
2104 IDirect3D_EnumDevices,
2105 IDirect3D_CreateLight,
2106 IDirect3D_CreateMaterial,
2107 IDirect3D_CreateViewport,
2108 IDirect3D_FindDevice
2111 /*******************************************************************************
2114 static HRESULT WINAPI IDirect3D2_QueryInterface(
2115 LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) {
2116 /* For the moment, we use the same function as in IDirect3D */
2117 TRACE(ddraw, "Calling IDirect3D enumerating function.\n");
2119 return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj);
2122 static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) {
2123 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2125 return ++(this->ref);
2128 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
2129 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2131 if (!--(this->ref)) {
2132 this->ddraw->lpvtbl->fnRelease(this->ddraw);
2133 HeapFree(GetProcessHeap(),0,this);
2139 static HRESULT WINAPI IDirect3D2_EnumDevices(
2140 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2142 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
2144 /* Call functions defined in d3ddevices.c */
2145 if (!d3d_OpenGL(cb, context))
2151 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,
2152 LPDIRECT3DLIGHT *lplight,
2155 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
2157 /* Call the creation function that is located in d3dlight.c */
2158 *lplight = d3dlight_create(this);
2163 static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this,
2164 LPDIRECT3DMATERIAL2 *lpmaterial,
2167 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2169 /* Call the creation function that is located in d3dviewport.c */
2170 *lpmaterial = d3dmaterial2_create(this);
2175 static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this,
2176 LPDIRECT3DVIEWPORT2 *lpviewport,
2179 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2181 /* Call the creation function that is located in d3dviewport.c */
2182 *lpviewport = d3dviewport2_create(this);
2187 static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this,
2188 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2189 LPD3DFINDDEVICERESULT lpfinddevrst)
2191 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2196 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,
2198 LPDIRECTDRAWSURFACE surface,
2199 LPDIRECT3DDEVICE2 *device)
2203 WINE_StringFromCLSID(rguid,xbuf);
2204 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device);
2206 if (is_OpenGL(rguid, surface, device, this)) {
2207 this->lpvtbl->fnAddRef(this);
2211 return DDERR_INVALIDPARAMS;
2214 static struct IDirect3D2_VTable d3d2vt = {
2215 IDirect3D2_QueryInterface,
2218 IDirect3D2_EnumDevices,
2219 IDirect3D2_CreateLight,
2220 IDirect3D2_CreateMaterial,
2221 IDirect3D2_CreateViewport,
2222 IDirect3D2_FindDevice,
2223 IDirect3D2_CreateDevice
2226 /*******************************************************************************
2230 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2231 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2233 static INT ddrawXlibThisOffset = 0;
2235 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
2236 LPDDSURFACEDESC lpddsd,
2237 LPDIRECTDRAWSURFACE lpdsf)
2241 /* The surface was already allocated when entering in this function */
2242 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2244 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2245 /* This is a Z Buffer */
2246 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2247 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2249 /* This is a standard image */
2250 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2251 /* No pixel format => use DirectDraw's format */
2252 lpddsd->ddpfPixelFormat = this->d.directdraw_pixelformat;
2253 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2255 /* To check what the program wants */
2256 if (TRACE_ON(ddraw)) {
2257 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2261 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2264 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2268 /* Copy the surface description */
2269 lpdsf->s.surface_desc = *lpddsd;
2271 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2272 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2273 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2278 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
2279 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2281 #ifdef HAVE_LIBXXF86DGA
2284 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
2285 if (TRACE_ON(ddraw)) {
2286 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2287 _dump_DDSD(lpddsd->dwFlags);
2289 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2292 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2293 this->lpvtbl->fnAddRef(this);
2296 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds4vt;
2297 (*lpdsf)->s.ddraw = this;
2298 (*lpdsf)->s.palette = NULL;
2299 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2301 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2302 lpddsd->dwWidth = this->d.width;
2303 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2304 lpddsd->dwHeight = this->d.height;
2306 /* Check if this a 'primary surface' or not */
2307 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2308 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2310 /* This is THE primary surface => there is DGA-specific code */
2311 /* First, store the surface description */
2312 (*lpdsf)->s.surface_desc = *lpddsd;
2314 /* Find a viewport */
2316 if (!(this->e.dga.vpmask & (1<<i)))
2318 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2319 /* if i == 32 or maximum ... return error */
2320 this->e.dga.vpmask|=(1<<i);
2321 (*lpdsf)->s.surface_desc.y.lpSurface =
2322 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2323 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
2324 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
2325 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
2327 /* Add flags if there were not present */
2328 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2329 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2330 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2331 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d.width,this->d.height,lpddsd->lPitch);
2332 /* We put our surface always in video memory */
2333 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2334 (*lpdsf)->s.surface_desc.ddpfPixelFormat = this->d.directdraw_pixelformat;
2335 (*lpdsf)->s.backbuffer = NULL;
2337 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2338 LPDIRECTDRAWSURFACE4 back;
2340 if (lpddsd->dwBackBufferCount>1)
2341 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2343 (*lpdsf)->s.backbuffer = back =
2344 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2345 this->lpvtbl->fnAddRef(this);
2347 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&dga_dds4vt;
2349 if (!(this->e.dga.vpmask & (1<<i)))
2351 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2352 /* if i == 32 or maximum ... return error */
2353 this->e.dga.vpmask|=(1<<i);
2354 back->t.dga.fb_height = i*this->e.dga.fb_height;
2356 /* Copy the surface description from the front buffer */
2357 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2358 /* Change the parameters that are not the same */
2359 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
2360 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2361 back->s.ddraw = this;
2362 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2365 /* Add relevant info to front and back buffers */
2366 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2367 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2368 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2369 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2370 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2373 /* There is no DGA-specific code here...
2374 Go to the common surface creation function */
2375 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2379 #else /* defined(HAVE_LIBXXF86DGA) */
2380 return E_UNEXPECTED;
2381 #endif /* defined(HAVE_LIBXXF86DGA) */
2384 #ifdef HAVE_LIBXXSHM
2385 /* Error handlers for Image creation */
2386 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2391 static XImage *create_xshmimage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2393 int (*WineXHandler)(Display *, XErrorEvent *);
2395 img = TSXShmCreateImage(display,
2396 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2397 this->d.pixmap_depth,
2400 &(lpdsf->t.xlib.shminfo),
2401 lpdsf->s.surface_desc.dwWidth,
2402 lpdsf->s.surface_desc.dwHeight);
2405 MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2406 this->e.xlib.xshm_active = 0;
2410 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2411 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2412 MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2413 this->e.xlib.xshm_active = 0;
2414 TSXDestroyImage(img);
2418 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2420 if (img->data == (char *) -1) {
2421 MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2422 this->e.xlib.xshm_active = 0;
2423 TSXDestroyImage(img);
2424 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2427 lpdsf->t.xlib.shminfo.readOnly = False;
2429 /* This is where things start to get trickier....
2430 First, we flush the current X connections to be sure to catch all non-XShm related
2432 TSXSync(display, False);
2433 /* Then we enter in the non-thread safe part of the tests */
2434 EnterCriticalSection( &X11DRV_CritSection );
2436 /* Reset the error flag, sets our new error handler and try to attach the surface */
2438 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2439 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2440 XSync(display, False);
2442 /* Check the error flag */
2443 if (XShmErrorFlag) {
2444 /* An error occured */
2448 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2449 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2450 XSetErrorHandler(WineXHandler);
2452 MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
2453 this->e.xlib.xshm_active = 0;
2455 /* Leave the critical section */
2456 LeaveCriticalSection( &X11DRV_CritSection );
2461 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2462 but it may be a bit overkill.... */
2463 XSetErrorHandler(WineXHandler);
2464 LeaveCriticalSection( &X11DRV_CritSection );
2466 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2468 if (this->d.pixel_convert != NULL) {
2469 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2470 lpdsf->s.surface_desc.dwWidth *
2471 lpdsf->s.surface_desc.dwHeight *
2472 (this->d.directdraw_pixelformat.x.dwRGBBitCount));
2474 lpdsf->s.surface_desc.y.lpSurface = img->data;
2479 #endif /* HAVE_LIBXXSHM */
2481 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2485 #ifdef HAVE_LIBXXSHM
2486 if (this->e.xlib.xshm_active) {
2487 img = create_xshmimage(this, lpdsf);
2492 /* Allocate surface memory */
2493 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2494 lpdsf->s.surface_desc.dwWidth *
2495 lpdsf->s.surface_desc.dwHeight *
2496 (this->d.directdraw_pixelformat.x.dwRGBBitCount / 8));
2498 if (this->d.pixel_convert != NULL) {
2499 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2500 lpdsf->s.surface_desc.dwWidth *
2501 lpdsf->s.surface_desc.dwHeight *
2502 (this->d.screen_pixelformat.x.dwRGBBitCount / 8));
2504 img_data = lpdsf->s.surface_desc.y.lpSurface;
2507 /* In this case, create an XImage */
2509 TSXCreateImage(display,
2510 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2511 this->d.pixmap_depth,
2515 lpdsf->s.surface_desc.dwWidth,
2516 lpdsf->s.surface_desc.dwHeight,
2518 lpdsf->s.surface_desc.dwWidth * (this->d.screen_pixelformat.x.dwRGBBitCount / 8)
2521 #ifdef HAVE_LIBXXSHM
2524 if (this->d.pixel_convert != NULL) {
2525 lpdsf->s.surface_desc.lPitch = (this->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
2527 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2533 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
2534 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2536 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2537 this,lpddsd,lpdsf,lpunk);
2539 if (TRACE_ON(ddraw)) {
2540 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2541 _dump_DDSD(lpddsd->dwFlags);
2543 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2546 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2548 this->lpvtbl->fnAddRef(this);
2549 (*lpdsf)->s.ddraw = this;
2551 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds4vt;
2552 (*lpdsf)->s.palette = NULL;
2553 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2555 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2556 lpddsd->dwWidth = this->d.width;
2557 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2558 lpddsd->dwHeight = this->d.height;
2560 /* Check if this a 'primary surface' or not */
2561 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2562 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2565 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
2567 /* First, store the surface description */
2568 (*lpdsf)->s.surface_desc = *lpddsd;
2570 /* Create the XImage */
2571 img = create_ximage(this, (LPDIRECTDRAWSURFACE4) *lpdsf);
2573 return DDERR_OUTOFMEMORY;
2574 (*lpdsf)->t.xlib.image = img;
2576 /* Add flags if there were not present */
2577 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2578 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2579 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2580 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2581 (*lpdsf)->s.surface_desc.ddpfPixelFormat = this->d.directdraw_pixelformat;
2582 (*lpdsf)->s.backbuffer = NULL;
2584 /* Check for backbuffers */
2585 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2586 LPDIRECTDRAWSURFACE4 back;
2589 if (lpddsd->dwBackBufferCount>1)
2590 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2592 (*lpdsf)->s.backbuffer = back =
2593 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2595 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2597 this->lpvtbl->fnAddRef(this);
2598 back->s.ddraw = this;
2601 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&xlib_dds4vt;
2602 /* Copy the surface description from the front buffer */
2603 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2605 /* Create the XImage */
2606 img = create_ximage(this, back);
2608 return DDERR_OUTOFMEMORY;
2609 back->t.xlib.image = img;
2611 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2614 /* Add relevant info to front and back buffers */
2615 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2616 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2617 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2618 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2619 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2622 /* There is no Xlib-specific code here...
2623 Go to the common surface creation function */
2624 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2630 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
2631 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2633 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
2634 *dst = src; /* FIXME */
2639 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2640 * even when the approbiate bitmasks are not specified.
2642 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
2643 LPDIRECTDRAW2 this,HWND hwnd,DWORD cooplevel
2650 FE(DDSCL_FULLSCREEN)
2651 FE(DDSCL_ALLOWREBOOT)
2652 FE(DDSCL_NOWINDOWCHANGES)
2654 FE(DDSCL_ALLOWMODEX)
2656 FE(DDSCL_SETFOCUSWINDOW)
2657 FE(DDSCL_SETDEVICEWINDOW)
2658 FE(DDSCL_CREATEDEVICEWINDOW)
2661 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
2662 if(TRACE_ON(ddraw)){
2663 dbg_decl_str(ddraw, 512);
2664 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2665 if (flagmap[i].mask & cooplevel)
2666 dsprintf(ddraw, "%s ", flagmap[i].name);
2667 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2669 this->d.mainWindow = hwnd;
2671 /* This will be overwritten in the case of Full Screen mode.
2672 Windowed games could work with that :-) */
2675 WND *tmpWnd = WIN_FindWndPtr(hwnd);
2676 this->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
2677 WIN_ReleaseWndPtr(tmpWnd);
2683 /* Small helper to either use the cooperative window or create a new
2684 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2686 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
2689 /* Do not destroy the application supplied cooperative window */
2690 if (this->d.window && this->d.window != this->d.mainWindow) {
2691 DestroyWindow(this->d.window);
2694 /* Sanity check cooperative window before assigning it to drawing. */
2695 if ( IsWindow(this->d.mainWindow) &&
2696 IsWindowVisible(this->d.mainWindow)
2698 GetWindowRect(this->d.mainWindow,&rect);
2699 if (((rect.right-rect.left) >= this->d.width) &&
2700 ((rect.bottom-rect.top) >= this->d.height)
2702 this->d.window = this->d.mainWindow;
2704 /* ... failed, create new one. */
2705 if (!this->d.window) {
2706 this->d.window = CreateWindowExA(
2710 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2719 /*Store THIS with the window. We'll use it in the window procedure*/
2720 SetWindowLongA(this->d.window,ddrawXlibThisOffset,(LONG)this);
2721 ShowWindow(this->d.window,TRUE);
2722 UpdateWindow(this->d.window);
2724 SetFocus(this->d.window);
2727 static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
2729 XPixmapFormatValues *pf;
2731 int nvisuals, npixmap, i;
2734 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
2735 pf = XListPixmapFormats(display, &npixmap);
2737 for (i = 0; i < npixmap; i++) {
2738 if (pf[i].bits_per_pixel == depth) {
2741 for (j = 0; j < nvisuals; j++) {
2742 if (vi[j].depth == pf[i].depth) {
2743 pixelformat->dwSize = sizeof(*pixelformat);
2745 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
2746 pixelformat->y.dwRBitMask = 0;
2747 pixelformat->z.dwGBitMask = 0;
2748 pixelformat->xx.dwBBitMask = 0;
2750 pixelformat->dwFlags = DDPF_RGB;
2751 pixelformat->y.dwRBitMask = vi[j].red_mask;
2752 pixelformat->z.dwGBitMask = vi[j].green_mask;
2753 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
2755 pixelformat->dwFourCC = 0;
2756 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
2757 pixelformat->xy.dwRGBAlphaBitMask= 0;
2759 *screen_pixelformat = *pixelformat;
2761 if (pix_depth != NULL)
2762 *pix_depth = vi[j].depth;
2771 ERR(ddraw, "No visual corresponding to pixmap format !\n");
2775 if ((match == 0) && (depth == 8)) {
2776 pixelformat->dwSize = sizeof(*pixelformat);
2777 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
2778 pixelformat->dwFourCC = 0;
2779 pixelformat->x.dwRGBBitCount = 8;
2780 pixelformat->y.dwRBitMask = 0;
2781 pixelformat->z.dwGBitMask = 0;
2782 pixelformat->xx.dwBBitMask = 0;
2783 pixelformat->xy.dwRGBAlphaBitMask= 0;
2785 /* In that case, find a visual to emulate the 8 bpp format */
2786 for (i = 0; i < npixmap; i++) {
2787 if (pf[i].bits_per_pixel >= depth) {
2790 for (j = 0; j < nvisuals; j++) {
2791 if (vi[j].depth == pf[i].depth) {
2792 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
2793 screen_pixelformat->dwFlags = DDPF_RGB;
2794 screen_pixelformat->dwFourCC = 0;
2795 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
2796 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
2797 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
2798 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
2799 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
2801 if (pix_depth != NULL)
2802 *pix_depth = vi[j].depth;
2811 ERR(ddraw, "No visual corresponding to pixmap format !\n");
2822 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
2823 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2825 #ifdef HAVE_LIBXXF86DGA
2828 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2830 /* We hope getting the asked for depth */
2831 if (_common_depth_to_pixelformat(depth, &(this->d.directdraw_pixelformat), &(this->d.screen_pixelformat), NULL) != 1) {
2832 /* I.e. no visual found or emulated */
2833 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2834 return DDERR_UNSUPPORTEDMODE;
2837 if (this->d.width < width) {
2838 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2839 return DDERR_UNSUPPORTEDMODE;
2841 this->d.width = width;
2842 this->d.height = height;
2844 /* adjust fb_height, so we don't overlap */
2845 if (this->e.dga.fb_height < height)
2846 this->e.dga.fb_height = height;
2847 _common_IDirectDraw_SetDisplayMode(this);
2849 #ifdef HAVE_LIBXXF86VM
2851 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2852 XF86VidModeModeLine mod_tmp;
2853 /* int dotclock_tmp; */
2855 /* save original video mode and set fullscreen if available*/
2856 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2857 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2858 orig_mode->hdisplay = mod_tmp.hdisplay;
2859 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2860 orig_mode->hsyncend = mod_tmp.hsyncend;
2861 orig_mode->htotal = mod_tmp.htotal;
2862 orig_mode->vdisplay = mod_tmp.vdisplay;
2863 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2864 orig_mode->vsyncend = mod_tmp.vsyncend;
2865 orig_mode->vtotal = mod_tmp.vtotal;
2866 orig_mode->flags = mod_tmp.flags;
2867 orig_mode->private = mod_tmp.private;
2869 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2870 for (i=0;i<mode_count;i++)
2872 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2874 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2875 *vidmode = *(all_modes[i]);
2878 TSXFree(all_modes[i]->private);
2880 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
2884 WARN(ddraw, "Fullscreen mode not available!\n");
2888 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
2889 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2890 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
2891 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2897 /* FIXME: this function OVERWRITES several signal handlers.
2898 * can we save them? and restore them later? In a way that
2899 * it works for the library too?
2901 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2903 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2905 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2908 #ifdef RESTORE_SIGNALS
2909 SIGNAL_InitHandlers();
2912 #else /* defined(HAVE_LIBXXF86DGA) */
2913 return E_UNEXPECTED;
2914 #endif /* defined(HAVE_LIBXXF86DGA) */
2917 /* *************************************
2918 16 / 15 bpp to palettized 8 bpp
2919 ************************************* */
2920 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, LPDIRECTDRAWPALETTE palette) {
2921 unsigned char *c_src = (unsigned char *) src;
2922 unsigned short *c_dst = (unsigned short *) dst;
2925 if (palette != NULL) {
2926 unsigned short *pal = (unsigned short *) palette->screen_palents;
2928 for (y = 0; y < height; y++) {
2929 for (x = 0; x < width; x++) {
2930 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
2934 WARN(ddraw, "No palette set...\n");
2935 memset(dst, 0, width * height * 2);
2938 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
2940 unsigned short *pal = (unsigned short *) screen_palette;
2942 for (i = 0; i < count; i++)
2943 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
2944 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
2945 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
2947 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
2949 unsigned short *pal = (unsigned short *) screen_palette;
2951 for (i = 0; i < count; i++)
2952 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
2953 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
2954 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
2957 /* *************************************
2958 24 / 32 bpp to palettized 8 bpp
2959 ************************************* */
2960 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, LPDIRECTDRAWPALETTE palette) {
2961 unsigned char *c_src = (unsigned char *) src;
2962 unsigned int *c_dst = (unsigned int *) dst;
2965 if (palette != NULL) {
2966 unsigned int *pal = (unsigned int *) palette->screen_palents;
2968 for (y = 0; y < height; y++) {
2969 for (x = 0; x < width; x++) {
2970 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
2974 WARN(ddraw, "No palette set...\n");
2975 memset(dst, 0, width * height * 4);
2978 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
2980 unsigned int *pal = (unsigned int *) screen_palette;
2982 for (i = 0; i < count; i++)
2983 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
2984 (((unsigned int) palent[i].peGreen) << 8) |
2985 ((unsigned int) palent[i].peBlue));
2988 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2989 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2994 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2995 this, width, height, depth);
2997 switch (_common_depth_to_pixelformat(depth,
2998 &(this->d.directdraw_pixelformat),
2999 &(this->d.screen_pixelformat),
3000 &(this->d.pixmap_depth))) {
3002 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3003 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3004 return DDERR_UNSUPPORTEDMODE;
3008 this->d.pixel_convert = NULL;
3009 this->d.palette_convert = NULL;
3015 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3017 /* Set the depth convertion routines */
3018 switch (this->d.screen_pixelformat.x.dwRGBBitCount) {
3020 if ((this->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
3021 (this->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
3022 (this->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3026 this->d.pixel_convert = pixel_convert_16_to_8;
3027 this->d.palette_convert = palette_convert_16_to_8;
3028 } else if ((this->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
3029 (this->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
3030 (this->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3034 this->d.pixel_convert = pixel_convert_16_to_8;
3035 this->d.palette_convert = palette_convert_15_to_8;
3040 /* Not handled yet :/ */
3045 if ((this->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) &&
3046 (this->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) &&
3047 (this->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
3051 this->d.pixel_convert = pixel_convert_32_to_8;
3052 this->d.palette_convert = palette_convert_24_to_8;
3058 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3059 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3060 return DDERR_UNSUPPORTEDMODE;
3065 this->d.width = width;
3066 this->d.height = height;
3068 _common_IDirectDraw_SetDisplayMode(this);
3070 tmpWnd = WIN_FindWndPtr(this->d.window);
3071 this->d.paintable = 1;
3072 this->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3073 /* We don't have a context for this window. Host off the desktop */
3075 if( !this->d.drawable )
3077 this->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3078 WIN_ReleaseDesktop();
3080 WIN_ReleaseWndPtr(tmpWnd);
3084 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
3085 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
3087 #ifdef HAVE_LIBXXF86DGA
3088 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
3089 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
3090 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3091 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3093 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
3094 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3095 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3098 #else /* defined(HAVE_LIBXXF86DGA) */
3099 return E_UNEXPECTED;
3100 #endif /* defined(HAVE_LIBXXF86DGA) */
3103 static void fill_caps(LPDDCAPS caps) {
3104 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3105 Need to be fixed, though.. */
3109 caps->dwSize = sizeof(*caps);
3110 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3111 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
3112 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3113 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3115 caps->dwFXAlphaCaps = 0;
3116 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3118 caps->dwZBufferBitDepths = DDBD_16;
3119 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3120 to put textures in video memory.
3121 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3123 caps->dwVidMemTotal = 8192 * 1024;
3124 caps->dwVidMemFree = 8192 * 1024;
3125 /* These are all the supported capabilities of the surfaces */
3126 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3127 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3128 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3129 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3131 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3132 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3133 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3137 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
3138 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
3140 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
3142 /* Put the same caps for the two capabilities */
3149 static HRESULT WINAPI IDirectDraw2_CreateClipper(
3150 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3152 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3153 this,x,lpddclip,lpunk
3155 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
3156 (*lpddclip)->ref = 1;
3157 (*lpddclip)->lpvtbl = &ddclipvt;
3161 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
3162 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk,int *psize
3166 if (TRACE_ON(ddraw))
3167 _dump_paletteformat(dwFlags);
3169 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
3170 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3171 (*lpddpal)->ref = 1;
3172 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
3173 (*lpddpal)->installed = 0;
3175 if (dwFlags & DDPCAPS_1BIT)
3177 else if (dwFlags & DDPCAPS_2BIT)
3179 else if (dwFlags & DDPCAPS_4BIT)
3181 else if (dwFlags & DDPCAPS_8BIT)
3184 ERR(ddraw, "unhandled palette format\n");
3189 /* Now, if we are in 'depth conversion mode', create the screen palette */
3190 if (this->d.palette_convert != NULL)
3191 this->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3193 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3194 } else if (this->d.palette_convert != NULL) {
3195 /* In that case, put all 0xFF */
3196 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3202 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
3203 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3208 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
3209 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
3210 if (res != 0) return res;
3211 (*lpddpal)->lpvtbl = &dga_ddpalvt;
3212 if (this->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3213 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3215 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3218 if (((*lpddpal)->cm)&&xsize) {
3219 for (i=0;i<xsize;i++) {
3222 xc.red = (*lpddpal)->palents[i].peRed<<8;
3223 xc.blue = (*lpddpal)->palents[i].peBlue<<8;
3224 xc.green = (*lpddpal)->palents[i].peGreen<<8;
3225 xc.flags = DoRed|DoBlue|DoGreen;
3227 TSXStoreColor(display,(*lpddpal)->cm,&xc);
3233 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
3234 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3239 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
3240 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
3241 if (res != 0) return res;
3242 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
3246 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3247 #ifdef HAVE_LIBXXF86DGA
3248 TRACE(ddraw, "(%p)->()\n",this);
3250 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3251 #ifdef RESTORE_SIGNALS
3252 SIGNAL_InitHandlers();
3255 #else /* defined(HAVE_LIBXXF86DGA) */
3256 return E_UNEXPECTED;
3260 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3261 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
3266 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
3267 LPDIRECTDRAW2 this,DWORD x,HANDLE h
3269 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
3273 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
3274 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
3276 return ++(this->ref);
3279 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3280 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3282 #ifdef HAVE_LIBXXF86DGA
3283 if (!--(this->ref)) {
3284 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3285 if (this->d.window && (this->d.mainWindow != this->d.window))
3286 DestroyWindow(this->d.window);
3287 #ifdef HAVE_LIBXXF86VM
3289 TSXF86VidModeSwitchToMode(
3291 DefaultScreen(display),
3293 if (orig_mode->privsize)
3294 TSXFree(orig_mode->private);
3300 #ifdef RESTORE_SIGNALS
3301 SIGNAL_InitHandlers();
3303 HeapFree(GetProcessHeap(),0,this);
3306 #endif /* defined(HAVE_LIBXXF86DGA) */
3310 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3311 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3313 if (!--(this->ref)) {
3314 if (this->d.window && (this->d.mainWindow != this->d.window))
3315 DestroyWindow(this->d.window);
3316 HeapFree(GetProcessHeap(),0,this);
3319 /* FIXME: destroy window ... */
3323 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
3324 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3328 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3329 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3330 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3332 this->lpvtbl->fnAddRef(this);
3334 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3338 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3339 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
3340 this->lpvtbl->fnAddRef(this);
3343 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3347 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3348 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
3349 this->lpvtbl->fnAddRef(this);
3352 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3356 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3357 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd4vt;
3358 this->lpvtbl->fnAddRef(this);
3361 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3365 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3368 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3370 d3d->ddraw = (LPDIRECTDRAW)this;
3371 this->lpvtbl->fnAddRef(this);
3372 d3d->lpvtbl = &d3dvt;
3375 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3379 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3382 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3384 d3d->ddraw = (LPDIRECTDRAW)this;
3385 this->lpvtbl->fnAddRef(this);
3386 d3d->lpvtbl = &d3d2vt;
3389 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3393 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3394 return OLE_E_ENUM_NOMORE;
3397 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
3398 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3402 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3403 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3404 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3406 this->lpvtbl->fnAddRef(this);
3408 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3412 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3413 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
3414 this->lpvtbl->fnAddRef(this);
3417 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3421 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3422 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
3423 this->lpvtbl->fnAddRef(this);
3426 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3430 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3431 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd4vt;
3432 this->lpvtbl->fnAddRef(this);
3435 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3439 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3442 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3444 d3d->ddraw = (LPDIRECTDRAW)this;
3445 this->lpvtbl->fnAddRef(this);
3446 d3d->lpvtbl = &d3dvt;
3449 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3453 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3456 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3458 d3d->ddraw = (LPDIRECTDRAW)this;
3459 this->lpvtbl->fnAddRef(this);
3460 d3d->lpvtbl = &d3d2vt;
3463 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3467 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3468 return OLE_E_ENUM_NOMORE;
3471 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
3472 LPDIRECTDRAW2 this,BOOL *status
3474 TRACE(ddraw,"(%p)->(%p)\n",this,status);
3479 static HRESULT WINAPI DGA_IDirectDraw2_EnumDisplayModes(
3480 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3482 DDSURFACEDESC ddsfd;
3485 } modes[5] = { /* some of the usual modes */
3492 static int depths[4] = {8,16,24,32};
3495 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
3496 ddsfd.dwSize = sizeof(ddsfd);
3497 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3498 if (dwFlags & DDEDM_REFRESHRATES) {
3499 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3500 ddsfd.x.dwRefreshRate = 60;
3503 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3504 ddsfd.dwBackBufferCount = 1;
3505 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3506 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3507 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3508 /* FIXME: those masks would have to be set in depth > 8 */
3510 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3511 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3512 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3513 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3514 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3515 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3517 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3519 /* FIXME: We should query those from X itself */
3520 switch (depths[i]) {
3522 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3523 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3524 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3527 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3528 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3529 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3532 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3533 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3534 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3539 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3540 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3541 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3542 if (!modescb(&ddsfd,context)) return DD_OK;
3544 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3545 ddsfd.dwWidth = modes[j].w;
3546 ddsfd.dwHeight = modes[j].h;
3547 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3548 if (!modescb(&ddsfd,context)) return DD_OK;
3551 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3552 /* modeX is not standard VGA */
3554 ddsfd.dwHeight = 200;
3555 ddsfd.dwWidth = 320;
3556 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3557 if (!modescb(&ddsfd,context)) return DD_OK;
3563 static HRESULT WINAPI Xlib_IDirectDraw2_EnumDisplayModes(
3564 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3567 XPixmapFormatValues *pf;
3569 int nvisuals, npixmap, i;
3572 DDSURFACEDESC ddsfd;
3575 } modes[] = { /* some of the usual modes */
3583 DWORD maxWidth, maxHeight;
3585 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
3586 ddsfd.dwSize = sizeof(ddsfd);
3587 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
3588 if (dwFlags & DDEDM_REFRESHRATES) {
3589 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3590 ddsfd.x.dwRefreshRate = 60;
3592 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3593 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3595 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3596 pf = XListPixmapFormats(display, &npixmap);
3600 while (i < npixmap) {
3601 if ((has_8bpp == 0) && (pf[i].depth == 8)) {
3602 /* Special case of a 8bpp depth */
3606 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
3607 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3608 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
3609 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3610 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
3611 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3612 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3613 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3614 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3615 } else if (pf[i].depth > 8) {
3618 /* All the 'true color' depths (15, 16 and 24)
3619 First, find the corresponding visual to extract the bit masks */
3620 for (j = 0; j < nvisuals; j++) {
3621 if (vi[j].depth == pf[i].depth) {
3622 ddsfd.ddsCaps.dwCaps = 0;
3623 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3624 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3625 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3626 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
3627 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
3628 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
3629 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
3630 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3638 ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
3646 if (TRACE_ON(ddraw)) {
3647 TRACE(ddraw, "Enumerating with pixel format : \n");
3648 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
3651 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
3652 /* Do not enumerate modes we cannot handle anyway */
3653 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
3656 ddsfd.dwWidth = modes[mode].w;
3657 ddsfd.dwHeight = modes[mode].h;
3659 /* Now, send the mode description to the application */
3660 TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
3661 if (!modescb(&ddsfd, context))
3665 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3666 /* modeX is not standard VGA */
3667 ddsfd.dwWidth = 320;
3668 ddsfd.dwHeight = 200;
3669 if (!modescb(&ddsfd, context))
3674 /* Hack to always enumerate a 8bpp depth */
3676 if ((i == npixmap) && (has_8bpp == 0)) {
3689 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
3690 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3692 #ifdef HAVE_LIBXXF86DGA
3693 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
3694 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3695 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3696 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3697 lpddsfd->lPitch = this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3698 lpddsfd->dwBackBufferCount = 1;
3699 lpddsfd->x.dwRefreshRate = 60;
3700 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3701 lpddsfd->ddpfPixelFormat = this->d.directdraw_pixelformat;
3703 #else /* defined(HAVE_LIBXXF86DGA) */
3704 return E_UNEXPECTED;
3705 #endif /* defined(HAVE_LIBXXF86DGA) */
3708 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
3709 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3711 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
3712 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3713 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3714 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3715 lpddsfd->lPitch = lpddsfd->dwWidth * this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3716 lpddsfd->dwBackBufferCount = 1;
3717 lpddsfd->x.dwRefreshRate = 60;
3718 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3719 lpddsfd->ddpfPixelFormat = this->d.directdraw_pixelformat;
3723 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
3724 TRACE(ddraw,"(%p)->()\n",this);
3728 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
3729 LPDIRECTDRAW2 this,LPDWORD freq
3731 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
3732 *freq = 60*100; /* 60 Hz */
3736 /* what can we directly decompress? */
3737 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
3738 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
3740 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
3744 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
3745 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
3747 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
3751 static HRESULT WINAPI IDirectDraw2_Compact(
3752 LPDIRECTDRAW2 this )
3754 FIXME(ddraw,"(%p)->()\n", this );
3759 static HRESULT WINAPI IDirectDraw2_GetGDISurface(LPDIRECTDRAW2 this,
3760 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
3761 FIXME(ddraw,"(%p)->(%p)\n", this, lplpGDIDDSSurface);
3766 static HRESULT WINAPI IDirectDraw2_GetScanLine(LPDIRECTDRAW2 this,
3767 LPDWORD lpdwScanLine) {
3768 FIXME(ddraw,"(%p)->(%p)\n", this, lpdwScanLine);
3773 static HRESULT WINAPI IDirectDraw2_Initialize(LPDIRECTDRAW2 this,
3775 FIXME(ddraw,"(%p)->(%p)\n", this, lpGUID);
3780 /* Note: Hack so we can reuse the old functions without compiler warnings */
3782 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
3784 # define XCAST(fun) (void*)
3787 static struct IDirectDraw_VTable dga_ddvt = {
3788 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3789 XCAST(AddRef)IDirectDraw2_AddRef,
3790 XCAST(Release)DGA_IDirectDraw2_Release,
3791 XCAST(Compact)IDirectDraw2_Compact,
3792 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3793 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3794 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3795 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3796 XCAST(EnumDisplayModes)DGA_IDirectDraw2_EnumDisplayModes,
3797 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3798 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3799 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3800 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3801 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3802 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3803 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3804 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3805 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3806 XCAST(Initialize)IDirectDraw2_Initialize,
3807 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3808 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3809 DGA_IDirectDraw_SetDisplayMode,
3810 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3813 static struct IDirectDraw_VTable xlib_ddvt = {
3814 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3815 XCAST(AddRef)IDirectDraw2_AddRef,
3816 XCAST(Release)Xlib_IDirectDraw2_Release,
3817 XCAST(Compact)IDirectDraw2_Compact,
3818 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3819 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3820 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3821 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3822 XCAST(EnumDisplayModes)Xlib_IDirectDraw2_EnumDisplayModes,
3823 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3824 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3825 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3826 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3827 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3828 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3829 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3830 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3831 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3832 XCAST(Initialize)IDirectDraw2_Initialize,
3833 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3834 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3835 Xlib_IDirectDraw_SetDisplayMode,
3836 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3841 /*****************************************************************************
3847 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
3848 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3850 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3853 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
3854 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3856 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3859 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
3860 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3862 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3863 this,ddscaps,total,free
3865 if (total) *total = this->e.dga.fb_memsize * 1024;
3866 if (free) *free = this->e.dga.fb_memsize * 1024;
3870 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
3871 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3873 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3874 this,ddscaps,total,free
3876 if (total) *total = 2048 * 1024;
3877 if (free) *free = 2048 * 1024;
3881 static IDirectDraw2_VTable dga_dd2vt = {
3882 DGA_IDirectDraw2_QueryInterface,
3883 IDirectDraw2_AddRef,
3884 DGA_IDirectDraw2_Release,
3885 IDirectDraw2_Compact,
3886 IDirectDraw2_CreateClipper,
3887 DGA_IDirectDraw2_CreatePalette,
3888 DGA_IDirectDraw2_CreateSurface,
3889 IDirectDraw2_DuplicateSurface,
3890 DGA_IDirectDraw2_EnumDisplayModes,
3891 IDirectDraw2_EnumSurfaces,
3892 IDirectDraw2_FlipToGDISurface,
3893 DGA_IDirectDraw2_GetCaps,
3894 DGA_IDirectDraw2_GetDisplayMode,
3895 IDirectDraw2_GetFourCCCodes,
3896 IDirectDraw2_GetGDISurface,
3897 IDirectDraw2_GetMonitorFrequency,
3898 IDirectDraw2_GetScanLine,
3899 IDirectDraw2_GetVerticalBlankStatus,
3900 IDirectDraw2_Initialize,
3901 DGA_IDirectDraw2_RestoreDisplayMode,
3902 IDirectDraw2_SetCooperativeLevel,
3903 DGA_IDirectDraw2_SetDisplayMode,
3904 IDirectDraw2_WaitForVerticalBlank,
3905 DGA_IDirectDraw2_GetAvailableVidMem
3908 static struct IDirectDraw2_VTable xlib_dd2vt = {
3909 Xlib_IDirectDraw2_QueryInterface,
3910 IDirectDraw2_AddRef,
3911 Xlib_IDirectDraw2_Release,
3912 IDirectDraw2_Compact,
3913 IDirectDraw2_CreateClipper,
3914 Xlib_IDirectDraw2_CreatePalette,
3915 Xlib_IDirectDraw2_CreateSurface,
3916 IDirectDraw2_DuplicateSurface,
3917 Xlib_IDirectDraw2_EnumDisplayModes,
3918 IDirectDraw2_EnumSurfaces,
3919 IDirectDraw2_FlipToGDISurface,
3920 Xlib_IDirectDraw2_GetCaps,
3921 Xlib_IDirectDraw2_GetDisplayMode,
3922 IDirectDraw2_GetFourCCCodes,
3923 IDirectDraw2_GetGDISurface,
3924 IDirectDraw2_GetMonitorFrequency,
3925 IDirectDraw2_GetScanLine,
3926 IDirectDraw2_GetVerticalBlankStatus,
3927 IDirectDraw2_Initialize,
3928 Xlib_IDirectDraw2_RestoreDisplayMode,
3929 IDirectDraw2_SetCooperativeLevel,
3930 Xlib_IDirectDraw2_SetDisplayMode,
3931 IDirectDraw2_WaitForVerticalBlank,
3932 Xlib_IDirectDraw2_GetAvailableVidMem
3935 /*****************************************************************************
3940 static HRESULT WINAPI IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4 this,
3942 LPDIRECTDRAWSURFACE *lpDDS) {
3943 FIXME(ddraw, "(%p)->(%08ld,%p)\n", this, (DWORD) hdc, lpDDS);
3948 static HRESULT WINAPI IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4 this) {
3949 FIXME(ddraw, "(%p)->()\n", this);
3954 static HRESULT WINAPI IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4 this) {
3955 FIXME(ddraw, "(%p)->()\n", this);
3960 static HRESULT WINAPI IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4 this,
3961 LPDDDEVICEIDENTIFIER lpdddi,
3963 FIXME(ddraw, "(%p)->(%p,%08lx)\n", this, lpdddi, dwFlags);
3969 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
3971 # define XCAST(fun) (void*)
3975 static struct IDirectDraw4_VTable dga_dd4vt = {
3976 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3977 XCAST(AddRef)IDirectDraw2_AddRef,
3978 XCAST(Release)DGA_IDirectDraw2_Release,
3979 XCAST(Compact)IDirectDraw2_Compact,
3980 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3981 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3982 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3983 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3984 XCAST(EnumDisplayModes)DGA_IDirectDraw2_EnumDisplayModes,
3985 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3986 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3987 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3988 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3989 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3990 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3991 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3992 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3993 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3994 XCAST(Initialize)IDirectDraw2_Initialize,
3995 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3996 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3997 XCAST(SetDisplayMode)DGA_IDirectDraw_SetDisplayMode,
3998 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3999 XCAST(GetAvailableVidMem)DGA_IDirectDraw2_GetAvailableVidMem,
4000 IDirectDraw4_GetSurfaceFromDC,
4001 IDirectDraw4_RestoreAllSurfaces,
4002 IDirectDraw4_TestCooperativeLevel,
4003 IDirectDraw4_GetDeviceIdentifier
4006 static struct IDirectDraw4_VTable xlib_dd4vt = {
4007 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
4008 XCAST(AddRef)IDirectDraw2_AddRef,
4009 XCAST(Release)Xlib_IDirectDraw2_Release,
4010 XCAST(Compact)IDirectDraw2_Compact,
4011 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
4012 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
4013 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
4014 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
4015 XCAST(EnumDisplayModes)Xlib_IDirectDraw2_EnumDisplayModes,
4016 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
4017 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
4018 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
4019 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
4020 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
4021 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
4022 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
4023 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
4024 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
4025 XCAST(Initialize)IDirectDraw2_Initialize,
4026 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
4027 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
4028 XCAST(SetDisplayMode)Xlib_IDirectDraw_SetDisplayMode,
4029 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
4030 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2_GetAvailableVidMem,
4031 IDirectDraw4_GetSurfaceFromDC,
4032 IDirectDraw4_RestoreAllSurfaces,
4033 IDirectDraw4_TestCooperativeLevel,
4034 IDirectDraw4_GetDeviceIdentifier
4039 /******************************************************************************
4043 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4046 LPDIRECTDRAW ddraw = NULL;
4049 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4051 SetLastError( ERROR_SUCCESS );
4052 ddraw = (LPDIRECTDRAW)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4054 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4057 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4062 /* Perform any special direct draw functions */
4064 ddraw->d.paintable = 1;
4066 /* Now let the application deal with the rest of this */
4067 if( ddraw->d.mainWindow )
4070 /* Don't think that we actually need to call this but...
4071 might as well be on the safe side of things... */
4073 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4074 it should be the procedures of our fake window that gets called
4075 instead of those of the window provided by the application.
4076 And with this patch, mouse clicks work with Monkey Island III
4078 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4082 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4083 /* We didn't handle the message - give it to the application */
4084 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4086 ret = CallWindowProcA(tmpWnd->winproc,
4087 ddraw->d.mainWindow, msg, wParam, lParam );
4089 WIN_ReleaseWndPtr(tmpWnd);
4094 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4100 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4106 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4107 #ifdef HAVE_LIBXXF86DGA
4108 int memsize,banksize,width,major,minor,flags,height;
4113 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4114 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4118 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4119 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4120 return E_UNEXPECTED;
4122 if (!DDRAW_DGA_Available()) {
4123 TRACE(ddraw,"No XF86DGA detected.\n");
4124 return DDERR_GENERIC;
4126 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
4127 (*lplpDD)->lpvtbl = &dga_ddvt;
4129 TSXF86DGAQueryVersion(display,&major,&minor);
4130 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4131 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4132 if (!(flags & XF86DGADirectPresent))
4133 MSG("direct video is NOT PRESENT.\n");
4134 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4135 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4136 addr,width,banksize,memsize
4138 (*lplpDD)->e.dga.fb_width = width;
4139 (*lplpDD)->d.width = width;
4140 (*lplpDD)->e.dga.fb_addr = addr;
4141 (*lplpDD)->e.dga.fb_memsize = memsize;
4142 (*lplpDD)->e.dga.fb_banksize = banksize;
4144 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4145 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4146 (*lplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4148 (*lplpDD)->e.dga.vpmask = 1;
4150 (*lplpDD)->e.dga.vpmask = 0;
4153 /* just assume the default depth is the DGA depth too */
4154 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4155 _common_depth_to_pixelformat(depth, &((*lplpDD)->d.directdraw_pixelformat), &((*lplpDD)->d.screen_pixelformat), NULL);
4156 #ifdef RESTORE_SIGNALS
4157 SIGNAL_InitHandlers();
4161 #else /* defined(HAVE_LIBXXF86DGA) */
4162 return DDERR_INVALIDDIRECTDRAWGUID;
4163 #endif /* defined(HAVE_LIBXXF86DGA) */
4167 DDRAW_XSHM_Available(void)
4169 #ifdef HAVE_LIBXXSHM
4170 if (TSXShmQueryExtension(display))
4175 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4187 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4190 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
4191 (*lplpDD)->lpvtbl = &xlib_ddvt;
4193 (*lplpDD)->d.drawable = 0; /* in SetDisplayMode */
4195 /* At DirectDraw creation, the depth is the default depth */
4196 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4197 _common_depth_to_pixelformat(depth, &((*lplpDD)->d.directdraw_pixelformat), &((*lplpDD)->d.screen_pixelformat), NULL);
4198 (*lplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4199 (*lplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4201 #ifdef HAVE_LIBXXSHM
4202 /* Test if XShm is available. */
4203 if (((*lplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4204 TRACE(ddraw, "Using XShm extension.\n");
4210 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4213 /* WND* pParentWindow; */
4217 WINE_StringFromCLSID(lpGUID,xclsid);
4219 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4223 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
4226 /* if they didn't request a particular interface, use the best
4228 if (DDRAW_DGA_Available())
4229 lpGUID = &DGA_DirectDraw_GUID;
4231 lpGUID = &XLIB_DirectDraw_GUID;
4234 wc.style = CS_GLOBALCLASS;
4235 wc.lpfnWndProc = Xlib_DDWndProc;
4237 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
4238 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
4240 /* We can be a child of the desktop since we're really important */
4242 This code is not useful since hInstance is forced to 0 afterward
4243 pParentWindow = WIN_GetDesktop();
4244 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
4250 wc.hCursor = (HCURSOR)IDC_ARROWA;
4251 wc.hbrBackground= NULL_BRUSH;
4252 wc.lpszMenuName = 0;
4253 wc.lpszClassName= "WINE_DirectDraw";
4254 RegisterClassA(&wc);
4256 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4257 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4258 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4259 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4264 (*lplpDD)->d.winclass = RegisterClassA(&wc);
4268 ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4269 return DDERR_INVALIDDIRECTDRAWGUID;
4273 #else /* !defined(X_DISPLAY_MISSING) */
4279 typedef void *LPGUID;
4280 typedef void *LPUNKNOWN;
4281 typedef void *LPDIRECTDRAW;
4282 typedef void *LPDIRECTDRAWCLIPPER;
4283 typedef void *LPDDENUMCALLBACKA;
4284 typedef void *LPDDENUMCALLBACKEXA;
4285 typedef void *LPDDENUMCALLBACKEXW;
4286 typedef void *LPDDENUMCALLBACKW;
4288 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
4293 HRESULT WINAPI DirectDrawCreate(
4294 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
4299 HRESULT WINAPI DirectDrawCreateClipper(
4300 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
4305 HRESULT WINAPI DirectDrawEnumerateA(
4306 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
4311 HRESULT WINAPI DirectDrawEnumerateExA(
4312 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
4317 HRESULT WINAPI DirectDrawEnumerateExW(
4318 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
4323 HRESULT WINAPI DirectDrawEnumerateW(
4324 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
4329 #endif /* !defined(X_DISPLAY_MISSING) */