Initialize process critical section in the correct process context.
[wine/dcerpc.git] / graphics / ddraw.c
blobf37fd9421679f25cb3c953c6422ec79d182d25e1
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 = 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 = 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 = 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 = 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);
669 if (!This->s.ddraw->d.paintable)
670 return DD_OK;
672 if (!iflipto) {
673 if (This->s.backbuffer)
674 iflipto = This->s.backbuffer;
675 else
676 iflipto = This;
679 Xlib_copy_surface_on_screen(This);
681 if (iflipto->s.palette && iflipto->s.palette->cm) {
682 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
684 if (iflipto!=This) {
685 XImage *tmp;
686 LPVOID *surf;
687 tmp = This->t.xlib.image;
688 This->t.xlib.image = iflipto->t.xlib.image;
689 iflipto->t.xlib.image = tmp;
690 surf = This->s.surface_desc.y.lpSurface;
691 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
692 iflipto->s.surface_desc.y.lpSurface = surf;
694 return DD_OK;
698 /* The IDirectDrawSurface4::SetPalette method attaches the specified
699 * DirectDrawPalette object to a surface. The surface uses this palette for all
700 * subsequent operations. The palette change takes place immediately.
702 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
703 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
705 ICOM_THIS(IDirectDrawSurface4Impl,iface);
706 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
707 int i;
708 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
710 if (ipal == NULL) {
711 if( This->s.palette != NULL )
712 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
713 This->s.palette = ipal;
715 return DD_OK;
718 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
720 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
721 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
723 if (!Options.managed)
724 TSXInstallColormap(display,ipal->cm);
726 for (i=0;i<256;i++) {
727 XColor xc;
729 xc.red = ipal->palents[i].peRed<<8;
730 xc.blue = ipal->palents[i].peBlue<<8;
731 xc.green = ipal->palents[i].peGreen<<8;
732 xc.flags = DoRed|DoBlue|DoGreen;
733 xc.pixel = i;
734 TSXStoreColor(display,ipal->cm,&xc);
736 TSXInstallColormap(display,ipal->cm);
739 /* According to spec, we are only supposed to
740 * AddRef if this is not the same palette.
742 if( This->s.palette != ipal )
744 if( ipal != NULL )
745 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
746 if( This->s.palette != NULL )
747 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
748 This->s.palette = ipal;
750 /* I think that we need to attach it to all backbuffers...*/
751 if( This->s.backbuffer ) {
752 if( This->s.backbuffer->s.palette )
753 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
754 This->s.backbuffer->s.palette = ipal;
755 if( ipal )
756 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
758 /* Perform the refresh */
759 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
761 return DD_OK;
764 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
765 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
767 ICOM_THIS(IDirectDrawSurface4Impl,iface);
768 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
769 TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
770 #ifdef HAVE_LIBXXF86DGA
771 /* According to spec, we are only supposed to
772 * AddRef if this is not the same palette.
774 if( This->s.palette != ipal )
776 if( ipal != NULL )
777 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
778 if( This->s.palette != NULL )
779 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
780 This->s.palette = ipal;
782 /* I think that we need to attach it to all backbuffers...*/
783 if( This->s.backbuffer ) {
784 if( This->s.backbuffer->s.palette )
785 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
786 This->s.backbuffer->s.palette = ipal;
787 if ( ipal )
788 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
790 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
792 return DD_OK;
793 #else /* defined(HAVE_LIBXXF86DGA) */
794 return E_UNEXPECTED;
795 #endif /* defined(HAVE_LIBXXF86DGA) */
800 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
802 int x, y;
803 LPBYTE first;
805 /* Do first row */
807 #define COLORFILL_ROW(type) { \
808 type *d = (type *) buf; \
809 for (x = 0; x < width; x++) \
810 d[x] = (type) color; \
811 break; \
814 switch(bpp) {
815 case 1: COLORFILL_ROW(BYTE)
816 case 2: COLORFILL_ROW(WORD)
817 case 4: COLORFILL_ROW(DWORD)
818 default:
819 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
820 return DDERR_UNSUPPORTED;
823 #undef COLORFILL_ROW
825 /* Now copy first row */
826 first = buf;
827 for (y = 1; y < height; y++) {
828 buf += lPitch;
829 memcpy(buf, first, width * bpp);
832 return DD_OK;
835 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
836 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
838 ICOM_THIS(IDirectDrawSurface4Impl,iface);
839 RECT xdst,xsrc;
840 DDSURFACEDESC ddesc,sdesc;
841 HRESULT ret = DD_OK;
842 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
843 int x, y;
844 LPBYTE dbuf, sbuf;
846 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
848 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
849 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
851 if (TRACE_ON(ddraw)) {
852 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
853 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
854 TRACE(ddraw,"\tflags: ");
855 _dump_DDBLT(dwFlags);
856 if (dwFlags & DDBLT_DDFX) {
857 TRACE(ddraw," blitfx: \n");
858 _dump_DDBLTFX(lpbltfx->dwDDFX);
862 if (rdst) {
863 memcpy(&xdst,rdst,sizeof(xdst));
864 } else {
865 xdst.top = 0;
866 xdst.bottom = ddesc.dwHeight;
867 xdst.left = 0;
868 xdst.right = ddesc.dwWidth;
871 if (rsrc) {
872 memcpy(&xsrc,rsrc,sizeof(xsrc));
873 } else {
874 if (src) {
875 xsrc.top = 0;
876 xsrc.bottom = sdesc.dwHeight;
877 xsrc.left = 0;
878 xsrc.right = sdesc.dwWidth;
879 } else {
880 memset(&xsrc,0,sizeof(xsrc));
884 bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
885 srcheight = xsrc.bottom - xsrc.top;
886 srcwidth = xsrc.right - xsrc.left;
887 dstheight = xdst.bottom - xdst.top;
888 dstwidth = xdst.right - xdst.left;
889 width = (xdst.right - xdst.left) * bpp;
890 dbuf = ddesc.y.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
892 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
894 /* First, all the 'source-less' blits */
895 if (dwFlags & DDBLT_COLORFILL) {
896 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
897 ddesc.lPitch, lpbltfx->b.dwFillColor);
898 dwFlags &= ~DDBLT_COLORFILL;
901 if (dwFlags & DDBLT_DEPTHFILL) {
902 #ifdef HAVE_MESAGL
903 GLboolean ztest;
905 /* Clears the screen */
906 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
907 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
908 glGetBooleanv(GL_DEPTH_TEST, &ztest);
909 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
910 glClear(GL_DEPTH_BUFFER_BIT);
911 glDepthMask(ztest);
913 dwFlags &= ~(DDBLT_DEPTHFILL);
914 #endif HAVE_MESAGL
917 if (dwFlags & DDBLT_ROP) {
918 /* Catch some degenerate cases here */
919 switch(lpbltfx->dwROP) {
920 case BLACKNESS:
921 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
922 break;
923 case 0xAA0029: /* No-op */
924 break;
925 case WHITENESS:
926 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
927 break;
928 default:
929 FIXME(ddraw, "Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->b.lpDDSPattern);
930 goto error;
932 dwFlags &= ~DDBLT_ROP;
935 if (dwFlags & DDBLT_DDROPS) {
936 FIXME(ddraw, "\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->b.lpDDSPattern);
939 /* Now the 'with source' blits */
940 if (src) {
941 LPBYTE sbase;
942 int sx, xinc, sy, yinc;
944 sbase = sdesc.y.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
945 xinc = (srcwidth << 16) / dstwidth;
946 yinc = (srcheight << 16) / dstheight;
948 if (!dwFlags) {
950 /* No effects, we can cheat here */
951 if (dstwidth == srcwidth) {
952 if (dstheight == srcheight) {
953 /* No stretching in either direction. This needs to be as fast as possible */
954 sbuf = sbase;
955 for (y = 0; y < dstheight; y++) {
956 memcpy(dbuf, sbuf, width);
957 sbuf += sdesc.lPitch;
958 dbuf += ddesc.lPitch;
960 } else {
961 /* Stretching in Y direction only */
962 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
963 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
964 memcpy(dbuf, sbuf, width);
965 dbuf += ddesc.lPitch;
968 } else {
969 /* Stretching in X direction */
970 int last_sy = -1;
971 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
972 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
974 if ((sy >> 16) == (last_sy >> 16)) {
975 /* Same as last row - copy already stretched row */
976 memcpy(dbuf, dbuf - ddesc.lPitch, width);
977 } else {
979 #define STRETCH_ROW(type) { \
980 type *s = (type *) sbuf, *d = (type *) dbuf; \
981 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
982 d[x] = s[sx >> 16]; \
983 break; \
986 switch(bpp) {
987 case 1: STRETCH_ROW(BYTE)
988 case 2: STRETCH_ROW(WORD)
989 case 4: STRETCH_ROW(DWORD)
990 default:
991 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
992 ret = DDERR_UNSUPPORTED;
993 goto error;
996 #undef STRETCH_ROW
999 last_sy = sy;
1000 dbuf += ddesc.lPitch;
1003 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1004 DWORD keylow, keyhigh;
1006 if (dwFlags & DDBLT_KEYSRC) {
1007 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1008 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1009 } else {
1010 /* I'm not sure if this is correct */
1011 FIXME(ddraw, "DDBLT_KEYDEST not fully supported yet.\n");
1012 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1013 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1016 #define COPYROW_COLORKEY(type) { \
1017 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1018 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1019 tmp = s[sx >> 16]; \
1020 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1022 break; \
1025 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1026 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1028 switch (bpp) {
1029 case 1: COPYROW_COLORKEY(BYTE)
1030 case 2: COPYROW_COLORKEY(WORD)
1031 case 4: COPYROW_COLORKEY(DWORD)
1032 default:
1033 FIXME(ddraw, "%s color-keyed blit not implemented for bpp %d!\n",
1034 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1035 ret = DDERR_UNSUPPORTED;
1036 goto error;
1038 dbuf += ddesc.lPitch;
1041 #undef COPYROW_COLORKEY
1043 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1048 error:
1050 if (dwFlags && FIXME_ON(ddraw)) {
1051 FIXME(ddraw,"\tUnsupported flags: ");
1052 _dump_DDBLT(dwFlags);
1055 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1056 if (src) IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1058 return DD_OK;
1061 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1062 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1064 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1065 int bpp, w, h, x, y;
1066 DDSURFACEDESC ddesc,sdesc;
1067 HRESULT ret = DD_OK;
1068 LPBYTE sbuf, dbuf;
1071 if (TRACE_ON(ddraw)) {
1072 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1073 This,dstx,dsty,src,rsrc,trans
1075 FIXME(ddraw," trans:");
1076 if (FIXME_ON(ddraw))
1077 _dump_DDBLTFAST(trans);
1078 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1080 /* We need to lock the surfaces, or we won't get refreshes when done. */
1081 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1082 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1084 bpp = This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
1085 sbuf = sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1086 dbuf = ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1089 h=rsrc->bottom-rsrc->top;
1090 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1091 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1092 if (h<0) h=0;
1094 w=rsrc->right-rsrc->left;
1095 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1096 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1097 if (w<0) w=0;
1099 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1100 DWORD keylow, keyhigh;
1101 if (trans & DDBLTFAST_SRCCOLORKEY) {
1102 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1103 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1104 } else {
1105 /* I'm not sure if this is correct */
1106 FIXME(ddraw, "DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1107 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1108 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1111 #define COPYBOX_COLORKEY(type) { \
1112 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1113 s = sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp; \
1114 d = ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp; \
1115 for (y = 0; y < h; y++) { \
1116 for (x = 0; x < w; x++) { \
1117 tmp = s[x]; \
1118 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1120 (LPBYTE)s += sdesc.lPitch; \
1121 (LPBYTE)d += ddesc.lPitch; \
1123 break; \
1126 switch (bpp) {
1127 case 1: COPYBOX_COLORKEY(BYTE)
1128 case 2: COPYBOX_COLORKEY(WORD)
1129 case 4: COPYBOX_COLORKEY(DWORD)
1130 default:
1131 FIXME(ddraw, "Source color key blitting not supported for bpp %d\n", bpp*8);
1132 ret = DDERR_UNSUPPORTED;
1133 goto error;
1136 #undef COPYBOX_COLORKEY
1138 } else {
1139 int width = w * bpp;
1141 for (y = 0; y < h; y++) {
1142 memcpy(dbuf, sbuf, width);
1143 sbuf += sdesc.lPitch;
1144 dbuf += ddesc.lPitch;
1148 error:
1150 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1151 IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1152 return ret;
1155 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1156 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1158 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1159 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1160 This,ddbltbatch,x,y
1162 return DD_OK;
1165 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1166 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1168 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1169 TRACE(ddraw,"(%p)->GetCaps(%p)\n",This,caps);
1170 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1171 return DD_OK;
1174 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1175 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1176 ) {
1177 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1178 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
1179 This,ddsd);
1181 /* Simply copy the surface description stored in the object */
1182 *ddsd = This->s.surface_desc;
1184 if (TRACE_ON(ddraw)) {
1185 DUMP(" flags: ");
1186 _dump_DDSD(ddsd->dwFlags);
1187 if (ddsd->dwFlags & DDSD_CAPS) {
1188 DUMP(" caps: ");
1189 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
1191 if (ddsd->dwFlags & DDSD_PIXELFORMAT) {
1192 DUMP(" pixel format : \n");
1193 _dump_pixelformat(&(ddsd->ddpfPixelFormat));
1197 return DD_OK;
1200 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1201 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1202 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1204 return ++(This->ref);
1207 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1208 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1209 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1211 #ifdef HAVE_LIBXXF86DGA
1212 if (!--(This->ref)) {
1213 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1214 /* clear out of surface list */
1215 if (This->t.dga.fb_height == -1) {
1216 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1217 } else {
1218 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1221 /* Free the backbuffer */
1222 if (This->s.backbuffer)
1223 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1225 HeapFree(GetProcessHeap(),0,This);
1226 return 0;
1228 #endif /* defined(HAVE_LIBXXF86DGA) */
1229 return This->ref;
1232 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1233 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1234 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1236 if (!--(This->ref)) {
1237 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1239 if( This->s.backbuffer )
1240 IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1242 if (This->t.xlib.image != NULL) {
1243 if (This->s.ddraw->d.pixel_convert != NULL) {
1244 /* In pixel conversion mode, there are two buffers to release... */
1245 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1247 #ifdef HAVE_LIBXXSHM
1248 if (This->s.ddraw->e.xlib.xshm_active) {
1249 TSXShmDetach(display, &(This->t.xlib.shminfo));
1250 TSXDestroyImage(This->t.xlib.image);
1251 shmdt(This->t.xlib.shminfo.shmaddr);
1252 } else {
1253 #endif
1254 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1255 This->t.xlib.image->data = NULL;
1256 TSXDestroyImage(This->t.xlib.image);
1257 #ifdef HAVE_LIBXXSHM
1259 #endif
1261 } else {
1262 This->t.xlib.image->data = NULL;
1264 #ifdef HAVE_LIBXXSHM
1265 if (This->s.ddraw->e.xlib.xshm_active) {
1266 TSXShmDetach(display, &(This->t.xlib.shminfo));
1267 TSXDestroyImage(This->t.xlib.image);
1268 shmdt(This->t.xlib.shminfo.shmaddr);
1269 } else {
1270 #endif
1271 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1272 TSXDestroyImage(This->t.xlib.image);
1273 #ifdef HAVE_LIBXXSHM
1275 #endif
1278 This->t.xlib.image = 0;
1279 } else {
1280 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1283 if (This->s.palette)
1284 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1286 HeapFree(GetProcessHeap(),0,This);
1287 return 0;
1290 return This->ref;
1293 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1294 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1296 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1297 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1298 This, lpddsd, lpdsf);
1300 if (TRACE_ON(ddraw)) {
1301 TRACE(ddraw," caps ");
1302 _dump_DDSCAPS(lpddsd->dwCaps);
1305 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1306 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1307 return E_FAIL;
1310 /* FIXME: should handle more than one backbuffer */
1311 *lpdsf = (LPDIRECTDRAWSURFACE4)This->s.backbuffer;
1313 if( This->s.backbuffer )
1314 IDirectDrawSurface4_AddRef( (IDirectDrawSurface4*)This->s.backbuffer );
1316 return DD_OK;
1319 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1320 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1322 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1323 TRACE(ddraw,"(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1325 return DDERR_ALREADYINITIALIZED;
1328 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1329 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1331 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1332 TRACE(ddraw,"(%p)->(%p)\n",This,pf);
1334 *pf = This->s.surface_desc.ddpfPixelFormat;
1336 return DD_OK;
1339 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1340 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1341 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,dwFlags);
1342 return DD_OK;
1345 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1346 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1348 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1349 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,x1,x2);
1350 return DD_OK;
1353 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1354 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1356 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1357 FIXME(ddraw,"(%p)->(%p),stub!\n",This,clipper);
1358 return DD_OK;
1361 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1362 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1364 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1365 FIXME(ddraw,"(%p)->(%p),stub!\n",This,surf);
1367 IDirectDrawSurface4_AddRef(iface);
1369 /* This hack will be enough for the moment */
1370 if (This->s.backbuffer == NULL)
1371 This->s.backbuffer = (IDirectDrawSurface4Impl*)surf;
1372 return DD_OK;
1375 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1376 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1377 FIXME(ddraw,"(%p)->GetDC(%p)\n",This,lphdc);
1378 *lphdc = BeginPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1379 return DD_OK;
1382 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1383 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1384 DDSURFACEDESC desc;
1385 DWORD x, y;
1387 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1388 EndPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1390 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1391 I fill it with 'dummy' values to have something on the screen */
1392 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1393 for (y = 0; y < desc.dwHeight; y++) {
1394 for (x = 0; x < desc.dwWidth; x++) {
1395 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) This + x + y;
1398 IDirectDrawSurface4_Unlock(iface,NULL);
1400 return DD_OK;
1404 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1405 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1406 char xrefiid[50];
1408 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1409 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
1411 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1412 * the same interface. And IUnknown does that too of course.
1414 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1415 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1416 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1417 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1418 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1420 *obj = This;
1421 IDirectDrawSurface4_AddRef(iface);
1423 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1425 return S_OK;
1427 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1429 /* Texture interface */
1430 *obj = d3dtexture2_create(This);
1431 IDirectDrawSurface4_AddRef(iface);
1433 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1435 return S_OK;
1437 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1439 /* Texture interface */
1440 *obj = d3dtexture_create(This);
1441 IDirectDrawSurface4_AddRef(iface);
1443 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1445 return S_OK;
1447 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj))
1449 /* It is the OpenGL Direct3D Device */
1450 IDirectDrawSurface4_AddRef(iface);
1452 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1454 return S_OK;
1457 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
1458 return OLE_E_ENUM_NOMORE;
1461 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1462 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1463 TRACE(ddraw,"(%p)->(), stub!\n",This);
1464 return DD_OK; /* hmm */
1467 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1468 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1469 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,context,esfcb);
1471 /* For the moment, only enumerating the back buffer */
1472 if (This->s.backbuffer != NULL) {
1473 TRACE(ddraw, "Enumerating back-buffer (%p)\n", This->s.backbuffer);
1474 if (esfcb((LPDIRECTDRAWSURFACE) This->s.backbuffer, &(This->s.backbuffer->s.surface_desc), context) == DDENUMRET_CANCEL)
1475 return DD_OK;
1478 return DD_OK;
1481 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1482 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1483 FIXME(ddraw,"(%p)->(),stub!\n",This);
1484 return DD_OK;
1487 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1488 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1490 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1491 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1492 if (TRACE_ON(ddraw)) {
1493 DUMP(" (0x%08lx <-> 0x%08lx) - ",
1494 ckey->dwColorSpaceLowValue,
1495 ckey->dwColorSpaceHighValue);
1496 _dump_colorkeyflag(dwFlags);
1499 /* If this surface was loaded as a texture, call also the texture
1500 SetColorKey callback */
1501 if (This->s.texture) {
1502 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1505 if( dwFlags & DDCKEY_SRCBLT )
1507 dwFlags &= ~DDCKEY_SRCBLT;
1508 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1509 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1512 if( dwFlags & DDCKEY_DESTBLT )
1514 dwFlags &= ~DDCKEY_DESTBLT;
1515 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1516 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1519 if( dwFlags & DDCKEY_SRCOVERLAY )
1521 dwFlags &= ~DDCKEY_SRCOVERLAY;
1522 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1523 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1526 if( dwFlags & DDCKEY_DESTOVERLAY )
1528 dwFlags &= ~DDCKEY_DESTOVERLAY;
1529 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1530 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1533 if( dwFlags )
1535 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1538 return DD_OK;
1542 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1543 LPDIRECTDRAWSURFACE4 iface,
1544 LPRECT lpRect )
1546 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1547 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpRect);
1549 return DD_OK;
1552 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1553 LPDIRECTDRAWSURFACE4 iface,
1554 DWORD dwFlags,
1555 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1557 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1558 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",This,dwFlags,lpDDSAttachedSurface);
1560 return DD_OK;
1563 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1564 LPDIRECTDRAWSURFACE4 iface,
1565 DWORD dwFlags,
1566 LPVOID lpContext,
1567 LPDDENUMSURFACESCALLBACK lpfnCallback )
1569 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1570 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1571 lpContext, lpfnCallback );
1573 return DD_OK;
1576 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1577 LPDIRECTDRAWSURFACE4 iface,
1578 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1580 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1581 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDClipper);
1583 return DD_OK;
1586 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1587 LPDIRECTDRAWSURFACE4 iface,
1588 DWORD dwFlags,
1589 LPDDCOLORKEY lpDDColorKey )
1591 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1592 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1594 if( dwFlags & DDCKEY_SRCBLT ) {
1595 dwFlags &= ~DDCKEY_SRCBLT;
1596 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1599 if( dwFlags & DDCKEY_DESTBLT )
1601 dwFlags &= ~DDCKEY_DESTBLT;
1602 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1605 if( dwFlags & DDCKEY_SRCOVERLAY )
1607 dwFlags &= ~DDCKEY_SRCOVERLAY;
1608 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1611 if( dwFlags & DDCKEY_DESTOVERLAY )
1613 dwFlags &= ~DDCKEY_DESTOVERLAY;
1614 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1617 if( dwFlags )
1619 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1622 return DD_OK;
1625 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1626 LPDIRECTDRAWSURFACE4 iface,
1627 DWORD dwFlags )
1629 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1630 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1632 return DD_OK;
1635 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1636 LPDIRECTDRAWSURFACE4 iface,
1637 LPDIRECTDRAWPALETTE* lplpDDPalette )
1639 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1640 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDPalette);
1642 return DD_OK;
1645 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1646 LPDIRECTDRAWSURFACE4 iface,
1647 LONG lX,
1648 LONG lY)
1650 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1651 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1653 return DD_OK;
1656 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1657 LPDIRECTDRAWSURFACE4 iface,
1658 LPRECT lpSrcRect,
1659 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1660 LPRECT lpDestRect,
1661 DWORD dwFlags,
1662 LPDDOVERLAYFX lpDDOverlayFx )
1664 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1665 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1666 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1668 return DD_OK;
1671 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1672 LPDIRECTDRAWSURFACE4 iface,
1673 DWORD dwFlags )
1675 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1676 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1678 return DD_OK;
1681 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1682 LPDIRECTDRAWSURFACE4 iface,
1683 DWORD dwFlags,
1684 LPDIRECTDRAWSURFACE4 lpDDSReference )
1686 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1687 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1689 return DD_OK;
1692 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1693 LPDIRECTDRAWSURFACE4 iface,
1694 LPVOID* lplpDD )
1696 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1697 FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDD);
1699 /* Not sure about that... */
1700 *lplpDD = (void *) This->s.ddraw;
1702 return DD_OK;
1705 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1706 LPDIRECTDRAWSURFACE4 iface,
1707 DWORD dwFlags )
1709 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1710 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1712 return DD_OK;
1715 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1716 LPDIRECTDRAWSURFACE4 iface,
1717 DWORD dwFlags )
1719 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1720 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1722 return DD_OK;
1725 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1726 LPDIRECTDRAWSURFACE4 iface,
1727 LPDDSURFACEDESC lpDDSD,
1728 DWORD dwFlags )
1730 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1731 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1733 return DD_OK;
1736 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1737 REFGUID guidTag,
1738 LPVOID lpData,
1739 DWORD cbSize,
1740 DWORD dwFlags) {
1741 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1742 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1744 return DD_OK;
1747 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1748 REFGUID guidTag,
1749 LPVOID lpBuffer,
1750 LPDWORD lpcbBufferSize) {
1751 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1752 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1754 return DD_OK;
1757 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
1758 REFGUID guidTag) {
1759 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1760 FIXME(ddraw, "(%p)->(%p)\n", This, guidTag);
1762 return DD_OK;
1765 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
1766 LPDWORD lpValue) {
1767 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1768 FIXME(ddraw, "(%p)->(%p)\n", This, lpValue);
1770 return DD_OK;
1773 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
1774 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1775 FIXME(ddraw, "(%p)\n", This);
1777 return DD_OK;
1780 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = {
1781 IDirectDrawSurface4Impl_QueryInterface,
1782 IDirectDrawSurface4Impl_AddRef,
1783 DGA_IDirectDrawSurface4Impl_Release,
1784 IDirectDrawSurface4Impl_AddAttachedSurface,
1785 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1786 IDirectDrawSurface4Impl_Blt,
1787 IDirectDrawSurface4Impl_BltBatch,
1788 IDirectDrawSurface4Impl_BltFast,
1789 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1790 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1791 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1792 DGA_IDirectDrawSurface4Impl_Flip,
1793 IDirectDrawSurface4Impl_GetAttachedSurface,
1794 IDirectDrawSurface4Impl_GetBltStatus,
1795 IDirectDrawSurface4Impl_GetCaps,
1796 IDirectDrawSurface4Impl_GetClipper,
1797 IDirectDrawSurface4Impl_GetColorKey,
1798 IDirectDrawSurface4Impl_GetDC,
1799 IDirectDrawSurface4Impl_GetFlipStatus,
1800 IDirectDrawSurface4Impl_GetOverlayPosition,
1801 IDirectDrawSurface4Impl_GetPalette,
1802 IDirectDrawSurface4Impl_GetPixelFormat,
1803 IDirectDrawSurface4Impl_GetSurfaceDesc,
1804 IDirectDrawSurface4Impl_Initialize,
1805 IDirectDrawSurface4Impl_IsLost,
1806 IDirectDrawSurface4Impl_Lock,
1807 IDirectDrawSurface4Impl_ReleaseDC,
1808 IDirectDrawSurface4Impl_Restore,
1809 IDirectDrawSurface4Impl_SetClipper,
1810 IDirectDrawSurface4Impl_SetColorKey,
1811 IDirectDrawSurface4Impl_SetOverlayPosition,
1812 DGA_IDirectDrawSurface4Impl_SetPalette,
1813 DGA_IDirectDrawSurface4Impl_Unlock,
1814 IDirectDrawSurface4Impl_UpdateOverlay,
1815 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1816 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1817 IDirectDrawSurface4Impl_GetDDInterface,
1818 IDirectDrawSurface4Impl_PageLock,
1819 IDirectDrawSurface4Impl_PageUnlock,
1820 IDirectDrawSurface4Impl_SetSurfaceDesc,
1821 IDirectDrawSurface4Impl_SetPrivateData,
1822 IDirectDrawSurface4Impl_GetPrivateData,
1823 IDirectDrawSurface4Impl_FreePrivateData,
1824 IDirectDrawSurface4Impl_GetUniquenessValue,
1825 IDirectDrawSurface4Impl_ChangeUniquenessValue
1828 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt = {
1829 IDirectDrawSurface4Impl_QueryInterface,
1830 IDirectDrawSurface4Impl_AddRef,
1831 Xlib_IDirectDrawSurface4Impl_Release,
1832 IDirectDrawSurface4Impl_AddAttachedSurface,
1833 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1834 IDirectDrawSurface4Impl_Blt,
1835 IDirectDrawSurface4Impl_BltBatch,
1836 IDirectDrawSurface4Impl_BltFast,
1837 IDirectDrawSurface4Impl_DeleteAttachedSurface,
1838 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1839 IDirectDrawSurface4Impl_EnumOverlayZOrders,
1840 Xlib_IDirectDrawSurface4Impl_Flip,
1841 IDirectDrawSurface4Impl_GetAttachedSurface,
1842 IDirectDrawSurface4Impl_GetBltStatus,
1843 IDirectDrawSurface4Impl_GetCaps,
1844 IDirectDrawSurface4Impl_GetClipper,
1845 IDirectDrawSurface4Impl_GetColorKey,
1846 IDirectDrawSurface4Impl_GetDC,
1847 IDirectDrawSurface4Impl_GetFlipStatus,
1848 IDirectDrawSurface4Impl_GetOverlayPosition,
1849 IDirectDrawSurface4Impl_GetPalette,
1850 IDirectDrawSurface4Impl_GetPixelFormat,
1851 IDirectDrawSurface4Impl_GetSurfaceDesc,
1852 IDirectDrawSurface4Impl_Initialize,
1853 IDirectDrawSurface4Impl_IsLost,
1854 IDirectDrawSurface4Impl_Lock,
1855 IDirectDrawSurface4Impl_ReleaseDC,
1856 IDirectDrawSurface4Impl_Restore,
1857 IDirectDrawSurface4Impl_SetClipper,
1858 IDirectDrawSurface4Impl_SetColorKey,
1859 IDirectDrawSurface4Impl_SetOverlayPosition,
1860 Xlib_IDirectDrawSurface4Impl_SetPalette,
1861 Xlib_IDirectDrawSurface4Impl_Unlock,
1862 IDirectDrawSurface4Impl_UpdateOverlay,
1863 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1864 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1865 IDirectDrawSurface4Impl_GetDDInterface,
1866 IDirectDrawSurface4Impl_PageLock,
1867 IDirectDrawSurface4Impl_PageUnlock,
1868 IDirectDrawSurface4Impl_SetSurfaceDesc,
1869 IDirectDrawSurface4Impl_SetPrivateData,
1870 IDirectDrawSurface4Impl_GetPrivateData,
1871 IDirectDrawSurface4Impl_FreePrivateData,
1872 IDirectDrawSurface4Impl_GetUniquenessValue,
1873 IDirectDrawSurface4Impl_ChangeUniquenessValue
1876 /******************************************************************************
1877 * DirectDrawCreateClipper (DDRAW.7)
1879 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1880 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1881 LPUNKNOWN pUnkOuter)
1883 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
1884 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
1886 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
1887 (*ilplpDDClipper)->lpvtbl = &ddclipvt;
1888 (*ilplpDDClipper)->ref = 1;
1890 return DD_OK;
1893 /******************************************************************************
1894 * IDirectDrawClipper
1896 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
1897 LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
1899 ICOM_THIS(IDirectDrawClipperImpl,iface);
1900 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
1901 return DD_OK;
1904 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
1905 ICOM_THIS(IDirectDrawClipperImpl,iface);
1906 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1908 This->ref--;
1909 if (This->ref)
1910 return This->ref;
1911 HeapFree(GetProcessHeap(),0,This);
1912 return 0;
1915 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
1916 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
1918 ICOM_THIS(IDirectDrawClipperImpl,iface);
1919 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
1920 if (hmm) *hmm=0;
1921 return DD_OK;
1924 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
1925 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
1927 ICOM_THIS(IDirectDrawClipperImpl,iface);
1928 FIXME(ddraw,"(%p,%p,%ld),stub!\n",This,lprgn,hmm);
1929 return DD_OK;
1932 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
1933 LPDIRECTDRAWCLIPPER iface,
1934 REFIID riid,
1935 LPVOID* ppvObj )
1937 ICOM_THIS(IDirectDrawClipperImpl,iface);
1938 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
1939 return OLE_E_ENUM_NOMORE;
1942 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
1944 ICOM_THIS(IDirectDrawClipperImpl,iface);
1945 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1946 return ++(This->ref);
1949 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
1950 LPDIRECTDRAWCLIPPER iface,
1951 HWND* HWndPtr )
1953 ICOM_THIS(IDirectDrawClipperImpl,iface);
1954 FIXME(ddraw,"(%p)->(%p),stub!\n",This,HWndPtr);
1955 return DD_OK;
1958 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
1959 LPDIRECTDRAWCLIPPER iface,
1960 LPDIRECTDRAW lpDD,
1961 DWORD dwFlags )
1963 ICOM_THIS(IDirectDrawClipperImpl,iface);
1964 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
1965 return DD_OK;
1968 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
1969 LPDIRECTDRAWCLIPPER iface,
1970 BOOL* lpbChanged )
1972 ICOM_THIS(IDirectDrawClipperImpl,iface);
1973 FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpbChanged);
1974 return DD_OK;
1977 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt = {
1978 IDirectDrawClipperImpl_QueryInterface,
1979 IDirectDrawClipperImpl_AddRef,
1980 IDirectDrawClipperImpl_Release,
1981 IDirectDrawClipperImpl_GetClipList,
1982 IDirectDrawClipperImpl_GetHWnd,
1983 IDirectDrawClipperImpl_Initialize,
1984 IDirectDrawClipperImpl_IsClipListChanged,
1985 IDirectDrawClipperImpl_SetClipList,
1986 IDirectDrawClipperImpl_SetHwnd
1990 /******************************************************************************
1991 * IDirectDrawPalette
1993 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
1994 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1996 ICOM_THIS(IDirectDrawPaletteImpl,iface);
1997 int i;
1999 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2000 This,x,start,count,palent);
2002 if (!This->cm) /* should not happen */ {
2003 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
2004 return DDERR_GENERIC;
2006 for (i=0;i<count;i++) {
2007 palent[i].peRed = This->palents[start+i].peRed;
2008 palent[i].peBlue = This->palents[start+i].peBlue;
2009 palent[i].peGreen = This->palents[start+i].peGreen;
2010 palent[i].peFlags = This->palents[start+i].peFlags;
2013 return DD_OK;
2016 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2017 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2019 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2020 XColor xc;
2021 int i;
2023 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2024 This,x,start,count,palent
2026 for (i=0;i<count;i++) {
2027 xc.red = palent[i].peRed<<8;
2028 xc.blue = palent[i].peBlue<<8;
2029 xc.green = palent[i].peGreen<<8;
2030 xc.flags = DoRed|DoBlue|DoGreen;
2031 xc.pixel = start+i;
2033 if (This->cm)
2034 TSXStoreColor(display,This->cm,&xc);
2036 This->palents[start+i].peRed = palent[i].peRed;
2037 This->palents[start+i].peBlue = palent[i].peBlue;
2038 This->palents[start+i].peGreen = palent[i].peGreen;
2039 This->palents[start+i].peFlags = palent[i].peFlags;
2042 /* Now, if we are in 'depth conversion mode', update the screen palette */
2043 if (This->ddraw->d.palette_convert != NULL)
2044 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2046 return DD_OK;
2049 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2050 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2052 #ifdef HAVE_LIBXXF86DGA
2053 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2054 XColor xc;
2055 Colormap cm;
2056 int i;
2058 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2059 This,x,start,count,palent
2061 if (!This->cm) /* should not happen */ {
2062 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
2063 return DDERR_GENERIC;
2065 /* FIXME: free colorcells instead of freeing whole map */
2066 cm = This->cm;
2067 This->cm = TSXCopyColormapAndFree(display,This->cm);
2068 TSXFreeColormap(display,cm);
2070 for (i=0;i<count;i++) {
2071 xc.red = palent[i].peRed<<8;
2072 xc.blue = palent[i].peBlue<<8;
2073 xc.green = palent[i].peGreen<<8;
2074 xc.flags = DoRed|DoBlue|DoGreen;
2075 xc.pixel = i+start;
2077 TSXStoreColor(display,This->cm,&xc);
2079 This->palents[start+i].peRed = palent[i].peRed;
2080 This->palents[start+i].peBlue = palent[i].peBlue;
2081 This->palents[start+i].peGreen = palent[i].peGreen;
2082 This->palents[start+i].peFlags = palent[i].peFlags;
2084 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2085 return DD_OK;
2086 #else /* defined(HAVE_LIBXXF86DGA) */
2087 return E_UNEXPECTED;
2088 #endif /* defined(HAVE_LIBXXF86DGA) */
2091 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2092 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2093 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2094 if (!--(This->ref)) {
2095 if (This->cm) {
2096 TSXFreeColormap(display,This->cm);
2097 This->cm = 0;
2099 HeapFree(GetProcessHeap(),0,This);
2100 return 0;
2102 return This->ref;
2105 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2106 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2108 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2109 return ++(This->ref);
2112 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2113 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2115 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2116 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2118 return DDERR_ALREADYINITIALIZED;
2121 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2122 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2124 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2125 FIXME( ddraw, "(%p)->(%p) stub.\n", This, lpdwCaps );
2126 return DD_OK;
2129 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2130 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2132 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2133 char xrefiid[50];
2135 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2136 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2138 return S_OK;
2141 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt = {
2142 IDirectDrawPaletteImpl_QueryInterface,
2143 IDirectDrawPaletteImpl_AddRef,
2144 IDirectDrawPaletteImpl_Release,
2145 IDirectDrawPaletteImpl_GetCaps,
2146 IDirectDrawPaletteImpl_GetEntries,
2147 IDirectDrawPaletteImpl_Initialize,
2148 DGA_IDirectDrawPaletteImpl_SetEntries
2151 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt = {
2152 IDirectDrawPaletteImpl_QueryInterface,
2153 IDirectDrawPaletteImpl_AddRef,
2154 IDirectDrawPaletteImpl_Release,
2155 IDirectDrawPaletteImpl_GetCaps,
2156 IDirectDrawPaletteImpl_GetEntries,
2157 IDirectDrawPaletteImpl_Initialize,
2158 Xlib_IDirectDrawPaletteImpl_SetEntries
2161 /*******************************************************************************
2162 * IDirect3D
2164 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2165 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2167 ICOM_THIS(IDirect3DImpl,iface);
2168 /* FIXME: Not sure if this is correct */
2169 char xrefiid[50];
2171 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2172 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2173 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2174 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2175 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2176 *obj = This->ddraw;
2177 IDirect3D_AddRef(iface);
2179 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2181 return S_OK;
2183 if ((!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) ||
2184 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2185 *obj = This;
2186 IDirect3D_AddRef(iface);
2188 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2190 return S_OK;
2192 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
2193 IDirect3D2Impl* d3d;
2195 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2196 d3d->ref = 1;
2197 d3d->ddraw = This->ddraw;
2198 IDirect3D_AddRef(iface);
2199 d3d->lpvtbl = &d3d2vt;
2200 *obj = d3d;
2202 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2204 return S_OK;
2206 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2207 return OLE_E_ENUM_NOMORE;
2210 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2211 ICOM_THIS(IDirect3DImpl,iface);
2212 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2214 return ++(This->ref);
2217 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2219 ICOM_THIS(IDirect3DImpl,iface);
2220 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2222 if (!--(This->ref)) {
2223 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2224 HeapFree(GetProcessHeap(),0,This);
2225 return 0;
2227 return This->ref;
2230 static HRESULT WINAPI IDirect3DImpl_Initialize(
2231 LPDIRECT3D iface, REFIID refiid )
2233 ICOM_THIS(IDirect3DImpl,iface);
2234 /* FIXME: Not sure if this is correct */
2235 char xrefiid[50];
2237 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2238 FIXME(ddraw,"(%p)->(%s):stub.\n",This,xrefiid);
2240 return DDERR_ALREADYINITIALIZED;
2243 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2244 LPD3DENUMDEVICESCALLBACK cb,
2245 LPVOID context) {
2246 ICOM_THIS(IDirect3DImpl,iface);
2247 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2249 /* Call functions defined in d3ddevices.c */
2250 if (!d3d_OpenGL_dx3(cb, context))
2251 return DD_OK;
2253 return DD_OK;
2256 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2257 LPDIRECT3DLIGHT *lplight,
2258 IUnknown *lpunk)
2260 ICOM_THIS(IDirect3DImpl,iface);
2261 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2263 /* Call the creation function that is located in d3dlight.c */
2264 *lplight = d3dlight_create_dx3(This);
2266 return DD_OK;
2269 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2270 LPDIRECT3DMATERIAL *lpmaterial,
2271 IUnknown *lpunk)
2273 ICOM_THIS(IDirect3DImpl,iface);
2274 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2276 /* Call the creation function that is located in d3dviewport.c */
2277 *lpmaterial = d3dmaterial_create(This);
2279 return DD_OK;
2282 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2283 LPDIRECT3DVIEWPORT *lpviewport,
2284 IUnknown *lpunk)
2286 ICOM_THIS(IDirect3DImpl,iface);
2287 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2289 /* Call the creation function that is located in d3dviewport.c */
2290 *lpviewport = d3dviewport_create(This);
2292 return DD_OK;
2295 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2296 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2297 LPD3DFINDDEVICERESULT lpfinddevrst)
2299 ICOM_THIS(IDirect3DImpl,iface);
2300 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2302 return DD_OK;
2305 static ICOM_VTABLE(IDirect3D) d3dvt = {
2306 IDirect3DImpl_QueryInterface,
2307 IDirect3DImpl_AddRef,
2308 IDirect3DImpl_Release,
2309 IDirect3DImpl_Initialize,
2310 IDirect3DImpl_EnumDevices,
2311 IDirect3DImpl_CreateLight,
2312 IDirect3DImpl_CreateMaterial,
2313 IDirect3DImpl_CreateViewport,
2314 IDirect3DImpl_FindDevice
2317 /*******************************************************************************
2318 * IDirect3D2
2320 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2321 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2322 ICOM_THIS(IDirect3D2Impl,iface);
2324 /* FIXME: Not sure if this is correct */
2325 char xrefiid[50];
2327 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2328 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2329 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2330 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2331 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2332 *obj = This->ddraw;
2333 IDirect3D2_AddRef(iface);
2335 TRACE(ddraw, " Creating IDirectDrawX interface (%p)\n", *obj);
2337 return S_OK;
2339 if ((!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) ||
2340 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2341 *obj = This;
2342 IDirect3D2_AddRef(iface);
2344 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2346 return S_OK;
2348 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2349 IDirect3DImpl* d3d;
2351 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2352 d3d->ref = 1;
2353 d3d->ddraw = This->ddraw;
2354 IDirect3D2_AddRef(iface);
2355 d3d->lpvtbl = &d3dvt;
2356 *obj = d3d;
2358 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2360 return S_OK;
2362 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2363 return OLE_E_ENUM_NOMORE;
2366 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2367 ICOM_THIS(IDirect3D2Impl,iface);
2368 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2370 return ++(This->ref);
2373 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2374 ICOM_THIS(IDirect3D2Impl,iface);
2375 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2377 if (!--(This->ref)) {
2378 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2379 HeapFree(GetProcessHeap(),0,This);
2380 return 0;
2382 return This->ref;
2385 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2386 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2388 ICOM_THIS(IDirect3D2Impl,iface);
2389 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2391 /* Call functions defined in d3ddevices.c */
2392 if (!d3d_OpenGL(cb, context))
2393 return DD_OK;
2395 return DD_OK;
2398 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2399 LPDIRECT3DLIGHT *lplight,
2400 IUnknown *lpunk)
2402 ICOM_THIS(IDirect3D2Impl,iface);
2403 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2405 /* Call the creation function that is located in d3dlight.c */
2406 *lplight = d3dlight_create(This);
2408 return DD_OK;
2411 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2412 LPDIRECT3DMATERIAL2 *lpmaterial,
2413 IUnknown *lpunk)
2415 ICOM_THIS(IDirect3D2Impl,iface);
2416 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2418 /* Call the creation function that is located in d3dviewport.c */
2419 *lpmaterial = d3dmaterial2_create(This);
2421 return DD_OK;
2424 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2425 LPDIRECT3DVIEWPORT2 *lpviewport,
2426 IUnknown *lpunk)
2428 ICOM_THIS(IDirect3D2Impl,iface);
2429 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2431 /* Call the creation function that is located in d3dviewport.c */
2432 *lpviewport = d3dviewport2_create(This);
2434 return DD_OK;
2437 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2438 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2439 LPD3DFINDDEVICERESULT lpfinddevrst)
2441 ICOM_THIS(IDirect3D2Impl,iface);
2442 TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2444 return DD_OK;
2447 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2448 REFCLSID rguid,
2449 LPDIRECTDRAWSURFACE surface,
2450 LPDIRECT3DDEVICE2 *device)
2452 ICOM_THIS(IDirect3D2Impl,iface);
2453 char xbuf[50];
2455 WINE_StringFromCLSID(rguid,xbuf);
2456 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2458 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2459 IDirect3D2_AddRef(iface);
2460 return DD_OK;
2463 return DDERR_INVALIDPARAMS;
2466 static ICOM_VTABLE(IDirect3D2) d3d2vt = {
2467 IDirect3D2Impl_QueryInterface,
2468 IDirect3D2Impl_AddRef,
2469 IDirect3D2Impl_Release,
2470 IDirect3D2Impl_EnumDevices,
2471 IDirect3D2Impl_CreateLight,
2472 IDirect3D2Impl_CreateMaterial,
2473 IDirect3D2Impl_CreateViewport,
2474 IDirect3D2Impl_FindDevice,
2475 IDirect3D2Impl_CreateDevice
2478 /*******************************************************************************
2479 * IDirectDraw
2482 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2483 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2485 static INT ddrawXlibThisOffset = 0;
2487 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2488 LPDDSURFACEDESC lpddsd,
2489 IDirectDrawSurfaceImpl* lpdsf)
2491 int bpp;
2493 /* The surface was already allocated when entering in this function */
2494 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2496 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2497 /* This is a Z Buffer */
2498 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2499 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2500 } else {
2501 /* This is a standard image */
2502 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2503 /* No pixel format => use DirectDraw's format */
2504 lpddsd->ddpfPixelFormat = This->d.directdraw_pixelformat;
2505 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2506 } else {
2507 /* To check what the program wants */
2508 if (TRACE_ON(ddraw)) {
2509 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2513 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2514 bpp = 1;
2515 } else {
2516 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2520 /* Copy the surface description */
2521 lpdsf->s.surface_desc = *lpddsd;
2523 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2524 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2525 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2527 return DD_OK;
2530 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2531 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2533 #ifdef HAVE_LIBXXF86DGA
2534 ICOM_THIS(IDirectDraw2Impl,iface);
2535 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2536 int i;
2538 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2539 if (TRACE_ON(ddraw)) {
2540 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2541 _dump_DDSD(lpddsd->dwFlags);
2542 DUMP(" caps ");
2543 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2546 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2547 IDirectDraw2_AddRef(iface);
2549 (*ilpdsf)->ref = 1;
2550 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2551 (*ilpdsf)->s.ddraw = This;
2552 (*ilpdsf)->s.palette = NULL;
2553 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2555 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2556 lpddsd->dwWidth = This->d.width;
2557 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2558 lpddsd->dwHeight = This->d.height;
2560 /* Check if this a 'primary surface' or not */
2561 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2562 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2564 /* This is THE primary surface => there is DGA-specific code */
2565 /* First, store the surface description */
2566 (*ilpdsf)->s.surface_desc = *lpddsd;
2568 /* Find a viewport */
2569 for (i=0;i<32;i++)
2570 if (!(This->e.dga.vpmask & (1<<i)))
2571 break;
2572 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2573 /* if i == 32 or maximum ... return error */
2574 This->e.dga.vpmask|=(1<<i);
2575 (*ilpdsf)->s.surface_desc.y.lpSurface =
2576 This->e.dga.fb_addr+((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2577 (*ilpdsf)->t.dga.fb_height = i*This->e.dga.fb_height;
2578 (*ilpdsf)->s.surface_desc.lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
2579 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch;
2581 /* Add flags if there were not present */
2582 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2583 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2584 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2585 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2586 /* We put our surface always in video memory */
2587 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2588 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2589 (*ilpdsf)->s.backbuffer = NULL;
2591 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2592 IDirectDrawSurface4Impl* back;
2594 if (lpddsd->dwBackBufferCount>1)
2595 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2597 (*ilpdsf)->s.backbuffer = back =
2598 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2599 IDirectDraw2_AddRef(iface);
2600 back->ref = 1;
2601 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2602 for (i=0;i<32;i++)
2603 if (!(This->e.dga.vpmask & (1<<i)))
2604 break;
2605 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2606 /* if i == 32 or maximum ... return error */
2607 This->e.dga.vpmask|=(1<<i);
2608 back->t.dga.fb_height = i*This->e.dga.fb_height;
2610 /* Copy the surface description from the front buffer */
2611 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2612 /* Change the parameters that are not the same */
2613 back->s.surface_desc.y.lpSurface = This->e.dga.fb_addr+
2614 ((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2615 back->s.ddraw = This;
2616 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2617 * one! */
2619 /* Add relevant info to front and back buffers */
2620 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2621 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2622 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2623 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2624 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2626 } else {
2627 /* There is no DGA-specific code here...
2628 Go to the common surface creation function */
2629 return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2632 return DD_OK;
2633 #else /* defined(HAVE_LIBXXF86DGA) */
2634 return E_UNEXPECTED;
2635 #endif /* defined(HAVE_LIBXXF86DGA) */
2638 #ifdef HAVE_LIBXXSHM
2639 /* Error handlers for Image creation */
2640 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2641 XShmErrorFlag = 1;
2642 return 0;
2645 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2646 XImage *img;
2647 int (*WineXHandler)(Display *, XErrorEvent *);
2649 img = TSXShmCreateImage(display,
2650 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2651 This->d.pixmap_depth,
2652 ZPixmap,
2653 NULL,
2654 &(lpdsf->t.xlib.shminfo),
2655 lpdsf->s.surface_desc.dwWidth,
2656 lpdsf->s.surface_desc.dwHeight);
2658 if (img == NULL) {
2659 MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2660 This->e.xlib.xshm_active = 0;
2661 return NULL;
2664 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2665 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2666 MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2667 This->e.xlib.xshm_active = 0;
2668 TSXDestroyImage(img);
2669 return NULL;
2672 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2674 if (img->data == (char *) -1) {
2675 MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2676 This->e.xlib.xshm_active = 0;
2677 TSXDestroyImage(img);
2678 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2679 return NULL;
2681 lpdsf->t.xlib.shminfo.readOnly = False;
2683 /* This is where things start to get trickier....
2684 First, we flush the current X connections to be sure to catch all non-XShm related
2685 errors */
2686 TSXSync(display, False);
2687 /* Then we enter in the non-thread safe part of the tests */
2688 EnterCriticalSection( &X11DRV_CritSection );
2690 /* Reset the error flag, sets our new error handler and try to attach the surface */
2691 XShmErrorFlag = 0;
2692 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2693 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2694 XSync(display, False);
2696 /* Check the error flag */
2697 if (XShmErrorFlag) {
2698 /* An error occured */
2699 XFlush(display);
2700 XShmErrorFlag = 0;
2701 XDestroyImage(img);
2702 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2703 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2704 XSetErrorHandler(WineXHandler);
2706 MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
2707 This->e.xlib.xshm_active = 0;
2709 /* Leave the critical section */
2710 LeaveCriticalSection( &X11DRV_CritSection );
2712 return NULL;
2715 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2716 but it may be a bit overkill.... */
2717 XSetErrorHandler(WineXHandler);
2718 LeaveCriticalSection( &X11DRV_CritSection );
2720 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2722 if (This->d.pixel_convert != NULL) {
2723 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2724 lpdsf->s.surface_desc.dwWidth *
2725 lpdsf->s.surface_desc.dwHeight *
2726 (This->d.directdraw_pixelformat.x.dwRGBBitCount));
2727 } else {
2728 lpdsf->s.surface_desc.y.lpSurface = img->data;
2731 return img;
2733 #endif /* HAVE_LIBXXSHM */
2735 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2736 XImage *img = NULL;
2737 void *img_data;
2739 #ifdef HAVE_LIBXXSHM
2740 if (This->e.xlib.xshm_active) {
2741 img = create_xshmimage(This, lpdsf);
2744 if (img == NULL) {
2745 #endif
2746 /* Allocate surface memory */
2747 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2748 lpdsf->s.surface_desc.dwWidth *
2749 lpdsf->s.surface_desc.dwHeight *
2750 (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8));
2752 if (This->d.pixel_convert != NULL) {
2753 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2754 lpdsf->s.surface_desc.dwWidth *
2755 lpdsf->s.surface_desc.dwHeight *
2756 (This->d.screen_pixelformat.x.dwRGBBitCount / 8));
2757 } else {
2758 img_data = lpdsf->s.surface_desc.y.lpSurface;
2761 /* In this case, create an XImage */
2762 img =
2763 TSXCreateImage(display,
2764 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2765 This->d.pixmap_depth,
2766 ZPixmap,
2768 img_data,
2769 lpdsf->s.surface_desc.dwWidth,
2770 lpdsf->s.surface_desc.dwHeight,
2772 lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
2775 #ifdef HAVE_LIBXXSHM
2777 #endif
2778 if (This->d.pixel_convert != NULL) {
2779 lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
2780 } else {
2781 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2784 return img;
2787 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
2788 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2790 ICOM_THIS(IDirectDraw2Impl,iface);
2791 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2792 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2793 This,lpddsd,ilpdsf,lpunk);
2795 if (TRACE_ON(ddraw)) {
2796 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2797 _dump_DDSD(lpddsd->dwFlags);
2798 DUMP(" caps ");
2799 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2802 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2804 IDirectDraw2_AddRef(iface);
2805 (*ilpdsf)->s.ddraw = This;
2806 (*ilpdsf)->ref = 1;
2807 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
2808 (*ilpdsf)->s.palette = NULL;
2809 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2811 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2812 lpddsd->dwWidth = This->d.width;
2813 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2814 lpddsd->dwHeight = This->d.height;
2816 /* Check if this a 'primary surface' or not */
2817 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2818 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2819 XImage *img;
2821 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *ilpdsf);
2823 /* First, store the surface description */
2824 (*ilpdsf)->s.surface_desc = *lpddsd;
2826 /* Create the XImage */
2827 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
2828 if (img == NULL)
2829 return DDERR_OUTOFMEMORY;
2830 (*ilpdsf)->t.xlib.image = img;
2832 /* Add flags if there were not present */
2833 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2834 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2835 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2836 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2837 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2838 (*ilpdsf)->s.backbuffer = NULL;
2840 /* Check for backbuffers */
2841 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2842 IDirectDrawSurface4Impl* back;
2843 XImage *img;
2845 if (lpddsd->dwBackBufferCount>1)
2846 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2848 (*ilpdsf)->s.backbuffer = back =
2849 (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2851 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2853 IDirectDraw2_AddRef(iface);
2854 back->s.ddraw = This;
2856 back->ref = 1;
2857 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
2858 /* Copy the surface description from the front buffer */
2859 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2861 /* Create the XImage */
2862 img = create_ximage(This, back);
2863 if (img == NULL)
2864 return DDERR_OUTOFMEMORY;
2865 back->t.xlib.image = img;
2867 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2868 * one! */
2870 /* Add relevant info to front and back buffers */
2871 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2872 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2873 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2874 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2875 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2877 } else {
2878 /* There is no Xlib-specific code here...
2879 Go to the common surface creation function */
2880 return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2883 return DD_OK;
2886 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
2887 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2889 ICOM_THIS(IDirectDraw2Impl,iface);
2890 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",This,src,dst);
2891 *dst = src; /* FIXME */
2892 return DD_OK;
2896 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2897 * even when the approbiate bitmasks are not specified.
2899 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
2900 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
2902 ICOM_THIS(IDirectDraw2Impl,iface);
2903 int i;
2904 const struct {
2905 int mask;
2906 char *name;
2907 } flagmap[] = {
2908 FE(DDSCL_FULLSCREEN)
2909 FE(DDSCL_ALLOWREBOOT)
2910 FE(DDSCL_NOWINDOWCHANGES)
2911 FE(DDSCL_NORMAL)
2912 FE(DDSCL_ALLOWMODEX)
2913 FE(DDSCL_EXCLUSIVE)
2914 FE(DDSCL_SETFOCUSWINDOW)
2915 FE(DDSCL_SETDEVICEWINDOW)
2916 FE(DDSCL_CREATEDEVICEWINDOW)
2919 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
2920 if(TRACE_ON(ddraw)){
2921 dbg_decl_str(ddraw, 512);
2922 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2923 if (flagmap[i].mask & cooplevel)
2924 dsprintf(ddraw, "%s ", flagmap[i].name);
2925 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2927 This->d.mainWindow = hwnd;
2929 /* This will be overwritten in the case of Full Screen mode.
2930 Windowed games could work with that :-) */
2931 if (hwnd)
2933 WND *tmpWnd = WIN_FindWndPtr(hwnd);
2934 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
2935 WIN_ReleaseWndPtr(tmpWnd);
2938 return DD_OK;
2941 /* Small helper to either use the cooperative window or create a new
2942 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2944 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
2945 RECT rect;
2947 /* Do not destroy the application supplied cooperative window */
2948 if (This->d.window && This->d.window != This->d.mainWindow) {
2949 DestroyWindow(This->d.window);
2950 This->d.window = 0;
2952 /* Sanity check cooperative window before assigning it to drawing. */
2953 if ( IsWindow(This->d.mainWindow) &&
2954 IsWindowVisible(This->d.mainWindow)
2956 GetWindowRect(This->d.mainWindow,&rect);
2957 if (((rect.right-rect.left) >= This->d.width) &&
2958 ((rect.bottom-rect.top) >= This->d.height)
2960 This->d.window = This->d.mainWindow;
2962 /* ... failed, create new one. */
2963 if (!This->d.window) {
2964 This->d.window = CreateWindowExA(
2966 "WINE_DirectDraw",
2967 "WINE_DirectDraw",
2968 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2969 0,0,
2970 This->d.width,
2971 This->d.height,
2975 NULL
2977 /*Store THIS with the window. We'll use it in the window procedure*/
2978 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
2979 ShowWindow(This->d.window,TRUE);
2980 UpdateWindow(This->d.window);
2982 SetFocus(This->d.window);
2985 static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
2986 XVisualInfo *vi;
2987 XPixmapFormatValues *pf;
2988 XVisualInfo vt;
2989 int nvisuals, npixmap, i;
2990 int match = 0;
2992 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
2993 pf = XListPixmapFormats(display, &npixmap);
2995 for (i = 0; i < npixmap; i++) {
2996 if (pf[i].bits_per_pixel == depth) {
2997 int j;
2999 for (j = 0; j < nvisuals; j++) {
3000 if (vi[j].depth == pf[i].depth) {
3001 pixelformat->dwSize = sizeof(*pixelformat);
3002 if (depth == 8) {
3003 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3004 pixelformat->y.dwRBitMask = 0;
3005 pixelformat->z.dwGBitMask = 0;
3006 pixelformat->xx.dwBBitMask = 0;
3007 } else {
3008 pixelformat->dwFlags = DDPF_RGB;
3009 pixelformat->y.dwRBitMask = vi[j].red_mask;
3010 pixelformat->z.dwGBitMask = vi[j].green_mask;
3011 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3013 pixelformat->dwFourCC = 0;
3014 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3015 pixelformat->xy.dwRGBAlphaBitMask= 0;
3017 *screen_pixelformat = *pixelformat;
3019 if (pix_depth != NULL)
3020 *pix_depth = vi[j].depth;
3022 match = 1;
3024 break;
3028 if (j == nvisuals)
3029 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3033 if ((match == 0) && (depth == 8)) {
3034 pixelformat->dwSize = sizeof(*pixelformat);
3035 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3036 pixelformat->dwFourCC = 0;
3037 pixelformat->x.dwRGBBitCount = 8;
3038 pixelformat->y.dwRBitMask = 0;
3039 pixelformat->z.dwGBitMask = 0;
3040 pixelformat->xx.dwBBitMask = 0;
3041 pixelformat->xy.dwRGBAlphaBitMask= 0;
3043 /* In that case, find a visual to emulate the 8 bpp format */
3044 for (i = 0; i < npixmap; i++) {
3045 if (pf[i].bits_per_pixel >= depth) {
3046 int j;
3048 for (j = 0; j < nvisuals; j++) {
3049 if (vi[j].depth == pf[i].depth) {
3050 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3051 screen_pixelformat->dwFlags = DDPF_RGB;
3052 screen_pixelformat->dwFourCC = 0;
3053 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3054 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
3055 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
3056 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3057 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
3059 if (pix_depth != NULL)
3060 *pix_depth = vi[j].depth;
3062 match = 2;
3064 break;
3068 if (j == nvisuals)
3069 ERR(ddraw, "No visual corresponding to pixmap format !\n");
3074 TSXFree(vi);
3075 TSXFree(pf);
3077 return match;
3080 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3081 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3083 #ifdef HAVE_LIBXXF86DGA
3084 ICOM_THIS(IDirectDrawImpl,iface);
3085 int i,mode_count;
3087 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3089 /* We hope getting the asked for depth */
3090 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != 1) {
3091 /* I.e. no visual found or emulated */
3092 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3093 return DDERR_UNSUPPORTEDMODE;
3096 if (This->d.width < width) {
3097 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3098 return DDERR_UNSUPPORTEDMODE;
3100 This->d.width = width;
3101 This->d.height = height;
3103 /* adjust fb_height, so we don't overlap */
3104 if (This->e.dga.fb_height < height)
3105 This->e.dga.fb_height = height;
3106 _common_IDirectDrawImpl_SetDisplayMode(This);
3108 #ifdef HAVE_LIBXXF86VM
3110 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3111 XF86VidModeModeLine mod_tmp;
3112 /* int dotclock_tmp; */
3114 /* save original video mode and set fullscreen if available*/
3115 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3116 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3117 orig_mode->hdisplay = mod_tmp.hdisplay;
3118 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3119 orig_mode->hsyncend = mod_tmp.hsyncend;
3120 orig_mode->htotal = mod_tmp.htotal;
3121 orig_mode->vdisplay = mod_tmp.vdisplay;
3122 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3123 orig_mode->vsyncend = mod_tmp.vsyncend;
3124 orig_mode->vtotal = mod_tmp.vtotal;
3125 orig_mode->flags = mod_tmp.flags;
3126 orig_mode->private = mod_tmp.private;
3128 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3129 for (i=0;i<mode_count;i++)
3131 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3133 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3134 *vidmode = *(all_modes[i]);
3135 break;
3136 } else
3137 TSXFree(all_modes[i]->private);
3139 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3140 TSXFree(all_modes);
3142 if (!vidmode)
3143 WARN(ddraw, "Fullscreen mode not available!\n");
3145 if (vidmode)
3147 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3148 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3149 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3150 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3151 #endif
3154 #endif
3156 /* FIXME: this function OVERWRITES several signal handlers.
3157 * can we save them? and restore them later? In a way that
3158 * it works for the library too?
3160 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3161 #ifdef DIABLO_HACK
3162 TSXF86DGASetViewPort(display,DefaultScreen(display),0,This->e.dga.fb_height);
3163 #else
3164 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3165 #endif
3167 #ifdef RESTORE_SIGNALS
3168 SIGNAL_InitHandlers();
3169 #endif
3170 return DD_OK;
3171 #else /* defined(HAVE_LIBXXF86DGA) */
3172 return E_UNEXPECTED;
3173 #endif /* defined(HAVE_LIBXXF86DGA) */
3176 /* *************************************
3177 16 / 15 bpp to palettized 8 bpp
3178 ************************************* */
3179 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3180 unsigned char *c_src = (unsigned char *) src;
3181 unsigned short *c_dst = (unsigned short *) dst;
3182 int x, y;
3184 if (palette != NULL) {
3185 unsigned short *pal = (unsigned short *) palette->screen_palents;
3187 for (y = 0; y < height; y++) {
3188 for (x = 0; x < width; x++) {
3189 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3192 } else {
3193 WARN(ddraw, "No palette set...\n");
3194 memset(dst, 0, width * height * 2);
3197 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3198 int i;
3199 unsigned short *pal = (unsigned short *) screen_palette;
3201 for (i = 0; i < count; i++)
3202 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3203 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3204 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3206 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3207 int i;
3208 unsigned short *pal = (unsigned short *) screen_palette;
3210 for (i = 0; i < count; i++)
3211 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3212 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3213 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3216 /* *************************************
3217 24 / 32 bpp to palettized 8 bpp
3218 ************************************* */
3219 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3220 unsigned char *c_src = (unsigned char *) src;
3221 unsigned int *c_dst = (unsigned int *) dst;
3222 int x, y;
3224 if (palette != NULL) {
3225 unsigned int *pal = (unsigned int *) palette->screen_palents;
3227 for (y = 0; y < height; y++) {
3228 for (x = 0; x < width; x++) {
3229 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3232 } else {
3233 WARN(ddraw, "No palette set...\n");
3234 memset(dst, 0, width * height * 4);
3237 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3238 int i;
3239 unsigned int *pal = (unsigned int *) screen_palette;
3241 for (i = 0; i < count; i++)
3242 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3243 (((unsigned int) palent[i].peGreen) << 8) |
3244 ((unsigned int) palent[i].peBlue));
3247 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3248 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3250 ICOM_THIS(IDirectDrawImpl,iface);
3251 char buf[200];
3252 WND *tmpWnd;
3254 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3255 This, width, height, depth);
3257 switch (_common_depth_to_pixelformat(depth,
3258 &(This->d.directdraw_pixelformat),
3259 &(This->d.screen_pixelformat),
3260 &(This->d.pixmap_depth))) {
3261 case 0:
3262 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3263 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3264 return DDERR_UNSUPPORTEDMODE;
3266 case 1:
3267 /* No convertion */
3268 This->d.pixel_convert = NULL;
3269 This->d.palette_convert = NULL;
3270 break;
3272 case 2: {
3273 int found = 0;
3275 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3277 /* Set the depth convertion routines */
3278 switch (This->d.screen_pixelformat.x.dwRGBBitCount) {
3279 case 16:
3280 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
3281 (This->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
3282 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3283 /* 16 bpp */
3284 found = 1;
3286 This->d.pixel_convert = pixel_convert_16_to_8;
3287 This->d.palette_convert = palette_convert_16_to_8;
3288 } else if ((This->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
3289 (This->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
3290 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3291 /* 15 bpp */
3292 found = 1;
3294 This->d.pixel_convert = pixel_convert_16_to_8;
3295 This->d.palette_convert = palette_convert_15_to_8;
3297 break;
3299 case 24:
3300 /* Not handled yet :/ */
3301 found = 0;
3302 break;
3304 case 32:
3305 if ((This->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) &&
3306 (This->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) &&
3307 (This->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
3308 /* 24 bpp */
3309 found = 1;
3311 This->d.pixel_convert = pixel_convert_32_to_8;
3312 This->d.palette_convert = palette_convert_24_to_8;
3314 break;
3317 if (!found) {
3318 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3319 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3320 return DDERR_UNSUPPORTEDMODE;
3322 } break;
3325 This->d.width = width;
3326 This->d.height = height;
3328 _common_IDirectDrawImpl_SetDisplayMode(This);
3330 tmpWnd = WIN_FindWndPtr(This->d.window);
3331 This->d.paintable = 1;
3332 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3333 /* We don't have a context for this window. Host off the desktop */
3335 if( !This->d.drawable )
3337 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3338 WIN_ReleaseDesktop();
3340 WIN_ReleaseWndPtr(tmpWnd);
3341 return DD_OK;
3344 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3345 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3347 #ifdef HAVE_LIBXXF86DGA
3348 ICOM_THIS(IDirectDraw2Impl,iface);
3349 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3350 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3351 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3352 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3353 if (caps2) {
3354 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3355 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3356 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3358 return DD_OK;
3359 #else /* defined(HAVE_LIBXXF86DGA) */
3360 return E_UNEXPECTED;
3361 #endif /* defined(HAVE_LIBXXF86DGA) */
3364 static void fill_caps(LPDDCAPS caps) {
3365 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3366 Need to be fixed, though.. */
3367 if (caps == NULL)
3368 return;
3370 caps->dwSize = sizeof(*caps);
3371 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3372 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
3373 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3374 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3375 caps->dwFXCaps = 0;
3376 caps->dwFXAlphaCaps = 0;
3377 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3378 caps->dwSVCaps = 0;
3379 caps->dwZBufferBitDepths = DDBD_16;
3380 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3381 to put textures in video memory.
3382 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3383 for example) ? */
3384 caps->dwVidMemTotal = 8192 * 1024;
3385 caps->dwVidMemFree = 8192 * 1024;
3386 /* These are all the supported capabilities of the surfaces */
3387 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3388 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3389 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3390 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3391 #ifdef HAVE_MESAGL
3392 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3393 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3394 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3395 #endif
3398 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3399 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3401 ICOM_THIS(IDirectDraw2Impl,iface);
3402 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3404 /* Put the same caps for the two capabilities */
3405 fill_caps(caps1);
3406 fill_caps(caps2);
3408 return DD_OK;
3411 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3412 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3414 ICOM_THIS(IDirectDraw2Impl,iface);
3415 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3416 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3417 This,x,ilpddclip,lpunk
3419 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3420 (*ilpddclip)->ref = 1;
3421 (*ilpddclip)->lpvtbl = &ddclipvt;
3422 return DD_OK;
3425 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3426 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3428 int size = 0;
3430 if (TRACE_ON(ddraw))
3431 _dump_paletteformat(dwFlags);
3433 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3434 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3435 (*lpddpal)->ref = 1;
3436 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3437 (*lpddpal)->installed = 0;
3439 if (dwFlags & DDPCAPS_1BIT)
3440 size = 2;
3441 else if (dwFlags & DDPCAPS_2BIT)
3442 size = 4;
3443 else if (dwFlags & DDPCAPS_4BIT)
3444 size = 16;
3445 else if (dwFlags & DDPCAPS_8BIT)
3446 size = 256;
3447 else
3448 ERR(ddraw, "unhandled palette format\n");
3449 *psize = size;
3451 if (palent)
3453 /* Now, if we are in 'depth conversion mode', create the screen palette */
3454 if (This->d.palette_convert != NULL)
3455 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3457 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3458 } else if (This->d.palette_convert != NULL) {
3459 /* In that case, put all 0xFF */
3460 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3463 return DD_OK;
3466 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3467 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3469 ICOM_THIS(IDirectDraw2Impl,iface);
3470 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3471 HRESULT res;
3472 int xsize = 0,i;
3474 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3475 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3476 if (res != 0) return res;
3477 (*ilpddpal)->lpvtbl = &dga_ddpalvt;
3478 if (This->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3479 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3480 } else {
3481 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3482 (*ilpddpal)->cm = 0;
3484 if (((*ilpddpal)->cm)&&xsize) {
3485 for (i=0;i<xsize;i++) {
3486 XColor xc;
3488 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3489 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3490 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3491 xc.flags = DoRed|DoBlue|DoGreen;
3492 xc.pixel = i;
3493 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3496 return DD_OK;
3499 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3500 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3502 ICOM_THIS(IDirectDraw2Impl,iface);
3503 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3504 int xsize;
3505 HRESULT res;
3507 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3508 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3509 if (res != 0) return res;
3510 (*ilpddpal)->lpvtbl = &xlib_ddpalvt;
3511 return DD_OK;
3514 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3515 #ifdef HAVE_LIBXXF86DGA
3516 ICOM_THIS(IDirectDraw2Impl,iface);
3517 TRACE(ddraw, "(%p)->()\n",This);
3518 Sleep(1000);
3519 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3520 #ifdef RESTORE_SIGNALS
3521 SIGNAL_InitHandlers();
3522 #endif
3523 return DD_OK;
3524 #else /* defined(HAVE_LIBXXF86DGA) */
3525 return E_UNEXPECTED;
3526 #endif
3529 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3530 ICOM_THIS(IDirectDraw2Impl,iface);
3531 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", This);
3532 Sleep(1000);
3533 return DD_OK;
3536 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3537 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3539 ICOM_THIS(IDirectDraw2Impl,iface);
3540 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3541 return DD_OK;
3544 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3545 ICOM_THIS(IDirectDraw2Impl,iface);
3546 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
3548 return ++(This->ref);
3551 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3552 ICOM_THIS(IDirectDraw2Impl,iface);
3553 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3555 #ifdef HAVE_LIBXXF86DGA
3556 if (!--(This->ref)) {
3557 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3558 if (This->d.window && (This->d.mainWindow != This->d.window))
3559 DestroyWindow(This->d.window);
3560 #ifdef HAVE_LIBXXF86VM
3561 if (orig_mode) {
3562 TSXF86VidModeSwitchToMode(
3563 display,
3564 DefaultScreen(display),
3565 orig_mode);
3566 if (orig_mode->privsize)
3567 TSXFree(orig_mode->private);
3568 free(orig_mode);
3569 orig_mode = NULL;
3571 #endif
3573 #ifdef RESTORE_SIGNALS
3574 SIGNAL_InitHandlers();
3575 #endif
3576 HeapFree(GetProcessHeap(),0,This);
3577 return 0;
3579 #endif /* defined(HAVE_LIBXXF86DGA) */
3580 return This->ref;
3583 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3584 ICOM_THIS(IDirectDraw2Impl,iface);
3585 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3587 if (!--(This->ref)) {
3588 if (This->d.window && (This->d.mainWindow != This->d.window))
3589 DestroyWindow(This->d.window);
3590 HeapFree(GetProcessHeap(),0,This);
3591 return 0;
3593 /* FIXME: destroy window ... */
3594 return This->ref;
3597 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
3598 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3600 ICOM_THIS(IDirectDraw2Impl,iface);
3601 char xrefiid[50];
3603 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3604 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3605 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3606 *obj = This;
3607 IDirectDraw2_AddRef(iface);
3609 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3611 return S_OK;
3613 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3614 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
3615 IDirectDraw2_AddRef(iface);
3616 *obj = This;
3618 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3620 return S_OK;
3622 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3623 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
3624 IDirectDraw2_AddRef(iface);
3625 *obj = This;
3627 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3629 return S_OK;
3631 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3632 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
3633 IDirectDraw2_AddRef(iface);
3634 *obj = This;
3636 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3638 return S_OK;
3640 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3641 IDirect3DImpl* d3d;
3643 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3644 d3d->ref = 1;
3645 d3d->ddraw = (IDirectDrawImpl*)This;
3646 IDirectDraw2_AddRef(iface);
3647 d3d->lpvtbl = &d3dvt;
3648 *obj = d3d;
3650 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3652 return S_OK;
3654 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3655 IDirect3D2Impl* d3d;
3657 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3658 d3d->ref = 1;
3659 d3d->ddraw = (IDirectDrawImpl*)This;
3660 IDirectDraw2_AddRef(iface);
3661 d3d->lpvtbl = &d3d2vt;
3662 *obj = d3d;
3664 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3666 return S_OK;
3668 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3669 return OLE_E_ENUM_NOMORE;
3672 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
3673 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3675 ICOM_THIS(IDirectDraw2Impl,iface);
3676 char xrefiid[50];
3678 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3679 TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3680 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3681 *obj = This;
3682 IDirectDraw2_AddRef(iface);
3684 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3686 return S_OK;
3688 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3689 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
3690 IDirectDraw2_AddRef(iface);
3691 *obj = This;
3693 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3695 return S_OK;
3697 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3698 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
3699 IDirectDraw2_AddRef(iface);
3700 *obj = This;
3702 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3704 return S_OK;
3706 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3707 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
3708 IDirectDraw2_AddRef(iface);
3709 *obj = This;
3711 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3713 return S_OK;
3715 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3716 IDirect3DImpl* d3d;
3718 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3719 d3d->ref = 1;
3720 d3d->ddraw = (IDirectDrawImpl*)This;
3721 IDirectDraw2_AddRef(iface);
3722 d3d->lpvtbl = &d3dvt;
3723 *obj = d3d;
3725 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3727 return S_OK;
3729 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3730 IDirect3D2Impl* d3d;
3732 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3733 d3d->ref = 1;
3734 d3d->ddraw = (IDirectDrawImpl*)This;
3735 IDirectDraw2_AddRef(iface);
3736 d3d->lpvtbl = &d3d2vt;
3737 *obj = d3d;
3739 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3741 return S_OK;
3743 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3744 return OLE_E_ENUM_NOMORE;
3747 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
3748 LPDIRECTDRAW2 iface,BOOL *status
3750 ICOM_THIS(IDirectDraw2Impl,iface);
3751 TRACE(ddraw,"(%p)->(%p)\n",This,status);
3752 *status = TRUE;
3753 return DD_OK;
3756 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
3757 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3759 ICOM_THIS(IDirectDraw2Impl,iface);
3760 DDSURFACEDESC ddsfd;
3761 static struct {
3762 int w,h;
3763 } modes[5] = { /* some of the usual modes */
3764 {512,384},
3765 {640,400},
3766 {640,480},
3767 {800,600},
3768 {1024,768},
3770 static int depths[4] = {8,16,24,32};
3771 int i,j;
3773 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3774 ddsfd.dwSize = sizeof(ddsfd);
3775 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3776 if (dwFlags & DDEDM_REFRESHRATES) {
3777 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3778 ddsfd.x.dwRefreshRate = 60;
3781 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3782 ddsfd.dwBackBufferCount = 1;
3783 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3784 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3785 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3786 /* FIXME: those masks would have to be set in depth > 8 */
3787 if (depths[i]==8) {
3788 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3789 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3790 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3791 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3792 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3793 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3794 } else {
3795 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3797 /* FIXME: We should query those from X itself */
3798 switch (depths[i]) {
3799 case 16:
3800 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3801 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3802 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3803 break;
3804 case 24:
3805 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3806 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3807 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3808 break;
3809 case 32:
3810 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3811 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3812 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3813 break;
3817 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3818 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3819 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3820 if (!modescb(&ddsfd,context)) return DD_OK;
3822 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3823 ddsfd.dwWidth = modes[j].w;
3824 ddsfd.dwHeight = modes[j].h;
3825 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3826 if (!modescb(&ddsfd,context)) return DD_OK;
3829 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3830 /* modeX is not standard VGA */
3832 ddsfd.dwHeight = 200;
3833 ddsfd.dwWidth = 320;
3834 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3835 if (!modescb(&ddsfd,context)) return DD_OK;
3838 return DD_OK;
3841 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
3842 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3844 ICOM_THIS(IDirectDraw2Impl,iface);
3845 XVisualInfo *vi;
3846 XPixmapFormatValues *pf;
3847 XVisualInfo vt;
3848 int nvisuals, npixmap, i;
3849 int send_mode;
3850 int has_8bpp = 0;
3851 DDSURFACEDESC ddsfd;
3852 static struct {
3853 int w,h;
3854 } modes[] = { /* some of the usual modes */
3855 {512,384},
3856 {640,400},
3857 {640,480},
3858 {800,600},
3859 {1024,768},
3860 {1280,1024}
3862 DWORD maxWidth, maxHeight;
3864 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3865 ddsfd.dwSize = sizeof(ddsfd);
3866 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
3867 if (dwFlags & DDEDM_REFRESHRATES) {
3868 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3869 ddsfd.x.dwRefreshRate = 60;
3871 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3872 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3874 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3875 pf = XListPixmapFormats(display, &npixmap);
3877 i = 0;
3878 send_mode = 0;
3879 while (i < npixmap) {
3880 if ((has_8bpp == 0) && (pf[i].depth == 8)) {
3881 /* Special case of a 8bpp depth */
3882 has_8bpp = 1;
3883 send_mode = 1;
3885 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
3886 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3887 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
3888 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3889 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
3890 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3891 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3892 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3893 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3894 } else if (pf[i].depth > 8) {
3895 int j;
3897 /* All the 'true color' depths (15, 16 and 24)
3898 First, find the corresponding visual to extract the bit masks */
3899 for (j = 0; j < nvisuals; j++) {
3900 if (vi[j].depth == pf[i].depth) {
3901 ddsfd.ddsCaps.dwCaps = 0;
3902 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3903 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3904 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3905 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
3906 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
3907 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
3908 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
3909 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3911 send_mode = 1;
3912 break;
3916 if (j == nvisuals)
3917 ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
3918 } else {
3919 send_mode = 0;
3922 if (send_mode) {
3923 int mode;
3925 if (TRACE_ON(ddraw)) {
3926 TRACE(ddraw, "Enumerating with pixel format : \n");
3927 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
3930 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
3931 /* Do not enumerate modes we cannot handle anyway */
3932 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
3933 break;
3935 ddsfd.dwWidth = modes[mode].w;
3936 ddsfd.dwHeight = modes[mode].h;
3938 /* Now, send the mode description to the application */
3939 TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
3940 if (!modescb(&ddsfd, context))
3941 goto exit_enum;
3944 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3945 /* modeX is not standard VGA */
3946 ddsfd.dwWidth = 320;
3947 ddsfd.dwHeight = 200;
3948 if (!modescb(&ddsfd, context))
3949 goto exit_enum;
3953 /* Hack to always enumerate a 8bpp depth */
3954 i++;
3955 if ((i == npixmap) && (has_8bpp == 0)) {
3956 i--;
3957 pf[i].depth = 8;
3961 exit_enum:
3962 TSXFree(vi);
3963 TSXFree(pf);
3965 return DD_OK;
3968 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
3969 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
3971 #ifdef HAVE_LIBXXF86DGA
3972 ICOM_THIS(IDirectDraw2Impl,iface);
3973 TRACE(ddraw,"(%p)->(%p)\n",This,lpddsfd);
3974 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3975 lpddsfd->dwHeight = This->d.height;
3976 lpddsfd->dwWidth = This->d.width;
3977 lpddsfd->lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3978 lpddsfd->dwBackBufferCount = 1;
3979 lpddsfd->x.dwRefreshRate = 60;
3980 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3981 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
3982 return DD_OK;
3983 #else /* defined(HAVE_LIBXXF86DGA) */
3984 return E_UNEXPECTED;
3985 #endif /* defined(HAVE_LIBXXF86DGA) */
3988 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
3989 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
3991 ICOM_THIS(IDirectDraw2Impl,iface);
3992 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
3993 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3994 lpddsfd->dwHeight = This->d.height;
3995 lpddsfd->dwWidth = This->d.width;
3996 lpddsfd->lPitch = lpddsfd->dwWidth * This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3997 lpddsfd->dwBackBufferCount = 1;
3998 lpddsfd->x.dwRefreshRate = 60;
3999 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4000 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4001 return DD_OK;
4004 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4005 ICOM_THIS(IDirectDraw2Impl,iface);
4006 TRACE(ddraw,"(%p)->()\n",This);
4007 return DD_OK;
4010 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4011 LPDIRECTDRAW2 iface,LPDWORD freq
4013 ICOM_THIS(IDirectDraw2Impl,iface);
4014 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",This,freq);
4015 *freq = 60*100; /* 60 Hz */
4016 return DD_OK;
4019 /* what can we directly decompress? */
4020 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4021 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4023 ICOM_THIS(IDirectDraw2Impl,iface);
4024 FIXME(ddraw,"(%p,%p,%p), stub\n",This,x,y);
4025 return DD_OK;
4028 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4029 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4031 ICOM_THIS(IDirectDraw2Impl,iface);
4032 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4033 return DD_OK;
4036 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4037 LPDIRECTDRAW2 iface )
4039 ICOM_THIS(IDirectDraw2Impl,iface);
4040 FIXME(ddraw,"(%p)->()\n", This );
4042 return DD_OK;
4045 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4046 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4047 ICOM_THIS(IDirectDraw2Impl,iface);
4048 FIXME(ddraw,"(%p)->(%p)\n", This, lplpGDIDDSSurface);
4050 return DD_OK;
4053 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4054 LPDWORD lpdwScanLine) {
4055 ICOM_THIS(IDirectDraw2Impl,iface);
4056 FIXME(ddraw,"(%p)->(%p)\n", This, lpdwScanLine);
4058 return DD_OK;
4061 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4062 GUID *lpGUID) {
4063 ICOM_THIS(IDirectDraw2Impl,iface);
4064 FIXME(ddraw,"(%p)->(%p)\n", This, lpGUID);
4066 return DD_OK;
4069 /* Note: Hack so we can reuse the old functions without compiler warnings */
4070 #ifdef __GNUC__
4071 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4072 #else
4073 # define XCAST(fun) (void*)
4074 #endif
4076 static ICOM_VTABLE(IDirectDraw) dga_ddvt = {
4077 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4078 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4079 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4080 XCAST(Compact)IDirectDraw2Impl_Compact,
4081 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4082 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4083 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4084 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4085 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4086 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4087 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4088 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4089 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4090 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4091 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4092 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4093 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4094 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4095 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4096 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4097 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4098 DGA_IDirectDrawImpl_SetDisplayMode,
4099 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4102 static ICOM_VTABLE(IDirectDraw) xlib_ddvt = {
4103 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4104 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4105 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4106 XCAST(Compact)IDirectDraw2Impl_Compact,
4107 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4108 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4109 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4110 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4111 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4112 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4113 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4114 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4115 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4116 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4117 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4118 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4119 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4120 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4121 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4122 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4123 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4124 Xlib_IDirectDrawImpl_SetDisplayMode,
4125 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4128 #undef XCAST
4130 /*****************************************************************************
4131 * IDirectDraw2
4136 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4137 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4139 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4142 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4143 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4145 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4148 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4149 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4151 ICOM_THIS(IDirectDraw2Impl,iface);
4152 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4153 This,ddscaps,total,free
4155 if (total) *total = This->e.dga.fb_memsize * 1024;
4156 if (free) *free = This->e.dga.fb_memsize * 1024;
4157 return DD_OK;
4160 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4161 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4163 ICOM_THIS(IDirectDraw2Impl,iface);
4164 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4165 This,ddscaps,total,free
4167 if (total) *total = 2048 * 1024;
4168 if (free) *free = 2048 * 1024;
4169 return DD_OK;
4172 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt = {
4173 DGA_IDirectDraw2Impl_QueryInterface,
4174 IDirectDraw2Impl_AddRef,
4175 DGA_IDirectDraw2Impl_Release,
4176 IDirectDraw2Impl_Compact,
4177 IDirectDraw2Impl_CreateClipper,
4178 DGA_IDirectDraw2Impl_CreatePalette,
4179 DGA_IDirectDraw2Impl_CreateSurface,
4180 IDirectDraw2Impl_DuplicateSurface,
4181 DGA_IDirectDraw2Impl_EnumDisplayModes,
4182 IDirectDraw2Impl_EnumSurfaces,
4183 IDirectDraw2Impl_FlipToGDISurface,
4184 DGA_IDirectDraw2Impl_GetCaps,
4185 DGA_IDirectDraw2Impl_GetDisplayMode,
4186 IDirectDraw2Impl_GetFourCCCodes,
4187 IDirectDraw2Impl_GetGDISurface,
4188 IDirectDraw2Impl_GetMonitorFrequency,
4189 IDirectDraw2Impl_GetScanLine,
4190 IDirectDraw2Impl_GetVerticalBlankStatus,
4191 IDirectDraw2Impl_Initialize,
4192 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4193 IDirectDraw2Impl_SetCooperativeLevel,
4194 DGA_IDirectDraw2Impl_SetDisplayMode,
4195 IDirectDraw2Impl_WaitForVerticalBlank,
4196 DGA_IDirectDraw2Impl_GetAvailableVidMem
4199 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = {
4200 Xlib_IDirectDraw2Impl_QueryInterface,
4201 IDirectDraw2Impl_AddRef,
4202 Xlib_IDirectDraw2Impl_Release,
4203 IDirectDraw2Impl_Compact,
4204 IDirectDraw2Impl_CreateClipper,
4205 Xlib_IDirectDraw2Impl_CreatePalette,
4206 Xlib_IDirectDraw2Impl_CreateSurface,
4207 IDirectDraw2Impl_DuplicateSurface,
4208 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4209 IDirectDraw2Impl_EnumSurfaces,
4210 IDirectDraw2Impl_FlipToGDISurface,
4211 Xlib_IDirectDraw2Impl_GetCaps,
4212 Xlib_IDirectDraw2Impl_GetDisplayMode,
4213 IDirectDraw2Impl_GetFourCCCodes,
4214 IDirectDraw2Impl_GetGDISurface,
4215 IDirectDraw2Impl_GetMonitorFrequency,
4216 IDirectDraw2Impl_GetScanLine,
4217 IDirectDraw2Impl_GetVerticalBlankStatus,
4218 IDirectDraw2Impl_Initialize,
4219 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4220 IDirectDraw2Impl_SetCooperativeLevel,
4221 Xlib_IDirectDraw2Impl_SetDisplayMode,
4222 IDirectDraw2Impl_WaitForVerticalBlank,
4223 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4226 /*****************************************************************************
4227 * IDirectDraw4
4231 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4232 HDC hdc,
4233 LPDIRECTDRAWSURFACE *lpDDS) {
4234 ICOM_THIS(IDirectDraw4Impl,iface);
4235 FIXME(ddraw, "(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4237 return DD_OK;
4240 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4241 ICOM_THIS(IDirectDraw4Impl,iface);
4242 FIXME(ddraw, "(%p)->()\n", This);
4244 return DD_OK;
4247 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4248 ICOM_THIS(IDirectDraw4Impl,iface);
4249 FIXME(ddraw, "(%p)->()\n", This);
4251 return DD_OK;
4254 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4255 LPDDDEVICEIDENTIFIER lpdddi,
4256 DWORD dwFlags) {
4257 ICOM_THIS(IDirectDraw4Impl,iface);
4258 FIXME(ddraw, "(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4260 return DD_OK;
4263 #ifdef __GNUC__
4264 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4265 #else
4266 # define XCAST(fun) (void*)
4267 #endif
4270 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt = {
4271 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4272 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4273 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4274 XCAST(Compact)IDirectDraw2Impl_Compact,
4275 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4276 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4277 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4278 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4279 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4280 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4281 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4282 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4283 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4284 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4285 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4286 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4287 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4288 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4289 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4290 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4291 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4292 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4293 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4294 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4295 IDirectDraw4Impl_GetSurfaceFromDC,
4296 IDirectDraw4Impl_RestoreAllSurfaces,
4297 IDirectDraw4Impl_TestCooperativeLevel,
4298 IDirectDraw4Impl_GetDeviceIdentifier
4301 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = {
4302 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4303 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4304 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4305 XCAST(Compact)IDirectDraw2Impl_Compact,
4306 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4307 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4308 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4309 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4310 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4311 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4312 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4313 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4314 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4315 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4316 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4317 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4318 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4319 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4320 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4321 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4322 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4323 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4324 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4325 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4326 IDirectDraw4Impl_GetSurfaceFromDC,
4327 IDirectDraw4Impl_RestoreAllSurfaces,
4328 IDirectDraw4Impl_TestCooperativeLevel,
4329 IDirectDraw4Impl_GetDeviceIdentifier
4332 #undef XCAST
4334 /******************************************************************************
4335 * DirectDrawCreate
4338 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4340 LRESULT ret;
4341 IDirectDrawImpl* ddraw = NULL;
4342 DWORD lastError;
4344 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4346 SetLastError( ERROR_SUCCESS );
4347 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4348 if( (!ddraw) &&
4349 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4352 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4355 if( ddraw )
4357 /* Perform any special direct draw functions */
4358 if (msg==WM_PAINT)
4359 ddraw->d.paintable = 1;
4361 /* Now let the application deal with the rest of this */
4362 if( ddraw->d.mainWindow )
4365 /* Don't think that we actually need to call this but...
4366 might as well be on the safe side of things... */
4368 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4369 it should be the procedures of our fake window that gets called
4370 instead of those of the window provided by the application.
4371 And with this patch, mouse clicks work with Monkey Island III
4372 - Lionel */
4373 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4375 if( !ret )
4377 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4378 /* We didn't handle the message - give it to the application */
4379 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4381 ret = CallWindowProcA(tmpWnd->winproc,
4382 ddraw->d.mainWindow, msg, wParam, lParam );
4384 WIN_ReleaseWndPtr(tmpWnd);
4388 } else {
4389 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4393 else
4395 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4398 return ret;
4401 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4402 #ifdef HAVE_LIBXXF86DGA
4403 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4404 int memsize,banksize,width,major,minor,flags,height;
4405 char *addr;
4406 int fd;
4407 int depth;
4409 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4410 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4411 close(fd);
4413 if (fd == -1) {
4414 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4415 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4416 return E_UNEXPECTED;
4418 if (!DDRAW_DGA_Available()) {
4419 TRACE(ddraw,"No XF86DGA detected.\n");
4420 return DDERR_GENERIC;
4422 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4423 (*ilplpDD)->lpvtbl = &dga_ddvt;
4424 (*ilplpDD)->ref = 1;
4425 TSXF86DGAQueryVersion(display,&major,&minor);
4426 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4427 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4428 if (!(flags & XF86DGADirectPresent))
4429 MSG("direct video is NOT PRESENT.\n");
4430 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4431 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4432 addr,width,banksize,memsize
4434 (*ilplpDD)->e.dga.fb_width = width;
4435 (*ilplpDD)->d.width = width;
4436 (*ilplpDD)->e.dga.fb_addr = addr;
4437 (*ilplpDD)->e.dga.fb_memsize = memsize;
4438 (*ilplpDD)->e.dga.fb_banksize = banksize;
4440 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4441 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4442 (*ilplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4443 #ifdef DIABLO_HACK
4444 (*ilplpDD)->e.dga.vpmask = 1;
4445 #else
4446 (*ilplpDD)->e.dga.vpmask = 0;
4447 #endif
4449 /* just assume the default depth is the DGA depth too */
4450 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4451 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4452 #ifdef RESTORE_SIGNALS
4453 SIGNAL_InitHandlers();
4454 #endif
4456 return DD_OK;
4457 #else /* defined(HAVE_LIBXXF86DGA) */
4458 return DDERR_INVALIDDIRECTDRAWGUID;
4459 #endif /* defined(HAVE_LIBXXF86DGA) */
4462 BOOL
4463 DDRAW_XSHM_Available(void)
4465 #ifdef HAVE_LIBXXSHM
4466 if (TSXShmQueryExtension(display))
4468 int major, minor;
4469 Bool shpix;
4471 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4472 return 1;
4473 else
4474 return 0;
4476 else
4477 return 0;
4478 #else
4479 return 0;
4480 #endif
4483 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4484 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4485 int depth;
4487 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4488 (*ilplpDD)->lpvtbl = &xlib_ddvt;
4489 (*ilplpDD)->ref = 1;
4490 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
4492 /* At DirectDraw creation, the depth is the default depth */
4493 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4494 _common_depth_to_pixelformat(depth,
4495 &((*ilplpDD)->d.directdraw_pixelformat),
4496 &((*ilplpDD)->d.screen_pixelformat),
4497 &((*ilplpDD)->d.pixmap_depth));
4498 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4499 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4501 #ifdef HAVE_LIBXXSHM
4502 /* Test if XShm is available. */
4503 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4504 TRACE(ddraw, "Using XShm extension.\n");
4505 #endif
4507 return DD_OK;
4510 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4511 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4512 char xclsid[50];
4513 WNDCLASSA wc;
4514 /* WND* pParentWindow; */
4515 HRESULT ret;
4517 if (HIWORD(lpGUID))
4518 WINE_StringFromCLSID(lpGUID,xclsid);
4519 else {
4520 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4521 lpGUID = NULL;
4524 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
4526 if ((!lpGUID) ||
4527 (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4528 (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4529 (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4530 /* if they didn't request a particular interface, use the best
4531 * supported one */
4532 if (DDRAW_DGA_Available())
4533 lpGUID = &DGA_DirectDraw_GUID;
4534 else
4535 lpGUID = &XLIB_DirectDraw_GUID;
4538 wc.style = CS_GLOBALCLASS;
4539 wc.lpfnWndProc = Xlib_DDWndProc;
4540 wc.cbClsExtra = 0;
4541 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
4542 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
4544 /* We can be a child of the desktop since we're really important */
4546 This code is not useful since hInstance is forced to 0 afterward
4547 pParentWindow = WIN_GetDesktop();
4548 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
4550 wc.hInstance = 0;
4553 wc.hIcon = 0;
4554 wc.hCursor = (HCURSOR)IDC_ARROWA;
4555 wc.hbrBackground= NULL_BRUSH;
4556 wc.lpszMenuName = 0;
4557 wc.lpszClassName= "WINE_DirectDraw";
4558 RegisterClassA(&wc);
4560 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4561 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4562 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4563 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4564 else
4565 goto err;
4568 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
4569 return ret;
4571 err:
4572 ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4573 return DDERR_INVALIDDIRECTDRAWGUID;
4577 #else /* !defined(X_DISPLAY_MISSING) */
4579 #include "windef.h"
4581 #define DD_OK 0
4583 typedef void *LPGUID;
4584 typedef void *LPUNKNOWN;
4585 typedef void *LPDIRECTDRAW;
4586 typedef void *LPDIRECTDRAWCLIPPER;
4587 typedef void *LPDDENUMCALLBACKA;
4588 typedef void *LPDDENUMCALLBACKEXA;
4589 typedef void *LPDDENUMCALLBACKEXW;
4590 typedef void *LPDDENUMCALLBACKW;
4592 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
4594 return DD_OK;
4597 HRESULT WINAPI DirectDrawCreate(
4598 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
4600 return DD_OK;
4603 HRESULT WINAPI DirectDrawCreateClipper(
4604 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
4606 return DD_OK;
4609 HRESULT WINAPI DirectDrawEnumerateA(
4610 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
4612 return DD_OK;
4615 HRESULT WINAPI DirectDrawEnumerateExA(
4616 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
4618 return DD_OK;
4621 HRESULT WINAPI DirectDrawEnumerateExW(
4622 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
4624 return DD_OK;
4627 HRESULT WINAPI DirectDrawEnumerateW(
4628 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
4630 return DD_OK;
4633 #endif /* !defined(X_DISPLAY_MISSING) */
4636 /*******************************************************************************
4637 * DirectDraw ClassFactory
4639 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
4642 typedef struct
4644 /* IUnknown fields */
4645 ICOM_VTABLE(IClassFactory)* lpvtbl;
4646 DWORD ref;
4647 } IClassFactoryImpl;
4649 static HRESULT WINAPI
4650 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
4651 ICOM_THIS(IClassFactoryImpl,iface);
4652 char buf[80];
4654 if (HIWORD(riid))
4655 WINE_StringFromCLSID(riid,buf);
4656 else
4657 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4658 FIXME(ddraw,"(%p)->(%s,%p),stub!\n",This,buf,ppobj);
4659 return E_NOINTERFACE;
4662 static ULONG WINAPI
4663 DDCF_AddRef(LPCLASSFACTORY iface) {
4664 ICOM_THIS(IClassFactoryImpl,iface);
4665 return ++(This->ref);
4668 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
4669 ICOM_THIS(IClassFactoryImpl,iface);
4670 /* static class, won't be freed */
4671 return --(This->ref);
4674 static HRESULT WINAPI DDCF_CreateInstance(
4675 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
4677 ICOM_THIS(IClassFactoryImpl,iface);
4678 char buf[80];
4680 WINE_StringFromCLSID(riid,buf);
4681 TRACE(ddraw,"(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
4682 if ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4683 (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4684 (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4685 /* FIXME: reuse already created DirectDraw if present? */
4686 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
4688 return E_NOINTERFACE;
4691 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
4692 ICOM_THIS(IClassFactoryImpl,iface);
4693 FIXME(ddraw,"(%p)->(%d),stub!\n",This,dolock);
4694 return S_OK;
4697 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl = {
4698 DDCF_QueryInterface,
4699 DDCF_AddRef,
4700 DDCF_Release,
4701 DDCF_CreateInstance,
4702 DDCF_LockServer
4704 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
4706 /*******************************************************************************
4707 * DllGetClassObject [DDRAW.13]
4708 * Retrieves class object from a DLL object
4710 * NOTES
4711 * Docs say returns STDAPI
4713 * PARAMS
4714 * rclsid [I] CLSID for the class object
4715 * riid [I] Reference to identifier of interface for class object
4716 * ppv [O] Address of variable to receive interface pointer for riid
4718 * RETURNS
4719 * Success: S_OK
4720 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
4721 * E_UNEXPECTED
4723 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
4725 char buf[80],xbuf[80];
4727 if (HIWORD(rclsid))
4728 WINE_StringFromCLSID(rclsid,xbuf);
4729 else
4730 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
4731 if (HIWORD(riid))
4732 WINE_StringFromCLSID(riid,buf);
4733 else
4734 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4735 WINE_StringFromCLSID(riid,xbuf);
4736 TRACE(ddraw, "(%p,%p,%p)\n", xbuf, buf, ppv);
4737 if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
4738 *ppv = (LPVOID)&DDRAW_CF;
4739 IClassFactory_AddRef((IClassFactory*)*ppv);
4740 return S_OK;
4742 FIXME(ddraw, "(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
4743 return E_NOINTERFACE;
4747 /*******************************************************************************
4748 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
4750 * RETURNS
4751 * Success: S_OK
4752 * Failure: S_FALSE
4754 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
4756 FIXME(ddraw, "(void): stub\n");
4757 return S_FALSE;