Added timeout to critical section waiting.
[wine/multimedia.git] / graphics / ddraw.c
blob1450a3af05e10a0035a9151e7938be522f241c95
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 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
71 #undef DIABLO_HACK
73 /* Restore signal handlers overwritten by XF86DGA
75 #define RESTORE_SIGNALS
77 /* Where do these GUIDs come from? mkuuid.
78 * They exist solely to distinguish between the targets Wine support,
79 * and should be different than any other GUIDs in existence.
81 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
82 0xe2dcb020,
83 0xdc60,
84 0x11d1,
85 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
88 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
89 0x1574a740,
90 0xdc61,
91 0x11d1,
92 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
95 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt, xlib_dds4vt;
96 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt, xlib_ddvt;
97 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt, xlib_dd2vt;
98 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt, xlib_dd4vt;
99 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
100 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt, xlib_ddpalvt;
101 static struct ICOM_VTABLE(IDirect3D) d3dvt;
102 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
104 #ifdef HAVE_LIBXXF86VM
105 static XF86VidModeModeInfo *orig_mode = NULL;
106 #endif
108 #ifdef HAVE_LIBXXSHM
109 static int XShmErrorFlag = 0;
110 #endif
112 BOOL
113 DDRAW_DGA_Available(void)
115 #ifdef HAVE_LIBXXF86DGA
116 int evbase, evret, fd;
118 if (Options.noDGA)
119 return 0;
121 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
122 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
123 /* others. --stephenc */
124 if ((fd = open("/dev/mem", O_RDWR)) != -1)
125 close(fd);
127 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
128 #else /* defined(HAVE_LIBXXF86DGA) */
129 return 0;
130 #endif /* defined(HAVE_LIBXXF86DGA) */
133 /**********************************************************************/
135 typedef struct {
136 LPVOID lpCallback;
137 LPVOID lpContext;
138 } DirectDrawEnumerateProcData;
140 /***********************************************************************
141 * DirectDrawEnumerateExA (DDRAW.*)
143 HRESULT WINAPI DirectDrawEnumerateExA(
144 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
146 TRACE(ddraw, "(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
148 if (TRACE_ON(ddraw)) {
149 DUMP(" Flags : ");
150 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
151 DUMP("DDENUM_ATTACHEDSECONDARYDEVICES ");
152 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
153 DUMP("DDENUM_DETACHEDSECONDARYDEVICES ");
154 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
155 DUMP("DDENUM_NONDISPLAYDEVICES ");
156 DUMP("\n");
159 if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
160 /* For the moment, Wine does not support any 3D only accelerators */
161 return DD_OK;
164 if (DDRAW_DGA_Available()) {
165 TRACE(ddraw, "Enumerating DGA interface\n");
166 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
167 return DD_OK;
170 TRACE(ddraw, "Enumerating Xlib interface\n");
171 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
172 return DD_OK;
174 TRACE(ddraw, "Enumerating Default interface\n");
175 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
176 return DD_OK;
178 return DD_OK;
181 /***********************************************************************
182 * DirectDrawEnumerateExW (DDRAW.*)
185 static BOOL CALLBACK DirectDrawEnumerateExProcW(
186 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
187 LPVOID lpContext, HMONITOR hm)
189 DirectDrawEnumerateProcData *pEPD =
190 (DirectDrawEnumerateProcData *) lpContext;
191 LPWSTR lpDriverDescriptionW =
192 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
193 LPWSTR lpDriverNameW =
194 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
196 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
197 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
199 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
200 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
202 return bResult;
205 /**********************************************************************/
207 HRESULT WINAPI DirectDrawEnumerateExW(
208 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
210 DirectDrawEnumerateProcData epd;
211 epd.lpCallback = lpCallback;
212 epd.lpContext = lpContext;
214 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
215 (LPVOID) &epd, 0);
218 /***********************************************************************
219 * DirectDrawEnumerateA (DDRAW.*)
222 static BOOL CALLBACK DirectDrawEnumerateProcA(
223 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
224 LPVOID lpContext, HMONITOR hm)
226 DirectDrawEnumerateProcData *pEPD =
227 (DirectDrawEnumerateProcData *) lpContext;
229 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
230 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
233 /**********************************************************************/
235 HRESULT WINAPI DirectDrawEnumerateA(
236 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
238 DirectDrawEnumerateProcData epd;
239 epd.lpCallback = lpCallback;
240 epd.lpContext = lpContext;
242 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
243 (LPVOID) &epd, 0);
246 /***********************************************************************
247 * DirectDrawEnumerateW (DDRAW.*)
250 static BOOL WINAPI DirectDrawEnumerateProcW(
251 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
252 LPVOID lpContext, HMONITOR hm)
254 DirectDrawEnumerateProcData *pEPD =
255 (DirectDrawEnumerateProcData *) lpContext;
257 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
258 lpGUID, lpDriverDescription, lpDriverName,
259 pEPD->lpContext);
262 /**********************************************************************/
264 HRESULT WINAPI DirectDrawEnumerateW(
265 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
267 DirectDrawEnumerateProcData epd;
268 epd.lpCallback = lpCallback;
269 epd.lpContext = lpContext;
271 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
272 (LPVOID) &epd, 0);
275 /***********************************************************************
276 * DSoundHelp (DDRAW.?)
279 /* What is this doing here? */
280 HRESULT WINAPI
281 DSoundHelp(DWORD x,DWORD y,DWORD z) {
282 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
283 return 0;
286 /******************************************************************************
287 * internal helper functions
289 static void _dump_DDBLTFX(DWORD flagmask) {
290 int i;
291 const struct {
292 DWORD mask;
293 char *name;
294 } flags[] = {
295 #define FE(x) { x, #x},
296 FE(DDBLTFX_ARITHSTRETCHY)
297 FE(DDBLTFX_MIRRORLEFTRIGHT)
298 FE(DDBLTFX_MIRRORUPDOWN)
299 FE(DDBLTFX_NOTEARING)
300 FE(DDBLTFX_ROTATE180)
301 FE(DDBLTFX_ROTATE270)
302 FE(DDBLTFX_ROTATE90)
303 FE(DDBLTFX_ZBUFFERRANGE)
304 FE(DDBLTFX_ZBUFFERBASEDEST)
306 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
307 if (flags[i].mask & flagmask) {
308 DUMP("%s ",flags[i].name);
311 DUMP("\n");
315 static void _dump_DDBLTFAST(DWORD flagmask) {
316 int i;
317 const struct {
318 DWORD mask;
319 char *name;
320 } flags[] = {
321 #define FE(x) { x, #x},
322 FE(DDBLTFAST_NOCOLORKEY)
323 FE(DDBLTFAST_SRCCOLORKEY)
324 FE(DDBLTFAST_DESTCOLORKEY)
325 FE(DDBLTFAST_WAIT)
327 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
328 if (flags[i].mask & flagmask)
329 DUMP("%s ",flags[i].name);
330 DUMP("\n");
333 static void _dump_DDBLT(DWORD flagmask) {
334 int i;
335 const struct {
336 DWORD mask;
337 char *name;
338 } flags[] = {
339 #define FE(x) { x, #x},
340 FE(DDBLT_ALPHADEST)
341 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
342 FE(DDBLT_ALPHADESTNEG)
343 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
344 FE(DDBLT_ALPHAEDGEBLEND)
345 FE(DDBLT_ALPHASRC)
346 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
347 FE(DDBLT_ALPHASRCNEG)
348 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
349 FE(DDBLT_ASYNC)
350 FE(DDBLT_COLORFILL)
351 FE(DDBLT_DDFX)
352 FE(DDBLT_DDROPS)
353 FE(DDBLT_KEYDEST)
354 FE(DDBLT_KEYDESTOVERRIDE)
355 FE(DDBLT_KEYSRC)
356 FE(DDBLT_KEYSRCOVERRIDE)
357 FE(DDBLT_ROP)
358 FE(DDBLT_ROTATIONANGLE)
359 FE(DDBLT_ZBUFFER)
360 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
361 FE(DDBLT_ZBUFFERDESTOVERRIDE)
362 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
363 FE(DDBLT_ZBUFFERSRCOVERRIDE)
364 FE(DDBLT_WAIT)
365 FE(DDBLT_DEPTHFILL)
367 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
368 if (flags[i].mask & flagmask)
369 DUMP("%s ",flags[i].name);
370 DUMP("\n");
373 static void _dump_DDSCAPS(DWORD flagmask) {
374 int i;
375 const struct {
376 DWORD mask;
377 char *name;
378 } flags[] = {
379 #define FE(x) { x, #x},
380 FE(DDSCAPS_RESERVED1)
381 FE(DDSCAPS_ALPHA)
382 FE(DDSCAPS_BACKBUFFER)
383 FE(DDSCAPS_COMPLEX)
384 FE(DDSCAPS_FLIP)
385 FE(DDSCAPS_FRONTBUFFER)
386 FE(DDSCAPS_OFFSCREENPLAIN)
387 FE(DDSCAPS_OVERLAY)
388 FE(DDSCAPS_PALETTE)
389 FE(DDSCAPS_PRIMARYSURFACE)
390 FE(DDSCAPS_PRIMARYSURFACELEFT)
391 FE(DDSCAPS_SYSTEMMEMORY)
392 FE(DDSCAPS_TEXTURE)
393 FE(DDSCAPS_3DDEVICE)
394 FE(DDSCAPS_VIDEOMEMORY)
395 FE(DDSCAPS_VISIBLE)
396 FE(DDSCAPS_WRITEONLY)
397 FE(DDSCAPS_ZBUFFER)
398 FE(DDSCAPS_OWNDC)
399 FE(DDSCAPS_LIVEVIDEO)
400 FE(DDSCAPS_HWCODEC)
401 FE(DDSCAPS_MODEX)
402 FE(DDSCAPS_MIPMAP)
403 FE(DDSCAPS_RESERVED2)
404 FE(DDSCAPS_ALLOCONLOAD)
405 FE(DDSCAPS_VIDEOPORT)
406 FE(DDSCAPS_LOCALVIDMEM)
407 FE(DDSCAPS_NONLOCALVIDMEM)
408 FE(DDSCAPS_STANDARDVGAMODE)
409 FE(DDSCAPS_OPTIMIZED)
411 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
412 if (flags[i].mask & flagmask)
413 DUMP("%s ",flags[i].name);
414 DUMP("\n");
417 static void _dump_DDSD(DWORD flagmask) {
418 int i;
419 const struct {
420 DWORD mask;
421 char *name;
422 } flags[] = {
423 FE(DDSD_CAPS)
424 FE(DDSD_HEIGHT)
425 FE(DDSD_WIDTH)
426 FE(DDSD_PITCH)
427 FE(DDSD_BACKBUFFERCOUNT)
428 FE(DDSD_ZBUFFERBITDEPTH)
429 FE(DDSD_ALPHABITDEPTH)
430 FE(DDSD_PIXELFORMAT)
431 FE(DDSD_CKDESTOVERLAY)
432 FE(DDSD_CKDESTBLT)
433 FE(DDSD_CKSRCOVERLAY)
434 FE(DDSD_CKSRCBLT)
435 FE(DDSD_MIPMAPCOUNT)
436 FE(DDSD_REFRESHRATE)
437 FE(DDSD_LINEARSIZE)
438 FE(DDSD_LPSURFACE)
440 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
441 if (flags[i].mask & flagmask)
442 DUMP("%s ",flags[i].name);
443 DUMP("\n");
446 static void _dump_DDCOLORKEY(DWORD flagmask) {
447 int i;
448 const struct {
449 DWORD mask;
450 char *name;
451 } flags[] = {
452 #define FE(x) { x, #x},
453 FE(DDPF_ALPHAPIXELS)
454 FE(DDPF_ALPHA)
455 FE(DDPF_FOURCC)
456 FE(DDPF_PALETTEINDEXED4)
457 FE(DDPF_PALETTEINDEXEDTO8)
458 FE(DDPF_PALETTEINDEXED8)
459 FE(DDPF_RGB)
460 FE(DDPF_COMPRESSED)
461 FE(DDPF_RGBTOYUV)
462 FE(DDPF_YUV)
463 FE(DDPF_ZBUFFER)
464 FE(DDPF_PALETTEINDEXED1)
465 FE(DDPF_PALETTEINDEXED2)
466 FE(DDPF_ZPIXELS)
468 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
469 if (flags[i].mask & flagmask)
470 DUMP("%s ",flags[i].name);
471 DUMP("\n");
474 static void _dump_paletteformat(DWORD dwFlags) {
475 int i;
476 const struct {
477 DWORD mask;
478 char *name;
479 } flags[] = {
480 #define FE(x) { x, #x},
481 FE(DDPCAPS_4BIT)
482 FE(DDPCAPS_8BITENTRIES)
483 FE(DDPCAPS_8BIT)
484 FE(DDPCAPS_INITIALIZE)
485 FE(DDPCAPS_PRIMARYSURFACE)
486 FE(DDPCAPS_PRIMARYSURFACELEFT)
487 FE(DDPCAPS_ALLOW256)
488 FE(DDPCAPS_VSYNC)
489 FE(DDPCAPS_1BIT)
490 FE(DDPCAPS_2BIT)
491 FE(DDPCAPS_ALPHA)
493 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
494 if (flags[i].mask & dwFlags)
495 DUMP("%s ",flags[i].name);
496 DUMP("\n");
499 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
500 DUMP("Size : %ld\n", pf->dwSize);
501 if (pf->dwFlags)
502 _dump_DDCOLORKEY(pf->dwFlags);
503 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
504 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
505 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
506 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
509 static void _dump_colorkeyflag(DWORD ck) {
510 int i;
511 const struct {
512 DWORD mask;
513 char *name;
514 } flags[] = {
515 #define FE(x) { x, #x},
516 FE(DDCKEY_COLORSPACE)
517 FE(DDCKEY_DESTBLT)
518 FE(DDCKEY_DESTOVERLAY)
519 FE(DDCKEY_SRCBLT)
520 FE(DDCKEY_SRCOVERLAY)
522 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
523 if (flags[i].mask & ck)
524 DUMP("%s ",flags[i].name);
525 DUMP("\n");
528 /******************************************************************************
529 * IDirectDrawSurface methods
531 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
532 * DDS and DDS2 use those functions. (Function calls did not change (except
533 * using different DirectDrawSurfaceX version), just added flags and functions)
535 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
536 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
538 ICOM_THIS(IDirectDrawSurface4Impl,iface);
539 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
540 This,lprect,lpddsd,flags,(DWORD)hnd);
541 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
542 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
543 This,lprect,lpddsd,flags,(DWORD)hnd);
545 /* First, copy the Surface description */
546 *lpddsd = This->s.surface_desc;
547 TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
548 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
550 /* If asked only for a part, change the surface pointer */
551 if (lprect) {
552 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
553 lprect->top,lprect->left,lprect->bottom,lprect->right
555 lpddsd->y.lpSurface = This->s.surface_desc.y.lpSurface +
556 (lprect->top*This->s.surface_desc.lPitch) +
557 (lprect->left*(This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
558 } else {
559 assert(This->s.surface_desc.y.lpSurface);
561 return DD_OK;
564 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
565 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
567 ICOM_THIS(IDirectDrawSurface4Impl,iface);
568 TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
569 return DD_OK;
572 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
573 if (This->s.ddraw->d.pixel_convert != NULL)
574 This->s.ddraw->d.pixel_convert(This->s.surface_desc.y.lpSurface,
575 This->t.xlib.image->data,
576 This->s.surface_desc.dwWidth,
577 This->s.surface_desc.dwHeight,
578 This->s.surface_desc.lPitch,
579 This->s.palette);
581 #ifdef HAVE_LIBXXSHM
582 if (This->s.ddraw->e.xlib.xshm_active)
583 TSXShmPutImage(display,
584 This->s.ddraw->d.drawable,
585 DefaultGCOfScreen(X11DRV_GetXScreen()),
586 This->t.xlib.image,
587 0, 0, 0, 0,
588 This->t.xlib.image->width,
589 This->t.xlib.image->height,
590 False);
591 else
592 #endif
593 TSXPutImage( display,
594 This->s.ddraw->d.drawable,
595 DefaultGCOfScreen(X11DRV_GetXScreen()),
596 This->t.xlib.image,
597 0, 0, 0, 0,
598 This->t.xlib.image->width,
599 This->t.xlib.image->height);
602 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
603 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
605 ICOM_THIS(IDirectDrawSurface4Impl,iface);
606 TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
608 if (!This->s.ddraw->d.paintable)
609 return DD_OK;
611 /* Only redraw the screen when unlocking the buffer that is on screen */
612 if ((This->t.xlib.image != NULL) &&
613 (This->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
614 Xlib_copy_surface_on_screen(This);
616 if (This->s.palette && This->s.palette->cm)
617 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
620 return DD_OK;
623 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
624 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
626 ICOM_THIS(IDirectDrawSurface4Impl,iface);
627 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
628 #ifdef HAVE_LIBXXF86DGA
629 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
630 if (!iflipto) {
631 if (This->s.backbuffer)
632 iflipto = This->s.backbuffer;
633 else
634 iflipto = This;
636 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
638 if (iflipto->s.palette && iflipto->s.palette->cm) {
639 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
641 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
643 if (iflipto!=This) {
644 int tmp;
645 LPVOID ptmp;
647 tmp = This->t.dga.fb_height;
648 This->t.dga.fb_height = iflipto->t.dga.fb_height;
649 iflipto->t.dga.fb_height = tmp;
651 ptmp = This->s.surface_desc.y.lpSurface;
652 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
653 iflipto->s.surface_desc.y.lpSurface = ptmp;
655 return DD_OK;
656 #else /* defined(HAVE_LIBXXF86DGA) */
657 return E_UNEXPECTED;
658 #endif /* defined(HAVE_LIBXXF86DGA) */
661 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
662 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
664 ICOM_THIS(IDirectDrawSurface4Impl,iface);
665 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
666 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
667 if (!This->s.ddraw->d.paintable)
668 return DD_OK;
670 if (!iflipto) {
671 if (This->s.backbuffer)
672 iflipto = This->s.backbuffer;
673 else
674 iflipto = This;
677 Xlib_copy_surface_on_screen(This);
679 if (iflipto->s.palette && iflipto->s.palette->cm) {
680 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
682 if (iflipto!=This) {
683 XImage *tmp;
684 LPVOID *surf;
685 tmp = This->t.xlib.image;
686 This->t.xlib.image = iflipto->t.xlib.image;
687 iflipto->t.xlib.image = tmp;
688 surf = This->s.surface_desc.y.lpSurface;
689 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
690 iflipto->s.surface_desc.y.lpSurface = surf;
692 return DD_OK;
696 /* The IDirectDrawSurface4::SetPalette method attaches the specified
697 * DirectDrawPalette object to a surface. The surface uses this palette for all
698 * subsequent operations. The palette change takes place immediately.
700 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
701 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
703 ICOM_THIS(IDirectDrawSurface4Impl,iface);
704 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
705 int i;
706 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
708 if (ipal == NULL) {
709 if( This->s.palette != NULL )
710 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
711 This->s.palette = ipal;
713 return DD_OK;
716 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
718 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
719 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
721 if (!Options.managed)
722 TSXInstallColormap(display,ipal->cm);
724 for (i=0;i<256;i++) {
725 XColor xc;
727 xc.red = ipal->palents[i].peRed<<8;
728 xc.blue = ipal->palents[i].peBlue<<8;
729 xc.green = ipal->palents[i].peGreen<<8;
730 xc.flags = DoRed|DoBlue|DoGreen;
731 xc.pixel = i;
732 TSXStoreColor(display,ipal->cm,&xc);
734 TSXInstallColormap(display,ipal->cm);
737 /* According to spec, we are only supposed to
738 * AddRef if this is not the same palette.
740 if( This->s.palette != ipal )
742 if( ipal != NULL )
743 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
744 if( This->s.palette != NULL )
745 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
746 This->s.palette = ipal;
748 /* I think that we need to attach it to all backbuffers...*/
749 if( This->s.backbuffer ) {
750 if( This->s.backbuffer->s.palette )
751 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
752 This->s.backbuffer->s.palette = ipal;
753 if( ipal )
754 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
756 /* Perform the refresh */
757 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
759 return DD_OK;
762 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
763 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
765 ICOM_THIS(IDirectDrawSurface4Impl,iface);
766 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
767 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
768 #ifdef HAVE_LIBXXF86DGA
769 /* According to spec, we are only supposed to
770 * AddRef if this is not the same palette.
772 if( This->s.palette != ipal )
774 if( ipal != NULL )
775 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
776 if( This->s.palette != NULL )
777 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
778 This->s.palette = ipal;
780 /* I think that we need to attach it to all backbuffers...*/
781 if( This->s.backbuffer ) {
782 if( This->s.backbuffer->s.palette )
783 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
784 This->s.backbuffer->s.palette = ipal;
785 if ( ipal )
786 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
788 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
790 return DD_OK;
791 #else /* defined(HAVE_LIBXXF86DGA) */
792 return E_UNEXPECTED;
793 #endif /* defined(HAVE_LIBXXF86DGA) */
798 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
800 int x, y;
801 LPBYTE first;
803 /* Do first row */
805 #define COLORFILL_ROW(type) { \
806 type *d = (type *) buf; \
807 for (x = 0; x < width; x++) \
808 d[x] = (type) color; \
809 break; \
812 switch(bpp) {
813 case 1: COLORFILL_ROW(BYTE)
814 case 2: COLORFILL_ROW(WORD)
815 case 4: COLORFILL_ROW(DWORD)
816 default:
817 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
818 return DDERR_UNSUPPORTED;
821 #undef COLORFILL_ROW
823 /* Now copy first row */
824 first = buf;
825 for (y = 1; y < height; y++) {
826 buf += lPitch;
827 memcpy(buf, first, width * bpp);
830 return DD_OK;
833 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
834 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
836 ICOM_THIS(IDirectDrawSurface4Impl,iface);
837 RECT xdst,xsrc;
838 DDSURFACEDESC ddesc,sdesc;
839 HRESULT ret = DD_OK;
840 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
841 int x, y;
842 LPBYTE dbuf, sbuf;
844 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
846 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
847 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
849 if (TRACE_ON(ddraw)) {
850 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
851 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
852 TRACE(ddraw,"\tflags: ");
853 _dump_DDBLT(dwFlags);
854 if (dwFlags & DDBLT_DDFX) {
855 TRACE(ddraw," blitfx: \n");
856 _dump_DDBLTFX(lpbltfx->dwDDFX);
860 if (rdst) {
861 memcpy(&xdst,rdst,sizeof(xdst));
862 } else {
863 xdst.top = 0;
864 xdst.bottom = ddesc.dwHeight;
865 xdst.left = 0;
866 xdst.right = ddesc.dwWidth;
869 if (rsrc) {
870 memcpy(&xsrc,rsrc,sizeof(xsrc));
871 } else {
872 if (src) {
873 xsrc.top = 0;
874 xsrc.bottom = sdesc.dwHeight;
875 xsrc.left = 0;
876 xsrc.right = sdesc.dwWidth;
877 } else {
878 memset(&xsrc,0,sizeof(xsrc));
882 bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
883 srcheight = xsrc.bottom - xsrc.top;
884 srcwidth = xsrc.right - xsrc.left;
885 dstheight = xdst.bottom - xdst.top;
886 dstwidth = xdst.right - xdst.left;
887 width = (xdst.right - xdst.left) * bpp;
888 dbuf = ddesc.y.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
890 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
892 /* First, all the 'source-less' blits */
893 if (dwFlags & DDBLT_COLORFILL) {
894 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
895 ddesc.lPitch, lpbltfx->b.dwFillColor);
896 dwFlags &= ~DDBLT_COLORFILL;
899 if (dwFlags & DDBLT_DEPTHFILL) {
900 #ifdef HAVE_MESAGL
901 GLboolean ztest;
903 /* Clears the screen */
904 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
905 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
906 glGetBooleanv(GL_DEPTH_TEST, &ztest);
907 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
908 glClear(GL_DEPTH_BUFFER_BIT);
909 glDepthMask(ztest);
911 dwFlags &= ~(DDBLT_DEPTHFILL);
912 #endif HAVE_MESAGL
915 if (dwFlags & DDBLT_ROP) {
916 /* Catch some degenerate cases here */
917 switch(lpbltfx->dwROP) {
918 case BLACKNESS:
919 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
920 break;
921 case 0xAA0029: /* No-op */
922 break;
923 case WHITENESS:
924 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
925 break;
926 default:
927 FIXME(ddraw, "Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->b.lpDDSPattern);
928 goto error;
930 dwFlags &= ~DDBLT_ROP;
933 if (dwFlags & DDBLT_DDROPS) {
934 FIXME(ddraw, "\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->b.lpDDSPattern);
937 /* Now the 'with source' blits */
938 if (src) {
939 LPBYTE sbase;
940 int sx, xinc, sy, yinc;
942 sbase = sdesc.y.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
943 xinc = (srcwidth << 16) / dstwidth;
944 yinc = (srcheight << 16) / dstheight;
946 if (!dwFlags) {
948 /* No effects, we can cheat here */
949 if (dstwidth == srcwidth) {
950 if (dstheight == srcheight) {
951 /* No stretching in either direction. This needs to be as fast as possible */
952 sbuf = sbase;
953 for (y = 0; y < dstheight; y++) {
954 memcpy(dbuf, sbuf, width);
955 sbuf += sdesc.lPitch;
956 dbuf += ddesc.lPitch;
958 } else {
959 /* Stretching in Y direction only */
960 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
961 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
962 memcpy(dbuf, sbuf, width);
963 dbuf += ddesc.lPitch;
966 } else {
967 /* Stretching in X direction */
968 int last_sy = -1;
969 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
970 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
972 if ((sy >> 16) == (last_sy >> 16)) {
973 /* Same as last row - copy already stretched row */
974 memcpy(dbuf, dbuf - ddesc.lPitch, width);
975 } else {
977 #define STRETCH_ROW(type) { \
978 type *s = (type *) sbuf, *d = (type *) dbuf; \
979 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
980 d[x] = s[sx >> 16]; \
981 break; \
984 switch(bpp) {
985 case 1: STRETCH_ROW(BYTE)
986 case 2: STRETCH_ROW(WORD)
987 case 4: STRETCH_ROW(DWORD)
988 default:
989 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
990 ret = DDERR_UNSUPPORTED;
991 goto error;
994 #undef STRETCH_ROW
997 last_sy = sy;
998 dbuf += ddesc.lPitch;
1001 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1002 DWORD keylow, keyhigh;
1004 if (dwFlags & DDBLT_KEYSRC) {
1005 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1006 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1007 } else {
1008 /* I'm not sure if this is correct */
1009 FIXME(ddraw, "DDBLT_KEYDEST not fully supported yet.\n");
1010 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1011 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1014 #define COPYROW_COLORKEY(type) { \
1015 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1016 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1017 tmp = s[sx >> 16]; \
1018 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1020 break; \
1023 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1024 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1026 switch (bpp) {
1027 case 1: COPYROW_COLORKEY(BYTE)
1028 case 2: COPYROW_COLORKEY(WORD)
1029 case 4: COPYROW_COLORKEY(DWORD)
1030 default:
1031 FIXME(ddraw, "%s color-keyed blit not implemented for bpp %d!\n",
1032 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1033 ret = DDERR_UNSUPPORTED;
1034 goto error;
1036 dbuf += ddesc.lPitch;
1039 #undef COPYROW_COLORKEY
1041 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1046 error:
1048 if (dwFlags && FIXME_ON(ddraw)) {
1049 FIXME(ddraw,"\tUnsupported flags: ");
1050 _dump_DDBLT(dwFlags);
1053 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1054 if (src) IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1056 return DD_OK;
1059 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1060 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1062 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1063 int bpp, w, h, x, y;
1064 DDSURFACEDESC ddesc,sdesc;
1065 HRESULT ret = DD_OK;
1066 LPBYTE sbuf, dbuf;
1069 if (TRACE_ON(ddraw)) {
1070 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1071 This,dstx,dsty,src,rsrc,trans
1073 FIXME(ddraw," trans:");
1074 if (FIXME_ON(ddraw))
1075 _dump_DDBLTFAST(trans);
1076 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1078 /* We need to lock the surfaces, or we won't get refreshes when done. */
1079 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1080 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1082 bpp = This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
1083 sbuf = sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1084 dbuf = ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1087 h=rsrc->bottom-rsrc->top;
1088 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1089 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1090 if (h<0) h=0;
1092 w=rsrc->right-rsrc->left;
1093 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1094 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1095 if (w<0) w=0;
1097 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1098 DWORD keylow, keyhigh;
1099 if (trans & DDBLTFAST_SRCCOLORKEY) {
1100 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1101 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1102 } else {
1103 /* I'm not sure if this is correct */
1104 FIXME(ddraw, "DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1105 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1106 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1109 #define COPYBOX_COLORKEY(type) { \
1110 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1111 s = sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp; \
1112 d = ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp; \
1113 for (y = 0; y < h; y++) { \
1114 for (x = 0; x < w; x++) { \
1115 tmp = s[x]; \
1116 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1118 (LPBYTE)s += sdesc.lPitch; \
1119 (LPBYTE)d += ddesc.lPitch; \
1121 break; \
1124 switch (bpp) {
1125 case 1: COPYBOX_COLORKEY(BYTE)
1126 case 2: COPYBOX_COLORKEY(WORD)
1127 case 4: COPYBOX_COLORKEY(DWORD)
1128 default:
1129 FIXME(ddraw, "Source color key blitting not supported for bpp %d\n", bpp*8);
1130 ret = DDERR_UNSUPPORTED;
1131 goto error;
1134 #undef COPYBOX_COLORKEY
1136 } else {
1137 int width = w * bpp;
1139 for (y = 0; y < h; y++) {
1140 memcpy(dbuf, sbuf, width);
1141 sbuf += sdesc.lPitch;
1142 dbuf += ddesc.lPitch;
1146 error:
1148 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1149 IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1150 return ret;
1153 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1154 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1156 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1157 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1158 This,ddbltbatch,x,y
1160 return DD_OK;
1163 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1164 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1166 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1167 TRACE(ddraw,"(%p)->GetCaps(%p)\n",This,caps);
1168 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1169 return DD_OK;
1172 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1173 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1174 ) {
1175 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1176 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
1177 This,ddsd);
1179 /* Simply copy the surface description stored in the object */
1180 *ddsd = This->s.surface_desc;
1182 if (TRACE_ON(ddraw)) {
1183 DUMP(" flags: ");
1184 _dump_DDSD(ddsd->dwFlags);
1185 if (ddsd->dwFlags & DDSD_CAPS) {
1186 DUMP(" caps: ");
1187 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
1189 if (ddsd->dwFlags & DDSD_PIXELFORMAT) {
1190 DUMP(" pixel format : \n");
1191 _dump_pixelformat(&(ddsd->ddpfPixelFormat));
1195 return DD_OK;
1198 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1199 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1200 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1202 return ++(This->ref);
1205 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1206 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1207 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1209 #ifdef HAVE_LIBXXF86DGA
1210 if (!--(This->ref)) {
1211 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1212 /* clear out of surface list */
1213 if (This->t.dga.fb_height == -1) {
1214 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1215 } else {
1216 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1219 /* Free the backbuffer */
1220 if (This->s.backbuffer)
1221 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1223 HeapFree(GetProcessHeap(),0,This);
1224 return 0;
1226 #endif /* defined(HAVE_LIBXXF86DGA) */
1227 return This->ref;
1230 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1231 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1232 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1234 if (!--(This->ref)) {
1235 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1237 if( This->s.backbuffer )
1238 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1240 if (This->t.xlib.image != NULL) {
1241 if (This->s.ddraw->d.pixel_convert != NULL) {
1242 /* In pixel conversion mode, there are two buffers to release... */
1243 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1245 #ifdef HAVE_LIBXXSHM
1246 if (This->s.ddraw->e.xlib.xshm_active) {
1247 TSXShmDetach(display, &(This->t.xlib.shminfo));
1248 TSXDestroyImage(This->t.xlib.image);
1249 shmdt(This->t.xlib.shminfo.shmaddr);
1250 } else {
1251 #endif
1252 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1253 This->t.xlib.image->data = NULL;
1254 TSXDestroyImage(This->t.xlib.image);
1255 #ifdef HAVE_LIBXXSHM
1257 #endif
1259 } else {
1260 This->t.xlib.image->data = NULL;
1262 #ifdef HAVE_LIBXXSHM
1263 if (This->s.ddraw->e.xlib.xshm_active) {
1264 TSXShmDetach(display, &(This->t.xlib.shminfo));
1265 TSXDestroyImage(This->t.xlib.image);
1266 shmdt(This->t.xlib.shminfo.shmaddr);
1267 } else {
1268 #endif
1269 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1270 TSXDestroyImage(This->t.xlib.image);
1271 #ifdef HAVE_LIBXXSHM
1273 #endif
1276 This->t.xlib.image = 0;
1277 } else {
1278 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1281 if (This->s.palette)
1282 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1284 HeapFree(GetProcessHeap(),0,This);
1285 return 0;
1288 return This->ref;
1291 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1292 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1294 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1295 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1296 This, lpddsd, lpdsf);
1298 if (TRACE_ON(ddraw)) {
1299 TRACE(ddraw," caps ");
1300 _dump_DDSCAPS(lpddsd->dwCaps);
1303 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1304 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1305 return E_FAIL;
1308 /* FIXME: should handle more than one backbuffer */
1309 *lpdsf = (LPDIRECTDRAWSURFACE4)This->s.backbuffer;
1311 if( This->s.backbuffer )
1312 IDirectDrawSurface4_AddRef( (IDirectDrawSurface4*)This->s.backbuffer );
1314 return DD_OK;
1317 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1318 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1320 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1321 TRACE(ddraw,"(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1323 return DDERR_ALREADYINITIALIZED;
1326 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1327 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1329 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1330 TRACE(ddraw,"(%p)->(%p)\n",This,pf);
1332 *pf = This->s.surface_desc.ddpfPixelFormat;
1334 return DD_OK;
1337 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1338 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1339 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,dwFlags);
1340 return DD_OK;
1343 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1344 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1346 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1347 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,x1,x2);
1348 return DD_OK;
1351 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1352 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1354 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1355 FIXME(ddraw,"(%p)->(%p),stub!\n",This,clipper);
1356 return DD_OK;
1359 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1360 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1362 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1363 FIXME(ddraw,"(%p)->(%p),stub!\n",This,surf);
1365 IDirectDrawSurface4_AddRef(iface);
1367 /* This hack will be enough for the moment */
1368 if (This->s.backbuffer == NULL)
1369 This->s.backbuffer = (IDirectDrawSurface4Impl*)surf;
1370 return DD_OK;
1373 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1374 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1375 FIXME(ddraw,"(%p)->GetDC(%p)\n",This,lphdc);
1376 *lphdc = BeginPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1377 return DD_OK;
1380 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1381 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1382 DDSURFACEDESC desc;
1383 DWORD x, y;
1385 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1386 EndPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1388 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1389 I fill it with 'dummy' values to have something on the screen */
1390 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1391 for (y = 0; y < desc.dwHeight; y++) {
1392 for (x = 0; x < desc.dwWidth; x++) {
1393 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) This + x + y;
1396 IDirectDrawSurface4_Unlock(iface,NULL);
1398 return DD_OK;
1402 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1403 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1404 char xrefiid[50];
1406 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1407 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
1409 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1410 * the same interface. And IUnknown does that too of course.
1412 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1413 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1414 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1415 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1416 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1418 *obj = This;
1419 IDirectDrawSurface4_AddRef(iface);
1421 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1423 return S_OK;
1425 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1427 /* Texture interface */
1428 *obj = d3dtexture2_create(This);
1429 IDirectDrawSurface4_AddRef(iface);
1431 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1433 return S_OK;
1435 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1437 /* Texture interface */
1438 *obj = d3dtexture_create(This);
1439 IDirectDrawSurface4_AddRef(iface);
1441 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1443 return S_OK;
1445 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj))
1447 /* It is the OpenGL Direct3D Device */
1448 IDirectDrawSurface4_AddRef(iface);
1450 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1452 return S_OK;
1455 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
1456 return OLE_E_ENUM_NOMORE;
1459 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1460 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1461 TRACE(ddraw,"(%p)->(), stub!\n",This);
1462 return DD_OK; /* hmm */
1465 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1466 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1467 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,context,esfcb);
1469 /* For the moment, only enumerating the back buffer */
1470 if (This->s.backbuffer != NULL) {
1471 TRACE(ddraw, "Enumerating back-buffer (%p)\n", This->s.backbuffer);
1472 if (esfcb((LPDIRECTDRAWSURFACE) This->s.backbuffer, &(This->s.backbuffer->s.surface_desc), context) == DDENUMRET_CANCEL)
1473 return DD_OK;
1476 return DD_OK;
1479 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1480 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1481 FIXME(ddraw,"(%p)->(),stub!\n",This);
1482 return DD_OK;
1485 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1486 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1488 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1489 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1490 if (TRACE_ON(ddraw)) {
1491 DUMP(" (0x%08lx <-> 0x%08lx) - ",
1492 ckey->dwColorSpaceLowValue,
1493 ckey->dwColorSpaceHighValue);
1494 _dump_colorkeyflag(dwFlags);
1497 /* If this surface was loaded as a texture, call also the texture
1498 SetColorKey callback */
1499 if (This->s.texture) {
1500 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1503 if( dwFlags & DDCKEY_SRCBLT )
1505 dwFlags &= ~DDCKEY_SRCBLT;
1506 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1507 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1510 if( dwFlags & DDCKEY_DESTBLT )
1512 dwFlags &= ~DDCKEY_DESTBLT;
1513 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1514 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1517 if( dwFlags & DDCKEY_SRCOVERLAY )
1519 dwFlags &= ~DDCKEY_SRCOVERLAY;
1520 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1521 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1524 if( dwFlags & DDCKEY_DESTOVERLAY )
1526 dwFlags &= ~DDCKEY_DESTOVERLAY;
1527 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1528 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1531 if( dwFlags )
1533 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1536 return DD_OK;
1540 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1541 LPDIRECTDRAWSURFACE4 iface,
1542 LPRECT lpRect )
1544 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1545 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpRect);
1547 return DD_OK;
1550 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1551 LPDIRECTDRAWSURFACE4 iface,
1552 DWORD dwFlags,
1553 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1555 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1556 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",This,dwFlags,lpDDSAttachedSurface);
1558 return DD_OK;
1561 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1562 LPDIRECTDRAWSURFACE4 iface,
1563 DWORD dwFlags,
1564 LPVOID lpContext,
1565 LPDDENUMSURFACESCALLBACK lpfnCallback )
1567 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1568 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1569 lpContext, lpfnCallback );
1571 return DD_OK;
1574 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1575 LPDIRECTDRAWSURFACE4 iface,
1576 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1578 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1579 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDClipper);
1581 return DD_OK;
1584 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1585 LPDIRECTDRAWSURFACE4 iface,
1586 DWORD dwFlags,
1587 LPDDCOLORKEY lpDDColorKey )
1589 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1590 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1592 if( dwFlags & DDCKEY_SRCBLT ) {
1593 dwFlags &= ~DDCKEY_SRCBLT;
1594 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1597 if( dwFlags & DDCKEY_DESTBLT )
1599 dwFlags &= ~DDCKEY_DESTBLT;
1600 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1603 if( dwFlags & DDCKEY_SRCOVERLAY )
1605 dwFlags &= ~DDCKEY_SRCOVERLAY;
1606 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1609 if( dwFlags & DDCKEY_DESTOVERLAY )
1611 dwFlags &= ~DDCKEY_DESTOVERLAY;
1612 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1615 if( dwFlags )
1617 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1620 return DD_OK;
1623 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1624 LPDIRECTDRAWSURFACE4 iface,
1625 DWORD dwFlags )
1627 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1628 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1630 return DD_OK;
1633 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1634 LPDIRECTDRAWSURFACE4 iface,
1635 LPDIRECTDRAWPALETTE* lplpDDPalette )
1637 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1638 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDPalette);
1640 return DD_OK;
1643 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1644 LPDIRECTDRAWSURFACE4 iface,
1645 LONG lX,
1646 LONG lY)
1648 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1649 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1651 return DD_OK;
1654 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1655 LPDIRECTDRAWSURFACE4 iface,
1656 LPRECT lpSrcRect,
1657 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1658 LPRECT lpDestRect,
1659 DWORD dwFlags,
1660 LPDDOVERLAYFX lpDDOverlayFx )
1662 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1663 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1664 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1666 return DD_OK;
1669 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1670 LPDIRECTDRAWSURFACE4 iface,
1671 DWORD dwFlags )
1673 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1674 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1676 return DD_OK;
1679 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1680 LPDIRECTDRAWSURFACE4 iface,
1681 DWORD dwFlags,
1682 LPDIRECTDRAWSURFACE4 lpDDSReference )
1684 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1685 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1687 return DD_OK;
1690 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1691 LPDIRECTDRAWSURFACE4 iface,
1692 LPVOID* lplpDD )
1694 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1695 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDD);
1697 /* Not sure about that... */
1698 *lplpDD = (void *) This->s.ddraw;
1700 return DD_OK;
1703 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1704 LPDIRECTDRAWSURFACE4 iface,
1705 DWORD dwFlags )
1707 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1708 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1710 return DD_OK;
1713 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1714 LPDIRECTDRAWSURFACE4 iface,
1715 DWORD dwFlags )
1717 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1718 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1720 return DD_OK;
1723 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1724 LPDIRECTDRAWSURFACE4 iface,
1725 LPDDSURFACEDESC lpDDSD,
1726 DWORD dwFlags )
1728 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1729 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1731 return DD_OK;
1734 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1735 REFGUID guidTag,
1736 LPVOID lpData,
1737 DWORD cbSize,
1738 DWORD dwFlags) {
1739 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1740 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1742 return DD_OK;
1745 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1746 REFGUID guidTag,
1747 LPVOID lpBuffer,
1748 LPDWORD lpcbBufferSize) {
1749 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1750 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1752 return DD_OK;
1755 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
1756 REFGUID guidTag) {
1757 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1758 FIXME(ddraw, "(%p)->(%p)\n", This, guidTag);
1760 return DD_OK;
1763 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
1764 LPDWORD lpValue) {
1765 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1766 FIXME(ddraw, "(%p)->(%p)\n", This, lpValue);
1768 return DD_OK;
1771 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
1772 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1773 FIXME(ddraw, "(%p)\n", This);
1775 return DD_OK;
1778 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = {
1779 IDirectDrawSurface4Impl_QueryInterface,
1780 IDirectDrawSurface4Impl_AddRef,
1781 DGA_IDirectDrawSurface4Impl_Release,
1782 IDirectDrawSurface4Impl_AddAttachedSurface,
1783 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1784 IDirectDrawSurface4Impl_Blt,
1785 IDirectDrawSurface4Impl_BltBatch,
1786 IDirectDrawSurface4Impl_BltFast,
1787 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1788 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1789 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1790 DGA_IDirectDrawSurface4Impl_Flip,
1791 IDirectDrawSurface4Impl_GetAttachedSurface,
1792 IDirectDrawSurface4Impl_GetBltStatus,
1793 IDirectDrawSurface4Impl_GetCaps,
1794 IDirectDrawSurface4Impl_GetClipper,
1795 IDirectDrawSurface4Impl_GetColorKey,
1796 IDirectDrawSurface4Impl_GetDC,
1797 IDirectDrawSurface4Impl_GetFlipStatus,
1798 IDirectDrawSurface4Impl_GetOverlayPosition,
1799 IDirectDrawSurface4Impl_GetPalette,
1800 IDirectDrawSurface4Impl_GetPixelFormat,
1801 IDirectDrawSurface4Impl_GetSurfaceDesc,
1802 IDirectDrawSurface4Impl_Initialize,
1803 IDirectDrawSurface4Impl_IsLost,
1804 IDirectDrawSurface4Impl_Lock,
1805 IDirectDrawSurface4Impl_ReleaseDC,
1806 IDirectDrawSurface4Impl_Restore,
1807 IDirectDrawSurface4Impl_SetClipper,
1808 IDirectDrawSurface4Impl_SetColorKey,
1809 IDirectDrawSurface4Impl_SetOverlayPosition,
1810 DGA_IDirectDrawSurface4Impl_SetPalette,
1811 DGA_IDirectDrawSurface4Impl_Unlock,
1812 IDirectDrawSurface4Impl_UpdateOverlay,
1813 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1814 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1815 IDirectDrawSurface4Impl_GetDDInterface,
1816 IDirectDrawSurface4Impl_PageLock,
1817 IDirectDrawSurface4Impl_PageUnlock,
1818 IDirectDrawSurface4Impl_SetSurfaceDesc,
1819 IDirectDrawSurface4Impl_SetPrivateData,
1820 IDirectDrawSurface4Impl_GetPrivateData,
1821 IDirectDrawSurface4Impl_FreePrivateData,
1822 IDirectDrawSurface4Impl_GetUniquenessValue,
1823 IDirectDrawSurface4Impl_ChangeUniquenessValue
1826 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt = {
1827 IDirectDrawSurface4Impl_QueryInterface,
1828 IDirectDrawSurface4Impl_AddRef,
1829 Xlib_IDirectDrawSurface4Impl_Release,
1830 IDirectDrawSurface4Impl_AddAttachedSurface,
1831 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1832 IDirectDrawSurface4Impl_Blt,
1833 IDirectDrawSurface4Impl_BltBatch,
1834 IDirectDrawSurface4Impl_BltFast,
1835 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1836 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1837 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1838 Xlib_IDirectDrawSurface4Impl_Flip,
1839 IDirectDrawSurface4Impl_GetAttachedSurface,
1840 IDirectDrawSurface4Impl_GetBltStatus,
1841 IDirectDrawSurface4Impl_GetCaps,
1842 IDirectDrawSurface4Impl_GetClipper,
1843 IDirectDrawSurface4Impl_GetColorKey,
1844 IDirectDrawSurface4Impl_GetDC,
1845 IDirectDrawSurface4Impl_GetFlipStatus,
1846 IDirectDrawSurface4Impl_GetOverlayPosition,
1847 IDirectDrawSurface4Impl_GetPalette,
1848 IDirectDrawSurface4Impl_GetPixelFormat,
1849 IDirectDrawSurface4Impl_GetSurfaceDesc,
1850 IDirectDrawSurface4Impl_Initialize,
1851 IDirectDrawSurface4Impl_IsLost,
1852 IDirectDrawSurface4Impl_Lock,
1853 IDirectDrawSurface4Impl_ReleaseDC,
1854 IDirectDrawSurface4Impl_Restore,
1855 IDirectDrawSurface4Impl_SetClipper,
1856 IDirectDrawSurface4Impl_SetColorKey,
1857 IDirectDrawSurface4Impl_SetOverlayPosition,
1858 Xlib_IDirectDrawSurface4Impl_SetPalette,
1859 Xlib_IDirectDrawSurface4Impl_Unlock,
1860 IDirectDrawSurface4Impl_UpdateOverlay,
1861 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1862 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1863 IDirectDrawSurface4Impl_GetDDInterface,
1864 IDirectDrawSurface4Impl_PageLock,
1865 IDirectDrawSurface4Impl_PageUnlock,
1866 IDirectDrawSurface4Impl_SetSurfaceDesc,
1867 IDirectDrawSurface4Impl_SetPrivateData,
1868 IDirectDrawSurface4Impl_GetPrivateData,
1869 IDirectDrawSurface4Impl_FreePrivateData,
1870 IDirectDrawSurface4Impl_GetUniquenessValue,
1871 IDirectDrawSurface4Impl_ChangeUniquenessValue
1874 /******************************************************************************
1875 * DirectDrawCreateClipper (DDRAW.7)
1877 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1878 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1879 LPUNKNOWN pUnkOuter)
1881 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
1882 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
1884 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
1885 (*ilplpDDClipper)->lpvtbl = &ddclipvt;
1886 (*ilplpDDClipper)->ref = 1;
1888 return DD_OK;
1891 /******************************************************************************
1892 * IDirectDrawClipper
1894 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
1895 LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
1897 ICOM_THIS(IDirectDrawClipperImpl,iface);
1898 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
1899 return DD_OK;
1902 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
1903 ICOM_THIS(IDirectDrawClipperImpl,iface);
1904 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1906 This->ref--;
1907 if (This->ref)
1908 return This->ref;
1909 HeapFree(GetProcessHeap(),0,This);
1910 return 0;
1913 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
1914 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
1916 ICOM_THIS(IDirectDrawClipperImpl,iface);
1917 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
1918 if (hmm) *hmm=0;
1919 return DD_OK;
1922 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
1923 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
1925 ICOM_THIS(IDirectDrawClipperImpl,iface);
1926 FIXME(ddraw,"(%p,%p,%ld),stub!\n",This,lprgn,hmm);
1927 return DD_OK;
1930 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
1931 LPDIRECTDRAWCLIPPER iface,
1932 REFIID riid,
1933 LPVOID* ppvObj )
1935 ICOM_THIS(IDirectDrawClipperImpl,iface);
1936 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
1937 return OLE_E_ENUM_NOMORE;
1940 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
1942 ICOM_THIS(IDirectDrawClipperImpl,iface);
1943 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1944 return ++(This->ref);
1947 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
1948 LPDIRECTDRAWCLIPPER iface,
1949 HWND* HWndPtr )
1951 ICOM_THIS(IDirectDrawClipperImpl,iface);
1952 FIXME(ddraw,"(%p)->(%p),stub!\n",This,HWndPtr);
1953 return DD_OK;
1956 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
1957 LPDIRECTDRAWCLIPPER iface,
1958 LPDIRECTDRAW lpDD,
1959 DWORD dwFlags )
1961 ICOM_THIS(IDirectDrawClipperImpl,iface);
1962 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
1963 return DD_OK;
1966 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
1967 LPDIRECTDRAWCLIPPER iface,
1968 BOOL* lpbChanged )
1970 ICOM_THIS(IDirectDrawClipperImpl,iface);
1971 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpbChanged);
1972 return DD_OK;
1975 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt = {
1976 IDirectDrawClipperImpl_QueryInterface,
1977 IDirectDrawClipperImpl_AddRef,
1978 IDirectDrawClipperImpl_Release,
1979 IDirectDrawClipperImpl_GetClipList,
1980 IDirectDrawClipperImpl_GetHWnd,
1981 IDirectDrawClipperImpl_Initialize,
1982 IDirectDrawClipperImpl_IsClipListChanged,
1983 IDirectDrawClipperImpl_SetClipList,
1984 IDirectDrawClipperImpl_SetHwnd
1988 /******************************************************************************
1989 * IDirectDrawPalette
1991 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
1992 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1994 ICOM_THIS(IDirectDrawPaletteImpl,iface);
1995 int i;
1997 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1998 This,x,start,count,palent);
2000 if (!This->cm) /* should not happen */ {
2001 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
2002 return DDERR_GENERIC;
2004 for (i=0;i<count;i++) {
2005 palent[i].peRed = This->palents[start+i].peRed;
2006 palent[i].peBlue = This->palents[start+i].peBlue;
2007 palent[i].peGreen = This->palents[start+i].peGreen;
2008 palent[i].peFlags = This->palents[start+i].peFlags;
2011 return DD_OK;
2014 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2015 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2017 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2018 XColor xc;
2019 int i;
2021 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2022 This,x,start,count,palent
2024 for (i=0;i<count;i++) {
2025 xc.red = palent[i].peRed<<8;
2026 xc.blue = palent[i].peBlue<<8;
2027 xc.green = palent[i].peGreen<<8;
2028 xc.flags = DoRed|DoBlue|DoGreen;
2029 xc.pixel = start+i;
2031 if (This->cm)
2032 TSXStoreColor(display,This->cm,&xc);
2034 This->palents[start+i].peRed = palent[i].peRed;
2035 This->palents[start+i].peBlue = palent[i].peBlue;
2036 This->palents[start+i].peGreen = palent[i].peGreen;
2037 This->palents[start+i].peFlags = palent[i].peFlags;
2040 /* Now, if we are in 'depth conversion mode', update the screen palette */
2041 if (This->ddraw->d.palette_convert != NULL)
2042 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2044 return DD_OK;
2047 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2048 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2050 #ifdef HAVE_LIBXXF86DGA
2051 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2052 XColor xc;
2053 Colormap cm;
2054 int i;
2056 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2057 This,x,start,count,palent
2059 if (!This->cm) /* should not happen */ {
2060 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
2061 return DDERR_GENERIC;
2063 /* FIXME: free colorcells instead of freeing whole map */
2064 cm = This->cm;
2065 This->cm = TSXCopyColormapAndFree(display,This->cm);
2066 TSXFreeColormap(display,cm);
2068 for (i=0;i<count;i++) {
2069 xc.red = palent[i].peRed<<8;
2070 xc.blue = palent[i].peBlue<<8;
2071 xc.green = palent[i].peGreen<<8;
2072 xc.flags = DoRed|DoBlue|DoGreen;
2073 xc.pixel = i+start;
2075 TSXStoreColor(display,This->cm,&xc);
2077 This->palents[start+i].peRed = palent[i].peRed;
2078 This->palents[start+i].peBlue = palent[i].peBlue;
2079 This->palents[start+i].peGreen = palent[i].peGreen;
2080 This->palents[start+i].peFlags = palent[i].peFlags;
2082 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2083 return DD_OK;
2084 #else /* defined(HAVE_LIBXXF86DGA) */
2085 return E_UNEXPECTED;
2086 #endif /* defined(HAVE_LIBXXF86DGA) */
2089 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2090 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2091 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2092 if (!--(This->ref)) {
2093 if (This->cm) {
2094 TSXFreeColormap(display,This->cm);
2095 This->cm = 0;
2097 HeapFree(GetProcessHeap(),0,This);
2098 return 0;
2100 return This->ref;
2103 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2104 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2106 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2107 return ++(This->ref);
2110 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2111 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2113 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2114 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2116 return DDERR_ALREADYINITIALIZED;
2119 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2120 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2122 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2123 FIXME( ddraw, "(%p)->(%p) stub.\n", This, lpdwCaps );
2124 return DD_OK;
2127 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2128 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2130 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2131 char xrefiid[50];
2133 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2134 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2136 return S_OK;
2139 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt = {
2140 IDirectDrawPaletteImpl_QueryInterface,
2141 IDirectDrawPaletteImpl_AddRef,
2142 IDirectDrawPaletteImpl_Release,
2143 IDirectDrawPaletteImpl_GetCaps,
2144 IDirectDrawPaletteImpl_GetEntries,
2145 IDirectDrawPaletteImpl_Initialize,
2146 DGA_IDirectDrawPaletteImpl_SetEntries
2149 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt = {
2150 IDirectDrawPaletteImpl_QueryInterface,
2151 IDirectDrawPaletteImpl_AddRef,
2152 IDirectDrawPaletteImpl_Release,
2153 IDirectDrawPaletteImpl_GetCaps,
2154 IDirectDrawPaletteImpl_GetEntries,
2155 IDirectDrawPaletteImpl_Initialize,
2156 Xlib_IDirectDrawPaletteImpl_SetEntries
2159 /*******************************************************************************
2160 * IDirect3D
2162 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2163 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2165 ICOM_THIS(IDirect3DImpl,iface);
2166 /* FIXME: Not sure if this is correct */
2167 char xrefiid[50];
2169 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2170 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2171 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2172 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2173 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2174 *obj = This->ddraw;
2175 IDirect3D_AddRef(iface);
2177 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2179 return S_OK;
2181 if ((!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) ||
2182 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2183 *obj = This;
2184 IDirect3D_AddRef(iface);
2186 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2188 return S_OK;
2190 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
2191 IDirect3D2Impl* d3d;
2193 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2194 d3d->ref = 1;
2195 d3d->ddraw = This->ddraw;
2196 IDirect3D_AddRef(iface);
2197 d3d->lpvtbl = &d3d2vt;
2198 *obj = d3d;
2200 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2202 return S_OK;
2204 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2205 return OLE_E_ENUM_NOMORE;
2208 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2209 ICOM_THIS(IDirect3DImpl,iface);
2210 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2212 return ++(This->ref);
2215 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2217 ICOM_THIS(IDirect3DImpl,iface);
2218 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2220 if (!--(This->ref)) {
2221 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2222 HeapFree(GetProcessHeap(),0,This);
2223 return 0;
2225 return This->ref;
2228 static HRESULT WINAPI IDirect3DImpl_Initialize(
2229 LPDIRECT3D iface, REFIID refiid )
2231 ICOM_THIS(IDirect3DImpl,iface);
2232 /* FIXME: Not sure if this is correct */
2233 char xrefiid[50];
2235 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2236 FIXME(ddraw,"(%p)->(%s):stub.\n",This,xrefiid);
2238 return DDERR_ALREADYINITIALIZED;
2241 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2242 LPD3DENUMDEVICESCALLBACK cb,
2243 LPVOID context) {
2244 ICOM_THIS(IDirect3DImpl,iface);
2245 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2247 /* Call functions defined in d3ddevices.c */
2248 if (!d3d_OpenGL_dx3(cb, context))
2249 return DD_OK;
2251 return DD_OK;
2254 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2255 LPDIRECT3DLIGHT *lplight,
2256 IUnknown *lpunk)
2258 ICOM_THIS(IDirect3DImpl,iface);
2259 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2261 /* Call the creation function that is located in d3dlight.c */
2262 *lplight = d3dlight_create_dx3(This);
2264 return DD_OK;
2267 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2268 LPDIRECT3DMATERIAL *lpmaterial,
2269 IUnknown *lpunk)
2271 ICOM_THIS(IDirect3DImpl,iface);
2272 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2274 /* Call the creation function that is located in d3dviewport.c */
2275 *lpmaterial = d3dmaterial_create(This);
2277 return DD_OK;
2280 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2281 LPDIRECT3DVIEWPORT *lpviewport,
2282 IUnknown *lpunk)
2284 ICOM_THIS(IDirect3DImpl,iface);
2285 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2287 /* Call the creation function that is located in d3dviewport.c */
2288 *lpviewport = d3dviewport_create(This);
2290 return DD_OK;
2293 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2294 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2295 LPD3DFINDDEVICERESULT lpfinddevrst)
2297 ICOM_THIS(IDirect3DImpl,iface);
2298 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2300 return DD_OK;
2303 static ICOM_VTABLE(IDirect3D) d3dvt = {
2304 IDirect3DImpl_QueryInterface,
2305 IDirect3DImpl_AddRef,
2306 IDirect3DImpl_Release,
2307 IDirect3DImpl_Initialize,
2308 IDirect3DImpl_EnumDevices,
2309 IDirect3DImpl_CreateLight,
2310 IDirect3DImpl_CreateMaterial,
2311 IDirect3DImpl_CreateViewport,
2312 IDirect3DImpl_FindDevice
2315 /*******************************************************************************
2316 * IDirect3D2
2318 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2319 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2320 ICOM_THIS(IDirect3D2Impl,iface);
2322 /* FIXME: Not sure if this is correct */
2323 char xrefiid[50];
2325 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2326 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2327 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2328 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2329 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2330 *obj = This->ddraw;
2331 IDirect3D2_AddRef(iface);
2333 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2335 return S_OK;
2337 if ((!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) ||
2338 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2339 *obj = This;
2340 IDirect3D2_AddRef(iface);
2342 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2344 return S_OK;
2346 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2347 IDirect3DImpl* d3d;
2349 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2350 d3d->ref = 1;
2351 d3d->ddraw = This->ddraw;
2352 IDirect3D2_AddRef(iface);
2353 d3d->lpvtbl = &d3dvt;
2354 *obj = d3d;
2356 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2358 return S_OK;
2360 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2361 return OLE_E_ENUM_NOMORE;
2364 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2365 ICOM_THIS(IDirect3D2Impl,iface);
2366 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2368 return ++(This->ref);
2371 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2372 ICOM_THIS(IDirect3D2Impl,iface);
2373 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2375 if (!--(This->ref)) {
2376 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2377 HeapFree(GetProcessHeap(),0,This);
2378 return 0;
2380 return This->ref;
2383 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2384 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2386 ICOM_THIS(IDirect3D2Impl,iface);
2387 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2389 /* Call functions defined in d3ddevices.c */
2390 if (!d3d_OpenGL(cb, context))
2391 return DD_OK;
2393 return DD_OK;
2396 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2397 LPDIRECT3DLIGHT *lplight,
2398 IUnknown *lpunk)
2400 ICOM_THIS(IDirect3D2Impl,iface);
2401 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2403 /* Call the creation function that is located in d3dlight.c */
2404 *lplight = d3dlight_create(This);
2406 return DD_OK;
2409 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2410 LPDIRECT3DMATERIAL2 *lpmaterial,
2411 IUnknown *lpunk)
2413 ICOM_THIS(IDirect3D2Impl,iface);
2414 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2416 /* Call the creation function that is located in d3dviewport.c */
2417 *lpmaterial = d3dmaterial2_create(This);
2419 return DD_OK;
2422 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2423 LPDIRECT3DVIEWPORT2 *lpviewport,
2424 IUnknown *lpunk)
2426 ICOM_THIS(IDirect3D2Impl,iface);
2427 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2429 /* Call the creation function that is located in d3dviewport.c */
2430 *lpviewport = d3dviewport2_create(This);
2432 return DD_OK;
2435 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2436 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2437 LPD3DFINDDEVICERESULT lpfinddevrst)
2439 ICOM_THIS(IDirect3D2Impl,iface);
2440 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2442 return DD_OK;
2445 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2446 REFCLSID rguid,
2447 LPDIRECTDRAWSURFACE surface,
2448 LPDIRECT3DDEVICE2 *device)
2450 ICOM_THIS(IDirect3D2Impl,iface);
2451 char xbuf[50];
2453 WINE_StringFromCLSID(rguid,xbuf);
2454 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2456 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2457 IDirect3D2_AddRef(iface);
2458 return DD_OK;
2461 return DDERR_INVALIDPARAMS;
2464 static ICOM_VTABLE(IDirect3D2) d3d2vt = {
2465 IDirect3D2Impl_QueryInterface,
2466 IDirect3D2Impl_AddRef,
2467 IDirect3D2Impl_Release,
2468 IDirect3D2Impl_EnumDevices,
2469 IDirect3D2Impl_CreateLight,
2470 IDirect3D2Impl_CreateMaterial,
2471 IDirect3D2Impl_CreateViewport,
2472 IDirect3D2Impl_FindDevice,
2473 IDirect3D2Impl_CreateDevice
2476 /*******************************************************************************
2477 * IDirectDraw
2480 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2481 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2483 static INT ddrawXlibThisOffset = 0;
2485 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2486 LPDDSURFACEDESC lpddsd,
2487 IDirectDrawSurfaceImpl* lpdsf)
2489 int bpp;
2491 /* The surface was already allocated when entering in this function */
2492 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2494 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2495 /* This is a Z Buffer */
2496 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2497 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2498 } else {
2499 /* This is a standard image */
2500 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2501 /* No pixel format => use DirectDraw's format */
2502 lpddsd->ddpfPixelFormat = This->d.directdraw_pixelformat;
2503 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2504 } else {
2505 /* To check what the program wants */
2506 if (TRACE_ON(ddraw)) {
2507 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2511 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2512 bpp = 1;
2513 } else {
2514 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2518 /* Copy the surface description */
2519 lpdsf->s.surface_desc = *lpddsd;
2521 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2522 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2523 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2525 return DD_OK;
2528 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2529 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2531 #ifdef HAVE_LIBXXF86DGA
2532 ICOM_THIS(IDirectDraw2Impl,iface);
2533 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2534 int i;
2536 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2537 if (TRACE_ON(ddraw)) {
2538 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2539 _dump_DDSD(lpddsd->dwFlags);
2540 DUMP(" caps ");
2541 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2544 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2545 IDirectDraw2_AddRef(iface);
2547 (*ilpdsf)->ref = 1;
2548 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2549 (*ilpdsf)->s.ddraw = This;
2550 (*ilpdsf)->s.palette = NULL;
2551 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2553 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2554 lpddsd->dwWidth = This->d.width;
2555 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2556 lpddsd->dwHeight = This->d.height;
2558 /* Check if this a 'primary surface' or not */
2559 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2560 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2562 /* This is THE primary surface => there is DGA-specific code */
2563 /* First, store the surface description */
2564 (*ilpdsf)->s.surface_desc = *lpddsd;
2566 /* Find a viewport */
2567 for (i=0;i<32;i++)
2568 if (!(This->e.dga.vpmask & (1<<i)))
2569 break;
2570 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2571 /* if i == 32 or maximum ... return error */
2572 This->e.dga.vpmask|=(1<<i);
2573 (*ilpdsf)->s.surface_desc.y.lpSurface =
2574 This->e.dga.fb_addr+((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2575 (*ilpdsf)->t.dga.fb_height = i*This->e.dga.fb_height;
2576 (*ilpdsf)->s.surface_desc.lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
2577 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch;
2579 /* Add flags if there were not present */
2580 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2581 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2582 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2583 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2584 /* We put our surface always in video memory */
2585 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2586 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2587 (*ilpdsf)->s.backbuffer = NULL;
2589 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2590 IDirectDrawSurface4Impl* back;
2592 if (lpddsd->dwBackBufferCount>1)
2593 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2595 (*ilpdsf)->s.backbuffer = back =
2596 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2597 IDirectDraw2_AddRef(iface);
2598 back->ref = 1;
2599 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2600 for (i=0;i<32;i++)
2601 if (!(This->e.dga.vpmask & (1<<i)))
2602 break;
2603 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2604 /* if i == 32 or maximum ... return error */
2605 This->e.dga.vpmask|=(1<<i);
2606 back->t.dga.fb_height = i*This->e.dga.fb_height;
2608 /* Copy the surface description from the front buffer */
2609 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2610 /* Change the parameters that are not the same */
2611 back->s.surface_desc.y.lpSurface = This->e.dga.fb_addr+
2612 ((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2613 back->s.ddraw = This;
2614 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2615 * one! */
2617 /* Add relevant info to front and back buffers */
2618 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2619 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2620 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2621 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2622 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2624 } else {
2625 /* There is no DGA-specific code here...
2626 Go to the common surface creation function */
2627 return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2630 return DD_OK;
2631 #else /* defined(HAVE_LIBXXF86DGA) */
2632 return E_UNEXPECTED;
2633 #endif /* defined(HAVE_LIBXXF86DGA) */
2636 #ifdef HAVE_LIBXXSHM
2637 /* Error handlers for Image creation */
2638 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2639 XShmErrorFlag = 1;
2640 return 0;
2643 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2644 XImage *img;
2645 int (*WineXHandler)(Display *, XErrorEvent *);
2647 img = TSXShmCreateImage(display,
2648 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2649 This->d.pixmap_depth,
2650 ZPixmap,
2651 NULL,
2652 &(lpdsf->t.xlib.shminfo),
2653 lpdsf->s.surface_desc.dwWidth,
2654 lpdsf->s.surface_desc.dwHeight);
2656 if (img == NULL) {
2657 MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2658 This->e.xlib.xshm_active = 0;
2659 return NULL;
2662 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2663 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2664 MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2665 This->e.xlib.xshm_active = 0;
2666 TSXDestroyImage(img);
2667 return NULL;
2670 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2672 if (img->data == (char *) -1) {
2673 MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2674 This->e.xlib.xshm_active = 0;
2675 TSXDestroyImage(img);
2676 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2677 return NULL;
2679 lpdsf->t.xlib.shminfo.readOnly = False;
2681 /* This is where things start to get trickier....
2682 First, we flush the current X connections to be sure to catch all non-XShm related
2683 errors */
2684 TSXSync(display, False);
2685 /* Then we enter in the non-thread safe part of the tests */
2686 EnterCriticalSection( &X11DRV_CritSection );
2688 /* Reset the error flag, sets our new error handler and try to attach the surface */
2689 XShmErrorFlag = 0;
2690 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2691 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2692 XSync(display, False);
2694 /* Check the error flag */
2695 if (XShmErrorFlag) {
2696 /* An error occured */
2697 XFlush(display);
2698 XShmErrorFlag = 0;
2699 XDestroyImage(img);
2700 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2701 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2702 XSetErrorHandler(WineXHandler);
2704 MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
2705 This->e.xlib.xshm_active = 0;
2707 /* Leave the critical section */
2708 LeaveCriticalSection( &X11DRV_CritSection );
2710 return NULL;
2713 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2714 but it may be a bit overkill.... */
2715 XSetErrorHandler(WineXHandler);
2716 LeaveCriticalSection( &X11DRV_CritSection );
2718 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2720 if (This->d.pixel_convert != NULL) {
2721 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2722 lpdsf->s.surface_desc.dwWidth *
2723 lpdsf->s.surface_desc.dwHeight *
2724 (This->d.directdraw_pixelformat.x.dwRGBBitCount));
2725 } else {
2726 lpdsf->s.surface_desc.y.lpSurface = img->data;
2729 return img;
2731 #endif /* HAVE_LIBXXSHM */
2733 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2734 XImage *img = NULL;
2735 void *img_data;
2737 #ifdef HAVE_LIBXXSHM
2738 if (This->e.xlib.xshm_active) {
2739 img = create_xshmimage(This, lpdsf);
2742 if (img == NULL) {
2743 #endif
2744 /* Allocate surface memory */
2745 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2746 lpdsf->s.surface_desc.dwWidth *
2747 lpdsf->s.surface_desc.dwHeight *
2748 (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8));
2750 if (This->d.pixel_convert != NULL) {
2751 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2752 lpdsf->s.surface_desc.dwWidth *
2753 lpdsf->s.surface_desc.dwHeight *
2754 (This->d.screen_pixelformat.x.dwRGBBitCount / 8));
2755 } else {
2756 img_data = lpdsf->s.surface_desc.y.lpSurface;
2759 /* In this case, create an XImage */
2760 img =
2761 TSXCreateImage(display,
2762 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2763 This->d.pixmap_depth,
2764 ZPixmap,
2766 img_data,
2767 lpdsf->s.surface_desc.dwWidth,
2768 lpdsf->s.surface_desc.dwHeight,
2770 lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
2773 #ifdef HAVE_LIBXXSHM
2775 #endif
2776 if (This->d.pixel_convert != NULL) {
2777 lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
2778 } else {
2779 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2782 return img;
2785 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
2786 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2788 ICOM_THIS(IDirectDraw2Impl,iface);
2789 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2790 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2791 This,lpddsd,ilpdsf,lpunk);
2793 if (TRACE_ON(ddraw)) {
2794 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2795 _dump_DDSD(lpddsd->dwFlags);
2796 DUMP(" caps ");
2797 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2800 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2802 IDirectDraw2_AddRef(iface);
2803 (*ilpdsf)->s.ddraw = This;
2804 (*ilpdsf)->ref = 1;
2805 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
2806 (*ilpdsf)->s.palette = NULL;
2807 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2809 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2810 lpddsd->dwWidth = This->d.width;
2811 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2812 lpddsd->dwHeight = This->d.height;
2814 /* Check if this a 'primary surface' or not */
2815 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2816 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2817 XImage *img;
2819 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *ilpdsf);
2821 /* First, store the surface description */
2822 (*ilpdsf)->s.surface_desc = *lpddsd;
2824 /* Create the XImage */
2825 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
2826 if (img == NULL)
2827 return DDERR_OUTOFMEMORY;
2828 (*ilpdsf)->t.xlib.image = img;
2830 /* Add flags if there were not present */
2831 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2832 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2833 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2834 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2835 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2836 (*ilpdsf)->s.backbuffer = NULL;
2838 /* Check for backbuffers */
2839 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2840 IDirectDrawSurface4Impl* back;
2841 XImage *img;
2843 if (lpddsd->dwBackBufferCount>1)
2844 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2846 (*ilpdsf)->s.backbuffer = back =
2847 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2849 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2851 IDirectDraw2_AddRef(iface);
2852 back->s.ddraw = This;
2854 back->ref = 1;
2855 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
2856 /* Copy the surface description from the front buffer */
2857 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2859 /* Create the XImage */
2860 img = create_ximage(This, back);
2861 if (img == NULL)
2862 return DDERR_OUTOFMEMORY;
2863 back->t.xlib.image = img;
2865 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2866 * one! */
2868 /* Add relevant info to front and back buffers */
2869 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2870 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2871 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2872 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2873 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2875 } else {
2876 /* There is no Xlib-specific code here...
2877 Go to the common surface creation function */
2878 return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2881 return DD_OK;
2884 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
2885 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2887 ICOM_THIS(IDirectDraw2Impl,iface);
2888 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",This,src,dst);
2889 *dst = src; /* FIXME */
2890 return DD_OK;
2894 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2895 * even when the approbiate bitmasks are not specified.
2897 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
2898 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
2900 ICOM_THIS(IDirectDraw2Impl,iface);
2901 int i;
2902 const struct {
2903 int mask;
2904 char *name;
2905 } flagmap[] = {
2906 FE(DDSCL_FULLSCREEN)
2907 FE(DDSCL_ALLOWREBOOT)
2908 FE(DDSCL_NOWINDOWCHANGES)
2909 FE(DDSCL_NORMAL)
2910 FE(DDSCL_ALLOWMODEX)
2911 FE(DDSCL_EXCLUSIVE)
2912 FE(DDSCL_SETFOCUSWINDOW)
2913 FE(DDSCL_SETDEVICEWINDOW)
2914 FE(DDSCL_CREATEDEVICEWINDOW)
2917 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
2918 if(TRACE_ON(ddraw)){
2919 dbg_decl_str(ddraw, 512);
2920 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2921 if (flagmap[i].mask & cooplevel)
2922 dsprintf(ddraw, "%s ", flagmap[i].name);
2923 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2925 This->d.mainWindow = hwnd;
2927 /* This will be overwritten in the case of Full Screen mode.
2928 Windowed games could work with that :-) */
2929 if (hwnd)
2931 WND *tmpWnd = WIN_FindWndPtr(hwnd);
2932 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
2933 WIN_ReleaseWndPtr(tmpWnd);
2936 return DD_OK;
2939 /* Small helper to either use the cooperative window or create a new
2940 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2942 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
2943 RECT rect;
2945 /* Do not destroy the application supplied cooperative window */
2946 if (This->d.window && This->d.window != This->d.mainWindow) {
2947 DestroyWindow(This->d.window);
2948 This->d.window = 0;
2950 /* Sanity check cooperative window before assigning it to drawing. */
2951 if ( IsWindow(This->d.mainWindow) &&
2952 IsWindowVisible(This->d.mainWindow)
2954 GetWindowRect(This->d.mainWindow,&rect);
2955 if (((rect.right-rect.left) >= This->d.width) &&
2956 ((rect.bottom-rect.top) >= This->d.height)
2958 This->d.window = This->d.mainWindow;
2960 /* ... failed, create new one. */
2961 if (!This->d.window) {
2962 This->d.window = CreateWindowExA(
2964 "WINE_DirectDraw",
2965 "WINE_DirectDraw",
2966 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2967 0,0,
2968 This->d.width,
2969 This->d.height,
2973 NULL
2975 /*Store THIS with the window. We'll use it in the window procedure*/
2976 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
2977 ShowWindow(This->d.window,TRUE);
2978 UpdateWindow(This->d.window);
2980 SetFocus(This->d.window);
2983 static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
2984 XVisualInfo *vi;
2985 XPixmapFormatValues *pf;
2986 XVisualInfo vt;
2987 int nvisuals, npixmap, i;
2988 int match = 0;
2990 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
2991 pf = XListPixmapFormats(display, &npixmap);
2993 for (i = 0; i < npixmap; i++) {
2994 if (pf[i].bits_per_pixel == depth) {
2995 int j;
2997 for (j = 0; j < nvisuals; j++) {
2998 if (vi[j].depth == pf[i].depth) {
2999 pixelformat->dwSize = sizeof(*pixelformat);
3000 if (depth == 8) {
3001 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3002 pixelformat->y.dwRBitMask = 0;
3003 pixelformat->z.dwGBitMask = 0;
3004 pixelformat->xx.dwBBitMask = 0;
3005 } else {
3006 pixelformat->dwFlags = DDPF_RGB;
3007 pixelformat->y.dwRBitMask = vi[j].red_mask;
3008 pixelformat->z.dwGBitMask = vi[j].green_mask;
3009 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3011 pixelformat->dwFourCC = 0;
3012 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3013 pixelformat->xy.dwRGBAlphaBitMask= 0;
3015 *screen_pixelformat = *pixelformat;
3017 if (pix_depth != NULL)
3018 *pix_depth = vi[j].depth;
3020 match = 1;
3022 break;
3026 if (j == nvisuals)
3027 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3031 if ((match == 0) && (depth == 8)) {
3032 pixelformat->dwSize = sizeof(*pixelformat);
3033 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3034 pixelformat->dwFourCC = 0;
3035 pixelformat->x.dwRGBBitCount = 8;
3036 pixelformat->y.dwRBitMask = 0;
3037 pixelformat->z.dwGBitMask = 0;
3038 pixelformat->xx.dwBBitMask = 0;
3039 pixelformat->xy.dwRGBAlphaBitMask= 0;
3041 /* In that case, find a visual to emulate the 8 bpp format */
3042 for (i = 0; i < npixmap; i++) {
3043 if (pf[i].bits_per_pixel >= depth) {
3044 int j;
3046 for (j = 0; j < nvisuals; j++) {
3047 if (vi[j].depth == pf[i].depth) {
3048 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3049 screen_pixelformat->dwFlags = DDPF_RGB;
3050 screen_pixelformat->dwFourCC = 0;
3051 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3052 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
3053 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
3054 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3055 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
3057 if (pix_depth != NULL)
3058 *pix_depth = vi[j].depth;
3060 match = 2;
3062 break;
3066 if (j == nvisuals)
3067 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3072 TSXFree(vi);
3073 TSXFree(pf);
3075 return match;
3078 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3079 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3081 #ifdef HAVE_LIBXXF86DGA
3082 ICOM_THIS(IDirectDrawImpl,iface);
3083 int i,mode_count;
3085 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3087 /* We hope getting the asked for depth */
3088 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != 1) {
3089 /* I.e. no visual found or emulated */
3090 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3091 return DDERR_UNSUPPORTEDMODE;
3094 if (This->d.width < width) {
3095 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3096 return DDERR_UNSUPPORTEDMODE;
3098 This->d.width = width;
3099 This->d.height = height;
3101 /* adjust fb_height, so we don't overlap */
3102 if (This->e.dga.fb_height < height)
3103 This->e.dga.fb_height = height;
3104 _common_IDirectDrawImpl_SetDisplayMode(This);
3106 #ifdef HAVE_LIBXXF86VM
3108 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3109 XF86VidModeModeLine mod_tmp;
3110 /* int dotclock_tmp; */
3112 /* save original video mode and set fullscreen if available*/
3113 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3114 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3115 orig_mode->hdisplay = mod_tmp.hdisplay;
3116 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3117 orig_mode->hsyncend = mod_tmp.hsyncend;
3118 orig_mode->htotal = mod_tmp.htotal;
3119 orig_mode->vdisplay = mod_tmp.vdisplay;
3120 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3121 orig_mode->vsyncend = mod_tmp.vsyncend;
3122 orig_mode->vtotal = mod_tmp.vtotal;
3123 orig_mode->flags = mod_tmp.flags;
3124 orig_mode->private = mod_tmp.private;
3126 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3127 for (i=0;i<mode_count;i++)
3129 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3131 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3132 *vidmode = *(all_modes[i]);
3133 break;
3134 } else
3135 TSXFree(all_modes[i]->private);
3137 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3138 TSXFree(all_modes);
3140 if (!vidmode)
3141 WARN(ddraw, "Fullscreen mode not available!\n");
3143 if (vidmode)
3145 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3146 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3147 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3148 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3149 #endif
3152 #endif
3154 /* FIXME: this function OVERWRITES several signal handlers.
3155 * can we save them? and restore them later? In a way that
3156 * it works for the library too?
3158 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3159 #ifdef DIABLO_HACK
3160 TSXF86DGASetViewPort(display,DefaultScreen(display),0,This->e.dga.fb_height);
3161 #else
3162 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3163 #endif
3165 #ifdef RESTORE_SIGNALS
3166 SIGNAL_InitHandlers();
3167 #endif
3168 return DD_OK;
3169 #else /* defined(HAVE_LIBXXF86DGA) */
3170 return E_UNEXPECTED;
3171 #endif /* defined(HAVE_LIBXXF86DGA) */
3174 /* *************************************
3175 16 / 15 bpp to palettized 8 bpp
3176 ************************************* */
3177 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3178 unsigned char *c_src = (unsigned char *) src;
3179 unsigned short *c_dst = (unsigned short *) dst;
3180 int x, y;
3182 if (palette != NULL) {
3183 unsigned short *pal = (unsigned short *) palette->screen_palents;
3185 for (y = 0; y < height; y++) {
3186 for (x = 0; x < width; x++) {
3187 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3190 } else {
3191 WARN(ddraw, "No palette set...\n");
3192 memset(dst, 0, width * height * 2);
3195 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3196 int i;
3197 unsigned short *pal = (unsigned short *) screen_palette;
3199 for (i = 0; i < count; i++)
3200 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3201 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3202 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3204 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3205 int i;
3206 unsigned short *pal = (unsigned short *) screen_palette;
3208 for (i = 0; i < count; i++)
3209 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3210 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3211 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3214 /* *************************************
3215 24 / 32 bpp to palettized 8 bpp
3216 ************************************* */
3217 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3218 unsigned char *c_src = (unsigned char *) src;
3219 unsigned int *c_dst = (unsigned int *) dst;
3220 int x, y;
3222 if (palette != NULL) {
3223 unsigned int *pal = (unsigned int *) palette->screen_palents;
3225 for (y = 0; y < height; y++) {
3226 for (x = 0; x < width; x++) {
3227 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3230 } else {
3231 WARN(ddraw, "No palette set...\n");
3232 memset(dst, 0, width * height * 4);
3235 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3236 int i;
3237 unsigned int *pal = (unsigned int *) screen_palette;
3239 for (i = 0; i < count; i++)
3240 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3241 (((unsigned int) palent[i].peGreen) << 8) |
3242 ((unsigned int) palent[i].peBlue));
3245 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3246 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3248 ICOM_THIS(IDirectDrawImpl,iface);
3249 char buf[200];
3250 WND *tmpWnd;
3252 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3253 This, width, height, depth);
3255 switch (_common_depth_to_pixelformat(depth,
3256 &(This->d.directdraw_pixelformat),
3257 &(This->d.screen_pixelformat),
3258 &(This->d.pixmap_depth))) {
3259 case 0:
3260 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3261 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3262 return DDERR_UNSUPPORTEDMODE;
3264 case 1:
3265 /* No convertion */
3266 This->d.pixel_convert = NULL;
3267 This->d.palette_convert = NULL;
3268 break;
3270 case 2: {
3271 int found = 0;
3273 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3275 /* Set the depth convertion routines */
3276 switch (This->d.screen_pixelformat.x.dwRGBBitCount) {
3277 case 16:
3278 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
3279 (This->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
3280 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3281 /* 16 bpp */
3282 found = 1;
3284 This->d.pixel_convert = pixel_convert_16_to_8;
3285 This->d.palette_convert = palette_convert_16_to_8;
3286 } else if ((This->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
3287 (This->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
3288 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3289 /* 15 bpp */
3290 found = 1;
3292 This->d.pixel_convert = pixel_convert_16_to_8;
3293 This->d.palette_convert = palette_convert_15_to_8;
3295 break;
3297 case 24:
3298 /* Not handled yet :/ */
3299 found = 0;
3300 break;
3302 case 32:
3303 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) &&
3304 (This->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) &&
3305 (This->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
3306 /* 24 bpp */
3307 found = 1;
3309 This->d.pixel_convert = pixel_convert_32_to_8;
3310 This->d.palette_convert = palette_convert_24_to_8;
3312 break;
3315 if (!found) {
3316 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3317 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3318 return DDERR_UNSUPPORTEDMODE;
3320 } break;
3323 This->d.width = width;
3324 This->d.height = height;
3326 _common_IDirectDrawImpl_SetDisplayMode(This);
3328 tmpWnd = WIN_FindWndPtr(This->d.window);
3329 This->d.paintable = 1;
3330 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3331 /* We don't have a context for this window. Host off the desktop */
3333 if( !This->d.drawable )
3335 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3336 WIN_ReleaseDesktop();
3338 WIN_ReleaseWndPtr(tmpWnd);
3339 return DD_OK;
3342 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3343 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3345 #ifdef HAVE_LIBXXF86DGA
3346 ICOM_THIS(IDirectDraw2Impl,iface);
3347 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3348 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3349 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3350 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3351 if (caps2) {
3352 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3353 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3354 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3356 return DD_OK;
3357 #else /* defined(HAVE_LIBXXF86DGA) */
3358 return E_UNEXPECTED;
3359 #endif /* defined(HAVE_LIBXXF86DGA) */
3362 static void fill_caps(LPDDCAPS caps) {
3363 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3364 Need to be fixed, though.. */
3365 if (caps == NULL)
3366 return;
3368 caps->dwSize = sizeof(*caps);
3369 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3370 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
3371 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3372 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3373 caps->dwFXCaps = 0;
3374 caps->dwFXAlphaCaps = 0;
3375 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3376 caps->dwSVCaps = 0;
3377 caps->dwZBufferBitDepths = DDBD_16;
3378 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3379 to put textures in video memory.
3380 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3381 for example) ? */
3382 caps->dwVidMemTotal = 8192 * 1024;
3383 caps->dwVidMemFree = 8192 * 1024;
3384 /* These are all the supported capabilities of the surfaces */
3385 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3386 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3387 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3388 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3389 #ifdef HAVE_MESAGL
3390 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3391 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3392 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3393 #endif
3396 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3397 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3399 ICOM_THIS(IDirectDraw2Impl,iface);
3400 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3402 /* Put the same caps for the two capabilities */
3403 fill_caps(caps1);
3404 fill_caps(caps2);
3406 return DD_OK;
3409 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3410 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3412 ICOM_THIS(IDirectDraw2Impl,iface);
3413 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3414 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3415 This,x,ilpddclip,lpunk
3417 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3418 (*ilpddclip)->ref = 1;
3419 (*ilpddclip)->lpvtbl = &ddclipvt;
3420 return DD_OK;
3423 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3424 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3426 int size = 0;
3428 if (TRACE_ON(ddraw))
3429 _dump_paletteformat(dwFlags);
3431 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3432 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3433 (*lpddpal)->ref = 1;
3434 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3435 (*lpddpal)->installed = 0;
3437 if (dwFlags & DDPCAPS_1BIT)
3438 size = 2;
3439 else if (dwFlags & DDPCAPS_2BIT)
3440 size = 4;
3441 else if (dwFlags & DDPCAPS_4BIT)
3442 size = 16;
3443 else if (dwFlags & DDPCAPS_8BIT)
3444 size = 256;
3445 else
3446 ERR(ddraw, "unhandled palette format\n");
3447 *psize = size;
3449 if (palent)
3451 /* Now, if we are in 'depth conversion mode', create the screen palette */
3452 if (This->d.palette_convert != NULL)
3453 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3455 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3456 } else if (This->d.palette_convert != NULL) {
3457 /* In that case, put all 0xFF */
3458 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3461 return DD_OK;
3464 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3465 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3467 ICOM_THIS(IDirectDraw2Impl,iface);
3468 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3469 HRESULT res;
3470 int xsize = 0,i;
3472 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3473 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3474 if (res != 0) return res;
3475 (*ilpddpal)->lpvtbl = &dga_ddpalvt;
3476 if (This->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3477 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3478 } else {
3479 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3480 (*ilpddpal)->cm = 0;
3482 if (((*ilpddpal)->cm)&&xsize) {
3483 for (i=0;i<xsize;i++) {
3484 XColor xc;
3486 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3487 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3488 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3489 xc.flags = DoRed|DoBlue|DoGreen;
3490 xc.pixel = i;
3491 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3494 return DD_OK;
3497 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3498 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3500 ICOM_THIS(IDirectDraw2Impl,iface);
3501 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3502 int xsize;
3503 HRESULT res;
3505 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3506 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3507 if (res != 0) return res;
3508 (*ilpddpal)->lpvtbl = &xlib_ddpalvt;
3509 return DD_OK;
3512 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3513 #ifdef HAVE_LIBXXF86DGA
3514 ICOM_THIS(IDirectDraw2Impl,iface);
3515 TRACE(ddraw, "(%p)->()\n",This);
3516 Sleep(1000);
3517 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3518 #ifdef RESTORE_SIGNALS
3519 SIGNAL_InitHandlers();
3520 #endif
3521 return DD_OK;
3522 #else /* defined(HAVE_LIBXXF86DGA) */
3523 return E_UNEXPECTED;
3524 #endif
3527 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3528 ICOM_THIS(IDirectDraw2Impl,iface);
3529 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", This);
3530 Sleep(1000);
3531 return DD_OK;
3534 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3535 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3537 ICOM_THIS(IDirectDraw2Impl,iface);
3538 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3539 return DD_OK;
3542 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3543 ICOM_THIS(IDirectDraw2Impl,iface);
3544 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
3546 return ++(This->ref);
3549 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3550 ICOM_THIS(IDirectDraw2Impl,iface);
3551 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3553 #ifdef HAVE_LIBXXF86DGA
3554 if (!--(This->ref)) {
3555 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3556 if (This->d.window && (This->d.mainWindow != This->d.window))
3557 DestroyWindow(This->d.window);
3558 #ifdef HAVE_LIBXXF86VM
3559 if (orig_mode) {
3560 TSXF86VidModeSwitchToMode(
3561 display,
3562 DefaultScreen(display),
3563 orig_mode);
3564 if (orig_mode->privsize)
3565 TSXFree(orig_mode->private);
3566 free(orig_mode);
3567 orig_mode = NULL;
3569 #endif
3571 #ifdef RESTORE_SIGNALS
3572 SIGNAL_InitHandlers();
3573 #endif
3574 HeapFree(GetProcessHeap(),0,This);
3575 return 0;
3577 #endif /* defined(HAVE_LIBXXF86DGA) */
3578 return This->ref;
3581 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3582 ICOM_THIS(IDirectDraw2Impl,iface);
3583 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3585 if (!--(This->ref)) {
3586 if (This->d.window && (This->d.mainWindow != This->d.window))
3587 DestroyWindow(This->d.window);
3588 HeapFree(GetProcessHeap(),0,This);
3589 return 0;
3591 /* FIXME: destroy window ... */
3592 return This->ref;
3595 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
3596 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3598 ICOM_THIS(IDirectDraw2Impl,iface);
3599 char xrefiid[50];
3601 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3602 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3603 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3604 *obj = This;
3605 IDirectDraw2_AddRef(iface);
3607 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3609 return S_OK;
3611 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3612 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
3613 IDirectDraw2_AddRef(iface);
3614 *obj = This;
3616 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3618 return S_OK;
3620 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3621 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
3622 IDirectDraw2_AddRef(iface);
3623 *obj = This;
3625 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3627 return S_OK;
3629 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3630 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
3631 IDirectDraw2_AddRef(iface);
3632 *obj = This;
3634 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3636 return S_OK;
3638 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3639 IDirect3DImpl* d3d;
3641 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3642 d3d->ref = 1;
3643 d3d->ddraw = (IDirectDrawImpl*)This;
3644 IDirectDraw2_AddRef(iface);
3645 d3d->lpvtbl = &d3dvt;
3646 *obj = d3d;
3648 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3650 return S_OK;
3652 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3653 IDirect3D2Impl* d3d;
3655 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3656 d3d->ref = 1;
3657 d3d->ddraw = (IDirectDrawImpl*)This;
3658 IDirectDraw2_AddRef(iface);
3659 d3d->lpvtbl = &d3d2vt;
3660 *obj = d3d;
3662 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3664 return S_OK;
3666 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3667 return OLE_E_ENUM_NOMORE;
3670 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
3671 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3673 ICOM_THIS(IDirectDraw2Impl,iface);
3674 char xrefiid[50];
3676 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3677 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3678 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3679 *obj = This;
3680 IDirectDraw2_AddRef(iface);
3682 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3684 return S_OK;
3686 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3687 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
3688 IDirectDraw2_AddRef(iface);
3689 *obj = This;
3691 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3693 return S_OK;
3695 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3696 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
3697 IDirectDraw2_AddRef(iface);
3698 *obj = This;
3700 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3702 return S_OK;
3704 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3705 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
3706 IDirectDraw2_AddRef(iface);
3707 *obj = This;
3709 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3711 return S_OK;
3713 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3714 IDirect3DImpl* d3d;
3716 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3717 d3d->ref = 1;
3718 d3d->ddraw = (IDirectDrawImpl*)This;
3719 IDirectDraw2_AddRef(iface);
3720 d3d->lpvtbl = &d3dvt;
3721 *obj = d3d;
3723 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3725 return S_OK;
3727 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3728 IDirect3D2Impl* d3d;
3730 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3731 d3d->ref = 1;
3732 d3d->ddraw = (IDirectDrawImpl*)This;
3733 IDirectDraw2_AddRef(iface);
3734 d3d->lpvtbl = &d3d2vt;
3735 *obj = d3d;
3737 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3739 return S_OK;
3741 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3742 return OLE_E_ENUM_NOMORE;
3745 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
3746 LPDIRECTDRAW2 iface,BOOL *status
3748 ICOM_THIS(IDirectDraw2Impl,iface);
3749 TRACE(ddraw,"(%p)->(%p)\n",This,status);
3750 *status = TRUE;
3751 return DD_OK;
3754 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
3755 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3757 ICOM_THIS(IDirectDraw2Impl,iface);
3758 DDSURFACEDESC ddsfd;
3759 static struct {
3760 int w,h;
3761 } modes[5] = { /* some of the usual modes */
3762 {512,384},
3763 {640,400},
3764 {640,480},
3765 {800,600},
3766 {1024,768},
3768 static int depths[4] = {8,16,24,32};
3769 int i,j;
3771 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3772 ddsfd.dwSize = sizeof(ddsfd);
3773 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3774 if (dwFlags & DDEDM_REFRESHRATES) {
3775 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3776 ddsfd.x.dwRefreshRate = 60;
3779 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3780 ddsfd.dwBackBufferCount = 1;
3781 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3782 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3783 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3784 /* FIXME: those masks would have to be set in depth > 8 */
3785 if (depths[i]==8) {
3786 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3787 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3788 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3789 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3790 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3791 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3792 } else {
3793 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3795 /* FIXME: We should query those from X itself */
3796 switch (depths[i]) {
3797 case 16:
3798 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3799 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3800 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3801 break;
3802 case 24:
3803 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3804 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3805 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3806 break;
3807 case 32:
3808 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3809 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3810 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3811 break;
3815 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3816 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3817 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3818 if (!modescb(&ddsfd,context)) return DD_OK;
3820 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3821 ddsfd.dwWidth = modes[j].w;
3822 ddsfd.dwHeight = modes[j].h;
3823 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3824 if (!modescb(&ddsfd,context)) return DD_OK;
3827 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3828 /* modeX is not standard VGA */
3830 ddsfd.dwHeight = 200;
3831 ddsfd.dwWidth = 320;
3832 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3833 if (!modescb(&ddsfd,context)) return DD_OK;
3836 return DD_OK;
3839 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
3840 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3842 ICOM_THIS(IDirectDraw2Impl,iface);
3843 XVisualInfo *vi;
3844 XPixmapFormatValues *pf;
3845 XVisualInfo vt;
3846 int nvisuals, npixmap, i;
3847 int send_mode;
3848 int has_8bpp = 0;
3849 DDSURFACEDESC ddsfd;
3850 static struct {
3851 int w,h;
3852 } modes[] = { /* some of the usual modes */
3853 {512,384},
3854 {640,400},
3855 {640,480},
3856 {800,600},
3857 {1024,768},
3858 {1280,1024}
3860 DWORD maxWidth, maxHeight;
3862 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3863 ddsfd.dwSize = sizeof(ddsfd);
3864 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
3865 if (dwFlags & DDEDM_REFRESHRATES) {
3866 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3867 ddsfd.x.dwRefreshRate = 60;
3869 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3870 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3872 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3873 pf = XListPixmapFormats(display, &npixmap);
3875 i = 0;
3876 send_mode = 0;
3877 while (i < npixmap) {
3878 if ((has_8bpp == 0) && (pf[i].depth == 8)) {
3879 /* Special case of a 8bpp depth */
3880 has_8bpp = 1;
3881 send_mode = 1;
3883 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
3884 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3885 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
3886 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3887 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
3888 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3889 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3890 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3891 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3892 } else if (pf[i].depth > 8) {
3893 int j;
3895 /* All the 'true color' depths (15, 16 and 24)
3896 First, find the corresponding visual to extract the bit masks */
3897 for (j = 0; j < nvisuals; j++) {
3898 if (vi[j].depth == pf[i].depth) {
3899 ddsfd.ddsCaps.dwCaps = 0;
3900 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3901 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3902 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3903 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
3904 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
3905 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
3906 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
3907 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3909 send_mode = 1;
3910 break;
3914 if (j == nvisuals)
3915 ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
3916 } else {
3917 send_mode = 0;
3920 if (send_mode) {
3921 int mode;
3923 if (TRACE_ON(ddraw)) {
3924 TRACE(ddraw, "Enumerating with pixel format : \n");
3925 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
3928 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
3929 /* Do not enumerate modes we cannot handle anyway */
3930 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
3931 break;
3933 ddsfd.dwWidth = modes[mode].w;
3934 ddsfd.dwHeight = modes[mode].h;
3936 /* Now, send the mode description to the application */
3937 TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
3938 if (!modescb(&ddsfd, context))
3939 goto exit_enum;
3942 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3943 /* modeX is not standard VGA */
3944 ddsfd.dwWidth = 320;
3945 ddsfd.dwHeight = 200;
3946 if (!modescb(&ddsfd, context))
3947 goto exit_enum;
3951 /* Hack to always enumerate a 8bpp depth */
3952 i++;
3953 if ((i == npixmap) && (has_8bpp == 0)) {
3954 i--;
3955 pf[i].depth = 8;
3959 exit_enum:
3960 TSXFree(vi);
3961 TSXFree(pf);
3963 return DD_OK;
3966 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
3967 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
3969 #ifdef HAVE_LIBXXF86DGA
3970 ICOM_THIS(IDirectDraw2Impl,iface);
3971 TRACE(ddraw,"(%p)->(%p)\n",This,lpddsfd);
3972 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3973 lpddsfd->dwHeight = This->d.height;
3974 lpddsfd->dwWidth = This->d.width;
3975 lpddsfd->lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3976 lpddsfd->dwBackBufferCount = 1;
3977 lpddsfd->x.dwRefreshRate = 60;
3978 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3979 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
3980 return DD_OK;
3981 #else /* defined(HAVE_LIBXXF86DGA) */
3982 return E_UNEXPECTED;
3983 #endif /* defined(HAVE_LIBXXF86DGA) */
3986 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
3987 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
3989 ICOM_THIS(IDirectDraw2Impl,iface);
3990 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
3991 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3992 lpddsfd->dwHeight = This->d.height;
3993 lpddsfd->dwWidth = This->d.width;
3994 lpddsfd->lPitch = lpddsfd->dwWidth * This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3995 lpddsfd->dwBackBufferCount = 1;
3996 lpddsfd->x.dwRefreshRate = 60;
3997 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3998 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
3999 return DD_OK;
4002 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4003 ICOM_THIS(IDirectDraw2Impl,iface);
4004 TRACE(ddraw,"(%p)->()\n",This);
4005 return DD_OK;
4008 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4009 LPDIRECTDRAW2 iface,LPDWORD freq
4011 ICOM_THIS(IDirectDraw2Impl,iface);
4012 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",This,freq);
4013 *freq = 60*100; /* 60 Hz */
4014 return DD_OK;
4017 /* what can we directly decompress? */
4018 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4019 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4021 ICOM_THIS(IDirectDraw2Impl,iface);
4022 FIXME(ddraw,"(%p,%p,%p), stub\n",This,x,y);
4023 return DD_OK;
4026 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4027 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4029 ICOM_THIS(IDirectDraw2Impl,iface);
4030 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4031 return DD_OK;
4034 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4035 LPDIRECTDRAW2 iface )
4037 ICOM_THIS(IDirectDraw2Impl,iface);
4038 FIXME(ddraw,"(%p)->()\n", This );
4040 return DD_OK;
4043 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4044 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4045 ICOM_THIS(IDirectDraw2Impl,iface);
4046 FIXME(ddraw,"(%p)->(%p)\n", This, lplpGDIDDSSurface);
4048 return DD_OK;
4051 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4052 LPDWORD lpdwScanLine) {
4053 ICOM_THIS(IDirectDraw2Impl,iface);
4054 FIXME(ddraw,"(%p)->(%p)\n", This, lpdwScanLine);
4056 return DD_OK;
4059 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4060 GUID *lpGUID) {
4061 ICOM_THIS(IDirectDraw2Impl,iface);
4062 FIXME(ddraw,"(%p)->(%p)\n", This, lpGUID);
4064 return DD_OK;
4067 /* Note: Hack so we can reuse the old functions without compiler warnings */
4068 #ifdef __GNUC__
4069 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4070 #else
4071 # define XCAST(fun) (void*)
4072 #endif
4074 static ICOM_VTABLE(IDirectDraw) dga_ddvt = {
4075 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4076 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4077 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4078 XCAST(Compact)IDirectDraw2Impl_Compact,
4079 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4080 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4081 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4082 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4083 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4084 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4085 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4086 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4087 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4088 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4089 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4090 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4091 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4092 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4093 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4094 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4095 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4096 DGA_IDirectDrawImpl_SetDisplayMode,
4097 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4100 static ICOM_VTABLE(IDirectDraw) xlib_ddvt = {
4101 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4102 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4103 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4104 XCAST(Compact)IDirectDraw2Impl_Compact,
4105 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4106 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4107 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4108 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4109 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4110 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4111 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4112 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4113 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4114 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4115 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4116 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4117 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4118 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4119 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4120 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4121 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4122 Xlib_IDirectDrawImpl_SetDisplayMode,
4123 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4126 #undef XCAST
4128 /*****************************************************************************
4129 * IDirectDraw2
4134 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4135 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4137 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4140 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4141 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4143 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4146 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4147 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4149 ICOM_THIS(IDirectDraw2Impl,iface);
4150 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4151 This,ddscaps,total,free
4153 if (total) *total = This->e.dga.fb_memsize * 1024;
4154 if (free) *free = This->e.dga.fb_memsize * 1024;
4155 return DD_OK;
4158 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4159 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4161 ICOM_THIS(IDirectDraw2Impl,iface);
4162 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4163 This,ddscaps,total,free
4165 if (total) *total = 2048 * 1024;
4166 if (free) *free = 2048 * 1024;
4167 return DD_OK;
4170 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt = {
4171 DGA_IDirectDraw2Impl_QueryInterface,
4172 IDirectDraw2Impl_AddRef,
4173 DGA_IDirectDraw2Impl_Release,
4174 IDirectDraw2Impl_Compact,
4175 IDirectDraw2Impl_CreateClipper,
4176 DGA_IDirectDraw2Impl_CreatePalette,
4177 DGA_IDirectDraw2Impl_CreateSurface,
4178 IDirectDraw2Impl_DuplicateSurface,
4179 DGA_IDirectDraw2Impl_EnumDisplayModes,
4180 IDirectDraw2Impl_EnumSurfaces,
4181 IDirectDraw2Impl_FlipToGDISurface,
4182 DGA_IDirectDraw2Impl_GetCaps,
4183 DGA_IDirectDraw2Impl_GetDisplayMode,
4184 IDirectDraw2Impl_GetFourCCCodes,
4185 IDirectDraw2Impl_GetGDISurface,
4186 IDirectDraw2Impl_GetMonitorFrequency,
4187 IDirectDraw2Impl_GetScanLine,
4188 IDirectDraw2Impl_GetVerticalBlankStatus,
4189 IDirectDraw2Impl_Initialize,
4190 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4191 IDirectDraw2Impl_SetCooperativeLevel,
4192 DGA_IDirectDraw2Impl_SetDisplayMode,
4193 IDirectDraw2Impl_WaitForVerticalBlank,
4194 DGA_IDirectDraw2Impl_GetAvailableVidMem
4197 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = {
4198 Xlib_IDirectDraw2Impl_QueryInterface,
4199 IDirectDraw2Impl_AddRef,
4200 Xlib_IDirectDraw2Impl_Release,
4201 IDirectDraw2Impl_Compact,
4202 IDirectDraw2Impl_CreateClipper,
4203 Xlib_IDirectDraw2Impl_CreatePalette,
4204 Xlib_IDirectDraw2Impl_CreateSurface,
4205 IDirectDraw2Impl_DuplicateSurface,
4206 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4207 IDirectDraw2Impl_EnumSurfaces,
4208 IDirectDraw2Impl_FlipToGDISurface,
4209 Xlib_IDirectDraw2Impl_GetCaps,
4210 Xlib_IDirectDraw2Impl_GetDisplayMode,
4211 IDirectDraw2Impl_GetFourCCCodes,
4212 IDirectDraw2Impl_GetGDISurface,
4213 IDirectDraw2Impl_GetMonitorFrequency,
4214 IDirectDraw2Impl_GetScanLine,
4215 IDirectDraw2Impl_GetVerticalBlankStatus,
4216 IDirectDraw2Impl_Initialize,
4217 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4218 IDirectDraw2Impl_SetCooperativeLevel,
4219 Xlib_IDirectDraw2Impl_SetDisplayMode,
4220 IDirectDraw2Impl_WaitForVerticalBlank,
4221 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4224 /*****************************************************************************
4225 * IDirectDraw4
4229 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4230 HDC hdc,
4231 LPDIRECTDRAWSURFACE *lpDDS) {
4232 ICOM_THIS(IDirectDraw4Impl,iface);
4233 FIXME(ddraw, "(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4235 return DD_OK;
4238 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4239 ICOM_THIS(IDirectDraw4Impl,iface);
4240 FIXME(ddraw, "(%p)->()\n", This);
4242 return DD_OK;
4245 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4246 ICOM_THIS(IDirectDraw4Impl,iface);
4247 FIXME(ddraw, "(%p)->()\n", This);
4249 return DD_OK;
4252 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4253 LPDDDEVICEIDENTIFIER lpdddi,
4254 DWORD dwFlags) {
4255 ICOM_THIS(IDirectDraw4Impl,iface);
4256 FIXME(ddraw, "(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4258 return DD_OK;
4261 #ifdef __GNUC__
4262 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4263 #else
4264 # define XCAST(fun) (void*)
4265 #endif
4268 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt = {
4269 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4270 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4271 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4272 XCAST(Compact)IDirectDraw2Impl_Compact,
4273 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4274 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4275 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4276 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4277 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4278 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4279 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4280 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4281 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4282 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4283 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4284 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4285 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4286 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4287 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4288 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4289 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4290 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4291 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4292 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4293 IDirectDraw4Impl_GetSurfaceFromDC,
4294 IDirectDraw4Impl_RestoreAllSurfaces,
4295 IDirectDraw4Impl_TestCooperativeLevel,
4296 IDirectDraw4Impl_GetDeviceIdentifier
4299 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = {
4300 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4301 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4302 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4303 XCAST(Compact)IDirectDraw2Impl_Compact,
4304 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4305 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4306 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4307 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4308 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4309 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4310 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4311 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4312 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4313 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4314 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4315 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4316 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4317 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4318 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4319 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4320 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4321 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4322 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4323 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4324 IDirectDraw4Impl_GetSurfaceFromDC,
4325 IDirectDraw4Impl_RestoreAllSurfaces,
4326 IDirectDraw4Impl_TestCooperativeLevel,
4327 IDirectDraw4Impl_GetDeviceIdentifier
4330 #undef XCAST
4332 /******************************************************************************
4333 * DirectDrawCreate
4336 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4338 LRESULT ret;
4339 IDirectDrawImpl* ddraw = NULL;
4340 DWORD lastError;
4342 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4344 SetLastError( ERROR_SUCCESS );
4345 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4346 if( (!ddraw) &&
4347 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4350 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4353 if( ddraw )
4355 /* Perform any special direct draw functions */
4356 if (msg==WM_PAINT)
4357 ddraw->d.paintable = 1;
4359 /* Now let the application deal with the rest of this */
4360 if( ddraw->d.mainWindow )
4363 /* Don't think that we actually need to call this but...
4364 might as well be on the safe side of things... */
4366 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4367 it should be the procedures of our fake window that gets called
4368 instead of those of the window provided by the application.
4369 And with this patch, mouse clicks work with Monkey Island III
4370 - Lionel */
4371 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4373 if( !ret )
4375 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4376 /* We didn't handle the message - give it to the application */
4377 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4379 ret = CallWindowProcA(tmpWnd->winproc,
4380 ddraw->d.mainWindow, msg, wParam, lParam );
4382 WIN_ReleaseWndPtr(tmpWnd);
4386 } else {
4387 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4391 else
4393 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4396 return ret;
4399 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4400 #ifdef HAVE_LIBXXF86DGA
4401 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4402 int memsize,banksize,width,major,minor,flags,height;
4403 char *addr;
4404 int fd;
4405 int depth;
4407 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4408 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4409 close(fd);
4411 if (fd == -1) {
4412 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4413 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4414 return E_UNEXPECTED;
4416 if (!DDRAW_DGA_Available()) {
4417 TRACE(ddraw,"No XF86DGA detected.\n");
4418 return DDERR_GENERIC;
4420 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4421 (*ilplpDD)->lpvtbl = &dga_ddvt;
4422 (*ilplpDD)->ref = 1;
4423 TSXF86DGAQueryVersion(display,&major,&minor);
4424 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4425 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4426 if (!(flags & XF86DGADirectPresent))
4427 MSG("direct video is NOT PRESENT.\n");
4428 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4429 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4430 addr,width,banksize,memsize
4432 (*ilplpDD)->e.dga.fb_width = width;
4433 (*ilplpDD)->d.width = width;
4434 (*ilplpDD)->e.dga.fb_addr = addr;
4435 (*ilplpDD)->e.dga.fb_memsize = memsize;
4436 (*ilplpDD)->e.dga.fb_banksize = banksize;
4438 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4439 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4440 (*ilplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4441 #ifdef DIABLO_HACK
4442 (*ilplpDD)->e.dga.vpmask = 1;
4443 #else
4444 (*ilplpDD)->e.dga.vpmask = 0;
4445 #endif
4447 /* just assume the default depth is the DGA depth too */
4448 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4449 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4450 #ifdef RESTORE_SIGNALS
4451 SIGNAL_InitHandlers();
4452 #endif
4454 return DD_OK;
4455 #else /* defined(HAVE_LIBXXF86DGA) */
4456 return DDERR_INVALIDDIRECTDRAWGUID;
4457 #endif /* defined(HAVE_LIBXXF86DGA) */
4460 BOOL
4461 DDRAW_XSHM_Available(void)
4463 #ifdef HAVE_LIBXXSHM
4464 if (TSXShmQueryExtension(display))
4466 int major, minor;
4467 Bool shpix;
4469 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4470 return 1;
4471 else
4472 return 0;
4474 else
4475 return 0;
4476 #else
4477 return 0;
4478 #endif
4481 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4482 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4483 int depth;
4485 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4486 (*ilplpDD)->lpvtbl = &xlib_ddvt;
4487 (*ilplpDD)->ref = 1;
4488 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
4490 /* At DirectDraw creation, the depth is the default depth */
4491 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4492 _common_depth_to_pixelformat(depth,
4493 &((*ilplpDD)->d.directdraw_pixelformat),
4494 &((*ilplpDD)->d.screen_pixelformat),
4495 &((*ilplpDD)->d.pixmap_depth));
4496 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4497 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4499 #ifdef HAVE_LIBXXSHM
4500 /* Test if XShm is available. */
4501 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4502 TRACE(ddraw, "Using XShm extension.\n");
4503 #endif
4505 return DD_OK;
4508 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4509 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4510 char xclsid[50];
4511 WNDCLASSA wc;
4512 /* WND* pParentWindow; */
4513 HRESULT ret;
4515 if (HIWORD(lpGUID))
4516 WINE_StringFromCLSID(lpGUID,xclsid);
4517 else {
4518 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4519 lpGUID = NULL;
4522 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
4524 if ((!lpGUID) ||
4525 (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4526 (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4527 (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4528 /* if they didn't request a particular interface, use the best
4529 * supported one */
4530 if (DDRAW_DGA_Available())
4531 lpGUID = &DGA_DirectDraw_GUID;
4532 else
4533 lpGUID = &XLIB_DirectDraw_GUID;
4536 wc.style = CS_GLOBALCLASS;
4537 wc.lpfnWndProc = Xlib_DDWndProc;
4538 wc.cbClsExtra = 0;
4539 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
4540 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
4542 /* We can be a child of the desktop since we're really important */
4544 This code is not useful since hInstance is forced to 0 afterward
4545 pParentWindow = WIN_GetDesktop();
4546 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
4548 wc.hInstance = 0;
4551 wc.hIcon = 0;
4552 wc.hCursor = (HCURSOR)IDC_ARROWA;
4553 wc.hbrBackground= NULL_BRUSH;
4554 wc.lpszMenuName = 0;
4555 wc.lpszClassName= "WINE_DirectDraw";
4556 RegisterClassA(&wc);
4558 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4559 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4560 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4561 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4562 else
4563 goto err;
4566 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
4567 return ret;
4569 err:
4570 ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4571 return DDERR_INVALIDDIRECTDRAWGUID;
4575 #else /* !defined(X_DISPLAY_MISSING) */
4577 #include "windef.h"
4579 #define DD_OK 0
4581 typedef void *LPGUID;
4582 typedef void *LPUNKNOWN;
4583 typedef void *LPDIRECTDRAW;
4584 typedef void *LPDIRECTDRAWCLIPPER;
4585 typedef void *LPDDENUMCALLBACKA;
4586 typedef void *LPDDENUMCALLBACKEXA;
4587 typedef void *LPDDENUMCALLBACKEXW;
4588 typedef void *LPDDENUMCALLBACKW;
4590 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
4592 return DD_OK;
4595 HRESULT WINAPI DirectDrawCreate(
4596 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
4598 return DD_OK;
4601 HRESULT WINAPI DirectDrawCreateClipper(
4602 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
4604 return DD_OK;
4607 HRESULT WINAPI DirectDrawEnumerateA(
4608 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
4610 return DD_OK;
4613 HRESULT WINAPI DirectDrawEnumerateExA(
4614 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
4616 return DD_OK;
4619 HRESULT WINAPI DirectDrawEnumerateExW(
4620 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
4622 return DD_OK;
4625 HRESULT WINAPI DirectDrawEnumerateW(
4626 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
4628 return DD_OK;
4631 #endif /* !defined(X_DISPLAY_MISSING) */
4634 /*******************************************************************************
4635 * DirectDraw ClassFactory
4637 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
4640 typedef struct
4642 /* IUnknown fields */
4643 ICOM_VTABLE(IClassFactory)* lpvtbl;
4644 DWORD ref;
4645 } IClassFactoryImpl;
4647 static HRESULT WINAPI
4648 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
4649 ICOM_THIS(IClassFactoryImpl,iface);
4650 char buf[80];
4652 if (HIWORD(riid))
4653 WINE_StringFromCLSID(riid,buf);
4654 else
4655 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4656 FIXME(ddraw,"(%p)->(%s,%p),stub!\n",This,buf,ppobj);
4657 return E_NOINTERFACE;
4660 static ULONG WINAPI
4661 DDCF_AddRef(LPCLASSFACTORY iface) {
4662 ICOM_THIS(IClassFactoryImpl,iface);
4663 return ++(This->ref);
4666 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
4667 ICOM_THIS(IClassFactoryImpl,iface);
4668 /* static class, won't be freed */
4669 return --(This->ref);
4672 static HRESULT WINAPI DDCF_CreateInstance(
4673 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
4675 ICOM_THIS(IClassFactoryImpl,iface);
4676 char buf[80];
4678 WINE_StringFromCLSID(riid,buf);
4679 TRACE(ddraw,"(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
4680 if ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4681 (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4682 (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4683 /* FIXME: reuse already created DirectDraw if present? */
4684 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
4686 return E_NOINTERFACE;
4689 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
4690 ICOM_THIS(IClassFactoryImpl,iface);
4691 FIXME(ddraw,"(%p)->(%d),stub!\n",This,dolock);
4692 return S_OK;
4695 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl = {
4696 DDCF_QueryInterface,
4697 DDCF_AddRef,
4698 DDCF_Release,
4699 DDCF_CreateInstance,
4700 DDCF_LockServer
4702 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
4704 /*******************************************************************************
4705 * DllGetClassObject [DDRAW.13]
4706 * Retrieves class object from a DLL object
4708 * NOTES
4709 * Docs say returns STDAPI
4711 * PARAMS
4712 * rclsid [I] CLSID for the class object
4713 * riid [I] Reference to identifier of interface for class object
4714 * ppv [O] Address of variable to receive interface pointer for riid
4716 * RETURNS
4717 * Success: S_OK
4718 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
4719 * E_UNEXPECTED
4721 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
4723 char buf[80],xbuf[80];
4725 if (HIWORD(rclsid))
4726 WINE_StringFromCLSID(rclsid,xbuf);
4727 else
4728 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
4729 if (HIWORD(riid))
4730 WINE_StringFromCLSID(riid,buf);
4731 else
4732 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4733 WINE_StringFromCLSID(riid,xbuf);
4734 TRACE(ddraw, "(%p,%p,%p)\n", xbuf, buf, ppv);
4735 if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
4736 *ppv = (LPVOID)&DDRAW_CF;
4737 IClassFactory_AddRef((IClassFactory*)*ppv);
4738 return S_OK;
4740 FIXME(ddraw, "(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
4741 return E_NOINTERFACE;
4745 /*******************************************************************************
4746 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
4748 * RETURNS
4749 * Success: S_OK
4750 * Failure: S_FALSE
4752 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
4754 FIXME(ddraw, "(void): stub\n");
4755 return S_FALSE;