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);
3647 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3648 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3649 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3652 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3653 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3654 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3657 #else /* defined(HAVE_LIBXXF86DGA) */
3658 return E_UNEXPECTED;
3659 #endif /* defined(HAVE_LIBXXF86DGA) */
3662 static void fill_caps(LPDDCAPS caps) {
3663 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3664 Need to be fixed, though.. */
3668 caps->dwSize = sizeof(*caps);
3669 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3670 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
3671 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3672 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3674 caps->dwFXAlphaCaps = 0;
3675 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3677 caps->dwZBufferBitDepths = DDBD_16;
3678 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3679 to put textures in video memory.
3680 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3682 caps->dwVidMemTotal = 8192 * 1024;
3683 caps->dwVidMemFree = 8192 * 1024;
3684 /* These are all the supported capabilities of the surfaces */
3685 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3686 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3687 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3688 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3690 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3691 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3692 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3696 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3697 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3699 ICOM_THIS(IDirectDraw2Impl,iface);
3700 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3702 /* Put the same caps for the two capabilities */
3709 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3710 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3712 ICOM_THIS(IDirectDraw2Impl,iface);
3713 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3714 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3715 This,x,ilpddclip,lpunk
3717 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3718 (*ilpddclip)->ref = 1;
3719 (*ilpddclip)->lpvtbl = &ddclipvt;
3723 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3724 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3728 if (TRACE_ON(ddraw))
3729 _dump_paletteformat(dwFlags);
3731 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3732 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3733 (*lpddpal)->ref = 1;
3734 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3735 (*lpddpal)->installed = 0;
3737 if (dwFlags & DDPCAPS_1BIT)
3739 else if (dwFlags & DDPCAPS_2BIT)
3741 else if (dwFlags & DDPCAPS_4BIT)
3743 else if (dwFlags & DDPCAPS_8BIT)
3746 ERR(ddraw, "unhandled palette format\n");
3751 /* Now, if we are in 'depth conversion mode', create the screen palette */
3752 if (This->d.palette_convert != NULL)
3753 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3755 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3756 } else if (This->d.palette_convert != NULL) {
3757 /* In that case, put all 0xFF */
3758 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3764 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3765 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3767 ICOM_THIS(IDirectDraw2Impl,iface);
3768 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3772 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3773 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3774 if (res != 0) return res;
3775 (*ilpddpal)->lpvtbl = &dga_ddpalvt;
3776 if (This->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3777 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3779 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3780 (*ilpddpal)->cm = 0;
3782 if (((*ilpddpal)->cm)&&xsize) {
3783 for (i=0;i<xsize;i++) {
3786 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3787 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3788 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3789 xc.flags = DoRed|DoBlue|DoGreen;
3791 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3797 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3798 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3800 ICOM_THIS(IDirectDraw2Impl,iface);
3801 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3805 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3806 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3807 if (res != 0) return res;
3808 (*ilpddpal)->lpvtbl = &xlib_ddpalvt;
3812 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3813 #ifdef HAVE_LIBXXF86DGA
3814 ICOM_THIS(IDirectDraw2Impl,iface);
3815 TRACE(ddraw, "(%p)->()\n",This);
3817 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3818 #ifdef RESTORE_SIGNALS
3822 #else /* defined(HAVE_LIBXXF86DGA) */
3823 return E_UNEXPECTED;
3827 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3828 ICOM_THIS(IDirectDraw2Impl,iface);
3829 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", This);
3834 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3835 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3837 ICOM_THIS(IDirectDraw2Impl,iface);
3838 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3842 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3843 ICOM_THIS(IDirectDraw2Impl,iface);
3844 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
3846 return ++(This->ref);
3849 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3850 ICOM_THIS(IDirectDraw2Impl,iface);
3851 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3853 #ifdef HAVE_LIBXXF86DGA
3854 if (!--(This->ref)) {
3855 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3856 if (This->d.window && (This->d.mainWindow != This->d.window))
3857 DestroyWindow(This->d.window);
3858 #ifdef HAVE_LIBXXF86VM
3860 TSXF86VidModeSwitchToMode(
3862 DefaultScreen(display),
3864 if (orig_mode->privsize)
3865 TSXFree(orig_mode->private);
3871 #ifdef RESTORE_SIGNALS
3874 HeapFree(GetProcessHeap(),0,This);
3877 #endif /* defined(HAVE_LIBXXF86DGA) */
3881 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3882 ICOM_THIS(IDirectDraw2Impl,iface);
3883 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3885 if (!--(This->ref)) {
3886 if (This->d.window && (This->d.mainWindow != This->d.window))
3887 DestroyWindow(This->d.window);
3888 HeapFree(GetProcessHeap(),0,This);
3891 /* FIXME: destroy window ... */
3895 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
3896 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3898 ICOM_THIS(IDirectDraw2Impl,iface);
3901 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3902 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3903 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3905 IDirectDraw2_AddRef(iface);
3907 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3911 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3912 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
3913 IDirectDraw2_AddRef(iface);
3916 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3920 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3921 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
3922 IDirectDraw2_AddRef(iface);
3925 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3929 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3930 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
3931 IDirectDraw2_AddRef(iface);
3934 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3938 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3941 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3943 d3d->ddraw = (IDirectDrawImpl*)This;
3944 IDirectDraw2_AddRef(iface);
3945 d3d->lpvtbl = &d3dvt;
3948 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3952 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3953 IDirect3D2Impl* d3d;
3955 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3957 d3d->ddraw = (IDirectDrawImpl*)This;
3958 IDirectDraw2_AddRef(iface);
3959 d3d->lpvtbl = &d3d2vt;
3962 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3966 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3967 return OLE_E_ENUM_NOMORE;
3970 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
3971 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3973 ICOM_THIS(IDirectDraw2Impl,iface);
3976 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3977 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3978 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3980 IDirectDraw2_AddRef(iface);
3982 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3986 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3987 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
3988 IDirectDraw2_AddRef(iface);
3991 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3995 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3996 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
3997 IDirectDraw2_AddRef(iface);
4000 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
4004 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
4005 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4006 IDirectDraw2_AddRef(iface);
4009 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
4013 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
4016 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4018 d3d->ddraw = (IDirectDrawImpl*)This;
4019 IDirectDraw2_AddRef(iface);
4020 d3d->lpvtbl = &d3dvt;
4023 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
4027 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
4028 IDirect3D2Impl* d3d;
4030 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4032 d3d->ddraw = (IDirectDrawImpl*)This;
4033 IDirectDraw2_AddRef(iface);
4034 d3d->lpvtbl = &d3d2vt;
4037 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
4041 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4042 return OLE_E_ENUM_NOMORE;
4045 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4046 LPDIRECTDRAW2 iface,BOOL *status
4048 ICOM_THIS(IDirectDraw2Impl,iface);
4049 TRACE(ddraw,"(%p)->(%p)\n",This,status);
4054 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4055 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4057 ICOM_THIS(IDirectDraw2Impl,iface);
4058 DDSURFACEDESC ddsfd;
4061 } modes[5] = { /* some of the usual modes */
4068 static int depths[4] = {8,16,24,32};
4071 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4072 ddsfd.dwSize = sizeof(ddsfd);
4073 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4074 if (dwFlags & DDEDM_REFRESHRATES) {
4075 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4076 ddsfd.x.dwRefreshRate = 60;
4079 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4080 ddsfd.dwBackBufferCount = 1;
4081 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4082 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4083 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
4084 /* FIXME: those masks would have to be set in depth > 8 */
4086 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
4087 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
4088 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
4089 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4090 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4091 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4093 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4095 /* FIXME: We should query those from X itself */
4096 switch (depths[i]) {
4098 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
4099 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
4100 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
4103 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
4104 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
4105 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
4108 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
4109 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
4110 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
4115 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4116 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4117 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4118 if (!modescb(&ddsfd,context)) return DD_OK;
4120 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4121 ddsfd.dwWidth = modes[j].w;
4122 ddsfd.dwHeight = modes[j].h;
4123 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4124 if (!modescb(&ddsfd,context)) return DD_OK;
4127 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4128 /* modeX is not standard VGA */
4130 ddsfd.dwHeight = 200;
4131 ddsfd.dwWidth = 320;
4132 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
4133 if (!modescb(&ddsfd,context)) return DD_OK;
4139 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4140 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4142 ICOM_THIS(IDirectDraw2Impl,iface);
4144 XPixmapFormatValues *pf;
4146 int nvisuals, npixmap, i;
4149 DDSURFACEDESC ddsfd;
4152 } modes[] = { /* some of the usual modes */
4160 DWORD maxWidth, maxHeight;
4162 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4163 ddsfd.dwSize = sizeof(ddsfd);
4164 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
4165 if (dwFlags & DDEDM_REFRESHRATES) {
4166 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4167 ddsfd.x.dwRefreshRate = 60;
4169 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4170 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4172 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4173 pf = XListPixmapFormats(display, &npixmap);
4177 while (i < npixmap) {
4178 if ((has_8bpp == 0) && (pf[i].depth == 8)) {
4179 /* Special case of a 8bpp depth */
4183 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4184 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4185 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4186 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4187 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
4188 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
4189 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
4190 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
4191 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4192 } else if (pf[i].depth > 8) {
4195 /* All the 'true color' depths (15, 16 and 24)
4196 First, find the corresponding visual to extract the bit masks */
4197 for (j = 0; j < nvisuals; j++) {
4198 if (vi[j].depth == pf[i].depth) {
4199 ddsfd.ddsCaps.dwCaps = 0;
4200 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4201 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4202 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4203 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
4204 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
4205 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
4206 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
4207 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4215 ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
4223 if (TRACE_ON(ddraw)) {
4224 TRACE(ddraw, "Enumerating with pixel format : \n");
4225 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4229 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4230 /* Do not enumerate modes we cannot handle anyway */
4231 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4234 ddsfd.dwWidth = modes[mode].w;
4235 ddsfd.dwHeight = modes[mode].h;
4237 /* Now, send the mode description to the application */
4238 TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4239 if (!modescb(&ddsfd, context))
4243 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4244 /* modeX is not standard VGA */
4245 ddsfd.dwWidth = 320;
4246 ddsfd.dwHeight = 200;
4247 if (!modescb(&ddsfd, context))
4252 /* Hack to always enumerate a 8bpp depth */
4254 if ((i == npixmap) && (has_8bpp == 0)) {
4267 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4268 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4270 #ifdef HAVE_LIBXXF86DGA
4271 ICOM_THIS(IDirectDraw2Impl,iface);
4272 TRACE(ddraw,"(%p)->(%p)\n",This,lpddsfd);
4273 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4274 lpddsfd->dwHeight = This->d.height;
4275 lpddsfd->dwWidth = This->d.width;
4276 lpddsfd->lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4277 lpddsfd->dwBackBufferCount = 1;
4278 lpddsfd->x.dwRefreshRate = 60;
4279 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4280 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4282 #else /* defined(HAVE_LIBXXF86DGA) */
4283 return E_UNEXPECTED;
4284 #endif /* defined(HAVE_LIBXXF86DGA) */
4287 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4288 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4290 ICOM_THIS(IDirectDraw2Impl,iface);
4291 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4292 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4293 lpddsfd->dwHeight = This->d.height;
4294 lpddsfd->dwWidth = This->d.width;
4295 lpddsfd->lPitch = lpddsfd->dwWidth * This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4296 lpddsfd->dwBackBufferCount = 1;
4297 lpddsfd->x.dwRefreshRate = 60;
4298 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4299 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4303 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4304 ICOM_THIS(IDirectDraw2Impl,iface);
4305 TRACE(ddraw,"(%p)->()\n",This);
4309 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4310 LPDIRECTDRAW2 iface,LPDWORD freq
4312 ICOM_THIS(IDirectDraw2Impl,iface);
4313 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",This,freq);
4314 *freq = 60*100; /* 60 Hz */
4318 /* what can we directly decompress? */
4319 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4320 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4322 ICOM_THIS(IDirectDraw2Impl,iface);
4323 FIXME(ddraw,"(%p,%p,%p), stub\n",This,x,y);
4327 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4328 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4330 ICOM_THIS(IDirectDraw2Impl,iface);
4331 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4335 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4336 LPDIRECTDRAW2 iface )
4338 ICOM_THIS(IDirectDraw2Impl,iface);
4339 FIXME(ddraw,"(%p)->()\n", This );
4344 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4345 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4346 ICOM_THIS(IDirectDraw2Impl,iface);
4347 FIXME(ddraw,"(%p)->(%p)\n", This, lplpGDIDDSSurface);
4352 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4353 LPDWORD lpdwScanLine) {
4354 ICOM_THIS(IDirectDraw2Impl,iface);
4355 FIXME(ddraw,"(%p)->(%p)\n", This, lpdwScanLine);
4360 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4362 ICOM_THIS(IDirectDraw2Impl,iface);
4363 FIXME(ddraw,"(%p)->(%p)\n", This, lpGUID);
4368 /* Note: Hack so we can reuse the old functions without compiler warnings */
4369 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4370 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4372 # define XCAST(fun) (void *)
4375 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4377 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4378 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4379 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4380 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4381 XCAST(Compact)IDirectDraw2Impl_Compact,
4382 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4383 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4384 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4385 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4386 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4387 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4388 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4389 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4390 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4391 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4392 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4393 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4394 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4395 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4396 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4397 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4398 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4399 DGA_IDirectDrawImpl_SetDisplayMode,
4400 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4403 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
4405 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4406 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4407 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4408 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4409 XCAST(Compact)IDirectDraw2Impl_Compact,
4410 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4411 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4412 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4413 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4414 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4415 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4416 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4417 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4418 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4419 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4420 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4421 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4422 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4423 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4424 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4425 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4426 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4427 Xlib_IDirectDrawImpl_SetDisplayMode,
4428 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4433 /*****************************************************************************
4439 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4440 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4442 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4445 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4446 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4448 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4451 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4452 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4454 ICOM_THIS(IDirectDraw2Impl,iface);
4455 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4456 This,ddscaps,total,free
4458 if (total) *total = This->e.dga.fb_memsize * 1024;
4459 if (free) *free = This->e.dga.fb_memsize * 1024;
4463 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4464 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4466 ICOM_THIS(IDirectDraw2Impl,iface);
4467 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4468 This,ddscaps,total,free
4470 if (total) *total = 2048 * 1024;
4471 if (free) *free = 2048 * 1024;
4475 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
4477 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4478 DGA_IDirectDraw2Impl_QueryInterface,
4479 IDirectDraw2Impl_AddRef,
4480 DGA_IDirectDraw2Impl_Release,
4481 IDirectDraw2Impl_Compact,
4482 IDirectDraw2Impl_CreateClipper,
4483 DGA_IDirectDraw2Impl_CreatePalette,
4484 DGA_IDirectDraw2Impl_CreateSurface,
4485 IDirectDraw2Impl_DuplicateSurface,
4486 DGA_IDirectDraw2Impl_EnumDisplayModes,
4487 IDirectDraw2Impl_EnumSurfaces,
4488 IDirectDraw2Impl_FlipToGDISurface,
4489 DGA_IDirectDraw2Impl_GetCaps,
4490 DGA_IDirectDraw2Impl_GetDisplayMode,
4491 IDirectDraw2Impl_GetFourCCCodes,
4492 IDirectDraw2Impl_GetGDISurface,
4493 IDirectDraw2Impl_GetMonitorFrequency,
4494 IDirectDraw2Impl_GetScanLine,
4495 IDirectDraw2Impl_GetVerticalBlankStatus,
4496 IDirectDraw2Impl_Initialize,
4497 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4498 IDirectDraw2Impl_SetCooperativeLevel,
4499 DGA_IDirectDraw2Impl_SetDisplayMode,
4500 IDirectDraw2Impl_WaitForVerticalBlank,
4501 DGA_IDirectDraw2Impl_GetAvailableVidMem
4504 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
4506 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4507 Xlib_IDirectDraw2Impl_QueryInterface,
4508 IDirectDraw2Impl_AddRef,
4509 Xlib_IDirectDraw2Impl_Release,
4510 IDirectDraw2Impl_Compact,
4511 IDirectDraw2Impl_CreateClipper,
4512 Xlib_IDirectDraw2Impl_CreatePalette,
4513 Xlib_IDirectDraw2Impl_CreateSurface,
4514 IDirectDraw2Impl_DuplicateSurface,
4515 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4516 IDirectDraw2Impl_EnumSurfaces,
4517 IDirectDraw2Impl_FlipToGDISurface,
4518 Xlib_IDirectDraw2Impl_GetCaps,
4519 Xlib_IDirectDraw2Impl_GetDisplayMode,
4520 IDirectDraw2Impl_GetFourCCCodes,
4521 IDirectDraw2Impl_GetGDISurface,
4522 IDirectDraw2Impl_GetMonitorFrequency,
4523 IDirectDraw2Impl_GetScanLine,
4524 IDirectDraw2Impl_GetVerticalBlankStatus,
4525 IDirectDraw2Impl_Initialize,
4526 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4527 IDirectDraw2Impl_SetCooperativeLevel,
4528 Xlib_IDirectDraw2Impl_SetDisplayMode,
4529 IDirectDraw2Impl_WaitForVerticalBlank,
4530 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4533 /*****************************************************************************
4538 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4540 LPDIRECTDRAWSURFACE *lpDDS) {
4541 ICOM_THIS(IDirectDraw4Impl,iface);
4542 FIXME(ddraw, "(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4547 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4548 ICOM_THIS(IDirectDraw4Impl,iface);
4549 FIXME(ddraw, "(%p)->()\n", This);
4554 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4555 ICOM_THIS(IDirectDraw4Impl,iface);
4556 FIXME(ddraw, "(%p)->()\n", This);
4561 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4562 LPDDDEVICEIDENTIFIER lpdddi,
4564 ICOM_THIS(IDirectDraw4Impl,iface);
4565 FIXME(ddraw, "(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4570 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4571 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4573 # define XCAST(fun) (void*)
4577 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
4579 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4580 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4581 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4582 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4583 XCAST(Compact)IDirectDraw2Impl_Compact,
4584 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4585 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4586 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4587 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4588 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4589 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4590 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4591 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4592 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4593 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4594 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4595 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4596 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4597 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4598 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4599 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4600 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4601 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4602 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4603 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4604 IDirectDraw4Impl_GetSurfaceFromDC,
4605 IDirectDraw4Impl_RestoreAllSurfaces,
4606 IDirectDraw4Impl_TestCooperativeLevel,
4607 IDirectDraw4Impl_GetDeviceIdentifier
4610 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
4612 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4613 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4614 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4615 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4616 XCAST(Compact)IDirectDraw2Impl_Compact,
4617 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4618 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4619 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4620 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4621 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4622 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4623 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4624 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4625 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4626 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4627 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4628 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4629 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4630 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4631 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4632 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4633 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4634 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4635 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4636 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4637 IDirectDraw4Impl_GetSurfaceFromDC,
4638 IDirectDraw4Impl_RestoreAllSurfaces,
4639 IDirectDraw4Impl_TestCooperativeLevel,
4640 IDirectDraw4Impl_GetDeviceIdentifier
4645 /******************************************************************************
4649 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4652 IDirectDrawImpl* ddraw = NULL;
4655 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4657 SetLastError( ERROR_SUCCESS );
4658 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4660 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4663 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4668 /* Perform any special direct draw functions */
4670 ddraw->d.paintable = 1;
4672 /* Now let the application deal with the rest of this */
4673 if( ddraw->d.mainWindow )
4676 /* Don't think that we actually need to call this but...
4677 might as well be on the safe side of things... */
4679 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4680 it should be the procedures of our fake window that gets called
4681 instead of those of the window provided by the application.
4682 And with this patch, mouse clicks work with Monkey Island III
4684 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4688 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4689 /* We didn't handle the message - give it to the application */
4690 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4692 ret = CallWindowProcA(tmpWnd->winproc,
4693 ddraw->d.mainWindow, msg, wParam, lParam );
4695 WIN_ReleaseWndPtr(tmpWnd);
4700 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4706 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4712 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4713 #ifdef HAVE_LIBXXF86DGA
4714 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4715 int memsize,banksize,width,major,minor,flags,height;
4720 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4721 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4725 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4726 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4727 return E_UNEXPECTED;
4729 if (!DDRAW_DGA_Available()) {
4730 TRACE(ddraw,"No XF86DGA detected.\n");
4731 return DDERR_GENERIC;
4733 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4734 (*ilplpDD)->lpvtbl = &dga_ddvt;
4735 (*ilplpDD)->ref = 1;
4736 TSXF86DGAQueryVersion(display,&major,&minor);
4737 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4738 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4739 if (!(flags & XF86DGADirectPresent))
4740 MSG("direct video is NOT PRESENT.\n");
4741 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4742 (*ilplpDD)->e.dga.fb_width = width;
4743 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4744 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4745 (*ilplpDD)->e.dga.fb_height = height;
4746 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4747 addr,width,banksize,memsize
4749 TRACE(ddraw,"viewport height: %d\n",height);
4751 /* Get the screen dimensions as seen by Wine.
4752 In that case, it may be better to ignore the -desktop mode and return the
4753 real screen size => print a warning */
4754 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4755 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4756 if (((*ilplpDD)->d.height != height) ||
4757 ((*ilplpDD)->d.width != width))
4758 WARN(ddraw, "You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
4759 (*ilplpDD)->e.dga.fb_addr = addr;
4760 (*ilplpDD)->e.dga.fb_memsize = memsize;
4761 (*ilplpDD)->e.dga.fb_banksize = banksize;
4762 (*ilplpDD)->e.dga.vpmask = 0;
4764 /* just assume the default depth is the DGA depth too */
4765 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4766 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4767 #ifdef RESTORE_SIGNALS
4772 #else /* defined(HAVE_LIBXXF86DGA) */
4773 return DDERR_INVALIDDIRECTDRAWGUID;
4774 #endif /* defined(HAVE_LIBXXF86DGA) */
4778 DDRAW_XSHM_Available(void)
4780 #ifdef HAVE_LIBXXSHM
4781 if (TSXShmQueryExtension(display))
4786 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4798 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4799 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4802 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4803 (*ilplpDD)->lpvtbl = &xlib_ddvt;
4804 (*ilplpDD)->ref = 1;
4805 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
4807 /* At DirectDraw creation, the depth is the default depth */
4808 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4809 _common_depth_to_pixelformat(depth,
4810 &((*ilplpDD)->d.directdraw_pixelformat),
4811 &((*ilplpDD)->d.screen_pixelformat),
4812 &((*ilplpDD)->d.pixmap_depth));
4813 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4814 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4816 #ifdef HAVE_LIBXXSHM
4817 /* Test if XShm is available. */
4818 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4819 TRACE(ddraw, "Using XShm extension.\n");
4825 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4826 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4829 /* WND* pParentWindow; */
4833 WINE_StringFromCLSID(lpGUID,xclsid);
4835 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4839 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
4842 (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4843 (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4844 (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4845 /* if they didn't request a particular interface, use the best
4847 if (DDRAW_DGA_Available())
4848 lpGUID = &DGA_DirectDraw_GUID;
4850 lpGUID = &XLIB_DirectDraw_GUID;
4853 wc.style = CS_GLOBALCLASS;
4854 wc.lpfnWndProc = Xlib_DDWndProc;
4856 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
4857 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
4859 /* We can be a child of the desktop since we're really important */
4861 This code is not useful since hInstance is forced to 0 afterward
4862 pParentWindow = WIN_GetDesktop();
4863 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
4869 wc.hCursor = (HCURSOR)IDC_ARROWA;
4870 wc.hbrBackground= NULL_BRUSH;
4871 wc.lpszMenuName = 0;
4872 wc.lpszClassName= "WINE_DirectDraw";
4873 RegisterClassA(&wc);
4875 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4876 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4877 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4878 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4883 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
4887 ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4888 return DDERR_INVALIDDIRECTDRAWGUID;
4892 #else /* !defined(X_DISPLAY_MISSING) */
4898 typedef void *LPGUID;
4899 typedef void *LPUNKNOWN;
4900 typedef void *LPDIRECTDRAW;
4901 typedef void *LPDIRECTDRAWCLIPPER;
4902 typedef void *LPDDENUMCALLBACKA;
4903 typedef void *LPDDENUMCALLBACKEXA;
4904 typedef void *LPDDENUMCALLBACKEXW;
4905 typedef void *LPDDENUMCALLBACKW;
4907 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
4912 HRESULT WINAPI DirectDrawCreate(
4913 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
4918 HRESULT WINAPI DirectDrawCreateClipper(
4919 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
4924 HRESULT WINAPI DirectDrawEnumerateA(
4925 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
4930 HRESULT WINAPI DirectDrawEnumerateExA(
4931 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
4936 HRESULT WINAPI DirectDrawEnumerateExW(
4937 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
4942 HRESULT WINAPI DirectDrawEnumerateW(
4943 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
4948 #endif /* !defined(X_DISPLAY_MISSING) */
4951 /*******************************************************************************
4952 * DirectDraw ClassFactory
4954 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
4959 /* IUnknown fields */
4960 ICOM_VTABLE(IClassFactory)* lpvtbl;
4962 } IClassFactoryImpl;
4964 static HRESULT WINAPI
4965 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
4966 ICOM_THIS(IClassFactoryImpl,iface);
4970 WINE_StringFromCLSID(riid,buf);
4972 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4973 FIXME(ddraw,"(%p)->(%s,%p),stub!\n",This,buf,ppobj);
4974 return E_NOINTERFACE;
4978 DDCF_AddRef(LPCLASSFACTORY iface) {
4979 ICOM_THIS(IClassFactoryImpl,iface);
4980 return ++(This->ref);
4983 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
4984 ICOM_THIS(IClassFactoryImpl,iface);
4985 /* static class, won't be freed */
4986 return --(This->ref);
4989 static HRESULT WINAPI DDCF_CreateInstance(
4990 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
4992 ICOM_THIS(IClassFactoryImpl,iface);
4995 WINE_StringFromCLSID(riid,buf);
4996 TRACE(ddraw,"(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
4997 if ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4998 (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4999 (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
5000 /* FIXME: reuse already created DirectDraw if present? */
5001 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5003 return E_NOINTERFACE;
5006 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5007 ICOM_THIS(IClassFactoryImpl,iface);
5008 FIXME(ddraw,"(%p)->(%d),stub!\n",This,dolock);
5012 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5014 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5015 DDCF_QueryInterface,
5018 DDCF_CreateInstance,
5021 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5023 /*******************************************************************************
5024 * DllGetClassObject [DDRAW.13]
5025 * Retrieves class object from a DLL object
5028 * Docs say returns STDAPI
5031 * rclsid [I] CLSID for the class object
5032 * riid [I] Reference to identifier of interface for class object
5033 * ppv [O] Address of variable to receive interface pointer for riid
5037 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5040 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5042 char buf[80],xbuf[80];
5045 WINE_StringFromCLSID(rclsid,xbuf);
5047 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
5049 WINE_StringFromCLSID(riid,buf);
5051 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5052 WINE_StringFromCLSID(riid,xbuf);
5053 TRACE(ddraw, "(%p,%p,%p)\n", xbuf, buf, ppv);
5054 if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
5055 *ppv = (LPVOID)&DDRAW_CF;
5056 IClassFactory_AddRef((IClassFactory*)*ppv);
5059 FIXME(ddraw, "(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
5060 return E_NOINTERFACE;
5064 /*******************************************************************************
5065 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5071 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5073 FIXME(ddraw, "(void): stub\n");