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>
57 #include "wine/exception.h"
66 /* This for all the enumeration and creation of D3D-related objects */
67 #include "ddraw_private.h"
68 #include "d3d_private.h"
70 DEFAULT_DEBUG_CHANNEL(ddraw)
72 /* Restore signal handlers overwritten by XF86DGA
74 #define RESTORE_SIGNALS
76 /* Get the number of bytes per pixel for a given surface */
77 #define GET_BPP(desc) (desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ? \
79 desc.ddpfPixelFormat.x.dwRGBBitCount / 8)
81 /* Where do these GUIDs come from? mkuuid.
82 * They exist solely to distinguish between the targets Wine support,
83 * and should be different than any other GUIDs in existence.
85 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
89 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
92 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
96 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
99 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt, xlib_dds4vt;
100 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt, xlib_ddvt;
101 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt, xlib_dd2vt;
102 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt, xlib_dd4vt;
103 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
104 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt, xlib_ddpalvt;
105 static struct ICOM_VTABLE(IDirect3D) d3dvt;
106 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
108 #ifdef HAVE_LIBXXF86VM
109 static XF86VidModeModeInfo *orig_mode = NULL;
113 static int XShmErrorFlag = 0;
117 DDRAW_DGA_Available(void)
119 #ifdef HAVE_LIBXXF86DGA
120 int evbase, evret, fd;
125 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
126 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
127 /* others. --stephenc */
128 if ((fd = open("/dev/mem", O_RDWR)) != -1)
131 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
132 #else /* defined(HAVE_LIBXXF86DGA) */
134 #endif /* defined(HAVE_LIBXXF86DGA) */
137 /**********************************************************************/
142 } DirectDrawEnumerateProcData;
144 /***********************************************************************
145 * DirectDrawEnumerateExA (DDRAW.*)
147 HRESULT WINAPI DirectDrawEnumerateExA(
148 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
150 TRACE(ddraw, "(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
152 if (TRACE_ON(ddraw)) {
154 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
155 DUMP("DDENUM_ATTACHEDSECONDARYDEVICES ");
156 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
157 DUMP("DDENUM_DETACHEDSECONDARYDEVICES ");
158 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
159 DUMP("DDENUM_NONDISPLAYDEVICES ");
163 if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
164 /* For the moment, Wine does not support any 3D only accelerators */
168 if (DDRAW_DGA_Available()) {
169 TRACE(ddraw, "Enumerating DGA interface\n");
170 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
174 TRACE(ddraw, "Enumerating Xlib interface\n");
175 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
178 TRACE(ddraw, "Enumerating Default interface\n");
179 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
185 /***********************************************************************
186 * DirectDrawEnumerateExW (DDRAW.*)
189 static BOOL CALLBACK DirectDrawEnumerateExProcW(
190 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
191 LPVOID lpContext, HMONITOR hm)
193 DirectDrawEnumerateProcData *pEPD =
194 (DirectDrawEnumerateProcData *) lpContext;
195 LPWSTR lpDriverDescriptionW =
196 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
197 LPWSTR lpDriverNameW =
198 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
200 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
201 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
203 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
204 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
209 /**********************************************************************/
211 HRESULT WINAPI DirectDrawEnumerateExW(
212 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
214 DirectDrawEnumerateProcData epd;
215 epd.lpCallback = (LPVOID) lpCallback;
216 epd.lpContext = lpContext;
218 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
222 /***********************************************************************
223 * DirectDrawEnumerateA (DDRAW.*)
226 static BOOL CALLBACK DirectDrawEnumerateProcA(
227 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
228 LPVOID lpContext, HMONITOR hm)
230 DirectDrawEnumerateProcData *pEPD =
231 (DirectDrawEnumerateProcData *) lpContext;
233 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
234 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
237 /**********************************************************************/
239 HRESULT WINAPI DirectDrawEnumerateA(
240 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
242 DirectDrawEnumerateProcData epd;
243 epd.lpCallback = (LPVOID) lpCallback;
244 epd.lpContext = lpContext;
246 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
250 /***********************************************************************
251 * DirectDrawEnumerateW (DDRAW.*)
254 static BOOL WINAPI DirectDrawEnumerateProcW(
255 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
256 LPVOID lpContext, HMONITOR hm)
258 DirectDrawEnumerateProcData *pEPD =
259 (DirectDrawEnumerateProcData *) lpContext;
261 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
262 lpGUID, lpDriverDescription, lpDriverName,
266 /**********************************************************************/
268 HRESULT WINAPI DirectDrawEnumerateW(
269 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
271 DirectDrawEnumerateProcData epd;
272 epd.lpCallback = (LPVOID) lpCallback;
273 epd.lpContext = lpContext;
275 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
279 /***********************************************************************
280 * DSoundHelp (DDRAW.?)
283 /* What is this doing here? */
285 DSoundHelp(DWORD x,DWORD y,DWORD z) {
286 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
290 /******************************************************************************
291 * internal helper functions
293 static void _dump_DDBLTFX(DWORD flagmask) {
299 #define FE(x) { x, #x},
300 FE(DDBLTFX_ARITHSTRETCHY)
301 FE(DDBLTFX_MIRRORLEFTRIGHT)
302 FE(DDBLTFX_MIRRORUPDOWN)
303 FE(DDBLTFX_NOTEARING)
304 FE(DDBLTFX_ROTATE180)
305 FE(DDBLTFX_ROTATE270)
307 FE(DDBLTFX_ZBUFFERRANGE)
308 FE(DDBLTFX_ZBUFFERBASEDEST)
311 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
312 if (flags[i].mask & flagmask) {
313 DUMP("%s ",flags[i].name);
320 static void _dump_DDBLTFAST(DWORD flagmask) {
326 #define FE(x) { x, #x},
327 FE(DDBLTFAST_NOCOLORKEY)
328 FE(DDBLTFAST_SRCCOLORKEY)
329 FE(DDBLTFAST_DESTCOLORKEY)
333 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
334 if (flags[i].mask & flagmask)
335 DUMP("%s ",flags[i].name);
339 static void _dump_DDBLT(DWORD flagmask) {
345 #define FE(x) { x, #x},
347 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
348 FE(DDBLT_ALPHADESTNEG)
349 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
350 FE(DDBLT_ALPHAEDGEBLEND)
352 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
353 FE(DDBLT_ALPHASRCNEG)
354 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
360 FE(DDBLT_KEYDESTOVERRIDE)
362 FE(DDBLT_KEYSRCOVERRIDE)
364 FE(DDBLT_ROTATIONANGLE)
366 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
367 FE(DDBLT_ZBUFFERDESTOVERRIDE)
368 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
369 FE(DDBLT_ZBUFFERSRCOVERRIDE)
374 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
375 if (flags[i].mask & flagmask)
376 DUMP("%s ",flags[i].name);
380 static void _dump_DDSCAPS(void *in) {
386 #define FE(x) { x, #x},
387 FE(DDSCAPS_RESERVED1)
389 FE(DDSCAPS_BACKBUFFER)
392 FE(DDSCAPS_FRONTBUFFER)
393 FE(DDSCAPS_OFFSCREENPLAIN)
396 FE(DDSCAPS_PRIMARYSURFACE)
397 FE(DDSCAPS_PRIMARYSURFACELEFT)
398 FE(DDSCAPS_SYSTEMMEMORY)
401 FE(DDSCAPS_VIDEOMEMORY)
403 FE(DDSCAPS_WRITEONLY)
406 FE(DDSCAPS_LIVEVIDEO)
410 FE(DDSCAPS_RESERVED2)
411 FE(DDSCAPS_ALLOCONLOAD)
412 FE(DDSCAPS_VIDEOPORT)
413 FE(DDSCAPS_LOCALVIDMEM)
414 FE(DDSCAPS_NONLOCALVIDMEM)
415 FE(DDSCAPS_STANDARDVGAMODE)
416 FE(DDSCAPS_OPTIMIZED)
419 DWORD flagmask = *((DWORD *) in);
420 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
421 if (flags[i].mask & flagmask)
422 DUMP("%s ",flags[i].name);
425 static void _dump_pixelformat_flag(DWORD flagmask) {
431 #define FE(x) { x, #x},
435 FE(DDPF_PALETTEINDEXED4)
436 FE(DDPF_PALETTEINDEXEDTO8)
437 FE(DDPF_PALETTEINDEXED8)
443 FE(DDPF_PALETTEINDEXED1)
444 FE(DDPF_PALETTEINDEXED2)
448 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
449 if (flags[i].mask & flagmask)
450 DUMP("%s ",flags[i].name);
453 static void _dump_paletteformat(DWORD dwFlags) {
459 #define FE(x) { x, #x},
461 FE(DDPCAPS_8BITENTRIES)
463 FE(DDPCAPS_INITIALIZE)
464 FE(DDPCAPS_PRIMARYSURFACE)
465 FE(DDPCAPS_PRIMARYSURFACELEFT)
473 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
474 if (flags[i].mask & dwFlags)
475 DUMP("%s ",flags[i].name);
479 static void _dump_pixelformat(void *in) {
480 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
484 _dump_pixelformat_flag(pf->dwFlags);
485 if (pf->dwFlags & DDPF_FOURCC) {
486 DUMP(", dwFourCC : %ld", pf->dwFourCC);
488 if (pf->dwFlags & DDPF_RGB) {
489 DUMP(", RGB bits: %ld, ", pf->x.dwRGBBitCount);
490 switch (pf->x.dwRGBBitCount) {
507 ERR(ddraw, "Unexpected bit depth !\n");
510 DUMP(" R "); DUMP(cmd, pf->y.dwRBitMask);
511 DUMP(" G "); DUMP(cmd, pf->z.dwGBitMask);
512 DUMP(" B "); DUMP(cmd, pf->xx.dwBBitMask);
513 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
514 DUMP(" A "); DUMP(cmd, pf->xy.dwRGBAlphaBitMask);
516 if (pf->dwFlags & DDPF_ZPIXELS) {
517 DUMP(" Z "); DUMP(cmd, pf->xy.dwRGBZBitMask);
520 if (pf->dwFlags & DDPF_ZBUFFER) {
521 DUMP(", Z bits : %ld", pf->x.dwZBufferBitDepth);
523 if (pf->dwFlags & DDPF_ALPHA) {
524 DUMP(", Alpha bits : %ld", pf->x.dwAlphaBitDepth);
529 static void _dump_colorkeyflag(DWORD ck) {
535 #define FE(x) { x, #x},
536 FE(DDCKEY_COLORSPACE)
538 FE(DDCKEY_DESTOVERLAY)
540 FE(DDCKEY_SRCOVERLAY)
543 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
544 if (flags[i].mask & ck)
545 DUMP("%s ",flags[i].name);
548 static void _dump_DWORD(void *in) {
549 DUMP("%ld", *((DWORD *) in));
551 static void _dump_PTR(void *in) {
552 DUMP("%p", *((void **) in));
554 static void _dump_DDCOLORKEY(void *in) {
555 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
557 DUMP(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
560 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
565 void (*func)(void *);
568 #define FE(x,func,elt) { x, #x, func, (void *) &(lpddsd->elt)}
569 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps),
570 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight),
571 FE(DDSD_WIDTH, _dump_DWORD, dwWidth),
572 FE(DDSD_PITCH, _dump_DWORD, lPitch),
573 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount),
574 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, x.dwZBufferBitDepth),
575 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth),
576 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat),
577 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay),
578 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt),
579 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay),
580 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt),
581 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, x.dwMipMapCount),
582 FE(DDSD_REFRESHRATE, _dump_DWORD, x.dwRefreshRate),
583 FE(DDSD_LINEARSIZE, _dump_DWORD, y.dwLinearSize),
584 FE(DDSD_LPSURFACE, _dump_PTR, y.lpSurface)
587 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
588 if (flags[i].mask & lpddsd->dwFlags) {
589 DUMP(" - %s : ",flags[i].name);
590 flags[i].func(flags[i].elt);
596 /******************************************************************************
597 * IDirectDrawSurface methods
599 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
600 * DDS and DDS2 use those functions. (Function calls did not change (except
601 * using different DirectDrawSurfaceX version), just added flags and functions)
603 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
604 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
606 ICOM_THIS(IDirectDrawSurface4Impl,iface);
607 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
608 This,lprect,lpddsd,flags,(DWORD)hnd);
609 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
610 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
611 This,lprect,lpddsd,flags,(DWORD)hnd);
613 /* First, copy the Surface description */
614 *lpddsd = This->s.surface_desc;
615 TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
616 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
618 /* If asked only for a part, change the surface pointer */
620 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
621 lprect->top,lprect->left,lprect->bottom,lprect->right
623 lpddsd->y.lpSurface = (LPVOID) ((char *) This->s.surface_desc.y.lpSurface +
624 (lprect->top*This->s.surface_desc.lPitch) +
625 (lprect->left*(This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8)));
627 assert(This->s.surface_desc.y.lpSurface);
632 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
633 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
635 ICOM_THIS(IDirectDrawSurface4Impl,iface);
636 TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
640 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
641 if (This->s.ddraw->d.pixel_convert != NULL)
642 This->s.ddraw->d.pixel_convert(This->s.surface_desc.y.lpSurface,
643 This->t.xlib.image->data,
644 This->s.surface_desc.dwWidth,
645 This->s.surface_desc.dwHeight,
646 This->s.surface_desc.lPitch,
650 if (This->s.ddraw->e.xlib.xshm_active)
651 TSXShmPutImage(display,
652 This->s.ddraw->d.drawable,
653 DefaultGCOfScreen(X11DRV_GetXScreen()),
656 This->t.xlib.image->width,
657 This->t.xlib.image->height,
661 TSXPutImage( display,
662 This->s.ddraw->d.drawable,
663 DefaultGCOfScreen(X11DRV_GetXScreen()),
666 This->t.xlib.image->width,
667 This->t.xlib.image->height);
670 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
671 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
673 ICOM_THIS(IDirectDrawSurface4Impl,iface);
674 TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
676 if (!This->s.ddraw->d.paintable)
679 /* Only redraw the screen when unlocking the buffer that is on screen */
680 if ((This->t.xlib.image != NULL) &&
681 (This->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
682 Xlib_copy_surface_on_screen(This);
684 if (This->s.palette && This->s.palette->cm)
685 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
691 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
692 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
694 ICOM_THIS(IDirectDrawSurface4Impl,iface);
695 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
696 #ifdef HAVE_LIBXXF86DGA
697 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
699 if (This->s.backbuffer)
700 iflipto = This->s.backbuffer;
704 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
706 if (iflipto->s.palette && iflipto->s.palette->cm) {
707 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
709 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
715 tmp = This->t.dga.fb_height;
716 This->t.dga.fb_height = iflipto->t.dga.fb_height;
717 iflipto->t.dga.fb_height = tmp;
719 ptmp = This->s.surface_desc.y.lpSurface;
720 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
721 iflipto->s.surface_desc.y.lpSurface = ptmp;
724 #else /* defined(HAVE_LIBXXF86DGA) */
726 #endif /* defined(HAVE_LIBXXF86DGA) */
729 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
730 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
732 ICOM_THIS(IDirectDrawSurface4Impl,iface);
733 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
734 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
737 if ((This->s.d3d_device != NULL) ||
738 ((This->s.backbuffer != NULL) && (This->s.backbuffer->s.d3d_device != NULL))) {
739 TRACE(ddraw," - OpenGL flip\n");
741 glXSwapBuffers(display,
742 This->s.ddraw->d.drawable);
747 #endif /* defined(HAVE_MESAGL) */
749 if (!This->s.ddraw->d.paintable)
753 if (This->s.backbuffer)
754 iflipto = This->s.backbuffer;
759 Xlib_copy_surface_on_screen(iflipto);
761 if (iflipto->s.palette && iflipto->s.palette->cm) {
762 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
767 tmp = This->t.xlib.image;
768 This->t.xlib.image = iflipto->t.xlib.image;
769 iflipto->t.xlib.image = tmp;
770 surf = This->s.surface_desc.y.lpSurface;
771 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
772 iflipto->s.surface_desc.y.lpSurface = surf;
778 /* The IDirectDrawSurface4::SetPalette method attaches the specified
779 * DirectDrawPalette object to a surface. The surface uses this palette for all
780 * subsequent operations. The palette change takes place immediately.
782 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
783 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
785 ICOM_THIS(IDirectDrawSurface4Impl,iface);
786 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
788 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
791 if( This->s.palette != NULL )
792 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
793 This->s.palette = ipal;
798 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
800 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
801 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
803 if (!Options.managed)
804 TSXInstallColormap(display,ipal->cm);
806 for (i=0;i<256;i++) {
809 xc.red = ipal->palents[i].peRed<<8;
810 xc.blue = ipal->palents[i].peBlue<<8;
811 xc.green = ipal->palents[i].peGreen<<8;
812 xc.flags = DoRed|DoBlue|DoGreen;
814 TSXStoreColor(display,ipal->cm,&xc);
816 TSXInstallColormap(display,ipal->cm);
819 /* According to spec, we are only supposed to
820 * AddRef if this is not the same palette.
822 if( This->s.palette != ipal )
825 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
826 if( This->s.palette != NULL )
827 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
828 This->s.palette = ipal;
830 /* I think that we need to attach it to all backbuffers...*/
831 if( This->s.backbuffer ) {
832 if( This->s.backbuffer->s.palette )
833 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
834 This->s.backbuffer->s.palette = ipal;
836 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
838 /* Perform the refresh */
839 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
844 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
845 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
847 ICOM_THIS(IDirectDrawSurface4Impl,iface);
848 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
849 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
850 #ifdef HAVE_LIBXXF86DGA
851 /* According to spec, we are only supposed to
852 * AddRef if this is not the same palette.
854 if( This->s.palette != ipal )
857 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
858 if( This->s.palette != NULL )
859 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
860 This->s.palette = ipal;
862 /* I think that we need to attach it to all backbuffers...*/
863 if( This->s.backbuffer ) {
864 if( This->s.backbuffer->s.palette )
865 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
866 This->s.backbuffer->s.palette = ipal;
868 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
870 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
873 #else /* defined(HAVE_LIBXXF86DGA) */
875 #endif /* defined(HAVE_LIBXXF86DGA) */
880 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
887 #define COLORFILL_ROW(type) { \
888 type *d = (type *) buf; \
889 for (x = 0; x < width; x++) \
890 d[x] = (type) color; \
895 case 1: COLORFILL_ROW(BYTE)
896 case 2: COLORFILL_ROW(WORD)
897 case 4: COLORFILL_ROW(DWORD)
899 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
900 return DDERR_UNSUPPORTED;
905 /* Now copy first row */
907 for (y = 1; y < height; y++) {
909 memcpy(buf, first, width * bpp);
915 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
916 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
918 ICOM_THIS(IDirectDrawSurface4Impl,iface);
920 DDSURFACEDESC ddesc,sdesc;
922 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
926 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
928 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
929 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
931 if (TRACE_ON(ddraw)) {
932 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
933 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
934 TRACE(ddraw,"\tflags: ");
935 _dump_DDBLT(dwFlags);
936 if (dwFlags & DDBLT_DDFX) {
937 TRACE(ddraw," blitfx: \n");
938 _dump_DDBLTFX(lpbltfx->dwDDFX);
943 memcpy(&xdst,rdst,sizeof(xdst));
946 xdst.bottom = ddesc.dwHeight;
948 xdst.right = ddesc.dwWidth;
952 memcpy(&xsrc,rsrc,sizeof(xsrc));
956 xsrc.bottom = sdesc.dwHeight;
958 xsrc.right = sdesc.dwWidth;
960 memset(&xsrc,0,sizeof(xsrc));
964 bpp = GET_BPP(ddesc);
965 srcheight = xsrc.bottom - xsrc.top;
966 srcwidth = xsrc.right - xsrc.left;
967 dstheight = xdst.bottom - xdst.top;
968 dstwidth = xdst.right - xdst.left;
969 width = (xdst.right - xdst.left) * bpp;
970 dbuf = (BYTE *) ddesc.y.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
972 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
974 /* First, all the 'source-less' blits */
975 if (dwFlags & DDBLT_COLORFILL) {
976 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
977 ddesc.lPitch, lpbltfx->b.dwFillColor);
978 dwFlags &= ~DDBLT_COLORFILL;
981 if (dwFlags & DDBLT_DEPTHFILL) {
985 /* Clears the screen */
986 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
987 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
988 glGetBooleanv(GL_DEPTH_TEST, &ztest);
989 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
990 glClear(GL_DEPTH_BUFFER_BIT);
993 dwFlags &= ~(DDBLT_DEPTHFILL);
994 #endif /* defined(HAVE_MESAGL) */
997 if (dwFlags & DDBLT_ROP) {
998 /* Catch some degenerate cases here */
999 switch(lpbltfx->dwROP) {
1001 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1003 case 0xAA0029: /* No-op */
1006 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1009 FIXME(ddraw, "Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->b.lpDDSPattern);
1012 dwFlags &= ~DDBLT_ROP;
1015 if (dwFlags & DDBLT_DDROPS) {
1016 FIXME(ddraw, "\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->b.lpDDSPattern);
1019 /* Now the 'with source' blits */
1022 int sx, xinc, sy, yinc;
1024 sbase = (BYTE *) sdesc.y.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1025 xinc = (srcwidth << 16) / dstwidth;
1026 yinc = (srcheight << 16) / dstheight;
1030 /* No effects, we can cheat here */
1031 if (dstwidth == srcwidth) {
1032 if (dstheight == srcheight) {
1033 /* No stretching in either direction. This needs to be as fast as possible */
1035 for (y = 0; y < dstheight; y++) {
1036 memcpy(dbuf, sbuf, width);
1037 sbuf += sdesc.lPitch;
1038 dbuf += ddesc.lPitch;
1041 /* Stretching in Y direction only */
1042 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1043 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1044 memcpy(dbuf, sbuf, width);
1045 dbuf += ddesc.lPitch;
1049 /* Stretching in X direction */
1051 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1052 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1054 if ((sy >> 16) == (last_sy >> 16)) {
1055 /* Same as last row - copy already stretched row */
1056 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1059 #define STRETCH_ROW(type) { \
1060 type *s = (type *) sbuf, *d = (type *) dbuf; \
1061 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1062 d[x] = s[sx >> 16]; \
1067 case 1: STRETCH_ROW(BYTE)
1068 case 2: STRETCH_ROW(WORD)
1069 case 4: STRETCH_ROW(DWORD)
1071 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
1072 ret = DDERR_UNSUPPORTED;
1080 dbuf += ddesc.lPitch;
1083 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1084 DWORD keylow, keyhigh;
1086 if (dwFlags & DDBLT_KEYSRC) {
1087 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1088 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1090 /* I'm not sure if this is correct */
1091 FIXME(ddraw, "DDBLT_KEYDEST not fully supported yet.\n");
1092 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1093 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1096 #define COPYROW_COLORKEY(type) { \
1097 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1098 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1099 tmp = s[sx >> 16]; \
1100 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1105 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1106 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1109 case 1: COPYROW_COLORKEY(BYTE)
1110 case 2: COPYROW_COLORKEY(WORD)
1111 case 4: COPYROW_COLORKEY(DWORD)
1113 FIXME(ddraw, "%s color-keyed blit not implemented for bpp %d!\n",
1114 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1115 ret = DDERR_UNSUPPORTED;
1118 dbuf += ddesc.lPitch;
1121 #undef COPYROW_COLORKEY
1123 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1130 if (dwFlags && FIXME_ON(ddraw)) {
1131 FIXME(ddraw,"\tUnsupported flags: ");
1132 _dump_DDBLT(dwFlags);
1135 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1136 if (src) IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1141 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1142 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1144 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1145 int bpp, w, h, x, y;
1146 DDSURFACEDESC ddesc,sdesc;
1147 HRESULT ret = DD_OK;
1151 if (TRACE_ON(ddraw)) {
1152 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1153 This,dstx,dsty,src,rsrc,trans
1155 FIXME(ddraw," trans:");
1156 if (FIXME_ON(ddraw))
1157 _dump_DDBLTFAST(trans);
1158 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1160 /* We need to lock the surfaces, or we won't get refreshes when done. */
1161 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1162 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1164 bpp = GET_BPP(This->s.surface_desc);
1165 sbuf = (BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1166 dbuf = (BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1169 h=rsrc->bottom-rsrc->top;
1170 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1171 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1174 w=rsrc->right-rsrc->left;
1175 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1176 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1179 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1180 DWORD keylow, keyhigh;
1181 if (trans & DDBLTFAST_SRCCOLORKEY) {
1182 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1183 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1185 /* I'm not sure if this is correct */
1186 FIXME(ddraw, "DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1187 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1188 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1191 #define COPYBOX_COLORKEY(type) { \
1192 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1193 s = (type *) ((BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1194 d = (type *) ((BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1195 for (y = 0; y < h; y++) { \
1196 for (x = 0; x < w; x++) { \
1198 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1200 (LPBYTE)s += sdesc.lPitch; \
1201 (LPBYTE)d += ddesc.lPitch; \
1207 case 1: COPYBOX_COLORKEY(BYTE)
1208 case 2: COPYBOX_COLORKEY(WORD)
1209 case 4: COPYBOX_COLORKEY(DWORD)
1211 FIXME(ddraw, "Source color key blitting not supported for bpp %d\n", bpp*8);
1212 ret = DDERR_UNSUPPORTED;
1216 #undef COPYBOX_COLORKEY
1219 int width = w * bpp;
1221 for (y = 0; y < h; y++) {
1222 memcpy(dbuf, sbuf, width);
1223 sbuf += sdesc.lPitch;
1224 dbuf += ddesc.lPitch;
1230 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1231 IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1235 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1236 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1238 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1239 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1245 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1246 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1248 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1249 TRACE(ddraw,"(%p)->GetCaps(%p)\n",This,caps);
1250 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1254 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1255 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1257 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1258 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
1261 /* Simply copy the surface description stored in the object */
1262 *ddsd = This->s.surface_desc;
1264 if (TRACE_ON(ddraw)) {
1265 _dump_surface_desc(ddsd);
1271 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1272 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1273 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1275 return ++(This->ref);
1278 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1279 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1280 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1282 #ifdef HAVE_LIBXXF86DGA
1283 if (!--(This->ref)) {
1284 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1285 /* clear out of surface list */
1286 if (This->t.dga.fb_height == -1) {
1287 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1289 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1292 /* Free the backbuffer */
1293 if (This->s.backbuffer)
1294 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1296 /* Free the DIBSection (if any) */
1297 if (This->s.hdc != 0) {
1298 SelectObject(This->s.hdc, This->s.holdbitmap);
1299 DeleteDC(This->s.hdc);
1300 DeleteObject(This->s.DIBsection);
1303 HeapFree(GetProcessHeap(),0,This);
1306 #endif /* defined(HAVE_LIBXXF86DGA) */
1310 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1311 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1312 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1314 if (!--(This->ref)) {
1315 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1317 if( This->s.backbuffer )
1318 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1320 if (This->t.xlib.image != NULL) {
1321 if (This->s.ddraw->d.pixel_convert != NULL) {
1322 /* In pixel conversion mode, there are two buffers to release... */
1323 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1325 #ifdef HAVE_LIBXXSHM
1326 if (This->s.ddraw->e.xlib.xshm_active) {
1327 TSXShmDetach(display, &(This->t.xlib.shminfo));
1328 TSXDestroyImage(This->t.xlib.image);
1329 shmdt(This->t.xlib.shminfo.shmaddr);
1332 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1333 This->t.xlib.image->data = NULL;
1334 TSXDestroyImage(This->t.xlib.image);
1335 #ifdef HAVE_LIBXXSHM
1340 This->t.xlib.image->data = NULL;
1342 #ifdef HAVE_LIBXXSHM
1343 if (This->s.ddraw->e.xlib.xshm_active) {
1344 TSXShmDetach(display, &(This->t.xlib.shminfo));
1345 TSXDestroyImage(This->t.xlib.image);
1346 shmdt(This->t.xlib.shminfo.shmaddr);
1349 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1350 TSXDestroyImage(This->t.xlib.image);
1351 #ifdef HAVE_LIBXXSHM
1356 This->t.xlib.image = 0;
1358 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1361 if (This->s.palette)
1362 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1364 /* Free the DIBSection (if any) */
1365 if (This->s.hdc != 0) {
1366 SelectObject(This->s.hdc, This->s.holdbitmap);
1367 DeleteDC(This->s.hdc);
1368 DeleteObject(This->s.DIBsection);
1371 HeapFree(GetProcessHeap(),0,This);
1378 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1379 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1381 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1382 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1383 This, lpddsd, lpdsf);
1385 if (TRACE_ON(ddraw)) {
1386 TRACE(ddraw," caps ");
1387 _dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1391 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1392 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1396 /* FIXME: should handle more than one backbuffer */
1397 *lpdsf = (LPDIRECTDRAWSURFACE4)This->s.backbuffer;
1399 if( This->s.backbuffer )
1400 IDirectDrawSurface4_AddRef( (IDirectDrawSurface4*)This->s.backbuffer );
1405 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1406 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1408 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1409 TRACE(ddraw,"(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1411 return DDERR_ALREADYINITIALIZED;
1414 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1415 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1417 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1418 TRACE(ddraw,"(%p)->(%p)\n",This,pf);
1420 *pf = This->s.surface_desc.ddpfPixelFormat;
1422 if (TRACE_ON(ddraw)) {
1423 _dump_pixelformat(pf);
1430 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1431 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1432 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,dwFlags);
1436 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1437 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1439 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1440 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,x1,x2);
1444 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1445 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1447 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1448 FIXME(ddraw,"(%p)->(%p),stub!\n",This,clipper);
1452 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1453 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1455 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1456 FIXME(ddraw,"(%p)->(%p),stub!\n",This,surf);
1458 IDirectDrawSurface4_AddRef(iface);
1460 /* This hack will be enough for the moment */
1461 if (This->s.backbuffer == NULL)
1462 This->s.backbuffer = (IDirectDrawSurface4Impl*)surf;
1466 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1467 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1472 FIXME(ddraw,"(%p)->GetDC(%p)\n",This,lphdc);
1474 /* Creates a DIB Section of the same size / format as the surface */
1475 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1477 if (This->s.hdc == 0) {
1478 switch (desc.ddpfPixelFormat.x.dwRGBBitCount) {
1481 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1482 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1487 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1491 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1492 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.x.dwRGBBitCount));
1496 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1497 b_info->bmiHeader.biWidth = desc.dwWidth;
1498 b_info->bmiHeader.biHeight = desc.dwHeight;
1499 b_info->bmiHeader.biPlanes = 1;
1500 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.x.dwRGBBitCount;
1502 if ((desc.ddpfPixelFormat.x.dwRGBBitCount != 16) &&
1503 (desc.ddpfPixelFormat.x.dwRGBBitCount != 32))
1505 b_info->bmiHeader.biCompression = BI_RGB;
1508 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1510 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.x.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1511 b_info->bmiHeader.biXPelsPerMeter = 0;
1512 b_info->bmiHeader.biYPelsPerMeter = 0;
1513 b_info->bmiHeader.biClrUsed = 0;
1514 b_info->bmiHeader.biClrImportant = 0;
1516 switch (desc.ddpfPixelFormat.x.dwRGBBitCount) {
1521 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1524 masks[0] = desc.ddpfPixelFormat.y.dwRBitMask;
1525 masks[1] = desc.ddpfPixelFormat.z.dwGBitMask;
1526 masks[2] = desc.ddpfPixelFormat.xx.dwBBitMask;
1532 usage = DIB_RGB_COLORS;
1538 /* Fill the palette */
1539 usage = DIB_RGB_COLORS;
1541 if (This->s.palette == NULL) {
1542 ERR(ddraw, "Bad palette !!!\n");
1544 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1545 PALETTEENTRY *pent = (PALETTEENTRY *) &(This->s.palette->palents);
1547 for (i = 0; i < (2 << desc.ddpfPixelFormat.x.dwRGBBitCount); i++) {
1548 rgb[i].rgbBlue = pent[i].peBlue;
1549 rgb[i].rgbRed = pent[i].peRed;
1550 rgb[i].rgbGreen = pent[i].peGreen;
1556 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1559 &(This->s.bitmap_data),
1562 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1563 TRACE(ddraw, "DIBSection at : %p\n", This->s.bitmap_data);
1565 /* b_info is not useful anymore */
1566 HeapFree(GetProcessHeap(), 0, b_info);
1569 This->s.hdc = CreateCompatibleDC(0);
1570 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1573 /* Copy our surface in the DIB section */
1574 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch) {
1575 memcpy(This->s.bitmap_data, desc.y.lpSurface, desc.lPitch * desc.dwHeight);
1578 FIXME(ddraw, "This case has to be done :/\n");
1581 TRACE(ddraw, "HDC : %08lx\n", (DWORD) This->s.hdc);
1582 *lphdc = This->s.hdc;
1587 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1588 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1590 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1592 TRACE(ddraw, "Copying DIBSection at : %p\n", This->s.bitmap_data);
1594 /* Copy the DIB section to our surface */
1595 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1596 memcpy(This->s.surface_desc.y.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1599 FIXME(ddraw, "This case has to be done :/\n");
1602 /* Unlock the surface */
1603 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.y.lpSurface);
1609 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1610 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1613 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1614 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
1616 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1617 * the same interface. And IUnknown does that too of course.
1619 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1620 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1621 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1622 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1623 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1626 IDirectDrawSurface4_AddRef(iface);
1628 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1632 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1634 /* Texture interface */
1635 *obj = d3dtexture2_create(This);
1636 IDirectDrawSurface4_AddRef(iface);
1638 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1642 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1644 /* Texture interface */
1645 *obj = d3dtexture_create(This);
1646 IDirectDrawSurface4_AddRef(iface);
1648 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1652 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj))
1654 /* It is the OpenGL Direct3D Device */
1655 IDirectDrawSurface4_AddRef(iface);
1657 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1662 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
1663 return OLE_E_ENUM_NOMORE;
1666 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1667 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1668 TRACE(ddraw,"(%p)->(), stub!\n",This);
1669 return DD_OK; /* hmm */
1672 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1673 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1674 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,context,esfcb);
1676 /* For the moment, only enumerating the back buffer */
1677 if (This->s.backbuffer != NULL) {
1678 TRACE(ddraw, "Enumerating back-buffer (%p)\n", This->s.backbuffer);
1679 if (esfcb((LPDIRECTDRAWSURFACE) This->s.backbuffer, &(This->s.backbuffer->s.surface_desc), context) == DDENUMRET_CANCEL)
1686 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1687 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1688 FIXME(ddraw,"(%p)->(),stub!\n",This);
1692 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1693 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1695 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1696 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1697 if (TRACE_ON(ddraw)) {
1698 _dump_colorkeyflag(dwFlags);
1700 _dump_DDCOLORKEY((void *) ckey);
1704 /* If this surface was loaded as a texture, call also the texture
1705 SetColorKey callback */
1706 if (This->s.texture) {
1707 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1710 if( dwFlags & DDCKEY_SRCBLT )
1712 dwFlags &= ~DDCKEY_SRCBLT;
1713 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1714 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1717 if( dwFlags & DDCKEY_DESTBLT )
1719 dwFlags &= ~DDCKEY_DESTBLT;
1720 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1721 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1724 if( dwFlags & DDCKEY_SRCOVERLAY )
1726 dwFlags &= ~DDCKEY_SRCOVERLAY;
1727 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1728 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1731 if( dwFlags & DDCKEY_DESTOVERLAY )
1733 dwFlags &= ~DDCKEY_DESTOVERLAY;
1734 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1735 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1740 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1747 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1748 LPDIRECTDRAWSURFACE4 iface,
1751 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1752 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpRect);
1757 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1758 LPDIRECTDRAWSURFACE4 iface,
1760 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1762 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1763 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",This,dwFlags,lpDDSAttachedSurface);
1768 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1769 LPDIRECTDRAWSURFACE4 iface,
1772 LPDDENUMSURFACESCALLBACK lpfnCallback )
1774 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1775 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1776 lpContext, lpfnCallback );
1781 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1782 LPDIRECTDRAWSURFACE4 iface,
1783 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1785 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1786 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDClipper);
1791 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1792 LPDIRECTDRAWSURFACE4 iface,
1794 LPDDCOLORKEY lpDDColorKey )
1796 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1797 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1799 if( dwFlags & DDCKEY_SRCBLT ) {
1800 dwFlags &= ~DDCKEY_SRCBLT;
1801 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1804 if( dwFlags & DDCKEY_DESTBLT )
1806 dwFlags &= ~DDCKEY_DESTBLT;
1807 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1810 if( dwFlags & DDCKEY_SRCOVERLAY )
1812 dwFlags &= ~DDCKEY_SRCOVERLAY;
1813 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1816 if( dwFlags & DDCKEY_DESTOVERLAY )
1818 dwFlags &= ~DDCKEY_DESTOVERLAY;
1819 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1824 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1830 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1831 LPDIRECTDRAWSURFACE4 iface,
1834 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1835 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1840 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1841 LPDIRECTDRAWSURFACE4 iface,
1842 LPDIRECTDRAWPALETTE* lplpDDPalette )
1844 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1845 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDPalette);
1850 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1851 LPDIRECTDRAWSURFACE4 iface,
1855 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1856 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1861 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1862 LPDIRECTDRAWSURFACE4 iface,
1864 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1867 LPDDOVERLAYFX lpDDOverlayFx )
1869 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1870 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1871 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1876 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1877 LPDIRECTDRAWSURFACE4 iface,
1880 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1881 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1886 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1887 LPDIRECTDRAWSURFACE4 iface,
1889 LPDIRECTDRAWSURFACE4 lpDDSReference )
1891 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1892 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1897 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1898 LPDIRECTDRAWSURFACE4 iface,
1901 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1902 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDD);
1904 /* Not sure about that... */
1905 *lplpDD = (void *) This->s.ddraw;
1910 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1911 LPDIRECTDRAWSURFACE4 iface,
1914 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1915 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1920 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1921 LPDIRECTDRAWSURFACE4 iface,
1924 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1925 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1930 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1931 LPDIRECTDRAWSURFACE4 iface,
1932 LPDDSURFACEDESC lpDDSD,
1935 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1936 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1941 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1946 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1947 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1952 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1955 LPDWORD lpcbBufferSize) {
1956 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1957 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1962 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
1964 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1965 FIXME(ddraw, "(%p)->(%p)\n", This, guidTag);
1970 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
1972 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1973 FIXME(ddraw, "(%p)->(%p)\n", This, lpValue);
1978 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
1979 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1980 FIXME(ddraw, "(%p)\n", This);
1985 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
1987 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1988 IDirectDrawSurface4Impl_QueryInterface,
1989 IDirectDrawSurface4Impl_AddRef,
1990 DGA_IDirectDrawSurface4Impl_Release,
1991 IDirectDrawSurface4Impl_AddAttachedSurface,
1992 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1993 IDirectDrawSurface4Impl_Blt,
1994 IDirectDrawSurface4Impl_BltBatch,
1995 IDirectDrawSurface4Impl_BltFast,
1996 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1997 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1998 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1999 DGA_IDirectDrawSurface4Impl_Flip,
2000 IDirectDrawSurface4Impl_GetAttachedSurface,
2001 IDirectDrawSurface4Impl_GetBltStatus,
2002 IDirectDrawSurface4Impl_GetCaps,
2003 IDirectDrawSurface4Impl_GetClipper,
2004 IDirectDrawSurface4Impl_GetColorKey,
2005 IDirectDrawSurface4Impl_GetDC,
2006 IDirectDrawSurface4Impl_GetFlipStatus,
2007 IDirectDrawSurface4Impl_GetOverlayPosition,
2008 IDirectDrawSurface4Impl_GetPalette,
2009 IDirectDrawSurface4Impl_GetPixelFormat,
2010 IDirectDrawSurface4Impl_GetSurfaceDesc,
2011 IDirectDrawSurface4Impl_Initialize,
2012 IDirectDrawSurface4Impl_IsLost,
2013 IDirectDrawSurface4Impl_Lock,
2014 IDirectDrawSurface4Impl_ReleaseDC,
2015 IDirectDrawSurface4Impl_Restore,
2016 IDirectDrawSurface4Impl_SetClipper,
2017 IDirectDrawSurface4Impl_SetColorKey,
2018 IDirectDrawSurface4Impl_SetOverlayPosition,
2019 DGA_IDirectDrawSurface4Impl_SetPalette,
2020 DGA_IDirectDrawSurface4Impl_Unlock,
2021 IDirectDrawSurface4Impl_UpdateOverlay,
2022 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2023 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2024 IDirectDrawSurface4Impl_GetDDInterface,
2025 IDirectDrawSurface4Impl_PageLock,
2026 IDirectDrawSurface4Impl_PageUnlock,
2027 IDirectDrawSurface4Impl_SetSurfaceDesc,
2028 IDirectDrawSurface4Impl_SetPrivateData,
2029 IDirectDrawSurface4Impl_GetPrivateData,
2030 IDirectDrawSurface4Impl_FreePrivateData,
2031 IDirectDrawSurface4Impl_GetUniquenessValue,
2032 IDirectDrawSurface4Impl_ChangeUniquenessValue
2035 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2037 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2038 IDirectDrawSurface4Impl_QueryInterface,
2039 IDirectDrawSurface4Impl_AddRef,
2040 Xlib_IDirectDrawSurface4Impl_Release,
2041 IDirectDrawSurface4Impl_AddAttachedSurface,
2042 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2043 IDirectDrawSurface4Impl_Blt,
2044 IDirectDrawSurface4Impl_BltBatch,
2045 IDirectDrawSurface4Impl_BltFast,
2046 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2047 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2048 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2049 Xlib_IDirectDrawSurface4Impl_Flip,
2050 IDirectDrawSurface4Impl_GetAttachedSurface,
2051 IDirectDrawSurface4Impl_GetBltStatus,
2052 IDirectDrawSurface4Impl_GetCaps,
2053 IDirectDrawSurface4Impl_GetClipper,
2054 IDirectDrawSurface4Impl_GetColorKey,
2055 IDirectDrawSurface4Impl_GetDC,
2056 IDirectDrawSurface4Impl_GetFlipStatus,
2057 IDirectDrawSurface4Impl_GetOverlayPosition,
2058 IDirectDrawSurface4Impl_GetPalette,
2059 IDirectDrawSurface4Impl_GetPixelFormat,
2060 IDirectDrawSurface4Impl_GetSurfaceDesc,
2061 IDirectDrawSurface4Impl_Initialize,
2062 IDirectDrawSurface4Impl_IsLost,
2063 IDirectDrawSurface4Impl_Lock,
2064 IDirectDrawSurface4Impl_ReleaseDC,
2065 IDirectDrawSurface4Impl_Restore,
2066 IDirectDrawSurface4Impl_SetClipper,
2067 IDirectDrawSurface4Impl_SetColorKey,
2068 IDirectDrawSurface4Impl_SetOverlayPosition,
2069 Xlib_IDirectDrawSurface4Impl_SetPalette,
2070 Xlib_IDirectDrawSurface4Impl_Unlock,
2071 IDirectDrawSurface4Impl_UpdateOverlay,
2072 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2073 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2074 IDirectDrawSurface4Impl_GetDDInterface,
2075 IDirectDrawSurface4Impl_PageLock,
2076 IDirectDrawSurface4Impl_PageUnlock,
2077 IDirectDrawSurface4Impl_SetSurfaceDesc,
2078 IDirectDrawSurface4Impl_SetPrivateData,
2079 IDirectDrawSurface4Impl_GetPrivateData,
2080 IDirectDrawSurface4Impl_FreePrivateData,
2081 IDirectDrawSurface4Impl_GetUniquenessValue,
2082 IDirectDrawSurface4Impl_ChangeUniquenessValue
2085 /******************************************************************************
2086 * DirectDrawCreateClipper (DDRAW.7)
2088 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2089 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2090 LPUNKNOWN pUnkOuter)
2092 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2093 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2095 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2096 (*ilplpDDClipper)->lpvtbl = &ddclipvt;
2097 (*ilplpDDClipper)->ref = 1;
2102 /******************************************************************************
2103 * IDirectDrawClipper
2105 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2106 LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
2108 ICOM_THIS(IDirectDrawClipperImpl,iface);
2109 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
2113 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2114 ICOM_THIS(IDirectDrawClipperImpl,iface);
2115 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2120 HeapFree(GetProcessHeap(),0,This);
2124 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2125 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2127 ICOM_THIS(IDirectDrawClipperImpl,iface);
2128 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2133 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2134 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2136 ICOM_THIS(IDirectDrawClipperImpl,iface);
2137 FIXME(ddraw,"(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2141 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2142 LPDIRECTDRAWCLIPPER iface,
2146 ICOM_THIS(IDirectDrawClipperImpl,iface);
2147 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2148 return OLE_E_ENUM_NOMORE;
2151 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2153 ICOM_THIS(IDirectDrawClipperImpl,iface);
2154 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2155 return ++(This->ref);
2158 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2159 LPDIRECTDRAWCLIPPER iface,
2162 ICOM_THIS(IDirectDrawClipperImpl,iface);
2163 FIXME(ddraw,"(%p)->(%p),stub!\n",This,HWndPtr);
2167 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2168 LPDIRECTDRAWCLIPPER iface,
2172 ICOM_THIS(IDirectDrawClipperImpl,iface);
2173 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2177 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2178 LPDIRECTDRAWCLIPPER iface,
2181 ICOM_THIS(IDirectDrawClipperImpl,iface);
2182 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpbChanged);
2186 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2188 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2189 IDirectDrawClipperImpl_QueryInterface,
2190 IDirectDrawClipperImpl_AddRef,
2191 IDirectDrawClipperImpl_Release,
2192 IDirectDrawClipperImpl_GetClipList,
2193 IDirectDrawClipperImpl_GetHWnd,
2194 IDirectDrawClipperImpl_Initialize,
2195 IDirectDrawClipperImpl_IsClipListChanged,
2196 IDirectDrawClipperImpl_SetClipList,
2197 IDirectDrawClipperImpl_SetHwnd
2201 /******************************************************************************
2202 * IDirectDrawPalette
2204 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2205 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2207 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2210 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2211 This,x,start,count,palent);
2213 /* No palette created and not in depth-convertion mode -> BUG ! */
2214 if ((This->cm == None) &&
2215 (This->ddraw->d.palette_convert == NULL))
2217 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
2218 return DDERR_GENERIC;
2220 for (i=0;i<count;i++) {
2221 palent[i].peRed = This->palents[start+i].peRed;
2222 palent[i].peBlue = This->palents[start+i].peBlue;
2223 palent[i].peGreen = This->palents[start+i].peGreen;
2224 palent[i].peFlags = This->palents[start+i].peFlags;
2230 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2231 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2233 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2237 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2238 This,x,start,count,palent
2240 for (i=0;i<count;i++) {
2241 xc.red = palent[i].peRed<<8;
2242 xc.blue = palent[i].peBlue<<8;
2243 xc.green = palent[i].peGreen<<8;
2244 xc.flags = DoRed|DoBlue|DoGreen;
2248 TSXStoreColor(display,This->cm,&xc);
2250 This->palents[start+i].peRed = palent[i].peRed;
2251 This->palents[start+i].peBlue = palent[i].peBlue;
2252 This->palents[start+i].peGreen = palent[i].peGreen;
2253 This->palents[start+i].peFlags = palent[i].peFlags;
2256 /* Now, if we are in 'depth conversion mode', update the screen palette */
2257 /* FIXME: we need to update the image or we won't get palette fading. */
2258 if (This->ddraw->d.palette_convert != NULL)
2259 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2264 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2265 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2267 #ifdef HAVE_LIBXXF86DGA
2268 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2273 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2274 This,x,start,count,palent
2276 if (!This->cm) /* should not happen */ {
2277 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
2278 return DDERR_GENERIC;
2280 /* FIXME: free colorcells instead of freeing whole map */
2282 This->cm = TSXCopyColormapAndFree(display,This->cm);
2283 TSXFreeColormap(display,cm);
2285 for (i=0;i<count;i++) {
2286 xc.red = palent[i].peRed<<8;
2287 xc.blue = palent[i].peBlue<<8;
2288 xc.green = palent[i].peGreen<<8;
2289 xc.flags = DoRed|DoBlue|DoGreen;
2292 TSXStoreColor(display,This->cm,&xc);
2294 This->palents[start+i].peRed = palent[i].peRed;
2295 This->palents[start+i].peBlue = palent[i].peBlue;
2296 This->palents[start+i].peGreen = palent[i].peGreen;
2297 This->palents[start+i].peFlags = palent[i].peFlags;
2299 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2301 #else /* defined(HAVE_LIBXXF86DGA) */
2302 return E_UNEXPECTED;
2303 #endif /* defined(HAVE_LIBXXF86DGA) */
2306 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2307 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2308 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2309 if (!--(This->ref)) {
2311 TSXFreeColormap(display,This->cm);
2314 HeapFree(GetProcessHeap(),0,This);
2320 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2321 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2323 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2324 return ++(This->ref);
2327 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2328 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2330 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2331 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2333 return DDERR_ALREADYINITIALIZED;
2336 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2337 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2339 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2340 FIXME( ddraw, "(%p)->(%p) stub.\n", This, lpdwCaps );
2344 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2345 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2347 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2350 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2351 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2356 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2358 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2359 IDirectDrawPaletteImpl_QueryInterface,
2360 IDirectDrawPaletteImpl_AddRef,
2361 IDirectDrawPaletteImpl_Release,
2362 IDirectDrawPaletteImpl_GetCaps,
2363 IDirectDrawPaletteImpl_GetEntries,
2364 IDirectDrawPaletteImpl_Initialize,
2365 DGA_IDirectDrawPaletteImpl_SetEntries
2368 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2370 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2371 IDirectDrawPaletteImpl_QueryInterface,
2372 IDirectDrawPaletteImpl_AddRef,
2373 IDirectDrawPaletteImpl_Release,
2374 IDirectDrawPaletteImpl_GetCaps,
2375 IDirectDrawPaletteImpl_GetEntries,
2376 IDirectDrawPaletteImpl_Initialize,
2377 Xlib_IDirectDrawPaletteImpl_SetEntries
2380 /*******************************************************************************
2383 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2384 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2386 ICOM_THIS(IDirect3DImpl,iface);
2387 /* FIXME: Not sure if this is correct */
2390 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2391 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2392 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2393 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2394 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2396 IDirect3D_AddRef(iface);
2398 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2402 if ((!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) ||
2403 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2405 IDirect3D_AddRef(iface);
2407 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2411 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
2412 IDirect3D2Impl* d3d;
2414 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2416 d3d->ddraw = This->ddraw;
2417 IDirect3D_AddRef(iface);
2418 d3d->lpvtbl = &d3d2vt;
2421 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2425 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2426 return OLE_E_ENUM_NOMORE;
2429 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2430 ICOM_THIS(IDirect3DImpl,iface);
2431 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2433 return ++(This->ref);
2436 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2438 ICOM_THIS(IDirect3DImpl,iface);
2439 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2441 if (!--(This->ref)) {
2442 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2443 HeapFree(GetProcessHeap(),0,This);
2449 static HRESULT WINAPI IDirect3DImpl_Initialize(
2450 LPDIRECT3D iface, REFIID refiid )
2452 ICOM_THIS(IDirect3DImpl,iface);
2453 /* FIXME: Not sure if this is correct */
2456 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2457 FIXME(ddraw,"(%p)->(%s):stub.\n",This,xrefiid);
2459 return DDERR_ALREADYINITIALIZED;
2462 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2463 LPD3DENUMDEVICESCALLBACK cb,
2465 ICOM_THIS(IDirect3DImpl,iface);
2466 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2468 /* Call functions defined in d3ddevices.c */
2469 if (!d3d_OpenGL_dx3(cb, context))
2475 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2476 LPDIRECT3DLIGHT *lplight,
2479 ICOM_THIS(IDirect3DImpl,iface);
2480 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2482 /* Call the creation function that is located in d3dlight.c */
2483 *lplight = d3dlight_create_dx3(This);
2488 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2489 LPDIRECT3DMATERIAL *lpmaterial,
2492 ICOM_THIS(IDirect3DImpl,iface);
2493 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2495 /* Call the creation function that is located in d3dviewport.c */
2496 *lpmaterial = d3dmaterial_create(This);
2501 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2502 LPDIRECT3DVIEWPORT *lpviewport,
2505 ICOM_THIS(IDirect3DImpl,iface);
2506 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2508 /* Call the creation function that is located in d3dviewport.c */
2509 *lpviewport = d3dviewport_create(This);
2514 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2515 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2516 LPD3DFINDDEVICERESULT lpfinddevrst)
2518 ICOM_THIS(IDirect3DImpl,iface);
2519 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2524 static ICOM_VTABLE(IDirect3D) d3dvt =
2526 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2527 IDirect3DImpl_QueryInterface,
2528 IDirect3DImpl_AddRef,
2529 IDirect3DImpl_Release,
2530 IDirect3DImpl_Initialize,
2531 IDirect3DImpl_EnumDevices,
2532 IDirect3DImpl_CreateLight,
2533 IDirect3DImpl_CreateMaterial,
2534 IDirect3DImpl_CreateViewport,
2535 IDirect3DImpl_FindDevice
2538 /*******************************************************************************
2541 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2542 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2543 ICOM_THIS(IDirect3D2Impl,iface);
2545 /* FIXME: Not sure if this is correct */
2548 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2549 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2550 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2551 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2552 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2554 IDirect3D2_AddRef(iface);
2556 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2560 if ((!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) ||
2561 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2563 IDirect3D2_AddRef(iface);
2565 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2569 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2572 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2574 d3d->ddraw = This->ddraw;
2575 IDirect3D2_AddRef(iface);
2576 d3d->lpvtbl = &d3dvt;
2579 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2583 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2584 return OLE_E_ENUM_NOMORE;
2587 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2588 ICOM_THIS(IDirect3D2Impl,iface);
2589 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2591 return ++(This->ref);
2594 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2595 ICOM_THIS(IDirect3D2Impl,iface);
2596 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2598 if (!--(This->ref)) {
2599 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2600 HeapFree(GetProcessHeap(),0,This);
2606 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2607 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2609 ICOM_THIS(IDirect3D2Impl,iface);
2610 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2612 /* Call functions defined in d3ddevices.c */
2613 if (!d3d_OpenGL(cb, context))
2619 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2620 LPDIRECT3DLIGHT *lplight,
2623 ICOM_THIS(IDirect3D2Impl,iface);
2624 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2626 /* Call the creation function that is located in d3dlight.c */
2627 *lplight = d3dlight_create(This);
2632 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2633 LPDIRECT3DMATERIAL2 *lpmaterial,
2636 ICOM_THIS(IDirect3D2Impl,iface);
2637 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2639 /* Call the creation function that is located in d3dviewport.c */
2640 *lpmaterial = d3dmaterial2_create(This);
2645 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2646 LPDIRECT3DVIEWPORT2 *lpviewport,
2649 ICOM_THIS(IDirect3D2Impl,iface);
2650 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2652 /* Call the creation function that is located in d3dviewport.c */
2653 *lpviewport = d3dviewport2_create(This);
2658 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2659 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2660 LPD3DFINDDEVICERESULT lpfinddevrst)
2662 ICOM_THIS(IDirect3D2Impl,iface);
2663 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2668 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2670 LPDIRECTDRAWSURFACE surface,
2671 LPDIRECT3DDEVICE2 *device)
2673 ICOM_THIS(IDirect3D2Impl,iface);
2676 WINE_StringFromCLSID(rguid,xbuf);
2677 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2679 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2680 IDirect3D2_AddRef(iface);
2684 return DDERR_INVALIDPARAMS;
2687 static ICOM_VTABLE(IDirect3D2) d3d2vt =
2689 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2690 IDirect3D2Impl_QueryInterface,
2691 IDirect3D2Impl_AddRef,
2692 IDirect3D2Impl_Release,
2693 IDirect3D2Impl_EnumDevices,
2694 IDirect3D2Impl_CreateLight,
2695 IDirect3D2Impl_CreateMaterial,
2696 IDirect3D2Impl_CreateViewport,
2697 IDirect3D2Impl_FindDevice,
2698 IDirect3D2Impl_CreateDevice
2701 /*******************************************************************************
2705 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2706 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2708 static INT ddrawXlibThisOffset = 0;
2710 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2711 IDirectDrawSurfaceImpl* lpdsf)
2715 /* The surface was already allocated when entering in this function */
2716 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2718 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
2719 /* This is a Z Buffer */
2720 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.x.dwZBufferBitDepth);
2721 bpp = lpdsf->s.surface_desc.x.dwZBufferBitDepth / 8;
2723 /* This is a standard image */
2724 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
2725 /* No pixel format => use DirectDraw's format */
2726 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2727 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
2730 bpp = GET_BPP(lpdsf->s.surface_desc);
2733 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
2734 /* The surface was preallocated : seems that we have nothing to do :-) */
2735 WARN(ddraw, "Creates a surface that is already allocated : assuming this is an application bug !\n");
2738 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
2739 lpdsf->s.surface_desc.y.lpSurface =
2740 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
2741 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
2746 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2747 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2749 #ifdef HAVE_LIBXXF86DGA
2750 ICOM_THIS(IDirectDraw2Impl,iface);
2751 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2754 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2755 if (TRACE_ON(ddraw)) {
2756 _dump_surface_desc(lpddsd);
2759 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2760 IDirectDraw2_AddRef(iface);
2763 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2764 (*ilpdsf)->s.ddraw = This;
2765 (*ilpdsf)->s.palette = NULL;
2766 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2768 /* Copy the surface description */
2769 (*ilpdsf)->s.surface_desc = *lpddsd;
2771 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2772 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2773 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2774 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2775 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
2777 /* Check if this a 'primary surface' or not */
2778 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2779 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2781 /* This is THE primary surface => there is DGA-specific code */
2782 /* First, store the surface description */
2783 (*ilpdsf)->s.surface_desc = *lpddsd;
2785 /* Find a viewport */
2787 if (!(This->e.dga.vpmask & (1<<i)))
2789 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2790 /* if i == 32 or maximum ... return error */
2791 This->e.dga.vpmask|=(1<<i);
2792 (*ilpdsf)->s.surface_desc.y.lpSurface =
2793 This->e.dga.fb_addr+((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2794 (*ilpdsf)->t.dga.fb_height = i*This->e.dga.fb_height;
2795 (*ilpdsf)->s.surface_desc.lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
2796 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch;
2798 /* Add flags if there were not present */
2799 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2800 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2801 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2802 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2803 /* We put our surface always in video memory */
2804 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2805 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2806 (*ilpdsf)->s.backbuffer = NULL;
2808 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2809 IDirectDrawSurface4Impl* back;
2811 if (lpddsd->dwBackBufferCount>1)
2812 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2814 (*ilpdsf)->s.backbuffer = back =
2815 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2816 IDirectDraw2_AddRef(iface);
2818 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2820 if (!(This->e.dga.vpmask & (1<<i)))
2822 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2823 /* if i == 32 or maximum ... return error */
2824 This->e.dga.vpmask|=(1<<i);
2825 back->t.dga.fb_height = i*This->e.dga.fb_height;
2827 /* Copy the surface description from the front buffer */
2828 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2829 /* Change the parameters that are not the same */
2830 back->s.surface_desc.y.lpSurface = This->e.dga.fb_addr+
2831 ((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2832 back->s.ddraw = This;
2833 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2836 /* Add relevant info to front and back buffers */
2837 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2838 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2839 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2840 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2841 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2844 /* There is no DGA-specific code here...
2845 Go to the common surface creation function */
2846 return common_off_screen_CreateSurface(This, *ilpdsf);
2850 #else /* defined(HAVE_LIBXXF86DGA) */
2851 return E_UNEXPECTED;
2852 #endif /* defined(HAVE_LIBXXF86DGA) */
2855 #ifdef HAVE_LIBXXSHM
2856 /* Error handlers for Image creation */
2857 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2862 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2864 int (*WineXHandler)(Display *, XErrorEvent *);
2866 img = TSXShmCreateImage(display,
2867 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2868 This->d.pixmap_depth,
2871 &(lpdsf->t.xlib.shminfo),
2872 lpdsf->s.surface_desc.dwWidth,
2873 lpdsf->s.surface_desc.dwHeight);
2876 MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2877 This->e.xlib.xshm_active = 0;
2881 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2882 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2883 MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2884 This->e.xlib.xshm_active = 0;
2885 TSXDestroyImage(img);
2889 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2891 if (img->data == (char *) -1) {
2892 MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2893 This->e.xlib.xshm_active = 0;
2894 TSXDestroyImage(img);
2895 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2898 lpdsf->t.xlib.shminfo.readOnly = False;
2900 /* This is where things start to get trickier....
2901 First, we flush the current X connections to be sure to catch all non-XShm related
2903 TSXSync(display, False);
2904 /* Then we enter in the non-thread safe part of the tests */
2905 EnterCriticalSection( &X11DRV_CritSection );
2907 /* Reset the error flag, sets our new error handler and try to attach the surface */
2909 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2910 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2911 XSync(display, False);
2913 /* Check the error flag */
2914 if (XShmErrorFlag) {
2915 /* An error occured */
2919 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2920 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2921 XSetErrorHandler(WineXHandler);
2923 MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
2924 This->e.xlib.xshm_active = 0;
2926 /* Leave the critical section */
2927 LeaveCriticalSection( &X11DRV_CritSection );
2932 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2933 but it may be a bit overkill.... */
2934 XSetErrorHandler(WineXHandler);
2935 LeaveCriticalSection( &X11DRV_CritSection );
2937 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2939 if (This->d.pixel_convert != NULL) {
2940 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2941 lpdsf->s.surface_desc.dwWidth *
2942 lpdsf->s.surface_desc.dwHeight *
2943 (This->d.directdraw_pixelformat.x.dwRGBBitCount));
2945 lpdsf->s.surface_desc.y.lpSurface = img->data;
2950 #endif /* HAVE_LIBXXSHM */
2952 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2956 #ifdef HAVE_LIBXXSHM
2957 if (This->e.xlib.xshm_active) {
2958 img = create_xshmimage(This, lpdsf);
2963 /* Allocate surface memory */
2964 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2965 lpdsf->s.surface_desc.dwWidth *
2966 lpdsf->s.surface_desc.dwHeight *
2967 (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8));
2969 if (This->d.pixel_convert != NULL) {
2970 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2971 lpdsf->s.surface_desc.dwWidth *
2972 lpdsf->s.surface_desc.dwHeight *
2973 (This->d.screen_pixelformat.x.dwRGBBitCount / 8));
2975 img_data = lpdsf->s.surface_desc.y.lpSurface;
2978 /* In this case, create an XImage */
2980 TSXCreateImage(display,
2981 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2982 This->d.pixmap_depth,
2986 lpdsf->s.surface_desc.dwWidth,
2987 lpdsf->s.surface_desc.dwHeight,
2989 lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
2992 #ifdef HAVE_LIBXXSHM
2995 if (This->d.pixel_convert != NULL) {
2996 lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
2998 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3004 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3005 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3007 ICOM_THIS(IDirectDraw2Impl,iface);
3008 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3009 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
3010 This,lpddsd,ilpdsf,lpunk);
3012 if (TRACE_ON(ddraw)) {
3013 _dump_surface_desc(lpddsd);
3016 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
3018 IDirectDraw2_AddRef(iface);
3019 (*ilpdsf)->s.ddraw = This;
3021 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3022 (*ilpdsf)->s.palette = NULL;
3023 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3025 /* Copy the surface description */
3026 (*ilpdsf)->s.surface_desc = *lpddsd;
3028 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3029 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3030 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3031 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3032 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3034 /* Check if this a 'primary surface' or not */
3035 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3036 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3039 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *ilpdsf);
3041 /* Create the XImage */
3042 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3044 return DDERR_OUTOFMEMORY;
3045 (*ilpdsf)->t.xlib.image = img;
3047 /* Add flags if there were not present */
3048 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3049 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3050 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3051 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3052 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3053 (*ilpdsf)->s.backbuffer = NULL;
3055 /* Check for backbuffers */
3056 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3057 IDirectDrawSurface4Impl* back;
3060 if (lpddsd->dwBackBufferCount>1)
3061 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
3063 (*ilpdsf)->s.backbuffer = back =
3064 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
3066 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
3068 IDirectDraw2_AddRef(iface);
3069 back->s.ddraw = This;
3072 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3073 /* Copy the surface description from the front buffer */
3074 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3076 /* Create the XImage */
3077 img = create_ximage(This, back);
3079 return DDERR_OUTOFMEMORY;
3080 back->t.xlib.image = img;
3082 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
3085 /* Add relevant info to front and back buffers */
3086 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
3087 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
3088 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3089 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
3090 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
3093 /* There is no Xlib-specific code here...
3094 Go to the common surface creation function */
3095 return common_off_screen_CreateSurface(This, *ilpdsf);
3101 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3102 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3104 ICOM_THIS(IDirectDraw2Impl,iface);
3105 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",This,src,dst);
3106 *dst = src; /* FIXME */
3111 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3112 * even when the approbiate bitmasks are not specified.
3114 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3115 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3117 ICOM_THIS(IDirectDraw2Impl,iface);
3123 #define FE(x) { x, #x},
3124 FE(DDSCL_FULLSCREEN)
3125 FE(DDSCL_ALLOWREBOOT)
3126 FE(DDSCL_NOWINDOWCHANGES)
3128 FE(DDSCL_ALLOWMODEX)
3130 FE(DDSCL_SETFOCUSWINDOW)
3131 FE(DDSCL_SETDEVICEWINDOW)
3132 FE(DDSCL_CREATEDEVICEWINDOW)
3136 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3137 if(TRACE_ON(ddraw)){
3138 dbg_decl_str(ddraw, 512);
3139 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
3140 if (flagmap[i].mask & cooplevel)
3141 dsprintf(ddraw, "%s ", flagmap[i].name);
3142 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
3144 This->d.mainWindow = hwnd;
3146 /* This will be overwritten in the case of Full Screen mode.
3147 Windowed games could work with that :-) */
3150 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3151 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3152 WIN_ReleaseWndPtr(tmpWnd);
3154 if( !This->d.drawable ) {
3155 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3156 WIN_ReleaseDesktop();
3158 TRACE(ddraw, "Setting drawable to %ld\n", This->d.drawable);
3164 /* Small helper to either use the cooperative window or create a new
3165 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3167 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3170 /* Do not destroy the application supplied cooperative window */
3171 if (This->d.window && This->d.window != This->d.mainWindow) {
3172 DestroyWindow(This->d.window);
3175 /* Sanity check cooperative window before assigning it to drawing. */
3176 if ( IsWindow(This->d.mainWindow) &&
3177 IsWindowVisible(This->d.mainWindow)
3179 GetWindowRect(This->d.mainWindow,&rect);
3180 if (((rect.right-rect.left) >= This->d.width) &&
3181 ((rect.bottom-rect.top) >= This->d.height)
3183 This->d.window = This->d.mainWindow;
3185 /* ... failed, create new one. */
3186 if (!This->d.window) {
3187 This->d.window = CreateWindowExA(
3191 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3200 /*Store THIS with the window. We'll use it in the window procedure*/
3201 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3202 ShowWindow(This->d.window,TRUE);
3203 UpdateWindow(This->d.window);
3205 SetFocus(This->d.window);
3208 static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
3210 XPixmapFormatValues *pf;
3212 int nvisuals, npixmap, i;
3215 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3216 pf = XListPixmapFormats(display, &npixmap);
3218 for (i = 0; i < npixmap; i++) {
3219 if (pf[i].bits_per_pixel == depth) {
3222 for (j = 0; j < nvisuals; j++) {
3223 if (vi[j].depth == pf[i].depth) {
3224 pixelformat->dwSize = sizeof(*pixelformat);
3226 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3227 pixelformat->y.dwRBitMask = 0;
3228 pixelformat->z.dwGBitMask = 0;
3229 pixelformat->xx.dwBBitMask = 0;
3231 pixelformat->dwFlags = DDPF_RGB;
3232 pixelformat->y.dwRBitMask = vi[j].red_mask;
3233 pixelformat->z.dwGBitMask = vi[j].green_mask;
3234 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3236 pixelformat->dwFourCC = 0;
3237 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3238 pixelformat->xy.dwRGBAlphaBitMask= 0;
3240 *screen_pixelformat = *pixelformat;
3242 if (pix_depth != NULL)
3243 *pix_depth = vi[j].depth;
3252 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3256 if ((match == 0) && (depth == 8)) {
3257 pixelformat->dwSize = sizeof(*pixelformat);
3258 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3259 pixelformat->dwFourCC = 0;
3260 pixelformat->x.dwRGBBitCount = 8;
3261 pixelformat->y.dwRBitMask = 0;
3262 pixelformat->z.dwGBitMask = 0;
3263 pixelformat->xx.dwBBitMask = 0;
3264 pixelformat->xy.dwRGBAlphaBitMask= 0;
3266 /* In that case, find a visual to emulate the 8 bpp format */
3267 for (i = 0; i < npixmap; i++) {
3268 if (pf[i].bits_per_pixel >= depth) {
3271 for (j = 0; j < nvisuals; j++) {
3272 if (vi[j].depth == pf[i].depth) {
3273 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3274 screen_pixelformat->dwFlags = DDPF_RGB;
3275 screen_pixelformat->dwFourCC = 0;
3276 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3277 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
3278 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
3279 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3280 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
3282 if (pix_depth != NULL)
3283 *pix_depth = vi[j].depth;
3292 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3303 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3304 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3306 #ifdef HAVE_LIBXXF86DGA
3307 ICOM_THIS(IDirectDrawImpl,iface);
3310 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3312 /* We hope getting the asked for depth */
3313 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != 1) {
3314 /* I.e. no visual found or emulated */
3315 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3316 return DDERR_UNSUPPORTEDMODE;
3319 if (This->d.width < width) {
3320 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3321 return DDERR_UNSUPPORTEDMODE;
3323 This->d.width = width;
3324 This->d.height = height;
3326 /* adjust fb_height, so we don't overlap */
3327 if (This->e.dga.fb_height < height)
3328 This->e.dga.fb_height = height;
3329 _common_IDirectDrawImpl_SetDisplayMode(This);
3331 #ifdef HAVE_LIBXXF86VM
3333 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3334 XF86VidModeModeLine mod_tmp;
3335 /* int dotclock_tmp; */
3337 /* save original video mode and set fullscreen if available*/
3338 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3339 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3340 orig_mode->hdisplay = mod_tmp.hdisplay;
3341 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3342 orig_mode->hsyncend = mod_tmp.hsyncend;
3343 orig_mode->htotal = mod_tmp.htotal;
3344 orig_mode->vdisplay = mod_tmp.vdisplay;
3345 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3346 orig_mode->vsyncend = mod_tmp.vsyncend;
3347 orig_mode->vtotal = mod_tmp.vtotal;
3348 orig_mode->flags = mod_tmp.flags;
3349 orig_mode->private = mod_tmp.private;
3351 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3352 for (i=0;i<mode_count;i++)
3354 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3356 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3357 *vidmode = *(all_modes[i]);
3360 TSXFree(all_modes[i]->private);
3362 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3366 WARN(ddraw, "Fullscreen mode not available!\n");
3370 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3371 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3372 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3373 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3379 /* FIXME: this function OVERWRITES several signal handlers.
3380 * can we save them? and restore them later? In a way that
3381 * it works for the library too?
3383 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3384 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3386 #ifdef RESTORE_SIGNALS
3390 #else /* defined(HAVE_LIBXXF86DGA) */
3391 return E_UNEXPECTED;
3392 #endif /* defined(HAVE_LIBXXF86DGA) */
3395 /* *************************************
3396 16 / 15 bpp to palettized 8 bpp
3397 ************************************* */
3398 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3399 unsigned char *c_src = (unsigned char *) src;
3400 unsigned short *c_dst = (unsigned short *) dst;
3403 if (palette != NULL) {
3404 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3406 for (y = height; y--; ) {
3408 /* gcc generates slightly inefficient code for the the copy / lookup,
3409 * it generates one excess memory access (to pal) per pixel. Since
3410 * we know that pal is not modified by the memory write we can
3411 * put it into a register and reduce the number of memory accesses
3412 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3413 * (This is not guaranteed to be the fastest method.)
3415 __asm__ __volatile__(
3419 " movw (%%edx,%%eax,2),%%ax\n"
3421 " xor %%eax,%%eax\n"
3423 : "=S" (c_src), "=D" (c_dst)
3424 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3425 : "eax", "cc", "memory"
3427 c_src+=(pitch-width);
3429 unsigned char * srclineend = c_src+width;
3430 while (c_src < srclineend)
3431 *c_dst++ = pal[*c_src++];
3432 c_src+=(pitch-width);
3436 WARN(ddraw, "No palette set...\n");
3437 memset(dst, 0, width * height * 2);
3440 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3442 unsigned short *pal = (unsigned short *) screen_palette;
3444 for (i = 0; i < count; i++)
3445 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3446 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3447 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3449 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3451 unsigned short *pal = (unsigned short *) screen_palette;
3453 for (i = 0; i < count; i++)
3454 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3455 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3456 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3459 /* *************************************
3460 24 to palettized 8 bpp
3461 ************************************* */
3462 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3463 unsigned char *c_src = (unsigned char *) src;
3464 unsigned char *c_dst = (unsigned char *) dst;
3467 if (palette != NULL) {
3468 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3470 for (y = height; y--; ) {
3471 unsigned char * srclineend = c_src+width;
3472 while (c_src < srclineend ) {
3473 register long pixel = pal[*c_src++];
3475 *c_dst++ = pixel>>8;
3476 *c_dst++ = pixel>>16;
3478 c_src+=(pitch-width);
3481 WARN(ddraw, "No palette set...\n");
3482 memset(dst, 0, width * height * 4);
3485 /* *************************************
3486 32 bpp to palettized 8 bpp
3487 ************************************* */
3488 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3489 unsigned char *c_src = (unsigned char *) src;
3490 unsigned int *c_dst = (unsigned int *) dst;
3493 if (palette != NULL) {
3494 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3496 for (y = height; y--; ) {
3498 /* See comment in pixel_convert_16_to_8 */
3499 __asm__ __volatile__(
3503 " movl (%%edx,%%eax,4),%%eax\n"
3505 " xor %%eax,%%eax\n"
3507 : "=S" (c_src), "=D" (c_dst)
3508 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3509 : "eax", "cc", "memory"
3511 c_src+=(pitch-width);
3513 unsigned char * srclineend = c_src+width;
3514 while (c_src < srclineend )
3515 *c_dst++ = pal[*c_src++];
3516 c_src+=(pitch-width);
3520 WARN(ddraw, "No palette set...\n");
3521 memset(dst, 0, width * height * 4);
3525 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3527 unsigned int *pal = (unsigned int *) screen_palette;
3529 for (i = 0; i < count; i++)
3530 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3531 (((unsigned int) palent[i].peGreen) << 8) |
3532 ((unsigned int) palent[i].peBlue));
3535 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3536 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3538 ICOM_THIS(IDirectDrawImpl,iface);
3542 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3543 This, width, height, depth);
3545 switch (_common_depth_to_pixelformat(depth,
3546 &(This->d.directdraw_pixelformat),
3547 &(This->d.screen_pixelformat),
3548 &(This->d.pixmap_depth))) {
3550 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3551 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3552 return DDERR_UNSUPPORTEDMODE;
3556 This->d.pixel_convert = NULL;
3557 This->d.palette_convert = NULL;
3563 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3565 /* Set the depth convertion routines */
3566 switch (This->d.screen_pixelformat.x.dwRGBBitCount) {
3568 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
3569 (This->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
3570 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3574 This->d.pixel_convert = pixel_convert_16_to_8;
3575 This->d.palette_convert = palette_convert_16_to_8;
3576 } else if ((This->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
3577 (This->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
3578 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3582 This->d.pixel_convert = pixel_convert_16_to_8;
3583 This->d.palette_convert = palette_convert_15_to_8;
3588 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) &&
3589 (This->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) &&
3590 (This->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
3593 This->d.pixel_convert = pixel_convert_24_to_8;
3594 This->d.palette_convert = palette_convert_24_to_8;
3599 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) &&
3600 (This->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) &&
3601 (This->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
3605 This->d.pixel_convert = pixel_convert_32_to_8;
3606 This->d.palette_convert = palette_convert_24_to_8;
3612 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3613 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3614 return DDERR_UNSUPPORTEDMODE;
3619 This->d.width = width;
3620 This->d.height = height;
3622 _common_IDirectDrawImpl_SetDisplayMode(This);
3624 tmpWnd = WIN_FindWndPtr(This->d.window);
3625 This->d.paintable = 1;
3626 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3627 WIN_ReleaseWndPtr(tmpWnd);
3629 /* We don't have a context for this window. Host off the desktop */
3630 if( !This->d.drawable )
3632 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3633 WIN_ReleaseDesktop();
3635 TRACE(ddraw, "Setting drawable to %ld\n", This->d.drawable);
3640 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3641 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3643 #ifdef HAVE_LIBXXF86DGA
3644 ICOM_THIS(IDirectDraw2Impl,iface);
3645 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3646 if (!caps1 && !caps2)
3647 return DDERR_INVALIDPARAMS;
3649 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3650 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3651 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3654 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3655 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3656 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3659 #else /* defined(HAVE_LIBXXF86DGA) */
3660 return E_UNEXPECTED;
3661 #endif /* defined(HAVE_LIBXXF86DGA) */
3664 static void fill_caps(LPDDCAPS caps) {
3665 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3666 Need to be fixed, though.. */
3670 caps->dwSize = sizeof(*caps);
3671 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3672 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
3673 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3674 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3676 caps->dwFXAlphaCaps = 0;
3677 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3679 caps->dwZBufferBitDepths = DDBD_16;
3680 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3681 to put textures in video memory.
3682 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3684 caps->dwVidMemTotal = 8192 * 1024;
3685 caps->dwVidMemFree = 8192 * 1024;
3686 /* These are all the supported capabilities of the surfaces */
3687 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3688 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3689 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3690 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3692 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3693 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3694 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3698 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3699 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3701 ICOM_THIS(IDirectDraw2Impl,iface);
3702 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3704 /* Put the same caps for the two capabilities */
3711 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3712 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3714 ICOM_THIS(IDirectDraw2Impl,iface);
3715 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3716 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3717 This,x,ilpddclip,lpunk
3719 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3720 (*ilpddclip)->ref = 1;
3721 (*ilpddclip)->lpvtbl = &ddclipvt;
3725 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3726 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3730 if (TRACE_ON(ddraw))
3731 _dump_paletteformat(dwFlags);
3733 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3734 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3735 (*lpddpal)->ref = 1;
3736 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3737 (*lpddpal)->installed = 0;
3739 if (dwFlags & DDPCAPS_1BIT)
3741 else if (dwFlags & DDPCAPS_2BIT)
3743 else if (dwFlags & DDPCAPS_4BIT)
3745 else if (dwFlags & DDPCAPS_8BIT)
3748 ERR(ddraw, "unhandled palette format\n");
3753 /* Now, if we are in 'depth conversion mode', create the screen palette */
3754 if (This->d.palette_convert != NULL)
3755 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3757 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3758 } else if (This->d.palette_convert != NULL) {
3759 /* In that case, put all 0xFF */
3760 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3766 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3767 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3769 ICOM_THIS(IDirectDraw2Impl,iface);
3770 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3774 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3775 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3776 if (res != 0) return res;
3777 (*ilpddpal)->lpvtbl = &dga_ddpalvt;
3778 if (This->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3779 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3781 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3782 (*ilpddpal)->cm = 0;
3784 if (((*ilpddpal)->cm)&&xsize) {
3785 for (i=0;i<xsize;i++) {
3788 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3789 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3790 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3791 xc.flags = DoRed|DoBlue|DoGreen;
3793 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3799 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3800 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3802 ICOM_THIS(IDirectDraw2Impl,iface);
3803 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3807 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3808 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3809 if (res != 0) return res;
3810 (*ilpddpal)->lpvtbl = &xlib_ddpalvt;
3814 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3815 #ifdef HAVE_LIBXXF86DGA
3816 ICOM_THIS(IDirectDraw2Impl,iface);
3817 TRACE(ddraw, "(%p)->()\n",This);
3819 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3820 #ifdef RESTORE_SIGNALS
3824 #else /* defined(HAVE_LIBXXF86DGA) */
3825 return E_UNEXPECTED;
3829 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3830 ICOM_THIS(IDirectDraw2Impl,iface);
3831 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", This);
3836 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3837 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3839 ICOM_THIS(IDirectDraw2Impl,iface);
3840 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3844 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3845 ICOM_THIS(IDirectDraw2Impl,iface);
3846 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
3848 return ++(This->ref);
3851 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3852 ICOM_THIS(IDirectDraw2Impl,iface);
3853 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3855 #ifdef HAVE_LIBXXF86DGA
3856 if (!--(This->ref)) {
3857 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3858 if (This->d.window && (This->d.mainWindow != This->d.window))
3859 DestroyWindow(This->d.window);
3860 #ifdef HAVE_LIBXXF86VM
3862 TSXF86VidModeSwitchToMode(
3864 DefaultScreen(display),
3866 if (orig_mode->privsize)
3867 TSXFree(orig_mode->private);
3873 #ifdef RESTORE_SIGNALS
3876 HeapFree(GetProcessHeap(),0,This);
3879 #endif /* defined(HAVE_LIBXXF86DGA) */
3883 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3884 ICOM_THIS(IDirectDraw2Impl,iface);
3885 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3887 if (!--(This->ref)) {
3888 if (This->d.window && (This->d.mainWindow != This->d.window))
3889 DestroyWindow(This->d.window);
3890 HeapFree(GetProcessHeap(),0,This);
3893 /* FIXME: destroy window ... */
3897 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
3898 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3900 ICOM_THIS(IDirectDraw2Impl,iface);
3903 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3904 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3905 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3907 IDirectDraw2_AddRef(iface);
3909 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3913 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3914 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
3915 IDirectDraw2_AddRef(iface);
3918 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3922 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3923 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
3924 IDirectDraw2_AddRef(iface);
3927 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3931 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3932 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
3933 IDirectDraw2_AddRef(iface);
3936 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3940 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3943 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3945 d3d->ddraw = (IDirectDrawImpl*)This;
3946 IDirectDraw2_AddRef(iface);
3947 d3d->lpvtbl = &d3dvt;
3950 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3954 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3955 IDirect3D2Impl* d3d;
3957 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3959 d3d->ddraw = (IDirectDrawImpl*)This;
3960 IDirectDraw2_AddRef(iface);
3961 d3d->lpvtbl = &d3d2vt;
3964 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3968 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3969 return OLE_E_ENUM_NOMORE;
3972 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
3973 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3975 ICOM_THIS(IDirectDraw2Impl,iface);
3978 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3979 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3980 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3982 IDirectDraw2_AddRef(iface);
3984 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3988 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3989 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
3990 IDirectDraw2_AddRef(iface);
3993 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3997 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3998 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
3999 IDirectDraw2_AddRef(iface);
4002 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
4006 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
4007 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4008 IDirectDraw2_AddRef(iface);
4011 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
4015 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
4018 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4020 d3d->ddraw = (IDirectDrawImpl*)This;
4021 IDirectDraw2_AddRef(iface);
4022 d3d->lpvtbl = &d3dvt;
4025 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
4029 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
4030 IDirect3D2Impl* d3d;
4032 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4034 d3d->ddraw = (IDirectDrawImpl*)This;
4035 IDirectDraw2_AddRef(iface);
4036 d3d->lpvtbl = &d3d2vt;
4039 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
4043 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4044 return OLE_E_ENUM_NOMORE;
4047 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4048 LPDIRECTDRAW2 iface,BOOL *status
4050 ICOM_THIS(IDirectDraw2Impl,iface);
4051 TRACE(ddraw,"(%p)->(%p)\n",This,status);
4056 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4057 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4059 ICOM_THIS(IDirectDraw2Impl,iface);
4060 DDSURFACEDESC ddsfd;
4063 } modes[5] = { /* some of the usual modes */
4070 static int depths[4] = {8,16,24,32};
4073 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4074 ddsfd.dwSize = sizeof(ddsfd);
4075 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4076 if (dwFlags & DDEDM_REFRESHRATES) {
4077 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4078 ddsfd.x.dwRefreshRate = 60;
4081 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4082 ddsfd.dwBackBufferCount = 1;
4083 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4084 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4085 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
4086 /* FIXME: those masks would have to be set in depth > 8 */
4088 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
4089 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
4090 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
4091 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4092 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4093 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4095 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4097 /* FIXME: We should query those from X itself */
4098 switch (depths[i]) {
4100 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
4101 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
4102 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
4105 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
4106 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
4107 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
4110 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
4111 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
4112 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
4117 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4118 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4119 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4120 if (!modescb(&ddsfd,context)) return DD_OK;
4122 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4123 ddsfd.dwWidth = modes[j].w;
4124 ddsfd.dwHeight = modes[j].h;
4125 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4126 if (!modescb(&ddsfd,context)) return DD_OK;
4129 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4130 /* modeX is not standard VGA */
4132 ddsfd.dwHeight = 200;
4133 ddsfd.dwWidth = 320;
4134 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
4135 if (!modescb(&ddsfd,context)) return DD_OK;
4141 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4142 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4144 ICOM_THIS(IDirectDraw2Impl,iface);
4146 XPixmapFormatValues *pf;
4148 int nvisuals, npixmap, i;
4151 DDSURFACEDESC ddsfd;
4154 } modes[] = { /* some of the usual modes */
4162 DWORD maxWidth, maxHeight;
4164 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4165 ddsfd.dwSize = sizeof(ddsfd);
4166 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
4167 if (dwFlags & DDEDM_REFRESHRATES) {
4168 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4169 ddsfd.x.dwRefreshRate = 60;
4171 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4172 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4174 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4175 pf = XListPixmapFormats(display, &npixmap);
4179 while (i < npixmap) {
4180 if ((has_8bpp == 0) && (pf[i].depth == 8)) {
4181 /* Special case of a 8bpp depth */
4185 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4186 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4187 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4188 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4189 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
4190 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
4191 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
4192 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
4193 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4194 } else if (pf[i].depth > 8) {
4197 /* All the 'true color' depths (15, 16 and 24)
4198 First, find the corresponding visual to extract the bit masks */
4199 for (j = 0; j < nvisuals; j++) {
4200 if (vi[j].depth == pf[i].depth) {
4201 ddsfd.ddsCaps.dwCaps = 0;
4202 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4203 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4204 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4205 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
4206 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
4207 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
4208 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
4209 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4217 ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
4225 if (TRACE_ON(ddraw)) {
4226 TRACE(ddraw, "Enumerating with pixel format : \n");
4227 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4231 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4232 /* Do not enumerate modes we cannot handle anyway */
4233 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4236 ddsfd.dwWidth = modes[mode].w;
4237 ddsfd.dwHeight = modes[mode].h;
4239 /* Now, send the mode description to the application */
4240 TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4241 if (!modescb(&ddsfd, context))
4245 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4246 /* modeX is not standard VGA */
4247 ddsfd.dwWidth = 320;
4248 ddsfd.dwHeight = 200;
4249 if (!modescb(&ddsfd, context))
4254 /* Hack to always enumerate a 8bpp depth */
4256 if ((i == npixmap) && (has_8bpp == 0)) {
4269 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4270 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4272 #ifdef HAVE_LIBXXF86DGA
4273 ICOM_THIS(IDirectDraw2Impl,iface);
4274 TRACE(ddraw,"(%p)->(%p)\n",This,lpddsfd);
4275 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4276 lpddsfd->dwHeight = This->d.height;
4277 lpddsfd->dwWidth = This->d.width;
4278 lpddsfd->lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4279 lpddsfd->dwBackBufferCount = 1;
4280 lpddsfd->x.dwRefreshRate = 60;
4281 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4282 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4284 #else /* defined(HAVE_LIBXXF86DGA) */
4285 return E_UNEXPECTED;
4286 #endif /* defined(HAVE_LIBXXF86DGA) */
4289 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4290 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4292 ICOM_THIS(IDirectDraw2Impl,iface);
4293 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4294 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4295 lpddsfd->dwHeight = This->d.height;
4296 lpddsfd->dwWidth = This->d.width;
4297 lpddsfd->lPitch = lpddsfd->dwWidth * This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4298 lpddsfd->dwBackBufferCount = 1;
4299 lpddsfd->x.dwRefreshRate = 60;
4300 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4301 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4305 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4306 ICOM_THIS(IDirectDraw2Impl,iface);
4307 TRACE(ddraw,"(%p)->()\n",This);
4311 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4312 LPDIRECTDRAW2 iface,LPDWORD freq
4314 ICOM_THIS(IDirectDraw2Impl,iface);
4315 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",This,freq);
4316 *freq = 60*100; /* 60 Hz */
4320 /* what can we directly decompress? */
4321 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4322 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4324 ICOM_THIS(IDirectDraw2Impl,iface);
4325 FIXME(ddraw,"(%p,%p,%p), stub\n",This,x,y);
4329 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4330 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4332 ICOM_THIS(IDirectDraw2Impl,iface);
4333 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4337 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4338 LPDIRECTDRAW2 iface )
4340 ICOM_THIS(IDirectDraw2Impl,iface);
4341 FIXME(ddraw,"(%p)->()\n", This );
4346 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4347 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4348 ICOM_THIS(IDirectDraw2Impl,iface);
4349 FIXME(ddraw,"(%p)->(%p)\n", This, lplpGDIDDSSurface);
4354 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4355 LPDWORD lpdwScanLine) {
4356 ICOM_THIS(IDirectDraw2Impl,iface);
4357 FIXME(ddraw,"(%p)->(%p)\n", This, lpdwScanLine);
4362 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4364 ICOM_THIS(IDirectDraw2Impl,iface);
4365 FIXME(ddraw,"(%p)->(%p)\n", This, lpGUID);
4370 /* Note: Hack so we can reuse the old functions without compiler warnings */
4371 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4372 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4374 # define XCAST(fun) (void *)
4377 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4379 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4380 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4381 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4382 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4383 XCAST(Compact)IDirectDraw2Impl_Compact,
4384 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4385 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4386 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4387 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4388 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4389 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4390 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4391 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4392 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4393 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4394 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4395 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4396 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4397 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4398 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4399 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4400 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4401 DGA_IDirectDrawImpl_SetDisplayMode,
4402 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4405 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
4407 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4408 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4409 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4410 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4411 XCAST(Compact)IDirectDraw2Impl_Compact,
4412 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4413 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4414 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4415 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4416 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4417 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4418 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4419 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4420 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4421 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4422 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4423 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4424 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4425 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4426 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4427 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4428 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4429 Xlib_IDirectDrawImpl_SetDisplayMode,
4430 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4435 /*****************************************************************************
4441 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4442 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4444 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4447 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4448 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4450 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4453 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4454 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4456 ICOM_THIS(IDirectDraw2Impl,iface);
4457 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4458 This,ddscaps,total,free
4460 if (total) *total = This->e.dga.fb_memsize * 1024;
4461 if (free) *free = This->e.dga.fb_memsize * 1024;
4465 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4466 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4468 ICOM_THIS(IDirectDraw2Impl,iface);
4469 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4470 This,ddscaps,total,free
4472 if (total) *total = 2048 * 1024;
4473 if (free) *free = 2048 * 1024;
4477 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
4479 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4480 DGA_IDirectDraw2Impl_QueryInterface,
4481 IDirectDraw2Impl_AddRef,
4482 DGA_IDirectDraw2Impl_Release,
4483 IDirectDraw2Impl_Compact,
4484 IDirectDraw2Impl_CreateClipper,
4485 DGA_IDirectDraw2Impl_CreatePalette,
4486 DGA_IDirectDraw2Impl_CreateSurface,
4487 IDirectDraw2Impl_DuplicateSurface,
4488 DGA_IDirectDraw2Impl_EnumDisplayModes,
4489 IDirectDraw2Impl_EnumSurfaces,
4490 IDirectDraw2Impl_FlipToGDISurface,
4491 DGA_IDirectDraw2Impl_GetCaps,
4492 DGA_IDirectDraw2Impl_GetDisplayMode,
4493 IDirectDraw2Impl_GetFourCCCodes,
4494 IDirectDraw2Impl_GetGDISurface,
4495 IDirectDraw2Impl_GetMonitorFrequency,
4496 IDirectDraw2Impl_GetScanLine,
4497 IDirectDraw2Impl_GetVerticalBlankStatus,
4498 IDirectDraw2Impl_Initialize,
4499 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4500 IDirectDraw2Impl_SetCooperativeLevel,
4501 DGA_IDirectDraw2Impl_SetDisplayMode,
4502 IDirectDraw2Impl_WaitForVerticalBlank,
4503 DGA_IDirectDraw2Impl_GetAvailableVidMem
4506 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
4508 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4509 Xlib_IDirectDraw2Impl_QueryInterface,
4510 IDirectDraw2Impl_AddRef,
4511 Xlib_IDirectDraw2Impl_Release,
4512 IDirectDraw2Impl_Compact,
4513 IDirectDraw2Impl_CreateClipper,
4514 Xlib_IDirectDraw2Impl_CreatePalette,
4515 Xlib_IDirectDraw2Impl_CreateSurface,
4516 IDirectDraw2Impl_DuplicateSurface,
4517 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4518 IDirectDraw2Impl_EnumSurfaces,
4519 IDirectDraw2Impl_FlipToGDISurface,
4520 Xlib_IDirectDraw2Impl_GetCaps,
4521 Xlib_IDirectDraw2Impl_GetDisplayMode,
4522 IDirectDraw2Impl_GetFourCCCodes,
4523 IDirectDraw2Impl_GetGDISurface,
4524 IDirectDraw2Impl_GetMonitorFrequency,
4525 IDirectDraw2Impl_GetScanLine,
4526 IDirectDraw2Impl_GetVerticalBlankStatus,
4527 IDirectDraw2Impl_Initialize,
4528 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4529 IDirectDraw2Impl_SetCooperativeLevel,
4530 Xlib_IDirectDraw2Impl_SetDisplayMode,
4531 IDirectDraw2Impl_WaitForVerticalBlank,
4532 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4535 /*****************************************************************************
4540 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4542 LPDIRECTDRAWSURFACE *lpDDS) {
4543 ICOM_THIS(IDirectDraw4Impl,iface);
4544 FIXME(ddraw, "(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4549 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4550 ICOM_THIS(IDirectDraw4Impl,iface);
4551 FIXME(ddraw, "(%p)->()\n", This);
4556 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4557 ICOM_THIS(IDirectDraw4Impl,iface);
4558 FIXME(ddraw, "(%p)->()\n", This);
4563 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4564 LPDDDEVICEIDENTIFIER lpdddi,
4566 ICOM_THIS(IDirectDraw4Impl,iface);
4567 FIXME(ddraw, "(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4572 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4573 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4575 # define XCAST(fun) (void*)
4579 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
4581 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4582 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4583 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4584 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4585 XCAST(Compact)IDirectDraw2Impl_Compact,
4586 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4587 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4588 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4589 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4590 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4591 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4592 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4593 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4594 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4595 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4596 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4597 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4598 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4599 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4600 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4601 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4602 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4603 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4604 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4605 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4606 IDirectDraw4Impl_GetSurfaceFromDC,
4607 IDirectDraw4Impl_RestoreAllSurfaces,
4608 IDirectDraw4Impl_TestCooperativeLevel,
4609 IDirectDraw4Impl_GetDeviceIdentifier
4612 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
4614 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4615 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4616 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4617 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4618 XCAST(Compact)IDirectDraw2Impl_Compact,
4619 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4620 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4621 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4622 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4623 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4624 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4625 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4626 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4627 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4628 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4629 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4630 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4631 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4632 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4633 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4634 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4635 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4636 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4637 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4638 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4639 IDirectDraw4Impl_GetSurfaceFromDC,
4640 IDirectDraw4Impl_RestoreAllSurfaces,
4641 IDirectDraw4Impl_TestCooperativeLevel,
4642 IDirectDraw4Impl_GetDeviceIdentifier
4647 /******************************************************************************
4651 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4654 IDirectDrawImpl* ddraw = NULL;
4657 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4659 SetLastError( ERROR_SUCCESS );
4660 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4662 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4665 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4670 /* Perform any special direct draw functions */
4672 ddraw->d.paintable = 1;
4674 /* Now let the application deal with the rest of this */
4675 if( ddraw->d.mainWindow )
4678 /* Don't think that we actually need to call this but...
4679 might as well be on the safe side of things... */
4681 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4682 it should be the procedures of our fake window that gets called
4683 instead of those of the window provided by the application.
4684 And with this patch, mouse clicks work with Monkey Island III
4686 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4690 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4691 /* We didn't handle the message - give it to the application */
4692 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4694 ret = CallWindowProcA(tmpWnd->winproc,
4695 ddraw->d.mainWindow, msg, wParam, lParam );
4697 WIN_ReleaseWndPtr(tmpWnd);
4702 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4708 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4714 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4715 #ifdef HAVE_LIBXXF86DGA
4716 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4717 int memsize,banksize,width,major,minor,flags,height;
4722 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4723 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4727 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4728 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4729 return E_UNEXPECTED;
4731 if (!DDRAW_DGA_Available()) {
4732 TRACE(ddraw,"No XF86DGA detected.\n");
4733 return DDERR_GENERIC;
4735 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4736 (*ilplpDD)->lpvtbl = &dga_ddvt;
4737 (*ilplpDD)->ref = 1;
4738 TSXF86DGAQueryVersion(display,&major,&minor);
4739 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4740 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4741 if (!(flags & XF86DGADirectPresent))
4742 MSG("direct video is NOT PRESENT.\n");
4743 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4744 (*ilplpDD)->e.dga.fb_width = width;
4745 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4746 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4747 (*ilplpDD)->e.dga.fb_height = height;
4748 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4749 addr,width,banksize,memsize
4751 TRACE(ddraw,"viewport height: %d\n",height);
4753 /* Get the screen dimensions as seen by Wine.
4754 In that case, it may be better to ignore the -desktop mode and return the
4755 real screen size => print a warning */
4756 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4757 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4758 if (((*ilplpDD)->d.height != height) ||
4759 ((*ilplpDD)->d.width != width))
4760 WARN(ddraw, "You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
4761 (*ilplpDD)->e.dga.fb_addr = addr;
4762 (*ilplpDD)->e.dga.fb_memsize = memsize;
4763 (*ilplpDD)->e.dga.fb_banksize = banksize;
4764 (*ilplpDD)->e.dga.vpmask = 0;
4766 /* just assume the default depth is the DGA depth too */
4767 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4768 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4769 #ifdef RESTORE_SIGNALS
4774 #else /* defined(HAVE_LIBXXF86DGA) */
4775 return DDERR_INVALIDDIRECTDRAWGUID;
4776 #endif /* defined(HAVE_LIBXXF86DGA) */
4780 DDRAW_XSHM_Available(void)
4782 #ifdef HAVE_LIBXXSHM
4783 if (TSXShmQueryExtension(display))
4788 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4800 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4801 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4804 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4805 (*ilplpDD)->lpvtbl = &xlib_ddvt;
4806 (*ilplpDD)->ref = 1;
4807 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
4809 /* At DirectDraw creation, the depth is the default depth */
4810 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4811 _common_depth_to_pixelformat(depth,
4812 &((*ilplpDD)->d.directdraw_pixelformat),
4813 &((*ilplpDD)->d.screen_pixelformat),
4814 &((*ilplpDD)->d.pixmap_depth));
4815 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4816 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4818 #ifdef HAVE_LIBXXSHM
4819 /* Test if XShm is available. */
4820 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4821 TRACE(ddraw, "Using XShm extension.\n");
4827 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4828 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4831 /* WND* pParentWindow; */
4835 WINE_StringFromCLSID(lpGUID,xclsid);
4837 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4841 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
4844 (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4845 (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4846 (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4847 /* if they didn't request a particular interface, use the best
4849 if (DDRAW_DGA_Available())
4850 lpGUID = &DGA_DirectDraw_GUID;
4852 lpGUID = &XLIB_DirectDraw_GUID;
4855 wc.style = CS_GLOBALCLASS;
4856 wc.lpfnWndProc = Xlib_DDWndProc;
4858 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
4859 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
4861 /* We can be a child of the desktop since we're really important */
4863 This code is not useful since hInstance is forced to 0 afterward
4864 pParentWindow = WIN_GetDesktop();
4865 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
4871 wc.hCursor = (HCURSOR)IDC_ARROWA;
4872 wc.hbrBackground= NULL_BRUSH;
4873 wc.lpszMenuName = 0;
4874 wc.lpszClassName= "WINE_DirectDraw";
4875 RegisterClassA(&wc);
4877 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4878 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4879 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4880 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4885 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
4889 ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4890 return DDERR_INVALIDDIRECTDRAWGUID;
4894 #else /* !defined(X_DISPLAY_MISSING) */
4900 typedef void *LPGUID;
4901 typedef void *LPUNKNOWN;
4902 typedef void *LPDIRECTDRAW;
4903 typedef void *LPDIRECTDRAWCLIPPER;
4904 typedef void *LPDDENUMCALLBACKA;
4905 typedef void *LPDDENUMCALLBACKEXA;
4906 typedef void *LPDDENUMCALLBACKEXW;
4907 typedef void *LPDDENUMCALLBACKW;
4909 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
4914 HRESULT WINAPI DirectDrawCreate(
4915 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
4920 HRESULT WINAPI DirectDrawCreateClipper(
4921 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
4926 HRESULT WINAPI DirectDrawEnumerateA(
4927 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
4932 HRESULT WINAPI DirectDrawEnumerateExA(
4933 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
4938 HRESULT WINAPI DirectDrawEnumerateExW(
4939 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
4944 HRESULT WINAPI DirectDrawEnumerateW(
4945 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
4950 #endif /* !defined(X_DISPLAY_MISSING) */
4953 /*******************************************************************************
4954 * DirectDraw ClassFactory
4956 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
4961 /* IUnknown fields */
4962 ICOM_VTABLE(IClassFactory)* lpvtbl;
4964 } IClassFactoryImpl;
4966 static HRESULT WINAPI
4967 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
4968 ICOM_THIS(IClassFactoryImpl,iface);
4972 WINE_StringFromCLSID(riid,buf);
4974 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4975 FIXME(ddraw,"(%p)->(%s,%p),stub!\n",This,buf,ppobj);
4976 return E_NOINTERFACE;
4980 DDCF_AddRef(LPCLASSFACTORY iface) {
4981 ICOM_THIS(IClassFactoryImpl,iface);
4982 return ++(This->ref);
4985 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
4986 ICOM_THIS(IClassFactoryImpl,iface);
4987 /* static class, won't be freed */
4988 return --(This->ref);
4991 static HRESULT WINAPI DDCF_CreateInstance(
4992 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
4994 ICOM_THIS(IClassFactoryImpl,iface);
4997 WINE_StringFromCLSID(riid,buf);
4998 TRACE(ddraw,"(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
4999 if ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
5000 (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
5001 (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
5002 /* FIXME: reuse already created DirectDraw if present? */
5003 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5005 return E_NOINTERFACE;
5008 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5009 ICOM_THIS(IClassFactoryImpl,iface);
5010 FIXME(ddraw,"(%p)->(%d),stub!\n",This,dolock);
5014 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5016 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5017 DDCF_QueryInterface,
5020 DDCF_CreateInstance,
5023 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5025 /*******************************************************************************
5026 * DllGetClassObject [DDRAW.13]
5027 * Retrieves class object from a DLL object
5030 * Docs say returns STDAPI
5033 * rclsid [I] CLSID for the class object
5034 * riid [I] Reference to identifier of interface for class object
5035 * ppv [O] Address of variable to receive interface pointer for riid
5039 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5042 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5044 char buf[80],xbuf[80];
5047 WINE_StringFromCLSID(rclsid,xbuf);
5049 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
5051 WINE_StringFromCLSID(riid,buf);
5053 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5054 WINE_StringFromCLSID(riid,xbuf);
5055 TRACE(ddraw, "(%p,%p,%p)\n", xbuf, buf, ppv);
5056 if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
5057 *ppv = (LPVOID)&DDRAW_CF;
5058 IClassFactory_AddRef((IClassFactory*)*ppv);
5061 FIXME(ddraw, "(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
5062 return E_NOINTERFACE;
5066 /*******************************************************************************
5067 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5073 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5075 FIXME(ddraw, "(void): stub\n");