1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
19 #ifndef X_DISPLAY_MISSING
25 #include <sys/types.h>
29 #endif /* defined(HAVE_LIBXXSHM) */
31 #ifdef HAVE_LIBXXF86DGA
32 #include "ts_xf86dga.h"
33 #endif /* defined(HAVE_LIBXXF86DGA) */
35 #ifdef HAVE_LIBXXF86VM
36 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
37 this is a crude hack to get around it */
40 #include "ts_xf86vmode.h"
41 #endif /* defined(HAVE_LIBXXF86VM) */
47 #include <sys/signal.h>
66 /* This for all the enumeration and creation of D3D-related objects */
67 #include "ddraw_private.h"
68 #include "d3d_private.h"
70 DEFAULT_DEBUG_CHANNEL(ddraw)
72 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
75 /* Restore signal handlers overwritten by XF86DGA
77 #define RESTORE_SIGNALS
79 /* Where do these GUIDs come from? mkuuid.
80 * They exist solely to distinguish between the targets Wine support,
81 * and should be different than any other GUIDs in existence.
83 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
87 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
90 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
94 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
97 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt, xlib_dds4vt;
98 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt, xlib_ddvt;
99 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt, xlib_dd2vt;
100 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt, xlib_dd4vt;
101 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
102 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt, xlib_ddpalvt;
103 static struct ICOM_VTABLE(IDirect3D) d3dvt;
104 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
106 #ifdef HAVE_LIBXXF86VM
107 static XF86VidModeModeInfo *orig_mode = NULL;
111 static int XShmErrorFlag = 0;
115 DDRAW_DGA_Available(void)
117 #ifdef HAVE_LIBXXF86DGA
118 int evbase, evret, fd;
123 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
124 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
125 /* others. --stephenc */
126 if ((fd = open("/dev/mem", O_RDWR)) != -1)
129 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
130 #else /* defined(HAVE_LIBXXF86DGA) */
132 #endif /* defined(HAVE_LIBXXF86DGA) */
135 /**********************************************************************/
140 } DirectDrawEnumerateProcData;
142 /***********************************************************************
143 * DirectDrawEnumerateExA (DDRAW.*)
145 HRESULT WINAPI DirectDrawEnumerateExA(
146 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
148 TRACE(ddraw, "(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
150 if (TRACE_ON(ddraw)) {
152 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
153 DUMP("DDENUM_ATTACHEDSECONDARYDEVICES ");
154 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
155 DUMP("DDENUM_DETACHEDSECONDARYDEVICES ");
156 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
157 DUMP("DDENUM_NONDISPLAYDEVICES ");
161 if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
162 /* For the moment, Wine does not support any 3D only accelerators */
166 if (DDRAW_DGA_Available()) {
167 TRACE(ddraw, "Enumerating DGA interface\n");
168 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
172 TRACE(ddraw, "Enumerating Xlib interface\n");
173 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
176 TRACE(ddraw, "Enumerating Default interface\n");
177 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
183 /***********************************************************************
184 * DirectDrawEnumerateExW (DDRAW.*)
187 static BOOL CALLBACK DirectDrawEnumerateExProcW(
188 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
189 LPVOID lpContext, HMONITOR hm)
191 DirectDrawEnumerateProcData *pEPD =
192 (DirectDrawEnumerateProcData *) lpContext;
193 LPWSTR lpDriverDescriptionW =
194 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
195 LPWSTR lpDriverNameW =
196 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
198 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
199 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
201 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
202 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
207 /**********************************************************************/
209 HRESULT WINAPI DirectDrawEnumerateExW(
210 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
212 DirectDrawEnumerateProcData epd;
213 epd.lpCallback = lpCallback;
214 epd.lpContext = lpContext;
216 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
220 /***********************************************************************
221 * DirectDrawEnumerateA (DDRAW.*)
224 static BOOL CALLBACK DirectDrawEnumerateProcA(
225 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
226 LPVOID lpContext, HMONITOR hm)
228 DirectDrawEnumerateProcData *pEPD =
229 (DirectDrawEnumerateProcData *) lpContext;
231 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
232 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
235 /**********************************************************************/
237 HRESULT WINAPI DirectDrawEnumerateA(
238 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
240 DirectDrawEnumerateProcData epd;
241 epd.lpCallback = lpCallback;
242 epd.lpContext = lpContext;
244 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
248 /***********************************************************************
249 * DirectDrawEnumerateW (DDRAW.*)
252 static BOOL WINAPI DirectDrawEnumerateProcW(
253 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
254 LPVOID lpContext, HMONITOR hm)
256 DirectDrawEnumerateProcData *pEPD =
257 (DirectDrawEnumerateProcData *) lpContext;
259 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
260 lpGUID, lpDriverDescription, lpDriverName,
264 /**********************************************************************/
266 HRESULT WINAPI DirectDrawEnumerateW(
267 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
269 DirectDrawEnumerateProcData epd;
270 epd.lpCallback = lpCallback;
271 epd.lpContext = lpContext;
273 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
277 /***********************************************************************
278 * DSoundHelp (DDRAW.?)
281 /* What is this doing here? */
283 DSoundHelp(DWORD x,DWORD y,DWORD z) {
284 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
288 /******************************************************************************
289 * internal helper functions
291 static void _dump_DDBLTFX(DWORD flagmask) {
297 #define FE(x) { x, #x},
298 FE(DDBLTFX_ARITHSTRETCHY)
299 FE(DDBLTFX_MIRRORLEFTRIGHT)
300 FE(DDBLTFX_MIRRORUPDOWN)
301 FE(DDBLTFX_NOTEARING)
302 FE(DDBLTFX_ROTATE180)
303 FE(DDBLTFX_ROTATE270)
305 FE(DDBLTFX_ZBUFFERRANGE)
306 FE(DDBLTFX_ZBUFFERBASEDEST)
308 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
309 if (flags[i].mask & flagmask) {
310 DUMP("%s ",flags[i].name);
317 static void _dump_DDBLTFAST(DWORD flagmask) {
323 #define FE(x) { x, #x},
324 FE(DDBLTFAST_NOCOLORKEY)
325 FE(DDBLTFAST_SRCCOLORKEY)
326 FE(DDBLTFAST_DESTCOLORKEY)
329 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
330 if (flags[i].mask & flagmask)
331 DUMP("%s ",flags[i].name);
335 static void _dump_DDBLT(DWORD flagmask) {
341 #define FE(x) { x, #x},
343 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
344 FE(DDBLT_ALPHADESTNEG)
345 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
346 FE(DDBLT_ALPHAEDGEBLEND)
348 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
349 FE(DDBLT_ALPHASRCNEG)
350 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
356 FE(DDBLT_KEYDESTOVERRIDE)
358 FE(DDBLT_KEYSRCOVERRIDE)
360 FE(DDBLT_ROTATIONANGLE)
362 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
363 FE(DDBLT_ZBUFFERDESTOVERRIDE)
364 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
365 FE(DDBLT_ZBUFFERSRCOVERRIDE)
369 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
370 if (flags[i].mask & flagmask)
371 DUMP("%s ",flags[i].name);
375 static void _dump_DDSCAPS(DWORD flagmask) {
381 #define FE(x) { x, #x},
382 FE(DDSCAPS_RESERVED1)
384 FE(DDSCAPS_BACKBUFFER)
387 FE(DDSCAPS_FRONTBUFFER)
388 FE(DDSCAPS_OFFSCREENPLAIN)
391 FE(DDSCAPS_PRIMARYSURFACE)
392 FE(DDSCAPS_PRIMARYSURFACELEFT)
393 FE(DDSCAPS_SYSTEMMEMORY)
396 FE(DDSCAPS_VIDEOMEMORY)
398 FE(DDSCAPS_WRITEONLY)
401 FE(DDSCAPS_LIVEVIDEO)
405 FE(DDSCAPS_RESERVED2)
406 FE(DDSCAPS_ALLOCONLOAD)
407 FE(DDSCAPS_VIDEOPORT)
408 FE(DDSCAPS_LOCALVIDMEM)
409 FE(DDSCAPS_NONLOCALVIDMEM)
410 FE(DDSCAPS_STANDARDVGAMODE)
411 FE(DDSCAPS_OPTIMIZED)
413 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
414 if (flags[i].mask & flagmask)
415 DUMP("%s ",flags[i].name);
419 static void _dump_DDSD(DWORD flagmask) {
429 FE(DDSD_BACKBUFFERCOUNT)
430 FE(DDSD_ZBUFFERBITDEPTH)
431 FE(DDSD_ALPHABITDEPTH)
433 FE(DDSD_CKDESTOVERLAY)
435 FE(DDSD_CKSRCOVERLAY)
442 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
443 if (flags[i].mask & flagmask)
444 DUMP("%s ",flags[i].name);
448 static void _dump_DDCOLORKEY(DWORD flagmask) {
454 #define FE(x) { x, #x},
458 FE(DDPF_PALETTEINDEXED4)
459 FE(DDPF_PALETTEINDEXEDTO8)
460 FE(DDPF_PALETTEINDEXED8)
466 FE(DDPF_PALETTEINDEXED1)
467 FE(DDPF_PALETTEINDEXED2)
470 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
471 if (flags[i].mask & flagmask)
472 DUMP("%s ",flags[i].name);
476 static void _dump_paletteformat(DWORD dwFlags) {
482 #define FE(x) { x, #x},
484 FE(DDPCAPS_8BITENTRIES)
486 FE(DDPCAPS_INITIALIZE)
487 FE(DDPCAPS_PRIMARYSURFACE)
488 FE(DDPCAPS_PRIMARYSURFACELEFT)
495 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
496 if (flags[i].mask & dwFlags)
497 DUMP("%s ",flags[i].name);
501 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
502 DUMP("Size : %ld\n", pf->dwSize);
504 _dump_DDCOLORKEY(pf->dwFlags);
505 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
506 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
507 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
508 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
511 static void _dump_colorkeyflag(DWORD ck) {
517 #define FE(x) { x, #x},
518 FE(DDCKEY_COLORSPACE)
520 FE(DDCKEY_DESTOVERLAY)
522 FE(DDCKEY_SRCOVERLAY)
524 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
525 if (flags[i].mask & ck)
526 DUMP("%s ",flags[i].name);
530 /******************************************************************************
531 * IDirectDrawSurface methods
533 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
534 * DDS and DDS2 use those functions. (Function calls did not change (except
535 * using different DirectDrawSurfaceX version), just added flags and functions)
537 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
538 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
540 ICOM_THIS(IDirectDrawSurface4Impl,iface);
541 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
542 This,lprect,lpddsd,flags,(DWORD)hnd);
543 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
544 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
545 This,lprect,lpddsd,flags,(DWORD)hnd);
547 /* First, copy the Surface description */
548 *lpddsd = This->s.surface_desc;
549 TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
550 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
552 /* If asked only for a part, change the surface pointer */
554 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
555 lprect->top,lprect->left,lprect->bottom,lprect->right
557 lpddsd->y.lpSurface = This->s.surface_desc.y.lpSurface +
558 (lprect->top*This->s.surface_desc.lPitch) +
559 (lprect->left*(This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
561 assert(This->s.surface_desc.y.lpSurface);
566 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
567 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
569 ICOM_THIS(IDirectDrawSurface4Impl,iface);
570 TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
574 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
575 if (This->s.ddraw->d.pixel_convert != NULL)
576 This->s.ddraw->d.pixel_convert(This->s.surface_desc.y.lpSurface,
577 This->t.xlib.image->data,
578 This->s.surface_desc.dwWidth,
579 This->s.surface_desc.dwHeight,
580 This->s.surface_desc.lPitch,
584 if (This->s.ddraw->e.xlib.xshm_active)
585 TSXShmPutImage(display,
586 This->s.ddraw->d.drawable,
587 DefaultGCOfScreen(X11DRV_GetXScreen()),
590 This->t.xlib.image->width,
591 This->t.xlib.image->height,
595 TSXPutImage( display,
596 This->s.ddraw->d.drawable,
597 DefaultGCOfScreen(X11DRV_GetXScreen()),
600 This->t.xlib.image->width,
601 This->t.xlib.image->height);
604 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
605 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
607 ICOM_THIS(IDirectDrawSurface4Impl,iface);
608 TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
610 if (!This->s.ddraw->d.paintable)
613 /* Only redraw the screen when unlocking the buffer that is on screen */
614 if ((This->t.xlib.image != NULL) &&
615 (This->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
616 Xlib_copy_surface_on_screen(This);
618 if (This->s.palette && This->s.palette->cm)
619 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
625 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
626 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
628 ICOM_THIS(IDirectDrawSurface4Impl,iface);
629 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
630 #ifdef HAVE_LIBXXF86DGA
631 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
633 if (This->s.backbuffer)
634 iflipto = This->s.backbuffer;
638 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
640 if (iflipto->s.palette && iflipto->s.palette->cm) {
641 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
643 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
649 tmp = This->t.dga.fb_height;
650 This->t.dga.fb_height = iflipto->t.dga.fb_height;
651 iflipto->t.dga.fb_height = tmp;
653 ptmp = This->s.surface_desc.y.lpSurface;
654 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
655 iflipto->s.surface_desc.y.lpSurface = ptmp;
658 #else /* defined(HAVE_LIBXXF86DGA) */
660 #endif /* defined(HAVE_LIBXXF86DGA) */
663 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
664 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
666 ICOM_THIS(IDirectDrawSurface4Impl,iface);
667 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
668 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
669 if (!This->s.ddraw->d.paintable)
673 if (This->s.backbuffer)
674 iflipto = This->s.backbuffer;
679 Xlib_copy_surface_on_screen(This);
681 if (iflipto->s.palette && iflipto->s.palette->cm) {
682 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
687 tmp = This->t.xlib.image;
688 This->t.xlib.image = iflipto->t.xlib.image;
689 iflipto->t.xlib.image = tmp;
690 surf = This->s.surface_desc.y.lpSurface;
691 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
692 iflipto->s.surface_desc.y.lpSurface = surf;
698 /* The IDirectDrawSurface4::SetPalette method attaches the specified
699 * DirectDrawPalette object to a surface. The surface uses this palette for all
700 * subsequent operations. The palette change takes place immediately.
702 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
703 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
705 ICOM_THIS(IDirectDrawSurface4Impl,iface);
706 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
708 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
711 if( This->s.palette != NULL )
712 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
713 This->s.palette = ipal;
718 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
720 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
721 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
723 if (!Options.managed)
724 TSXInstallColormap(display,ipal->cm);
726 for (i=0;i<256;i++) {
729 xc.red = ipal->palents[i].peRed<<8;
730 xc.blue = ipal->palents[i].peBlue<<8;
731 xc.green = ipal->palents[i].peGreen<<8;
732 xc.flags = DoRed|DoBlue|DoGreen;
734 TSXStoreColor(display,ipal->cm,&xc);
736 TSXInstallColormap(display,ipal->cm);
739 /* According to spec, we are only supposed to
740 * AddRef if this is not the same palette.
742 if( This->s.palette != ipal )
745 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
746 if( This->s.palette != NULL )
747 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
748 This->s.palette = ipal;
750 /* I think that we need to attach it to all backbuffers...*/
751 if( This->s.backbuffer ) {
752 if( This->s.backbuffer->s.palette )
753 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
754 This->s.backbuffer->s.palette = ipal;
756 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
758 /* Perform the refresh */
759 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
764 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
765 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
767 ICOM_THIS(IDirectDrawSurface4Impl,iface);
768 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
769 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
770 #ifdef HAVE_LIBXXF86DGA
771 /* According to spec, we are only supposed to
772 * AddRef if this is not the same palette.
774 if( This->s.palette != ipal )
777 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
778 if( This->s.palette != NULL )
779 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
780 This->s.palette = ipal;
782 /* I think that we need to attach it to all backbuffers...*/
783 if( This->s.backbuffer ) {
784 if( This->s.backbuffer->s.palette )
785 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
786 This->s.backbuffer->s.palette = ipal;
788 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
790 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
793 #else /* defined(HAVE_LIBXXF86DGA) */
795 #endif /* defined(HAVE_LIBXXF86DGA) */
800 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
807 #define COLORFILL_ROW(type) { \
808 type *d = (type *) buf; \
809 for (x = 0; x < width; x++) \
810 d[x] = (type) color; \
815 case 1: COLORFILL_ROW(BYTE)
816 case 2: COLORFILL_ROW(WORD)
817 case 4: COLORFILL_ROW(DWORD)
819 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
820 return DDERR_UNSUPPORTED;
825 /* Now copy first row */
827 for (y = 1; y < height; y++) {
829 memcpy(buf, first, width * bpp);
835 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
836 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
838 ICOM_THIS(IDirectDrawSurface4Impl,iface);
840 DDSURFACEDESC ddesc,sdesc;
842 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
846 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
848 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
849 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
851 if (TRACE_ON(ddraw)) {
852 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
853 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
854 TRACE(ddraw,"\tflags: ");
855 _dump_DDBLT(dwFlags);
856 if (dwFlags & DDBLT_DDFX) {
857 TRACE(ddraw," blitfx: \n");
858 _dump_DDBLTFX(lpbltfx->dwDDFX);
863 memcpy(&xdst,rdst,sizeof(xdst));
866 xdst.bottom = ddesc.dwHeight;
868 xdst.right = ddesc.dwWidth;
872 memcpy(&xsrc,rsrc,sizeof(xsrc));
876 xsrc.bottom = sdesc.dwHeight;
878 xsrc.right = sdesc.dwWidth;
880 memset(&xsrc,0,sizeof(xsrc));
884 bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
885 srcheight = xsrc.bottom - xsrc.top;
886 srcwidth = xsrc.right - xsrc.left;
887 dstheight = xdst.bottom - xdst.top;
888 dstwidth = xdst.right - xdst.left;
889 width = (xdst.right - xdst.left) * bpp;
890 dbuf = ddesc.y.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
892 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
894 /* First, all the 'source-less' blits */
895 if (dwFlags & DDBLT_COLORFILL) {
896 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
897 ddesc.lPitch, lpbltfx->b.dwFillColor);
898 dwFlags &= ~DDBLT_COLORFILL;
901 if (dwFlags & DDBLT_DEPTHFILL) {
905 /* Clears the screen */
906 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
907 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
908 glGetBooleanv(GL_DEPTH_TEST, &ztest);
909 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
910 glClear(GL_DEPTH_BUFFER_BIT);
913 dwFlags &= ~(DDBLT_DEPTHFILL);
917 if (dwFlags & DDBLT_ROP) {
918 /* Catch some degenerate cases here */
919 switch(lpbltfx->dwROP) {
921 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
923 case 0xAA0029: /* No-op */
926 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
929 FIXME(ddraw, "Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->b.lpDDSPattern);
932 dwFlags &= ~DDBLT_ROP;
935 if (dwFlags & DDBLT_DDROPS) {
936 FIXME(ddraw, "\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->b.lpDDSPattern);
939 /* Now the 'with source' blits */
942 int sx, xinc, sy, yinc;
944 sbase = sdesc.y.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
945 xinc = (srcwidth << 16) / dstwidth;
946 yinc = (srcheight << 16) / dstheight;
950 /* No effects, we can cheat here */
951 if (dstwidth == srcwidth) {
952 if (dstheight == srcheight) {
953 /* No stretching in either direction. This needs to be as fast as possible */
955 for (y = 0; y < dstheight; y++) {
956 memcpy(dbuf, sbuf, width);
957 sbuf += sdesc.lPitch;
958 dbuf += ddesc.lPitch;
961 /* Stretching in Y direction only */
962 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
963 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
964 memcpy(dbuf, sbuf, width);
965 dbuf += ddesc.lPitch;
969 /* Stretching in X direction */
971 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
972 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
974 if ((sy >> 16) == (last_sy >> 16)) {
975 /* Same as last row - copy already stretched row */
976 memcpy(dbuf, dbuf - ddesc.lPitch, width);
979 #define STRETCH_ROW(type) { \
980 type *s = (type *) sbuf, *d = (type *) dbuf; \
981 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
982 d[x] = s[sx >> 16]; \
987 case 1: STRETCH_ROW(BYTE)
988 case 2: STRETCH_ROW(WORD)
989 case 4: STRETCH_ROW(DWORD)
991 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
992 ret = DDERR_UNSUPPORTED;
1000 dbuf += ddesc.lPitch;
1003 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1004 DWORD keylow, keyhigh;
1006 if (dwFlags & DDBLT_KEYSRC) {
1007 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1008 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1010 /* I'm not sure if this is correct */
1011 FIXME(ddraw, "DDBLT_KEYDEST not fully supported yet.\n");
1012 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1013 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1016 #define COPYROW_COLORKEY(type) { \
1017 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1018 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1019 tmp = s[sx >> 16]; \
1020 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1025 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1026 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1029 case 1: COPYROW_COLORKEY(BYTE)
1030 case 2: COPYROW_COLORKEY(WORD)
1031 case 4: COPYROW_COLORKEY(DWORD)
1033 FIXME(ddraw, "%s color-keyed blit not implemented for bpp %d!\n",
1034 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1035 ret = DDERR_UNSUPPORTED;
1038 dbuf += ddesc.lPitch;
1041 #undef COPYROW_COLORKEY
1043 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1050 if (dwFlags && FIXME_ON(ddraw)) {
1051 FIXME(ddraw,"\tUnsupported flags: ");
1052 _dump_DDBLT(dwFlags);
1055 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1056 if (src) IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1061 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1062 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1064 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1065 int bpp, w, h, x, y;
1066 DDSURFACEDESC ddesc,sdesc;
1067 HRESULT ret = DD_OK;
1071 if (TRACE_ON(ddraw)) {
1072 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1073 This,dstx,dsty,src,rsrc,trans
1075 FIXME(ddraw," trans:");
1076 if (FIXME_ON(ddraw))
1077 _dump_DDBLTFAST(trans);
1078 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1080 /* We need to lock the surfaces, or we won't get refreshes when done. */
1081 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1082 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1084 bpp = This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
1085 sbuf = sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1086 dbuf = ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1089 h=rsrc->bottom-rsrc->top;
1090 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1091 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1094 w=rsrc->right-rsrc->left;
1095 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1096 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1099 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1100 DWORD keylow, keyhigh;
1101 if (trans & DDBLTFAST_SRCCOLORKEY) {
1102 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1103 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1105 /* I'm not sure if this is correct */
1106 FIXME(ddraw, "DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1107 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1108 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1111 #define COPYBOX_COLORKEY(type) { \
1112 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1113 s = sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp; \
1114 d = ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp; \
1115 for (y = 0; y < h; y++) { \
1116 for (x = 0; x < w; x++) { \
1118 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1120 (LPBYTE)s += sdesc.lPitch; \
1121 (LPBYTE)d += ddesc.lPitch; \
1127 case 1: COPYBOX_COLORKEY(BYTE)
1128 case 2: COPYBOX_COLORKEY(WORD)
1129 case 4: COPYBOX_COLORKEY(DWORD)
1131 FIXME(ddraw, "Source color key blitting not supported for bpp %d\n", bpp*8);
1132 ret = DDERR_UNSUPPORTED;
1136 #undef COPYBOX_COLORKEY
1139 int width = w * bpp;
1141 for (y = 0; y < h; y++) {
1142 memcpy(dbuf, sbuf, width);
1143 sbuf += sdesc.lPitch;
1144 dbuf += ddesc.lPitch;
1150 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1151 IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1155 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1156 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1158 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1159 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1165 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1166 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1168 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1169 TRACE(ddraw,"(%p)->GetCaps(%p)\n",This,caps);
1170 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1174 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1175 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1177 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1178 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
1181 /* Simply copy the surface description stored in the object */
1182 *ddsd = This->s.surface_desc;
1184 if (TRACE_ON(ddraw)) {
1186 _dump_DDSD(ddsd->dwFlags);
1187 if (ddsd->dwFlags & DDSD_CAPS) {
1189 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
1191 if (ddsd->dwFlags & DDSD_PIXELFORMAT) {
1192 DUMP(" pixel format : \n");
1193 _dump_pixelformat(&(ddsd->ddpfPixelFormat));
1200 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1201 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1202 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1204 return ++(This->ref);
1207 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1208 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1209 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1211 #ifdef HAVE_LIBXXF86DGA
1212 if (!--(This->ref)) {
1213 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1214 /* clear out of surface list */
1215 if (This->t.dga.fb_height == -1) {
1216 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1218 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1221 /* Free the backbuffer */
1222 if (This->s.backbuffer)
1223 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1225 HeapFree(GetProcessHeap(),0,This);
1228 #endif /* defined(HAVE_LIBXXF86DGA) */
1232 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1233 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1234 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1236 if (!--(This->ref)) {
1237 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1239 if( This->s.backbuffer )
1240 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1242 if (This->t.xlib.image != NULL) {
1243 if (This->s.ddraw->d.pixel_convert != NULL) {
1244 /* In pixel conversion mode, there are two buffers to release... */
1245 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1247 #ifdef HAVE_LIBXXSHM
1248 if (This->s.ddraw->e.xlib.xshm_active) {
1249 TSXShmDetach(display, &(This->t.xlib.shminfo));
1250 TSXDestroyImage(This->t.xlib.image);
1251 shmdt(This->t.xlib.shminfo.shmaddr);
1254 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1255 This->t.xlib.image->data = NULL;
1256 TSXDestroyImage(This->t.xlib.image);
1257 #ifdef HAVE_LIBXXSHM
1262 This->t.xlib.image->data = NULL;
1264 #ifdef HAVE_LIBXXSHM
1265 if (This->s.ddraw->e.xlib.xshm_active) {
1266 TSXShmDetach(display, &(This->t.xlib.shminfo));
1267 TSXDestroyImage(This->t.xlib.image);
1268 shmdt(This->t.xlib.shminfo.shmaddr);
1271 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1272 TSXDestroyImage(This->t.xlib.image);
1273 #ifdef HAVE_LIBXXSHM
1278 This->t.xlib.image = 0;
1280 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1283 if (This->s.palette)
1284 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1286 HeapFree(GetProcessHeap(),0,This);
1293 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1294 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1296 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1297 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1298 This, lpddsd, lpdsf);
1300 if (TRACE_ON(ddraw)) {
1301 TRACE(ddraw," caps ");
1302 _dump_DDSCAPS(lpddsd->dwCaps);
1305 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1306 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1310 /* FIXME: should handle more than one backbuffer */
1311 *lpdsf = (LPDIRECTDRAWSURFACE4)This->s.backbuffer;
1313 if( This->s.backbuffer )
1314 IDirectDrawSurface4_AddRef( (IDirectDrawSurface4*)This->s.backbuffer );
1319 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1320 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1322 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1323 TRACE(ddraw,"(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1325 return DDERR_ALREADYINITIALIZED;
1328 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1329 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1331 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1332 TRACE(ddraw,"(%p)->(%p)\n",This,pf);
1334 *pf = This->s.surface_desc.ddpfPixelFormat;
1339 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1340 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1341 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,dwFlags);
1345 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1346 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1348 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1349 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,x1,x2);
1353 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1354 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1356 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1357 FIXME(ddraw,"(%p)->(%p),stub!\n",This,clipper);
1361 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1362 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1364 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1365 FIXME(ddraw,"(%p)->(%p),stub!\n",This,surf);
1367 IDirectDrawSurface4_AddRef(iface);
1369 /* This hack will be enough for the moment */
1370 if (This->s.backbuffer == NULL)
1371 This->s.backbuffer = (IDirectDrawSurface4Impl*)surf;
1375 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1376 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1377 FIXME(ddraw,"(%p)->GetDC(%p)\n",This,lphdc);
1378 *lphdc = BeginPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1382 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1383 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1387 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1388 EndPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1390 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1391 I fill it with 'dummy' values to have something on the screen */
1392 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1393 for (y = 0; y < desc.dwHeight; y++) {
1394 for (x = 0; x < desc.dwWidth; x++) {
1395 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) This + x + y;
1398 IDirectDrawSurface4_Unlock(iface,NULL);
1404 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1405 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1408 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1409 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
1411 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1412 * the same interface. And IUnknown does that too of course.
1414 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1415 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1416 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1417 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1418 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1421 IDirectDrawSurface4_AddRef(iface);
1423 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1427 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1429 /* Texture interface */
1430 *obj = d3dtexture2_create(This);
1431 IDirectDrawSurface4_AddRef(iface);
1433 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1437 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1439 /* Texture interface */
1440 *obj = d3dtexture_create(This);
1441 IDirectDrawSurface4_AddRef(iface);
1443 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1447 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj))
1449 /* It is the OpenGL Direct3D Device */
1450 IDirectDrawSurface4_AddRef(iface);
1452 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1457 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
1458 return OLE_E_ENUM_NOMORE;
1461 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1462 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1463 TRACE(ddraw,"(%p)->(), stub!\n",This);
1464 return DD_OK; /* hmm */
1467 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1468 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1469 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,context,esfcb);
1471 /* For the moment, only enumerating the back buffer */
1472 if (This->s.backbuffer != NULL) {
1473 TRACE(ddraw, "Enumerating back-buffer (%p)\n", This->s.backbuffer);
1474 if (esfcb((LPDIRECTDRAWSURFACE) This->s.backbuffer, &(This->s.backbuffer->s.surface_desc), context) == DDENUMRET_CANCEL)
1481 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1482 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1483 FIXME(ddraw,"(%p)->(),stub!\n",This);
1487 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1488 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1490 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1491 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1492 if (TRACE_ON(ddraw)) {
1493 DUMP(" (0x%08lx <-> 0x%08lx) - ",
1494 ckey->dwColorSpaceLowValue,
1495 ckey->dwColorSpaceHighValue);
1496 _dump_colorkeyflag(dwFlags);
1499 /* If this surface was loaded as a texture, call also the texture
1500 SetColorKey callback */
1501 if (This->s.texture) {
1502 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1505 if( dwFlags & DDCKEY_SRCBLT )
1507 dwFlags &= ~DDCKEY_SRCBLT;
1508 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1509 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1512 if( dwFlags & DDCKEY_DESTBLT )
1514 dwFlags &= ~DDCKEY_DESTBLT;
1515 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1516 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1519 if( dwFlags & DDCKEY_SRCOVERLAY )
1521 dwFlags &= ~DDCKEY_SRCOVERLAY;
1522 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1523 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1526 if( dwFlags & DDCKEY_DESTOVERLAY )
1528 dwFlags &= ~DDCKEY_DESTOVERLAY;
1529 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1530 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1535 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1542 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1543 LPDIRECTDRAWSURFACE4 iface,
1546 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1547 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpRect);
1552 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1553 LPDIRECTDRAWSURFACE4 iface,
1555 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1557 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1558 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",This,dwFlags,lpDDSAttachedSurface);
1563 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1564 LPDIRECTDRAWSURFACE4 iface,
1567 LPDDENUMSURFACESCALLBACK lpfnCallback )
1569 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1570 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1571 lpContext, lpfnCallback );
1576 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1577 LPDIRECTDRAWSURFACE4 iface,
1578 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1580 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1581 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDClipper);
1586 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1587 LPDIRECTDRAWSURFACE4 iface,
1589 LPDDCOLORKEY lpDDColorKey )
1591 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1592 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1594 if( dwFlags & DDCKEY_SRCBLT ) {
1595 dwFlags &= ~DDCKEY_SRCBLT;
1596 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1599 if( dwFlags & DDCKEY_DESTBLT )
1601 dwFlags &= ~DDCKEY_DESTBLT;
1602 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1605 if( dwFlags & DDCKEY_SRCOVERLAY )
1607 dwFlags &= ~DDCKEY_SRCOVERLAY;
1608 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1611 if( dwFlags & DDCKEY_DESTOVERLAY )
1613 dwFlags &= ~DDCKEY_DESTOVERLAY;
1614 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1619 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1625 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1626 LPDIRECTDRAWSURFACE4 iface,
1629 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1630 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1635 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1636 LPDIRECTDRAWSURFACE4 iface,
1637 LPDIRECTDRAWPALETTE* lplpDDPalette )
1639 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1640 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDPalette);
1645 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1646 LPDIRECTDRAWSURFACE4 iface,
1650 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1651 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1656 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1657 LPDIRECTDRAWSURFACE4 iface,
1659 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1662 LPDDOVERLAYFX lpDDOverlayFx )
1664 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1665 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1666 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1671 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1672 LPDIRECTDRAWSURFACE4 iface,
1675 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1676 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1681 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1682 LPDIRECTDRAWSURFACE4 iface,
1684 LPDIRECTDRAWSURFACE4 lpDDSReference )
1686 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1687 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1692 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1693 LPDIRECTDRAWSURFACE4 iface,
1696 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1697 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDD);
1699 /* Not sure about that... */
1700 *lplpDD = (void *) This->s.ddraw;
1705 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1706 LPDIRECTDRAWSURFACE4 iface,
1709 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1710 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1715 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1716 LPDIRECTDRAWSURFACE4 iface,
1719 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1720 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1725 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1726 LPDIRECTDRAWSURFACE4 iface,
1727 LPDDSURFACEDESC lpDDSD,
1730 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1731 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1736 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1741 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1742 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1747 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1750 LPDWORD lpcbBufferSize) {
1751 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1752 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1757 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
1759 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1760 FIXME(ddraw, "(%p)->(%p)\n", This, guidTag);
1765 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
1767 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1768 FIXME(ddraw, "(%p)->(%p)\n", This, lpValue);
1773 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
1774 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1775 FIXME(ddraw, "(%p)\n", This);
1780 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = {
1781 IDirectDrawSurface4Impl_QueryInterface,
1782 IDirectDrawSurface4Impl_AddRef,
1783 DGA_IDirectDrawSurface4Impl_Release,
1784 IDirectDrawSurface4Impl_AddAttachedSurface,
1785 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1786 IDirectDrawSurface4Impl_Blt,
1787 IDirectDrawSurface4Impl_BltBatch,
1788 IDirectDrawSurface4Impl_BltFast,
1789 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1790 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1791 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1792 DGA_IDirectDrawSurface4Impl_Flip,
1793 IDirectDrawSurface4Impl_GetAttachedSurface,
1794 IDirectDrawSurface4Impl_GetBltStatus,
1795 IDirectDrawSurface4Impl_GetCaps,
1796 IDirectDrawSurface4Impl_GetClipper,
1797 IDirectDrawSurface4Impl_GetColorKey,
1798 IDirectDrawSurface4Impl_GetDC,
1799 IDirectDrawSurface4Impl_GetFlipStatus,
1800 IDirectDrawSurface4Impl_GetOverlayPosition,
1801 IDirectDrawSurface4Impl_GetPalette,
1802 IDirectDrawSurface4Impl_GetPixelFormat,
1803 IDirectDrawSurface4Impl_GetSurfaceDesc,
1804 IDirectDrawSurface4Impl_Initialize,
1805 IDirectDrawSurface4Impl_IsLost,
1806 IDirectDrawSurface4Impl_Lock,
1807 IDirectDrawSurface4Impl_ReleaseDC,
1808 IDirectDrawSurface4Impl_Restore,
1809 IDirectDrawSurface4Impl_SetClipper,
1810 IDirectDrawSurface4Impl_SetColorKey,
1811 IDirectDrawSurface4Impl_SetOverlayPosition,
1812 DGA_IDirectDrawSurface4Impl_SetPalette,
1813 DGA_IDirectDrawSurface4Impl_Unlock,
1814 IDirectDrawSurface4Impl_UpdateOverlay,
1815 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1816 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1817 IDirectDrawSurface4Impl_GetDDInterface,
1818 IDirectDrawSurface4Impl_PageLock,
1819 IDirectDrawSurface4Impl_PageUnlock,
1820 IDirectDrawSurface4Impl_SetSurfaceDesc,
1821 IDirectDrawSurface4Impl_SetPrivateData,
1822 IDirectDrawSurface4Impl_GetPrivateData,
1823 IDirectDrawSurface4Impl_FreePrivateData,
1824 IDirectDrawSurface4Impl_GetUniquenessValue,
1825 IDirectDrawSurface4Impl_ChangeUniquenessValue
1828 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt = {
1829 IDirectDrawSurface4Impl_QueryInterface,
1830 IDirectDrawSurface4Impl_AddRef,
1831 Xlib_IDirectDrawSurface4Impl_Release,
1832 IDirectDrawSurface4Impl_AddAttachedSurface,
1833 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1834 IDirectDrawSurface4Impl_Blt,
1835 IDirectDrawSurface4Impl_BltBatch,
1836 IDirectDrawSurface4Impl_BltFast,
1837 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1838 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1839 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1840 Xlib_IDirectDrawSurface4Impl_Flip,
1841 IDirectDrawSurface4Impl_GetAttachedSurface,
1842 IDirectDrawSurface4Impl_GetBltStatus,
1843 IDirectDrawSurface4Impl_GetCaps,
1844 IDirectDrawSurface4Impl_GetClipper,
1845 IDirectDrawSurface4Impl_GetColorKey,
1846 IDirectDrawSurface4Impl_GetDC,
1847 IDirectDrawSurface4Impl_GetFlipStatus,
1848 IDirectDrawSurface4Impl_GetOverlayPosition,
1849 IDirectDrawSurface4Impl_GetPalette,
1850 IDirectDrawSurface4Impl_GetPixelFormat,
1851 IDirectDrawSurface4Impl_GetSurfaceDesc,
1852 IDirectDrawSurface4Impl_Initialize,
1853 IDirectDrawSurface4Impl_IsLost,
1854 IDirectDrawSurface4Impl_Lock,
1855 IDirectDrawSurface4Impl_ReleaseDC,
1856 IDirectDrawSurface4Impl_Restore,
1857 IDirectDrawSurface4Impl_SetClipper,
1858 IDirectDrawSurface4Impl_SetColorKey,
1859 IDirectDrawSurface4Impl_SetOverlayPosition,
1860 Xlib_IDirectDrawSurface4Impl_SetPalette,
1861 Xlib_IDirectDrawSurface4Impl_Unlock,
1862 IDirectDrawSurface4Impl_UpdateOverlay,
1863 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1864 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1865 IDirectDrawSurface4Impl_GetDDInterface,
1866 IDirectDrawSurface4Impl_PageLock,
1867 IDirectDrawSurface4Impl_PageUnlock,
1868 IDirectDrawSurface4Impl_SetSurfaceDesc,
1869 IDirectDrawSurface4Impl_SetPrivateData,
1870 IDirectDrawSurface4Impl_GetPrivateData,
1871 IDirectDrawSurface4Impl_FreePrivateData,
1872 IDirectDrawSurface4Impl_GetUniquenessValue,
1873 IDirectDrawSurface4Impl_ChangeUniquenessValue
1876 /******************************************************************************
1877 * DirectDrawCreateClipper (DDRAW.7)
1879 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1880 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1881 LPUNKNOWN pUnkOuter)
1883 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
1884 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
1886 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
1887 (*ilplpDDClipper)->lpvtbl = &ddclipvt;
1888 (*ilplpDDClipper)->ref = 1;
1893 /******************************************************************************
1894 * IDirectDrawClipper
1896 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
1897 LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
1899 ICOM_THIS(IDirectDrawClipperImpl,iface);
1900 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
1904 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
1905 ICOM_THIS(IDirectDrawClipperImpl,iface);
1906 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1911 HeapFree(GetProcessHeap(),0,This);
1915 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
1916 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
1918 ICOM_THIS(IDirectDrawClipperImpl,iface);
1919 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
1924 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
1925 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
1927 ICOM_THIS(IDirectDrawClipperImpl,iface);
1928 FIXME(ddraw,"(%p,%p,%ld),stub!\n",This,lprgn,hmm);
1932 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
1933 LPDIRECTDRAWCLIPPER iface,
1937 ICOM_THIS(IDirectDrawClipperImpl,iface);
1938 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
1939 return OLE_E_ENUM_NOMORE;
1942 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
1944 ICOM_THIS(IDirectDrawClipperImpl,iface);
1945 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1946 return ++(This->ref);
1949 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
1950 LPDIRECTDRAWCLIPPER iface,
1953 ICOM_THIS(IDirectDrawClipperImpl,iface);
1954 FIXME(ddraw,"(%p)->(%p),stub!\n",This,HWndPtr);
1958 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
1959 LPDIRECTDRAWCLIPPER iface,
1963 ICOM_THIS(IDirectDrawClipperImpl,iface);
1964 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
1968 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
1969 LPDIRECTDRAWCLIPPER iface,
1972 ICOM_THIS(IDirectDrawClipperImpl,iface);
1973 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpbChanged);
1977 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt = {
1978 IDirectDrawClipperImpl_QueryInterface,
1979 IDirectDrawClipperImpl_AddRef,
1980 IDirectDrawClipperImpl_Release,
1981 IDirectDrawClipperImpl_GetClipList,
1982 IDirectDrawClipperImpl_GetHWnd,
1983 IDirectDrawClipperImpl_Initialize,
1984 IDirectDrawClipperImpl_IsClipListChanged,
1985 IDirectDrawClipperImpl_SetClipList,
1986 IDirectDrawClipperImpl_SetHwnd
1990 /******************************************************************************
1991 * IDirectDrawPalette
1993 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
1994 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1996 ICOM_THIS(IDirectDrawPaletteImpl,iface);
1999 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2000 This,x,start,count,palent);
2002 if (!This->cm) /* should not happen */ {
2003 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
2004 return DDERR_GENERIC;
2006 for (i=0;i<count;i++) {
2007 palent[i].peRed = This->palents[start+i].peRed;
2008 palent[i].peBlue = This->palents[start+i].peBlue;
2009 palent[i].peGreen = This->palents[start+i].peGreen;
2010 palent[i].peFlags = This->palents[start+i].peFlags;
2016 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2017 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2019 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2023 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2024 This,x,start,count,palent
2026 for (i=0;i<count;i++) {
2027 xc.red = palent[i].peRed<<8;
2028 xc.blue = palent[i].peBlue<<8;
2029 xc.green = palent[i].peGreen<<8;
2030 xc.flags = DoRed|DoBlue|DoGreen;
2034 TSXStoreColor(display,This->cm,&xc);
2036 This->palents[start+i].peRed = palent[i].peRed;
2037 This->palents[start+i].peBlue = palent[i].peBlue;
2038 This->palents[start+i].peGreen = palent[i].peGreen;
2039 This->palents[start+i].peFlags = palent[i].peFlags;
2042 /* Now, if we are in 'depth conversion mode', update the screen palette */
2043 if (This->ddraw->d.palette_convert != NULL)
2044 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2049 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2050 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2052 #ifdef HAVE_LIBXXF86DGA
2053 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2058 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2059 This,x,start,count,palent
2061 if (!This->cm) /* should not happen */ {
2062 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
2063 return DDERR_GENERIC;
2065 /* FIXME: free colorcells instead of freeing whole map */
2067 This->cm = TSXCopyColormapAndFree(display,This->cm);
2068 TSXFreeColormap(display,cm);
2070 for (i=0;i<count;i++) {
2071 xc.red = palent[i].peRed<<8;
2072 xc.blue = palent[i].peBlue<<8;
2073 xc.green = palent[i].peGreen<<8;
2074 xc.flags = DoRed|DoBlue|DoGreen;
2077 TSXStoreColor(display,This->cm,&xc);
2079 This->palents[start+i].peRed = palent[i].peRed;
2080 This->palents[start+i].peBlue = palent[i].peBlue;
2081 This->palents[start+i].peGreen = palent[i].peGreen;
2082 This->palents[start+i].peFlags = palent[i].peFlags;
2084 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2086 #else /* defined(HAVE_LIBXXF86DGA) */
2087 return E_UNEXPECTED;
2088 #endif /* defined(HAVE_LIBXXF86DGA) */
2091 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2092 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2093 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2094 if (!--(This->ref)) {
2096 TSXFreeColormap(display,This->cm);
2099 HeapFree(GetProcessHeap(),0,This);
2105 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2106 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2108 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2109 return ++(This->ref);
2112 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2113 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2115 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2116 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2118 return DDERR_ALREADYINITIALIZED;
2121 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2122 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2124 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2125 FIXME( ddraw, "(%p)->(%p) stub.\n", This, lpdwCaps );
2129 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2130 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2132 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2135 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2136 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2141 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt = {
2142 IDirectDrawPaletteImpl_QueryInterface,
2143 IDirectDrawPaletteImpl_AddRef,
2144 IDirectDrawPaletteImpl_Release,
2145 IDirectDrawPaletteImpl_GetCaps,
2146 IDirectDrawPaletteImpl_GetEntries,
2147 IDirectDrawPaletteImpl_Initialize,
2148 DGA_IDirectDrawPaletteImpl_SetEntries
2151 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt = {
2152 IDirectDrawPaletteImpl_QueryInterface,
2153 IDirectDrawPaletteImpl_AddRef,
2154 IDirectDrawPaletteImpl_Release,
2155 IDirectDrawPaletteImpl_GetCaps,
2156 IDirectDrawPaletteImpl_GetEntries,
2157 IDirectDrawPaletteImpl_Initialize,
2158 Xlib_IDirectDrawPaletteImpl_SetEntries
2161 /*******************************************************************************
2164 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2165 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2167 ICOM_THIS(IDirect3DImpl,iface);
2168 /* FIXME: Not sure if this is correct */
2171 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2172 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2173 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2174 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2175 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2177 IDirect3D_AddRef(iface);
2179 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2183 if ((!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) ||
2184 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2186 IDirect3D_AddRef(iface);
2188 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2192 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
2193 IDirect3D2Impl* d3d;
2195 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2197 d3d->ddraw = This->ddraw;
2198 IDirect3D_AddRef(iface);
2199 d3d->lpvtbl = &d3d2vt;
2202 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2206 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2207 return OLE_E_ENUM_NOMORE;
2210 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2211 ICOM_THIS(IDirect3DImpl,iface);
2212 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2214 return ++(This->ref);
2217 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2219 ICOM_THIS(IDirect3DImpl,iface);
2220 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2222 if (!--(This->ref)) {
2223 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2224 HeapFree(GetProcessHeap(),0,This);
2230 static HRESULT WINAPI IDirect3DImpl_Initialize(
2231 LPDIRECT3D iface, REFIID refiid )
2233 ICOM_THIS(IDirect3DImpl,iface);
2234 /* FIXME: Not sure if this is correct */
2237 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2238 FIXME(ddraw,"(%p)->(%s):stub.\n",This,xrefiid);
2240 return DDERR_ALREADYINITIALIZED;
2243 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2244 LPD3DENUMDEVICESCALLBACK cb,
2246 ICOM_THIS(IDirect3DImpl,iface);
2247 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2249 /* Call functions defined in d3ddevices.c */
2250 if (!d3d_OpenGL_dx3(cb, context))
2256 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2257 LPDIRECT3DLIGHT *lplight,
2260 ICOM_THIS(IDirect3DImpl,iface);
2261 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2263 /* Call the creation function that is located in d3dlight.c */
2264 *lplight = d3dlight_create_dx3(This);
2269 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2270 LPDIRECT3DMATERIAL *lpmaterial,
2273 ICOM_THIS(IDirect3DImpl,iface);
2274 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2276 /* Call the creation function that is located in d3dviewport.c */
2277 *lpmaterial = d3dmaterial_create(This);
2282 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2283 LPDIRECT3DVIEWPORT *lpviewport,
2286 ICOM_THIS(IDirect3DImpl,iface);
2287 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2289 /* Call the creation function that is located in d3dviewport.c */
2290 *lpviewport = d3dviewport_create(This);
2295 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2296 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2297 LPD3DFINDDEVICERESULT lpfinddevrst)
2299 ICOM_THIS(IDirect3DImpl,iface);
2300 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2305 static ICOM_VTABLE(IDirect3D) d3dvt = {
2306 IDirect3DImpl_QueryInterface,
2307 IDirect3DImpl_AddRef,
2308 IDirect3DImpl_Release,
2309 IDirect3DImpl_Initialize,
2310 IDirect3DImpl_EnumDevices,
2311 IDirect3DImpl_CreateLight,
2312 IDirect3DImpl_CreateMaterial,
2313 IDirect3DImpl_CreateViewport,
2314 IDirect3DImpl_FindDevice
2317 /*******************************************************************************
2320 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2321 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2322 ICOM_THIS(IDirect3D2Impl,iface);
2324 /* FIXME: Not sure if this is correct */
2327 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2328 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2329 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2330 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2331 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2333 IDirect3D2_AddRef(iface);
2335 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2339 if ((!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) ||
2340 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2342 IDirect3D2_AddRef(iface);
2344 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2348 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2351 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2353 d3d->ddraw = This->ddraw;
2354 IDirect3D2_AddRef(iface);
2355 d3d->lpvtbl = &d3dvt;
2358 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2362 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2363 return OLE_E_ENUM_NOMORE;
2366 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2367 ICOM_THIS(IDirect3D2Impl,iface);
2368 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2370 return ++(This->ref);
2373 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2374 ICOM_THIS(IDirect3D2Impl,iface);
2375 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2377 if (!--(This->ref)) {
2378 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2379 HeapFree(GetProcessHeap(),0,This);
2385 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2386 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2388 ICOM_THIS(IDirect3D2Impl,iface);
2389 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2391 /* Call functions defined in d3ddevices.c */
2392 if (!d3d_OpenGL(cb, context))
2398 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2399 LPDIRECT3DLIGHT *lplight,
2402 ICOM_THIS(IDirect3D2Impl,iface);
2403 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2405 /* Call the creation function that is located in d3dlight.c */
2406 *lplight = d3dlight_create(This);
2411 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2412 LPDIRECT3DMATERIAL2 *lpmaterial,
2415 ICOM_THIS(IDirect3D2Impl,iface);
2416 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2418 /* Call the creation function that is located in d3dviewport.c */
2419 *lpmaterial = d3dmaterial2_create(This);
2424 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2425 LPDIRECT3DVIEWPORT2 *lpviewport,
2428 ICOM_THIS(IDirect3D2Impl,iface);
2429 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2431 /* Call the creation function that is located in d3dviewport.c */
2432 *lpviewport = d3dviewport2_create(This);
2437 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2438 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2439 LPD3DFINDDEVICERESULT lpfinddevrst)
2441 ICOM_THIS(IDirect3D2Impl,iface);
2442 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2447 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2449 LPDIRECTDRAWSURFACE surface,
2450 LPDIRECT3DDEVICE2 *device)
2452 ICOM_THIS(IDirect3D2Impl,iface);
2455 WINE_StringFromCLSID(rguid,xbuf);
2456 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2458 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2459 IDirect3D2_AddRef(iface);
2463 return DDERR_INVALIDPARAMS;
2466 static ICOM_VTABLE(IDirect3D2) d3d2vt = {
2467 IDirect3D2Impl_QueryInterface,
2468 IDirect3D2Impl_AddRef,
2469 IDirect3D2Impl_Release,
2470 IDirect3D2Impl_EnumDevices,
2471 IDirect3D2Impl_CreateLight,
2472 IDirect3D2Impl_CreateMaterial,
2473 IDirect3D2Impl_CreateViewport,
2474 IDirect3D2Impl_FindDevice,
2475 IDirect3D2Impl_CreateDevice
2478 /*******************************************************************************
2482 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2483 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2485 static INT ddrawXlibThisOffset = 0;
2487 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2488 LPDDSURFACEDESC lpddsd,
2489 IDirectDrawSurfaceImpl* lpdsf)
2493 /* The surface was already allocated when entering in this function */
2494 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2496 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2497 /* This is a Z Buffer */
2498 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2499 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2501 /* This is a standard image */
2502 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2503 /* No pixel format => use DirectDraw's format */
2504 lpddsd->ddpfPixelFormat = This->d.directdraw_pixelformat;
2505 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2507 /* To check what the program wants */
2508 if (TRACE_ON(ddraw)) {
2509 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2513 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2516 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2520 /* Copy the surface description */
2521 lpdsf->s.surface_desc = *lpddsd;
2523 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2524 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2525 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2530 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2531 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2533 #ifdef HAVE_LIBXXF86DGA
2534 ICOM_THIS(IDirectDraw2Impl,iface);
2535 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2538 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2539 if (TRACE_ON(ddraw)) {
2540 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2541 _dump_DDSD(lpddsd->dwFlags);
2543 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2546 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2547 IDirectDraw2_AddRef(iface);
2550 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2551 (*ilpdsf)->s.ddraw = This;
2552 (*ilpdsf)->s.palette = NULL;
2553 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2555 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2556 lpddsd->dwWidth = This->d.width;
2557 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2558 lpddsd->dwHeight = This->d.height;
2560 /* Check if this a 'primary surface' or not */
2561 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2562 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2564 /* This is THE primary surface => there is DGA-specific code */
2565 /* First, store the surface description */
2566 (*ilpdsf)->s.surface_desc = *lpddsd;
2568 /* Find a viewport */
2570 if (!(This->e.dga.vpmask & (1<<i)))
2572 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2573 /* if i == 32 or maximum ... return error */
2574 This->e.dga.vpmask|=(1<<i);
2575 (*ilpdsf)->s.surface_desc.y.lpSurface =
2576 This->e.dga.fb_addr+((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2577 (*ilpdsf)->t.dga.fb_height = i*This->e.dga.fb_height;
2578 (*ilpdsf)->s.surface_desc.lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
2579 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch;
2581 /* Add flags if there were not present */
2582 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2583 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2584 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2585 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2586 /* We put our surface always in video memory */
2587 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2588 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2589 (*ilpdsf)->s.backbuffer = NULL;
2591 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2592 IDirectDrawSurface4Impl* back;
2594 if (lpddsd->dwBackBufferCount>1)
2595 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2597 (*ilpdsf)->s.backbuffer = back =
2598 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2599 IDirectDraw2_AddRef(iface);
2601 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2603 if (!(This->e.dga.vpmask & (1<<i)))
2605 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2606 /* if i == 32 or maximum ... return error */
2607 This->e.dga.vpmask|=(1<<i);
2608 back->t.dga.fb_height = i*This->e.dga.fb_height;
2610 /* Copy the surface description from the front buffer */
2611 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2612 /* Change the parameters that are not the same */
2613 back->s.surface_desc.y.lpSurface = This->e.dga.fb_addr+
2614 ((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2615 back->s.ddraw = This;
2616 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2619 /* Add relevant info to front and back buffers */
2620 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2621 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2622 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2623 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2624 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2627 /* There is no DGA-specific code here...
2628 Go to the common surface creation function */
2629 return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2633 #else /* defined(HAVE_LIBXXF86DGA) */
2634 return E_UNEXPECTED;
2635 #endif /* defined(HAVE_LIBXXF86DGA) */
2638 #ifdef HAVE_LIBXXSHM
2639 /* Error handlers for Image creation */
2640 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2645 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2647 int (*WineXHandler)(Display *, XErrorEvent *);
2649 img = TSXShmCreateImage(display,
2650 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2651 This->d.pixmap_depth,
2654 &(lpdsf->t.xlib.shminfo),
2655 lpdsf->s.surface_desc.dwWidth,
2656 lpdsf->s.surface_desc.dwHeight);
2659 MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2660 This->e.xlib.xshm_active = 0;
2664 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2665 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2666 MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2667 This->e.xlib.xshm_active = 0;
2668 TSXDestroyImage(img);
2672 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2674 if (img->data == (char *) -1) {
2675 MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2676 This->e.xlib.xshm_active = 0;
2677 TSXDestroyImage(img);
2678 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2681 lpdsf->t.xlib.shminfo.readOnly = False;
2683 /* This is where things start to get trickier....
2684 First, we flush the current X connections to be sure to catch all non-XShm related
2686 TSXSync(display, False);
2687 /* Then we enter in the non-thread safe part of the tests */
2688 EnterCriticalSection( &X11DRV_CritSection );
2690 /* Reset the error flag, sets our new error handler and try to attach the surface */
2692 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2693 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2694 XSync(display, False);
2696 /* Check the error flag */
2697 if (XShmErrorFlag) {
2698 /* An error occured */
2702 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2703 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2704 XSetErrorHandler(WineXHandler);
2706 MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
2707 This->e.xlib.xshm_active = 0;
2709 /* Leave the critical section */
2710 LeaveCriticalSection( &X11DRV_CritSection );
2715 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2716 but it may be a bit overkill.... */
2717 XSetErrorHandler(WineXHandler);
2718 LeaveCriticalSection( &X11DRV_CritSection );
2720 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2722 if (This->d.pixel_convert != NULL) {
2723 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2724 lpdsf->s.surface_desc.dwWidth *
2725 lpdsf->s.surface_desc.dwHeight *
2726 (This->d.directdraw_pixelformat.x.dwRGBBitCount));
2728 lpdsf->s.surface_desc.y.lpSurface = img->data;
2733 #endif /* HAVE_LIBXXSHM */
2735 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2739 #ifdef HAVE_LIBXXSHM
2740 if (This->e.xlib.xshm_active) {
2741 img = create_xshmimage(This, lpdsf);
2746 /* Allocate surface memory */
2747 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2748 lpdsf->s.surface_desc.dwWidth *
2749 lpdsf->s.surface_desc.dwHeight *
2750 (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8));
2752 if (This->d.pixel_convert != NULL) {
2753 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2754 lpdsf->s.surface_desc.dwWidth *
2755 lpdsf->s.surface_desc.dwHeight *
2756 (This->d.screen_pixelformat.x.dwRGBBitCount / 8));
2758 img_data = lpdsf->s.surface_desc.y.lpSurface;
2761 /* In this case, create an XImage */
2763 TSXCreateImage(display,
2764 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2765 This->d.pixmap_depth,
2769 lpdsf->s.surface_desc.dwWidth,
2770 lpdsf->s.surface_desc.dwHeight,
2772 lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
2775 #ifdef HAVE_LIBXXSHM
2778 if (This->d.pixel_convert != NULL) {
2779 lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
2781 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2787 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
2788 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2790 ICOM_THIS(IDirectDraw2Impl,iface);
2791 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2792 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2793 This,lpddsd,ilpdsf,lpunk);
2795 if (TRACE_ON(ddraw)) {
2796 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2797 _dump_DDSD(lpddsd->dwFlags);
2799 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2802 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2804 IDirectDraw2_AddRef(iface);
2805 (*ilpdsf)->s.ddraw = This;
2807 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
2808 (*ilpdsf)->s.palette = NULL;
2809 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2811 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2812 lpddsd->dwWidth = This->d.width;
2813 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2814 lpddsd->dwHeight = This->d.height;
2816 /* Check if this a 'primary surface' or not */
2817 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2818 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2821 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *ilpdsf);
2823 /* First, store the surface description */
2824 (*ilpdsf)->s.surface_desc = *lpddsd;
2826 /* Create the XImage */
2827 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
2829 return DDERR_OUTOFMEMORY;
2830 (*ilpdsf)->t.xlib.image = img;
2832 /* Add flags if there were not present */
2833 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2834 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2835 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2836 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2837 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2838 (*ilpdsf)->s.backbuffer = NULL;
2840 /* Check for backbuffers */
2841 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2842 IDirectDrawSurface4Impl* back;
2845 if (lpddsd->dwBackBufferCount>1)
2846 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2848 (*ilpdsf)->s.backbuffer = back =
2849 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2851 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2853 IDirectDraw2_AddRef(iface);
2854 back->s.ddraw = This;
2857 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
2858 /* Copy the surface description from the front buffer */
2859 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2861 /* Create the XImage */
2862 img = create_ximage(This, back);
2864 return DDERR_OUTOFMEMORY;
2865 back->t.xlib.image = img;
2867 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2870 /* Add relevant info to front and back buffers */
2871 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2872 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2873 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2874 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2875 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2878 /* There is no Xlib-specific code here...
2879 Go to the common surface creation function */
2880 return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2886 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
2887 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2889 ICOM_THIS(IDirectDraw2Impl,iface);
2890 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",This,src,dst);
2891 *dst = src; /* FIXME */
2896 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2897 * even when the approbiate bitmasks are not specified.
2899 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
2900 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
2902 ICOM_THIS(IDirectDraw2Impl,iface);
2908 FE(DDSCL_FULLSCREEN)
2909 FE(DDSCL_ALLOWREBOOT)
2910 FE(DDSCL_NOWINDOWCHANGES)
2912 FE(DDSCL_ALLOWMODEX)
2914 FE(DDSCL_SETFOCUSWINDOW)
2915 FE(DDSCL_SETDEVICEWINDOW)
2916 FE(DDSCL_CREATEDEVICEWINDOW)
2919 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
2920 if(TRACE_ON(ddraw)){
2921 dbg_decl_str(ddraw, 512);
2922 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2923 if (flagmap[i].mask & cooplevel)
2924 dsprintf(ddraw, "%s ", flagmap[i].name);
2925 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2927 This->d.mainWindow = hwnd;
2929 /* This will be overwritten in the case of Full Screen mode.
2930 Windowed games could work with that :-) */
2933 WND *tmpWnd = WIN_FindWndPtr(hwnd);
2934 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
2935 WIN_ReleaseWndPtr(tmpWnd);
2941 /* Small helper to either use the cooperative window or create a new
2942 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2944 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
2947 /* Do not destroy the application supplied cooperative window */
2948 if (This->d.window && This->d.window != This->d.mainWindow) {
2949 DestroyWindow(This->d.window);
2952 /* Sanity check cooperative window before assigning it to drawing. */
2953 if ( IsWindow(This->d.mainWindow) &&
2954 IsWindowVisible(This->d.mainWindow)
2956 GetWindowRect(This->d.mainWindow,&rect);
2957 if (((rect.right-rect.left) >= This->d.width) &&
2958 ((rect.bottom-rect.top) >= This->d.height)
2960 This->d.window = This->d.mainWindow;
2962 /* ... failed, create new one. */
2963 if (!This->d.window) {
2964 This->d.window = CreateWindowExA(
2968 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2977 /*Store THIS with the window. We'll use it in the window procedure*/
2978 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
2979 ShowWindow(This->d.window,TRUE);
2980 UpdateWindow(This->d.window);
2982 SetFocus(This->d.window);
2985 static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
2987 XPixmapFormatValues *pf;
2989 int nvisuals, npixmap, i;
2992 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
2993 pf = XListPixmapFormats(display, &npixmap);
2995 for (i = 0; i < npixmap; i++) {
2996 if (pf[i].bits_per_pixel == depth) {
2999 for (j = 0; j < nvisuals; j++) {
3000 if (vi[j].depth == pf[i].depth) {
3001 pixelformat->dwSize = sizeof(*pixelformat);
3003 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3004 pixelformat->y.dwRBitMask = 0;
3005 pixelformat->z.dwGBitMask = 0;
3006 pixelformat->xx.dwBBitMask = 0;
3008 pixelformat->dwFlags = DDPF_RGB;
3009 pixelformat->y.dwRBitMask = vi[j].red_mask;
3010 pixelformat->z.dwGBitMask = vi[j].green_mask;
3011 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3013 pixelformat->dwFourCC = 0;
3014 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3015 pixelformat->xy.dwRGBAlphaBitMask= 0;
3017 *screen_pixelformat = *pixelformat;
3019 if (pix_depth != NULL)
3020 *pix_depth = vi[j].depth;
3029 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3033 if ((match == 0) && (depth == 8)) {
3034 pixelformat->dwSize = sizeof(*pixelformat);
3035 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3036 pixelformat->dwFourCC = 0;
3037 pixelformat->x.dwRGBBitCount = 8;
3038 pixelformat->y.dwRBitMask = 0;
3039 pixelformat->z.dwGBitMask = 0;
3040 pixelformat->xx.dwBBitMask = 0;
3041 pixelformat->xy.dwRGBAlphaBitMask= 0;
3043 /* In that case, find a visual to emulate the 8 bpp format */
3044 for (i = 0; i < npixmap; i++) {
3045 if (pf[i].bits_per_pixel >= depth) {
3048 for (j = 0; j < nvisuals; j++) {
3049 if (vi[j].depth == pf[i].depth) {
3050 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3051 screen_pixelformat->dwFlags = DDPF_RGB;
3052 screen_pixelformat->dwFourCC = 0;
3053 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3054 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
3055 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
3056 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3057 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
3059 if (pix_depth != NULL)
3060 *pix_depth = vi[j].depth;
3069 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3080 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3081 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3083 #ifdef HAVE_LIBXXF86DGA
3084 ICOM_THIS(IDirectDrawImpl,iface);
3087 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3089 /* We hope getting the asked for depth */
3090 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != 1) {
3091 /* I.e. no visual found or emulated */
3092 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3093 return DDERR_UNSUPPORTEDMODE;
3096 if (This->d.width < width) {
3097 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3098 return DDERR_UNSUPPORTEDMODE;
3100 This->d.width = width;
3101 This->d.height = height;
3103 /* adjust fb_height, so we don't overlap */
3104 if (This->e.dga.fb_height < height)
3105 This->e.dga.fb_height = height;
3106 _common_IDirectDrawImpl_SetDisplayMode(This);
3108 #ifdef HAVE_LIBXXF86VM
3110 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3111 XF86VidModeModeLine mod_tmp;
3112 /* int dotclock_tmp; */
3114 /* save original video mode and set fullscreen if available*/
3115 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3116 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3117 orig_mode->hdisplay = mod_tmp.hdisplay;
3118 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3119 orig_mode->hsyncend = mod_tmp.hsyncend;
3120 orig_mode->htotal = mod_tmp.htotal;
3121 orig_mode->vdisplay = mod_tmp.vdisplay;
3122 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3123 orig_mode->vsyncend = mod_tmp.vsyncend;
3124 orig_mode->vtotal = mod_tmp.vtotal;
3125 orig_mode->flags = mod_tmp.flags;
3126 orig_mode->private = mod_tmp.private;
3128 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3129 for (i=0;i<mode_count;i++)
3131 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3133 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3134 *vidmode = *(all_modes[i]);
3137 TSXFree(all_modes[i]->private);
3139 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3143 WARN(ddraw, "Fullscreen mode not available!\n");
3147 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3148 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3149 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3150 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3156 /* FIXME: this function OVERWRITES several signal handlers.
3157 * can we save them? and restore them later? In a way that
3158 * it works for the library too?
3160 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3162 TSXF86DGASetViewPort(display,DefaultScreen(display),0,This->e.dga.fb_height);
3164 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3167 #ifdef RESTORE_SIGNALS
3168 SIGNAL_InitHandlers();
3171 #else /* defined(HAVE_LIBXXF86DGA) */
3172 return E_UNEXPECTED;
3173 #endif /* defined(HAVE_LIBXXF86DGA) */
3176 /* *************************************
3177 16 / 15 bpp to palettized 8 bpp
3178 ************************************* */
3179 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3180 unsigned char *c_src = (unsigned char *) src;
3181 unsigned short *c_dst = (unsigned short *) dst;
3184 if (palette != NULL) {
3185 unsigned short *pal = (unsigned short *) palette->screen_palents;
3187 for (y = 0; y < height; y++) {
3188 for (x = 0; x < width; x++) {
3189 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3193 WARN(ddraw, "No palette set...\n");
3194 memset(dst, 0, width * height * 2);
3197 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3199 unsigned short *pal = (unsigned short *) screen_palette;
3201 for (i = 0; i < count; i++)
3202 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3203 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3204 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3206 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3208 unsigned short *pal = (unsigned short *) screen_palette;
3210 for (i = 0; i < count; i++)
3211 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3212 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3213 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3216 /* *************************************
3217 24 / 32 bpp to palettized 8 bpp
3218 ************************************* */
3219 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3220 unsigned char *c_src = (unsigned char *) src;
3221 unsigned int *c_dst = (unsigned int *) dst;
3224 if (palette != NULL) {
3225 unsigned int *pal = (unsigned int *) palette->screen_palents;
3227 for (y = 0; y < height; y++) {
3228 for (x = 0; x < width; x++) {
3229 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3233 WARN(ddraw, "No palette set...\n");
3234 memset(dst, 0, width * height * 4);
3237 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3239 unsigned int *pal = (unsigned int *) screen_palette;
3241 for (i = 0; i < count; i++)
3242 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3243 (((unsigned int) palent[i].peGreen) << 8) |
3244 ((unsigned int) palent[i].peBlue));
3247 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3248 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3250 ICOM_THIS(IDirectDrawImpl,iface);
3254 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3255 This, width, height, depth);
3257 switch (_common_depth_to_pixelformat(depth,
3258 &(This->d.directdraw_pixelformat),
3259 &(This->d.screen_pixelformat),
3260 &(This->d.pixmap_depth))) {
3262 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3263 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3264 return DDERR_UNSUPPORTEDMODE;
3268 This->d.pixel_convert = NULL;
3269 This->d.palette_convert = NULL;
3275 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3277 /* Set the depth convertion routines */
3278 switch (This->d.screen_pixelformat.x.dwRGBBitCount) {
3280 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
3281 (This->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
3282 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3286 This->d.pixel_convert = pixel_convert_16_to_8;
3287 This->d.palette_convert = palette_convert_16_to_8;
3288 } else if ((This->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
3289 (This->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
3290 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3294 This->d.pixel_convert = pixel_convert_16_to_8;
3295 This->d.palette_convert = palette_convert_15_to_8;
3300 /* Not handled yet :/ */
3305 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) &&
3306 (This->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) &&
3307 (This->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
3311 This->d.pixel_convert = pixel_convert_32_to_8;
3312 This->d.palette_convert = palette_convert_24_to_8;
3318 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3319 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3320 return DDERR_UNSUPPORTEDMODE;
3325 This->d.width = width;
3326 This->d.height = height;
3328 _common_IDirectDrawImpl_SetDisplayMode(This);
3330 tmpWnd = WIN_FindWndPtr(This->d.window);
3331 This->d.paintable = 1;
3332 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3333 /* We don't have a context for this window. Host off the desktop */
3335 if( !This->d.drawable )
3337 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3338 WIN_ReleaseDesktop();
3340 WIN_ReleaseWndPtr(tmpWnd);
3344 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3345 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3347 #ifdef HAVE_LIBXXF86DGA
3348 ICOM_THIS(IDirectDraw2Impl,iface);
3349 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3350 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3351 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3352 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3354 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3355 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3356 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3359 #else /* defined(HAVE_LIBXXF86DGA) */
3360 return E_UNEXPECTED;
3361 #endif /* defined(HAVE_LIBXXF86DGA) */
3364 static void fill_caps(LPDDCAPS caps) {
3365 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3366 Need to be fixed, though.. */
3370 caps->dwSize = sizeof(*caps);
3371 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3372 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
3373 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3374 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3376 caps->dwFXAlphaCaps = 0;
3377 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3379 caps->dwZBufferBitDepths = DDBD_16;
3380 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3381 to put textures in video memory.
3382 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3384 caps->dwVidMemTotal = 8192 * 1024;
3385 caps->dwVidMemFree = 8192 * 1024;
3386 /* These are all the supported capabilities of the surfaces */
3387 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3388 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3389 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3390 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3392 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3393 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3394 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3398 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3399 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3401 ICOM_THIS(IDirectDraw2Impl,iface);
3402 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3404 /* Put the same caps for the two capabilities */
3411 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3412 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3414 ICOM_THIS(IDirectDraw2Impl,iface);
3415 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3416 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3417 This,x,ilpddclip,lpunk
3419 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3420 (*ilpddclip)->ref = 1;
3421 (*ilpddclip)->lpvtbl = &ddclipvt;
3425 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3426 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3430 if (TRACE_ON(ddraw))
3431 _dump_paletteformat(dwFlags);
3433 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3434 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3435 (*lpddpal)->ref = 1;
3436 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3437 (*lpddpal)->installed = 0;
3439 if (dwFlags & DDPCAPS_1BIT)
3441 else if (dwFlags & DDPCAPS_2BIT)
3443 else if (dwFlags & DDPCAPS_4BIT)
3445 else if (dwFlags & DDPCAPS_8BIT)
3448 ERR(ddraw, "unhandled palette format\n");
3453 /* Now, if we are in 'depth conversion mode', create the screen palette */
3454 if (This->d.palette_convert != NULL)
3455 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3457 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3458 } else if (This->d.palette_convert != NULL) {
3459 /* In that case, put all 0xFF */
3460 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3466 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3467 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3469 ICOM_THIS(IDirectDraw2Impl,iface);
3470 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3474 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3475 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3476 if (res != 0) return res;
3477 (*ilpddpal)->lpvtbl = &dga_ddpalvt;
3478 if (This->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3479 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3481 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3482 (*ilpddpal)->cm = 0;
3484 if (((*ilpddpal)->cm)&&xsize) {
3485 for (i=0;i<xsize;i++) {
3488 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3489 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3490 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3491 xc.flags = DoRed|DoBlue|DoGreen;
3493 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3499 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3500 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3502 ICOM_THIS(IDirectDraw2Impl,iface);
3503 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3507 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3508 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3509 if (res != 0) return res;
3510 (*ilpddpal)->lpvtbl = &xlib_ddpalvt;
3514 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3515 #ifdef HAVE_LIBXXF86DGA
3516 ICOM_THIS(IDirectDraw2Impl,iface);
3517 TRACE(ddraw, "(%p)->()\n",This);
3519 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3520 #ifdef RESTORE_SIGNALS
3521 SIGNAL_InitHandlers();
3524 #else /* defined(HAVE_LIBXXF86DGA) */
3525 return E_UNEXPECTED;
3529 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3530 ICOM_THIS(IDirectDraw2Impl,iface);
3531 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", This);
3536 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3537 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3539 ICOM_THIS(IDirectDraw2Impl,iface);
3540 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3544 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3545 ICOM_THIS(IDirectDraw2Impl,iface);
3546 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
3548 return ++(This->ref);
3551 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3552 ICOM_THIS(IDirectDraw2Impl,iface);
3553 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3555 #ifdef HAVE_LIBXXF86DGA
3556 if (!--(This->ref)) {
3557 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3558 if (This->d.window && (This->d.mainWindow != This->d.window))
3559 DestroyWindow(This->d.window);
3560 #ifdef HAVE_LIBXXF86VM
3562 TSXF86VidModeSwitchToMode(
3564 DefaultScreen(display),
3566 if (orig_mode->privsize)
3567 TSXFree(orig_mode->private);
3573 #ifdef RESTORE_SIGNALS
3574 SIGNAL_InitHandlers();
3576 HeapFree(GetProcessHeap(),0,This);
3579 #endif /* defined(HAVE_LIBXXF86DGA) */
3583 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3584 ICOM_THIS(IDirectDraw2Impl,iface);
3585 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3587 if (!--(This->ref)) {
3588 if (This->d.window && (This->d.mainWindow != This->d.window))
3589 DestroyWindow(This->d.window);
3590 HeapFree(GetProcessHeap(),0,This);
3593 /* FIXME: destroy window ... */
3597 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
3598 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3600 ICOM_THIS(IDirectDraw2Impl,iface);
3603 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3604 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3605 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3607 IDirectDraw2_AddRef(iface);
3609 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3613 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3614 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
3615 IDirectDraw2_AddRef(iface);
3618 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3622 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3623 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
3624 IDirectDraw2_AddRef(iface);
3627 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3631 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3632 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
3633 IDirectDraw2_AddRef(iface);
3636 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3640 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3643 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3645 d3d->ddraw = (IDirectDrawImpl*)This;
3646 IDirectDraw2_AddRef(iface);
3647 d3d->lpvtbl = &d3dvt;
3650 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3654 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3655 IDirect3D2Impl* d3d;
3657 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3659 d3d->ddraw = (IDirectDrawImpl*)This;
3660 IDirectDraw2_AddRef(iface);
3661 d3d->lpvtbl = &d3d2vt;
3664 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3668 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3669 return OLE_E_ENUM_NOMORE;
3672 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
3673 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3675 ICOM_THIS(IDirectDraw2Impl,iface);
3678 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3679 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3680 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3682 IDirectDraw2_AddRef(iface);
3684 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3688 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3689 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
3690 IDirectDraw2_AddRef(iface);
3693 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3697 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3698 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
3699 IDirectDraw2_AddRef(iface);
3702 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3706 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3707 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
3708 IDirectDraw2_AddRef(iface);
3711 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3715 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3718 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3720 d3d->ddraw = (IDirectDrawImpl*)This;
3721 IDirectDraw2_AddRef(iface);
3722 d3d->lpvtbl = &d3dvt;
3725 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3729 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3730 IDirect3D2Impl* d3d;
3732 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3734 d3d->ddraw = (IDirectDrawImpl*)This;
3735 IDirectDraw2_AddRef(iface);
3736 d3d->lpvtbl = &d3d2vt;
3739 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3743 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3744 return OLE_E_ENUM_NOMORE;
3747 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
3748 LPDIRECTDRAW2 iface,BOOL *status
3750 ICOM_THIS(IDirectDraw2Impl,iface);
3751 TRACE(ddraw,"(%p)->(%p)\n",This,status);
3756 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
3757 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3759 ICOM_THIS(IDirectDraw2Impl,iface);
3760 DDSURFACEDESC ddsfd;
3763 } modes[5] = { /* some of the usual modes */
3770 static int depths[4] = {8,16,24,32};
3773 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3774 ddsfd.dwSize = sizeof(ddsfd);
3775 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3776 if (dwFlags & DDEDM_REFRESHRATES) {
3777 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3778 ddsfd.x.dwRefreshRate = 60;
3781 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3782 ddsfd.dwBackBufferCount = 1;
3783 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3784 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3785 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3786 /* FIXME: those masks would have to be set in depth > 8 */
3788 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3789 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3790 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3791 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3792 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3793 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3795 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3797 /* FIXME: We should query those from X itself */
3798 switch (depths[i]) {
3800 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3801 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3802 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3805 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3806 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3807 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3810 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3811 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3812 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3817 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3818 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3819 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3820 if (!modescb(&ddsfd,context)) return DD_OK;
3822 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3823 ddsfd.dwWidth = modes[j].w;
3824 ddsfd.dwHeight = modes[j].h;
3825 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3826 if (!modescb(&ddsfd,context)) return DD_OK;
3829 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3830 /* modeX is not standard VGA */
3832 ddsfd.dwHeight = 200;
3833 ddsfd.dwWidth = 320;
3834 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3835 if (!modescb(&ddsfd,context)) return DD_OK;
3841 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
3842 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3844 ICOM_THIS(IDirectDraw2Impl,iface);
3846 XPixmapFormatValues *pf;
3848 int nvisuals, npixmap, i;
3851 DDSURFACEDESC ddsfd;
3854 } modes[] = { /* some of the usual modes */
3862 DWORD maxWidth, maxHeight;
3864 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3865 ddsfd.dwSize = sizeof(ddsfd);
3866 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
3867 if (dwFlags & DDEDM_REFRESHRATES) {
3868 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3869 ddsfd.x.dwRefreshRate = 60;
3871 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3872 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3874 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3875 pf = XListPixmapFormats(display, &npixmap);
3879 while (i < npixmap) {
3880 if ((has_8bpp == 0) && (pf[i].depth == 8)) {
3881 /* Special case of a 8bpp depth */
3885 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
3886 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3887 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
3888 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3889 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
3890 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3891 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3892 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3893 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3894 } else if (pf[i].depth > 8) {
3897 /* All the 'true color' depths (15, 16 and 24)
3898 First, find the corresponding visual to extract the bit masks */
3899 for (j = 0; j < nvisuals; j++) {
3900 if (vi[j].depth == pf[i].depth) {
3901 ddsfd.ddsCaps.dwCaps = 0;
3902 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3903 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3904 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3905 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
3906 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
3907 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
3908 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
3909 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3917 ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
3925 if (TRACE_ON(ddraw)) {
3926 TRACE(ddraw, "Enumerating with pixel format : \n");
3927 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
3930 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
3931 /* Do not enumerate modes we cannot handle anyway */
3932 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
3935 ddsfd.dwWidth = modes[mode].w;
3936 ddsfd.dwHeight = modes[mode].h;
3938 /* Now, send the mode description to the application */
3939 TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
3940 if (!modescb(&ddsfd, context))
3944 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3945 /* modeX is not standard VGA */
3946 ddsfd.dwWidth = 320;
3947 ddsfd.dwHeight = 200;
3948 if (!modescb(&ddsfd, context))
3953 /* Hack to always enumerate a 8bpp depth */
3955 if ((i == npixmap) && (has_8bpp == 0)) {
3968 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
3969 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
3971 #ifdef HAVE_LIBXXF86DGA
3972 ICOM_THIS(IDirectDraw2Impl,iface);
3973 TRACE(ddraw,"(%p)->(%p)\n",This,lpddsfd);
3974 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3975 lpddsfd->dwHeight = This->d.height;
3976 lpddsfd->dwWidth = This->d.width;
3977 lpddsfd->lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3978 lpddsfd->dwBackBufferCount = 1;
3979 lpddsfd->x.dwRefreshRate = 60;
3980 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3981 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
3983 #else /* defined(HAVE_LIBXXF86DGA) */
3984 return E_UNEXPECTED;
3985 #endif /* defined(HAVE_LIBXXF86DGA) */
3988 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
3989 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
3991 ICOM_THIS(IDirectDraw2Impl,iface);
3992 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
3993 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3994 lpddsfd->dwHeight = This->d.height;
3995 lpddsfd->dwWidth = This->d.width;
3996 lpddsfd->lPitch = lpddsfd->dwWidth * This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3997 lpddsfd->dwBackBufferCount = 1;
3998 lpddsfd->x.dwRefreshRate = 60;
3999 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4000 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4004 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4005 ICOM_THIS(IDirectDraw2Impl,iface);
4006 TRACE(ddraw,"(%p)->()\n",This);
4010 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4011 LPDIRECTDRAW2 iface,LPDWORD freq
4013 ICOM_THIS(IDirectDraw2Impl,iface);
4014 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",This,freq);
4015 *freq = 60*100; /* 60 Hz */
4019 /* what can we directly decompress? */
4020 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4021 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4023 ICOM_THIS(IDirectDraw2Impl,iface);
4024 FIXME(ddraw,"(%p,%p,%p), stub\n",This,x,y);
4028 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4029 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4031 ICOM_THIS(IDirectDraw2Impl,iface);
4032 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4036 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4037 LPDIRECTDRAW2 iface )
4039 ICOM_THIS(IDirectDraw2Impl,iface);
4040 FIXME(ddraw,"(%p)->()\n", This );
4045 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4046 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4047 ICOM_THIS(IDirectDraw2Impl,iface);
4048 FIXME(ddraw,"(%p)->(%p)\n", This, lplpGDIDDSSurface);
4053 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4054 LPDWORD lpdwScanLine) {
4055 ICOM_THIS(IDirectDraw2Impl,iface);
4056 FIXME(ddraw,"(%p)->(%p)\n", This, lpdwScanLine);
4061 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4063 ICOM_THIS(IDirectDraw2Impl,iface);
4064 FIXME(ddraw,"(%p)->(%p)\n", This, lpGUID);
4069 /* Note: Hack so we can reuse the old functions without compiler warnings */
4071 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4073 # define XCAST(fun) (void*)
4076 static ICOM_VTABLE(IDirectDraw) dga_ddvt = {
4077 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4078 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4079 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4080 XCAST(Compact)IDirectDraw2Impl_Compact,
4081 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4082 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4083 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4084 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4085 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4086 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4087 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4088 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4089 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4090 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4091 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4092 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4093 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4094 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4095 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4096 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4097 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4098 DGA_IDirectDrawImpl_SetDisplayMode,
4099 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4102 static ICOM_VTABLE(IDirectDraw) xlib_ddvt = {
4103 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4104 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4105 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4106 XCAST(Compact)IDirectDraw2Impl_Compact,
4107 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4108 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4109 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4110 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4111 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4112 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4113 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4114 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4115 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4116 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4117 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4118 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4119 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4120 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4121 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4122 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4123 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4124 Xlib_IDirectDrawImpl_SetDisplayMode,
4125 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4130 /*****************************************************************************
4136 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4137 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4139 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4142 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4143 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4145 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4148 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4149 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4151 ICOM_THIS(IDirectDraw2Impl,iface);
4152 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4153 This,ddscaps,total,free
4155 if (total) *total = This->e.dga.fb_memsize * 1024;
4156 if (free) *free = This->e.dga.fb_memsize * 1024;
4160 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4161 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4163 ICOM_THIS(IDirectDraw2Impl,iface);
4164 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4165 This,ddscaps,total,free
4167 if (total) *total = 2048 * 1024;
4168 if (free) *free = 2048 * 1024;
4172 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt = {
4173 DGA_IDirectDraw2Impl_QueryInterface,
4174 IDirectDraw2Impl_AddRef,
4175 DGA_IDirectDraw2Impl_Release,
4176 IDirectDraw2Impl_Compact,
4177 IDirectDraw2Impl_CreateClipper,
4178 DGA_IDirectDraw2Impl_CreatePalette,
4179 DGA_IDirectDraw2Impl_CreateSurface,
4180 IDirectDraw2Impl_DuplicateSurface,
4181 DGA_IDirectDraw2Impl_EnumDisplayModes,
4182 IDirectDraw2Impl_EnumSurfaces,
4183 IDirectDraw2Impl_FlipToGDISurface,
4184 DGA_IDirectDraw2Impl_GetCaps,
4185 DGA_IDirectDraw2Impl_GetDisplayMode,
4186 IDirectDraw2Impl_GetFourCCCodes,
4187 IDirectDraw2Impl_GetGDISurface,
4188 IDirectDraw2Impl_GetMonitorFrequency,
4189 IDirectDraw2Impl_GetScanLine,
4190 IDirectDraw2Impl_GetVerticalBlankStatus,
4191 IDirectDraw2Impl_Initialize,
4192 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4193 IDirectDraw2Impl_SetCooperativeLevel,
4194 DGA_IDirectDraw2Impl_SetDisplayMode,
4195 IDirectDraw2Impl_WaitForVerticalBlank,
4196 DGA_IDirectDraw2Impl_GetAvailableVidMem
4199 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = {
4200 Xlib_IDirectDraw2Impl_QueryInterface,
4201 IDirectDraw2Impl_AddRef,
4202 Xlib_IDirectDraw2Impl_Release,
4203 IDirectDraw2Impl_Compact,
4204 IDirectDraw2Impl_CreateClipper,
4205 Xlib_IDirectDraw2Impl_CreatePalette,
4206 Xlib_IDirectDraw2Impl_CreateSurface,
4207 IDirectDraw2Impl_DuplicateSurface,
4208 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4209 IDirectDraw2Impl_EnumSurfaces,
4210 IDirectDraw2Impl_FlipToGDISurface,
4211 Xlib_IDirectDraw2Impl_GetCaps,
4212 Xlib_IDirectDraw2Impl_GetDisplayMode,
4213 IDirectDraw2Impl_GetFourCCCodes,
4214 IDirectDraw2Impl_GetGDISurface,
4215 IDirectDraw2Impl_GetMonitorFrequency,
4216 IDirectDraw2Impl_GetScanLine,
4217 IDirectDraw2Impl_GetVerticalBlankStatus,
4218 IDirectDraw2Impl_Initialize,
4219 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4220 IDirectDraw2Impl_SetCooperativeLevel,
4221 Xlib_IDirectDraw2Impl_SetDisplayMode,
4222 IDirectDraw2Impl_WaitForVerticalBlank,
4223 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4226 /*****************************************************************************
4231 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4233 LPDIRECTDRAWSURFACE *lpDDS) {
4234 ICOM_THIS(IDirectDraw4Impl,iface);
4235 FIXME(ddraw, "(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4240 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4241 ICOM_THIS(IDirectDraw4Impl,iface);
4242 FIXME(ddraw, "(%p)->()\n", This);
4247 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4248 ICOM_THIS(IDirectDraw4Impl,iface);
4249 FIXME(ddraw, "(%p)->()\n", This);
4254 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4255 LPDDDEVICEIDENTIFIER lpdddi,
4257 ICOM_THIS(IDirectDraw4Impl,iface);
4258 FIXME(ddraw, "(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4264 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4266 # define XCAST(fun) (void*)
4270 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt = {
4271 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4272 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4273 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4274 XCAST(Compact)IDirectDraw2Impl_Compact,
4275 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4276 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4277 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4278 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4279 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4280 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4281 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4282 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4283 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4284 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4285 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4286 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4287 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4288 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4289 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4290 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4291 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4292 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4293 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4294 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4295 IDirectDraw4Impl_GetSurfaceFromDC,
4296 IDirectDraw4Impl_RestoreAllSurfaces,
4297 IDirectDraw4Impl_TestCooperativeLevel,
4298 IDirectDraw4Impl_GetDeviceIdentifier
4301 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = {
4302 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4303 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4304 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4305 XCAST(Compact)IDirectDraw2Impl_Compact,
4306 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4307 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4308 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4309 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4310 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4311 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4312 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4313 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4314 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4315 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4316 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4317 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4318 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4319 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4320 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4321 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4322 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4323 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4324 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4325 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4326 IDirectDraw4Impl_GetSurfaceFromDC,
4327 IDirectDraw4Impl_RestoreAllSurfaces,
4328 IDirectDraw4Impl_TestCooperativeLevel,
4329 IDirectDraw4Impl_GetDeviceIdentifier
4334 /******************************************************************************
4338 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4341 IDirectDrawImpl* ddraw = NULL;
4344 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4346 SetLastError( ERROR_SUCCESS );
4347 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4349 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4352 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4357 /* Perform any special direct draw functions */
4359 ddraw->d.paintable = 1;
4361 /* Now let the application deal with the rest of this */
4362 if( ddraw->d.mainWindow )
4365 /* Don't think that we actually need to call this but...
4366 might as well be on the safe side of things... */
4368 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4369 it should be the procedures of our fake window that gets called
4370 instead of those of the window provided by the application.
4371 And with this patch, mouse clicks work with Monkey Island III
4373 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4377 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4378 /* We didn't handle the message - give it to the application */
4379 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4381 ret = CallWindowProcA(tmpWnd->winproc,
4382 ddraw->d.mainWindow, msg, wParam, lParam );
4384 WIN_ReleaseWndPtr(tmpWnd);
4389 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4395 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4401 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4402 #ifdef HAVE_LIBXXF86DGA
4403 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4404 int memsize,banksize,width,major,minor,flags,height;
4409 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4410 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4414 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4415 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4416 return E_UNEXPECTED;
4418 if (!DDRAW_DGA_Available()) {
4419 TRACE(ddraw,"No XF86DGA detected.\n");
4420 return DDERR_GENERIC;
4422 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4423 (*ilplpDD)->lpvtbl = &dga_ddvt;
4424 (*ilplpDD)->ref = 1;
4425 TSXF86DGAQueryVersion(display,&major,&minor);
4426 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4427 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4428 if (!(flags & XF86DGADirectPresent))
4429 MSG("direct video is NOT PRESENT.\n");
4430 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4431 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4432 addr,width,banksize,memsize
4434 (*ilplpDD)->e.dga.fb_width = width;
4435 (*ilplpDD)->d.width = width;
4436 (*ilplpDD)->e.dga.fb_addr = addr;
4437 (*ilplpDD)->e.dga.fb_memsize = memsize;
4438 (*ilplpDD)->e.dga.fb_banksize = banksize;
4440 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4441 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4442 (*ilplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4444 (*ilplpDD)->e.dga.vpmask = 1;
4446 (*ilplpDD)->e.dga.vpmask = 0;
4449 /* just assume the default depth is the DGA depth too */
4450 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4451 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4452 #ifdef RESTORE_SIGNALS
4453 SIGNAL_InitHandlers();
4457 #else /* defined(HAVE_LIBXXF86DGA) */
4458 return DDERR_INVALIDDIRECTDRAWGUID;
4459 #endif /* defined(HAVE_LIBXXF86DGA) */
4463 DDRAW_XSHM_Available(void)
4465 #ifdef HAVE_LIBXXSHM
4466 if (TSXShmQueryExtension(display))
4471 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4483 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4484 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4487 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4488 (*ilplpDD)->lpvtbl = &xlib_ddvt;
4489 (*ilplpDD)->ref = 1;
4490 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
4492 /* At DirectDraw creation, the depth is the default depth */
4493 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4494 _common_depth_to_pixelformat(depth,
4495 &((*ilplpDD)->d.directdraw_pixelformat),
4496 &((*ilplpDD)->d.screen_pixelformat),
4497 &((*ilplpDD)->d.pixmap_depth));
4498 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4499 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4501 #ifdef HAVE_LIBXXSHM
4502 /* Test if XShm is available. */
4503 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4504 TRACE(ddraw, "Using XShm extension.\n");
4510 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4511 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4514 /* WND* pParentWindow; */
4518 WINE_StringFromCLSID(lpGUID,xclsid);
4520 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4524 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
4527 (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4528 (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4529 (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4530 /* if they didn't request a particular interface, use the best
4532 if (DDRAW_DGA_Available())
4533 lpGUID = &DGA_DirectDraw_GUID;
4535 lpGUID = &XLIB_DirectDraw_GUID;
4538 wc.style = CS_GLOBALCLASS;
4539 wc.lpfnWndProc = Xlib_DDWndProc;
4541 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
4542 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
4544 /* We can be a child of the desktop since we're really important */
4546 This code is not useful since hInstance is forced to 0 afterward
4547 pParentWindow = WIN_GetDesktop();
4548 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
4554 wc.hCursor = (HCURSOR)IDC_ARROWA;
4555 wc.hbrBackground= NULL_BRUSH;
4556 wc.lpszMenuName = 0;
4557 wc.lpszClassName= "WINE_DirectDraw";
4558 RegisterClassA(&wc);
4560 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4561 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4562 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4563 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4568 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
4572 ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4573 return DDERR_INVALIDDIRECTDRAWGUID;
4577 #else /* !defined(X_DISPLAY_MISSING) */
4583 typedef void *LPGUID;
4584 typedef void *LPUNKNOWN;
4585 typedef void *LPDIRECTDRAW;
4586 typedef void *LPDIRECTDRAWCLIPPER;
4587 typedef void *LPDDENUMCALLBACKA;
4588 typedef void *LPDDENUMCALLBACKEXA;
4589 typedef void *LPDDENUMCALLBACKEXW;
4590 typedef void *LPDDENUMCALLBACKW;
4592 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
4597 HRESULT WINAPI DirectDrawCreate(
4598 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
4603 HRESULT WINAPI DirectDrawCreateClipper(
4604 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
4609 HRESULT WINAPI DirectDrawEnumerateA(
4610 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
4615 HRESULT WINAPI DirectDrawEnumerateExA(
4616 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
4621 HRESULT WINAPI DirectDrawEnumerateExW(
4622 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
4627 HRESULT WINAPI DirectDrawEnumerateW(
4628 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
4633 #endif /* !defined(X_DISPLAY_MISSING) */
4636 /*******************************************************************************
4637 * DirectDraw ClassFactory
4639 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
4644 /* IUnknown fields */
4645 ICOM_VTABLE(IClassFactory)* lpvtbl;
4647 } IClassFactoryImpl;
4649 static HRESULT WINAPI
4650 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
4651 ICOM_THIS(IClassFactoryImpl,iface);
4655 WINE_StringFromCLSID(riid,buf);
4657 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4658 FIXME(ddraw,"(%p)->(%s,%p),stub!\n",This,buf,ppobj);
4659 return E_NOINTERFACE;
4663 DDCF_AddRef(LPCLASSFACTORY iface) {
4664 ICOM_THIS(IClassFactoryImpl,iface);
4665 return ++(This->ref);
4668 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
4669 ICOM_THIS(IClassFactoryImpl,iface);
4670 /* static class, won't be freed */
4671 return --(This->ref);
4674 static HRESULT WINAPI DDCF_CreateInstance(
4675 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
4677 ICOM_THIS(IClassFactoryImpl,iface);
4680 WINE_StringFromCLSID(riid,buf);
4681 TRACE(ddraw,"(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
4682 if ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4683 (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4684 (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4685 /* FIXME: reuse already created DirectDraw if present? */
4686 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
4688 return E_NOINTERFACE;
4691 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
4692 ICOM_THIS(IClassFactoryImpl,iface);
4693 FIXME(ddraw,"(%p)->(%d),stub!\n",This,dolock);
4697 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl = {
4698 DDCF_QueryInterface,
4701 DDCF_CreateInstance,
4704 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
4706 /*******************************************************************************
4707 * DllGetClassObject [DDRAW.13]
4708 * Retrieves class object from a DLL object
4711 * Docs say returns STDAPI
4714 * rclsid [I] CLSID for the class object
4715 * riid [I] Reference to identifier of interface for class object
4716 * ppv [O] Address of variable to receive interface pointer for riid
4720 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
4723 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
4725 char buf[80],xbuf[80];
4728 WINE_StringFromCLSID(rclsid,xbuf);
4730 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
4732 WINE_StringFromCLSID(riid,buf);
4734 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4735 WINE_StringFromCLSID(riid,xbuf);
4736 TRACE(ddraw, "(%p,%p,%p)\n", xbuf, buf, ppv);
4737 if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
4738 *ppv = (LPVOID)&DDRAW_CF;
4739 IClassFactory_AddRef((IClassFactory*)*ppv);
4742 FIXME(ddraw, "(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
4743 return E_NOINTERFACE;
4747 /*******************************************************************************
4748 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
4754 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
4756 FIXME(ddraw, "(void): stub\n");