- added some more debug output
[wine.git] / graphics / ddraw.c
blob927b41cfa16b540e2e1aab2b4066443837b883c2
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
5 */
6 /* XF86DGA:
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
10 * is running.
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.
17 #include "config.h"
19 #ifndef X_DISPLAY_MISSING
21 #include "ts_xlib.h"
22 #include "ts_xutil.h"
24 #ifdef HAVE_LIBXXSHM
25 #include <sys/types.h>
26 #include <sys/ipc.h>
27 #include <sys/shm.h>
28 #include "ts_xshm.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 */
38 #define XMD_H
39 typedef int INT32;
40 #include "ts_xf86vmode.h"
41 #endif /* defined(HAVE_LIBXXF86VM) */
43 #include "x11drv.h"
45 #include <unistd.h>
46 #include <assert.h>
47 #include <sys/signal.h>
48 #include <fcntl.h>
49 #include <string.h>
50 #include <stdlib.h>
52 #include "winerror.h"
53 #include "gdi.h"
54 #include "heap.h"
55 #include "dc.h"
56 #include "win.h"
57 #include "miscemu.h"
58 #include "ddraw.h"
59 #include "d3d.h"
60 #include "debug.h"
61 #include "spy.h"
62 #include "message.h"
63 #include "options.h"
64 #include "monitor.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) */
73 #undef DIABLO_HACK
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 */
84 0xe2dcb020,
85 0xdc60,
86 0x11d1,
87 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
90 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
91 0x1574a740,
92 0xdc61,
93 0x11d1,
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;
108 #endif
110 #ifdef HAVE_LIBXXSHM
111 static int XShmErrorFlag = 0;
112 #endif
114 BOOL
115 DDRAW_DGA_Available(void)
117 #ifdef HAVE_LIBXXF86DGA
118 int evbase, evret, fd;
120 if (Options.noDGA)
121 return 0;
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)
127 close(fd);
129 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
130 #else /* defined(HAVE_LIBXXF86DGA) */
131 return 0;
132 #endif /* defined(HAVE_LIBXXF86DGA) */
135 /**********************************************************************/
137 typedef struct {
138 LPVOID lpCallback;
139 LPVOID lpContext;
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)) {
151 DUMP(" Flags : ");
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 ");
158 DUMP("\n");
161 if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
162 /* For the moment, Wine does not support any 3D only accelerators */
163 return DD_OK;
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))
169 return DD_OK;
172 TRACE(ddraw, "Enumerating Xlib interface\n");
173 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
174 return DD_OK;
176 TRACE(ddraw, "Enumerating Default interface\n");
177 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
178 return DD_OK;
180 return DD_OK;
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);
204 return bResult;
207 /**********************************************************************/
209 HRESULT WINAPI DirectDrawEnumerateExW(
210 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
212 DirectDrawEnumerateProcData epd;
213 epd.lpCallback = (LPVOID) lpCallback;
214 epd.lpContext = lpContext;
216 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
217 (LPVOID) &epd, 0);
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 = (LPVOID) lpCallback;
242 epd.lpContext = lpContext;
244 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
245 (LPVOID) &epd, 0);
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,
261 pEPD->lpContext);
264 /**********************************************************************/
266 HRESULT WINAPI DirectDrawEnumerateW(
267 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
269 DirectDrawEnumerateProcData epd;
270 epd.lpCallback = (LPVOID) lpCallback;
271 epd.lpContext = lpContext;
273 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
274 (LPVOID) &epd, 0);
277 /***********************************************************************
278 * DSoundHelp (DDRAW.?)
281 /* What is this doing here? */
282 HRESULT WINAPI
283 DSoundHelp(DWORD x,DWORD y,DWORD z) {
284 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
285 return 0;
288 /******************************************************************************
289 * internal helper functions
291 static void _dump_DDBLTFX(DWORD flagmask) {
292 int i;
293 const struct {
294 DWORD mask;
295 char *name;
296 } flags[] = {
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)
304 FE(DDBLTFX_ROTATE90)
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);
313 DUMP("\n");
317 static void _dump_DDBLTFAST(DWORD flagmask) {
318 int i;
319 const struct {
320 DWORD mask;
321 char *name;
322 } flags[] = {
323 #define FE(x) { x, #x},
324 FE(DDBLTFAST_NOCOLORKEY)
325 FE(DDBLTFAST_SRCCOLORKEY)
326 FE(DDBLTFAST_DESTCOLORKEY)
327 FE(DDBLTFAST_WAIT)
329 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
330 if (flags[i].mask & flagmask)
331 DUMP("%s ",flags[i].name);
332 DUMP("\n");
335 static void _dump_DDBLT(DWORD flagmask) {
336 int i;
337 const struct {
338 DWORD mask;
339 char *name;
340 } flags[] = {
341 #define FE(x) { x, #x},
342 FE(DDBLT_ALPHADEST)
343 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
344 FE(DDBLT_ALPHADESTNEG)
345 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
346 FE(DDBLT_ALPHAEDGEBLEND)
347 FE(DDBLT_ALPHASRC)
348 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
349 FE(DDBLT_ALPHASRCNEG)
350 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
351 FE(DDBLT_ASYNC)
352 FE(DDBLT_COLORFILL)
353 FE(DDBLT_DDFX)
354 FE(DDBLT_DDROPS)
355 FE(DDBLT_KEYDEST)
356 FE(DDBLT_KEYDESTOVERRIDE)
357 FE(DDBLT_KEYSRC)
358 FE(DDBLT_KEYSRCOVERRIDE)
359 FE(DDBLT_ROP)
360 FE(DDBLT_ROTATIONANGLE)
361 FE(DDBLT_ZBUFFER)
362 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
363 FE(DDBLT_ZBUFFERDESTOVERRIDE)
364 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
365 FE(DDBLT_ZBUFFERSRCOVERRIDE)
366 FE(DDBLT_WAIT)
367 FE(DDBLT_DEPTHFILL)
369 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
370 if (flags[i].mask & flagmask)
371 DUMP("%s ",flags[i].name);
372 DUMP("\n");
375 static void _dump_DDSCAPS(DWORD flagmask) {
376 int i;
377 const struct {
378 DWORD mask;
379 char *name;
380 } flags[] = {
381 #define FE(x) { x, #x},
382 FE(DDSCAPS_RESERVED1)
383 FE(DDSCAPS_ALPHA)
384 FE(DDSCAPS_BACKBUFFER)
385 FE(DDSCAPS_COMPLEX)
386 FE(DDSCAPS_FLIP)
387 FE(DDSCAPS_FRONTBUFFER)
388 FE(DDSCAPS_OFFSCREENPLAIN)
389 FE(DDSCAPS_OVERLAY)
390 FE(DDSCAPS_PALETTE)
391 FE(DDSCAPS_PRIMARYSURFACE)
392 FE(DDSCAPS_PRIMARYSURFACELEFT)
393 FE(DDSCAPS_SYSTEMMEMORY)
394 FE(DDSCAPS_TEXTURE)
395 FE(DDSCAPS_3DDEVICE)
396 FE(DDSCAPS_VIDEOMEMORY)
397 FE(DDSCAPS_VISIBLE)
398 FE(DDSCAPS_WRITEONLY)
399 FE(DDSCAPS_ZBUFFER)
400 FE(DDSCAPS_OWNDC)
401 FE(DDSCAPS_LIVEVIDEO)
402 FE(DDSCAPS_HWCODEC)
403 FE(DDSCAPS_MODEX)
404 FE(DDSCAPS_MIPMAP)
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);
416 DUMP("\n");
419 static void _dump_DDSD(DWORD flagmask) {
420 int i;
421 const struct {
422 DWORD mask;
423 char *name;
424 } flags[] = {
425 FE(DDSD_CAPS)
426 FE(DDSD_HEIGHT)
427 FE(DDSD_WIDTH)
428 FE(DDSD_PITCH)
429 FE(DDSD_BACKBUFFERCOUNT)
430 FE(DDSD_ZBUFFERBITDEPTH)
431 FE(DDSD_ALPHABITDEPTH)
432 FE(DDSD_PIXELFORMAT)
433 FE(DDSD_CKDESTOVERLAY)
434 FE(DDSD_CKDESTBLT)
435 FE(DDSD_CKSRCOVERLAY)
436 FE(DDSD_CKSRCBLT)
437 FE(DDSD_MIPMAPCOUNT)
438 FE(DDSD_REFRESHRATE)
439 FE(DDSD_LINEARSIZE)
440 FE(DDSD_LPSURFACE)
442 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
443 if (flags[i].mask & flagmask)
444 DUMP("%s ",flags[i].name);
445 DUMP("\n");
448 static void _dump_DDCOLORKEY(DWORD flagmask) {
449 int i;
450 const struct {
451 DWORD mask;
452 char *name;
453 } flags[] = {
454 #define FE(x) { x, #x},
455 FE(DDPF_ALPHAPIXELS)
456 FE(DDPF_ALPHA)
457 FE(DDPF_FOURCC)
458 FE(DDPF_PALETTEINDEXED4)
459 FE(DDPF_PALETTEINDEXEDTO8)
460 FE(DDPF_PALETTEINDEXED8)
461 FE(DDPF_RGB)
462 FE(DDPF_COMPRESSED)
463 FE(DDPF_RGBTOYUV)
464 FE(DDPF_YUV)
465 FE(DDPF_ZBUFFER)
466 FE(DDPF_PALETTEINDEXED1)
467 FE(DDPF_PALETTEINDEXED2)
468 FE(DDPF_ZPIXELS)
470 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
471 if (flags[i].mask & flagmask)
472 DUMP("%s ",flags[i].name);
473 DUMP("\n");
476 static void _dump_paletteformat(DWORD dwFlags) {
477 int i;
478 const struct {
479 DWORD mask;
480 char *name;
481 } flags[] = {
482 #define FE(x) { x, #x},
483 FE(DDPCAPS_4BIT)
484 FE(DDPCAPS_8BITENTRIES)
485 FE(DDPCAPS_8BIT)
486 FE(DDPCAPS_INITIALIZE)
487 FE(DDPCAPS_PRIMARYSURFACE)
488 FE(DDPCAPS_PRIMARYSURFACELEFT)
489 FE(DDPCAPS_ALLOW256)
490 FE(DDPCAPS_VSYNC)
491 FE(DDPCAPS_1BIT)
492 FE(DDPCAPS_2BIT)
493 FE(DDPCAPS_ALPHA)
495 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
496 if (flags[i].mask & dwFlags)
497 DUMP("%s ",flags[i].name);
498 DUMP("\n");
501 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
502 DUMP("Size : %ld\n", pf->dwSize);
503 if (pf->dwFlags)
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) {
512 int i;
513 const struct {
514 DWORD mask;
515 char *name;
516 } flags[] = {
517 #define FE(x) { x, #x},
518 FE(DDCKEY_COLORSPACE)
519 FE(DDCKEY_DESTBLT)
520 FE(DDCKEY_DESTOVERLAY)
521 FE(DDCKEY_SRCBLT)
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);
527 DUMP("\n");
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 */
553 if (lprect) {
554 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
555 lprect->top,lprect->left,lprect->bottom,lprect->right
557 lpddsd->y.lpSurface = (LPVOID) ((char *) 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)));
560 } else {
561 assert(This->s.surface_desc.y.lpSurface);
563 return DD_OK;
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);
571 return DD_OK;
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,
581 This->s.palette);
583 #ifdef HAVE_LIBXXSHM
584 if (This->s.ddraw->e.xlib.xshm_active)
585 TSXShmPutImage(display,
586 This->s.ddraw->d.drawable,
587 DefaultGCOfScreen(X11DRV_GetXScreen()),
588 This->t.xlib.image,
589 0, 0, 0, 0,
590 This->t.xlib.image->width,
591 This->t.xlib.image->height,
592 False);
593 else
594 #endif
595 TSXPutImage( display,
596 This->s.ddraw->d.drawable,
597 DefaultGCOfScreen(X11DRV_GetXScreen()),
598 This->t.xlib.image,
599 0, 0, 0, 0,
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)
611 return DD_OK;
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);
622 return DD_OK;
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);
632 if (!iflipto) {
633 if (This->s.backbuffer)
634 iflipto = This->s.backbuffer;
635 else
636 iflipto = This;
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)) {
645 if (iflipto!=This) {
646 int tmp;
647 LPVOID ptmp;
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;
657 return DD_OK;
658 #else /* defined(HAVE_LIBXXF86DGA) */
659 return E_UNEXPECTED;
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);
670 #ifdef HAVE_MESAGL
671 if ((This->s.d3d_device != NULL) ||
672 ((This->s.backbuffer != NULL) && (This->s.backbuffer->s.d3d_device != NULL))) {
673 TRACE(ddraw," - OpenGL flip\n");
674 ENTER_GL();
675 glXSwapBuffers(display,
676 This->s.ddraw->d.drawable);
677 LEAVE_GL();
679 return DD_OK;
681 #endif /* defined(HAVE_MESAGL) */
683 if (!This->s.ddraw->d.paintable)
684 return DD_OK;
686 if (!iflipto) {
687 if (This->s.backbuffer)
688 iflipto = This->s.backbuffer;
689 else
690 iflipto = This;
693 Xlib_copy_surface_on_screen(iflipto);
695 if (iflipto->s.palette && iflipto->s.palette->cm) {
696 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
698 if (iflipto!=This) {
699 XImage *tmp;
700 LPVOID *surf;
701 tmp = This->t.xlib.image;
702 This->t.xlib.image = iflipto->t.xlib.image;
703 iflipto->t.xlib.image = tmp;
704 surf = This->s.surface_desc.y.lpSurface;
705 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
706 iflipto->s.surface_desc.y.lpSurface = surf;
708 return DD_OK;
712 /* The IDirectDrawSurface4::SetPalette method attaches the specified
713 * DirectDrawPalette object to a surface. The surface uses this palette for all
714 * subsequent operations. The palette change takes place immediately.
716 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
717 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
719 ICOM_THIS(IDirectDrawSurface4Impl,iface);
720 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
721 int i;
722 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
724 if (ipal == NULL) {
725 if( This->s.palette != NULL )
726 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
727 This->s.palette = ipal;
729 return DD_OK;
732 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
734 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
735 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
737 if (!Options.managed)
738 TSXInstallColormap(display,ipal->cm);
740 for (i=0;i<256;i++) {
741 XColor xc;
743 xc.red = ipal->palents[i].peRed<<8;
744 xc.blue = ipal->palents[i].peBlue<<8;
745 xc.green = ipal->palents[i].peGreen<<8;
746 xc.flags = DoRed|DoBlue|DoGreen;
747 xc.pixel = i;
748 TSXStoreColor(display,ipal->cm,&xc);
750 TSXInstallColormap(display,ipal->cm);
753 /* According to spec, we are only supposed to
754 * AddRef if this is not the same palette.
756 if( This->s.palette != ipal )
758 if( ipal != NULL )
759 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
760 if( This->s.palette != NULL )
761 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
762 This->s.palette = ipal;
764 /* I think that we need to attach it to all backbuffers...*/
765 if( This->s.backbuffer ) {
766 if( This->s.backbuffer->s.palette )
767 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
768 This->s.backbuffer->s.palette = ipal;
769 if( ipal )
770 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
772 /* Perform the refresh */
773 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
775 return DD_OK;
778 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
779 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
781 ICOM_THIS(IDirectDrawSurface4Impl,iface);
782 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
783 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
784 #ifdef HAVE_LIBXXF86DGA
785 /* According to spec, we are only supposed to
786 * AddRef if this is not the same palette.
788 if( This->s.palette != ipal )
790 if( ipal != NULL )
791 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
792 if( This->s.palette != NULL )
793 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
794 This->s.palette = ipal;
796 /* I think that we need to attach it to all backbuffers...*/
797 if( This->s.backbuffer ) {
798 if( This->s.backbuffer->s.palette )
799 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
800 This->s.backbuffer->s.palette = ipal;
801 if ( ipal )
802 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
804 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
806 return DD_OK;
807 #else /* defined(HAVE_LIBXXF86DGA) */
808 return E_UNEXPECTED;
809 #endif /* defined(HAVE_LIBXXF86DGA) */
814 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
816 int x, y;
817 LPBYTE first;
819 /* Do first row */
821 #define COLORFILL_ROW(type) { \
822 type *d = (type *) buf; \
823 for (x = 0; x < width; x++) \
824 d[x] = (type) color; \
825 break; \
828 switch(bpp) {
829 case 1: COLORFILL_ROW(BYTE)
830 case 2: COLORFILL_ROW(WORD)
831 case 4: COLORFILL_ROW(DWORD)
832 default:
833 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
834 return DDERR_UNSUPPORTED;
837 #undef COLORFILL_ROW
839 /* Now copy first row */
840 first = buf;
841 for (y = 1; y < height; y++) {
842 buf += lPitch;
843 memcpy(buf, first, width * bpp);
846 return DD_OK;
849 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
850 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
852 ICOM_THIS(IDirectDrawSurface4Impl,iface);
853 RECT xdst,xsrc;
854 DDSURFACEDESC ddesc,sdesc;
855 HRESULT ret = DD_OK;
856 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
857 int x, y;
858 LPBYTE dbuf, sbuf;
860 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
862 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
863 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
865 if (TRACE_ON(ddraw)) {
866 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
867 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
868 TRACE(ddraw,"\tflags: ");
869 _dump_DDBLT(dwFlags);
870 if (dwFlags & DDBLT_DDFX) {
871 TRACE(ddraw," blitfx: \n");
872 _dump_DDBLTFX(lpbltfx->dwDDFX);
876 if (rdst) {
877 memcpy(&xdst,rdst,sizeof(xdst));
878 } else {
879 xdst.top = 0;
880 xdst.bottom = ddesc.dwHeight;
881 xdst.left = 0;
882 xdst.right = ddesc.dwWidth;
885 if (rsrc) {
886 memcpy(&xsrc,rsrc,sizeof(xsrc));
887 } else {
888 if (src) {
889 xsrc.top = 0;
890 xsrc.bottom = sdesc.dwHeight;
891 xsrc.left = 0;
892 xsrc.right = sdesc.dwWidth;
893 } else {
894 memset(&xsrc,0,sizeof(xsrc));
898 bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
899 srcheight = xsrc.bottom - xsrc.top;
900 srcwidth = xsrc.right - xsrc.left;
901 dstheight = xdst.bottom - xdst.top;
902 dstwidth = xdst.right - xdst.left;
903 width = (xdst.right - xdst.left) * bpp;
904 dbuf = (BYTE *) ddesc.y.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
906 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
908 /* First, all the 'source-less' blits */
909 if (dwFlags & DDBLT_COLORFILL) {
910 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
911 ddesc.lPitch, lpbltfx->b.dwFillColor);
912 dwFlags &= ~DDBLT_COLORFILL;
915 if (dwFlags & DDBLT_DEPTHFILL) {
916 #ifdef HAVE_MESAGL
917 GLboolean ztest;
919 /* Clears the screen */
920 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
921 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
922 glGetBooleanv(GL_DEPTH_TEST, &ztest);
923 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
924 glClear(GL_DEPTH_BUFFER_BIT);
925 glDepthMask(ztest);
927 dwFlags &= ~(DDBLT_DEPTHFILL);
928 #endif /* defined(HAVE_MESAGL) */
931 if (dwFlags & DDBLT_ROP) {
932 /* Catch some degenerate cases here */
933 switch(lpbltfx->dwROP) {
934 case BLACKNESS:
935 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
936 break;
937 case 0xAA0029: /* No-op */
938 break;
939 case WHITENESS:
940 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
941 break;
942 default:
943 FIXME(ddraw, "Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->b.lpDDSPattern);
944 goto error;
946 dwFlags &= ~DDBLT_ROP;
949 if (dwFlags & DDBLT_DDROPS) {
950 FIXME(ddraw, "\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->b.lpDDSPattern);
953 /* Now the 'with source' blits */
954 if (src) {
955 LPBYTE sbase;
956 int sx, xinc, sy, yinc;
958 sbase = (BYTE *) sdesc.y.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
959 xinc = (srcwidth << 16) / dstwidth;
960 yinc = (srcheight << 16) / dstheight;
962 if (!dwFlags) {
964 /* No effects, we can cheat here */
965 if (dstwidth == srcwidth) {
966 if (dstheight == srcheight) {
967 /* No stretching in either direction. This needs to be as fast as possible */
968 sbuf = sbase;
969 for (y = 0; y < dstheight; y++) {
970 memcpy(dbuf, sbuf, width);
971 sbuf += sdesc.lPitch;
972 dbuf += ddesc.lPitch;
974 } else {
975 /* Stretching in Y direction only */
976 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
977 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
978 memcpy(dbuf, sbuf, width);
979 dbuf += ddesc.lPitch;
982 } else {
983 /* Stretching in X direction */
984 int last_sy = -1;
985 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
986 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
988 if ((sy >> 16) == (last_sy >> 16)) {
989 /* Same as last row - copy already stretched row */
990 memcpy(dbuf, dbuf - ddesc.lPitch, width);
991 } else {
993 #define STRETCH_ROW(type) { \
994 type *s = (type *) sbuf, *d = (type *) dbuf; \
995 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
996 d[x] = s[sx >> 16]; \
997 break; \
1000 switch(bpp) {
1001 case 1: STRETCH_ROW(BYTE)
1002 case 2: STRETCH_ROW(WORD)
1003 case 4: STRETCH_ROW(DWORD)
1004 default:
1005 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
1006 ret = DDERR_UNSUPPORTED;
1007 goto error;
1010 #undef STRETCH_ROW
1013 last_sy = sy;
1014 dbuf += ddesc.lPitch;
1017 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1018 DWORD keylow, keyhigh;
1020 if (dwFlags & DDBLT_KEYSRC) {
1021 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1022 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1023 } else {
1024 /* I'm not sure if this is correct */
1025 FIXME(ddraw, "DDBLT_KEYDEST not fully supported yet.\n");
1026 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1027 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1030 #define COPYROW_COLORKEY(type) { \
1031 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1032 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1033 tmp = s[sx >> 16]; \
1034 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1036 break; \
1039 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1040 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1042 switch (bpp) {
1043 case 1: COPYROW_COLORKEY(BYTE)
1044 case 2: COPYROW_COLORKEY(WORD)
1045 case 4: COPYROW_COLORKEY(DWORD)
1046 default:
1047 FIXME(ddraw, "%s color-keyed blit not implemented for bpp %d!\n",
1048 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1049 ret = DDERR_UNSUPPORTED;
1050 goto error;
1052 dbuf += ddesc.lPitch;
1055 #undef COPYROW_COLORKEY
1057 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1062 error:
1064 if (dwFlags && FIXME_ON(ddraw)) {
1065 FIXME(ddraw,"\tUnsupported flags: ");
1066 _dump_DDBLT(dwFlags);
1069 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1070 if (src) IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1072 return DD_OK;
1075 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1076 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1078 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1079 int bpp, w, h, x, y;
1080 DDSURFACEDESC ddesc,sdesc;
1081 HRESULT ret = DD_OK;
1082 LPBYTE sbuf, dbuf;
1085 if (TRACE_ON(ddraw)) {
1086 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1087 This,dstx,dsty,src,rsrc,trans
1089 FIXME(ddraw," trans:");
1090 if (FIXME_ON(ddraw))
1091 _dump_DDBLTFAST(trans);
1092 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1094 /* We need to lock the surfaces, or we won't get refreshes when done. */
1095 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1096 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1098 bpp = This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
1099 sbuf = (BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1100 dbuf = (BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1103 h=rsrc->bottom-rsrc->top;
1104 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1105 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1106 if (h<0) h=0;
1108 w=rsrc->right-rsrc->left;
1109 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1110 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1111 if (w<0) w=0;
1113 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1114 DWORD keylow, keyhigh;
1115 if (trans & DDBLTFAST_SRCCOLORKEY) {
1116 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1117 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1118 } else {
1119 /* I'm not sure if this is correct */
1120 FIXME(ddraw, "DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1121 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1122 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1125 #define COPYBOX_COLORKEY(type) { \
1126 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1127 s = (type *) ((BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1128 d = (type *) ((BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1129 for (y = 0; y < h; y++) { \
1130 for (x = 0; x < w; x++) { \
1131 tmp = s[x]; \
1132 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1134 (LPBYTE)s += sdesc.lPitch; \
1135 (LPBYTE)d += ddesc.lPitch; \
1137 break; \
1140 switch (bpp) {
1141 case 1: COPYBOX_COLORKEY(BYTE)
1142 case 2: COPYBOX_COLORKEY(WORD)
1143 case 4: COPYBOX_COLORKEY(DWORD)
1144 default:
1145 FIXME(ddraw, "Source color key blitting not supported for bpp %d\n", bpp*8);
1146 ret = DDERR_UNSUPPORTED;
1147 goto error;
1150 #undef COPYBOX_COLORKEY
1152 } else {
1153 int width = w * bpp;
1155 for (y = 0; y < h; y++) {
1156 memcpy(dbuf, sbuf, width);
1157 sbuf += sdesc.lPitch;
1158 dbuf += ddesc.lPitch;
1162 error:
1164 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1165 IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1166 return ret;
1169 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1170 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1172 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1173 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1174 This,ddbltbatch,x,y
1176 return DD_OK;
1179 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1180 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1182 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1183 TRACE(ddraw,"(%p)->GetCaps(%p)\n",This,caps);
1184 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1185 return DD_OK;
1188 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1189 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1190 ) {
1191 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1192 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
1193 This,ddsd);
1195 /* Simply copy the surface description stored in the object */
1196 *ddsd = This->s.surface_desc;
1198 if (TRACE_ON(ddraw)) {
1199 DUMP(" flags: ");
1200 _dump_DDSD(ddsd->dwFlags);
1201 if (ddsd->dwFlags & DDSD_CAPS) {
1202 DUMP(" caps: ");
1203 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
1205 if (ddsd->dwFlags & DDSD_PIXELFORMAT) {
1206 DUMP(" pixel format : \n");
1207 _dump_pixelformat(&(ddsd->ddpfPixelFormat));
1211 return DD_OK;
1214 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1215 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1216 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1218 return ++(This->ref);
1221 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1222 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1223 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1225 #ifdef HAVE_LIBXXF86DGA
1226 if (!--(This->ref)) {
1227 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1228 /* clear out of surface list */
1229 if (This->t.dga.fb_height == -1) {
1230 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1231 } else {
1232 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1235 /* Free the backbuffer */
1236 if (This->s.backbuffer)
1237 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1239 HeapFree(GetProcessHeap(),0,This);
1240 return 0;
1242 #endif /* defined(HAVE_LIBXXF86DGA) */
1243 return This->ref;
1246 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1247 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1248 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1250 if (!--(This->ref)) {
1251 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1253 if( This->s.backbuffer )
1254 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1256 if (This->t.xlib.image != NULL) {
1257 if (This->s.ddraw->d.pixel_convert != NULL) {
1258 /* In pixel conversion mode, there are two buffers to release... */
1259 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1261 #ifdef HAVE_LIBXXSHM
1262 if (This->s.ddraw->e.xlib.xshm_active) {
1263 TSXShmDetach(display, &(This->t.xlib.shminfo));
1264 TSXDestroyImage(This->t.xlib.image);
1265 shmdt(This->t.xlib.shminfo.shmaddr);
1266 } else {
1267 #endif
1268 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1269 This->t.xlib.image->data = NULL;
1270 TSXDestroyImage(This->t.xlib.image);
1271 #ifdef HAVE_LIBXXSHM
1273 #endif
1275 } else {
1276 This->t.xlib.image->data = NULL;
1278 #ifdef HAVE_LIBXXSHM
1279 if (This->s.ddraw->e.xlib.xshm_active) {
1280 TSXShmDetach(display, &(This->t.xlib.shminfo));
1281 TSXDestroyImage(This->t.xlib.image);
1282 shmdt(This->t.xlib.shminfo.shmaddr);
1283 } else {
1284 #endif
1285 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1286 TSXDestroyImage(This->t.xlib.image);
1287 #ifdef HAVE_LIBXXSHM
1289 #endif
1292 This->t.xlib.image = 0;
1293 } else {
1294 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1297 if (This->s.palette)
1298 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1300 HeapFree(GetProcessHeap(),0,This);
1301 return 0;
1304 return This->ref;
1307 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1308 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1310 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1311 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1312 This, lpddsd, lpdsf);
1314 if (TRACE_ON(ddraw)) {
1315 TRACE(ddraw," caps ");
1316 _dump_DDSCAPS(lpddsd->dwCaps);
1319 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1320 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1321 return E_FAIL;
1324 /* FIXME: should handle more than one backbuffer */
1325 *lpdsf = (LPDIRECTDRAWSURFACE4)This->s.backbuffer;
1327 if( This->s.backbuffer )
1328 IDirectDrawSurface4_AddRef( (IDirectDrawSurface4*)This->s.backbuffer );
1330 return DD_OK;
1333 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1334 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1336 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1337 TRACE(ddraw,"(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1339 return DDERR_ALREADYINITIALIZED;
1342 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1343 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1345 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1346 TRACE(ddraw,"(%p)->(%p)\n",This,pf);
1348 *pf = This->s.surface_desc.ddpfPixelFormat;
1350 _dump_pixelformat(pf);
1352 return DD_OK;
1355 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1356 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1357 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,dwFlags);
1358 return DD_OK;
1361 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1362 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1364 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1365 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,x1,x2);
1366 return DD_OK;
1369 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1370 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1372 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1373 FIXME(ddraw,"(%p)->(%p),stub!\n",This,clipper);
1374 return DD_OK;
1377 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1378 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1380 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1381 FIXME(ddraw,"(%p)->(%p),stub!\n",This,surf);
1383 IDirectDrawSurface4_AddRef(iface);
1385 /* This hack will be enough for the moment */
1386 if (This->s.backbuffer == NULL)
1387 This->s.backbuffer = (IDirectDrawSurface4Impl*)surf;
1388 return DD_OK;
1391 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1392 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1393 FIXME(ddraw,"(%p)->GetDC(%p)\n",This,lphdc);
1394 *lphdc = BeginPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1395 return DD_OK;
1398 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1399 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1400 DDSURFACEDESC desc;
1401 DWORD x, y;
1403 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1404 EndPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1406 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1407 I fill it with 'dummy' values to have something on the screen */
1408 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1409 for (y = 0; y < desc.dwHeight; y++) {
1410 for (x = 0; x < desc.dwWidth; x++) {
1411 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) This + x + y;
1414 IDirectDrawSurface4_Unlock(iface,NULL);
1416 return DD_OK;
1420 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1421 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1422 char xrefiid[50];
1424 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1425 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
1427 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1428 * the same interface. And IUnknown does that too of course.
1430 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1431 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1432 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1433 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1434 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1436 *obj = This;
1437 IDirectDrawSurface4_AddRef(iface);
1439 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1441 return S_OK;
1443 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1445 /* Texture interface */
1446 *obj = d3dtexture2_create(This);
1447 IDirectDrawSurface4_AddRef(iface);
1449 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1451 return S_OK;
1453 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1455 /* Texture interface */
1456 *obj = d3dtexture_create(This);
1457 IDirectDrawSurface4_AddRef(iface);
1459 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1461 return S_OK;
1463 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj))
1465 /* It is the OpenGL Direct3D Device */
1466 IDirectDrawSurface4_AddRef(iface);
1468 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1470 return S_OK;
1473 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
1474 return OLE_E_ENUM_NOMORE;
1477 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1478 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1479 TRACE(ddraw,"(%p)->(), stub!\n",This);
1480 return DD_OK; /* hmm */
1483 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1484 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1485 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,context,esfcb);
1487 /* For the moment, only enumerating the back buffer */
1488 if (This->s.backbuffer != NULL) {
1489 TRACE(ddraw, "Enumerating back-buffer (%p)\n", This->s.backbuffer);
1490 if (esfcb((LPDIRECTDRAWSURFACE) This->s.backbuffer, &(This->s.backbuffer->s.surface_desc), context) == DDENUMRET_CANCEL)
1491 return DD_OK;
1494 return DD_OK;
1497 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1498 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1499 FIXME(ddraw,"(%p)->(),stub!\n",This);
1500 return DD_OK;
1503 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1504 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1506 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1507 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1508 if (TRACE_ON(ddraw)) {
1509 DUMP(" (0x%08lx <-> 0x%08lx) - ",
1510 ckey->dwColorSpaceLowValue,
1511 ckey->dwColorSpaceHighValue);
1512 _dump_colorkeyflag(dwFlags);
1515 /* If this surface was loaded as a texture, call also the texture
1516 SetColorKey callback */
1517 if (This->s.texture) {
1518 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1521 if( dwFlags & DDCKEY_SRCBLT )
1523 dwFlags &= ~DDCKEY_SRCBLT;
1524 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1525 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1528 if( dwFlags & DDCKEY_DESTBLT )
1530 dwFlags &= ~DDCKEY_DESTBLT;
1531 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1532 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1535 if( dwFlags & DDCKEY_SRCOVERLAY )
1537 dwFlags &= ~DDCKEY_SRCOVERLAY;
1538 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1539 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1542 if( dwFlags & DDCKEY_DESTOVERLAY )
1544 dwFlags &= ~DDCKEY_DESTOVERLAY;
1545 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1546 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1549 if( dwFlags )
1551 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1554 return DD_OK;
1558 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1559 LPDIRECTDRAWSURFACE4 iface,
1560 LPRECT lpRect )
1562 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1563 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpRect);
1565 return DD_OK;
1568 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1569 LPDIRECTDRAWSURFACE4 iface,
1570 DWORD dwFlags,
1571 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1573 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1574 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",This,dwFlags,lpDDSAttachedSurface);
1576 return DD_OK;
1579 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1580 LPDIRECTDRAWSURFACE4 iface,
1581 DWORD dwFlags,
1582 LPVOID lpContext,
1583 LPDDENUMSURFACESCALLBACK lpfnCallback )
1585 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1586 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1587 lpContext, lpfnCallback );
1589 return DD_OK;
1592 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1593 LPDIRECTDRAWSURFACE4 iface,
1594 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1596 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1597 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDClipper);
1599 return DD_OK;
1602 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1603 LPDIRECTDRAWSURFACE4 iface,
1604 DWORD dwFlags,
1605 LPDDCOLORKEY lpDDColorKey )
1607 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1608 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1610 if( dwFlags & DDCKEY_SRCBLT ) {
1611 dwFlags &= ~DDCKEY_SRCBLT;
1612 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1615 if( dwFlags & DDCKEY_DESTBLT )
1617 dwFlags &= ~DDCKEY_DESTBLT;
1618 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1621 if( dwFlags & DDCKEY_SRCOVERLAY )
1623 dwFlags &= ~DDCKEY_SRCOVERLAY;
1624 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1627 if( dwFlags & DDCKEY_DESTOVERLAY )
1629 dwFlags &= ~DDCKEY_DESTOVERLAY;
1630 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1633 if( dwFlags )
1635 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1638 return DD_OK;
1641 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1642 LPDIRECTDRAWSURFACE4 iface,
1643 DWORD dwFlags )
1645 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1646 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1648 return DD_OK;
1651 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1652 LPDIRECTDRAWSURFACE4 iface,
1653 LPDIRECTDRAWPALETTE* lplpDDPalette )
1655 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1656 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDPalette);
1658 return DD_OK;
1661 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1662 LPDIRECTDRAWSURFACE4 iface,
1663 LONG lX,
1664 LONG lY)
1666 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1667 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1669 return DD_OK;
1672 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1673 LPDIRECTDRAWSURFACE4 iface,
1674 LPRECT lpSrcRect,
1675 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1676 LPRECT lpDestRect,
1677 DWORD dwFlags,
1678 LPDDOVERLAYFX lpDDOverlayFx )
1680 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1681 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1682 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1684 return DD_OK;
1687 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1688 LPDIRECTDRAWSURFACE4 iface,
1689 DWORD dwFlags )
1691 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1692 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1694 return DD_OK;
1697 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1698 LPDIRECTDRAWSURFACE4 iface,
1699 DWORD dwFlags,
1700 LPDIRECTDRAWSURFACE4 lpDDSReference )
1702 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1703 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1705 return DD_OK;
1708 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1709 LPDIRECTDRAWSURFACE4 iface,
1710 LPVOID* lplpDD )
1712 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1713 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDD);
1715 /* Not sure about that... */
1716 *lplpDD = (void *) This->s.ddraw;
1718 return DD_OK;
1721 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1722 LPDIRECTDRAWSURFACE4 iface,
1723 DWORD dwFlags )
1725 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1726 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1728 return DD_OK;
1731 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1732 LPDIRECTDRAWSURFACE4 iface,
1733 DWORD dwFlags )
1735 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1736 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1738 return DD_OK;
1741 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1742 LPDIRECTDRAWSURFACE4 iface,
1743 LPDDSURFACEDESC lpDDSD,
1744 DWORD dwFlags )
1746 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1747 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1749 return DD_OK;
1752 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1753 REFGUID guidTag,
1754 LPVOID lpData,
1755 DWORD cbSize,
1756 DWORD dwFlags) {
1757 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1758 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1760 return DD_OK;
1763 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1764 REFGUID guidTag,
1765 LPVOID lpBuffer,
1766 LPDWORD lpcbBufferSize) {
1767 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1768 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1770 return DD_OK;
1773 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
1774 REFGUID guidTag) {
1775 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1776 FIXME(ddraw, "(%p)->(%p)\n", This, guidTag);
1778 return DD_OK;
1781 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
1782 LPDWORD lpValue) {
1783 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1784 FIXME(ddraw, "(%p)->(%p)\n", This, lpValue);
1786 return DD_OK;
1789 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
1790 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1791 FIXME(ddraw, "(%p)\n", This);
1793 return DD_OK;
1796 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
1798 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1799 IDirectDrawSurface4Impl_QueryInterface,
1800 IDirectDrawSurface4Impl_AddRef,
1801 DGA_IDirectDrawSurface4Impl_Release,
1802 IDirectDrawSurface4Impl_AddAttachedSurface,
1803 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1804 IDirectDrawSurface4Impl_Blt,
1805 IDirectDrawSurface4Impl_BltBatch,
1806 IDirectDrawSurface4Impl_BltFast,
1807 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1808 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1809 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1810 DGA_IDirectDrawSurface4Impl_Flip,
1811 IDirectDrawSurface4Impl_GetAttachedSurface,
1812 IDirectDrawSurface4Impl_GetBltStatus,
1813 IDirectDrawSurface4Impl_GetCaps,
1814 IDirectDrawSurface4Impl_GetClipper,
1815 IDirectDrawSurface4Impl_GetColorKey,
1816 IDirectDrawSurface4Impl_GetDC,
1817 IDirectDrawSurface4Impl_GetFlipStatus,
1818 IDirectDrawSurface4Impl_GetOverlayPosition,
1819 IDirectDrawSurface4Impl_GetPalette,
1820 IDirectDrawSurface4Impl_GetPixelFormat,
1821 IDirectDrawSurface4Impl_GetSurfaceDesc,
1822 IDirectDrawSurface4Impl_Initialize,
1823 IDirectDrawSurface4Impl_IsLost,
1824 IDirectDrawSurface4Impl_Lock,
1825 IDirectDrawSurface4Impl_ReleaseDC,
1826 IDirectDrawSurface4Impl_Restore,
1827 IDirectDrawSurface4Impl_SetClipper,
1828 IDirectDrawSurface4Impl_SetColorKey,
1829 IDirectDrawSurface4Impl_SetOverlayPosition,
1830 DGA_IDirectDrawSurface4Impl_SetPalette,
1831 DGA_IDirectDrawSurface4Impl_Unlock,
1832 IDirectDrawSurface4Impl_UpdateOverlay,
1833 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1834 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1835 IDirectDrawSurface4Impl_GetDDInterface,
1836 IDirectDrawSurface4Impl_PageLock,
1837 IDirectDrawSurface4Impl_PageUnlock,
1838 IDirectDrawSurface4Impl_SetSurfaceDesc,
1839 IDirectDrawSurface4Impl_SetPrivateData,
1840 IDirectDrawSurface4Impl_GetPrivateData,
1841 IDirectDrawSurface4Impl_FreePrivateData,
1842 IDirectDrawSurface4Impl_GetUniquenessValue,
1843 IDirectDrawSurface4Impl_ChangeUniquenessValue
1846 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
1848 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1849 IDirectDrawSurface4Impl_QueryInterface,
1850 IDirectDrawSurface4Impl_AddRef,
1851 Xlib_IDirectDrawSurface4Impl_Release,
1852 IDirectDrawSurface4Impl_AddAttachedSurface,
1853 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1854 IDirectDrawSurface4Impl_Blt,
1855 IDirectDrawSurface4Impl_BltBatch,
1856 IDirectDrawSurface4Impl_BltFast,
1857 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1858 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1859 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1860 Xlib_IDirectDrawSurface4Impl_Flip,
1861 IDirectDrawSurface4Impl_GetAttachedSurface,
1862 IDirectDrawSurface4Impl_GetBltStatus,
1863 IDirectDrawSurface4Impl_GetCaps,
1864 IDirectDrawSurface4Impl_GetClipper,
1865 IDirectDrawSurface4Impl_GetColorKey,
1866 IDirectDrawSurface4Impl_GetDC,
1867 IDirectDrawSurface4Impl_GetFlipStatus,
1868 IDirectDrawSurface4Impl_GetOverlayPosition,
1869 IDirectDrawSurface4Impl_GetPalette,
1870 IDirectDrawSurface4Impl_GetPixelFormat,
1871 IDirectDrawSurface4Impl_GetSurfaceDesc,
1872 IDirectDrawSurface4Impl_Initialize,
1873 IDirectDrawSurface4Impl_IsLost,
1874 IDirectDrawSurface4Impl_Lock,
1875 IDirectDrawSurface4Impl_ReleaseDC,
1876 IDirectDrawSurface4Impl_Restore,
1877 IDirectDrawSurface4Impl_SetClipper,
1878 IDirectDrawSurface4Impl_SetColorKey,
1879 IDirectDrawSurface4Impl_SetOverlayPosition,
1880 Xlib_IDirectDrawSurface4Impl_SetPalette,
1881 Xlib_IDirectDrawSurface4Impl_Unlock,
1882 IDirectDrawSurface4Impl_UpdateOverlay,
1883 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1884 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1885 IDirectDrawSurface4Impl_GetDDInterface,
1886 IDirectDrawSurface4Impl_PageLock,
1887 IDirectDrawSurface4Impl_PageUnlock,
1888 IDirectDrawSurface4Impl_SetSurfaceDesc,
1889 IDirectDrawSurface4Impl_SetPrivateData,
1890 IDirectDrawSurface4Impl_GetPrivateData,
1891 IDirectDrawSurface4Impl_FreePrivateData,
1892 IDirectDrawSurface4Impl_GetUniquenessValue,
1893 IDirectDrawSurface4Impl_ChangeUniquenessValue
1896 /******************************************************************************
1897 * DirectDrawCreateClipper (DDRAW.7)
1899 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1900 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1901 LPUNKNOWN pUnkOuter)
1903 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
1904 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
1906 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
1907 (*ilplpDDClipper)->lpvtbl = &ddclipvt;
1908 (*ilplpDDClipper)->ref = 1;
1910 return DD_OK;
1913 /******************************************************************************
1914 * IDirectDrawClipper
1916 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
1917 LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
1919 ICOM_THIS(IDirectDrawClipperImpl,iface);
1920 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
1921 return DD_OK;
1924 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
1925 ICOM_THIS(IDirectDrawClipperImpl,iface);
1926 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1928 This->ref--;
1929 if (This->ref)
1930 return This->ref;
1931 HeapFree(GetProcessHeap(),0,This);
1932 return 0;
1935 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
1936 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
1938 ICOM_THIS(IDirectDrawClipperImpl,iface);
1939 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
1940 if (hmm) *hmm=0;
1941 return DD_OK;
1944 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
1945 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
1947 ICOM_THIS(IDirectDrawClipperImpl,iface);
1948 FIXME(ddraw,"(%p,%p,%ld),stub!\n",This,lprgn,hmm);
1949 return DD_OK;
1952 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
1953 LPDIRECTDRAWCLIPPER iface,
1954 REFIID riid,
1955 LPVOID* ppvObj )
1957 ICOM_THIS(IDirectDrawClipperImpl,iface);
1958 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
1959 return OLE_E_ENUM_NOMORE;
1962 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
1964 ICOM_THIS(IDirectDrawClipperImpl,iface);
1965 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1966 return ++(This->ref);
1969 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
1970 LPDIRECTDRAWCLIPPER iface,
1971 HWND* HWndPtr )
1973 ICOM_THIS(IDirectDrawClipperImpl,iface);
1974 FIXME(ddraw,"(%p)->(%p),stub!\n",This,HWndPtr);
1975 return DD_OK;
1978 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
1979 LPDIRECTDRAWCLIPPER iface,
1980 LPDIRECTDRAW lpDD,
1981 DWORD dwFlags )
1983 ICOM_THIS(IDirectDrawClipperImpl,iface);
1984 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
1985 return DD_OK;
1988 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
1989 LPDIRECTDRAWCLIPPER iface,
1990 BOOL* lpbChanged )
1992 ICOM_THIS(IDirectDrawClipperImpl,iface);
1993 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpbChanged);
1994 return DD_OK;
1997 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
1999 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2000 IDirectDrawClipperImpl_QueryInterface,
2001 IDirectDrawClipperImpl_AddRef,
2002 IDirectDrawClipperImpl_Release,
2003 IDirectDrawClipperImpl_GetClipList,
2004 IDirectDrawClipperImpl_GetHWnd,
2005 IDirectDrawClipperImpl_Initialize,
2006 IDirectDrawClipperImpl_IsClipListChanged,
2007 IDirectDrawClipperImpl_SetClipList,
2008 IDirectDrawClipperImpl_SetHwnd
2012 /******************************************************************************
2013 * IDirectDrawPalette
2015 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2016 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2018 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2019 int i;
2021 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2022 This,x,start,count,palent);
2024 /* No palette created and not in depth-convertion mode -> BUG ! */
2025 if ((This->cm == None) &&
2026 (This->ddraw->d.palette_convert == NULL))
2028 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
2029 return DDERR_GENERIC;
2031 for (i=0;i<count;i++) {
2032 palent[i].peRed = This->palents[start+i].peRed;
2033 palent[i].peBlue = This->palents[start+i].peBlue;
2034 palent[i].peGreen = This->palents[start+i].peGreen;
2035 palent[i].peFlags = This->palents[start+i].peFlags;
2038 return DD_OK;
2041 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2042 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2044 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2045 XColor xc;
2046 int i;
2048 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2049 This,x,start,count,palent
2051 for (i=0;i<count;i++) {
2052 xc.red = palent[i].peRed<<8;
2053 xc.blue = palent[i].peBlue<<8;
2054 xc.green = palent[i].peGreen<<8;
2055 xc.flags = DoRed|DoBlue|DoGreen;
2056 xc.pixel = start+i;
2058 if (This->cm)
2059 TSXStoreColor(display,This->cm,&xc);
2061 This->palents[start+i].peRed = palent[i].peRed;
2062 This->palents[start+i].peBlue = palent[i].peBlue;
2063 This->palents[start+i].peGreen = palent[i].peGreen;
2064 This->palents[start+i].peFlags = palent[i].peFlags;
2067 /* Now, if we are in 'depth conversion mode', update the screen palette */
2068 if (This->ddraw->d.palette_convert != NULL)
2069 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2071 return DD_OK;
2074 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2075 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2077 #ifdef HAVE_LIBXXF86DGA
2078 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2079 XColor xc;
2080 Colormap cm;
2081 int i;
2083 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2084 This,x,start,count,palent
2086 if (!This->cm) /* should not happen */ {
2087 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
2088 return DDERR_GENERIC;
2090 /* FIXME: free colorcells instead of freeing whole map */
2091 cm = This->cm;
2092 This->cm = TSXCopyColormapAndFree(display,This->cm);
2093 TSXFreeColormap(display,cm);
2095 for (i=0;i<count;i++) {
2096 xc.red = palent[i].peRed<<8;
2097 xc.blue = palent[i].peBlue<<8;
2098 xc.green = palent[i].peGreen<<8;
2099 xc.flags = DoRed|DoBlue|DoGreen;
2100 xc.pixel = i+start;
2102 TSXStoreColor(display,This->cm,&xc);
2104 This->palents[start+i].peRed = palent[i].peRed;
2105 This->palents[start+i].peBlue = palent[i].peBlue;
2106 This->palents[start+i].peGreen = palent[i].peGreen;
2107 This->palents[start+i].peFlags = palent[i].peFlags;
2109 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2110 return DD_OK;
2111 #else /* defined(HAVE_LIBXXF86DGA) */
2112 return E_UNEXPECTED;
2113 #endif /* defined(HAVE_LIBXXF86DGA) */
2116 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2117 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2118 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2119 if (!--(This->ref)) {
2120 if (This->cm) {
2121 TSXFreeColormap(display,This->cm);
2122 This->cm = 0;
2124 HeapFree(GetProcessHeap(),0,This);
2125 return 0;
2127 return This->ref;
2130 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2131 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2133 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2134 return ++(This->ref);
2137 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2138 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2140 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2141 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2143 return DDERR_ALREADYINITIALIZED;
2146 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2147 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2149 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2150 FIXME( ddraw, "(%p)->(%p) stub.\n", This, lpdwCaps );
2151 return DD_OK;
2154 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2155 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2157 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2158 char xrefiid[50];
2160 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2161 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2163 return S_OK;
2166 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2168 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2169 IDirectDrawPaletteImpl_QueryInterface,
2170 IDirectDrawPaletteImpl_AddRef,
2171 IDirectDrawPaletteImpl_Release,
2172 IDirectDrawPaletteImpl_GetCaps,
2173 IDirectDrawPaletteImpl_GetEntries,
2174 IDirectDrawPaletteImpl_Initialize,
2175 DGA_IDirectDrawPaletteImpl_SetEntries
2178 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2180 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2181 IDirectDrawPaletteImpl_QueryInterface,
2182 IDirectDrawPaletteImpl_AddRef,
2183 IDirectDrawPaletteImpl_Release,
2184 IDirectDrawPaletteImpl_GetCaps,
2185 IDirectDrawPaletteImpl_GetEntries,
2186 IDirectDrawPaletteImpl_Initialize,
2187 Xlib_IDirectDrawPaletteImpl_SetEntries
2190 /*******************************************************************************
2191 * IDirect3D
2193 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2194 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2196 ICOM_THIS(IDirect3DImpl,iface);
2197 /* FIXME: Not sure if this is correct */
2198 char xrefiid[50];
2200 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2201 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2202 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2203 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2204 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2205 *obj = This->ddraw;
2206 IDirect3D_AddRef(iface);
2208 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2210 return S_OK;
2212 if ((!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) ||
2213 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2214 *obj = This;
2215 IDirect3D_AddRef(iface);
2217 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2219 return S_OK;
2221 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
2222 IDirect3D2Impl* d3d;
2224 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2225 d3d->ref = 1;
2226 d3d->ddraw = This->ddraw;
2227 IDirect3D_AddRef(iface);
2228 d3d->lpvtbl = &d3d2vt;
2229 *obj = d3d;
2231 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2233 return S_OK;
2235 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2236 return OLE_E_ENUM_NOMORE;
2239 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2240 ICOM_THIS(IDirect3DImpl,iface);
2241 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2243 return ++(This->ref);
2246 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2248 ICOM_THIS(IDirect3DImpl,iface);
2249 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2251 if (!--(This->ref)) {
2252 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2253 HeapFree(GetProcessHeap(),0,This);
2254 return 0;
2256 return This->ref;
2259 static HRESULT WINAPI IDirect3DImpl_Initialize(
2260 LPDIRECT3D iface, REFIID refiid )
2262 ICOM_THIS(IDirect3DImpl,iface);
2263 /* FIXME: Not sure if this is correct */
2264 char xrefiid[50];
2266 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2267 FIXME(ddraw,"(%p)->(%s):stub.\n",This,xrefiid);
2269 return DDERR_ALREADYINITIALIZED;
2272 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2273 LPD3DENUMDEVICESCALLBACK cb,
2274 LPVOID context) {
2275 ICOM_THIS(IDirect3DImpl,iface);
2276 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2278 /* Call functions defined in d3ddevices.c */
2279 if (!d3d_OpenGL_dx3(cb, context))
2280 return DD_OK;
2282 return DD_OK;
2285 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2286 LPDIRECT3DLIGHT *lplight,
2287 IUnknown *lpunk)
2289 ICOM_THIS(IDirect3DImpl,iface);
2290 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2292 /* Call the creation function that is located in d3dlight.c */
2293 *lplight = d3dlight_create_dx3(This);
2295 return DD_OK;
2298 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2299 LPDIRECT3DMATERIAL *lpmaterial,
2300 IUnknown *lpunk)
2302 ICOM_THIS(IDirect3DImpl,iface);
2303 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2305 /* Call the creation function that is located in d3dviewport.c */
2306 *lpmaterial = d3dmaterial_create(This);
2308 return DD_OK;
2311 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2312 LPDIRECT3DVIEWPORT *lpviewport,
2313 IUnknown *lpunk)
2315 ICOM_THIS(IDirect3DImpl,iface);
2316 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2318 /* Call the creation function that is located in d3dviewport.c */
2319 *lpviewport = d3dviewport_create(This);
2321 return DD_OK;
2324 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2325 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2326 LPD3DFINDDEVICERESULT lpfinddevrst)
2328 ICOM_THIS(IDirect3DImpl,iface);
2329 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2331 return DD_OK;
2334 static ICOM_VTABLE(IDirect3D) d3dvt =
2336 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2337 IDirect3DImpl_QueryInterface,
2338 IDirect3DImpl_AddRef,
2339 IDirect3DImpl_Release,
2340 IDirect3DImpl_Initialize,
2341 IDirect3DImpl_EnumDevices,
2342 IDirect3DImpl_CreateLight,
2343 IDirect3DImpl_CreateMaterial,
2344 IDirect3DImpl_CreateViewport,
2345 IDirect3DImpl_FindDevice
2348 /*******************************************************************************
2349 * IDirect3D2
2351 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2352 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2353 ICOM_THIS(IDirect3D2Impl,iface);
2355 /* FIXME: Not sure if this is correct */
2356 char xrefiid[50];
2358 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2359 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2360 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2361 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2362 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2363 *obj = This->ddraw;
2364 IDirect3D2_AddRef(iface);
2366 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2368 return S_OK;
2370 if ((!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) ||
2371 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2372 *obj = This;
2373 IDirect3D2_AddRef(iface);
2375 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2377 return S_OK;
2379 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2380 IDirect3DImpl* d3d;
2382 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2383 d3d->ref = 1;
2384 d3d->ddraw = This->ddraw;
2385 IDirect3D2_AddRef(iface);
2386 d3d->lpvtbl = &d3dvt;
2387 *obj = d3d;
2389 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2391 return S_OK;
2393 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2394 return OLE_E_ENUM_NOMORE;
2397 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2398 ICOM_THIS(IDirect3D2Impl,iface);
2399 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2401 return ++(This->ref);
2404 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2405 ICOM_THIS(IDirect3D2Impl,iface);
2406 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2408 if (!--(This->ref)) {
2409 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2410 HeapFree(GetProcessHeap(),0,This);
2411 return 0;
2413 return This->ref;
2416 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2417 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2419 ICOM_THIS(IDirect3D2Impl,iface);
2420 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2422 /* Call functions defined in d3ddevices.c */
2423 if (!d3d_OpenGL(cb, context))
2424 return DD_OK;
2426 return DD_OK;
2429 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2430 LPDIRECT3DLIGHT *lplight,
2431 IUnknown *lpunk)
2433 ICOM_THIS(IDirect3D2Impl,iface);
2434 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2436 /* Call the creation function that is located in d3dlight.c */
2437 *lplight = d3dlight_create(This);
2439 return DD_OK;
2442 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2443 LPDIRECT3DMATERIAL2 *lpmaterial,
2444 IUnknown *lpunk)
2446 ICOM_THIS(IDirect3D2Impl,iface);
2447 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2449 /* Call the creation function that is located in d3dviewport.c */
2450 *lpmaterial = d3dmaterial2_create(This);
2452 return DD_OK;
2455 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2456 LPDIRECT3DVIEWPORT2 *lpviewport,
2457 IUnknown *lpunk)
2459 ICOM_THIS(IDirect3D2Impl,iface);
2460 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2462 /* Call the creation function that is located in d3dviewport.c */
2463 *lpviewport = d3dviewport2_create(This);
2465 return DD_OK;
2468 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2469 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2470 LPD3DFINDDEVICERESULT lpfinddevrst)
2472 ICOM_THIS(IDirect3D2Impl,iface);
2473 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2475 return DD_OK;
2478 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2479 REFCLSID rguid,
2480 LPDIRECTDRAWSURFACE surface,
2481 LPDIRECT3DDEVICE2 *device)
2483 ICOM_THIS(IDirect3D2Impl,iface);
2484 char xbuf[50];
2486 WINE_StringFromCLSID(rguid,xbuf);
2487 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2489 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2490 IDirect3D2_AddRef(iface);
2491 return DD_OK;
2494 return DDERR_INVALIDPARAMS;
2497 static ICOM_VTABLE(IDirect3D2) d3d2vt =
2499 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2500 IDirect3D2Impl_QueryInterface,
2501 IDirect3D2Impl_AddRef,
2502 IDirect3D2Impl_Release,
2503 IDirect3D2Impl_EnumDevices,
2504 IDirect3D2Impl_CreateLight,
2505 IDirect3D2Impl_CreateMaterial,
2506 IDirect3D2Impl_CreateViewport,
2507 IDirect3D2Impl_FindDevice,
2508 IDirect3D2Impl_CreateDevice
2511 /*******************************************************************************
2512 * IDirectDraw
2515 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2516 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2518 static INT ddrawXlibThisOffset = 0;
2520 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2521 LPDDSURFACEDESC lpddsd,
2522 IDirectDrawSurfaceImpl* lpdsf)
2524 int bpp;
2526 /* The surface was already allocated when entering in this function */
2527 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2529 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2530 /* This is a Z Buffer */
2531 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2532 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2533 } else {
2534 /* This is a standard image */
2535 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2536 /* No pixel format => use DirectDraw's format */
2537 lpddsd->ddpfPixelFormat = This->d.directdraw_pixelformat;
2538 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2539 } else {
2540 /* To check what the program wants */
2541 if (TRACE_ON(ddraw)) {
2542 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2546 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2547 bpp = 1;
2548 } else {
2549 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2553 /* Copy the surface description */
2554 lpdsf->s.surface_desc = *lpddsd;
2556 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2557 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2558 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2560 return DD_OK;
2563 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2564 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2566 #ifdef HAVE_LIBXXF86DGA
2567 ICOM_THIS(IDirectDraw2Impl,iface);
2568 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2569 int i;
2571 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2572 if (TRACE_ON(ddraw)) {
2573 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2574 _dump_DDSD(lpddsd->dwFlags);
2575 DUMP(" caps ");
2576 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2579 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2580 IDirectDraw2_AddRef(iface);
2582 (*ilpdsf)->ref = 1;
2583 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2584 (*ilpdsf)->s.ddraw = This;
2585 (*ilpdsf)->s.palette = NULL;
2586 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2588 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2589 lpddsd->dwWidth = This->d.width;
2590 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2591 lpddsd->dwHeight = This->d.height;
2593 /* Check if this a 'primary surface' or not */
2594 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2595 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2597 /* This is THE primary surface => there is DGA-specific code */
2598 /* First, store the surface description */
2599 (*ilpdsf)->s.surface_desc = *lpddsd;
2601 /* Find a viewport */
2602 for (i=0;i<32;i++)
2603 if (!(This->e.dga.vpmask & (1<<i)))
2604 break;
2605 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2606 /* if i == 32 or maximum ... return error */
2607 This->e.dga.vpmask|=(1<<i);
2608 (*ilpdsf)->s.surface_desc.y.lpSurface =
2609 This->e.dga.fb_addr+((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2610 (*ilpdsf)->t.dga.fb_height = i*This->e.dga.fb_height;
2611 (*ilpdsf)->s.surface_desc.lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
2612 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch;
2614 /* Add flags if there were not present */
2615 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2616 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2617 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2618 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2619 /* We put our surface always in video memory */
2620 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2621 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2622 (*ilpdsf)->s.backbuffer = NULL;
2624 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2625 IDirectDrawSurface4Impl* back;
2627 if (lpddsd->dwBackBufferCount>1)
2628 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2630 (*ilpdsf)->s.backbuffer = back =
2631 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2632 IDirectDraw2_AddRef(iface);
2633 back->ref = 1;
2634 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2635 for (i=0;i<32;i++)
2636 if (!(This->e.dga.vpmask & (1<<i)))
2637 break;
2638 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2639 /* if i == 32 or maximum ... return error */
2640 This->e.dga.vpmask|=(1<<i);
2641 back->t.dga.fb_height = i*This->e.dga.fb_height;
2643 /* Copy the surface description from the front buffer */
2644 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2645 /* Change the parameters that are not the same */
2646 back->s.surface_desc.y.lpSurface = This->e.dga.fb_addr+
2647 ((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2648 back->s.ddraw = This;
2649 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2650 * one! */
2652 /* Add relevant info to front and back buffers */
2653 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2654 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2655 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2656 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2657 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2659 } else {
2660 /* There is no DGA-specific code here...
2661 Go to the common surface creation function */
2662 return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2665 return DD_OK;
2666 #else /* defined(HAVE_LIBXXF86DGA) */
2667 return E_UNEXPECTED;
2668 #endif /* defined(HAVE_LIBXXF86DGA) */
2671 #ifdef HAVE_LIBXXSHM
2672 /* Error handlers for Image creation */
2673 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2674 XShmErrorFlag = 1;
2675 return 0;
2678 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2679 XImage *img;
2680 int (*WineXHandler)(Display *, XErrorEvent *);
2682 img = TSXShmCreateImage(display,
2683 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2684 This->d.pixmap_depth,
2685 ZPixmap,
2686 NULL,
2687 &(lpdsf->t.xlib.shminfo),
2688 lpdsf->s.surface_desc.dwWidth,
2689 lpdsf->s.surface_desc.dwHeight);
2691 if (img == NULL) {
2692 MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2693 This->e.xlib.xshm_active = 0;
2694 return NULL;
2697 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2698 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2699 MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2700 This->e.xlib.xshm_active = 0;
2701 TSXDestroyImage(img);
2702 return NULL;
2705 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2707 if (img->data == (char *) -1) {
2708 MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2709 This->e.xlib.xshm_active = 0;
2710 TSXDestroyImage(img);
2711 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2712 return NULL;
2714 lpdsf->t.xlib.shminfo.readOnly = False;
2716 /* This is where things start to get trickier....
2717 First, we flush the current X connections to be sure to catch all non-XShm related
2718 errors */
2719 TSXSync(display, False);
2720 /* Then we enter in the non-thread safe part of the tests */
2721 EnterCriticalSection( &X11DRV_CritSection );
2723 /* Reset the error flag, sets our new error handler and try to attach the surface */
2724 XShmErrorFlag = 0;
2725 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2726 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2727 XSync(display, False);
2729 /* Check the error flag */
2730 if (XShmErrorFlag) {
2731 /* An error occured */
2732 XFlush(display);
2733 XShmErrorFlag = 0;
2734 XDestroyImage(img);
2735 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2736 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2737 XSetErrorHandler(WineXHandler);
2739 MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
2740 This->e.xlib.xshm_active = 0;
2742 /* Leave the critical section */
2743 LeaveCriticalSection( &X11DRV_CritSection );
2745 return NULL;
2748 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2749 but it may be a bit overkill.... */
2750 XSetErrorHandler(WineXHandler);
2751 LeaveCriticalSection( &X11DRV_CritSection );
2753 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2755 if (This->d.pixel_convert != NULL) {
2756 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2757 lpdsf->s.surface_desc.dwWidth *
2758 lpdsf->s.surface_desc.dwHeight *
2759 (This->d.directdraw_pixelformat.x.dwRGBBitCount));
2760 } else {
2761 lpdsf->s.surface_desc.y.lpSurface = img->data;
2764 return img;
2766 #endif /* HAVE_LIBXXSHM */
2768 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2769 XImage *img = NULL;
2770 void *img_data;
2772 #ifdef HAVE_LIBXXSHM
2773 if (This->e.xlib.xshm_active) {
2774 img = create_xshmimage(This, lpdsf);
2777 if (img == NULL) {
2778 #endif
2779 /* Allocate surface memory */
2780 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2781 lpdsf->s.surface_desc.dwWidth *
2782 lpdsf->s.surface_desc.dwHeight *
2783 (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8));
2785 if (This->d.pixel_convert != NULL) {
2786 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2787 lpdsf->s.surface_desc.dwWidth *
2788 lpdsf->s.surface_desc.dwHeight *
2789 (This->d.screen_pixelformat.x.dwRGBBitCount / 8));
2790 } else {
2791 img_data = lpdsf->s.surface_desc.y.lpSurface;
2794 /* In this case, create an XImage */
2795 img =
2796 TSXCreateImage(display,
2797 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2798 This->d.pixmap_depth,
2799 ZPixmap,
2801 img_data,
2802 lpdsf->s.surface_desc.dwWidth,
2803 lpdsf->s.surface_desc.dwHeight,
2805 lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
2808 #ifdef HAVE_LIBXXSHM
2810 #endif
2811 if (This->d.pixel_convert != NULL) {
2812 lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
2813 } else {
2814 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2817 return img;
2820 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
2821 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2823 ICOM_THIS(IDirectDraw2Impl,iface);
2824 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2825 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2826 This,lpddsd,ilpdsf,lpunk);
2828 if (TRACE_ON(ddraw)) {
2829 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2830 _dump_DDSD(lpddsd->dwFlags);
2831 DUMP(" caps ");
2832 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2835 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2837 IDirectDraw2_AddRef(iface);
2838 (*ilpdsf)->s.ddraw = This;
2839 (*ilpdsf)->ref = 1;
2840 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
2841 (*ilpdsf)->s.palette = NULL;
2842 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2844 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2845 lpddsd->dwWidth = This->d.width;
2846 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2847 lpddsd->dwHeight = This->d.height;
2849 /* Check if this a 'primary surface' or not */
2850 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2851 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2852 XImage *img;
2854 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *ilpdsf);
2856 /* First, store the surface description */
2857 (*ilpdsf)->s.surface_desc = *lpddsd;
2859 /* Create the XImage */
2860 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
2861 if (img == NULL)
2862 return DDERR_OUTOFMEMORY;
2863 (*ilpdsf)->t.xlib.image = img;
2865 /* Add flags if there were not present */
2866 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2867 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2868 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2869 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2870 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2871 (*ilpdsf)->s.backbuffer = NULL;
2873 /* Check for backbuffers */
2874 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2875 IDirectDrawSurface4Impl* back;
2876 XImage *img;
2878 if (lpddsd->dwBackBufferCount>1)
2879 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2881 (*ilpdsf)->s.backbuffer = back =
2882 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2884 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2886 IDirectDraw2_AddRef(iface);
2887 back->s.ddraw = This;
2889 back->ref = 1;
2890 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
2891 /* Copy the surface description from the front buffer */
2892 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2894 /* Create the XImage */
2895 img = create_ximage(This, back);
2896 if (img == NULL)
2897 return DDERR_OUTOFMEMORY;
2898 back->t.xlib.image = img;
2900 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2901 * one! */
2903 /* Add relevant info to front and back buffers */
2904 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2905 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2906 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2907 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2908 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2910 } else {
2911 /* There is no Xlib-specific code here...
2912 Go to the common surface creation function */
2913 return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2916 return DD_OK;
2919 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
2920 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2922 ICOM_THIS(IDirectDraw2Impl,iface);
2923 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",This,src,dst);
2924 *dst = src; /* FIXME */
2925 return DD_OK;
2929 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2930 * even when the approbiate bitmasks are not specified.
2932 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
2933 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
2935 ICOM_THIS(IDirectDraw2Impl,iface);
2936 int i;
2937 const struct {
2938 int mask;
2939 char *name;
2940 } flagmap[] = {
2941 FE(DDSCL_FULLSCREEN)
2942 FE(DDSCL_ALLOWREBOOT)
2943 FE(DDSCL_NOWINDOWCHANGES)
2944 FE(DDSCL_NORMAL)
2945 FE(DDSCL_ALLOWMODEX)
2946 FE(DDSCL_EXCLUSIVE)
2947 FE(DDSCL_SETFOCUSWINDOW)
2948 FE(DDSCL_SETDEVICEWINDOW)
2949 FE(DDSCL_CREATEDEVICEWINDOW)
2952 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
2953 if(TRACE_ON(ddraw)){
2954 dbg_decl_str(ddraw, 512);
2955 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2956 if (flagmap[i].mask & cooplevel)
2957 dsprintf(ddraw, "%s ", flagmap[i].name);
2958 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2960 This->d.mainWindow = hwnd;
2962 /* This will be overwritten in the case of Full Screen mode.
2963 Windowed games could work with that :-) */
2964 if (hwnd)
2966 WND *tmpWnd = WIN_FindWndPtr(hwnd);
2967 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
2968 WIN_ReleaseWndPtr(tmpWnd);
2970 if( !This->d.drawable ) {
2971 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
2972 WIN_ReleaseDesktop();
2974 TRACE(ddraw, "Setting drawable to %ld\n", This->d.drawable);
2977 return DD_OK;
2980 /* Small helper to either use the cooperative window or create a new
2981 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2983 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
2984 RECT rect;
2986 /* Do not destroy the application supplied cooperative window */
2987 if (This->d.window && This->d.window != This->d.mainWindow) {
2988 DestroyWindow(This->d.window);
2989 This->d.window = 0;
2991 /* Sanity check cooperative window before assigning it to drawing. */
2992 if ( IsWindow(This->d.mainWindow) &&
2993 IsWindowVisible(This->d.mainWindow)
2995 GetWindowRect(This->d.mainWindow,&rect);
2996 if (((rect.right-rect.left) >= This->d.width) &&
2997 ((rect.bottom-rect.top) >= This->d.height)
2999 This->d.window = This->d.mainWindow;
3001 /* ... failed, create new one. */
3002 if (!This->d.window) {
3003 This->d.window = CreateWindowExA(
3005 "WINE_DirectDraw",
3006 "WINE_DirectDraw",
3007 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3008 0,0,
3009 This->d.width,
3010 This->d.height,
3014 NULL
3016 /*Store THIS with the window. We'll use it in the window procedure*/
3017 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3018 ShowWindow(This->d.window,TRUE);
3019 UpdateWindow(This->d.window);
3021 SetFocus(This->d.window);
3024 static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
3025 XVisualInfo *vi;
3026 XPixmapFormatValues *pf;
3027 XVisualInfo vt;
3028 int nvisuals, npixmap, i;
3029 int match = 0;
3031 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3032 pf = XListPixmapFormats(display, &npixmap);
3034 for (i = 0; i < npixmap; i++) {
3035 if (pf[i].bits_per_pixel == depth) {
3036 int j;
3038 for (j = 0; j < nvisuals; j++) {
3039 if (vi[j].depth == pf[i].depth) {
3040 pixelformat->dwSize = sizeof(*pixelformat);
3041 if (depth == 8) {
3042 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3043 pixelformat->y.dwRBitMask = 0;
3044 pixelformat->z.dwGBitMask = 0;
3045 pixelformat->xx.dwBBitMask = 0;
3046 } else {
3047 pixelformat->dwFlags = DDPF_RGB;
3048 pixelformat->y.dwRBitMask = vi[j].red_mask;
3049 pixelformat->z.dwGBitMask = vi[j].green_mask;
3050 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3052 pixelformat->dwFourCC = 0;
3053 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3054 pixelformat->xy.dwRGBAlphaBitMask= 0;
3056 *screen_pixelformat = *pixelformat;
3058 if (pix_depth != NULL)
3059 *pix_depth = vi[j].depth;
3061 match = 1;
3063 break;
3067 if (j == nvisuals)
3068 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3072 if ((match == 0) && (depth == 8)) {
3073 pixelformat->dwSize = sizeof(*pixelformat);
3074 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3075 pixelformat->dwFourCC = 0;
3076 pixelformat->x.dwRGBBitCount = 8;
3077 pixelformat->y.dwRBitMask = 0;
3078 pixelformat->z.dwGBitMask = 0;
3079 pixelformat->xx.dwBBitMask = 0;
3080 pixelformat->xy.dwRGBAlphaBitMask= 0;
3082 /* In that case, find a visual to emulate the 8 bpp format */
3083 for (i = 0; i < npixmap; i++) {
3084 if (pf[i].bits_per_pixel >= depth) {
3085 int j;
3087 for (j = 0; j < nvisuals; j++) {
3088 if (vi[j].depth == pf[i].depth) {
3089 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3090 screen_pixelformat->dwFlags = DDPF_RGB;
3091 screen_pixelformat->dwFourCC = 0;
3092 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3093 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
3094 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
3095 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3096 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
3098 if (pix_depth != NULL)
3099 *pix_depth = vi[j].depth;
3101 match = 2;
3103 break;
3107 if (j == nvisuals)
3108 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3113 TSXFree(vi);
3114 TSXFree(pf);
3116 return match;
3119 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3120 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3122 #ifdef HAVE_LIBXXF86DGA
3123 ICOM_THIS(IDirectDrawImpl,iface);
3124 int i,mode_count;
3126 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3128 /* We hope getting the asked for depth */
3129 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != 1) {
3130 /* I.e. no visual found or emulated */
3131 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3132 return DDERR_UNSUPPORTEDMODE;
3135 if (This->d.width < width) {
3136 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3137 return DDERR_UNSUPPORTEDMODE;
3139 This->d.width = width;
3140 This->d.height = height;
3142 /* adjust fb_height, so we don't overlap */
3143 if (This->e.dga.fb_height < height)
3144 This->e.dga.fb_height = height;
3145 _common_IDirectDrawImpl_SetDisplayMode(This);
3147 #ifdef HAVE_LIBXXF86VM
3149 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3150 XF86VidModeModeLine mod_tmp;
3151 /* int dotclock_tmp; */
3153 /* save original video mode and set fullscreen if available*/
3154 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3155 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3156 orig_mode->hdisplay = mod_tmp.hdisplay;
3157 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3158 orig_mode->hsyncend = mod_tmp.hsyncend;
3159 orig_mode->htotal = mod_tmp.htotal;
3160 orig_mode->vdisplay = mod_tmp.vdisplay;
3161 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3162 orig_mode->vsyncend = mod_tmp.vsyncend;
3163 orig_mode->vtotal = mod_tmp.vtotal;
3164 orig_mode->flags = mod_tmp.flags;
3165 orig_mode->private = mod_tmp.private;
3167 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3168 for (i=0;i<mode_count;i++)
3170 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3172 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3173 *vidmode = *(all_modes[i]);
3174 break;
3175 } else
3176 TSXFree(all_modes[i]->private);
3178 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3179 TSXFree(all_modes);
3181 if (!vidmode)
3182 WARN(ddraw, "Fullscreen mode not available!\n");
3184 if (vidmode)
3186 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3187 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3188 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3189 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3190 #endif
3193 #endif
3195 /* FIXME: this function OVERWRITES several signal handlers.
3196 * can we save them? and restore them later? In a way that
3197 * it works for the library too?
3199 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3200 #ifdef DIABLO_HACK
3201 TSXF86DGASetViewPort(display,DefaultScreen(display),0,This->e.dga.fb_height);
3202 #else
3203 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3204 #endif
3206 #ifdef RESTORE_SIGNALS
3207 SIGNAL_InitHandlers();
3208 #endif
3209 return DD_OK;
3210 #else /* defined(HAVE_LIBXXF86DGA) */
3211 return E_UNEXPECTED;
3212 #endif /* defined(HAVE_LIBXXF86DGA) */
3215 /* *************************************
3216 16 / 15 bpp to palettized 8 bpp
3217 ************************************* */
3218 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3219 unsigned char *c_src = (unsigned char *) src;
3220 unsigned short *c_dst = (unsigned short *) dst;
3221 int x, y;
3223 if (palette != NULL) {
3224 unsigned short *pal = (unsigned short *) palette->screen_palents;
3226 for (y = 0; y < height; y++) {
3227 for (x = 0; x < width; x++) {
3228 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3231 } else {
3232 WARN(ddraw, "No palette set...\n");
3233 memset(dst, 0, width * height * 2);
3236 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3237 int i;
3238 unsigned short *pal = (unsigned short *) screen_palette;
3240 for (i = 0; i < count; i++)
3241 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3242 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3243 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3245 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3246 int i;
3247 unsigned short *pal = (unsigned short *) screen_palette;
3249 for (i = 0; i < count; i++)
3250 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3251 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3252 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3255 /* *************************************
3256 24 / 32 bpp to palettized 8 bpp
3257 ************************************* */
3258 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3259 unsigned char *c_src = (unsigned char *) src;
3260 unsigned int *c_dst = (unsigned int *) dst;
3261 int x, y;
3263 if (palette != NULL) {
3264 unsigned int *pal = (unsigned int *) palette->screen_palents;
3266 for (y = 0; y < height; y++) {
3267 for (x = 0; x < width; x++) {
3268 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3271 } else {
3272 WARN(ddraw, "No palette set...\n");
3273 memset(dst, 0, width * height * 4);
3276 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3277 int i;
3278 unsigned int *pal = (unsigned int *) screen_palette;
3280 for (i = 0; i < count; i++)
3281 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3282 (((unsigned int) palent[i].peGreen) << 8) |
3283 ((unsigned int) palent[i].peBlue));
3286 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3287 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3289 ICOM_THIS(IDirectDrawImpl,iface);
3290 char buf[200];
3291 WND *tmpWnd;
3293 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3294 This, width, height, depth);
3296 switch (_common_depth_to_pixelformat(depth,
3297 &(This->d.directdraw_pixelformat),
3298 &(This->d.screen_pixelformat),
3299 &(This->d.pixmap_depth))) {
3300 case 0:
3301 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3302 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3303 return DDERR_UNSUPPORTEDMODE;
3305 case 1:
3306 /* No convertion */
3307 This->d.pixel_convert = NULL;
3308 This->d.palette_convert = NULL;
3309 break;
3311 case 2: {
3312 int found = 0;
3314 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3316 /* Set the depth convertion routines */
3317 switch (This->d.screen_pixelformat.x.dwRGBBitCount) {
3318 case 16:
3319 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
3320 (This->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
3321 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3322 /* 16 bpp */
3323 found = 1;
3325 This->d.pixel_convert = pixel_convert_16_to_8;
3326 This->d.palette_convert = palette_convert_16_to_8;
3327 } else if ((This->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
3328 (This->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
3329 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3330 /* 15 bpp */
3331 found = 1;
3333 This->d.pixel_convert = pixel_convert_16_to_8;
3334 This->d.palette_convert = palette_convert_15_to_8;
3336 break;
3338 case 24:
3339 /* Not handled yet :/ */
3340 found = 0;
3341 break;
3343 case 32:
3344 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) &&
3345 (This->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) &&
3346 (This->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
3347 /* 24 bpp */
3348 found = 1;
3350 This->d.pixel_convert = pixel_convert_32_to_8;
3351 This->d.palette_convert = palette_convert_24_to_8;
3353 break;
3356 if (!found) {
3357 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3358 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3359 return DDERR_UNSUPPORTEDMODE;
3361 } break;
3364 This->d.width = width;
3365 This->d.height = height;
3367 _common_IDirectDrawImpl_SetDisplayMode(This);
3369 tmpWnd = WIN_FindWndPtr(This->d.window);
3370 This->d.paintable = 1;
3371 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3372 WIN_ReleaseWndPtr(tmpWnd);
3374 /* We don't have a context for this window. Host off the desktop */
3375 if( !This->d.drawable )
3377 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3378 WIN_ReleaseDesktop();
3380 TRACE(ddraw, "Setting drawable to %ld\n", This->d.drawable);
3382 return DD_OK;
3385 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3386 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3388 #ifdef HAVE_LIBXXF86DGA
3389 ICOM_THIS(IDirectDraw2Impl,iface);
3390 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3391 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3392 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3393 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3394 if (caps2) {
3395 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3396 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3397 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3399 return DD_OK;
3400 #else /* defined(HAVE_LIBXXF86DGA) */
3401 return E_UNEXPECTED;
3402 #endif /* defined(HAVE_LIBXXF86DGA) */
3405 static void fill_caps(LPDDCAPS caps) {
3406 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3407 Need to be fixed, though.. */
3408 if (caps == NULL)
3409 return;
3411 caps->dwSize = sizeof(*caps);
3412 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3413 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
3414 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3415 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3416 caps->dwFXCaps = 0;
3417 caps->dwFXAlphaCaps = 0;
3418 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3419 caps->dwSVCaps = 0;
3420 caps->dwZBufferBitDepths = DDBD_16;
3421 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3422 to put textures in video memory.
3423 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3424 for example) ? */
3425 caps->dwVidMemTotal = 8192 * 1024;
3426 caps->dwVidMemFree = 8192 * 1024;
3427 /* These are all the supported capabilities of the surfaces */
3428 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3429 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3430 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3431 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3432 #ifdef HAVE_MESAGL
3433 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3434 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3435 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3436 #endif
3439 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3440 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3442 ICOM_THIS(IDirectDraw2Impl,iface);
3443 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3445 /* Put the same caps for the two capabilities */
3446 fill_caps(caps1);
3447 fill_caps(caps2);
3449 return DD_OK;
3452 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3453 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3455 ICOM_THIS(IDirectDraw2Impl,iface);
3456 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3457 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3458 This,x,ilpddclip,lpunk
3460 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3461 (*ilpddclip)->ref = 1;
3462 (*ilpddclip)->lpvtbl = &ddclipvt;
3463 return DD_OK;
3466 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3467 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3469 int size = 0;
3471 if (TRACE_ON(ddraw))
3472 _dump_paletteformat(dwFlags);
3474 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3475 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3476 (*lpddpal)->ref = 1;
3477 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3478 (*lpddpal)->installed = 0;
3480 if (dwFlags & DDPCAPS_1BIT)
3481 size = 2;
3482 else if (dwFlags & DDPCAPS_2BIT)
3483 size = 4;
3484 else if (dwFlags & DDPCAPS_4BIT)
3485 size = 16;
3486 else if (dwFlags & DDPCAPS_8BIT)
3487 size = 256;
3488 else
3489 ERR(ddraw, "unhandled palette format\n");
3490 *psize = size;
3492 if (palent)
3494 /* Now, if we are in 'depth conversion mode', create the screen palette */
3495 if (This->d.palette_convert != NULL)
3496 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3498 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3499 } else if (This->d.palette_convert != NULL) {
3500 /* In that case, put all 0xFF */
3501 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3504 return DD_OK;
3507 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3508 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3510 ICOM_THIS(IDirectDraw2Impl,iface);
3511 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3512 HRESULT res;
3513 int xsize = 0,i;
3515 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3516 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3517 if (res != 0) return res;
3518 (*ilpddpal)->lpvtbl = &dga_ddpalvt;
3519 if (This->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3520 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3521 } else {
3522 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3523 (*ilpddpal)->cm = 0;
3525 if (((*ilpddpal)->cm)&&xsize) {
3526 for (i=0;i<xsize;i++) {
3527 XColor xc;
3529 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3530 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3531 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3532 xc.flags = DoRed|DoBlue|DoGreen;
3533 xc.pixel = i;
3534 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3537 return DD_OK;
3540 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3541 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3543 ICOM_THIS(IDirectDraw2Impl,iface);
3544 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3545 int xsize;
3546 HRESULT res;
3548 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3549 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3550 if (res != 0) return res;
3551 (*ilpddpal)->lpvtbl = &xlib_ddpalvt;
3552 return DD_OK;
3555 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3556 #ifdef HAVE_LIBXXF86DGA
3557 ICOM_THIS(IDirectDraw2Impl,iface);
3558 TRACE(ddraw, "(%p)->()\n",This);
3559 Sleep(1000);
3560 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3561 #ifdef RESTORE_SIGNALS
3562 SIGNAL_InitHandlers();
3563 #endif
3564 return DD_OK;
3565 #else /* defined(HAVE_LIBXXF86DGA) */
3566 return E_UNEXPECTED;
3567 #endif
3570 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3571 ICOM_THIS(IDirectDraw2Impl,iface);
3572 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", This);
3573 Sleep(1000);
3574 return DD_OK;
3577 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3578 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3580 ICOM_THIS(IDirectDraw2Impl,iface);
3581 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3582 return DD_OK;
3585 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3586 ICOM_THIS(IDirectDraw2Impl,iface);
3587 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
3589 return ++(This->ref);
3592 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3593 ICOM_THIS(IDirectDraw2Impl,iface);
3594 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3596 #ifdef HAVE_LIBXXF86DGA
3597 if (!--(This->ref)) {
3598 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3599 if (This->d.window && (This->d.mainWindow != This->d.window))
3600 DestroyWindow(This->d.window);
3601 #ifdef HAVE_LIBXXF86VM
3602 if (orig_mode) {
3603 TSXF86VidModeSwitchToMode(
3604 display,
3605 DefaultScreen(display),
3606 orig_mode);
3607 if (orig_mode->privsize)
3608 TSXFree(orig_mode->private);
3609 free(orig_mode);
3610 orig_mode = NULL;
3612 #endif
3614 #ifdef RESTORE_SIGNALS
3615 SIGNAL_InitHandlers();
3616 #endif
3617 HeapFree(GetProcessHeap(),0,This);
3618 return 0;
3620 #endif /* defined(HAVE_LIBXXF86DGA) */
3621 return This->ref;
3624 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3625 ICOM_THIS(IDirectDraw2Impl,iface);
3626 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3628 if (!--(This->ref)) {
3629 if (This->d.window && (This->d.mainWindow != This->d.window))
3630 DestroyWindow(This->d.window);
3631 HeapFree(GetProcessHeap(),0,This);
3632 return 0;
3634 /* FIXME: destroy window ... */
3635 return This->ref;
3638 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
3639 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3641 ICOM_THIS(IDirectDraw2Impl,iface);
3642 char xrefiid[50];
3644 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3645 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3646 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3647 *obj = This;
3648 IDirectDraw2_AddRef(iface);
3650 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3652 return S_OK;
3654 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3655 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
3656 IDirectDraw2_AddRef(iface);
3657 *obj = This;
3659 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3661 return S_OK;
3663 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3664 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
3665 IDirectDraw2_AddRef(iface);
3666 *obj = This;
3668 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3670 return S_OK;
3672 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3673 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
3674 IDirectDraw2_AddRef(iface);
3675 *obj = This;
3677 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3679 return S_OK;
3681 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3682 IDirect3DImpl* d3d;
3684 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3685 d3d->ref = 1;
3686 d3d->ddraw = (IDirectDrawImpl*)This;
3687 IDirectDraw2_AddRef(iface);
3688 d3d->lpvtbl = &d3dvt;
3689 *obj = d3d;
3691 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3693 return S_OK;
3695 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3696 IDirect3D2Impl* d3d;
3698 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3699 d3d->ref = 1;
3700 d3d->ddraw = (IDirectDrawImpl*)This;
3701 IDirectDraw2_AddRef(iface);
3702 d3d->lpvtbl = &d3d2vt;
3703 *obj = d3d;
3705 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3707 return S_OK;
3709 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3710 return OLE_E_ENUM_NOMORE;
3713 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
3714 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3716 ICOM_THIS(IDirectDraw2Impl,iface);
3717 char xrefiid[50];
3719 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3720 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3721 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3722 *obj = This;
3723 IDirectDraw2_AddRef(iface);
3725 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3727 return S_OK;
3729 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3730 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
3731 IDirectDraw2_AddRef(iface);
3732 *obj = This;
3734 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3736 return S_OK;
3738 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3739 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
3740 IDirectDraw2_AddRef(iface);
3741 *obj = This;
3743 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3745 return S_OK;
3747 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3748 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
3749 IDirectDraw2_AddRef(iface);
3750 *obj = This;
3752 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3754 return S_OK;
3756 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3757 IDirect3DImpl* d3d;
3759 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3760 d3d->ref = 1;
3761 d3d->ddraw = (IDirectDrawImpl*)This;
3762 IDirectDraw2_AddRef(iface);
3763 d3d->lpvtbl = &d3dvt;
3764 *obj = d3d;
3766 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3768 return S_OK;
3770 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3771 IDirect3D2Impl* d3d;
3773 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3774 d3d->ref = 1;
3775 d3d->ddraw = (IDirectDrawImpl*)This;
3776 IDirectDraw2_AddRef(iface);
3777 d3d->lpvtbl = &d3d2vt;
3778 *obj = d3d;
3780 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3782 return S_OK;
3784 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3785 return OLE_E_ENUM_NOMORE;
3788 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
3789 LPDIRECTDRAW2 iface,BOOL *status
3791 ICOM_THIS(IDirectDraw2Impl,iface);
3792 TRACE(ddraw,"(%p)->(%p)\n",This,status);
3793 *status = TRUE;
3794 return DD_OK;
3797 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
3798 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3800 ICOM_THIS(IDirectDraw2Impl,iface);
3801 DDSURFACEDESC ddsfd;
3802 static struct {
3803 int w,h;
3804 } modes[5] = { /* some of the usual modes */
3805 {512,384},
3806 {640,400},
3807 {640,480},
3808 {800,600},
3809 {1024,768},
3811 static int depths[4] = {8,16,24,32};
3812 int i,j;
3814 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3815 ddsfd.dwSize = sizeof(ddsfd);
3816 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3817 if (dwFlags & DDEDM_REFRESHRATES) {
3818 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3819 ddsfd.x.dwRefreshRate = 60;
3822 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3823 ddsfd.dwBackBufferCount = 1;
3824 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3825 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3826 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3827 /* FIXME: those masks would have to be set in depth > 8 */
3828 if (depths[i]==8) {
3829 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3830 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3831 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3832 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3833 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3834 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3835 } else {
3836 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3838 /* FIXME: We should query those from X itself */
3839 switch (depths[i]) {
3840 case 16:
3841 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3842 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3843 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3844 break;
3845 case 24:
3846 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3847 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3848 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3849 break;
3850 case 32:
3851 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3852 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3853 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3854 break;
3858 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3859 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3860 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3861 if (!modescb(&ddsfd,context)) return DD_OK;
3863 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3864 ddsfd.dwWidth = modes[j].w;
3865 ddsfd.dwHeight = modes[j].h;
3866 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3867 if (!modescb(&ddsfd,context)) return DD_OK;
3870 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3871 /* modeX is not standard VGA */
3873 ddsfd.dwHeight = 200;
3874 ddsfd.dwWidth = 320;
3875 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3876 if (!modescb(&ddsfd,context)) return DD_OK;
3879 return DD_OK;
3882 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
3883 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3885 ICOM_THIS(IDirectDraw2Impl,iface);
3886 XVisualInfo *vi;
3887 XPixmapFormatValues *pf;
3888 XVisualInfo vt;
3889 int nvisuals, npixmap, i;
3890 int send_mode;
3891 int has_8bpp = 0;
3892 DDSURFACEDESC ddsfd;
3893 static struct {
3894 int w,h;
3895 } modes[] = { /* some of the usual modes */
3896 {512,384},
3897 {640,400},
3898 {640,480},
3899 {800,600},
3900 {1024,768},
3901 {1280,1024}
3903 DWORD maxWidth, maxHeight;
3905 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3906 ddsfd.dwSize = sizeof(ddsfd);
3907 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
3908 if (dwFlags & DDEDM_REFRESHRATES) {
3909 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3910 ddsfd.x.dwRefreshRate = 60;
3912 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3913 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3915 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3916 pf = XListPixmapFormats(display, &npixmap);
3918 i = 0;
3919 send_mode = 0;
3920 while (i < npixmap) {
3921 if ((has_8bpp == 0) && (pf[i].depth == 8)) {
3922 /* Special case of a 8bpp depth */
3923 has_8bpp = 1;
3924 send_mode = 1;
3926 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
3927 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3928 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
3929 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3930 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
3931 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3932 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3933 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3934 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3935 } else if (pf[i].depth > 8) {
3936 int j;
3938 /* All the 'true color' depths (15, 16 and 24)
3939 First, find the corresponding visual to extract the bit masks */
3940 for (j = 0; j < nvisuals; j++) {
3941 if (vi[j].depth == pf[i].depth) {
3942 ddsfd.ddsCaps.dwCaps = 0;
3943 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3944 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3945 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3946 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
3947 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
3948 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
3949 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
3950 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3952 send_mode = 1;
3953 break;
3957 if (j == nvisuals)
3958 ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
3959 } else {
3960 send_mode = 0;
3963 if (send_mode) {
3964 int mode;
3966 if (TRACE_ON(ddraw)) {
3967 TRACE(ddraw, "Enumerating with pixel format : \n");
3968 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
3971 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
3972 /* Do not enumerate modes we cannot handle anyway */
3973 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
3974 break;
3976 ddsfd.dwWidth = modes[mode].w;
3977 ddsfd.dwHeight = modes[mode].h;
3979 /* Now, send the mode description to the application */
3980 TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
3981 if (!modescb(&ddsfd, context))
3982 goto exit_enum;
3985 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3986 /* modeX is not standard VGA */
3987 ddsfd.dwWidth = 320;
3988 ddsfd.dwHeight = 200;
3989 if (!modescb(&ddsfd, context))
3990 goto exit_enum;
3994 /* Hack to always enumerate a 8bpp depth */
3995 i++;
3996 if ((i == npixmap) && (has_8bpp == 0)) {
3997 i--;
3998 pf[i].depth = 8;
4002 exit_enum:
4003 TSXFree(vi);
4004 TSXFree(pf);
4006 return DD_OK;
4009 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4010 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4012 #ifdef HAVE_LIBXXF86DGA
4013 ICOM_THIS(IDirectDraw2Impl,iface);
4014 TRACE(ddraw,"(%p)->(%p)\n",This,lpddsfd);
4015 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4016 lpddsfd->dwHeight = This->d.height;
4017 lpddsfd->dwWidth = This->d.width;
4018 lpddsfd->lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4019 lpddsfd->dwBackBufferCount = 1;
4020 lpddsfd->x.dwRefreshRate = 60;
4021 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4022 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4023 return DD_OK;
4024 #else /* defined(HAVE_LIBXXF86DGA) */
4025 return E_UNEXPECTED;
4026 #endif /* defined(HAVE_LIBXXF86DGA) */
4029 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4030 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4032 ICOM_THIS(IDirectDraw2Impl,iface);
4033 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4034 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4035 lpddsfd->dwHeight = This->d.height;
4036 lpddsfd->dwWidth = This->d.width;
4037 lpddsfd->lPitch = lpddsfd->dwWidth * This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4038 lpddsfd->dwBackBufferCount = 1;
4039 lpddsfd->x.dwRefreshRate = 60;
4040 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4041 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4042 return DD_OK;
4045 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4046 ICOM_THIS(IDirectDraw2Impl,iface);
4047 TRACE(ddraw,"(%p)->()\n",This);
4048 return DD_OK;
4051 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4052 LPDIRECTDRAW2 iface,LPDWORD freq
4054 ICOM_THIS(IDirectDraw2Impl,iface);
4055 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",This,freq);
4056 *freq = 60*100; /* 60 Hz */
4057 return DD_OK;
4060 /* what can we directly decompress? */
4061 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4062 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4064 ICOM_THIS(IDirectDraw2Impl,iface);
4065 FIXME(ddraw,"(%p,%p,%p), stub\n",This,x,y);
4066 return DD_OK;
4069 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4070 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4072 ICOM_THIS(IDirectDraw2Impl,iface);
4073 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4074 return DD_OK;
4077 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4078 LPDIRECTDRAW2 iface )
4080 ICOM_THIS(IDirectDraw2Impl,iface);
4081 FIXME(ddraw,"(%p)->()\n", This );
4083 return DD_OK;
4086 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4087 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4088 ICOM_THIS(IDirectDraw2Impl,iface);
4089 FIXME(ddraw,"(%p)->(%p)\n", This, lplpGDIDDSSurface);
4091 return DD_OK;
4094 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4095 LPDWORD lpdwScanLine) {
4096 ICOM_THIS(IDirectDraw2Impl,iface);
4097 FIXME(ddraw,"(%p)->(%p)\n", This, lpdwScanLine);
4099 return DD_OK;
4102 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4103 GUID *lpGUID) {
4104 ICOM_THIS(IDirectDraw2Impl,iface);
4105 FIXME(ddraw,"(%p)->(%p)\n", This, lpGUID);
4107 return DD_OK;
4110 /* Note: Hack so we can reuse the old functions without compiler warnings */
4111 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4112 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4113 #else
4114 # define XCAST(fun) (void *)
4115 #endif
4117 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4119 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4120 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4121 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4122 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4123 XCAST(Compact)IDirectDraw2Impl_Compact,
4124 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4125 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4126 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4127 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4128 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4129 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4130 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4131 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4132 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4133 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4134 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4135 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4136 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4137 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4138 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4139 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4140 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4141 DGA_IDirectDrawImpl_SetDisplayMode,
4142 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4145 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
4147 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4148 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4149 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4150 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4151 XCAST(Compact)IDirectDraw2Impl_Compact,
4152 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4153 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4154 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4155 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4156 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4157 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4158 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4159 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4160 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4161 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4162 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4163 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4164 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4165 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4166 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4167 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4168 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4169 Xlib_IDirectDrawImpl_SetDisplayMode,
4170 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4173 #undef XCAST
4175 /*****************************************************************************
4176 * IDirectDraw2
4181 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4182 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4184 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4187 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4188 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4190 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4193 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4194 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4196 ICOM_THIS(IDirectDraw2Impl,iface);
4197 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4198 This,ddscaps,total,free
4200 if (total) *total = This->e.dga.fb_memsize * 1024;
4201 if (free) *free = This->e.dga.fb_memsize * 1024;
4202 return DD_OK;
4205 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4206 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4208 ICOM_THIS(IDirectDraw2Impl,iface);
4209 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4210 This,ddscaps,total,free
4212 if (total) *total = 2048 * 1024;
4213 if (free) *free = 2048 * 1024;
4214 return DD_OK;
4217 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
4219 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4220 DGA_IDirectDraw2Impl_QueryInterface,
4221 IDirectDraw2Impl_AddRef,
4222 DGA_IDirectDraw2Impl_Release,
4223 IDirectDraw2Impl_Compact,
4224 IDirectDraw2Impl_CreateClipper,
4225 DGA_IDirectDraw2Impl_CreatePalette,
4226 DGA_IDirectDraw2Impl_CreateSurface,
4227 IDirectDraw2Impl_DuplicateSurface,
4228 DGA_IDirectDraw2Impl_EnumDisplayModes,
4229 IDirectDraw2Impl_EnumSurfaces,
4230 IDirectDraw2Impl_FlipToGDISurface,
4231 DGA_IDirectDraw2Impl_GetCaps,
4232 DGA_IDirectDraw2Impl_GetDisplayMode,
4233 IDirectDraw2Impl_GetFourCCCodes,
4234 IDirectDraw2Impl_GetGDISurface,
4235 IDirectDraw2Impl_GetMonitorFrequency,
4236 IDirectDraw2Impl_GetScanLine,
4237 IDirectDraw2Impl_GetVerticalBlankStatus,
4238 IDirectDraw2Impl_Initialize,
4239 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4240 IDirectDraw2Impl_SetCooperativeLevel,
4241 DGA_IDirectDraw2Impl_SetDisplayMode,
4242 IDirectDraw2Impl_WaitForVerticalBlank,
4243 DGA_IDirectDraw2Impl_GetAvailableVidMem
4246 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
4248 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4249 Xlib_IDirectDraw2Impl_QueryInterface,
4250 IDirectDraw2Impl_AddRef,
4251 Xlib_IDirectDraw2Impl_Release,
4252 IDirectDraw2Impl_Compact,
4253 IDirectDraw2Impl_CreateClipper,
4254 Xlib_IDirectDraw2Impl_CreatePalette,
4255 Xlib_IDirectDraw2Impl_CreateSurface,
4256 IDirectDraw2Impl_DuplicateSurface,
4257 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4258 IDirectDraw2Impl_EnumSurfaces,
4259 IDirectDraw2Impl_FlipToGDISurface,
4260 Xlib_IDirectDraw2Impl_GetCaps,
4261 Xlib_IDirectDraw2Impl_GetDisplayMode,
4262 IDirectDraw2Impl_GetFourCCCodes,
4263 IDirectDraw2Impl_GetGDISurface,
4264 IDirectDraw2Impl_GetMonitorFrequency,
4265 IDirectDraw2Impl_GetScanLine,
4266 IDirectDraw2Impl_GetVerticalBlankStatus,
4267 IDirectDraw2Impl_Initialize,
4268 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4269 IDirectDraw2Impl_SetCooperativeLevel,
4270 Xlib_IDirectDraw2Impl_SetDisplayMode,
4271 IDirectDraw2Impl_WaitForVerticalBlank,
4272 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4275 /*****************************************************************************
4276 * IDirectDraw4
4280 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4281 HDC hdc,
4282 LPDIRECTDRAWSURFACE *lpDDS) {
4283 ICOM_THIS(IDirectDraw4Impl,iface);
4284 FIXME(ddraw, "(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4286 return DD_OK;
4289 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4290 ICOM_THIS(IDirectDraw4Impl,iface);
4291 FIXME(ddraw, "(%p)->()\n", This);
4293 return DD_OK;
4296 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4297 ICOM_THIS(IDirectDraw4Impl,iface);
4298 FIXME(ddraw, "(%p)->()\n", This);
4300 return DD_OK;
4303 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4304 LPDDDEVICEIDENTIFIER lpdddi,
4305 DWORD dwFlags) {
4306 ICOM_THIS(IDirectDraw4Impl,iface);
4307 FIXME(ddraw, "(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4309 return DD_OK;
4312 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4313 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4314 #else
4315 # define XCAST(fun) (void*)
4316 #endif
4319 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
4321 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4322 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4323 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4324 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4325 XCAST(Compact)IDirectDraw2Impl_Compact,
4326 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4327 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4328 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4329 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4330 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4331 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4332 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4333 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4334 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4335 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4336 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4337 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4338 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4339 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4340 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4341 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4342 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4343 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4344 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4345 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4346 IDirectDraw4Impl_GetSurfaceFromDC,
4347 IDirectDraw4Impl_RestoreAllSurfaces,
4348 IDirectDraw4Impl_TestCooperativeLevel,
4349 IDirectDraw4Impl_GetDeviceIdentifier
4352 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
4354 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4355 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4356 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4357 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4358 XCAST(Compact)IDirectDraw2Impl_Compact,
4359 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4360 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4361 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4362 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4363 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4364 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4365 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4366 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4367 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4368 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4369 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4370 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4371 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4372 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4373 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4374 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4375 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4376 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4377 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4378 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4379 IDirectDraw4Impl_GetSurfaceFromDC,
4380 IDirectDraw4Impl_RestoreAllSurfaces,
4381 IDirectDraw4Impl_TestCooperativeLevel,
4382 IDirectDraw4Impl_GetDeviceIdentifier
4385 #undef XCAST
4387 /******************************************************************************
4388 * DirectDrawCreate
4391 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4393 LRESULT ret;
4394 IDirectDrawImpl* ddraw = NULL;
4395 DWORD lastError;
4397 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4399 SetLastError( ERROR_SUCCESS );
4400 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4401 if( (!ddraw) &&
4402 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4405 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4408 if( ddraw )
4410 /* Perform any special direct draw functions */
4411 if (msg==WM_PAINT)
4412 ddraw->d.paintable = 1;
4414 /* Now let the application deal with the rest of this */
4415 if( ddraw->d.mainWindow )
4418 /* Don't think that we actually need to call this but...
4419 might as well be on the safe side of things... */
4421 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4422 it should be the procedures of our fake window that gets called
4423 instead of those of the window provided by the application.
4424 And with this patch, mouse clicks work with Monkey Island III
4425 - Lionel */
4426 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4428 if( !ret )
4430 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4431 /* We didn't handle the message - give it to the application */
4432 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4434 ret = CallWindowProcA(tmpWnd->winproc,
4435 ddraw->d.mainWindow, msg, wParam, lParam );
4437 WIN_ReleaseWndPtr(tmpWnd);
4441 } else {
4442 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4446 else
4448 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4451 return ret;
4454 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4455 #ifdef HAVE_LIBXXF86DGA
4456 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4457 int memsize,banksize,width,major,minor,flags,height;
4458 char *addr;
4459 int fd;
4460 int depth;
4462 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4463 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4464 close(fd);
4466 if (fd == -1) {
4467 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4468 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4469 return E_UNEXPECTED;
4471 if (!DDRAW_DGA_Available()) {
4472 TRACE(ddraw,"No XF86DGA detected.\n");
4473 return DDERR_GENERIC;
4475 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4476 (*ilplpDD)->lpvtbl = &dga_ddvt;
4477 (*ilplpDD)->ref = 1;
4478 TSXF86DGAQueryVersion(display,&major,&minor);
4479 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4480 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4481 if (!(flags & XF86DGADirectPresent))
4482 MSG("direct video is NOT PRESENT.\n");
4483 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4484 (*ilplpDD)->e.dga.fb_width = width;
4485 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4486 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4487 (*ilplpDD)->e.dga.fb_height = height;
4488 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4489 addr,width,banksize,memsize
4491 TRACE(ddraw,"viewport height: %d\n",height);
4493 /* Get the screen dimensions as seen by Wine.
4494 In that case, it may be better to ignore the -desktop mode and return the
4495 real screen size => print a warning */
4496 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4497 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4498 if (((*ilplpDD)->d.height != height) ||
4499 ((*ilplpDD)->d.width != width))
4500 WARN(ddraw, "You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
4501 (*ilplpDD)->e.dga.fb_addr = addr;
4502 (*ilplpDD)->e.dga.fb_memsize = memsize;
4503 (*ilplpDD)->e.dga.fb_banksize = banksize;
4505 #ifdef DIABLO_HACK
4506 (*ilplpDD)->e.dga.vpmask = 1;
4507 #else
4508 (*ilplpDD)->e.dga.vpmask = 0;
4509 #endif
4511 /* just assume the default depth is the DGA depth too */
4512 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4513 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4514 #ifdef RESTORE_SIGNALS
4515 SIGNAL_InitHandlers();
4516 #endif
4518 return DD_OK;
4519 #else /* defined(HAVE_LIBXXF86DGA) */
4520 return DDERR_INVALIDDIRECTDRAWGUID;
4521 #endif /* defined(HAVE_LIBXXF86DGA) */
4524 BOOL
4525 DDRAW_XSHM_Available(void)
4527 #ifdef HAVE_LIBXXSHM
4528 if (TSXShmQueryExtension(display))
4530 int major, minor;
4531 Bool shpix;
4533 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4534 return 1;
4535 else
4536 return 0;
4538 else
4539 return 0;
4540 #else
4541 return 0;
4542 #endif
4545 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4546 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4547 int depth;
4549 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4550 (*ilplpDD)->lpvtbl = &xlib_ddvt;
4551 (*ilplpDD)->ref = 1;
4552 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
4554 /* At DirectDraw creation, the depth is the default depth */
4555 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4556 _common_depth_to_pixelformat(depth,
4557 &((*ilplpDD)->d.directdraw_pixelformat),
4558 &((*ilplpDD)->d.screen_pixelformat),
4559 &((*ilplpDD)->d.pixmap_depth));
4560 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4561 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4563 #ifdef HAVE_LIBXXSHM
4564 /* Test if XShm is available. */
4565 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4566 TRACE(ddraw, "Using XShm extension.\n");
4567 #endif
4569 return DD_OK;
4572 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4573 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4574 char xclsid[50];
4575 WNDCLASSA wc;
4576 /* WND* pParentWindow; */
4577 HRESULT ret;
4579 if (HIWORD(lpGUID))
4580 WINE_StringFromCLSID(lpGUID,xclsid);
4581 else {
4582 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4583 lpGUID = NULL;
4586 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
4588 if ((!lpGUID) ||
4589 (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4590 (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4591 (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4592 /* if they didn't request a particular interface, use the best
4593 * supported one */
4594 if (DDRAW_DGA_Available())
4595 lpGUID = &DGA_DirectDraw_GUID;
4596 else
4597 lpGUID = &XLIB_DirectDraw_GUID;
4600 wc.style = CS_GLOBALCLASS;
4601 wc.lpfnWndProc = Xlib_DDWndProc;
4602 wc.cbClsExtra = 0;
4603 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
4604 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
4606 /* We can be a child of the desktop since we're really important */
4608 This code is not useful since hInstance is forced to 0 afterward
4609 pParentWindow = WIN_GetDesktop();
4610 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
4612 wc.hInstance = 0;
4615 wc.hIcon = 0;
4616 wc.hCursor = (HCURSOR)IDC_ARROWA;
4617 wc.hbrBackground= NULL_BRUSH;
4618 wc.lpszMenuName = 0;
4619 wc.lpszClassName= "WINE_DirectDraw";
4620 RegisterClassA(&wc);
4622 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4623 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4624 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4625 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4626 else
4627 goto err;
4630 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
4631 return ret;
4633 err:
4634 ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4635 return DDERR_INVALIDDIRECTDRAWGUID;
4639 #else /* !defined(X_DISPLAY_MISSING) */
4641 #include "windef.h"
4643 #define DD_OK 0
4645 typedef void *LPGUID;
4646 typedef void *LPUNKNOWN;
4647 typedef void *LPDIRECTDRAW;
4648 typedef void *LPDIRECTDRAWCLIPPER;
4649 typedef void *LPDDENUMCALLBACKA;
4650 typedef void *LPDDENUMCALLBACKEXA;
4651 typedef void *LPDDENUMCALLBACKEXW;
4652 typedef void *LPDDENUMCALLBACKW;
4654 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
4656 return DD_OK;
4659 HRESULT WINAPI DirectDrawCreate(
4660 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
4662 return DD_OK;
4665 HRESULT WINAPI DirectDrawCreateClipper(
4666 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
4668 return DD_OK;
4671 HRESULT WINAPI DirectDrawEnumerateA(
4672 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
4674 return DD_OK;
4677 HRESULT WINAPI DirectDrawEnumerateExA(
4678 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
4680 return DD_OK;
4683 HRESULT WINAPI DirectDrawEnumerateExW(
4684 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
4686 return DD_OK;
4689 HRESULT WINAPI DirectDrawEnumerateW(
4690 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
4692 return DD_OK;
4695 #endif /* !defined(X_DISPLAY_MISSING) */
4698 /*******************************************************************************
4699 * DirectDraw ClassFactory
4701 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
4704 typedef struct
4706 /* IUnknown fields */
4707 ICOM_VTABLE(IClassFactory)* lpvtbl;
4708 DWORD ref;
4709 } IClassFactoryImpl;
4711 static HRESULT WINAPI
4712 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
4713 ICOM_THIS(IClassFactoryImpl,iface);
4714 char buf[80];
4716 if (HIWORD(riid))
4717 WINE_StringFromCLSID(riid,buf);
4718 else
4719 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4720 FIXME(ddraw,"(%p)->(%s,%p),stub!\n",This,buf,ppobj);
4721 return E_NOINTERFACE;
4724 static ULONG WINAPI
4725 DDCF_AddRef(LPCLASSFACTORY iface) {
4726 ICOM_THIS(IClassFactoryImpl,iface);
4727 return ++(This->ref);
4730 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
4731 ICOM_THIS(IClassFactoryImpl,iface);
4732 /* static class, won't be freed */
4733 return --(This->ref);
4736 static HRESULT WINAPI DDCF_CreateInstance(
4737 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
4739 ICOM_THIS(IClassFactoryImpl,iface);
4740 char buf[80];
4742 WINE_StringFromCLSID(riid,buf);
4743 TRACE(ddraw,"(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
4744 if ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4745 (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4746 (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4747 /* FIXME: reuse already created DirectDraw if present? */
4748 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
4750 return E_NOINTERFACE;
4753 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
4754 ICOM_THIS(IClassFactoryImpl,iface);
4755 FIXME(ddraw,"(%p)->(%d),stub!\n",This,dolock);
4756 return S_OK;
4759 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
4761 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4762 DDCF_QueryInterface,
4763 DDCF_AddRef,
4764 DDCF_Release,
4765 DDCF_CreateInstance,
4766 DDCF_LockServer
4768 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
4770 /*******************************************************************************
4771 * DllGetClassObject [DDRAW.13]
4772 * Retrieves class object from a DLL object
4774 * NOTES
4775 * Docs say returns STDAPI
4777 * PARAMS
4778 * rclsid [I] CLSID for the class object
4779 * riid [I] Reference to identifier of interface for class object
4780 * ppv [O] Address of variable to receive interface pointer for riid
4782 * RETURNS
4783 * Success: S_OK
4784 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
4785 * E_UNEXPECTED
4787 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
4789 char buf[80],xbuf[80];
4791 if (HIWORD(rclsid))
4792 WINE_StringFromCLSID(rclsid,xbuf);
4793 else
4794 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
4795 if (HIWORD(riid))
4796 WINE_StringFromCLSID(riid,buf);
4797 else
4798 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4799 WINE_StringFromCLSID(riid,xbuf);
4800 TRACE(ddraw, "(%p,%p,%p)\n", xbuf, buf, ppv);
4801 if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
4802 *ppv = (LPVOID)&DDRAW_CF;
4803 IClassFactory_AddRef((IClassFactory*)*ppv);
4804 return S_OK;
4806 FIXME(ddraw, "(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
4807 return E_NOINTERFACE;
4811 /*******************************************************************************
4812 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
4814 * RETURNS
4815 * Success: S_OK
4816 * Failure: S_FALSE
4818 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
4820 FIXME(ddraw, "(void): stub\n");
4821 return S_FALSE;