Check if in depth-conversion mode before returning an error message
[wine/dcerpc.git] / graphics / ddraw.c
blobb213f1fa301aadc7f19d55c0bd60bcbde49cc49a
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
5 */
6 /* XF86DGA:
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
10 * is running.
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
17 #include "config.h"
19 #ifndef X_DISPLAY_MISSING
21 #include "ts_xlib.h"
22 #include "ts_xutil.h"
24 #ifdef HAVE_LIBXXSHM
25 #include <sys/types.h>
26 #include <sys/ipc.h>
27 #include <sys/shm.h>
28 #include "ts_xshm.h"
29 #endif /* defined(HAVE_LIBXXSHM) */
31 #ifdef HAVE_LIBXXF86DGA
32 #include "ts_xf86dga.h"
33 #endif /* defined(HAVE_LIBXXF86DGA) */
35 #ifdef HAVE_LIBXXF86VM
36 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
37 this is a crude hack to get around it */
38 #define XMD_H
39 typedef int INT32;
40 #include "ts_xf86vmode.h"
41 #endif /* defined(HAVE_LIBXXF86VM) */
43 #include "x11drv.h"
45 #include <unistd.h>
46 #include <assert.h>
47 #include <sys/signal.h>
48 #include <fcntl.h>
49 #include <string.h>
50 #include <stdlib.h>
52 #include "winerror.h"
53 #include "gdi.h"
54 #include "heap.h"
55 #include "dc.h"
56 #include "win.h"
57 #include "miscemu.h"
58 #include "ddraw.h"
59 #include "d3d.h"
60 #include "debug.h"
61 #include "spy.h"
62 #include "message.h"
63 #include "options.h"
64 #include "monitor.h"
66 /* This for all the enumeration and creation of D3D-related objects */
67 #include "ddraw_private.h"
68 #include "d3d_private.h"
70 DEFAULT_DEBUG_CHANNEL(ddraw)
72 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
73 #undef DIABLO_HACK
75 /* Restore signal handlers overwritten by XF86DGA
77 #define RESTORE_SIGNALS
79 /* Where do these GUIDs come from? mkuuid.
80 * They exist solely to distinguish between the targets Wine support,
81 * and should be different than any other GUIDs in existence.
83 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
84 0xe2dcb020,
85 0xdc60,
86 0x11d1,
87 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
90 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
91 0x1574a740,
92 0xdc61,
93 0x11d1,
94 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
97 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt, xlib_dds4vt;
98 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt, xlib_ddvt;
99 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt, xlib_dd2vt;
100 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt, xlib_dd4vt;
101 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
102 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt, xlib_ddpalvt;
103 static struct ICOM_VTABLE(IDirect3D) d3dvt;
104 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
106 #ifdef HAVE_LIBXXF86VM
107 static XF86VidModeModeInfo *orig_mode = NULL;
108 #endif
110 #ifdef HAVE_LIBXXSHM
111 static int XShmErrorFlag = 0;
112 #endif
114 BOOL
115 DDRAW_DGA_Available(void)
117 #ifdef HAVE_LIBXXF86DGA
118 int evbase, evret, fd;
120 if (Options.noDGA)
121 return 0;
123 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
124 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
125 /* others. --stephenc */
126 if ((fd = open("/dev/mem", O_RDWR)) != -1)
127 close(fd);
129 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
130 #else /* defined(HAVE_LIBXXF86DGA) */
131 return 0;
132 #endif /* defined(HAVE_LIBXXF86DGA) */
135 /**********************************************************************/
137 typedef struct {
138 LPVOID lpCallback;
139 LPVOID lpContext;
140 } DirectDrawEnumerateProcData;
142 /***********************************************************************
143 * DirectDrawEnumerateExA (DDRAW.*)
145 HRESULT WINAPI DirectDrawEnumerateExA(
146 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
148 TRACE(ddraw, "(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
150 if (TRACE_ON(ddraw)) {
151 DUMP(" Flags : ");
152 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
153 DUMP("DDENUM_ATTACHEDSECONDARYDEVICES ");
154 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
155 DUMP("DDENUM_DETACHEDSECONDARYDEVICES ");
156 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
157 DUMP("DDENUM_NONDISPLAYDEVICES ");
158 DUMP("\n");
161 if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
162 /* For the moment, Wine does not support any 3D only accelerators */
163 return DD_OK;
166 if (DDRAW_DGA_Available()) {
167 TRACE(ddraw, "Enumerating DGA interface\n");
168 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
169 return DD_OK;
172 TRACE(ddraw, "Enumerating Xlib interface\n");
173 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
174 return DD_OK;
176 TRACE(ddraw, "Enumerating Default interface\n");
177 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
178 return DD_OK;
180 return DD_OK;
183 /***********************************************************************
184 * DirectDrawEnumerateExW (DDRAW.*)
187 static BOOL CALLBACK DirectDrawEnumerateExProcW(
188 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
189 LPVOID lpContext, HMONITOR hm)
191 DirectDrawEnumerateProcData *pEPD =
192 (DirectDrawEnumerateProcData *) lpContext;
193 LPWSTR lpDriverDescriptionW =
194 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
195 LPWSTR lpDriverNameW =
196 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
198 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
199 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
201 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
202 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
204 return bResult;
207 /**********************************************************************/
209 HRESULT WINAPI DirectDrawEnumerateExW(
210 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
212 DirectDrawEnumerateProcData epd;
213 epd.lpCallback = (LPVOID) lpCallback;
214 epd.lpContext = lpContext;
216 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
217 (LPVOID) &epd, 0);
220 /***********************************************************************
221 * DirectDrawEnumerateA (DDRAW.*)
224 static BOOL CALLBACK DirectDrawEnumerateProcA(
225 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
226 LPVOID lpContext, HMONITOR hm)
228 DirectDrawEnumerateProcData *pEPD =
229 (DirectDrawEnumerateProcData *) lpContext;
231 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
232 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
235 /**********************************************************************/
237 HRESULT WINAPI DirectDrawEnumerateA(
238 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
240 DirectDrawEnumerateProcData epd;
241 epd.lpCallback = (LPVOID) lpCallback;
242 epd.lpContext = lpContext;
244 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
245 (LPVOID) &epd, 0);
248 /***********************************************************************
249 * DirectDrawEnumerateW (DDRAW.*)
252 static BOOL WINAPI DirectDrawEnumerateProcW(
253 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
254 LPVOID lpContext, HMONITOR hm)
256 DirectDrawEnumerateProcData *pEPD =
257 (DirectDrawEnumerateProcData *) lpContext;
259 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
260 lpGUID, lpDriverDescription, lpDriverName,
261 pEPD->lpContext);
264 /**********************************************************************/
266 HRESULT WINAPI DirectDrawEnumerateW(
267 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
269 DirectDrawEnumerateProcData epd;
270 epd.lpCallback = (LPVOID) lpCallback;
271 epd.lpContext = lpContext;
273 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
274 (LPVOID) &epd, 0);
277 /***********************************************************************
278 * DSoundHelp (DDRAW.?)
281 /* What is this doing here? */
282 HRESULT WINAPI
283 DSoundHelp(DWORD x,DWORD y,DWORD z) {
284 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
285 return 0;
288 /******************************************************************************
289 * internal helper functions
291 static void _dump_DDBLTFX(DWORD flagmask) {
292 int i;
293 const struct {
294 DWORD mask;
295 char *name;
296 } flags[] = {
297 #define FE(x) { x, #x},
298 FE(DDBLTFX_ARITHSTRETCHY)
299 FE(DDBLTFX_MIRRORLEFTRIGHT)
300 FE(DDBLTFX_MIRRORUPDOWN)
301 FE(DDBLTFX_NOTEARING)
302 FE(DDBLTFX_ROTATE180)
303 FE(DDBLTFX_ROTATE270)
304 FE(DDBLTFX_ROTATE90)
305 FE(DDBLTFX_ZBUFFERRANGE)
306 FE(DDBLTFX_ZBUFFERBASEDEST)
308 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
309 if (flags[i].mask & flagmask) {
310 DUMP("%s ",flags[i].name);
313 DUMP("\n");
317 static void _dump_DDBLTFAST(DWORD flagmask) {
318 int i;
319 const struct {
320 DWORD mask;
321 char *name;
322 } flags[] = {
323 #define FE(x) { x, #x},
324 FE(DDBLTFAST_NOCOLORKEY)
325 FE(DDBLTFAST_SRCCOLORKEY)
326 FE(DDBLTFAST_DESTCOLORKEY)
327 FE(DDBLTFAST_WAIT)
329 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
330 if (flags[i].mask & flagmask)
331 DUMP("%s ",flags[i].name);
332 DUMP("\n");
335 static void _dump_DDBLT(DWORD flagmask) {
336 int i;
337 const struct {
338 DWORD mask;
339 char *name;
340 } flags[] = {
341 #define FE(x) { x, #x},
342 FE(DDBLT_ALPHADEST)
343 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
344 FE(DDBLT_ALPHADESTNEG)
345 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
346 FE(DDBLT_ALPHAEDGEBLEND)
347 FE(DDBLT_ALPHASRC)
348 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
349 FE(DDBLT_ALPHASRCNEG)
350 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
351 FE(DDBLT_ASYNC)
352 FE(DDBLT_COLORFILL)
353 FE(DDBLT_DDFX)
354 FE(DDBLT_DDROPS)
355 FE(DDBLT_KEYDEST)
356 FE(DDBLT_KEYDESTOVERRIDE)
357 FE(DDBLT_KEYSRC)
358 FE(DDBLT_KEYSRCOVERRIDE)
359 FE(DDBLT_ROP)
360 FE(DDBLT_ROTATIONANGLE)
361 FE(DDBLT_ZBUFFER)
362 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
363 FE(DDBLT_ZBUFFERDESTOVERRIDE)
364 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
365 FE(DDBLT_ZBUFFERSRCOVERRIDE)
366 FE(DDBLT_WAIT)
367 FE(DDBLT_DEPTHFILL)
369 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
370 if (flags[i].mask & flagmask)
371 DUMP("%s ",flags[i].name);
372 DUMP("\n");
375 static void _dump_DDSCAPS(DWORD flagmask) {
376 int i;
377 const struct {
378 DWORD mask;
379 char *name;
380 } flags[] = {
381 #define FE(x) { x, #x},
382 FE(DDSCAPS_RESERVED1)
383 FE(DDSCAPS_ALPHA)
384 FE(DDSCAPS_BACKBUFFER)
385 FE(DDSCAPS_COMPLEX)
386 FE(DDSCAPS_FLIP)
387 FE(DDSCAPS_FRONTBUFFER)
388 FE(DDSCAPS_OFFSCREENPLAIN)
389 FE(DDSCAPS_OVERLAY)
390 FE(DDSCAPS_PALETTE)
391 FE(DDSCAPS_PRIMARYSURFACE)
392 FE(DDSCAPS_PRIMARYSURFACELEFT)
393 FE(DDSCAPS_SYSTEMMEMORY)
394 FE(DDSCAPS_TEXTURE)
395 FE(DDSCAPS_3DDEVICE)
396 FE(DDSCAPS_VIDEOMEMORY)
397 FE(DDSCAPS_VISIBLE)
398 FE(DDSCAPS_WRITEONLY)
399 FE(DDSCAPS_ZBUFFER)
400 FE(DDSCAPS_OWNDC)
401 FE(DDSCAPS_LIVEVIDEO)
402 FE(DDSCAPS_HWCODEC)
403 FE(DDSCAPS_MODEX)
404 FE(DDSCAPS_MIPMAP)
405 FE(DDSCAPS_RESERVED2)
406 FE(DDSCAPS_ALLOCONLOAD)
407 FE(DDSCAPS_VIDEOPORT)
408 FE(DDSCAPS_LOCALVIDMEM)
409 FE(DDSCAPS_NONLOCALVIDMEM)
410 FE(DDSCAPS_STANDARDVGAMODE)
411 FE(DDSCAPS_OPTIMIZED)
413 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
414 if (flags[i].mask & flagmask)
415 DUMP("%s ",flags[i].name);
416 DUMP("\n");
419 static void _dump_DDSD(DWORD flagmask) {
420 int i;
421 const struct {
422 DWORD mask;
423 char *name;
424 } flags[] = {
425 FE(DDSD_CAPS)
426 FE(DDSD_HEIGHT)
427 FE(DDSD_WIDTH)
428 FE(DDSD_PITCH)
429 FE(DDSD_BACKBUFFERCOUNT)
430 FE(DDSD_ZBUFFERBITDEPTH)
431 FE(DDSD_ALPHABITDEPTH)
432 FE(DDSD_PIXELFORMAT)
433 FE(DDSD_CKDESTOVERLAY)
434 FE(DDSD_CKDESTBLT)
435 FE(DDSD_CKSRCOVERLAY)
436 FE(DDSD_CKSRCBLT)
437 FE(DDSD_MIPMAPCOUNT)
438 FE(DDSD_REFRESHRATE)
439 FE(DDSD_LINEARSIZE)
440 FE(DDSD_LPSURFACE)
442 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
443 if (flags[i].mask & flagmask)
444 DUMP("%s ",flags[i].name);
445 DUMP("\n");
448 static void _dump_DDCOLORKEY(DWORD flagmask) {
449 int i;
450 const struct {
451 DWORD mask;
452 char *name;
453 } flags[] = {
454 #define FE(x) { x, #x},
455 FE(DDPF_ALPHAPIXELS)
456 FE(DDPF_ALPHA)
457 FE(DDPF_FOURCC)
458 FE(DDPF_PALETTEINDEXED4)
459 FE(DDPF_PALETTEINDEXEDTO8)
460 FE(DDPF_PALETTEINDEXED8)
461 FE(DDPF_RGB)
462 FE(DDPF_COMPRESSED)
463 FE(DDPF_RGBTOYUV)
464 FE(DDPF_YUV)
465 FE(DDPF_ZBUFFER)
466 FE(DDPF_PALETTEINDEXED1)
467 FE(DDPF_PALETTEINDEXED2)
468 FE(DDPF_ZPIXELS)
470 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
471 if (flags[i].mask & flagmask)
472 DUMP("%s ",flags[i].name);
473 DUMP("\n");
476 static void _dump_paletteformat(DWORD dwFlags) {
477 int i;
478 const struct {
479 DWORD mask;
480 char *name;
481 } flags[] = {
482 #define FE(x) { x, #x},
483 FE(DDPCAPS_4BIT)
484 FE(DDPCAPS_8BITENTRIES)
485 FE(DDPCAPS_8BIT)
486 FE(DDPCAPS_INITIALIZE)
487 FE(DDPCAPS_PRIMARYSURFACE)
488 FE(DDPCAPS_PRIMARYSURFACELEFT)
489 FE(DDPCAPS_ALLOW256)
490 FE(DDPCAPS_VSYNC)
491 FE(DDPCAPS_1BIT)
492 FE(DDPCAPS_2BIT)
493 FE(DDPCAPS_ALPHA)
495 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
496 if (flags[i].mask & dwFlags)
497 DUMP("%s ",flags[i].name);
498 DUMP("\n");
501 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
502 DUMP("Size : %ld\n", pf->dwSize);
503 if (pf->dwFlags)
504 _dump_DDCOLORKEY(pf->dwFlags);
505 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
506 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
507 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
508 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
511 static void _dump_colorkeyflag(DWORD ck) {
512 int i;
513 const struct {
514 DWORD mask;
515 char *name;
516 } flags[] = {
517 #define FE(x) { x, #x},
518 FE(DDCKEY_COLORSPACE)
519 FE(DDCKEY_DESTBLT)
520 FE(DDCKEY_DESTOVERLAY)
521 FE(DDCKEY_SRCBLT)
522 FE(DDCKEY_SRCOVERLAY)
524 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
525 if (flags[i].mask & ck)
526 DUMP("%s ",flags[i].name);
527 DUMP("\n");
530 /******************************************************************************
531 * IDirectDrawSurface methods
533 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
534 * DDS and DDS2 use those functions. (Function calls did not change (except
535 * using different DirectDrawSurfaceX version), just added flags and functions)
537 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
538 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
540 ICOM_THIS(IDirectDrawSurface4Impl,iface);
541 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
542 This,lprect,lpddsd,flags,(DWORD)hnd);
543 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
544 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
545 This,lprect,lpddsd,flags,(DWORD)hnd);
547 /* First, copy the Surface description */
548 *lpddsd = This->s.surface_desc;
549 TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
550 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
552 /* If asked only for a part, change the surface pointer */
553 if (lprect) {
554 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
555 lprect->top,lprect->left,lprect->bottom,lprect->right
557 lpddsd->y.lpSurface = (LPVOID) ((char *) This->s.surface_desc.y.lpSurface +
558 (lprect->top*This->s.surface_desc.lPitch) +
559 (lprect->left*(This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8)));
560 } else {
561 assert(This->s.surface_desc.y.lpSurface);
563 return DD_OK;
566 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
567 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
569 ICOM_THIS(IDirectDrawSurface4Impl,iface);
570 TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
571 return DD_OK;
574 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
575 if (This->s.ddraw->d.pixel_convert != NULL)
576 This->s.ddraw->d.pixel_convert(This->s.surface_desc.y.lpSurface,
577 This->t.xlib.image->data,
578 This->s.surface_desc.dwWidth,
579 This->s.surface_desc.dwHeight,
580 This->s.surface_desc.lPitch,
581 This->s.palette);
583 #ifdef HAVE_LIBXXSHM
584 if (This->s.ddraw->e.xlib.xshm_active)
585 TSXShmPutImage(display,
586 This->s.ddraw->d.drawable,
587 DefaultGCOfScreen(X11DRV_GetXScreen()),
588 This->t.xlib.image,
589 0, 0, 0, 0,
590 This->t.xlib.image->width,
591 This->t.xlib.image->height,
592 False);
593 else
594 #endif
595 TSXPutImage( display,
596 This->s.ddraw->d.drawable,
597 DefaultGCOfScreen(X11DRV_GetXScreen()),
598 This->t.xlib.image,
599 0, 0, 0, 0,
600 This->t.xlib.image->width,
601 This->t.xlib.image->height);
604 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
605 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
607 ICOM_THIS(IDirectDrawSurface4Impl,iface);
608 TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
610 if (!This->s.ddraw->d.paintable)
611 return DD_OK;
613 /* Only redraw the screen when unlocking the buffer that is on screen */
614 if ((This->t.xlib.image != NULL) &&
615 (This->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
616 Xlib_copy_surface_on_screen(This);
618 if (This->s.palette && This->s.palette->cm)
619 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
622 return DD_OK;
625 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
626 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
628 ICOM_THIS(IDirectDrawSurface4Impl,iface);
629 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
630 #ifdef HAVE_LIBXXF86DGA
631 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
632 if (!iflipto) {
633 if (This->s.backbuffer)
634 iflipto = This->s.backbuffer;
635 else
636 iflipto = This;
638 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
640 if (iflipto->s.palette && iflipto->s.palette->cm) {
641 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
643 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
645 if (iflipto!=This) {
646 int tmp;
647 LPVOID ptmp;
649 tmp = This->t.dga.fb_height;
650 This->t.dga.fb_height = iflipto->t.dga.fb_height;
651 iflipto->t.dga.fb_height = tmp;
653 ptmp = This->s.surface_desc.y.lpSurface;
654 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
655 iflipto->s.surface_desc.y.lpSurface = ptmp;
657 return DD_OK;
658 #else /* defined(HAVE_LIBXXF86DGA) */
659 return E_UNEXPECTED;
660 #endif /* defined(HAVE_LIBXXF86DGA) */
663 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
664 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
666 ICOM_THIS(IDirectDrawSurface4Impl,iface);
667 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
668 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
670 #ifdef HAVE_MESAGL
671 if ((This->s.d3d_device != NULL) ||
672 ((This->s.backbuffer != NULL) && (This->s.backbuffer->s.d3d_device != NULL))) {
673 TRACE(ddraw," - OpenGL flip\n");
674 ENTER_GL();
675 glXSwapBuffers(display,
676 This->s.ddraw->d.drawable);
677 LEAVE_GL();
679 return DD_OK;
681 #endif /* defined(HAVE_MESAGL) */
683 if (!This->s.ddraw->d.paintable)
684 return DD_OK;
686 if (!iflipto) {
687 if (This->s.backbuffer)
688 iflipto = This->s.backbuffer;
689 else
690 iflipto = This;
693 Xlib_copy_surface_on_screen(This);
695 if (iflipto->s.palette && iflipto->s.palette->cm) {
696 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
698 if (iflipto!=This) {
699 XImage *tmp;
700 LPVOID *surf;
701 tmp = This->t.xlib.image;
702 This->t.xlib.image = iflipto->t.xlib.image;
703 iflipto->t.xlib.image = tmp;
704 surf = This->s.surface_desc.y.lpSurface;
705 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
706 iflipto->s.surface_desc.y.lpSurface = surf;
708 return DD_OK;
712 /* The IDirectDrawSurface4::SetPalette method attaches the specified
713 * DirectDrawPalette object to a surface. The surface uses this palette for all
714 * subsequent operations. The palette change takes place immediately.
716 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
717 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
719 ICOM_THIS(IDirectDrawSurface4Impl,iface);
720 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
721 int i;
722 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
724 if (ipal == NULL) {
725 if( This->s.palette != NULL )
726 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
727 This->s.palette = ipal;
729 return DD_OK;
732 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
734 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
735 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
737 if (!Options.managed)
738 TSXInstallColormap(display,ipal->cm);
740 for (i=0;i<256;i++) {
741 XColor xc;
743 xc.red = ipal->palents[i].peRed<<8;
744 xc.blue = ipal->palents[i].peBlue<<8;
745 xc.green = ipal->palents[i].peGreen<<8;
746 xc.flags = DoRed|DoBlue|DoGreen;
747 xc.pixel = i;
748 TSXStoreColor(display,ipal->cm,&xc);
750 TSXInstallColormap(display,ipal->cm);
753 /* According to spec, we are only supposed to
754 * AddRef if this is not the same palette.
756 if( This->s.palette != ipal )
758 if( ipal != NULL )
759 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
760 if( This->s.palette != NULL )
761 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
762 This->s.palette = ipal;
764 /* I think that we need to attach it to all backbuffers...*/
765 if( This->s.backbuffer ) {
766 if( This->s.backbuffer->s.palette )
767 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
768 This->s.backbuffer->s.palette = ipal;
769 if( ipal )
770 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
772 /* Perform the refresh */
773 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
775 return DD_OK;
778 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
779 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
781 ICOM_THIS(IDirectDrawSurface4Impl,iface);
782 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
783 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
784 #ifdef HAVE_LIBXXF86DGA
785 /* According to spec, we are only supposed to
786 * AddRef if this is not the same palette.
788 if( This->s.palette != ipal )
790 if( ipal != NULL )
791 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
792 if( This->s.palette != NULL )
793 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
794 This->s.palette = ipal;
796 /* I think that we need to attach it to all backbuffers...*/
797 if( This->s.backbuffer ) {
798 if( This->s.backbuffer->s.palette )
799 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
800 This->s.backbuffer->s.palette = ipal;
801 if ( ipal )
802 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
804 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
806 return DD_OK;
807 #else /* defined(HAVE_LIBXXF86DGA) */
808 return E_UNEXPECTED;
809 #endif /* defined(HAVE_LIBXXF86DGA) */
814 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
816 int x, y;
817 LPBYTE first;
819 /* Do first row */
821 #define COLORFILL_ROW(type) { \
822 type *d = (type *) buf; \
823 for (x = 0; x < width; x++) \
824 d[x] = (type) color; \
825 break; \
828 switch(bpp) {
829 case 1: COLORFILL_ROW(BYTE)
830 case 2: COLORFILL_ROW(WORD)
831 case 4: COLORFILL_ROW(DWORD)
832 default:
833 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
834 return DDERR_UNSUPPORTED;
837 #undef COLORFILL_ROW
839 /* Now copy first row */
840 first = buf;
841 for (y = 1; y < height; y++) {
842 buf += lPitch;
843 memcpy(buf, first, width * bpp);
846 return DD_OK;
849 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
850 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
852 ICOM_THIS(IDirectDrawSurface4Impl,iface);
853 RECT xdst,xsrc;
854 DDSURFACEDESC ddesc,sdesc;
855 HRESULT ret = DD_OK;
856 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
857 int x, y;
858 LPBYTE dbuf, sbuf;
860 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
862 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
863 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
865 if (TRACE_ON(ddraw)) {
866 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
867 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
868 TRACE(ddraw,"\tflags: ");
869 _dump_DDBLT(dwFlags);
870 if (dwFlags & DDBLT_DDFX) {
871 TRACE(ddraw," blitfx: \n");
872 _dump_DDBLTFX(lpbltfx->dwDDFX);
876 if (rdst) {
877 memcpy(&xdst,rdst,sizeof(xdst));
878 } else {
879 xdst.top = 0;
880 xdst.bottom = ddesc.dwHeight;
881 xdst.left = 0;
882 xdst.right = ddesc.dwWidth;
885 if (rsrc) {
886 memcpy(&xsrc,rsrc,sizeof(xsrc));
887 } else {
888 if (src) {
889 xsrc.top = 0;
890 xsrc.bottom = sdesc.dwHeight;
891 xsrc.left = 0;
892 xsrc.right = sdesc.dwWidth;
893 } else {
894 memset(&xsrc,0,sizeof(xsrc));
898 bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
899 srcheight = xsrc.bottom - xsrc.top;
900 srcwidth = xsrc.right - xsrc.left;
901 dstheight = xdst.bottom - xdst.top;
902 dstwidth = xdst.right - xdst.left;
903 width = (xdst.right - xdst.left) * bpp;
904 dbuf = (BYTE *) ddesc.y.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
906 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
908 /* First, all the 'source-less' blits */
909 if (dwFlags & DDBLT_COLORFILL) {
910 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
911 ddesc.lPitch, lpbltfx->b.dwFillColor);
912 dwFlags &= ~DDBLT_COLORFILL;
915 if (dwFlags & DDBLT_DEPTHFILL) {
916 #ifdef HAVE_MESAGL
917 GLboolean ztest;
919 /* Clears the screen */
920 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
921 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
922 glGetBooleanv(GL_DEPTH_TEST, &ztest);
923 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
924 glClear(GL_DEPTH_BUFFER_BIT);
925 glDepthMask(ztest);
927 dwFlags &= ~(DDBLT_DEPTHFILL);
928 #endif /* defined(HAVE_MESAGL) */
931 if (dwFlags & DDBLT_ROP) {
932 /* Catch some degenerate cases here */
933 switch(lpbltfx->dwROP) {
934 case BLACKNESS:
935 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
936 break;
937 case 0xAA0029: /* No-op */
938 break;
939 case WHITENESS:
940 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
941 break;
942 default:
943 FIXME(ddraw, "Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->b.lpDDSPattern);
944 goto error;
946 dwFlags &= ~DDBLT_ROP;
949 if (dwFlags & DDBLT_DDROPS) {
950 FIXME(ddraw, "\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->b.lpDDSPattern);
953 /* Now the 'with source' blits */
954 if (src) {
955 LPBYTE sbase;
956 int sx, xinc, sy, yinc;
958 sbase = (BYTE *) sdesc.y.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
959 xinc = (srcwidth << 16) / dstwidth;
960 yinc = (srcheight << 16) / dstheight;
962 if (!dwFlags) {
964 /* No effects, we can cheat here */
965 if (dstwidth == srcwidth) {
966 if (dstheight == srcheight) {
967 /* No stretching in either direction. This needs to be as fast as possible */
968 sbuf = sbase;
969 for (y = 0; y < dstheight; y++) {
970 memcpy(dbuf, sbuf, width);
971 sbuf += sdesc.lPitch;
972 dbuf += ddesc.lPitch;
974 } else {
975 /* Stretching in Y direction only */
976 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
977 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
978 memcpy(dbuf, sbuf, width);
979 dbuf += ddesc.lPitch;
982 } else {
983 /* Stretching in X direction */
984 int last_sy = -1;
985 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
986 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
988 if ((sy >> 16) == (last_sy >> 16)) {
989 /* Same as last row - copy already stretched row */
990 memcpy(dbuf, dbuf - ddesc.lPitch, width);
991 } else {
993 #define STRETCH_ROW(type) { \
994 type *s = (type *) sbuf, *d = (type *) dbuf; \
995 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
996 d[x] = s[sx >> 16]; \
997 break; \
1000 switch(bpp) {
1001 case 1: STRETCH_ROW(BYTE)
1002 case 2: STRETCH_ROW(WORD)
1003 case 4: STRETCH_ROW(DWORD)
1004 default:
1005 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
1006 ret = DDERR_UNSUPPORTED;
1007 goto error;
1010 #undef STRETCH_ROW
1013 last_sy = sy;
1014 dbuf += ddesc.lPitch;
1017 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1018 DWORD keylow, keyhigh;
1020 if (dwFlags & DDBLT_KEYSRC) {
1021 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1022 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1023 } else {
1024 /* I'm not sure if this is correct */
1025 FIXME(ddraw, "DDBLT_KEYDEST not fully supported yet.\n");
1026 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1027 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1030 #define COPYROW_COLORKEY(type) { \
1031 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1032 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1033 tmp = s[sx >> 16]; \
1034 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1036 break; \
1039 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1040 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1042 switch (bpp) {
1043 case 1: COPYROW_COLORKEY(BYTE)
1044 case 2: COPYROW_COLORKEY(WORD)
1045 case 4: COPYROW_COLORKEY(DWORD)
1046 default:
1047 FIXME(ddraw, "%s color-keyed blit not implemented for bpp %d!\n",
1048 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1049 ret = DDERR_UNSUPPORTED;
1050 goto error;
1052 dbuf += ddesc.lPitch;
1055 #undef COPYROW_COLORKEY
1057 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1062 error:
1064 if (dwFlags && FIXME_ON(ddraw)) {
1065 FIXME(ddraw,"\tUnsupported flags: ");
1066 _dump_DDBLT(dwFlags);
1069 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1070 if (src) IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1072 return DD_OK;
1075 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1076 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1078 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1079 int bpp, w, h, x, y;
1080 DDSURFACEDESC ddesc,sdesc;
1081 HRESULT ret = DD_OK;
1082 LPBYTE sbuf, dbuf;
1085 if (TRACE_ON(ddraw)) {
1086 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1087 This,dstx,dsty,src,rsrc,trans
1089 FIXME(ddraw," trans:");
1090 if (FIXME_ON(ddraw))
1091 _dump_DDBLTFAST(trans);
1092 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1094 /* We need to lock the surfaces, or we won't get refreshes when done. */
1095 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1096 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1098 bpp = This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
1099 sbuf = (BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1100 dbuf = (BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1103 h=rsrc->bottom-rsrc->top;
1104 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1105 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1106 if (h<0) h=0;
1108 w=rsrc->right-rsrc->left;
1109 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1110 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1111 if (w<0) w=0;
1113 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1114 DWORD keylow, keyhigh;
1115 if (trans & DDBLTFAST_SRCCOLORKEY) {
1116 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1117 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1118 } else {
1119 /* I'm not sure if this is correct */
1120 FIXME(ddraw, "DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1121 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1122 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1125 #define COPYBOX_COLORKEY(type) { \
1126 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1127 s = (type *) ((BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1128 d = (type *) ((BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1129 for (y = 0; y < h; y++) { \
1130 for (x = 0; x < w; x++) { \
1131 tmp = s[x]; \
1132 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1134 (LPBYTE)s += sdesc.lPitch; \
1135 (LPBYTE)d += ddesc.lPitch; \
1137 break; \
1140 switch (bpp) {
1141 case 1: COPYBOX_COLORKEY(BYTE)
1142 case 2: COPYBOX_COLORKEY(WORD)
1143 case 4: COPYBOX_COLORKEY(DWORD)
1144 default:
1145 FIXME(ddraw, "Source color key blitting not supported for bpp %d\n", bpp*8);
1146 ret = DDERR_UNSUPPORTED;
1147 goto error;
1150 #undef COPYBOX_COLORKEY
1152 } else {
1153 int width = w * bpp;
1155 for (y = 0; y < h; y++) {
1156 memcpy(dbuf, sbuf, width);
1157 sbuf += sdesc.lPitch;
1158 dbuf += ddesc.lPitch;
1162 error:
1164 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1165 IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1166 return ret;
1169 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1170 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1172 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1173 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1174 This,ddbltbatch,x,y
1176 return DD_OK;
1179 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1180 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1182 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1183 TRACE(ddraw,"(%p)->GetCaps(%p)\n",This,caps);
1184 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1185 return DD_OK;
1188 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1189 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1190 ) {
1191 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1192 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
1193 This,ddsd);
1195 /* Simply copy the surface description stored in the object */
1196 *ddsd = This->s.surface_desc;
1198 if (TRACE_ON(ddraw)) {
1199 DUMP(" flags: ");
1200 _dump_DDSD(ddsd->dwFlags);
1201 if (ddsd->dwFlags & DDSD_CAPS) {
1202 DUMP(" caps: ");
1203 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
1205 if (ddsd->dwFlags & DDSD_PIXELFORMAT) {
1206 DUMP(" pixel format : \n");
1207 _dump_pixelformat(&(ddsd->ddpfPixelFormat));
1211 return DD_OK;
1214 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1215 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1216 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1218 return ++(This->ref);
1221 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1222 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1223 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1225 #ifdef HAVE_LIBXXF86DGA
1226 if (!--(This->ref)) {
1227 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1228 /* clear out of surface list */
1229 if (This->t.dga.fb_height == -1) {
1230 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1231 } else {
1232 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1235 /* Free the backbuffer */
1236 if (This->s.backbuffer)
1237 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1239 HeapFree(GetProcessHeap(),0,This);
1240 return 0;
1242 #endif /* defined(HAVE_LIBXXF86DGA) */
1243 return This->ref;
1246 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1247 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1248 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1250 if (!--(This->ref)) {
1251 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1253 if( This->s.backbuffer )
1254 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1256 if (This->t.xlib.image != NULL) {
1257 if (This->s.ddraw->d.pixel_convert != NULL) {
1258 /* In pixel conversion mode, there are two buffers to release... */
1259 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1261 #ifdef HAVE_LIBXXSHM
1262 if (This->s.ddraw->e.xlib.xshm_active) {
1263 TSXShmDetach(display, &(This->t.xlib.shminfo));
1264 TSXDestroyImage(This->t.xlib.image);
1265 shmdt(This->t.xlib.shminfo.shmaddr);
1266 } else {
1267 #endif
1268 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1269 This->t.xlib.image->data = NULL;
1270 TSXDestroyImage(This->t.xlib.image);
1271 #ifdef HAVE_LIBXXSHM
1273 #endif
1275 } else {
1276 This->t.xlib.image->data = NULL;
1278 #ifdef HAVE_LIBXXSHM
1279 if (This->s.ddraw->e.xlib.xshm_active) {
1280 TSXShmDetach(display, &(This->t.xlib.shminfo));
1281 TSXDestroyImage(This->t.xlib.image);
1282 shmdt(This->t.xlib.shminfo.shmaddr);
1283 } else {
1284 #endif
1285 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1286 TSXDestroyImage(This->t.xlib.image);
1287 #ifdef HAVE_LIBXXSHM
1289 #endif
1292 This->t.xlib.image = 0;
1293 } else {
1294 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1297 if (This->s.palette)
1298 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1300 HeapFree(GetProcessHeap(),0,This);
1301 return 0;
1304 return This->ref;
1307 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1308 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1310 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1311 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1312 This, lpddsd, lpdsf);
1314 if (TRACE_ON(ddraw)) {
1315 TRACE(ddraw," caps ");
1316 _dump_DDSCAPS(lpddsd->dwCaps);
1319 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1320 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1321 return E_FAIL;
1324 /* FIXME: should handle more than one backbuffer */
1325 *lpdsf = (LPDIRECTDRAWSURFACE4)This->s.backbuffer;
1327 if( This->s.backbuffer )
1328 IDirectDrawSurface4_AddRef( (IDirectDrawSurface4*)This->s.backbuffer );
1330 return DD_OK;
1333 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1334 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1336 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1337 TRACE(ddraw,"(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1339 return DDERR_ALREADYINITIALIZED;
1342 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1343 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1345 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1346 TRACE(ddraw,"(%p)->(%p)\n",This,pf);
1348 *pf = This->s.surface_desc.ddpfPixelFormat;
1350 return DD_OK;
1353 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1354 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1355 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,dwFlags);
1356 return DD_OK;
1359 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1360 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1362 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1363 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,x1,x2);
1364 return DD_OK;
1367 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1368 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1370 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1371 FIXME(ddraw,"(%p)->(%p),stub!\n",This,clipper);
1372 return DD_OK;
1375 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1376 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1378 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1379 FIXME(ddraw,"(%p)->(%p),stub!\n",This,surf);
1381 IDirectDrawSurface4_AddRef(iface);
1383 /* This hack will be enough for the moment */
1384 if (This->s.backbuffer == NULL)
1385 This->s.backbuffer = (IDirectDrawSurface4Impl*)surf;
1386 return DD_OK;
1389 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1390 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1391 FIXME(ddraw,"(%p)->GetDC(%p)\n",This,lphdc);
1392 *lphdc = BeginPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1393 return DD_OK;
1396 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1397 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1398 DDSURFACEDESC desc;
1399 DWORD x, y;
1401 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1402 EndPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1404 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1405 I fill it with 'dummy' values to have something on the screen */
1406 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1407 for (y = 0; y < desc.dwHeight; y++) {
1408 for (x = 0; x < desc.dwWidth; x++) {
1409 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) This + x + y;
1412 IDirectDrawSurface4_Unlock(iface,NULL);
1414 return DD_OK;
1418 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1419 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1420 char xrefiid[50];
1422 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1423 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
1425 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1426 * the same interface. And IUnknown does that too of course.
1428 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1429 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1430 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1431 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1432 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1434 *obj = This;
1435 IDirectDrawSurface4_AddRef(iface);
1437 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1439 return S_OK;
1441 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1443 /* Texture interface */
1444 *obj = d3dtexture2_create(This);
1445 IDirectDrawSurface4_AddRef(iface);
1447 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1449 return S_OK;
1451 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1453 /* Texture interface */
1454 *obj = d3dtexture_create(This);
1455 IDirectDrawSurface4_AddRef(iface);
1457 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1459 return S_OK;
1461 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj))
1463 /* It is the OpenGL Direct3D Device */
1464 IDirectDrawSurface4_AddRef(iface);
1466 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1468 return S_OK;
1471 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
1472 return OLE_E_ENUM_NOMORE;
1475 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1476 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1477 TRACE(ddraw,"(%p)->(), stub!\n",This);
1478 return DD_OK; /* hmm */
1481 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1482 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1483 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,context,esfcb);
1485 /* For the moment, only enumerating the back buffer */
1486 if (This->s.backbuffer != NULL) {
1487 TRACE(ddraw, "Enumerating back-buffer (%p)\n", This->s.backbuffer);
1488 if (esfcb((LPDIRECTDRAWSURFACE) This->s.backbuffer, &(This->s.backbuffer->s.surface_desc), context) == DDENUMRET_CANCEL)
1489 return DD_OK;
1492 return DD_OK;
1495 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1496 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1497 FIXME(ddraw,"(%p)->(),stub!\n",This);
1498 return DD_OK;
1501 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1502 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1504 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1505 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1506 if (TRACE_ON(ddraw)) {
1507 DUMP(" (0x%08lx <-> 0x%08lx) - ",
1508 ckey->dwColorSpaceLowValue,
1509 ckey->dwColorSpaceHighValue);
1510 _dump_colorkeyflag(dwFlags);
1513 /* If this surface was loaded as a texture, call also the texture
1514 SetColorKey callback */
1515 if (This->s.texture) {
1516 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1519 if( dwFlags & DDCKEY_SRCBLT )
1521 dwFlags &= ~DDCKEY_SRCBLT;
1522 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1523 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1526 if( dwFlags & DDCKEY_DESTBLT )
1528 dwFlags &= ~DDCKEY_DESTBLT;
1529 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1530 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1533 if( dwFlags & DDCKEY_SRCOVERLAY )
1535 dwFlags &= ~DDCKEY_SRCOVERLAY;
1536 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1537 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1540 if( dwFlags & DDCKEY_DESTOVERLAY )
1542 dwFlags &= ~DDCKEY_DESTOVERLAY;
1543 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1544 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1547 if( dwFlags )
1549 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1552 return DD_OK;
1556 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1557 LPDIRECTDRAWSURFACE4 iface,
1558 LPRECT lpRect )
1560 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1561 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpRect);
1563 return DD_OK;
1566 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1567 LPDIRECTDRAWSURFACE4 iface,
1568 DWORD dwFlags,
1569 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1571 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1572 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",This,dwFlags,lpDDSAttachedSurface);
1574 return DD_OK;
1577 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1578 LPDIRECTDRAWSURFACE4 iface,
1579 DWORD dwFlags,
1580 LPVOID lpContext,
1581 LPDDENUMSURFACESCALLBACK lpfnCallback )
1583 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1584 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1585 lpContext, lpfnCallback );
1587 return DD_OK;
1590 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1591 LPDIRECTDRAWSURFACE4 iface,
1592 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1594 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1595 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDClipper);
1597 return DD_OK;
1600 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1601 LPDIRECTDRAWSURFACE4 iface,
1602 DWORD dwFlags,
1603 LPDDCOLORKEY lpDDColorKey )
1605 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1606 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1608 if( dwFlags & DDCKEY_SRCBLT ) {
1609 dwFlags &= ~DDCKEY_SRCBLT;
1610 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1613 if( dwFlags & DDCKEY_DESTBLT )
1615 dwFlags &= ~DDCKEY_DESTBLT;
1616 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1619 if( dwFlags & DDCKEY_SRCOVERLAY )
1621 dwFlags &= ~DDCKEY_SRCOVERLAY;
1622 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1625 if( dwFlags & DDCKEY_DESTOVERLAY )
1627 dwFlags &= ~DDCKEY_DESTOVERLAY;
1628 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1631 if( dwFlags )
1633 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1636 return DD_OK;
1639 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1640 LPDIRECTDRAWSURFACE4 iface,
1641 DWORD dwFlags )
1643 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1644 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1646 return DD_OK;
1649 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1650 LPDIRECTDRAWSURFACE4 iface,
1651 LPDIRECTDRAWPALETTE* lplpDDPalette )
1653 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1654 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDPalette);
1656 return DD_OK;
1659 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1660 LPDIRECTDRAWSURFACE4 iface,
1661 LONG lX,
1662 LONG lY)
1664 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1665 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1667 return DD_OK;
1670 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1671 LPDIRECTDRAWSURFACE4 iface,
1672 LPRECT lpSrcRect,
1673 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1674 LPRECT lpDestRect,
1675 DWORD dwFlags,
1676 LPDDOVERLAYFX lpDDOverlayFx )
1678 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1679 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1680 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1682 return DD_OK;
1685 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1686 LPDIRECTDRAWSURFACE4 iface,
1687 DWORD dwFlags )
1689 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1690 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1692 return DD_OK;
1695 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1696 LPDIRECTDRAWSURFACE4 iface,
1697 DWORD dwFlags,
1698 LPDIRECTDRAWSURFACE4 lpDDSReference )
1700 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1701 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1703 return DD_OK;
1706 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1707 LPDIRECTDRAWSURFACE4 iface,
1708 LPVOID* lplpDD )
1710 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1711 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDD);
1713 /* Not sure about that... */
1714 *lplpDD = (void *) This->s.ddraw;
1716 return DD_OK;
1719 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1720 LPDIRECTDRAWSURFACE4 iface,
1721 DWORD dwFlags )
1723 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1724 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1726 return DD_OK;
1729 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1730 LPDIRECTDRAWSURFACE4 iface,
1731 DWORD dwFlags )
1733 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1734 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1736 return DD_OK;
1739 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1740 LPDIRECTDRAWSURFACE4 iface,
1741 LPDDSURFACEDESC lpDDSD,
1742 DWORD dwFlags )
1744 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1745 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1747 return DD_OK;
1750 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1751 REFGUID guidTag,
1752 LPVOID lpData,
1753 DWORD cbSize,
1754 DWORD dwFlags) {
1755 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1756 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1758 return DD_OK;
1761 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1762 REFGUID guidTag,
1763 LPVOID lpBuffer,
1764 LPDWORD lpcbBufferSize) {
1765 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1766 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1768 return DD_OK;
1771 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
1772 REFGUID guidTag) {
1773 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1774 FIXME(ddraw, "(%p)->(%p)\n", This, guidTag);
1776 return DD_OK;
1779 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
1780 LPDWORD lpValue) {
1781 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1782 FIXME(ddraw, "(%p)->(%p)\n", This, lpValue);
1784 return DD_OK;
1787 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
1788 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1789 FIXME(ddraw, "(%p)\n", This);
1791 return DD_OK;
1794 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = {
1795 IDirectDrawSurface4Impl_QueryInterface,
1796 IDirectDrawSurface4Impl_AddRef,
1797 DGA_IDirectDrawSurface4Impl_Release,
1798 IDirectDrawSurface4Impl_AddAttachedSurface,
1799 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1800 IDirectDrawSurface4Impl_Blt,
1801 IDirectDrawSurface4Impl_BltBatch,
1802 IDirectDrawSurface4Impl_BltFast,
1803 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1804 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1805 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1806 DGA_IDirectDrawSurface4Impl_Flip,
1807 IDirectDrawSurface4Impl_GetAttachedSurface,
1808 IDirectDrawSurface4Impl_GetBltStatus,
1809 IDirectDrawSurface4Impl_GetCaps,
1810 IDirectDrawSurface4Impl_GetClipper,
1811 IDirectDrawSurface4Impl_GetColorKey,
1812 IDirectDrawSurface4Impl_GetDC,
1813 IDirectDrawSurface4Impl_GetFlipStatus,
1814 IDirectDrawSurface4Impl_GetOverlayPosition,
1815 IDirectDrawSurface4Impl_GetPalette,
1816 IDirectDrawSurface4Impl_GetPixelFormat,
1817 IDirectDrawSurface4Impl_GetSurfaceDesc,
1818 IDirectDrawSurface4Impl_Initialize,
1819 IDirectDrawSurface4Impl_IsLost,
1820 IDirectDrawSurface4Impl_Lock,
1821 IDirectDrawSurface4Impl_ReleaseDC,
1822 IDirectDrawSurface4Impl_Restore,
1823 IDirectDrawSurface4Impl_SetClipper,
1824 IDirectDrawSurface4Impl_SetColorKey,
1825 IDirectDrawSurface4Impl_SetOverlayPosition,
1826 DGA_IDirectDrawSurface4Impl_SetPalette,
1827 DGA_IDirectDrawSurface4Impl_Unlock,
1828 IDirectDrawSurface4Impl_UpdateOverlay,
1829 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1830 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1831 IDirectDrawSurface4Impl_GetDDInterface,
1832 IDirectDrawSurface4Impl_PageLock,
1833 IDirectDrawSurface4Impl_PageUnlock,
1834 IDirectDrawSurface4Impl_SetSurfaceDesc,
1835 IDirectDrawSurface4Impl_SetPrivateData,
1836 IDirectDrawSurface4Impl_GetPrivateData,
1837 IDirectDrawSurface4Impl_FreePrivateData,
1838 IDirectDrawSurface4Impl_GetUniquenessValue,
1839 IDirectDrawSurface4Impl_ChangeUniquenessValue
1842 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt = {
1843 IDirectDrawSurface4Impl_QueryInterface,
1844 IDirectDrawSurface4Impl_AddRef,
1845 Xlib_IDirectDrawSurface4Impl_Release,
1846 IDirectDrawSurface4Impl_AddAttachedSurface,
1847 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1848 IDirectDrawSurface4Impl_Blt,
1849 IDirectDrawSurface4Impl_BltBatch,
1850 IDirectDrawSurface4Impl_BltFast,
1851 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1852 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1853 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1854 Xlib_IDirectDrawSurface4Impl_Flip,
1855 IDirectDrawSurface4Impl_GetAttachedSurface,
1856 IDirectDrawSurface4Impl_GetBltStatus,
1857 IDirectDrawSurface4Impl_GetCaps,
1858 IDirectDrawSurface4Impl_GetClipper,
1859 IDirectDrawSurface4Impl_GetColorKey,
1860 IDirectDrawSurface4Impl_GetDC,
1861 IDirectDrawSurface4Impl_GetFlipStatus,
1862 IDirectDrawSurface4Impl_GetOverlayPosition,
1863 IDirectDrawSurface4Impl_GetPalette,
1864 IDirectDrawSurface4Impl_GetPixelFormat,
1865 IDirectDrawSurface4Impl_GetSurfaceDesc,
1866 IDirectDrawSurface4Impl_Initialize,
1867 IDirectDrawSurface4Impl_IsLost,
1868 IDirectDrawSurface4Impl_Lock,
1869 IDirectDrawSurface4Impl_ReleaseDC,
1870 IDirectDrawSurface4Impl_Restore,
1871 IDirectDrawSurface4Impl_SetClipper,
1872 IDirectDrawSurface4Impl_SetColorKey,
1873 IDirectDrawSurface4Impl_SetOverlayPosition,
1874 Xlib_IDirectDrawSurface4Impl_SetPalette,
1875 Xlib_IDirectDrawSurface4Impl_Unlock,
1876 IDirectDrawSurface4Impl_UpdateOverlay,
1877 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1878 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1879 IDirectDrawSurface4Impl_GetDDInterface,
1880 IDirectDrawSurface4Impl_PageLock,
1881 IDirectDrawSurface4Impl_PageUnlock,
1882 IDirectDrawSurface4Impl_SetSurfaceDesc,
1883 IDirectDrawSurface4Impl_SetPrivateData,
1884 IDirectDrawSurface4Impl_GetPrivateData,
1885 IDirectDrawSurface4Impl_FreePrivateData,
1886 IDirectDrawSurface4Impl_GetUniquenessValue,
1887 IDirectDrawSurface4Impl_ChangeUniquenessValue
1890 /******************************************************************************
1891 * DirectDrawCreateClipper (DDRAW.7)
1893 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1894 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1895 LPUNKNOWN pUnkOuter)
1897 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
1898 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
1900 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
1901 (*ilplpDDClipper)->lpvtbl = &ddclipvt;
1902 (*ilplpDDClipper)->ref = 1;
1904 return DD_OK;
1907 /******************************************************************************
1908 * IDirectDrawClipper
1910 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
1911 LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
1913 ICOM_THIS(IDirectDrawClipperImpl,iface);
1914 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
1915 return DD_OK;
1918 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
1919 ICOM_THIS(IDirectDrawClipperImpl,iface);
1920 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1922 This->ref--;
1923 if (This->ref)
1924 return This->ref;
1925 HeapFree(GetProcessHeap(),0,This);
1926 return 0;
1929 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
1930 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
1932 ICOM_THIS(IDirectDrawClipperImpl,iface);
1933 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
1934 if (hmm) *hmm=0;
1935 return DD_OK;
1938 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
1939 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
1941 ICOM_THIS(IDirectDrawClipperImpl,iface);
1942 FIXME(ddraw,"(%p,%p,%ld),stub!\n",This,lprgn,hmm);
1943 return DD_OK;
1946 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
1947 LPDIRECTDRAWCLIPPER iface,
1948 REFIID riid,
1949 LPVOID* ppvObj )
1951 ICOM_THIS(IDirectDrawClipperImpl,iface);
1952 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
1953 return OLE_E_ENUM_NOMORE;
1956 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
1958 ICOM_THIS(IDirectDrawClipperImpl,iface);
1959 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1960 return ++(This->ref);
1963 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
1964 LPDIRECTDRAWCLIPPER iface,
1965 HWND* HWndPtr )
1967 ICOM_THIS(IDirectDrawClipperImpl,iface);
1968 FIXME(ddraw,"(%p)->(%p),stub!\n",This,HWndPtr);
1969 return DD_OK;
1972 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
1973 LPDIRECTDRAWCLIPPER iface,
1974 LPDIRECTDRAW lpDD,
1975 DWORD dwFlags )
1977 ICOM_THIS(IDirectDrawClipperImpl,iface);
1978 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
1979 return DD_OK;
1982 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
1983 LPDIRECTDRAWCLIPPER iface,
1984 BOOL* lpbChanged )
1986 ICOM_THIS(IDirectDrawClipperImpl,iface);
1987 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpbChanged);
1988 return DD_OK;
1991 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt = {
1992 IDirectDrawClipperImpl_QueryInterface,
1993 IDirectDrawClipperImpl_AddRef,
1994 IDirectDrawClipperImpl_Release,
1995 IDirectDrawClipperImpl_GetClipList,
1996 IDirectDrawClipperImpl_GetHWnd,
1997 IDirectDrawClipperImpl_Initialize,
1998 IDirectDrawClipperImpl_IsClipListChanged,
1999 IDirectDrawClipperImpl_SetClipList,
2000 IDirectDrawClipperImpl_SetHwnd
2004 /******************************************************************************
2005 * IDirectDrawPalette
2007 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2008 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2010 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2011 int i;
2013 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2014 This,x,start,count,palent);
2016 /* No palette created and not in depth-convertion mode -> BUG ! */
2017 if ((This->cm == NULL) &&
2018 (This->ddraw->d.palette_convert == NULL))
2020 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
2021 return DDERR_GENERIC;
2023 for (i=0;i<count;i++) {
2024 palent[i].peRed = This->palents[start+i].peRed;
2025 palent[i].peBlue = This->palents[start+i].peBlue;
2026 palent[i].peGreen = This->palents[start+i].peGreen;
2027 palent[i].peFlags = This->palents[start+i].peFlags;
2030 return DD_OK;
2033 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2034 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2036 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2037 XColor xc;
2038 int i;
2040 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2041 This,x,start,count,palent
2043 for (i=0;i<count;i++) {
2044 xc.red = palent[i].peRed<<8;
2045 xc.blue = palent[i].peBlue<<8;
2046 xc.green = palent[i].peGreen<<8;
2047 xc.flags = DoRed|DoBlue|DoGreen;
2048 xc.pixel = start+i;
2050 if (This->cm)
2051 TSXStoreColor(display,This->cm,&xc);
2053 This->palents[start+i].peRed = palent[i].peRed;
2054 This->palents[start+i].peBlue = palent[i].peBlue;
2055 This->palents[start+i].peGreen = palent[i].peGreen;
2056 This->palents[start+i].peFlags = palent[i].peFlags;
2059 /* Now, if we are in 'depth conversion mode', update the screen palette */
2060 if (This->ddraw->d.palette_convert != NULL)
2061 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2063 return DD_OK;
2066 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2067 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2069 #ifdef HAVE_LIBXXF86DGA
2070 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2071 XColor xc;
2072 Colormap cm;
2073 int i;
2075 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2076 This,x,start,count,palent
2078 if (!This->cm) /* should not happen */ {
2079 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
2080 return DDERR_GENERIC;
2082 /* FIXME: free colorcells instead of freeing whole map */
2083 cm = This->cm;
2084 This->cm = TSXCopyColormapAndFree(display,This->cm);
2085 TSXFreeColormap(display,cm);
2087 for (i=0;i<count;i++) {
2088 xc.red = palent[i].peRed<<8;
2089 xc.blue = palent[i].peBlue<<8;
2090 xc.green = palent[i].peGreen<<8;
2091 xc.flags = DoRed|DoBlue|DoGreen;
2092 xc.pixel = i+start;
2094 TSXStoreColor(display,This->cm,&xc);
2096 This->palents[start+i].peRed = palent[i].peRed;
2097 This->palents[start+i].peBlue = palent[i].peBlue;
2098 This->palents[start+i].peGreen = palent[i].peGreen;
2099 This->palents[start+i].peFlags = palent[i].peFlags;
2101 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2102 return DD_OK;
2103 #else /* defined(HAVE_LIBXXF86DGA) */
2104 return E_UNEXPECTED;
2105 #endif /* defined(HAVE_LIBXXF86DGA) */
2108 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2109 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2110 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2111 if (!--(This->ref)) {
2112 if (This->cm) {
2113 TSXFreeColormap(display,This->cm);
2114 This->cm = 0;
2116 HeapFree(GetProcessHeap(),0,This);
2117 return 0;
2119 return This->ref;
2122 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2123 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2125 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2126 return ++(This->ref);
2129 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2130 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2132 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2133 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2135 return DDERR_ALREADYINITIALIZED;
2138 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2139 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2141 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2142 FIXME( ddraw, "(%p)->(%p) stub.\n", This, lpdwCaps );
2143 return DD_OK;
2146 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2147 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2149 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2150 char xrefiid[50];
2152 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2153 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2155 return S_OK;
2158 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt = {
2159 IDirectDrawPaletteImpl_QueryInterface,
2160 IDirectDrawPaletteImpl_AddRef,
2161 IDirectDrawPaletteImpl_Release,
2162 IDirectDrawPaletteImpl_GetCaps,
2163 IDirectDrawPaletteImpl_GetEntries,
2164 IDirectDrawPaletteImpl_Initialize,
2165 DGA_IDirectDrawPaletteImpl_SetEntries
2168 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt = {
2169 IDirectDrawPaletteImpl_QueryInterface,
2170 IDirectDrawPaletteImpl_AddRef,
2171 IDirectDrawPaletteImpl_Release,
2172 IDirectDrawPaletteImpl_GetCaps,
2173 IDirectDrawPaletteImpl_GetEntries,
2174 IDirectDrawPaletteImpl_Initialize,
2175 Xlib_IDirectDrawPaletteImpl_SetEntries
2178 /*******************************************************************************
2179 * IDirect3D
2181 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2182 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2184 ICOM_THIS(IDirect3DImpl,iface);
2185 /* FIXME: Not sure if this is correct */
2186 char xrefiid[50];
2188 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2189 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2190 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2191 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2192 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2193 *obj = This->ddraw;
2194 IDirect3D_AddRef(iface);
2196 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2198 return S_OK;
2200 if ((!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) ||
2201 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2202 *obj = This;
2203 IDirect3D_AddRef(iface);
2205 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2207 return S_OK;
2209 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
2210 IDirect3D2Impl* d3d;
2212 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2213 d3d->ref = 1;
2214 d3d->ddraw = This->ddraw;
2215 IDirect3D_AddRef(iface);
2216 d3d->lpvtbl = &d3d2vt;
2217 *obj = d3d;
2219 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2221 return S_OK;
2223 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2224 return OLE_E_ENUM_NOMORE;
2227 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2228 ICOM_THIS(IDirect3DImpl,iface);
2229 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2231 return ++(This->ref);
2234 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2236 ICOM_THIS(IDirect3DImpl,iface);
2237 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2239 if (!--(This->ref)) {
2240 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2241 HeapFree(GetProcessHeap(),0,This);
2242 return 0;
2244 return This->ref;
2247 static HRESULT WINAPI IDirect3DImpl_Initialize(
2248 LPDIRECT3D iface, REFIID refiid )
2250 ICOM_THIS(IDirect3DImpl,iface);
2251 /* FIXME: Not sure if this is correct */
2252 char xrefiid[50];
2254 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2255 FIXME(ddraw,"(%p)->(%s):stub.\n",This,xrefiid);
2257 return DDERR_ALREADYINITIALIZED;
2260 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2261 LPD3DENUMDEVICESCALLBACK cb,
2262 LPVOID context) {
2263 ICOM_THIS(IDirect3DImpl,iface);
2264 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2266 /* Call functions defined in d3ddevices.c */
2267 if (!d3d_OpenGL_dx3(cb, context))
2268 return DD_OK;
2270 return DD_OK;
2273 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2274 LPDIRECT3DLIGHT *lplight,
2275 IUnknown *lpunk)
2277 ICOM_THIS(IDirect3DImpl,iface);
2278 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2280 /* Call the creation function that is located in d3dlight.c */
2281 *lplight = d3dlight_create_dx3(This);
2283 return DD_OK;
2286 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2287 LPDIRECT3DMATERIAL *lpmaterial,
2288 IUnknown *lpunk)
2290 ICOM_THIS(IDirect3DImpl,iface);
2291 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2293 /* Call the creation function that is located in d3dviewport.c */
2294 *lpmaterial = d3dmaterial_create(This);
2296 return DD_OK;
2299 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2300 LPDIRECT3DVIEWPORT *lpviewport,
2301 IUnknown *lpunk)
2303 ICOM_THIS(IDirect3DImpl,iface);
2304 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2306 /* Call the creation function that is located in d3dviewport.c */
2307 *lpviewport = d3dviewport_create(This);
2309 return DD_OK;
2312 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2313 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2314 LPD3DFINDDEVICERESULT lpfinddevrst)
2316 ICOM_THIS(IDirect3DImpl,iface);
2317 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2319 return DD_OK;
2322 static ICOM_VTABLE(IDirect3D) d3dvt = {
2323 IDirect3DImpl_QueryInterface,
2324 IDirect3DImpl_AddRef,
2325 IDirect3DImpl_Release,
2326 IDirect3DImpl_Initialize,
2327 IDirect3DImpl_EnumDevices,
2328 IDirect3DImpl_CreateLight,
2329 IDirect3DImpl_CreateMaterial,
2330 IDirect3DImpl_CreateViewport,
2331 IDirect3DImpl_FindDevice
2334 /*******************************************************************************
2335 * IDirect3D2
2337 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2338 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2339 ICOM_THIS(IDirect3D2Impl,iface);
2341 /* FIXME: Not sure if this is correct */
2342 char xrefiid[50];
2344 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2345 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2346 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2347 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2348 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2349 *obj = This->ddraw;
2350 IDirect3D2_AddRef(iface);
2352 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2354 return S_OK;
2356 if ((!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) ||
2357 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2358 *obj = This;
2359 IDirect3D2_AddRef(iface);
2361 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2363 return S_OK;
2365 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2366 IDirect3DImpl* d3d;
2368 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2369 d3d->ref = 1;
2370 d3d->ddraw = This->ddraw;
2371 IDirect3D2_AddRef(iface);
2372 d3d->lpvtbl = &d3dvt;
2373 *obj = d3d;
2375 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2377 return S_OK;
2379 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2380 return OLE_E_ENUM_NOMORE;
2383 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2384 ICOM_THIS(IDirect3D2Impl,iface);
2385 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2387 return ++(This->ref);
2390 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2391 ICOM_THIS(IDirect3D2Impl,iface);
2392 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2394 if (!--(This->ref)) {
2395 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2396 HeapFree(GetProcessHeap(),0,This);
2397 return 0;
2399 return This->ref;
2402 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2403 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2405 ICOM_THIS(IDirect3D2Impl,iface);
2406 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2408 /* Call functions defined in d3ddevices.c */
2409 if (!d3d_OpenGL(cb, context))
2410 return DD_OK;
2412 return DD_OK;
2415 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2416 LPDIRECT3DLIGHT *lplight,
2417 IUnknown *lpunk)
2419 ICOM_THIS(IDirect3D2Impl,iface);
2420 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2422 /* Call the creation function that is located in d3dlight.c */
2423 *lplight = d3dlight_create(This);
2425 return DD_OK;
2428 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2429 LPDIRECT3DMATERIAL2 *lpmaterial,
2430 IUnknown *lpunk)
2432 ICOM_THIS(IDirect3D2Impl,iface);
2433 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2435 /* Call the creation function that is located in d3dviewport.c */
2436 *lpmaterial = d3dmaterial2_create(This);
2438 return DD_OK;
2441 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2442 LPDIRECT3DVIEWPORT2 *lpviewport,
2443 IUnknown *lpunk)
2445 ICOM_THIS(IDirect3D2Impl,iface);
2446 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2448 /* Call the creation function that is located in d3dviewport.c */
2449 *lpviewport = d3dviewport2_create(This);
2451 return DD_OK;
2454 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2455 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2456 LPD3DFINDDEVICERESULT lpfinddevrst)
2458 ICOM_THIS(IDirect3D2Impl,iface);
2459 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2461 return DD_OK;
2464 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2465 REFCLSID rguid,
2466 LPDIRECTDRAWSURFACE surface,
2467 LPDIRECT3DDEVICE2 *device)
2469 ICOM_THIS(IDirect3D2Impl,iface);
2470 char xbuf[50];
2472 WINE_StringFromCLSID(rguid,xbuf);
2473 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2475 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2476 IDirect3D2_AddRef(iface);
2477 return DD_OK;
2480 return DDERR_INVALIDPARAMS;
2483 static ICOM_VTABLE(IDirect3D2) d3d2vt = {
2484 IDirect3D2Impl_QueryInterface,
2485 IDirect3D2Impl_AddRef,
2486 IDirect3D2Impl_Release,
2487 IDirect3D2Impl_EnumDevices,
2488 IDirect3D2Impl_CreateLight,
2489 IDirect3D2Impl_CreateMaterial,
2490 IDirect3D2Impl_CreateViewport,
2491 IDirect3D2Impl_FindDevice,
2492 IDirect3D2Impl_CreateDevice
2495 /*******************************************************************************
2496 * IDirectDraw
2499 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2500 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2502 static INT ddrawXlibThisOffset = 0;
2504 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2505 LPDDSURFACEDESC lpddsd,
2506 IDirectDrawSurfaceImpl* lpdsf)
2508 int bpp;
2510 /* The surface was already allocated when entering in this function */
2511 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2513 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2514 /* This is a Z Buffer */
2515 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2516 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2517 } else {
2518 /* This is a standard image */
2519 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2520 /* No pixel format => use DirectDraw's format */
2521 lpddsd->ddpfPixelFormat = This->d.directdraw_pixelformat;
2522 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2523 } else {
2524 /* To check what the program wants */
2525 if (TRACE_ON(ddraw)) {
2526 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2530 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2531 bpp = 1;
2532 } else {
2533 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2537 /* Copy the surface description */
2538 lpdsf->s.surface_desc = *lpddsd;
2540 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2541 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2542 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2544 return DD_OK;
2547 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2548 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2550 #ifdef HAVE_LIBXXF86DGA
2551 ICOM_THIS(IDirectDraw2Impl,iface);
2552 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2553 int i;
2555 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2556 if (TRACE_ON(ddraw)) {
2557 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2558 _dump_DDSD(lpddsd->dwFlags);
2559 DUMP(" caps ");
2560 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2563 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2564 IDirectDraw2_AddRef(iface);
2566 (*ilpdsf)->ref = 1;
2567 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2568 (*ilpdsf)->s.ddraw = This;
2569 (*ilpdsf)->s.palette = NULL;
2570 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2572 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2573 lpddsd->dwWidth = This->d.width;
2574 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2575 lpddsd->dwHeight = This->d.height;
2577 /* Check if this a 'primary surface' or not */
2578 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2579 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2581 /* This is THE primary surface => there is DGA-specific code */
2582 /* First, store the surface description */
2583 (*ilpdsf)->s.surface_desc = *lpddsd;
2585 /* Find a viewport */
2586 for (i=0;i<32;i++)
2587 if (!(This->e.dga.vpmask & (1<<i)))
2588 break;
2589 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2590 /* if i == 32 or maximum ... return error */
2591 This->e.dga.vpmask|=(1<<i);
2592 (*ilpdsf)->s.surface_desc.y.lpSurface =
2593 This->e.dga.fb_addr+((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2594 (*ilpdsf)->t.dga.fb_height = i*This->e.dga.fb_height;
2595 (*ilpdsf)->s.surface_desc.lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
2596 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch;
2598 /* Add flags if there were not present */
2599 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2600 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2601 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2602 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2603 /* We put our surface always in video memory */
2604 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2605 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2606 (*ilpdsf)->s.backbuffer = NULL;
2608 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2609 IDirectDrawSurface4Impl* back;
2611 if (lpddsd->dwBackBufferCount>1)
2612 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2614 (*ilpdsf)->s.backbuffer = back =
2615 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2616 IDirectDraw2_AddRef(iface);
2617 back->ref = 1;
2618 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2619 for (i=0;i<32;i++)
2620 if (!(This->e.dga.vpmask & (1<<i)))
2621 break;
2622 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2623 /* if i == 32 or maximum ... return error */
2624 This->e.dga.vpmask|=(1<<i);
2625 back->t.dga.fb_height = i*This->e.dga.fb_height;
2627 /* Copy the surface description from the front buffer */
2628 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2629 /* Change the parameters that are not the same */
2630 back->s.surface_desc.y.lpSurface = This->e.dga.fb_addr+
2631 ((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2632 back->s.ddraw = This;
2633 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2634 * one! */
2636 /* Add relevant info to front and back buffers */
2637 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2638 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2639 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2640 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2641 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2643 } else {
2644 /* There is no DGA-specific code here...
2645 Go to the common surface creation function */
2646 return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2649 return DD_OK;
2650 #else /* defined(HAVE_LIBXXF86DGA) */
2651 return E_UNEXPECTED;
2652 #endif /* defined(HAVE_LIBXXF86DGA) */
2655 #ifdef HAVE_LIBXXSHM
2656 /* Error handlers for Image creation */
2657 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2658 XShmErrorFlag = 1;
2659 return 0;
2662 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2663 XImage *img;
2664 int (*WineXHandler)(Display *, XErrorEvent *);
2666 img = TSXShmCreateImage(display,
2667 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2668 This->d.pixmap_depth,
2669 ZPixmap,
2670 NULL,
2671 &(lpdsf->t.xlib.shminfo),
2672 lpdsf->s.surface_desc.dwWidth,
2673 lpdsf->s.surface_desc.dwHeight);
2675 if (img == NULL) {
2676 MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2677 This->e.xlib.xshm_active = 0;
2678 return NULL;
2681 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2682 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2683 MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2684 This->e.xlib.xshm_active = 0;
2685 TSXDestroyImage(img);
2686 return NULL;
2689 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2691 if (img->data == (char *) -1) {
2692 MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2693 This->e.xlib.xshm_active = 0;
2694 TSXDestroyImage(img);
2695 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2696 return NULL;
2698 lpdsf->t.xlib.shminfo.readOnly = False;
2700 /* This is where things start to get trickier....
2701 First, we flush the current X connections to be sure to catch all non-XShm related
2702 errors */
2703 TSXSync(display, False);
2704 /* Then we enter in the non-thread safe part of the tests */
2705 EnterCriticalSection( &X11DRV_CritSection );
2707 /* Reset the error flag, sets our new error handler and try to attach the surface */
2708 XShmErrorFlag = 0;
2709 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2710 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2711 XSync(display, False);
2713 /* Check the error flag */
2714 if (XShmErrorFlag) {
2715 /* An error occured */
2716 XFlush(display);
2717 XShmErrorFlag = 0;
2718 XDestroyImage(img);
2719 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2720 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2721 XSetErrorHandler(WineXHandler);
2723 MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
2724 This->e.xlib.xshm_active = 0;
2726 /* Leave the critical section */
2727 LeaveCriticalSection( &X11DRV_CritSection );
2729 return NULL;
2732 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2733 but it may be a bit overkill.... */
2734 XSetErrorHandler(WineXHandler);
2735 LeaveCriticalSection( &X11DRV_CritSection );
2737 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2739 if (This->d.pixel_convert != NULL) {
2740 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2741 lpdsf->s.surface_desc.dwWidth *
2742 lpdsf->s.surface_desc.dwHeight *
2743 (This->d.directdraw_pixelformat.x.dwRGBBitCount));
2744 } else {
2745 lpdsf->s.surface_desc.y.lpSurface = img->data;
2748 return img;
2750 #endif /* HAVE_LIBXXSHM */
2752 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2753 XImage *img = NULL;
2754 void *img_data;
2756 #ifdef HAVE_LIBXXSHM
2757 if (This->e.xlib.xshm_active) {
2758 img = create_xshmimage(This, lpdsf);
2761 if (img == NULL) {
2762 #endif
2763 /* Allocate surface memory */
2764 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2765 lpdsf->s.surface_desc.dwWidth *
2766 lpdsf->s.surface_desc.dwHeight *
2767 (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8));
2769 if (This->d.pixel_convert != NULL) {
2770 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2771 lpdsf->s.surface_desc.dwWidth *
2772 lpdsf->s.surface_desc.dwHeight *
2773 (This->d.screen_pixelformat.x.dwRGBBitCount / 8));
2774 } else {
2775 img_data = lpdsf->s.surface_desc.y.lpSurface;
2778 /* In this case, create an XImage */
2779 img =
2780 TSXCreateImage(display,
2781 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2782 This->d.pixmap_depth,
2783 ZPixmap,
2785 img_data,
2786 lpdsf->s.surface_desc.dwWidth,
2787 lpdsf->s.surface_desc.dwHeight,
2789 lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
2792 #ifdef HAVE_LIBXXSHM
2794 #endif
2795 if (This->d.pixel_convert != NULL) {
2796 lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
2797 } else {
2798 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2801 return img;
2804 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
2805 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2807 ICOM_THIS(IDirectDraw2Impl,iface);
2808 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2809 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2810 This,lpddsd,ilpdsf,lpunk);
2812 if (TRACE_ON(ddraw)) {
2813 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2814 _dump_DDSD(lpddsd->dwFlags);
2815 DUMP(" caps ");
2816 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2819 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2821 IDirectDraw2_AddRef(iface);
2822 (*ilpdsf)->s.ddraw = This;
2823 (*ilpdsf)->ref = 1;
2824 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
2825 (*ilpdsf)->s.palette = NULL;
2826 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2828 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2829 lpddsd->dwWidth = This->d.width;
2830 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2831 lpddsd->dwHeight = This->d.height;
2833 /* Check if this a 'primary surface' or not */
2834 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2835 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2836 XImage *img;
2838 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *ilpdsf);
2840 /* First, store the surface description */
2841 (*ilpdsf)->s.surface_desc = *lpddsd;
2843 /* Create the XImage */
2844 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
2845 if (img == NULL)
2846 return DDERR_OUTOFMEMORY;
2847 (*ilpdsf)->t.xlib.image = img;
2849 /* Add flags if there were not present */
2850 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2851 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2852 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2853 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2854 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2855 (*ilpdsf)->s.backbuffer = NULL;
2857 /* Check for backbuffers */
2858 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2859 IDirectDrawSurface4Impl* back;
2860 XImage *img;
2862 if (lpddsd->dwBackBufferCount>1)
2863 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2865 (*ilpdsf)->s.backbuffer = back =
2866 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2868 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2870 IDirectDraw2_AddRef(iface);
2871 back->s.ddraw = This;
2873 back->ref = 1;
2874 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
2875 /* Copy the surface description from the front buffer */
2876 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2878 /* Create the XImage */
2879 img = create_ximage(This, back);
2880 if (img == NULL)
2881 return DDERR_OUTOFMEMORY;
2882 back->t.xlib.image = img;
2884 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2885 * one! */
2887 /* Add relevant info to front and back buffers */
2888 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2889 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2890 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2891 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2892 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2894 } else {
2895 /* There is no Xlib-specific code here...
2896 Go to the common surface creation function */
2897 return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2900 return DD_OK;
2903 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
2904 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2906 ICOM_THIS(IDirectDraw2Impl,iface);
2907 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",This,src,dst);
2908 *dst = src; /* FIXME */
2909 return DD_OK;
2913 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2914 * even when the approbiate bitmasks are not specified.
2916 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
2917 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
2919 ICOM_THIS(IDirectDraw2Impl,iface);
2920 int i;
2921 const struct {
2922 int mask;
2923 char *name;
2924 } flagmap[] = {
2925 FE(DDSCL_FULLSCREEN)
2926 FE(DDSCL_ALLOWREBOOT)
2927 FE(DDSCL_NOWINDOWCHANGES)
2928 FE(DDSCL_NORMAL)
2929 FE(DDSCL_ALLOWMODEX)
2930 FE(DDSCL_EXCLUSIVE)
2931 FE(DDSCL_SETFOCUSWINDOW)
2932 FE(DDSCL_SETDEVICEWINDOW)
2933 FE(DDSCL_CREATEDEVICEWINDOW)
2936 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
2937 if(TRACE_ON(ddraw)){
2938 dbg_decl_str(ddraw, 512);
2939 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2940 if (flagmap[i].mask & cooplevel)
2941 dsprintf(ddraw, "%s ", flagmap[i].name);
2942 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2944 This->d.mainWindow = hwnd;
2946 /* This will be overwritten in the case of Full Screen mode.
2947 Windowed games could work with that :-) */
2948 if (hwnd)
2950 WND *tmpWnd = WIN_FindWndPtr(hwnd);
2951 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
2952 WIN_ReleaseWndPtr(tmpWnd);
2954 if( !This->d.drawable ) {
2955 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
2956 WIN_ReleaseDesktop();
2958 TRACE(ddraw, "Setting drawable to %ld\n", This->d.drawable);
2961 return DD_OK;
2964 /* Small helper to either use the cooperative window or create a new
2965 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2967 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
2968 RECT rect;
2970 /* Do not destroy the application supplied cooperative window */
2971 if (This->d.window && This->d.window != This->d.mainWindow) {
2972 DestroyWindow(This->d.window);
2973 This->d.window = 0;
2975 /* Sanity check cooperative window before assigning it to drawing. */
2976 if ( IsWindow(This->d.mainWindow) &&
2977 IsWindowVisible(This->d.mainWindow)
2979 GetWindowRect(This->d.mainWindow,&rect);
2980 if (((rect.right-rect.left) >= This->d.width) &&
2981 ((rect.bottom-rect.top) >= This->d.height)
2983 This->d.window = This->d.mainWindow;
2985 /* ... failed, create new one. */
2986 if (!This->d.window) {
2987 This->d.window = CreateWindowExA(
2989 "WINE_DirectDraw",
2990 "WINE_DirectDraw",
2991 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2992 0,0,
2993 This->d.width,
2994 This->d.height,
2998 NULL
3000 /*Store THIS with the window. We'll use it in the window procedure*/
3001 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3002 ShowWindow(This->d.window,TRUE);
3003 UpdateWindow(This->d.window);
3005 SetFocus(This->d.window);
3008 static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
3009 XVisualInfo *vi;
3010 XPixmapFormatValues *pf;
3011 XVisualInfo vt;
3012 int nvisuals, npixmap, i;
3013 int match = 0;
3015 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3016 pf = XListPixmapFormats(display, &npixmap);
3018 for (i = 0; i < npixmap; i++) {
3019 if (pf[i].bits_per_pixel == depth) {
3020 int j;
3022 for (j = 0; j < nvisuals; j++) {
3023 if (vi[j].depth == pf[i].depth) {
3024 pixelformat->dwSize = sizeof(*pixelformat);
3025 if (depth == 8) {
3026 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3027 pixelformat->y.dwRBitMask = 0;
3028 pixelformat->z.dwGBitMask = 0;
3029 pixelformat->xx.dwBBitMask = 0;
3030 } else {
3031 pixelformat->dwFlags = DDPF_RGB;
3032 pixelformat->y.dwRBitMask = vi[j].red_mask;
3033 pixelformat->z.dwGBitMask = vi[j].green_mask;
3034 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3036 pixelformat->dwFourCC = 0;
3037 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3038 pixelformat->xy.dwRGBAlphaBitMask= 0;
3040 *screen_pixelformat = *pixelformat;
3042 if (pix_depth != NULL)
3043 *pix_depth = vi[j].depth;
3045 match = 1;
3047 break;
3051 if (j == nvisuals)
3052 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3056 if ((match == 0) && (depth == 8)) {
3057 pixelformat->dwSize = sizeof(*pixelformat);
3058 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3059 pixelformat->dwFourCC = 0;
3060 pixelformat->x.dwRGBBitCount = 8;
3061 pixelformat->y.dwRBitMask = 0;
3062 pixelformat->z.dwGBitMask = 0;
3063 pixelformat->xx.dwBBitMask = 0;
3064 pixelformat->xy.dwRGBAlphaBitMask= 0;
3066 /* In that case, find a visual to emulate the 8 bpp format */
3067 for (i = 0; i < npixmap; i++) {
3068 if (pf[i].bits_per_pixel >= depth) {
3069 int j;
3071 for (j = 0; j < nvisuals; j++) {
3072 if (vi[j].depth == pf[i].depth) {
3073 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3074 screen_pixelformat->dwFlags = DDPF_RGB;
3075 screen_pixelformat->dwFourCC = 0;
3076 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3077 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
3078 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
3079 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3080 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
3082 if (pix_depth != NULL)
3083 *pix_depth = vi[j].depth;
3085 match = 2;
3087 break;
3091 if (j == nvisuals)
3092 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3097 TSXFree(vi);
3098 TSXFree(pf);
3100 return match;
3103 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3104 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3106 #ifdef HAVE_LIBXXF86DGA
3107 ICOM_THIS(IDirectDrawImpl,iface);
3108 int i,mode_count;
3110 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3112 /* We hope getting the asked for depth */
3113 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != 1) {
3114 /* I.e. no visual found or emulated */
3115 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3116 return DDERR_UNSUPPORTEDMODE;
3119 if (This->d.width < width) {
3120 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3121 return DDERR_UNSUPPORTEDMODE;
3123 This->d.width = width;
3124 This->d.height = height;
3126 /* adjust fb_height, so we don't overlap */
3127 if (This->e.dga.fb_height < height)
3128 This->e.dga.fb_height = height;
3129 _common_IDirectDrawImpl_SetDisplayMode(This);
3131 #ifdef HAVE_LIBXXF86VM
3133 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3134 XF86VidModeModeLine mod_tmp;
3135 /* int dotclock_tmp; */
3137 /* save original video mode and set fullscreen if available*/
3138 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3139 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3140 orig_mode->hdisplay = mod_tmp.hdisplay;
3141 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3142 orig_mode->hsyncend = mod_tmp.hsyncend;
3143 orig_mode->htotal = mod_tmp.htotal;
3144 orig_mode->vdisplay = mod_tmp.vdisplay;
3145 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3146 orig_mode->vsyncend = mod_tmp.vsyncend;
3147 orig_mode->vtotal = mod_tmp.vtotal;
3148 orig_mode->flags = mod_tmp.flags;
3149 orig_mode->private = mod_tmp.private;
3151 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3152 for (i=0;i<mode_count;i++)
3154 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3156 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3157 *vidmode = *(all_modes[i]);
3158 break;
3159 } else
3160 TSXFree(all_modes[i]->private);
3162 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3163 TSXFree(all_modes);
3165 if (!vidmode)
3166 WARN(ddraw, "Fullscreen mode not available!\n");
3168 if (vidmode)
3170 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3171 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3172 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3173 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3174 #endif
3177 #endif
3179 /* FIXME: this function OVERWRITES several signal handlers.
3180 * can we save them? and restore them later? In a way that
3181 * it works for the library too?
3183 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3184 #ifdef DIABLO_HACK
3185 TSXF86DGASetViewPort(display,DefaultScreen(display),0,This->e.dga.fb_height);
3186 #else
3187 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3188 #endif
3190 #ifdef RESTORE_SIGNALS
3191 SIGNAL_InitHandlers();
3192 #endif
3193 return DD_OK;
3194 #else /* defined(HAVE_LIBXXF86DGA) */
3195 return E_UNEXPECTED;
3196 #endif /* defined(HAVE_LIBXXF86DGA) */
3199 /* *************************************
3200 16 / 15 bpp to palettized 8 bpp
3201 ************************************* */
3202 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3203 unsigned char *c_src = (unsigned char *) src;
3204 unsigned short *c_dst = (unsigned short *) dst;
3205 int x, y;
3207 if (palette != NULL) {
3208 unsigned short *pal = (unsigned short *) palette->screen_palents;
3210 for (y = 0; y < height; y++) {
3211 for (x = 0; x < width; x++) {
3212 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3215 } else {
3216 WARN(ddraw, "No palette set...\n");
3217 memset(dst, 0, width * height * 2);
3220 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3221 int i;
3222 unsigned short *pal = (unsigned short *) screen_palette;
3224 for (i = 0; i < count; i++)
3225 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3226 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3227 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3229 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3230 int i;
3231 unsigned short *pal = (unsigned short *) screen_palette;
3233 for (i = 0; i < count; i++)
3234 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3235 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3236 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3239 /* *************************************
3240 24 / 32 bpp to palettized 8 bpp
3241 ************************************* */
3242 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3243 unsigned char *c_src = (unsigned char *) src;
3244 unsigned int *c_dst = (unsigned int *) dst;
3245 int x, y;
3247 if (palette != NULL) {
3248 unsigned int *pal = (unsigned int *) palette->screen_palents;
3250 for (y = 0; y < height; y++) {
3251 for (x = 0; x < width; x++) {
3252 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3255 } else {
3256 WARN(ddraw, "No palette set...\n");
3257 memset(dst, 0, width * height * 4);
3260 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3261 int i;
3262 unsigned int *pal = (unsigned int *) screen_palette;
3264 for (i = 0; i < count; i++)
3265 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3266 (((unsigned int) palent[i].peGreen) << 8) |
3267 ((unsigned int) palent[i].peBlue));
3270 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3271 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3273 ICOM_THIS(IDirectDrawImpl,iface);
3274 char buf[200];
3275 WND *tmpWnd;
3277 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3278 This, width, height, depth);
3280 switch (_common_depth_to_pixelformat(depth,
3281 &(This->d.directdraw_pixelformat),
3282 &(This->d.screen_pixelformat),
3283 &(This->d.pixmap_depth))) {
3284 case 0:
3285 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3286 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3287 return DDERR_UNSUPPORTEDMODE;
3289 case 1:
3290 /* No convertion */
3291 This->d.pixel_convert = NULL;
3292 This->d.palette_convert = NULL;
3293 break;
3295 case 2: {
3296 int found = 0;
3298 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3300 /* Set the depth convertion routines */
3301 switch (This->d.screen_pixelformat.x.dwRGBBitCount) {
3302 case 16:
3303 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
3304 (This->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
3305 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3306 /* 16 bpp */
3307 found = 1;
3309 This->d.pixel_convert = pixel_convert_16_to_8;
3310 This->d.palette_convert = palette_convert_16_to_8;
3311 } else if ((This->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
3312 (This->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
3313 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3314 /* 15 bpp */
3315 found = 1;
3317 This->d.pixel_convert = pixel_convert_16_to_8;
3318 This->d.palette_convert = palette_convert_15_to_8;
3320 break;
3322 case 24:
3323 /* Not handled yet :/ */
3324 found = 0;
3325 break;
3327 case 32:
3328 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) &&
3329 (This->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) &&
3330 (This->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
3331 /* 24 bpp */
3332 found = 1;
3334 This->d.pixel_convert = pixel_convert_32_to_8;
3335 This->d.palette_convert = palette_convert_24_to_8;
3337 break;
3340 if (!found) {
3341 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3342 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3343 return DDERR_UNSUPPORTEDMODE;
3345 } break;
3348 This->d.width = width;
3349 This->d.height = height;
3351 _common_IDirectDrawImpl_SetDisplayMode(This);
3353 tmpWnd = WIN_FindWndPtr(This->d.window);
3354 This->d.paintable = 1;
3355 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3356 WIN_ReleaseWndPtr(tmpWnd);
3358 /* We don't have a context for this window. Host off the desktop */
3359 if( !This->d.drawable )
3361 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3362 WIN_ReleaseDesktop();
3364 TRACE(ddraw, "Setting drawable to %ld\n", This->d.drawable);
3366 return DD_OK;
3369 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3370 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3372 #ifdef HAVE_LIBXXF86DGA
3373 ICOM_THIS(IDirectDraw2Impl,iface);
3374 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3375 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3376 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3377 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3378 if (caps2) {
3379 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3380 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3381 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3383 return DD_OK;
3384 #else /* defined(HAVE_LIBXXF86DGA) */
3385 return E_UNEXPECTED;
3386 #endif /* defined(HAVE_LIBXXF86DGA) */
3389 static void fill_caps(LPDDCAPS caps) {
3390 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3391 Need to be fixed, though.. */
3392 if (caps == NULL)
3393 return;
3395 caps->dwSize = sizeof(*caps);
3396 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3397 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
3398 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3399 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3400 caps->dwFXCaps = 0;
3401 caps->dwFXAlphaCaps = 0;
3402 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3403 caps->dwSVCaps = 0;
3404 caps->dwZBufferBitDepths = DDBD_16;
3405 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3406 to put textures in video memory.
3407 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3408 for example) ? */
3409 caps->dwVidMemTotal = 8192 * 1024;
3410 caps->dwVidMemFree = 8192 * 1024;
3411 /* These are all the supported capabilities of the surfaces */
3412 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3413 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3414 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3415 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3416 #ifdef HAVE_MESAGL
3417 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3418 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3419 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3420 #endif
3423 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3424 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3426 ICOM_THIS(IDirectDraw2Impl,iface);
3427 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3429 /* Put the same caps for the two capabilities */
3430 fill_caps(caps1);
3431 fill_caps(caps2);
3433 return DD_OK;
3436 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3437 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3439 ICOM_THIS(IDirectDraw2Impl,iface);
3440 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3441 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3442 This,x,ilpddclip,lpunk
3444 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3445 (*ilpddclip)->ref = 1;
3446 (*ilpddclip)->lpvtbl = &ddclipvt;
3447 return DD_OK;
3450 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3451 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3453 int size = 0;
3455 if (TRACE_ON(ddraw))
3456 _dump_paletteformat(dwFlags);
3458 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3459 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3460 (*lpddpal)->ref = 1;
3461 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3462 (*lpddpal)->installed = 0;
3464 if (dwFlags & DDPCAPS_1BIT)
3465 size = 2;
3466 else if (dwFlags & DDPCAPS_2BIT)
3467 size = 4;
3468 else if (dwFlags & DDPCAPS_4BIT)
3469 size = 16;
3470 else if (dwFlags & DDPCAPS_8BIT)
3471 size = 256;
3472 else
3473 ERR(ddraw, "unhandled palette format\n");
3474 *psize = size;
3476 if (palent)
3478 /* Now, if we are in 'depth conversion mode', create the screen palette */
3479 if (This->d.palette_convert != NULL)
3480 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3482 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3483 } else if (This->d.palette_convert != NULL) {
3484 /* In that case, put all 0xFF */
3485 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3488 return DD_OK;
3491 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3492 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3494 ICOM_THIS(IDirectDraw2Impl,iface);
3495 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3496 HRESULT res;
3497 int xsize = 0,i;
3499 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3500 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3501 if (res != 0) return res;
3502 (*ilpddpal)->lpvtbl = &dga_ddpalvt;
3503 if (This->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3504 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3505 } else {
3506 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3507 (*ilpddpal)->cm = 0;
3509 if (((*ilpddpal)->cm)&&xsize) {
3510 for (i=0;i<xsize;i++) {
3511 XColor xc;
3513 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3514 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3515 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3516 xc.flags = DoRed|DoBlue|DoGreen;
3517 xc.pixel = i;
3518 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3521 return DD_OK;
3524 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3525 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3527 ICOM_THIS(IDirectDraw2Impl,iface);
3528 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3529 int xsize;
3530 HRESULT res;
3532 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3533 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3534 if (res != 0) return res;
3535 (*ilpddpal)->lpvtbl = &xlib_ddpalvt;
3536 return DD_OK;
3539 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3540 #ifdef HAVE_LIBXXF86DGA
3541 ICOM_THIS(IDirectDraw2Impl,iface);
3542 TRACE(ddraw, "(%p)->()\n",This);
3543 Sleep(1000);
3544 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3545 #ifdef RESTORE_SIGNALS
3546 SIGNAL_InitHandlers();
3547 #endif
3548 return DD_OK;
3549 #else /* defined(HAVE_LIBXXF86DGA) */
3550 return E_UNEXPECTED;
3551 #endif
3554 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3555 ICOM_THIS(IDirectDraw2Impl,iface);
3556 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", This);
3557 Sleep(1000);
3558 return DD_OK;
3561 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3562 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3564 ICOM_THIS(IDirectDraw2Impl,iface);
3565 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3566 return DD_OK;
3569 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3570 ICOM_THIS(IDirectDraw2Impl,iface);
3571 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
3573 return ++(This->ref);
3576 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3577 ICOM_THIS(IDirectDraw2Impl,iface);
3578 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3580 #ifdef HAVE_LIBXXF86DGA
3581 if (!--(This->ref)) {
3582 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3583 if (This->d.window && (This->d.mainWindow != This->d.window))
3584 DestroyWindow(This->d.window);
3585 #ifdef HAVE_LIBXXF86VM
3586 if (orig_mode) {
3587 TSXF86VidModeSwitchToMode(
3588 display,
3589 DefaultScreen(display),
3590 orig_mode);
3591 if (orig_mode->privsize)
3592 TSXFree(orig_mode->private);
3593 free(orig_mode);
3594 orig_mode = NULL;
3596 #endif
3598 #ifdef RESTORE_SIGNALS
3599 SIGNAL_InitHandlers();
3600 #endif
3601 HeapFree(GetProcessHeap(),0,This);
3602 return 0;
3604 #endif /* defined(HAVE_LIBXXF86DGA) */
3605 return This->ref;
3608 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3609 ICOM_THIS(IDirectDraw2Impl,iface);
3610 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3612 if (!--(This->ref)) {
3613 if (This->d.window && (This->d.mainWindow != This->d.window))
3614 DestroyWindow(This->d.window);
3615 HeapFree(GetProcessHeap(),0,This);
3616 return 0;
3618 /* FIXME: destroy window ... */
3619 return This->ref;
3622 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
3623 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3625 ICOM_THIS(IDirectDraw2Impl,iface);
3626 char xrefiid[50];
3628 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3629 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3630 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3631 *obj = This;
3632 IDirectDraw2_AddRef(iface);
3634 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3636 return S_OK;
3638 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3639 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
3640 IDirectDraw2_AddRef(iface);
3641 *obj = This;
3643 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3645 return S_OK;
3647 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3648 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
3649 IDirectDraw2_AddRef(iface);
3650 *obj = This;
3652 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3654 return S_OK;
3656 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3657 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
3658 IDirectDraw2_AddRef(iface);
3659 *obj = This;
3661 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3663 return S_OK;
3665 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3666 IDirect3DImpl* d3d;
3668 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3669 d3d->ref = 1;
3670 d3d->ddraw = (IDirectDrawImpl*)This;
3671 IDirectDraw2_AddRef(iface);
3672 d3d->lpvtbl = &d3dvt;
3673 *obj = d3d;
3675 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3677 return S_OK;
3679 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3680 IDirect3D2Impl* d3d;
3682 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3683 d3d->ref = 1;
3684 d3d->ddraw = (IDirectDrawImpl*)This;
3685 IDirectDraw2_AddRef(iface);
3686 d3d->lpvtbl = &d3d2vt;
3687 *obj = d3d;
3689 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3691 return S_OK;
3693 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3694 return OLE_E_ENUM_NOMORE;
3697 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
3698 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3700 ICOM_THIS(IDirectDraw2Impl,iface);
3701 char xrefiid[50];
3703 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3704 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3705 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3706 *obj = This;
3707 IDirectDraw2_AddRef(iface);
3709 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3711 return S_OK;
3713 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3714 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
3715 IDirectDraw2_AddRef(iface);
3716 *obj = This;
3718 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3720 return S_OK;
3722 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3723 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
3724 IDirectDraw2_AddRef(iface);
3725 *obj = This;
3727 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3729 return S_OK;
3731 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3732 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
3733 IDirectDraw2_AddRef(iface);
3734 *obj = This;
3736 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3738 return S_OK;
3740 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3741 IDirect3DImpl* d3d;
3743 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3744 d3d->ref = 1;
3745 d3d->ddraw = (IDirectDrawImpl*)This;
3746 IDirectDraw2_AddRef(iface);
3747 d3d->lpvtbl = &d3dvt;
3748 *obj = d3d;
3750 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3752 return S_OK;
3754 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3755 IDirect3D2Impl* d3d;
3757 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3758 d3d->ref = 1;
3759 d3d->ddraw = (IDirectDrawImpl*)This;
3760 IDirectDraw2_AddRef(iface);
3761 d3d->lpvtbl = &d3d2vt;
3762 *obj = d3d;
3764 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3766 return S_OK;
3768 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3769 return OLE_E_ENUM_NOMORE;
3772 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
3773 LPDIRECTDRAW2 iface,BOOL *status
3775 ICOM_THIS(IDirectDraw2Impl,iface);
3776 TRACE(ddraw,"(%p)->(%p)\n",This,status);
3777 *status = TRUE;
3778 return DD_OK;
3781 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
3782 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3784 ICOM_THIS(IDirectDraw2Impl,iface);
3785 DDSURFACEDESC ddsfd;
3786 static struct {
3787 int w,h;
3788 } modes[5] = { /* some of the usual modes */
3789 {512,384},
3790 {640,400},
3791 {640,480},
3792 {800,600},
3793 {1024,768},
3795 static int depths[4] = {8,16,24,32};
3796 int i,j;
3798 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3799 ddsfd.dwSize = sizeof(ddsfd);
3800 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3801 if (dwFlags & DDEDM_REFRESHRATES) {
3802 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3803 ddsfd.x.dwRefreshRate = 60;
3806 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3807 ddsfd.dwBackBufferCount = 1;
3808 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3809 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3810 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3811 /* FIXME: those masks would have to be set in depth > 8 */
3812 if (depths[i]==8) {
3813 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3814 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3815 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3816 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3817 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3818 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3819 } else {
3820 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3822 /* FIXME: We should query those from X itself */
3823 switch (depths[i]) {
3824 case 16:
3825 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3826 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3827 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3828 break;
3829 case 24:
3830 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3831 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3832 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3833 break;
3834 case 32:
3835 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3836 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3837 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3838 break;
3842 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3843 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3844 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3845 if (!modescb(&ddsfd,context)) return DD_OK;
3847 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3848 ddsfd.dwWidth = modes[j].w;
3849 ddsfd.dwHeight = modes[j].h;
3850 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3851 if (!modescb(&ddsfd,context)) return DD_OK;
3854 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3855 /* modeX is not standard VGA */
3857 ddsfd.dwHeight = 200;
3858 ddsfd.dwWidth = 320;
3859 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3860 if (!modescb(&ddsfd,context)) return DD_OK;
3863 return DD_OK;
3866 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
3867 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3869 ICOM_THIS(IDirectDraw2Impl,iface);
3870 XVisualInfo *vi;
3871 XPixmapFormatValues *pf;
3872 XVisualInfo vt;
3873 int nvisuals, npixmap, i;
3874 int send_mode;
3875 int has_8bpp = 0;
3876 DDSURFACEDESC ddsfd;
3877 static struct {
3878 int w,h;
3879 } modes[] = { /* some of the usual modes */
3880 {512,384},
3881 {640,400},
3882 {640,480},
3883 {800,600},
3884 {1024,768},
3885 {1280,1024}
3887 DWORD maxWidth, maxHeight;
3889 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3890 ddsfd.dwSize = sizeof(ddsfd);
3891 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
3892 if (dwFlags & DDEDM_REFRESHRATES) {
3893 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3894 ddsfd.x.dwRefreshRate = 60;
3896 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3897 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3899 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3900 pf = XListPixmapFormats(display, &npixmap);
3902 i = 0;
3903 send_mode = 0;
3904 while (i < npixmap) {
3905 if ((has_8bpp == 0) && (pf[i].depth == 8)) {
3906 /* Special case of a 8bpp depth */
3907 has_8bpp = 1;
3908 send_mode = 1;
3910 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
3911 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3912 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
3913 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3914 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
3915 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3916 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3917 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3918 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3919 } else if (pf[i].depth > 8) {
3920 int j;
3922 /* All the 'true color' depths (15, 16 and 24)
3923 First, find the corresponding visual to extract the bit masks */
3924 for (j = 0; j < nvisuals; j++) {
3925 if (vi[j].depth == pf[i].depth) {
3926 ddsfd.ddsCaps.dwCaps = 0;
3927 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3928 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3929 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3930 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
3931 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
3932 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
3933 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
3934 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3936 send_mode = 1;
3937 break;
3941 if (j == nvisuals)
3942 ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
3943 } else {
3944 send_mode = 0;
3947 if (send_mode) {
3948 int mode;
3950 if (TRACE_ON(ddraw)) {
3951 TRACE(ddraw, "Enumerating with pixel format : \n");
3952 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
3955 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
3956 /* Do not enumerate modes we cannot handle anyway */
3957 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
3958 break;
3960 ddsfd.dwWidth = modes[mode].w;
3961 ddsfd.dwHeight = modes[mode].h;
3963 /* Now, send the mode description to the application */
3964 TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
3965 if (!modescb(&ddsfd, context))
3966 goto exit_enum;
3969 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3970 /* modeX is not standard VGA */
3971 ddsfd.dwWidth = 320;
3972 ddsfd.dwHeight = 200;
3973 if (!modescb(&ddsfd, context))
3974 goto exit_enum;
3978 /* Hack to always enumerate a 8bpp depth */
3979 i++;
3980 if ((i == npixmap) && (has_8bpp == 0)) {
3981 i--;
3982 pf[i].depth = 8;
3986 exit_enum:
3987 TSXFree(vi);
3988 TSXFree(pf);
3990 return DD_OK;
3993 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
3994 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
3996 #ifdef HAVE_LIBXXF86DGA
3997 ICOM_THIS(IDirectDraw2Impl,iface);
3998 TRACE(ddraw,"(%p)->(%p)\n",This,lpddsfd);
3999 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4000 lpddsfd->dwHeight = This->d.height;
4001 lpddsfd->dwWidth = This->d.width;
4002 lpddsfd->lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4003 lpddsfd->dwBackBufferCount = 1;
4004 lpddsfd->x.dwRefreshRate = 60;
4005 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4006 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4007 return DD_OK;
4008 #else /* defined(HAVE_LIBXXF86DGA) */
4009 return E_UNEXPECTED;
4010 #endif /* defined(HAVE_LIBXXF86DGA) */
4013 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4014 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4016 ICOM_THIS(IDirectDraw2Impl,iface);
4017 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4018 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4019 lpddsfd->dwHeight = This->d.height;
4020 lpddsfd->dwWidth = This->d.width;
4021 lpddsfd->lPitch = lpddsfd->dwWidth * This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4022 lpddsfd->dwBackBufferCount = 1;
4023 lpddsfd->x.dwRefreshRate = 60;
4024 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4025 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4026 return DD_OK;
4029 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4030 ICOM_THIS(IDirectDraw2Impl,iface);
4031 TRACE(ddraw,"(%p)->()\n",This);
4032 return DD_OK;
4035 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4036 LPDIRECTDRAW2 iface,LPDWORD freq
4038 ICOM_THIS(IDirectDraw2Impl,iface);
4039 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",This,freq);
4040 *freq = 60*100; /* 60 Hz */
4041 return DD_OK;
4044 /* what can we directly decompress? */
4045 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4046 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4048 ICOM_THIS(IDirectDraw2Impl,iface);
4049 FIXME(ddraw,"(%p,%p,%p), stub\n",This,x,y);
4050 return DD_OK;
4053 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4054 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4056 ICOM_THIS(IDirectDraw2Impl,iface);
4057 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4058 return DD_OK;
4061 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4062 LPDIRECTDRAW2 iface )
4064 ICOM_THIS(IDirectDraw2Impl,iface);
4065 FIXME(ddraw,"(%p)->()\n", This );
4067 return DD_OK;
4070 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4071 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4072 ICOM_THIS(IDirectDraw2Impl,iface);
4073 FIXME(ddraw,"(%p)->(%p)\n", This, lplpGDIDDSSurface);
4075 return DD_OK;
4078 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4079 LPDWORD lpdwScanLine) {
4080 ICOM_THIS(IDirectDraw2Impl,iface);
4081 FIXME(ddraw,"(%p)->(%p)\n", This, lpdwScanLine);
4083 return DD_OK;
4086 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4087 GUID *lpGUID) {
4088 ICOM_THIS(IDirectDraw2Impl,iface);
4089 FIXME(ddraw,"(%p)->(%p)\n", This, lpGUID);
4091 return DD_OK;
4094 /* Note: Hack so we can reuse the old functions without compiler warnings */
4095 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4096 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4097 #else
4098 # define XCAST(fun) (void *)
4099 #endif
4101 static ICOM_VTABLE(IDirectDraw) dga_ddvt = {
4102 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4103 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4104 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4105 XCAST(Compact)IDirectDraw2Impl_Compact,
4106 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4107 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4108 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4109 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4110 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4111 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4112 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4113 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4114 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4115 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4116 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4117 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4118 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4119 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4120 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4121 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4122 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4123 DGA_IDirectDrawImpl_SetDisplayMode,
4124 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4127 static ICOM_VTABLE(IDirectDraw) xlib_ddvt = {
4128 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4129 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4130 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4131 XCAST(Compact)IDirectDraw2Impl_Compact,
4132 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4133 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4134 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4135 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4136 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4137 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4138 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4139 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4140 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4141 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4142 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4143 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4144 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4145 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4146 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4147 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4148 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4149 Xlib_IDirectDrawImpl_SetDisplayMode,
4150 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4153 #undef XCAST
4155 /*****************************************************************************
4156 * IDirectDraw2
4161 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4162 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4164 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4167 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4168 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4170 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4173 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4174 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4176 ICOM_THIS(IDirectDraw2Impl,iface);
4177 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4178 This,ddscaps,total,free
4180 if (total) *total = This->e.dga.fb_memsize * 1024;
4181 if (free) *free = This->e.dga.fb_memsize * 1024;
4182 return DD_OK;
4185 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4186 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4188 ICOM_THIS(IDirectDraw2Impl,iface);
4189 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4190 This,ddscaps,total,free
4192 if (total) *total = 2048 * 1024;
4193 if (free) *free = 2048 * 1024;
4194 return DD_OK;
4197 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt = {
4198 DGA_IDirectDraw2Impl_QueryInterface,
4199 IDirectDraw2Impl_AddRef,
4200 DGA_IDirectDraw2Impl_Release,
4201 IDirectDraw2Impl_Compact,
4202 IDirectDraw2Impl_CreateClipper,
4203 DGA_IDirectDraw2Impl_CreatePalette,
4204 DGA_IDirectDraw2Impl_CreateSurface,
4205 IDirectDraw2Impl_DuplicateSurface,
4206 DGA_IDirectDraw2Impl_EnumDisplayModes,
4207 IDirectDraw2Impl_EnumSurfaces,
4208 IDirectDraw2Impl_FlipToGDISurface,
4209 DGA_IDirectDraw2Impl_GetCaps,
4210 DGA_IDirectDraw2Impl_GetDisplayMode,
4211 IDirectDraw2Impl_GetFourCCCodes,
4212 IDirectDraw2Impl_GetGDISurface,
4213 IDirectDraw2Impl_GetMonitorFrequency,
4214 IDirectDraw2Impl_GetScanLine,
4215 IDirectDraw2Impl_GetVerticalBlankStatus,
4216 IDirectDraw2Impl_Initialize,
4217 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4218 IDirectDraw2Impl_SetCooperativeLevel,
4219 DGA_IDirectDraw2Impl_SetDisplayMode,
4220 IDirectDraw2Impl_WaitForVerticalBlank,
4221 DGA_IDirectDraw2Impl_GetAvailableVidMem
4224 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = {
4225 Xlib_IDirectDraw2Impl_QueryInterface,
4226 IDirectDraw2Impl_AddRef,
4227 Xlib_IDirectDraw2Impl_Release,
4228 IDirectDraw2Impl_Compact,
4229 IDirectDraw2Impl_CreateClipper,
4230 Xlib_IDirectDraw2Impl_CreatePalette,
4231 Xlib_IDirectDraw2Impl_CreateSurface,
4232 IDirectDraw2Impl_DuplicateSurface,
4233 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4234 IDirectDraw2Impl_EnumSurfaces,
4235 IDirectDraw2Impl_FlipToGDISurface,
4236 Xlib_IDirectDraw2Impl_GetCaps,
4237 Xlib_IDirectDraw2Impl_GetDisplayMode,
4238 IDirectDraw2Impl_GetFourCCCodes,
4239 IDirectDraw2Impl_GetGDISurface,
4240 IDirectDraw2Impl_GetMonitorFrequency,
4241 IDirectDraw2Impl_GetScanLine,
4242 IDirectDraw2Impl_GetVerticalBlankStatus,
4243 IDirectDraw2Impl_Initialize,
4244 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4245 IDirectDraw2Impl_SetCooperativeLevel,
4246 Xlib_IDirectDraw2Impl_SetDisplayMode,
4247 IDirectDraw2Impl_WaitForVerticalBlank,
4248 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4251 /*****************************************************************************
4252 * IDirectDraw4
4256 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4257 HDC hdc,
4258 LPDIRECTDRAWSURFACE *lpDDS) {
4259 ICOM_THIS(IDirectDraw4Impl,iface);
4260 FIXME(ddraw, "(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4262 return DD_OK;
4265 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4266 ICOM_THIS(IDirectDraw4Impl,iface);
4267 FIXME(ddraw, "(%p)->()\n", This);
4269 return DD_OK;
4272 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4273 ICOM_THIS(IDirectDraw4Impl,iface);
4274 FIXME(ddraw, "(%p)->()\n", This);
4276 return DD_OK;
4279 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4280 LPDDDEVICEIDENTIFIER lpdddi,
4281 DWORD dwFlags) {
4282 ICOM_THIS(IDirectDraw4Impl,iface);
4283 FIXME(ddraw, "(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4285 return DD_OK;
4288 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4289 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4290 #else
4291 # define XCAST(fun) (void*)
4292 #endif
4295 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt = {
4296 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4297 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4298 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4299 XCAST(Compact)IDirectDraw2Impl_Compact,
4300 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4301 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4302 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4303 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4304 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4305 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4306 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4307 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4308 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4309 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4310 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4311 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4312 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4313 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4314 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4315 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4316 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4317 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4318 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4319 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4320 IDirectDraw4Impl_GetSurfaceFromDC,
4321 IDirectDraw4Impl_RestoreAllSurfaces,
4322 IDirectDraw4Impl_TestCooperativeLevel,
4323 IDirectDraw4Impl_GetDeviceIdentifier
4326 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = {
4327 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4328 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4329 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4330 XCAST(Compact)IDirectDraw2Impl_Compact,
4331 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4332 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4333 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4334 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4335 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4336 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4337 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4338 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4339 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4340 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4341 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4342 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4343 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4344 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4345 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4346 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4347 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4348 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4349 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4350 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4351 IDirectDraw4Impl_GetSurfaceFromDC,
4352 IDirectDraw4Impl_RestoreAllSurfaces,
4353 IDirectDraw4Impl_TestCooperativeLevel,
4354 IDirectDraw4Impl_GetDeviceIdentifier
4357 #undef XCAST
4359 /******************************************************************************
4360 * DirectDrawCreate
4363 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4365 LRESULT ret;
4366 IDirectDrawImpl* ddraw = NULL;
4367 DWORD lastError;
4369 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4371 SetLastError( ERROR_SUCCESS );
4372 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4373 if( (!ddraw) &&
4374 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4377 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4380 if( ddraw )
4382 /* Perform any special direct draw functions */
4383 if (msg==WM_PAINT)
4384 ddraw->d.paintable = 1;
4386 /* Now let the application deal with the rest of this */
4387 if( ddraw->d.mainWindow )
4390 /* Don't think that we actually need to call this but...
4391 might as well be on the safe side of things... */
4393 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4394 it should be the procedures of our fake window that gets called
4395 instead of those of the window provided by the application.
4396 And with this patch, mouse clicks work with Monkey Island III
4397 - Lionel */
4398 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4400 if( !ret )
4402 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4403 /* We didn't handle the message - give it to the application */
4404 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4406 ret = CallWindowProcA(tmpWnd->winproc,
4407 ddraw->d.mainWindow, msg, wParam, lParam );
4409 WIN_ReleaseWndPtr(tmpWnd);
4413 } else {
4414 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4418 else
4420 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4423 return ret;
4426 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4427 #ifdef HAVE_LIBXXF86DGA
4428 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4429 int memsize,banksize,width,major,minor,flags,height;
4430 char *addr;
4431 int fd;
4432 int depth;
4434 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4435 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4436 close(fd);
4438 if (fd == -1) {
4439 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4440 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4441 return E_UNEXPECTED;
4443 if (!DDRAW_DGA_Available()) {
4444 TRACE(ddraw,"No XF86DGA detected.\n");
4445 return DDERR_GENERIC;
4447 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4448 (*ilplpDD)->lpvtbl = &dga_ddvt;
4449 (*ilplpDD)->ref = 1;
4450 TSXF86DGAQueryVersion(display,&major,&minor);
4451 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4452 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4453 if (!(flags & XF86DGADirectPresent))
4454 MSG("direct video is NOT PRESENT.\n");
4455 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4456 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4457 addr,width,banksize,memsize
4459 (*ilplpDD)->e.dga.fb_width = width;
4460 (*ilplpDD)->d.width = width;
4461 (*ilplpDD)->e.dga.fb_addr = addr;
4462 (*ilplpDD)->e.dga.fb_memsize = memsize;
4463 (*ilplpDD)->e.dga.fb_banksize = banksize;
4465 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4466 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4467 (*ilplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4468 #ifdef DIABLO_HACK
4469 (*ilplpDD)->e.dga.vpmask = 1;
4470 #else
4471 (*ilplpDD)->e.dga.vpmask = 0;
4472 #endif
4474 /* just assume the default depth is the DGA depth too */
4475 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4476 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4477 #ifdef RESTORE_SIGNALS
4478 SIGNAL_InitHandlers();
4479 #endif
4481 return DD_OK;
4482 #else /* defined(HAVE_LIBXXF86DGA) */
4483 return DDERR_INVALIDDIRECTDRAWGUID;
4484 #endif /* defined(HAVE_LIBXXF86DGA) */
4487 BOOL
4488 DDRAW_XSHM_Available(void)
4490 #ifdef HAVE_LIBXXSHM
4491 if (TSXShmQueryExtension(display))
4493 int major, minor;
4494 Bool shpix;
4496 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4497 return 1;
4498 else
4499 return 0;
4501 else
4502 return 0;
4503 #else
4504 return 0;
4505 #endif
4508 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4509 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4510 int depth;
4512 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4513 (*ilplpDD)->lpvtbl = &xlib_ddvt;
4514 (*ilplpDD)->ref = 1;
4515 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
4517 /* At DirectDraw creation, the depth is the default depth */
4518 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4519 _common_depth_to_pixelformat(depth,
4520 &((*ilplpDD)->d.directdraw_pixelformat),
4521 &((*ilplpDD)->d.screen_pixelformat),
4522 &((*ilplpDD)->d.pixmap_depth));
4523 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4524 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4526 #ifdef HAVE_LIBXXSHM
4527 /* Test if XShm is available. */
4528 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4529 TRACE(ddraw, "Using XShm extension.\n");
4530 #endif
4532 return DD_OK;
4535 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4536 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4537 char xclsid[50];
4538 WNDCLASSA wc;
4539 /* WND* pParentWindow; */
4540 HRESULT ret;
4542 if (HIWORD(lpGUID))
4543 WINE_StringFromCLSID(lpGUID,xclsid);
4544 else {
4545 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4546 lpGUID = NULL;
4549 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
4551 if ((!lpGUID) ||
4552 (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4553 (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4554 (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4555 /* if they didn't request a particular interface, use the best
4556 * supported one */
4557 if (DDRAW_DGA_Available())
4558 lpGUID = &DGA_DirectDraw_GUID;
4559 else
4560 lpGUID = &XLIB_DirectDraw_GUID;
4563 wc.style = CS_GLOBALCLASS;
4564 wc.lpfnWndProc = Xlib_DDWndProc;
4565 wc.cbClsExtra = 0;
4566 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
4567 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
4569 /* We can be a child of the desktop since we're really important */
4571 This code is not useful since hInstance is forced to 0 afterward
4572 pParentWindow = WIN_GetDesktop();
4573 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
4575 wc.hInstance = 0;
4578 wc.hIcon = 0;
4579 wc.hCursor = (HCURSOR)IDC_ARROWA;
4580 wc.hbrBackground= NULL_BRUSH;
4581 wc.lpszMenuName = 0;
4582 wc.lpszClassName= "WINE_DirectDraw";
4583 RegisterClassA(&wc);
4585 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4586 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4587 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4588 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4589 else
4590 goto err;
4593 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
4594 return ret;
4596 err:
4597 ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4598 return DDERR_INVALIDDIRECTDRAWGUID;
4602 #else /* !defined(X_DISPLAY_MISSING) */
4604 #include "windef.h"
4606 #define DD_OK 0
4608 typedef void *LPGUID;
4609 typedef void *LPUNKNOWN;
4610 typedef void *LPDIRECTDRAW;
4611 typedef void *LPDIRECTDRAWCLIPPER;
4612 typedef void *LPDDENUMCALLBACKA;
4613 typedef void *LPDDENUMCALLBACKEXA;
4614 typedef void *LPDDENUMCALLBACKEXW;
4615 typedef void *LPDDENUMCALLBACKW;
4617 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
4619 return DD_OK;
4622 HRESULT WINAPI DirectDrawCreate(
4623 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
4625 return DD_OK;
4628 HRESULT WINAPI DirectDrawCreateClipper(
4629 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
4631 return DD_OK;
4634 HRESULT WINAPI DirectDrawEnumerateA(
4635 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
4637 return DD_OK;
4640 HRESULT WINAPI DirectDrawEnumerateExA(
4641 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
4643 return DD_OK;
4646 HRESULT WINAPI DirectDrawEnumerateExW(
4647 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
4649 return DD_OK;
4652 HRESULT WINAPI DirectDrawEnumerateW(
4653 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
4655 return DD_OK;
4658 #endif /* !defined(X_DISPLAY_MISSING) */
4661 /*******************************************************************************
4662 * DirectDraw ClassFactory
4664 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
4667 typedef struct
4669 /* IUnknown fields */
4670 ICOM_VTABLE(IClassFactory)* lpvtbl;
4671 DWORD ref;
4672 } IClassFactoryImpl;
4674 static HRESULT WINAPI
4675 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
4676 ICOM_THIS(IClassFactoryImpl,iface);
4677 char buf[80];
4679 if (HIWORD(riid))
4680 WINE_StringFromCLSID(riid,buf);
4681 else
4682 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4683 FIXME(ddraw,"(%p)->(%s,%p),stub!\n",This,buf,ppobj);
4684 return E_NOINTERFACE;
4687 static ULONG WINAPI
4688 DDCF_AddRef(LPCLASSFACTORY iface) {
4689 ICOM_THIS(IClassFactoryImpl,iface);
4690 return ++(This->ref);
4693 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
4694 ICOM_THIS(IClassFactoryImpl,iface);
4695 /* static class, won't be freed */
4696 return --(This->ref);
4699 static HRESULT WINAPI DDCF_CreateInstance(
4700 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
4702 ICOM_THIS(IClassFactoryImpl,iface);
4703 char buf[80];
4705 WINE_StringFromCLSID(riid,buf);
4706 TRACE(ddraw,"(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
4707 if ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4708 (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4709 (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4710 /* FIXME: reuse already created DirectDraw if present? */
4711 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
4713 return E_NOINTERFACE;
4716 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
4717 ICOM_THIS(IClassFactoryImpl,iface);
4718 FIXME(ddraw,"(%p)->(%d),stub!\n",This,dolock);
4719 return S_OK;
4722 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl = {
4723 DDCF_QueryInterface,
4724 DDCF_AddRef,
4725 DDCF_Release,
4726 DDCF_CreateInstance,
4727 DDCF_LockServer
4729 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
4731 /*******************************************************************************
4732 * DllGetClassObject [DDRAW.13]
4733 * Retrieves class object from a DLL object
4735 * NOTES
4736 * Docs say returns STDAPI
4738 * PARAMS
4739 * rclsid [I] CLSID for the class object
4740 * riid [I] Reference to identifier of interface for class object
4741 * ppv [O] Address of variable to receive interface pointer for riid
4743 * RETURNS
4744 * Success: S_OK
4745 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
4746 * E_UNEXPECTED
4748 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
4750 char buf[80],xbuf[80];
4752 if (HIWORD(rclsid))
4753 WINE_StringFromCLSID(rclsid,xbuf);
4754 else
4755 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
4756 if (HIWORD(riid))
4757 WINE_StringFromCLSID(riid,buf);
4758 else
4759 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4760 WINE_StringFromCLSID(riid,xbuf);
4761 TRACE(ddraw, "(%p,%p,%p)\n", xbuf, buf, ppv);
4762 if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
4763 *ppv = (LPVOID)&DDRAW_CF;
4764 IClassFactory_AddRef((IClassFactory*)*ppv);
4765 return S_OK;
4767 FIXME(ddraw, "(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
4768 return E_NOINTERFACE;
4772 /*******************************************************************************
4773 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
4775 * RETURNS
4776 * Success: S_OK
4777 * Failure: S_FALSE
4779 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
4781 FIXME(ddraw, "(void): stub\n");
4782 return S_FALSE;