Fixed some unresolved externals on non-Intel archs.
[wine/multimedia.git] / graphics / ddraw.c
blob8fee4092e70f503a7af923bfdd2ff1acc7c81b39
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997-1999 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 # ifdef HAVE_SYS_IPC_H
27 # include <sys/ipc.h>
28 # endif
29 # ifdef HAVE_SYS_SHM_H
30 # include <sys/shm.h>
31 # endif
32 # include "ts_xshm.h"
33 #endif /* defined(HAVE_LIBXXSHM) */
35 #ifdef HAVE_LIBXXF86DGA
36 #include "ts_xf86dga.h"
37 #endif /* defined(HAVE_LIBXXF86DGA) */
39 #ifdef HAVE_LIBXXF86VM
40 #include "ts_xf86vmode.h"
41 #endif /* defined(HAVE_LIBXXF86VM) */
43 #include "x11drv.h"
45 #include <unistd.h>
46 #include <assert.h>
47 #ifdef HAVE_SYS_SIGNAL_H
48 # include <sys/signal.h>
49 #endif
50 #include <fcntl.h>
51 #include <string.h>
52 #include <stdlib.h>
54 #include "winerror.h"
55 #include "gdi.h"
56 #include "heap.h"
57 #include "dc.h"
58 #include "win.h"
59 #include "wine/exception.h"
60 #include "ddraw.h"
61 #include "d3d.h"
62 #include "debugtools.h"
63 #include "spy.h"
64 #include "message.h"
65 #include "options.h"
66 #include "monitor.h"
68 /* This for all the enumeration and creation of D3D-related objects */
69 #include "ddraw_private.h"
70 #include "d3d_private.h"
72 DEFAULT_DEBUG_CHANNEL(ddraw)
74 /* Restore signal handlers overwritten by XF86DGA
76 #define RESTORE_SIGNALS
78 /* Get DDSCAPS of surface (shortcutmacro) */
79 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
81 /* Get the number of bytes per pixel for a given surface */
82 #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
84 #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
86 /* Where do these GUIDs come from? mkuuid.
87 * They exist solely to distinguish between the targets Wine support,
88 * and should be different than any other GUIDs in existence.
90 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
91 0xe2dcb020,
92 0xdc60,
93 0x11d1,
94 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
97 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
98 0x1574a740,
99 0xdc61,
100 0x11d1,
101 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
104 #ifdef HAVE_LIBXXF86DGA
105 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt;
106 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt;
107 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt;
108 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt;
109 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt;
110 #endif /* defined(HAVE_LIBXXF86DGA) */
112 static struct ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt;
113 static struct ICOM_VTABLE(IDirectDraw) xlib_ddvt;
114 static struct ICOM_VTABLE(IDirectDraw2) xlib_dd2vt;
115 static struct ICOM_VTABLE(IDirectDraw4) xlib_dd4vt;
116 static struct ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt;
118 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
119 static struct ICOM_VTABLE(IDirect3D) d3dvt;
120 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
122 /* This is for mode-emulation */
124 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
125 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
126 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
127 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
128 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
129 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
130 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
132 typedef struct {
133 unsigned short bpp;
134 unsigned short depth;
135 unsigned int rmask;
136 unsigned int gmask;
137 unsigned int bmask;
138 } ConvertMode;
140 typedef struct {
141 void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
142 void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
143 } ConvertFuncs;
145 typedef struct {
146 ConvertMode screen, dest;
147 ConvertFuncs funcs;
148 } Convert;
150 static Convert ModeEmulations[] = {
151 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
152 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
153 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
154 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
155 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
158 #ifdef HAVE_LIBXXF86VM
159 static XF86VidModeModeInfo *orig_mode = NULL;
160 #endif
162 #ifdef HAVE_LIBXXSHM
163 static int XShmErrorFlag = 0;
164 #endif
166 static BOOL
167 DDRAW_DGA_Available(void)
169 #ifdef HAVE_LIBXXF86DGA
170 int evbase, evret, fd;
172 if (Options.noDGA)
173 return 0;
175 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
176 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
177 /* others. --stephenc */
178 if ((fd = open("/dev/mem", O_RDWR)) != -1)
179 close(fd);
181 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
182 #else /* defined(HAVE_LIBXXF86DGA) */
183 return 0;
184 #endif /* defined(HAVE_LIBXXF86DGA) */
187 /**********************************************************************/
189 typedef struct {
190 LPVOID lpCallback;
191 LPVOID lpContext;
192 } DirectDrawEnumerateProcData;
194 /***********************************************************************
195 * DirectDrawEnumerateExA (DDRAW.*)
197 HRESULT WINAPI DirectDrawEnumerateExA(
198 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
200 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
202 if (TRACE_ON(ddraw)) {
203 DPRINTF(" Flags : ");
204 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
205 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
206 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
207 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
208 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
209 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
210 DPRINTF("\n");
213 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
214 /* For the moment, Wine does not support any 3D only accelerators */
215 return DD_OK;
218 if (DDRAW_DGA_Available()) {
219 TRACE("Enumerating DGA interface\n");
220 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
221 return DD_OK;
224 TRACE("Enumerating Xlib interface\n");
225 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
226 return DD_OK;
228 TRACE("Enumerating Default interface\n");
229 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
230 return DD_OK;
232 return DD_OK;
235 /***********************************************************************
236 * DirectDrawEnumerateExW (DDRAW.*)
239 static BOOL CALLBACK DirectDrawEnumerateExProcW(
240 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
241 LPVOID lpContext, HMONITOR hm)
243 DirectDrawEnumerateProcData *pEPD =
244 (DirectDrawEnumerateProcData *) lpContext;
245 LPWSTR lpDriverDescriptionW =
246 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
247 LPWSTR lpDriverNameW =
248 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
250 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
251 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
253 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
254 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
256 return bResult;
259 /**********************************************************************/
261 HRESULT WINAPI DirectDrawEnumerateExW(
262 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
264 DirectDrawEnumerateProcData epd;
265 epd.lpCallback = (LPVOID) lpCallback;
266 epd.lpContext = lpContext;
268 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
269 (LPVOID) &epd, 0);
272 /***********************************************************************
273 * DirectDrawEnumerateA (DDRAW.*)
276 static BOOL CALLBACK DirectDrawEnumerateProcA(
277 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
278 LPVOID lpContext, HMONITOR hm)
280 DirectDrawEnumerateProcData *pEPD =
281 (DirectDrawEnumerateProcData *) lpContext;
283 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
284 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
287 /**********************************************************************/
289 HRESULT WINAPI DirectDrawEnumerateA(
290 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
292 DirectDrawEnumerateProcData epd;
293 epd.lpCallback = (LPVOID) lpCallback;
294 epd.lpContext = lpContext;
296 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
297 (LPVOID) &epd, 0);
300 /***********************************************************************
301 * DirectDrawEnumerateW (DDRAW.*)
304 static BOOL WINAPI DirectDrawEnumerateProcW(
305 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
306 LPVOID lpContext, HMONITOR hm)
308 DirectDrawEnumerateProcData *pEPD =
309 (DirectDrawEnumerateProcData *) lpContext;
311 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
312 lpGUID, lpDriverDescription, lpDriverName,
313 pEPD->lpContext);
316 /**********************************************************************/
318 HRESULT WINAPI DirectDrawEnumerateW(
319 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
321 DirectDrawEnumerateProcData epd;
322 epd.lpCallback = (LPVOID) lpCallback;
323 epd.lpContext = lpContext;
325 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
326 (LPVOID) &epd, 0);
329 /***********************************************************************
330 * DSoundHelp (DDRAW.?)
333 /* What is this doing here? */
334 HRESULT WINAPI
335 DSoundHelp(DWORD x,DWORD y,DWORD z) {
336 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
337 return 0;
340 /******************************************************************************
341 * internal helper functions
343 static void _dump_DDBLTFX(DWORD flagmask) {
344 int i;
345 const struct {
346 DWORD mask;
347 char *name;
348 } flags[] = {
349 #define FE(x) { x, #x},
350 FE(DDBLTFX_ARITHSTRETCHY)
351 FE(DDBLTFX_MIRRORLEFTRIGHT)
352 FE(DDBLTFX_MIRRORUPDOWN)
353 FE(DDBLTFX_NOTEARING)
354 FE(DDBLTFX_ROTATE180)
355 FE(DDBLTFX_ROTATE270)
356 FE(DDBLTFX_ROTATE90)
357 FE(DDBLTFX_ZBUFFERRANGE)
358 FE(DDBLTFX_ZBUFFERBASEDEST)
359 #undef FE
361 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
362 if (flags[i].mask & flagmask) {
363 DPRINTF("%s ",flags[i].name);
366 DPRINTF("\n");
370 static void _dump_DDBLTFAST(DWORD flagmask) {
371 int i;
372 const struct {
373 DWORD mask;
374 char *name;
375 } flags[] = {
376 #define FE(x) { x, #x},
377 FE(DDBLTFAST_NOCOLORKEY)
378 FE(DDBLTFAST_SRCCOLORKEY)
379 FE(DDBLTFAST_DESTCOLORKEY)
380 FE(DDBLTFAST_WAIT)
381 #undef FE
383 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
384 if (flags[i].mask & flagmask)
385 DPRINTF("%s ",flags[i].name);
386 DPRINTF("\n");
389 static void _dump_DDBLT(DWORD flagmask) {
390 int i;
391 const struct {
392 DWORD mask;
393 char *name;
394 } flags[] = {
395 #define FE(x) { x, #x},
396 FE(DDBLT_ALPHADEST)
397 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
398 FE(DDBLT_ALPHADESTNEG)
399 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
400 FE(DDBLT_ALPHAEDGEBLEND)
401 FE(DDBLT_ALPHASRC)
402 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
403 FE(DDBLT_ALPHASRCNEG)
404 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
405 FE(DDBLT_ASYNC)
406 FE(DDBLT_COLORFILL)
407 FE(DDBLT_DDFX)
408 FE(DDBLT_DDROPS)
409 FE(DDBLT_KEYDEST)
410 FE(DDBLT_KEYDESTOVERRIDE)
411 FE(DDBLT_KEYSRC)
412 FE(DDBLT_KEYSRCOVERRIDE)
413 FE(DDBLT_ROP)
414 FE(DDBLT_ROTATIONANGLE)
415 FE(DDBLT_ZBUFFER)
416 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
417 FE(DDBLT_ZBUFFERDESTOVERRIDE)
418 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
419 FE(DDBLT_ZBUFFERSRCOVERRIDE)
420 FE(DDBLT_WAIT)
421 FE(DDBLT_DEPTHFILL)
422 #undef FE
424 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
425 if (flags[i].mask & flagmask)
426 DPRINTF("%s ",flags[i].name);
427 DPRINTF("\n");
430 static void _dump_DDSCAPS(void *in) {
431 int i;
432 const struct {
433 DWORD mask;
434 char *name;
435 } flags[] = {
436 #define FE(x) { x, #x},
437 FE(DDSCAPS_RESERVED1)
438 FE(DDSCAPS_ALPHA)
439 FE(DDSCAPS_BACKBUFFER)
440 FE(DDSCAPS_COMPLEX)
441 FE(DDSCAPS_FLIP)
442 FE(DDSCAPS_FRONTBUFFER)
443 FE(DDSCAPS_OFFSCREENPLAIN)
444 FE(DDSCAPS_OVERLAY)
445 FE(DDSCAPS_PALETTE)
446 FE(DDSCAPS_PRIMARYSURFACE)
447 FE(DDSCAPS_PRIMARYSURFACELEFT)
448 FE(DDSCAPS_SYSTEMMEMORY)
449 FE(DDSCAPS_TEXTURE)
450 FE(DDSCAPS_3DDEVICE)
451 FE(DDSCAPS_VIDEOMEMORY)
452 FE(DDSCAPS_VISIBLE)
453 FE(DDSCAPS_WRITEONLY)
454 FE(DDSCAPS_ZBUFFER)
455 FE(DDSCAPS_OWNDC)
456 FE(DDSCAPS_LIVEVIDEO)
457 FE(DDSCAPS_HWCODEC)
458 FE(DDSCAPS_MODEX)
459 FE(DDSCAPS_MIPMAP)
460 FE(DDSCAPS_RESERVED2)
461 FE(DDSCAPS_ALLOCONLOAD)
462 FE(DDSCAPS_VIDEOPORT)
463 FE(DDSCAPS_LOCALVIDMEM)
464 FE(DDSCAPS_NONLOCALVIDMEM)
465 FE(DDSCAPS_STANDARDVGAMODE)
466 FE(DDSCAPS_OPTIMIZED)
467 #undef FE
469 DWORD flagmask = *((DWORD *) in);
470 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
471 if (flags[i].mask & flagmask)
472 DPRINTF("%s ",flags[i].name);
475 static void _dump_pixelformat_flag(DWORD flagmask) {
476 int i;
477 const struct {
478 DWORD mask;
479 char *name;
480 } flags[] = {
481 #define FE(x) { x, #x},
482 FE(DDPF_ALPHAPIXELS)
483 FE(DDPF_ALPHA)
484 FE(DDPF_FOURCC)
485 FE(DDPF_PALETTEINDEXED4)
486 FE(DDPF_PALETTEINDEXEDTO8)
487 FE(DDPF_PALETTEINDEXED8)
488 FE(DDPF_RGB)
489 FE(DDPF_COMPRESSED)
490 FE(DDPF_RGBTOYUV)
491 FE(DDPF_YUV)
492 FE(DDPF_ZBUFFER)
493 FE(DDPF_PALETTEINDEXED1)
494 FE(DDPF_PALETTEINDEXED2)
495 FE(DDPF_ZPIXELS)
496 #undef FE
498 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
499 if (flags[i].mask & flagmask)
500 DPRINTF("%s ",flags[i].name);
503 static void _dump_paletteformat(DWORD dwFlags) {
504 int i;
505 const struct {
506 DWORD mask;
507 char *name;
508 } flags[] = {
509 #define FE(x) { x, #x},
510 FE(DDPCAPS_4BIT)
511 FE(DDPCAPS_8BITENTRIES)
512 FE(DDPCAPS_8BIT)
513 FE(DDPCAPS_INITIALIZE)
514 FE(DDPCAPS_PRIMARYSURFACE)
515 FE(DDPCAPS_PRIMARYSURFACELEFT)
516 FE(DDPCAPS_ALLOW256)
517 FE(DDPCAPS_VSYNC)
518 FE(DDPCAPS_1BIT)
519 FE(DDPCAPS_2BIT)
520 FE(DDPCAPS_ALPHA)
521 #undef FE
523 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
524 if (flags[i].mask & dwFlags)
525 DPRINTF("%s ",flags[i].name);
526 DPRINTF("\n");
529 static void _dump_pixelformat(void *in) {
530 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
531 char *cmd;
533 DPRINTF("( ");
534 _dump_pixelformat_flag(pf->dwFlags);
535 if (pf->dwFlags & DDPF_FOURCC) {
536 DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
538 if (pf->dwFlags & DDPF_RGB) {
539 DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount);
540 switch (pf->u.dwRGBBitCount) {
541 case 4:
542 cmd = "%1lx";
543 break;
544 case 8:
545 cmd = "%02lx";
546 break;
547 case 16:
548 cmd = "%04lx";
549 break;
550 case 24:
551 cmd = "%06lx";
552 break;
553 case 32:
554 cmd = "%08lx";
555 break;
556 default:
557 ERR("Unexpected bit depth !\n");
558 cmd = "%d";
560 DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask);
561 DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask);
562 DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask);
563 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
564 DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask);
566 if (pf->dwFlags & DDPF_ZPIXELS) {
567 DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask);
570 if (pf->dwFlags & DDPF_ZBUFFER) {
571 DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth);
573 if (pf->dwFlags & DDPF_ALPHA) {
574 DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth);
576 DPRINTF(")");
579 static void _dump_colorkeyflag(DWORD ck) {
580 int i;
581 const struct {
582 DWORD mask;
583 char *name;
584 } flags[] = {
585 #define FE(x) { x, #x},
586 FE(DDCKEY_COLORSPACE)
587 FE(DDCKEY_DESTBLT)
588 FE(DDCKEY_DESTOVERLAY)
589 FE(DDCKEY_SRCBLT)
590 FE(DDCKEY_SRCOVERLAY)
591 #undef FE
593 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
594 if (flags[i].mask & ck)
595 DPRINTF("%s ",flags[i].name);
598 static void _dump_DWORD(void *in) {
599 DPRINTF("%ld", *((DWORD *) in));
601 static void _dump_PTR(void *in) {
602 DPRINTF("%p", *((void **) in));
604 static void _dump_DDCOLORKEY(void *in) {
605 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
607 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
610 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
611 int i;
612 struct {
613 DWORD mask;
614 char *name;
615 void (*func)(void *);
616 void *elt;
617 } flags[16], *fe = flags;
618 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
619 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
620 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
621 FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
622 FE(DDSD_PITCH, _dump_DWORD, lPitch);
623 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
624 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth);
625 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
626 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
627 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
628 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
629 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
630 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
631 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount);
632 FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate);
633 FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize);
634 FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface);
635 #undef FE
637 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
638 if (flags[i].mask & lpddsd->dwFlags) {
639 DPRINTF(" - %s : ",flags[i].name);
640 flags[i].func(flags[i].elt);
641 DPRINTF("\n");
646 /******************************************************************************
647 * IDirectDrawSurface methods
649 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
650 * DDS and DDS2 use those functions. (Function calls did not change (except
651 * using different DirectDrawSurfaceX version), just added flags and functions)
654 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
655 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
657 ICOM_THIS(IDirectDrawSurface4Impl,iface);
658 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
659 This,lprect,lpddsd,flags,(DWORD)hnd);
660 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
661 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
662 This,lprect,lpddsd,flags,(DWORD)hnd);
664 /* First, copy the Surface description */
665 *lpddsd = This->s.surface_desc;
666 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
667 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
669 /* If asked only for a part, change the surface pointer */
670 if (lprect) {
671 TRACE(" lprect: %dx%d-%dx%d\n",
672 lprect->top,lprect->left,lprect->bottom,lprect->right
674 if ((lprect->top < 0) ||
675 (lprect->left < 0) ||
676 (lprect->bottom < 0) ||
677 (lprect->right < 0)) {
678 ERR(" Negative values in LPRECT !!!\n");
679 return DDERR_INVALIDPARAMS;
682 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
683 (lprect->top*This->s.surface_desc.lPitch) +
684 lprect->left*GET_BPP(This->s.surface_desc));
685 } else {
686 assert(This->s.surface_desc.u1.lpSurface);
688 return DD_OK;
691 #ifdef HAVE_LIBXXF86DGA
692 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
693 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
695 ICOM_THIS(IDirectDrawSurface4Impl,iface);
696 TRACE("(%p)->Unlock(%p)\n",This,surface);
697 return DD_OK;
699 #endif /* defined(HAVE_LIBXXF86DGA) */
701 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
702 if (This->s.ddraw->d.pixel_convert != NULL)
703 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
704 This->t.xlib.image->data,
705 This->s.surface_desc.dwWidth,
706 This->s.surface_desc.dwHeight,
707 This->s.surface_desc.lPitch,
708 This->s.palette);
710 #ifdef HAVE_LIBXXSHM
711 if (This->s.ddraw->e.xlib.xshm_active) {
712 int compl = This->s.ddraw->e.xlib.xshm_compl;
713 if (compl)
714 X11DRV_EVENT_WaitShmCompletion( compl );
715 This->s.ddraw->e.xlib.xshm_compl = X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
716 TSXShmPutImage(display,
717 This->s.ddraw->d.drawable,
718 DefaultGCOfScreen(X11DRV_GetXScreen()),
719 This->t.xlib.image,
720 0, 0, 0, 0,
721 This->t.xlib.image->width,
722 This->t.xlib.image->height,
723 True);
725 else
726 #endif
727 TSXPutImage( display,
728 This->s.ddraw->d.drawable,
729 DefaultGCOfScreen(X11DRV_GetXScreen()),
730 This->t.xlib.image,
731 0, 0, 0, 0,
732 This->t.xlib.image->width,
733 This->t.xlib.image->height);
736 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
737 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
739 ICOM_THIS(IDirectDrawSurface4Impl,iface);
740 TRACE("(%p)->Unlock(%p)\n",This,surface);
742 if (!This->s.ddraw->d.paintable)
743 return DD_OK;
745 /* Only redraw the screen when unlocking the buffer that is on screen */
746 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
747 Xlib_copy_surface_on_screen(This);
749 if (This->s.palette && This->s.palette->cm)
750 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
752 return DD_OK;
755 static IDirectDrawSurface4Impl* _common_find_flipto(
756 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
758 int i,j,flipable=0;
759 struct _surface_chain *chain = This->s.chain;
761 /* if there was no override flipto, look for current backbuffer */
762 if (!flipto) {
763 /* walk the flip chain looking for backbuffer */
764 for (i=0;i<chain->nrofsurfaces;i++) {
765 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
766 flipable++;
767 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
768 flipto = chain->surfaces[i];
770 /* sanity checks ... */
771 if (!flipto) {
772 if (flipable>1) {
773 for (i=0;i<chain->nrofsurfaces;i++)
774 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
775 break;
776 if (i==chain->nrofsurfaces) {
777 /* we do not have a frontbuffer either */
778 for (i=0;i<chain->nrofsurfaces;i++)
779 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
780 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
781 break;
783 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
784 int k = j % chain->nrofsurfaces;
785 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
786 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
787 flipto = chain->surfaces[k];
788 break;
793 if (!flipto)
794 flipto = This;
796 TRACE("flipping to %p\n",flipto);
798 return flipto;
801 #ifdef HAVE_LIBXXF86DGA
802 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
803 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
805 ICOM_THIS(IDirectDrawSurface4Impl,iface);
806 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
807 DWORD xheight;
808 LPBYTE surf;
810 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
811 iflipto = _common_find_flipto(This,iflipto);
813 /* and flip! */
814 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
815 if (iflipto->s.palette && iflipto->s.palette->cm)
816 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
817 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
820 /* We need to switch the lowlevel surfaces, for DGA this is: */
822 /* The height within the framebuffer */
823 xheight = This->t.dga.fb_height;
824 This->t.dga.fb_height = iflipto->t.dga.fb_height;
825 iflipto->t.dga.fb_height = xheight;
827 /* And the assciated surface pointer */
828 surf = This->s.surface_desc.u1.lpSurface;
829 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
830 iflipto->s.surface_desc.u1.lpSurface = surf;
832 return DD_OK;
834 #endif /* defined(HAVE_LIBXXF86DGA) */
836 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
837 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
839 ICOM_THIS(IDirectDrawSurface4Impl,iface);
840 XImage *image;
841 LPBYTE surf;
842 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
844 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
845 iflipto = _common_find_flipto(This,iflipto);
847 #if defined(HAVE_MESAGL) && 0 /* does not work */
848 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
849 TRACE(" - OpenGL flip\n");
850 ENTER_GL();
851 glXSwapBuffers(display, This->s.ddraw->d.drawable);
852 LEAVE_GL();
854 return DD_OK;
856 #endif /* defined(HAVE_MESAGL) */
858 if (!This->s.ddraw->d.paintable)
859 return DD_OK;
861 /* We need to switch the lowlevel surfaces, for xlib this is: */
862 /* The surface pointer */
863 surf = This->s.surface_desc.u1.lpSurface;
864 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
865 iflipto->s.surface_desc.u1.lpSurface = surf;
866 /* the associated ximage */
867 image = This->t.xlib.image;
868 This->t.xlib.image = iflipto->t.xlib.image;
869 iflipto->t.xlib.image = image;
871 Xlib_copy_surface_on_screen(This);
873 if (iflipto->s.palette && iflipto->s.palette->cm)
874 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
875 return DD_OK;
878 /* The IDirectDrawSurface4::SetPalette method attaches the specified
879 * DirectDrawPalette object to a surface. The surface uses this palette for all
880 * subsequent operations. The palette change takes place immediately.
882 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
883 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
885 ICOM_THIS(IDirectDrawSurface4Impl,iface);
886 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
887 int i;
888 TRACE("(%p)->(%p)\n",This,ipal);
890 if (ipal == NULL) {
891 if( This->s.palette != NULL )
892 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
893 This->s.palette = ipal;
895 return DD_OK;
898 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8))
900 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
901 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
903 if (!Options.managed)
904 TSXInstallColormap(display,ipal->cm);
906 for (i=0;i<256;i++) {
907 XColor xc;
909 xc.red = ipal->palents[i].peRed<<8;
910 xc.blue = ipal->palents[i].peBlue<<8;
911 xc.green = ipal->palents[i].peGreen<<8;
912 xc.flags = DoRed|DoBlue|DoGreen;
913 xc.pixel = i;
914 TSXStoreColor(display,ipal->cm,&xc);
916 TSXInstallColormap(display,ipal->cm);
919 /* According to spec, we are only supposed to
920 * AddRef if this is not the same palette.
922 if( This->s.palette != ipal )
924 if( ipal != NULL )
925 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
926 if( This->s.palette != NULL )
927 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
928 This->s.palette = ipal;
929 /* Perform the refresh */
930 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
932 return DD_OK;
935 #ifdef HAVE_LIBXXF86DGA
936 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
937 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
939 ICOM_THIS(IDirectDrawSurface4Impl,iface);
940 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
941 TRACE("(%p)->(%p)\n",This,ipal);
943 /* According to spec, we are only supposed to
944 * AddRef if this is not the same palette.
946 if( This->s.palette != ipal )
948 if( ipal != NULL )
949 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
950 if( This->s.palette != NULL )
951 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
952 This->s.palette = ipal;
953 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
955 return DD_OK;
957 #endif /* defined(HAVE_LIBXXF86DGA) */
959 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
961 int x, y;
962 LPBYTE first;
964 /* Do first row */
966 #define COLORFILL_ROW(type) { \
967 type *d = (type *) buf; \
968 for (x = 0; x < width; x++) \
969 d[x] = (type) color; \
970 break; \
973 switch(bpp) {
974 case 1: COLORFILL_ROW(BYTE)
975 case 2: COLORFILL_ROW(WORD)
976 case 4: COLORFILL_ROW(DWORD)
977 default:
978 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
979 return DDERR_UNSUPPORTED;
982 #undef COLORFILL_ROW
984 /* Now copy first row */
985 first = buf;
986 for (y = 1; y < height; y++) {
987 buf += lPitch;
988 memcpy(buf, first, width * bpp);
991 return DD_OK;
994 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
995 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
997 ICOM_THIS(IDirectDrawSurface4Impl,iface);
998 RECT xdst,xsrc;
999 DDSURFACEDESC ddesc,sdesc;
1000 HRESULT ret = DD_OK;
1001 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
1002 int x, y;
1003 LPBYTE dbuf, sbuf;
1005 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
1007 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
1008 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1010 if (TRACE_ON(ddraw)) {
1011 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1012 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1013 TRACE("\tflags: ");
1014 _dump_DDBLT(dwFlags);
1015 if (dwFlags & DDBLT_DDFX) {
1016 TRACE("\tblitfx: ");
1017 _dump_DDBLTFX(lpbltfx->dwDDFX);
1021 if (rdst) {
1022 if ((rdst->top < 0) ||
1023 (rdst->left < 0) ||
1024 (rdst->bottom < 0) ||
1025 (rdst->right < 0)) {
1026 ERR(" Negative values in LPRECT !!!\n");
1027 goto release;
1029 memcpy(&xdst,rdst,sizeof(xdst));
1030 } else {
1031 xdst.top = 0;
1032 xdst.bottom = ddesc.dwHeight;
1033 xdst.left = 0;
1034 xdst.right = ddesc.dwWidth;
1037 if (rsrc) {
1038 if ((rsrc->top < 0) ||
1039 (rsrc->left < 0) ||
1040 (rsrc->bottom < 0) ||
1041 (rsrc->right < 0)) {
1042 ERR(" Negative values in LPRECT !!!\n");
1043 goto release;
1045 memcpy(&xsrc,rsrc,sizeof(xsrc));
1046 } else {
1047 if (src) {
1048 xsrc.top = 0;
1049 xsrc.bottom = sdesc.dwHeight;
1050 xsrc.left = 0;
1051 xsrc.right = sdesc.dwWidth;
1052 } else {
1053 memset(&xsrc,0,sizeof(xsrc));
1057 bpp = GET_BPP(ddesc);
1058 srcheight = xsrc.bottom - xsrc.top;
1059 srcwidth = xsrc.right - xsrc.left;
1060 dstheight = xdst.bottom - xdst.top;
1061 dstwidth = xdst.right - xdst.left;
1062 width = (xdst.right - xdst.left) * bpp;
1063 dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1065 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1067 /* First, all the 'source-less' blits */
1068 if (dwFlags & DDBLT_COLORFILL) {
1069 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1070 ddesc.lPitch, lpbltfx->u4.dwFillColor);
1071 dwFlags &= ~DDBLT_COLORFILL;
1074 if (dwFlags & DDBLT_DEPTHFILL) {
1075 #ifdef HAVE_MESAGL
1076 GLboolean ztest;
1078 /* Clears the screen */
1079 TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
1080 glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1081 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1082 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1083 glClear(GL_DEPTH_BUFFER_BIT);
1084 glDepthMask(ztest);
1086 dwFlags &= ~(DDBLT_DEPTHFILL);
1087 #endif /* defined(HAVE_MESAGL) */
1090 if (dwFlags & DDBLT_ROP) {
1091 /* Catch some degenerate cases here */
1092 switch(lpbltfx->dwROP) {
1093 case BLACKNESS:
1094 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1095 break;
1096 case 0xAA0029: /* No-op */
1097 break;
1098 case WHITENESS:
1099 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1100 break;
1101 default:
1102 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
1103 goto error;
1105 dwFlags &= ~DDBLT_ROP;
1108 if (dwFlags & DDBLT_DDROPS) {
1109 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
1112 /* Now the 'with source' blits */
1113 if (src) {
1114 LPBYTE sbase;
1115 int sx, xinc, sy, yinc;
1117 sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1118 xinc = (srcwidth << 16) / dstwidth;
1119 yinc = (srcheight << 16) / dstheight;
1121 if (!dwFlags) {
1123 /* No effects, we can cheat here */
1124 if (dstwidth == srcwidth) {
1125 if (dstheight == srcheight) {
1126 /* No stretching in either direction. This needs to be as fast as possible */
1127 sbuf = sbase;
1128 for (y = 0; y < dstheight; y++) {
1129 memcpy(dbuf, sbuf, width);
1130 sbuf += sdesc.lPitch;
1131 dbuf += ddesc.lPitch;
1133 } else {
1134 /* Stretching in Y direction only */
1135 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1136 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1137 memcpy(dbuf, sbuf, width);
1138 dbuf += ddesc.lPitch;
1141 } else {
1142 /* Stretching in X direction */
1143 int last_sy = -1;
1144 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1145 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1147 if ((sy >> 16) == (last_sy >> 16)) {
1148 /* Same as last row - copy already stretched row */
1149 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1150 } else {
1152 #define STRETCH_ROW(type) { \
1153 type *s = (type *) sbuf, *d = (type *) dbuf; \
1154 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1155 d[x] = s[sx >> 16]; \
1156 break; }
1158 switch(bpp) {
1159 case 1: STRETCH_ROW(BYTE)
1160 case 2: STRETCH_ROW(WORD)
1161 case 4: STRETCH_ROW(DWORD)
1162 default:
1163 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1164 ret = DDERR_UNSUPPORTED;
1165 goto error;
1168 #undef STRETCH_ROW
1171 last_sy = sy;
1172 dbuf += ddesc.lPitch;
1175 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1176 DWORD keylow, keyhigh;
1178 if (dwFlags & DDBLT_KEYSRC) {
1179 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1180 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1181 } else {
1182 /* I'm not sure if this is correct */
1183 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1184 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1185 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1189 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1190 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1192 #define COPYROW_COLORKEY(type) { \
1193 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1194 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1195 tmp = s[sx >> 16]; \
1196 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1198 break; }
1200 switch (bpp) {
1201 case 1: COPYROW_COLORKEY(BYTE)
1202 case 2: COPYROW_COLORKEY(WORD)
1203 case 4: COPYROW_COLORKEY(DWORD)
1204 default:
1205 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1206 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1207 ret = DDERR_UNSUPPORTED;
1208 goto error;
1210 dbuf += ddesc.lPitch;
1213 #undef COPYROW_COLORKEY
1215 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1220 error:
1222 if (dwFlags && FIXME_ON(ddraw)) {
1223 FIXME("\tUnsupported flags: ");
1224 _dump_DDBLT(dwFlags);
1226 release:
1228 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1229 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1231 return DD_OK;
1234 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1235 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1237 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1238 int bpp, w, h, x, y;
1239 DDSURFACEDESC ddesc,sdesc;
1240 HRESULT ret = DD_OK;
1241 LPBYTE sbuf, dbuf;
1244 if (TRACE_ON(ddraw)) {
1245 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1246 This,dstx,dsty,src,rsrc,trans
1248 FIXME(" trans:");
1249 if (FIXME_ON(ddraw))
1250 _dump_DDBLTFAST(trans);
1251 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1253 /* We need to lock the surfaces, or we won't get refreshes when done. */
1254 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1255 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1257 bpp = GET_BPP(This->s.surface_desc);
1258 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1259 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1262 h=rsrc->bottom-rsrc->top;
1263 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1264 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1265 if (h<0) h=0;
1267 w=rsrc->right-rsrc->left;
1268 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1269 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1270 if (w<0) w=0;
1272 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1273 DWORD keylow, keyhigh;
1274 if (trans & DDBLTFAST_SRCCOLORKEY) {
1275 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1276 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1277 } else {
1278 /* I'm not sure if this is correct */
1279 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1280 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1281 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1284 #define COPYBOX_COLORKEY(type) { \
1285 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1286 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1287 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1288 for (y = 0; y < h; y++) { \
1289 for (x = 0; x < w; x++) { \
1290 tmp = s[x]; \
1291 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1293 (LPBYTE)s += sdesc.lPitch; \
1294 (LPBYTE)d += ddesc.lPitch; \
1296 break; \
1299 switch (bpp) {
1300 case 1: COPYBOX_COLORKEY(BYTE)
1301 case 2: COPYBOX_COLORKEY(WORD)
1302 case 4: COPYBOX_COLORKEY(DWORD)
1303 default:
1304 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1305 ret = DDERR_UNSUPPORTED;
1306 goto error;
1309 #undef COPYBOX_COLORKEY
1311 } else {
1312 int width = w * bpp;
1314 for (y = 0; y < h; y++) {
1315 memcpy(dbuf, sbuf, width);
1316 sbuf += sdesc.lPitch;
1317 dbuf += ddesc.lPitch;
1321 error:
1323 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1324 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1325 return ret;
1328 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1329 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1331 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1332 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1333 This,ddbltbatch,x,y
1335 return DD_OK;
1338 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1339 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1341 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1342 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1343 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1344 return DD_OK;
1347 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1348 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1349 ) {
1350 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1351 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1353 /* Simply copy the surface description stored in the object */
1354 *ddsd = This->s.surface_desc;
1356 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1358 return DD_OK;
1361 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1362 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1363 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1364 return ++(This->ref);
1367 #ifdef HAVE_LIBXXF86DGA
1368 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1369 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1371 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1373 if (--(This->ref))
1374 return This->ref;
1376 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1377 /* clear out of surface list */
1378 if (This->t.dga.fb_height == -1)
1379 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1380 else
1381 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1383 /* Free the DIBSection (if any) */
1384 if (This->s.hdc != 0) {
1385 SelectObject(This->s.hdc, This->s.holdbitmap);
1386 DeleteDC(This->s.hdc);
1387 DeleteObject(This->s.DIBsection);
1390 HeapFree(GetProcessHeap(),0,This);
1391 return S_OK;
1393 #endif /* defined(HAVE_LIBXXF86DGA) */
1395 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1396 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1398 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1400 if (--(This->ref))
1401 return This->ref;
1403 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1405 if (This->t.xlib.image != NULL) {
1406 if (This->s.ddraw->d.pixel_convert != NULL) {
1407 /* In pixel conversion mode, there are 2 buffers to release. */
1408 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1410 #ifdef HAVE_LIBXXSHM
1411 if (This->s.ddraw->e.xlib.xshm_active) {
1412 TSXShmDetach(display, &(This->t.xlib.shminfo));
1413 TSXDestroyImage(This->t.xlib.image);
1414 shmdt(This->t.xlib.shminfo.shmaddr);
1415 } else {
1416 #endif
1417 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1418 This->t.xlib.image->data = NULL;
1419 TSXDestroyImage(This->t.xlib.image);
1420 #ifdef HAVE_LIBXXSHM
1422 #endif
1423 } else {
1424 This->t.xlib.image->data = NULL;
1426 #ifdef HAVE_LIBXXSHM
1427 if (This->s.ddraw->e.xlib.xshm_active) {
1428 TSXShmDetach(display, &(This->t.xlib.shminfo));
1429 TSXDestroyImage(This->t.xlib.image);
1430 shmdt(This->t.xlib.shminfo.shmaddr);
1431 } else {
1432 #endif
1433 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1434 TSXDestroyImage(This->t.xlib.image);
1435 #ifdef HAVE_LIBXXSHM
1437 #endif
1439 This->t.xlib.image = 0;
1440 } else {
1441 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1444 if (This->s.palette)
1445 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1447 /* Free the DIBSection (if any) */
1448 if (This->s.hdc != 0) {
1449 SelectObject(This->s.hdc, This->s.holdbitmap);
1450 DeleteDC(This->s.hdc);
1451 DeleteObject(This->s.DIBsection);
1454 HeapFree(GetProcessHeap(),0,This);
1455 return S_OK;
1458 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1459 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1461 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1462 int i,found = 0,xstart;
1463 struct _surface_chain *chain;
1465 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1466 if (TRACE_ON(ddraw)) {
1467 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1469 chain = This->s.chain;
1470 if (!chain)
1471 return DDERR_NOTFOUND;
1473 for (i=0;i<chain->nrofsurfaces;i++)
1474 if (chain->surfaces[i] == This)
1475 break;
1477 xstart = i;
1478 for (i=0;i<chain->nrofsurfaces;i++) {
1479 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1480 #if 0
1481 if (found) /* may not find the same caps twice, (doc) */
1482 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1483 #endif
1484 found = (i+1)+xstart;
1487 if (!found)
1488 return DDERR_NOTFOUND;
1489 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1490 /* FIXME: AddRef? */
1491 TRACE("found %p\n",*lpdsf);
1492 return DD_OK;
1495 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1496 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1498 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1499 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1501 return DDERR_ALREADYINITIALIZED;
1504 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1505 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1507 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1508 TRACE("(%p)->(%p)\n",This,pf);
1510 *pf = This->s.surface_desc.ddpfPixelFormat;
1511 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1512 return DD_OK;
1515 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1516 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1517 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1518 return DD_OK;
1521 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1522 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1524 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1525 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1526 return DD_OK;
1529 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1530 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1532 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1533 FIXME("(%p)->(%p),stub!\n",This,clipper);
1534 return DD_OK;
1537 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1538 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1540 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1541 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1542 int i;
1543 struct _surface_chain *chain;
1545 IDirectDrawSurface4_AddRef(iface);
1547 FIXME("(%p)->(%p)\n",This,surf);
1548 chain = This->s.chain;
1550 if (chain) {
1551 for (i=0;i<chain->nrofsurfaces;i++)
1552 if (chain->surfaces[i] == isurf)
1553 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1554 } else {
1555 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1556 chain->nrofsurfaces = 1;
1557 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1558 chain->surfaces[0] = This;
1559 This->s.chain = chain;
1562 if (chain->surfaces)
1563 chain->surfaces = HeapReAlloc(
1564 GetProcessHeap(),
1566 chain->surfaces,
1567 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1569 else
1570 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1571 isurf->s.chain = chain;
1572 chain->surfaces[chain->nrofsurfaces++] = isurf;
1573 return DD_OK;
1576 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1577 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1578 DDSURFACEDESC desc;
1579 BITMAPINFO *b_info;
1580 UINT usage;
1582 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1584 /* Creates a DIB Section of the same size / format as the surface */
1585 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1587 if (This->s.hdc == 0) {
1588 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1589 case 16:
1590 case 32:
1591 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1592 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1593 break;
1594 #endif
1596 case 24:
1597 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1598 break;
1600 default:
1601 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1602 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1603 break;
1606 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1607 b_info->bmiHeader.biWidth = desc.dwWidth;
1608 b_info->bmiHeader.biHeight = desc.dwHeight;
1609 b_info->bmiHeader.biPlanes = 1;
1610 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1611 #if 0
1612 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1613 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1614 #endif
1615 b_info->bmiHeader.biCompression = BI_RGB;
1616 #if 0
1617 else
1618 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1619 #endif
1620 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1621 b_info->bmiHeader.biXPelsPerMeter = 0;
1622 b_info->bmiHeader.biYPelsPerMeter = 0;
1623 b_info->bmiHeader.biClrUsed = 0;
1624 b_info->bmiHeader.biClrImportant = 0;
1626 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1627 case 16:
1628 case 32:
1629 #if 0
1631 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1633 usage = 0;
1634 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1635 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1636 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1638 break;
1639 #endif
1640 case 24:
1641 /* Nothing to do */
1642 usage = DIB_RGB_COLORS;
1643 break;
1645 default: {
1646 int i;
1648 /* Fill the palette */
1649 usage = DIB_RGB_COLORS;
1651 if (This->s.palette == NULL) {
1652 ERR("Bad palette !!!\n");
1653 } else {
1654 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1655 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1657 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1658 rgb[i].rgbBlue = pent[i].peBlue;
1659 rgb[i].rgbRed = pent[i].peRed;
1660 rgb[i].rgbGreen = pent[i].peGreen;
1664 break;
1666 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1667 b_info,
1668 usage,
1669 &(This->s.bitmap_data),
1673 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1674 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1676 /* b_info is not useful anymore */
1677 HeapFree(GetProcessHeap(), 0, b_info);
1679 /* Create the DC */
1680 This->s.hdc = CreateCompatibleDC(0);
1681 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1684 /* Copy our surface in the DIB section */
1685 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1686 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1687 else
1688 /* TODO */
1689 FIXME("This case has to be done :/\n");
1691 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1692 *lphdc = This->s.hdc;
1694 return DD_OK;
1697 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1698 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1700 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1701 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1702 /* Copy the DIB section to our surface */
1703 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1704 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1705 } else {
1706 /* TODO */
1707 FIXME("This case has to be done :/\n");
1709 /* Unlock the surface */
1710 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1711 return DD_OK;
1714 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1715 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1716 char xrefiid[50];
1718 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1719 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
1721 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1722 * the same interface. And IUnknown does that too of course.
1724 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1725 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1726 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1727 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1728 IsEqualGUID( &IID_IUnknown, refiid )
1730 *obj = This;
1731 IDirectDrawSurface4_AddRef(iface);
1733 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1734 return S_OK;
1736 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1738 /* Texture interface */
1739 *obj = d3dtexture2_create(This);
1740 IDirectDrawSurface4_AddRef(iface);
1741 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1742 return S_OK;
1744 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1746 /* Texture interface */
1747 *obj = d3dtexture_create(This);
1748 IDirectDrawSurface4_AddRef(iface);
1750 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1752 return S_OK;
1754 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1755 /* It is the OpenGL Direct3D Device */
1756 IDirectDrawSurface4_AddRef(iface);
1757 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1758 return S_OK;
1761 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
1762 return OLE_E_ENUM_NOMORE;
1765 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1766 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1767 TRACE("(%p)->(), stub!\n",This);
1768 return DD_OK; /* hmm */
1771 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1772 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1773 int i;
1774 struct _surface_chain *chain = This->s.chain;
1776 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1777 for (i=0;i<chain->nrofsurfaces;i++) {
1778 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1779 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1780 return DD_OK; /* FIXME: return value correct? */
1782 return DD_OK;
1785 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1786 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1787 FIXME("(%p)->(),stub!\n",This);
1788 return DD_OK;
1791 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1792 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1794 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1795 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1796 if (TRACE_ON(ddraw)) {
1797 _dump_colorkeyflag(dwFlags);
1798 DPRINTF(" : ");
1799 _dump_DDCOLORKEY((void *) ckey);
1800 DPRINTF("\n");
1803 /* If this surface was loaded as a texture, call also the texture
1804 SetColorKey callback */
1805 if (This->s.texture) {
1806 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1809 if( dwFlags & DDCKEY_SRCBLT )
1811 dwFlags &= ~DDCKEY_SRCBLT;
1812 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1813 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1816 if( dwFlags & DDCKEY_DESTBLT )
1818 dwFlags &= ~DDCKEY_DESTBLT;
1819 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1820 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1823 if( dwFlags & DDCKEY_SRCOVERLAY )
1825 dwFlags &= ~DDCKEY_SRCOVERLAY;
1826 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1827 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1830 if( dwFlags & DDCKEY_DESTOVERLAY )
1832 dwFlags &= ~DDCKEY_DESTOVERLAY;
1833 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1834 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1837 if( dwFlags )
1839 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1842 return DD_OK;
1846 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1847 LPDIRECTDRAWSURFACE4 iface,
1848 LPRECT lpRect )
1850 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1851 FIXME("(%p)->(%p),stub!\n",This,lpRect);
1853 return DD_OK;
1856 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1857 LPDIRECTDRAWSURFACE4 iface,
1858 DWORD dwFlags,
1859 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1861 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1862 int i;
1863 struct _surface_chain *chain;
1865 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
1866 chain = This->s.chain;
1867 for (i=0;i<chain->nrofsurfaces;i++) {
1868 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
1869 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
1871 chain->surfaces[i]->s.chain = NULL;
1872 memcpy( chain->surfaces+i,
1873 chain->surfaces+(i+1),
1874 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
1876 chain->surfaces = HeapReAlloc(
1877 GetProcessHeap(),
1879 chain->surfaces,
1880 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
1882 chain->nrofsurfaces--;
1883 return DD_OK;
1886 return DD_OK;
1889 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1890 LPDIRECTDRAWSURFACE4 iface,
1891 DWORD dwFlags,
1892 LPVOID lpContext,
1893 LPDDENUMSURFACESCALLBACK lpfnCallback )
1895 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1896 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1897 lpContext, lpfnCallback );
1899 return DD_OK;
1902 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1903 LPDIRECTDRAWSURFACE4 iface,
1904 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1906 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1907 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
1909 return DD_OK;
1912 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1913 LPDIRECTDRAWSURFACE4 iface,
1914 DWORD dwFlags,
1915 LPDDCOLORKEY lpDDColorKey )
1917 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1918 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1920 if( dwFlags & DDCKEY_SRCBLT ) {
1921 dwFlags &= ~DDCKEY_SRCBLT;
1922 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1925 if( dwFlags & DDCKEY_DESTBLT )
1927 dwFlags &= ~DDCKEY_DESTBLT;
1928 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1931 if( dwFlags & DDCKEY_SRCOVERLAY )
1933 dwFlags &= ~DDCKEY_SRCOVERLAY;
1934 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1937 if( dwFlags & DDCKEY_DESTOVERLAY )
1939 dwFlags &= ~DDCKEY_DESTOVERLAY;
1940 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1943 if( dwFlags )
1945 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1948 return DD_OK;
1951 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1952 LPDIRECTDRAWSURFACE4 iface,
1953 DWORD dwFlags )
1955 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1956 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1958 return DD_OK;
1961 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1962 LPDIRECTDRAWSURFACE4 iface,
1963 LPDIRECTDRAWPALETTE* lplpDDPalette )
1965 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1966 FIXME("(%p)->(%p),stub!\n", This, lplpDDPalette);
1968 return DD_OK;
1971 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1972 LPDIRECTDRAWSURFACE4 iface,
1973 LONG lX,
1974 LONG lY)
1976 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1977 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1979 return DD_OK;
1982 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1983 LPDIRECTDRAWSURFACE4 iface,
1984 LPRECT lpSrcRect,
1985 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1986 LPRECT lpDestRect,
1987 DWORD dwFlags,
1988 LPDDOVERLAYFX lpDDOverlayFx )
1990 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1991 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1992 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1994 return DD_OK;
1997 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1998 LPDIRECTDRAWSURFACE4 iface,
1999 DWORD dwFlags )
2001 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2002 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2004 return DD_OK;
2007 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2008 LPDIRECTDRAWSURFACE4 iface,
2009 DWORD dwFlags,
2010 LPDIRECTDRAWSURFACE4 lpDDSReference )
2012 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2013 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2015 return DD_OK;
2018 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2019 LPDIRECTDRAWSURFACE4 iface,
2020 LPVOID* lplpDD )
2022 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2023 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2025 /* Not sure about that... */
2026 *lplpDD = (void *) This->s.ddraw;
2028 return DD_OK;
2031 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2032 LPDIRECTDRAWSURFACE4 iface,
2033 DWORD dwFlags )
2035 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2036 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2038 return DD_OK;
2041 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2042 LPDIRECTDRAWSURFACE4 iface,
2043 DWORD dwFlags )
2045 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2046 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2048 return DD_OK;
2051 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2052 LPDIRECTDRAWSURFACE4 iface,
2053 LPDDSURFACEDESC lpDDSD,
2054 DWORD dwFlags )
2056 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2057 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2059 return DD_OK;
2062 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2063 REFGUID guidTag,
2064 LPVOID lpData,
2065 DWORD cbSize,
2066 DWORD dwFlags) {
2067 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2068 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2070 return DD_OK;
2073 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2074 REFGUID guidTag,
2075 LPVOID lpBuffer,
2076 LPDWORD lpcbBufferSize) {
2077 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2078 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2080 return DD_OK;
2083 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2084 REFGUID guidTag) {
2085 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2086 FIXME("(%p)->(%p)\n", This, guidTag);
2088 return DD_OK;
2091 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2092 LPDWORD lpValue) {
2093 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2094 FIXME("(%p)->(%p)\n", This, lpValue);
2096 return DD_OK;
2099 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2100 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2101 FIXME("(%p)\n", This);
2103 return DD_OK;
2106 #ifdef HAVE_LIBXXF86DGA
2107 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2109 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2110 IDirectDrawSurface4Impl_QueryInterface,
2111 IDirectDrawSurface4Impl_AddRef,
2112 DGA_IDirectDrawSurface4Impl_Release,
2113 IDirectDrawSurface4Impl_AddAttachedSurface,
2114 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2115 IDirectDrawSurface4Impl_Blt,
2116 IDirectDrawSurface4Impl_BltBatch,
2117 IDirectDrawSurface4Impl_BltFast,
2118 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2119 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2120 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2121 DGA_IDirectDrawSurface4Impl_Flip,
2122 IDirectDrawSurface4Impl_GetAttachedSurface,
2123 IDirectDrawSurface4Impl_GetBltStatus,
2124 IDirectDrawSurface4Impl_GetCaps,
2125 IDirectDrawSurface4Impl_GetClipper,
2126 IDirectDrawSurface4Impl_GetColorKey,
2127 IDirectDrawSurface4Impl_GetDC,
2128 IDirectDrawSurface4Impl_GetFlipStatus,
2129 IDirectDrawSurface4Impl_GetOverlayPosition,
2130 IDirectDrawSurface4Impl_GetPalette,
2131 IDirectDrawSurface4Impl_GetPixelFormat,
2132 IDirectDrawSurface4Impl_GetSurfaceDesc,
2133 IDirectDrawSurface4Impl_Initialize,
2134 IDirectDrawSurface4Impl_IsLost,
2135 IDirectDrawSurface4Impl_Lock,
2136 IDirectDrawSurface4Impl_ReleaseDC,
2137 IDirectDrawSurface4Impl_Restore,
2138 IDirectDrawSurface4Impl_SetClipper,
2139 IDirectDrawSurface4Impl_SetColorKey,
2140 IDirectDrawSurface4Impl_SetOverlayPosition,
2141 DGA_IDirectDrawSurface4Impl_SetPalette,
2142 DGA_IDirectDrawSurface4Impl_Unlock,
2143 IDirectDrawSurface4Impl_UpdateOverlay,
2144 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2145 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2146 IDirectDrawSurface4Impl_GetDDInterface,
2147 IDirectDrawSurface4Impl_PageLock,
2148 IDirectDrawSurface4Impl_PageUnlock,
2149 IDirectDrawSurface4Impl_SetSurfaceDesc,
2150 IDirectDrawSurface4Impl_SetPrivateData,
2151 IDirectDrawSurface4Impl_GetPrivateData,
2152 IDirectDrawSurface4Impl_FreePrivateData,
2153 IDirectDrawSurface4Impl_GetUniquenessValue,
2154 IDirectDrawSurface4Impl_ChangeUniquenessValue
2156 #endif /* defined(HAVE_LIBXXF86DGA) */
2158 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2160 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2161 IDirectDrawSurface4Impl_QueryInterface,
2162 IDirectDrawSurface4Impl_AddRef,
2163 Xlib_IDirectDrawSurface4Impl_Release,
2164 IDirectDrawSurface4Impl_AddAttachedSurface,
2165 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2166 IDirectDrawSurface4Impl_Blt,
2167 IDirectDrawSurface4Impl_BltBatch,
2168 IDirectDrawSurface4Impl_BltFast,
2169 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2170 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2171 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2172 Xlib_IDirectDrawSurface4Impl_Flip,
2173 IDirectDrawSurface4Impl_GetAttachedSurface,
2174 IDirectDrawSurface4Impl_GetBltStatus,
2175 IDirectDrawSurface4Impl_GetCaps,
2176 IDirectDrawSurface4Impl_GetClipper,
2177 IDirectDrawSurface4Impl_GetColorKey,
2178 IDirectDrawSurface4Impl_GetDC,
2179 IDirectDrawSurface4Impl_GetFlipStatus,
2180 IDirectDrawSurface4Impl_GetOverlayPosition,
2181 IDirectDrawSurface4Impl_GetPalette,
2182 IDirectDrawSurface4Impl_GetPixelFormat,
2183 IDirectDrawSurface4Impl_GetSurfaceDesc,
2184 IDirectDrawSurface4Impl_Initialize,
2185 IDirectDrawSurface4Impl_IsLost,
2186 IDirectDrawSurface4Impl_Lock,
2187 IDirectDrawSurface4Impl_ReleaseDC,
2188 IDirectDrawSurface4Impl_Restore,
2189 IDirectDrawSurface4Impl_SetClipper,
2190 IDirectDrawSurface4Impl_SetColorKey,
2191 IDirectDrawSurface4Impl_SetOverlayPosition,
2192 Xlib_IDirectDrawSurface4Impl_SetPalette,
2193 Xlib_IDirectDrawSurface4Impl_Unlock,
2194 IDirectDrawSurface4Impl_UpdateOverlay,
2195 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2196 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2197 IDirectDrawSurface4Impl_GetDDInterface,
2198 IDirectDrawSurface4Impl_PageLock,
2199 IDirectDrawSurface4Impl_PageUnlock,
2200 IDirectDrawSurface4Impl_SetSurfaceDesc,
2201 IDirectDrawSurface4Impl_SetPrivateData,
2202 IDirectDrawSurface4Impl_GetPrivateData,
2203 IDirectDrawSurface4Impl_FreePrivateData,
2204 IDirectDrawSurface4Impl_GetUniquenessValue,
2205 IDirectDrawSurface4Impl_ChangeUniquenessValue
2208 /******************************************************************************
2209 * DirectDrawCreateClipper (DDRAW.7)
2211 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2212 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2213 LPUNKNOWN pUnkOuter)
2215 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2216 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2218 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2219 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2220 (*ilplpDDClipper)->ref = 1;
2222 return DD_OK;
2225 /******************************************************************************
2226 * IDirectDrawClipper
2228 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2229 LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
2231 ICOM_THIS(IDirectDrawClipperImpl,iface);
2232 FIXME("(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
2233 return DD_OK;
2236 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2237 ICOM_THIS(IDirectDrawClipperImpl,iface);
2238 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2240 This->ref--;
2241 if (This->ref)
2242 return This->ref;
2243 HeapFree(GetProcessHeap(),0,This);
2244 return S_OK;
2247 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2248 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2250 ICOM_THIS(IDirectDrawClipperImpl,iface);
2251 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2252 if (hmm) *hmm=0;
2253 return DD_OK;
2256 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2257 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2259 ICOM_THIS(IDirectDrawClipperImpl,iface);
2260 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2261 return DD_OK;
2264 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2265 LPDIRECTDRAWCLIPPER iface,
2266 REFIID riid,
2267 LPVOID* ppvObj )
2269 ICOM_THIS(IDirectDrawClipperImpl,iface);
2270 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2271 return OLE_E_ENUM_NOMORE;
2274 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2276 ICOM_THIS(IDirectDrawClipperImpl,iface);
2277 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2278 return ++(This->ref);
2281 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2282 LPDIRECTDRAWCLIPPER iface,
2283 HWND* HWndPtr )
2285 ICOM_THIS(IDirectDrawClipperImpl,iface);
2286 FIXME("(%p)->(%p),stub!\n",This,HWndPtr);
2287 return DD_OK;
2290 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2291 LPDIRECTDRAWCLIPPER iface,
2292 LPDIRECTDRAW lpDD,
2293 DWORD dwFlags )
2295 ICOM_THIS(IDirectDrawClipperImpl,iface);
2296 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2297 return DD_OK;
2300 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2301 LPDIRECTDRAWCLIPPER iface,
2302 BOOL* lpbChanged )
2304 ICOM_THIS(IDirectDrawClipperImpl,iface);
2305 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2306 return DD_OK;
2309 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2311 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2312 IDirectDrawClipperImpl_QueryInterface,
2313 IDirectDrawClipperImpl_AddRef,
2314 IDirectDrawClipperImpl_Release,
2315 IDirectDrawClipperImpl_GetClipList,
2316 IDirectDrawClipperImpl_GetHWnd,
2317 IDirectDrawClipperImpl_Initialize,
2318 IDirectDrawClipperImpl_IsClipListChanged,
2319 IDirectDrawClipperImpl_SetClipList,
2320 IDirectDrawClipperImpl_SetHwnd
2324 /******************************************************************************
2325 * IDirectDrawPalette
2327 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2328 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2330 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2331 int i;
2333 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2334 This,x,start,count,palent);
2336 /* No palette created and not in depth-convertion mode -> BUG ! */
2337 if ((This->cm == None) &&
2338 (This->ddraw->d.palette_convert == NULL))
2340 FIXME("app tried to read colormap for non-palettized mode\n");
2341 return DDERR_GENERIC;
2343 for (i=0;i<count;i++) {
2344 palent[i].peRed = This->palents[start+i].peRed;
2345 palent[i].peBlue = This->palents[start+i].peBlue;
2346 palent[i].peGreen = This->palents[start+i].peGreen;
2347 palent[i].peFlags = This->palents[start+i].peFlags;
2350 return DD_OK;
2353 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2354 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2356 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2357 XColor xc;
2358 int i;
2360 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2361 This,x,start,count,palent
2363 for (i=0;i<count;i++) {
2364 xc.red = palent[i].peRed<<8;
2365 xc.blue = palent[i].peBlue<<8;
2366 xc.green = palent[i].peGreen<<8;
2367 xc.flags = DoRed|DoBlue|DoGreen;
2368 xc.pixel = start+i;
2370 if (This->cm)
2371 TSXStoreColor(display,This->cm,&xc);
2373 This->palents[start+i].peRed = palent[i].peRed;
2374 This->palents[start+i].peBlue = palent[i].peBlue;
2375 This->palents[start+i].peGreen = palent[i].peGreen;
2376 This->palents[start+i].peFlags = palent[i].peFlags;
2379 /* Now, if we are in 'depth conversion mode', update the screen palette */
2380 /* FIXME: we need to update the image or we won't get palette fading. */
2381 if (This->ddraw->d.palette_convert != NULL)
2382 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2384 return DD_OK;
2387 #ifdef HAVE_LIBXXF86DGA
2388 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2389 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2391 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2392 XColor xc;
2393 Colormap cm;
2394 int i;
2396 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2397 This,x,start,count,palent
2399 if (!This->cm) /* should not happen */ {
2400 FIXME("app tried to set colormap in non-palettized mode\n");
2401 return DDERR_GENERIC;
2403 /* FIXME: free colorcells instead of freeing whole map */
2404 cm = This->cm;
2405 This->cm = TSXCopyColormapAndFree(display,This->cm);
2406 TSXFreeColormap(display,cm);
2408 for (i=0;i<count;i++) {
2409 xc.red = palent[i].peRed<<8;
2410 xc.blue = palent[i].peBlue<<8;
2411 xc.green = palent[i].peGreen<<8;
2412 xc.flags = DoRed|DoBlue|DoGreen;
2413 xc.pixel = i+start;
2415 TSXStoreColor(display,This->cm,&xc);
2417 This->palents[start+i].peRed = palent[i].peRed;
2418 This->palents[start+i].peBlue = palent[i].peBlue;
2419 This->palents[start+i].peGreen = palent[i].peGreen;
2420 This->palents[start+i].peFlags = palent[i].peFlags;
2422 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2423 return DD_OK;
2425 #endif /* defined(HAVE_LIBXXF86DGA) */
2427 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2428 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2429 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2430 if (!--(This->ref)) {
2431 if (This->cm) {
2432 TSXFreeColormap(display,This->cm);
2433 This->cm = 0;
2435 HeapFree(GetProcessHeap(),0,This);
2436 return S_OK;
2438 return This->ref;
2441 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2442 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2444 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2445 return ++(This->ref);
2448 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2449 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2451 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2452 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2454 return DDERR_ALREADYINITIALIZED;
2457 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2458 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2460 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2461 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2462 return DD_OK;
2465 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2466 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2468 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2469 char xrefiid[50];
2471 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2472 FIXME("(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2474 return S_OK;
2477 #ifdef HAVE_LIBXXF86DGA
2478 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2480 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2481 IDirectDrawPaletteImpl_QueryInterface,
2482 IDirectDrawPaletteImpl_AddRef,
2483 IDirectDrawPaletteImpl_Release,
2484 IDirectDrawPaletteImpl_GetCaps,
2485 IDirectDrawPaletteImpl_GetEntries,
2486 IDirectDrawPaletteImpl_Initialize,
2487 DGA_IDirectDrawPaletteImpl_SetEntries
2489 #endif /* defined(HAVE_LIBXXF86DGA) */
2491 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2493 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2494 IDirectDrawPaletteImpl_QueryInterface,
2495 IDirectDrawPaletteImpl_AddRef,
2496 IDirectDrawPaletteImpl_Release,
2497 IDirectDrawPaletteImpl_GetCaps,
2498 IDirectDrawPaletteImpl_GetEntries,
2499 IDirectDrawPaletteImpl_Initialize,
2500 Xlib_IDirectDrawPaletteImpl_SetEntries
2503 /*******************************************************************************
2504 * IDirect3D
2506 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2507 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2509 ICOM_THIS(IDirect3DImpl,iface);
2510 /* FIXME: Not sure if this is correct */
2511 char xrefiid[50];
2513 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2514 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2515 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2516 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2517 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2518 *obj = This->ddraw;
2519 IDirect3D_AddRef(iface);
2521 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2523 return S_OK;
2525 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2526 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2527 *obj = This;
2528 IDirect3D_AddRef(iface);
2530 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2532 return S_OK;
2534 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2535 IDirect3D2Impl* d3d;
2537 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2538 d3d->ref = 1;
2539 d3d->ddraw = This->ddraw;
2540 IDirect3D_AddRef(iface);
2541 ICOM_VTBL(d3d) = &d3d2vt;
2542 *obj = d3d;
2544 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2546 return S_OK;
2548 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2549 return OLE_E_ENUM_NOMORE;
2552 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2553 ICOM_THIS(IDirect3DImpl,iface);
2554 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2556 return ++(This->ref);
2559 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2561 ICOM_THIS(IDirect3DImpl,iface);
2562 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2564 if (!--(This->ref)) {
2565 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2566 HeapFree(GetProcessHeap(),0,This);
2567 return S_OK;
2569 return This->ref;
2572 static HRESULT WINAPI IDirect3DImpl_Initialize(
2573 LPDIRECT3D iface, REFIID refiid )
2575 ICOM_THIS(IDirect3DImpl,iface);
2576 /* FIXME: Not sure if this is correct */
2577 char xrefiid[50];
2579 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2580 FIXME("(%p)->(%s):stub.\n",This,xrefiid);
2582 return DDERR_ALREADYINITIALIZED;
2585 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2586 LPD3DENUMDEVICESCALLBACK cb,
2587 LPVOID context) {
2588 ICOM_THIS(IDirect3DImpl,iface);
2589 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2591 /* Call functions defined in d3ddevices.c */
2592 if (!d3d_OpenGL_dx3(cb, context))
2593 return DD_OK;
2595 return DD_OK;
2598 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2599 LPDIRECT3DLIGHT *lplight,
2600 IUnknown *lpunk)
2602 ICOM_THIS(IDirect3DImpl,iface);
2603 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2605 /* Call the creation function that is located in d3dlight.c */
2606 *lplight = d3dlight_create_dx3(This);
2608 return DD_OK;
2611 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2612 LPDIRECT3DMATERIAL *lpmaterial,
2613 IUnknown *lpunk)
2615 ICOM_THIS(IDirect3DImpl,iface);
2616 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2618 /* Call the creation function that is located in d3dviewport.c */
2619 *lpmaterial = d3dmaterial_create(This);
2621 return DD_OK;
2624 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2625 LPDIRECT3DVIEWPORT *lpviewport,
2626 IUnknown *lpunk)
2628 ICOM_THIS(IDirect3DImpl,iface);
2629 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2631 /* Call the creation function that is located in d3dviewport.c */
2632 *lpviewport = d3dviewport_create(This);
2634 return DD_OK;
2637 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2638 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2639 LPD3DFINDDEVICERESULT lpfinddevrst)
2641 ICOM_THIS(IDirect3DImpl,iface);
2642 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2644 return DD_OK;
2647 static ICOM_VTABLE(IDirect3D) d3dvt =
2649 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2650 IDirect3DImpl_QueryInterface,
2651 IDirect3DImpl_AddRef,
2652 IDirect3DImpl_Release,
2653 IDirect3DImpl_Initialize,
2654 IDirect3DImpl_EnumDevices,
2655 IDirect3DImpl_CreateLight,
2656 IDirect3DImpl_CreateMaterial,
2657 IDirect3DImpl_CreateViewport,
2658 IDirect3DImpl_FindDevice
2661 /*******************************************************************************
2662 * IDirect3D2
2664 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2665 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2666 ICOM_THIS(IDirect3D2Impl,iface);
2668 /* FIXME: Not sure if this is correct */
2669 char xrefiid[50];
2671 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2672 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2673 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2674 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2675 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2676 *obj = This->ddraw;
2677 IDirect3D2_AddRef(iface);
2679 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2681 return S_OK;
2683 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2684 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2685 *obj = This;
2686 IDirect3D2_AddRef(iface);
2688 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2690 return S_OK;
2692 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2693 IDirect3DImpl* d3d;
2695 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2696 d3d->ref = 1;
2697 d3d->ddraw = This->ddraw;
2698 IDirect3D2_AddRef(iface);
2699 ICOM_VTBL(d3d) = &d3dvt;
2700 *obj = d3d;
2702 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2704 return S_OK;
2706 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2707 return OLE_E_ENUM_NOMORE;
2710 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2711 ICOM_THIS(IDirect3D2Impl,iface);
2712 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2714 return ++(This->ref);
2717 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2718 ICOM_THIS(IDirect3D2Impl,iface);
2719 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2721 if (!--(This->ref)) {
2722 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2723 HeapFree(GetProcessHeap(),0,This);
2724 return S_OK;
2726 return This->ref;
2729 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2730 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2732 ICOM_THIS(IDirect3D2Impl,iface);
2733 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2735 /* Call functions defined in d3ddevices.c */
2736 if (!d3d_OpenGL(cb, context))
2737 return DD_OK;
2739 return DD_OK;
2742 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2743 LPDIRECT3DLIGHT *lplight,
2744 IUnknown *lpunk)
2746 ICOM_THIS(IDirect3D2Impl,iface);
2747 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2749 /* Call the creation function that is located in d3dlight.c */
2750 *lplight = d3dlight_create(This);
2752 return DD_OK;
2755 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2756 LPDIRECT3DMATERIAL2 *lpmaterial,
2757 IUnknown *lpunk)
2759 ICOM_THIS(IDirect3D2Impl,iface);
2760 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2762 /* Call the creation function that is located in d3dviewport.c */
2763 *lpmaterial = d3dmaterial2_create(This);
2765 return DD_OK;
2768 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2769 LPDIRECT3DVIEWPORT2 *lpviewport,
2770 IUnknown *lpunk)
2772 ICOM_THIS(IDirect3D2Impl,iface);
2773 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2775 /* Call the creation function that is located in d3dviewport.c */
2776 *lpviewport = d3dviewport2_create(This);
2778 return DD_OK;
2781 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2782 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2783 LPD3DFINDDEVICERESULT lpfinddevrst)
2785 ICOM_THIS(IDirect3D2Impl,iface);
2786 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2788 return DD_OK;
2791 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2792 REFCLSID rguid,
2793 LPDIRECTDRAWSURFACE surface,
2794 LPDIRECT3DDEVICE2 *device)
2796 ICOM_THIS(IDirect3D2Impl,iface);
2797 char xbuf[50];
2799 WINE_StringFromCLSID(rguid,xbuf);
2800 FIXME("(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2802 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2803 IDirect3D2_AddRef(iface);
2804 return DD_OK;
2807 return DDERR_INVALIDPARAMS;
2810 static ICOM_VTABLE(IDirect3D2) d3d2vt =
2812 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2813 IDirect3D2Impl_QueryInterface,
2814 IDirect3D2Impl_AddRef,
2815 IDirect3D2Impl_Release,
2816 IDirect3D2Impl_EnumDevices,
2817 IDirect3D2Impl_CreateLight,
2818 IDirect3D2Impl_CreateMaterial,
2819 IDirect3D2Impl_CreateViewport,
2820 IDirect3D2Impl_FindDevice,
2821 IDirect3D2Impl_CreateDevice
2824 /*******************************************************************************
2825 * IDirectDraw
2828 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2829 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2831 static INT ddrawXlibThisOffset = 0;
2833 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2834 IDirectDrawSurfaceImpl* lpdsf)
2836 int bpp;
2838 /* The surface was already allocated when entering in this function */
2839 TRACE("using system memory for a surface (%p) \n", lpdsf);
2841 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
2842 /* This is a Z Buffer */
2843 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
2844 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
2845 } else {
2846 /* This is a standard image */
2847 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
2848 /* No pixel format => use DirectDraw's format */
2849 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2850 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
2853 bpp = GET_BPP(lpdsf->s.surface_desc);
2856 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
2857 /* The surface was preallocated : seems that we have nothing to do :-) */
2858 WARN("Creates a surface that is already allocated : assuming this is an application bug !\n");
2861 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
2862 lpdsf->s.surface_desc.u1.lpSurface =
2863 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
2864 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
2866 return DD_OK;
2869 #ifdef HAVE_LIBXXF86DGA
2870 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2871 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2873 ICOM_THIS(IDirectDraw2Impl,iface);
2874 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2875 int i, fbheight = This->e.dga.fb_height;
2877 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2878 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
2880 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
2881 GetProcessHeap(),
2882 HEAP_ZERO_MEMORY,
2883 sizeof(IDirectDrawSurfaceImpl)
2885 IDirectDraw2_AddRef(iface);
2887 (*ilpdsf)->ref = 1;
2888 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2889 (*ilpdsf)->s.ddraw = This;
2890 (*ilpdsf)->s.palette = NULL;
2891 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2893 /* Copy the surface description */
2894 (*ilpdsf)->s.surface_desc = *lpddsd;
2896 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2897 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2898 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2899 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2901 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
2903 /* Check if this a 'primary surface' or not */
2904 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2905 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2906 /* This is THE primary surface => there is DGA-specific code */
2908 /* First, store the surface description */
2909 (*ilpdsf)->s.surface_desc = *lpddsd;
2911 /* Find a viewport */
2912 for (i=0;i<32;i++)
2913 if (!(This->e.dga.vpmask & (1<<i)))
2914 break;
2915 TRACE("using viewport %d for a primary surface\n",i);
2916 /* if i == 32 or maximum ... return error */
2917 This->e.dga.vpmask|=(1<<i);
2918 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
2919 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
2921 (*ilpdsf)->s.surface_desc.u1.lpSurface =
2922 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
2924 (*ilpdsf)->t.dga.fb_height = i*fbheight;
2926 /* Add flags if there were not present */
2927 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2928 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2929 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2930 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2931 /* We put our surface always in video memory */
2932 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2933 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2934 (*ilpdsf)->s.chain = NULL;
2936 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2937 IDirectDrawSurface4Impl* back;
2938 int bbc;
2940 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
2941 int i;
2943 back = (IDirectDrawSurface4Impl*)HeapAlloc(
2944 GetProcessHeap(),
2945 HEAP_ZERO_MEMORY,
2946 sizeof(IDirectDrawSurface4Impl)
2948 IDirectDraw2_AddRef(iface);
2949 back->ref = 1;
2950 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2951 for (i=0;i<32;i++)
2952 if (!(This->e.dga.vpmask & (1<<i)))
2953 break;
2954 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
2955 /* if i == 32 or maximum ... return error */
2956 This->e.dga.vpmask|=(1<<i);
2957 back->t.dga.fb_height = i*fbheight;
2958 /* Copy the surface description from the front buffer */
2959 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2960 /* Change the parameters that are not the same */
2961 back->s.surface_desc.u1.lpSurface =
2962 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
2964 back->s.ddraw = This;
2965 /* Add relevant info to front and back buffers */
2966 /* FIXME: backbuffer/frontbuffer handling broken here, but
2967 * will be fixed up in _Flip().
2969 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
2970 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
2971 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2972 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
2973 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
2976 } else {
2977 /* There is no DGA-specific code here...
2978 Go to the common surface creation function */
2979 return common_off_screen_CreateSurface(This, *ilpdsf);
2981 return DD_OK;
2983 #endif /* defined(HAVE_LIBXXF86DGA) */
2985 #ifdef HAVE_LIBXXSHM
2986 /* Error handlers for Image creation */
2987 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2988 XShmErrorFlag = 1;
2989 return 0;
2992 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2993 XImage *img;
2994 int (*WineXHandler)(Display *, XErrorEvent *);
2996 img = TSXShmCreateImage(display,
2997 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2998 This->d.pixmap_depth,
2999 ZPixmap,
3000 NULL,
3001 &(lpdsf->t.xlib.shminfo),
3002 lpdsf->s.surface_desc.dwWidth,
3003 lpdsf->s.surface_desc.dwHeight
3006 if (img == NULL) {
3007 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3008 This->e.xlib.xshm_active = 0;
3009 return NULL;
3012 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3013 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3014 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3015 This->e.xlib.xshm_active = 0;
3016 TSXDestroyImage(img);
3017 return NULL;
3020 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3022 if (img->data == (char *) -1) {
3023 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3024 This->e.xlib.xshm_active = 0;
3025 TSXDestroyImage(img);
3026 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3027 return NULL;
3029 lpdsf->t.xlib.shminfo.readOnly = False;
3031 /* This is where things start to get trickier....
3032 * First, we flush the current X connections to be sure to catch all
3033 * non-XShm related errors
3035 TSXSync(display, False);
3036 /* Then we enter in the non-thread safe part of the tests */
3037 EnterCriticalSection( &X11DRV_CritSection );
3039 /* Reset the error flag, sets our new error handler and try to attach
3040 * the surface
3042 XShmErrorFlag = 0;
3043 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3044 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3045 XSync(display, False);
3047 /* Check the error flag */
3048 if (XShmErrorFlag) {
3049 /* An error occured */
3050 XFlush(display);
3051 XShmErrorFlag = 0;
3052 XDestroyImage(img);
3053 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3054 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3055 XSetErrorHandler(WineXHandler);
3057 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3058 This->e.xlib.xshm_active = 0;
3060 /* Leave the critical section */
3061 LeaveCriticalSection( &X11DRV_CritSection );
3062 return NULL;
3064 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3065 * this works, but it may be a bit overkill....
3067 XSetErrorHandler(WineXHandler);
3068 LeaveCriticalSection( &X11DRV_CritSection );
3070 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3072 if (This->d.pixel_convert != NULL) {
3073 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3074 GetProcessHeap(),
3075 HEAP_ZERO_MEMORY,
3076 lpdsf->s.surface_desc.dwWidth *
3077 lpdsf->s.surface_desc.dwHeight *
3078 PFGET_BPP(This->d.directdraw_pixelformat)
3080 } else {
3081 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3083 return img;
3085 #endif /* HAVE_LIBXXSHM */
3087 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3088 XImage *img = NULL;
3089 void *img_data;
3091 #ifdef HAVE_LIBXXSHM
3092 if (This->e.xlib.xshm_active)
3093 img = create_xshmimage(This, lpdsf);
3095 if (img == NULL) {
3096 #endif
3097 /* Allocate surface memory */
3098 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3099 GetProcessHeap(),HEAP_ZERO_MEMORY,
3100 lpdsf->s.surface_desc.dwWidth *
3101 lpdsf->s.surface_desc.dwHeight *
3102 PFGET_BPP(This->d.directdraw_pixelformat)
3105 if (This->d.pixel_convert != NULL) {
3106 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3107 lpdsf->s.surface_desc.dwWidth *
3108 lpdsf->s.surface_desc.dwHeight *
3109 PFGET_BPP(This->d.screen_pixelformat)
3111 } else {
3112 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3115 /* In this case, create an XImage */
3116 img = TSXCreateImage(display,
3117 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3118 This->d.pixmap_depth,
3119 ZPixmap,
3121 img_data,
3122 lpdsf->s.surface_desc.dwWidth,
3123 lpdsf->s.surface_desc.dwHeight,
3125 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3127 #ifdef HAVE_LIBXXSHM
3129 #endif
3130 if (This->d.pixel_convert != NULL)
3131 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3132 else
3133 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3134 return img;
3137 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3138 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3140 ICOM_THIS(IDirectDraw2Impl,iface);
3141 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3143 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3145 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3147 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3148 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3151 IDirectDraw2_AddRef(iface);
3153 (*ilpdsf)->s.ddraw = This;
3154 (*ilpdsf)->ref = 1;
3155 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3156 (*ilpdsf)->s.palette = NULL;
3157 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3159 /* Copy the surface description */
3160 (*ilpdsf)->s.surface_desc = *lpddsd;
3162 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3163 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3164 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3165 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3166 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3168 /* Check if this a 'primary surface' or not */
3169 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3170 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3171 XImage *img;
3173 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3174 /* Create the XImage */
3175 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3176 if (img == NULL)
3177 return DDERR_OUTOFMEMORY;
3178 (*ilpdsf)->t.xlib.image = img;
3180 /* Add flags if there were not present */
3181 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3182 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3183 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3184 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3185 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3187 /* Check for backbuffers */
3188 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3189 IDirectDrawSurface4Impl* back;
3190 XImage *img;
3191 int i;
3193 for (i=lpddsd->dwBackBufferCount;i--;) {
3194 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3195 GetProcessHeap(),HEAP_ZERO_MEMORY,
3196 sizeof(IDirectDrawSurface4Impl)
3199 TRACE("allocated back-buffer (%p)\n", back);
3201 IDirectDraw2_AddRef(iface);
3202 back->s.ddraw = This;
3204 back->ref = 1;
3205 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3206 /* Copy the surface description from the front buffer */
3207 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3209 /* Create the XImage */
3210 img = create_ximage(This, back);
3211 if (img == NULL)
3212 return DDERR_OUTOFMEMORY;
3213 back->t.xlib.image = img;
3215 /* Add relevant info to front and back buffers */
3216 /* FIXME: backbuffer/frontbuffer handling broken here, but
3217 * will be fixed up in _Flip().
3219 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3220 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3221 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3222 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3223 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3226 } else {
3227 /* There is no Xlib-specific code here...
3228 Go to the common surface creation function */
3229 return common_off_screen_CreateSurface(This, *ilpdsf);
3231 return DD_OK;
3234 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3235 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3237 ICOM_THIS(IDirectDraw2Impl,iface);
3238 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3239 *dst = src; /* FIXME */
3240 return DD_OK;
3244 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3245 * even when the approbiate bitmasks are not specified.
3247 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3248 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3250 ICOM_THIS(IDirectDraw2Impl,iface);
3252 int i;
3253 const struct {
3254 int mask;
3255 char *name;
3256 } flagmap[] = {
3257 #define FE(x) { x, #x},
3258 FE(DDSCL_FULLSCREEN)
3259 FE(DDSCL_ALLOWREBOOT)
3260 FE(DDSCL_NOWINDOWCHANGES)
3261 FE(DDSCL_NORMAL)
3262 FE(DDSCL_ALLOWMODEX)
3263 FE(DDSCL_EXCLUSIVE)
3264 FE(DDSCL_SETFOCUSWINDOW)
3265 FE(DDSCL_SETDEVICEWINDOW)
3266 FE(DDSCL_CREATEDEVICEWINDOW)
3267 #undef FE
3271 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3272 This->d.mainWindow = hwnd;
3274 /* This will be overwritten in the case of Full Screen mode.
3275 Windowed games could work with that :-) */
3276 if (hwnd)
3278 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3279 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3280 WIN_ReleaseWndPtr(tmpWnd);
3282 if( !This->d.drawable ) {
3283 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3284 WIN_ReleaseDesktop();
3286 TRACE("Setting drawable to %ld\n", This->d.drawable);
3289 return DD_OK;
3292 /* Small helper to either use the cooperative window or create a new
3293 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3295 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3296 RECT rect;
3298 /* Do not destroy the application supplied cooperative window */
3299 if (This->d.window && This->d.window != This->d.mainWindow) {
3300 DestroyWindow(This->d.window);
3301 This->d.window = 0;
3303 /* Sanity check cooperative window before assigning it to drawing. */
3304 if ( IsWindow(This->d.mainWindow) &&
3305 IsWindowVisible(This->d.mainWindow)
3307 /* if it does not fit, resize the cooperative window.
3308 * and hope the app likes it
3310 GetWindowRect(This->d.mainWindow,&rect);
3311 if ((((rect.right-rect.left) >= This->d.width) &&
3312 ((rect.bottom-rect.top) >= This->d.height))
3314 This->d.window = This->d.mainWindow;
3315 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3319 /* ... failed, create new one. */
3320 if (!This->d.window) {
3321 This->d.window = CreateWindowExA(
3323 "WINE_DirectDraw",
3324 "WINE_DirectDraw",
3325 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3326 0,0,
3327 This->d.width,
3328 This->d.height,
3332 NULL
3334 /*Store THIS with the window. We'll use it in the window procedure*/
3335 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3336 ShowWindow(This->d.window,TRUE);
3337 UpdateWindow(This->d.window);
3339 SetFocus(This->d.window);
3342 static int _common_depth_to_pixelformat(DWORD depth,
3343 DDPIXELFORMAT *pixelformat,
3344 DDPIXELFORMAT *screen_pixelformat,
3345 int *pix_depth) {
3346 XVisualInfo *vi;
3347 XPixmapFormatValues *pf;
3348 XVisualInfo vt;
3349 int nvisuals, npixmap, i;
3350 int match = 0;
3351 int index = -2;
3353 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3354 pf = XListPixmapFormats(display, &npixmap);
3356 for (i = 0; i < npixmap; i++) {
3357 if (pf[i].depth == depth) {
3358 int j;
3360 for (j = 0; j < nvisuals; j++) {
3361 if (vi[j].depth == pf[i].depth) {
3362 pixelformat->dwSize = sizeof(*pixelformat);
3363 if (depth == 8) {
3364 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3365 pixelformat->u1.dwRBitMask = 0;
3366 pixelformat->u2.dwGBitMask = 0;
3367 pixelformat->u3.dwBBitMask = 0;
3368 } else {
3369 pixelformat->dwFlags = DDPF_RGB;
3370 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3371 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3372 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3374 pixelformat->dwFourCC = 0;
3375 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3376 pixelformat->u4.dwRGBAlphaBitMask= 0;
3378 *screen_pixelformat = *pixelformat;
3380 if (pix_depth != NULL)
3381 *pix_depth = vi[j].depth;
3383 match = 1;
3384 index = -1;
3386 goto clean_up_and_exit;
3390 ERR("No visual corresponding to pixmap format !\n");
3394 if (match == 0) {
3395 /* We try now to find an emulated mode */
3396 int c;
3398 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3399 if (ModeEmulations[c].dest.depth == depth) {
3400 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3401 for (i = 0; i < npixmap; i++) {
3402 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3403 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3404 int j;
3406 for (j = 0; j < nvisuals; j++) {
3407 if (vi[j].depth == pf[i].depth) {
3408 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3409 screen_pixelformat->dwFlags = DDPF_RGB;
3410 screen_pixelformat->dwFourCC = 0;
3411 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3412 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3413 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3414 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3415 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3417 pixelformat->dwSize = sizeof(*pixelformat);
3418 pixelformat->dwFourCC = 0;
3419 if (depth == 8) {
3420 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3421 pixelformat->u.dwRGBBitCount = 8;
3422 pixelformat->u1.dwRBitMask = 0;
3423 pixelformat->u2.dwGBitMask = 0;
3424 pixelformat->u3.dwBBitMask = 0;
3425 } else {
3426 pixelformat->dwFlags = DDPF_RGB;
3427 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3428 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3429 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3430 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3432 pixelformat->u4.dwRGBAlphaBitMask= 0;
3434 if (pix_depth != NULL)
3435 *pix_depth = vi[j].depth;
3437 match = 2;
3438 index = c;
3440 goto clean_up_and_exit;
3443 ERR("No visual corresponding to pixmap format !\n");
3451 clean_up_and_exit:
3452 TSXFree(vi);
3453 TSXFree(pf);
3455 return index;
3458 #ifdef HAVE_LIBXXF86DGA
3459 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3460 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3462 ICOM_THIS(IDirectDrawImpl,iface);
3463 int i,mode_count;
3465 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3467 /* We hope getting the asked for depth */
3468 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3469 /* I.e. no visual found or emulated */
3470 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3471 return DDERR_UNSUPPORTEDMODE;
3474 if (This->d.width < width) {
3475 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3476 return DDERR_UNSUPPORTEDMODE;
3478 This->d.width = width;
3479 This->d.height = height;
3481 /* adjust fb_height, so we don't overlap */
3482 if (This->e.dga.fb_height < height)
3483 This->e.dga.fb_height = height;
3484 _common_IDirectDrawImpl_SetDisplayMode(This);
3486 #ifdef HAVE_LIBXXF86VM
3488 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3489 XF86VidModeModeLine mod_tmp;
3490 /* int dotclock_tmp; */
3492 /* save original video mode and set fullscreen if available*/
3493 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3494 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3495 orig_mode->hdisplay = mod_tmp.hdisplay;
3496 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3497 orig_mode->hsyncend = mod_tmp.hsyncend;
3498 orig_mode->htotal = mod_tmp.htotal;
3499 orig_mode->vdisplay = mod_tmp.vdisplay;
3500 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3501 orig_mode->vsyncend = mod_tmp.vsyncend;
3502 orig_mode->vtotal = mod_tmp.vtotal;
3503 orig_mode->flags = mod_tmp.flags;
3504 orig_mode->private = mod_tmp.private;
3506 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3507 for (i=0;i<mode_count;i++)
3509 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3511 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3512 *vidmode = *(all_modes[i]);
3513 break;
3514 } else
3515 TSXFree(all_modes[i]->private);
3517 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3518 TSXFree(all_modes);
3520 if (!vidmode)
3521 WARN("Fullscreen mode not available!\n");
3523 if (vidmode)
3525 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3526 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3527 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3528 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3529 #endif
3532 #endif
3534 /* FIXME: this function OVERWRITES several signal handlers.
3535 * can we save them? and restore them later? In a way that
3536 * it works for the library too?
3538 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3539 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3541 #ifdef RESTORE_SIGNALS
3542 SIGNAL_Init();
3543 #endif
3544 return DD_OK;
3546 #endif /* defined(HAVE_LIBXXF86DGA) */
3548 /* *************************************
3549 16 / 15 bpp to palettized 8 bpp
3550 ************************************* */
3551 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3552 unsigned char *c_src = (unsigned char *) src;
3553 unsigned short *c_dst = (unsigned short *) dst;
3554 int y;
3556 if (palette != NULL) {
3557 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3559 for (y = height; y--; ) {
3560 #if defined(__i386__) && defined(__GNUC__)
3561 /* gcc generates slightly inefficient code for the the copy / lookup,
3562 * it generates one excess memory access (to pal) per pixel. Since
3563 * we know that pal is not modified by the memory write we can
3564 * put it into a register and reduce the number of memory accesses
3565 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3566 * (This is not guaranteed to be the fastest method.)
3568 __asm__ __volatile__(
3569 "xor %%eax,%%eax\n"
3570 "1:\n"
3571 " lodsb\n"
3572 " movw (%%edx,%%eax,2),%%ax\n"
3573 " stosw\n"
3574 " xor %%eax,%%eax\n"
3575 " loop 1b\n"
3576 : "=S" (c_src), "=D" (c_dst)
3577 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3578 : "eax", "cc", "memory"
3580 c_src+=(pitch-width);
3581 #else
3582 unsigned char * srclineend = c_src+width;
3583 while (c_src < srclineend)
3584 *c_dst++ = pal[*c_src++];
3585 c_src+=(pitch-width);
3586 #endif
3588 } else {
3589 WARN("No palette set...\n");
3590 memset(dst, 0, width * height * 2);
3593 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3594 int i;
3595 unsigned short *pal = (unsigned short *) screen_palette;
3597 for (i = 0; i < count; i++)
3598 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3599 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3600 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3602 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3603 int i;
3604 unsigned short *pal = (unsigned short *) screen_palette;
3606 for (i = 0; i < count; i++)
3607 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3608 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3609 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3612 /* *************************************
3613 24 to palettized 8 bpp
3614 ************************************* */
3615 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3616 unsigned char *c_src = (unsigned char *) src;
3617 unsigned char *c_dst = (unsigned char *) dst;
3618 int y;
3620 if (palette != NULL) {
3621 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3623 for (y = height; y--; ) {
3624 unsigned char * srclineend = c_src+width;
3625 while (c_src < srclineend ) {
3626 register long pixel = pal[*c_src++];
3627 *c_dst++ = pixel;
3628 *c_dst++ = pixel>>8;
3629 *c_dst++ = pixel>>16;
3631 c_src+=(pitch-width);
3633 } else {
3634 WARN("No palette set...\n");
3635 memset(dst, 0, width * height * 4);
3638 /* *************************************
3639 32 bpp to palettized 8 bpp
3640 ************************************* */
3641 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3642 unsigned char *c_src = (unsigned char *) src;
3643 unsigned int *c_dst = (unsigned int *) dst;
3644 int y;
3646 if (palette != NULL) {
3647 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3649 for (y = height; y--; ) {
3650 #if defined(__i386__) && defined(__GNUC__)
3651 /* See comment in pixel_convert_16_to_8 */
3652 __asm__ __volatile__(
3653 "xor %%eax,%%eax\n"
3654 "1:\n"
3655 " lodsb\n"
3656 " movl (%%edx,%%eax,4),%%eax\n"
3657 " stosl\n"
3658 " xor %%eax,%%eax\n"
3659 " loop 1b\n"
3660 : "=S" (c_src), "=D" (c_dst)
3661 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3662 : "eax", "cc", "memory"
3664 c_src+=(pitch-width);
3665 #else
3666 unsigned char * srclineend = c_src+width;
3667 while (c_src < srclineend )
3668 *c_dst++ = pal[*c_src++];
3669 c_src+=(pitch-width);
3670 #endif
3672 } else {
3673 WARN("No palette set...\n");
3674 memset(dst, 0, width * height * 4);
3678 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3679 int i;
3680 unsigned int *pal = (unsigned int *) screen_palette;
3682 for (i = 0; i < count; i++)
3683 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3684 (((unsigned int) palent[i].peGreen) << 8) |
3685 ((unsigned int) palent[i].peBlue));
3688 /* *************************************
3689 32 bpp to 16 bpp
3690 ************************************* */
3691 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3692 unsigned short *c_src = (unsigned short *) src;
3693 unsigned int *c_dst = (unsigned int *) dst;
3694 int y;
3696 for (y = height; y--; ) {
3697 unsigned short * srclineend = c_src+width;
3698 while (c_src < srclineend ) {
3699 *c_dst++ = (((*c_src & 0xF800) << 8) |
3700 ((*c_src & 0x07E0) << 5) |
3701 ((*c_src & 0x001F) << 3));
3702 c_src++;
3704 c_src+=((pitch/2)-width);
3709 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3710 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3712 ICOM_THIS(IDirectDrawImpl,iface);
3713 char buf[200];
3714 WND *tmpWnd;
3715 int c;
3717 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3718 This, width, height, depth);
3720 switch ((c = _common_depth_to_pixelformat(depth,
3721 &(This->d.directdraw_pixelformat),
3722 &(This->d.screen_pixelformat),
3723 &(This->d.pixmap_depth)))) {
3724 case -2:
3725 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3726 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3727 return DDERR_UNSUPPORTEDMODE;
3729 case -1:
3730 /* No convertion */
3731 This->d.pixel_convert = NULL;
3732 This->d.palette_convert = NULL;
3733 break;
3735 default:
3736 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3738 /* Set the depth convertion routines */
3739 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
3740 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
3743 This->d.width = width;
3744 This->d.height = height;
3746 _common_IDirectDrawImpl_SetDisplayMode(This);
3748 tmpWnd = WIN_FindWndPtr(This->d.window);
3749 This->d.paintable = 1;
3750 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3751 WIN_ReleaseWndPtr(tmpWnd);
3753 /* We don't have a context for this window. Host off the desktop */
3754 if( !This->d.drawable )
3756 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3757 WIN_ReleaseDesktop();
3759 TRACE("Setting drawable to %ld\n", This->d.drawable);
3761 return DD_OK;
3764 #ifdef HAVE_LIBXXF86DGA
3765 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3766 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3768 ICOM_THIS(IDirectDraw2Impl,iface);
3769 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3770 if (!caps1 && !caps2)
3771 return DDERR_INVALIDPARAMS;
3772 if (caps1) {
3773 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3774 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3775 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3777 if (caps2) {
3778 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3779 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3780 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3782 return DD_OK;
3784 #endif /* defined(HAVE_LIBXXF86DGA) */
3786 static void fill_caps(LPDDCAPS caps) {
3787 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3788 Need to be fixed, though.. */
3789 if (caps == NULL)
3790 return;
3792 caps->dwSize = sizeof(*caps);
3793 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
3794 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3795 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3796 caps->dwFXCaps = 0;
3797 caps->dwFXAlphaCaps = 0;
3798 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3799 caps->dwSVCaps = 0;
3800 caps->dwZBufferBitDepths = DDBD_16;
3801 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3802 to put textures in video memory.
3803 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3804 for example) ? */
3805 caps->dwVidMemTotal = 8192 * 1024;
3806 caps->dwVidMemFree = 8192 * 1024;
3807 /* These are all the supported capabilities of the surfaces */
3808 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3809 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3810 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3811 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3812 #ifdef HAVE_MESAGL
3813 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3814 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3815 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3816 #endif
3819 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3820 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3822 ICOM_THIS(IDirectDraw2Impl,iface);
3823 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3825 /* Put the same caps for the two capabilities */
3826 fill_caps(caps1);
3827 fill_caps(caps2);
3829 return DD_OK;
3832 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3833 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3835 ICOM_THIS(IDirectDraw2Impl,iface);
3836 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3837 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
3838 This,x,ilpddclip,lpunk
3840 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3841 (*ilpddclip)->ref = 1;
3842 ICOM_VTBL(*ilpddclip) = &ddclipvt;
3843 return DD_OK;
3846 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3847 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3849 int size = 0;
3851 if (TRACE_ON(ddraw))
3852 _dump_paletteformat(dwFlags);
3854 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3855 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3856 (*lpddpal)->ref = 1;
3857 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3858 (*lpddpal)->installed = 0;
3860 if (dwFlags & DDPCAPS_1BIT)
3861 size = 2;
3862 else if (dwFlags & DDPCAPS_2BIT)
3863 size = 4;
3864 else if (dwFlags & DDPCAPS_4BIT)
3865 size = 16;
3866 else if (dwFlags & DDPCAPS_8BIT)
3867 size = 256;
3868 else
3869 ERR("unhandled palette format\n");
3870 *psize = size;
3872 if (palent)
3874 /* Now, if we are in 'depth conversion mode', create the screen palette */
3875 if (This->d.palette_convert != NULL)
3876 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3878 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3879 } else if (This->d.palette_convert != NULL) {
3880 /* In that case, put all 0xFF */
3881 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3884 return DD_OK;
3887 #ifdef HAVE_LIBXXF86DGA
3888 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3889 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3891 ICOM_THIS(IDirectDraw2Impl,iface);
3892 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3893 HRESULT res;
3894 int xsize = 0,i;
3896 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3897 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3898 if (res != 0) return res;
3899 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
3900 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
3901 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3902 } else {
3903 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
3904 (*ilpddpal)->cm = 0;
3906 if (((*ilpddpal)->cm)&&xsize) {
3907 for (i=0;i<xsize;i++) {
3908 XColor xc;
3910 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3911 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3912 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3913 xc.flags = DoRed|DoBlue|DoGreen;
3914 xc.pixel = i;
3915 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3918 return DD_OK;
3920 #endif /* defined(HAVE_LIBXXF86DGA) */
3922 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3923 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3925 ICOM_THIS(IDirectDraw2Impl,iface);
3926 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3927 int xsize;
3928 HRESULT res;
3930 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3931 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3932 if (res != 0) return res;
3933 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
3934 return DD_OK;
3937 #ifdef HAVE_LIBXXF86DGA
3938 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3939 ICOM_THIS(IDirectDraw2Impl,iface);
3940 TRACE("(%p)->()\n",This);
3941 Sleep(1000);
3942 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3943 #ifdef RESTORE_SIGNALS
3944 SIGNAL_Init();
3945 #endif
3946 return DD_OK;
3948 #endif /* defined(HAVE_LIBXXF86DGA) */
3950 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3951 ICOM_THIS(IDirectDraw2Impl,iface);
3952 TRACE("(%p)->RestoreDisplayMode()\n", This);
3953 Sleep(1000);
3954 return DD_OK;
3957 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3958 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3960 ICOM_THIS(IDirectDraw2Impl,iface);
3961 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3962 return DD_OK;
3965 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3966 ICOM_THIS(IDirectDraw2Impl,iface);
3967 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
3969 return ++(This->ref);
3972 #ifdef HAVE_LIBXXF86DGA
3973 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3974 ICOM_THIS(IDirectDraw2Impl,iface);
3975 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
3977 if (!--(This->ref)) {
3978 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3979 if (This->d.window && (This->d.mainWindow != This->d.window))
3980 DestroyWindow(This->d.window);
3981 #ifdef HAVE_LIBXXF86VM
3982 if (orig_mode) {
3983 TSXF86VidModeSwitchToMode(
3984 display,
3985 DefaultScreen(display),
3986 orig_mode);
3987 if (orig_mode->privsize)
3988 TSXFree(orig_mode->private);
3989 free(orig_mode);
3990 orig_mode = NULL;
3992 #endif
3994 #ifdef RESTORE_SIGNALS
3995 SIGNAL_Init();
3996 #endif
3997 HeapFree(GetProcessHeap(),0,This);
3998 return S_OK;
4000 return This->ref;
4002 #endif /* defined(HAVE_LIBXXF86DGA) */
4004 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4005 ICOM_THIS(IDirectDraw2Impl,iface);
4006 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4008 if (!--(This->ref)) {
4009 if (This->d.window && (This->d.mainWindow != This->d.window))
4010 DestroyWindow(This->d.window);
4011 HeapFree(GetProcessHeap(),0,This);
4012 return S_OK;
4014 /* FIXME: destroy window ... */
4015 return This->ref;
4018 #ifdef HAVE_LIBXXF86DGA
4019 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4020 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4022 ICOM_THIS(IDirectDraw2Impl,iface);
4023 char xrefiid[50];
4025 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4026 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4027 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4028 *obj = This;
4029 IDirectDraw2_AddRef(iface);
4031 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4033 return S_OK;
4035 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4036 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4037 IDirectDraw2_AddRef(iface);
4038 *obj = This;
4040 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4042 return S_OK;
4044 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4045 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4046 IDirectDraw2_AddRef(iface);
4047 *obj = This;
4049 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4051 return S_OK;
4053 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4054 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4055 IDirectDraw2_AddRef(iface);
4056 *obj = This;
4058 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4060 return S_OK;
4062 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4063 IDirect3DImpl* d3d;
4065 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4066 d3d->ref = 1;
4067 d3d->ddraw = (IDirectDrawImpl*)This;
4068 IDirectDraw2_AddRef(iface);
4069 ICOM_VTBL(d3d) = &d3dvt;
4070 *obj = d3d;
4072 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4074 return S_OK;
4076 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4077 IDirect3D2Impl* d3d;
4079 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4080 d3d->ref = 1;
4081 d3d->ddraw = (IDirectDrawImpl*)This;
4082 IDirectDraw2_AddRef(iface);
4083 ICOM_VTBL(d3d) = &d3d2vt;
4084 *obj = d3d;
4086 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4088 return S_OK;
4090 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4091 return OLE_E_ENUM_NOMORE;
4093 #endif /* defined(HAVE_LIBXXF86DGA) */
4095 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4096 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4098 ICOM_THIS(IDirectDraw2Impl,iface);
4099 char xrefiid[50];
4101 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4102 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4103 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4104 *obj = This;
4105 IDirectDraw2_AddRef(iface);
4107 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4109 return S_OK;
4111 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4112 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4113 IDirectDraw2_AddRef(iface);
4114 *obj = This;
4116 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4118 return S_OK;
4120 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4121 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4122 IDirectDraw2_AddRef(iface);
4123 *obj = This;
4125 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4127 return S_OK;
4129 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4130 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4131 IDirectDraw2_AddRef(iface);
4132 *obj = This;
4134 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4136 return S_OK;
4138 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4139 IDirect3DImpl* d3d;
4141 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4142 d3d->ref = 1;
4143 d3d->ddraw = (IDirectDrawImpl*)This;
4144 IDirectDraw2_AddRef(iface);
4145 ICOM_VTBL(d3d) = &d3dvt;
4146 *obj = d3d;
4148 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4150 return S_OK;
4152 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4153 IDirect3D2Impl* d3d;
4155 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4156 d3d->ref = 1;
4157 d3d->ddraw = (IDirectDrawImpl*)This;
4158 IDirectDraw2_AddRef(iface);
4159 ICOM_VTBL(d3d) = &d3d2vt;
4160 *obj = d3d;
4162 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4164 return S_OK;
4166 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4167 return OLE_E_ENUM_NOMORE;
4170 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4171 LPDIRECTDRAW2 iface,BOOL *status
4173 ICOM_THIS(IDirectDraw2Impl,iface);
4174 TRACE("(%p)->(%p)\n",This,status);
4175 *status = TRUE;
4176 return DD_OK;
4179 #ifdef HAVE_LIBXXF86DGA
4180 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4181 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4183 ICOM_THIS(IDirectDraw2Impl,iface);
4184 DDSURFACEDESC ddsfd;
4185 static struct {
4186 int w,h;
4187 } modes[5] = { /* some of the usual modes */
4188 {512,384},
4189 {640,400},
4190 {640,480},
4191 {800,600},
4192 {1024,768},
4194 static int depths[4] = {8,16,24,32};
4195 int i,j;
4197 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4198 ddsfd.dwSize = sizeof(ddsfd);
4199 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4200 if (dwFlags & DDEDM_REFRESHRATES) {
4201 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4202 ddsfd.u.dwRefreshRate = 60;
4205 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4206 ddsfd.dwBackBufferCount = 1;
4207 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4208 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4209 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4210 /* FIXME: those masks would have to be set in depth > 8 */
4211 if (depths[i]==8) {
4212 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4213 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4214 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4215 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4216 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4217 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4218 } else {
4219 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4221 /* FIXME: We should query those from X itself */
4222 switch (depths[i]) {
4223 case 16:
4224 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4225 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4226 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4227 break;
4228 case 24:
4229 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4230 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4231 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4232 break;
4233 case 32:
4234 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4235 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4236 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4237 break;
4241 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4242 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4243 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4244 if (!modescb(&ddsfd,context)) return DD_OK;
4246 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4247 ddsfd.dwWidth = modes[j].w;
4248 ddsfd.dwHeight = modes[j].h;
4249 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4250 if (!modescb(&ddsfd,context)) return DD_OK;
4253 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4254 /* modeX is not standard VGA */
4256 ddsfd.dwHeight = 200;
4257 ddsfd.dwWidth = 320;
4258 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4259 if (!modescb(&ddsfd,context)) return DD_OK;
4262 return DD_OK;
4264 #endif /* defined(HAVE_LIBXXF86DGA) */
4266 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4267 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4269 ICOM_THIS(IDirectDraw2Impl,iface);
4270 XVisualInfo *vi;
4271 XPixmapFormatValues *pf;
4272 XVisualInfo vt;
4273 int nvisuals, npixmap, i, emu;
4274 int has_mode[] = { 0, 0, 0, 0 };
4275 int has_depth[] = { 8, 15, 16, 24 };
4276 DDSURFACEDESC ddsfd;
4277 static struct {
4278 int w,h;
4279 } modes[] = { /* some of the usual modes */
4280 {512,384},
4281 {640,400},
4282 {640,480},
4283 {800,600},
4284 {1024,768},
4285 {1280,1024}
4287 DWORD maxWidth, maxHeight;
4289 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4290 ddsfd.dwSize = sizeof(ddsfd);
4291 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
4292 if (dwFlags & DDEDM_REFRESHRATES) {
4293 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4294 ddsfd.u.dwRefreshRate = 60;
4296 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4297 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4299 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4300 pf = XListPixmapFormats(display, &npixmap);
4302 i = 0;
4303 emu = 0;
4304 while ((i < npixmap) ||
4305 (emu != 4)) {
4306 int mode_index;
4307 int send_mode = 0;
4308 int j;
4310 if (i < npixmap) {
4311 for (j = 0; j < 4; j++) {
4312 if (has_depth[j] == pf[i].depth) {
4313 mode_index = j;
4314 break;
4317 if (j == 4) {
4318 i++;
4319 continue;
4323 if (has_mode[mode_index] == 0) {
4324 if (mode_index == 0) {
4325 send_mode = 1;
4327 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4328 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4329 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4330 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4331 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4332 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4333 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4334 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4335 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4337 has_mode[mode_index] = 1;
4338 } else {
4339 /* All the 'true color' depths (15, 16 and 24)
4340 First, find the corresponding visual to extract the bit masks */
4341 for (j = 0; j < nvisuals; j++) {
4342 if (vi[j].depth == pf[i].depth) {
4343 ddsfd.ddsCaps.dwCaps = 0;
4344 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4345 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4346 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4347 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4348 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4349 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4350 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4351 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4353 send_mode = 1;
4354 has_mode[mode_index] = 1;
4355 break;
4359 if (j == nvisuals)
4360 ERR("Did not find visual corresponding the the pixmap format !\n");
4364 i++;
4365 } else {
4366 /* Now to emulated modes */
4367 if (has_mode[emu] == 0) {
4368 int c;
4369 int l;
4370 int depth = has_depth[emu];
4372 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4373 if (ModeEmulations[c].dest.depth == depth) {
4374 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4375 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4376 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4377 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4378 int j;
4379 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4380 if ((vi[j].depth == pf[l].depth) &&
4381 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4382 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4383 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4384 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4385 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4386 if (depth == 8) {
4387 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4388 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4389 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4390 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4391 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4392 } else {
4393 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4394 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4395 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4396 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4397 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4399 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4400 send_mode = 1;
4403 if (send_mode == 0)
4404 ERR("No visual corresponding to pixmap format !\n");
4412 emu++;
4415 if (send_mode) {
4416 int mode;
4418 if (TRACE_ON(ddraw)) {
4419 TRACE("Enumerating with pixel format : \n");
4420 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4421 DPRINTF("\n");
4424 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4425 /* Do not enumerate modes we cannot handle anyway */
4426 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4427 break;
4429 ddsfd.dwWidth = modes[mode].w;
4430 ddsfd.dwHeight = modes[mode].h;
4432 /* Now, send the mode description to the application */
4433 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4434 if (!modescb(&ddsfd, context))
4435 goto exit_enum;
4438 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4439 /* modeX is not standard VGA */
4440 ddsfd.dwWidth = 320;
4441 ddsfd.dwHeight = 200;
4442 if (!modescb(&ddsfd, context))
4443 goto exit_enum;
4448 exit_enum:
4449 TSXFree(vi);
4450 TSXFree(pf);
4452 return DD_OK;
4455 #ifdef HAVE_LIBXXF86DGA
4456 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4457 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4459 ICOM_THIS(IDirectDraw2Impl,iface);
4460 TRACE("(%p)->(%p)\n",This,lpddsfd);
4461 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4462 lpddsfd->dwHeight = This->d.height;
4463 lpddsfd->dwWidth = This->d.width;
4464 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4465 lpddsfd->dwBackBufferCount = 1;
4466 lpddsfd->u.dwRefreshRate = 60;
4467 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4468 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4469 return DD_OK;
4471 #endif /* defined(HAVE_LIBXXF86DGA) */
4473 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4474 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4476 ICOM_THIS(IDirectDraw2Impl,iface);
4477 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4478 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4479 lpddsfd->dwHeight = This->d.height;
4480 lpddsfd->dwWidth = This->d.width;
4481 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4482 lpddsfd->dwBackBufferCount = 1;
4483 lpddsfd->u.dwRefreshRate = 60;
4484 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4485 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4486 return DD_OK;
4489 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4490 ICOM_THIS(IDirectDraw2Impl,iface);
4491 TRACE("(%p)->()\n",This);
4492 return DD_OK;
4495 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4496 LPDIRECTDRAW2 iface,LPDWORD freq
4498 ICOM_THIS(IDirectDraw2Impl,iface);
4499 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4500 *freq = 60*100; /* 60 Hz */
4501 return DD_OK;
4504 /* what can we directly decompress? */
4505 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4506 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4508 ICOM_THIS(IDirectDraw2Impl,iface);
4509 FIXME("(%p,%p,%p), stub\n",This,x,y);
4510 return DD_OK;
4513 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4514 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4516 ICOM_THIS(IDirectDraw2Impl,iface);
4517 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4518 return DD_OK;
4521 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4522 LPDIRECTDRAW2 iface )
4524 ICOM_THIS(IDirectDraw2Impl,iface);
4525 FIXME("(%p)->()\n", This );
4527 return DD_OK;
4530 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4531 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4532 ICOM_THIS(IDirectDraw2Impl,iface);
4533 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4535 return DD_OK;
4538 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4539 LPDWORD lpdwScanLine) {
4540 ICOM_THIS(IDirectDraw2Impl,iface);
4541 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4543 return DD_OK;
4546 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4547 GUID *lpGUID) {
4548 ICOM_THIS(IDirectDraw2Impl,iface);
4549 FIXME("(%p)->(%p)\n", This, lpGUID);
4551 return DD_OK;
4554 #ifdef HAVE_LIBXXF86DGA
4556 /* Note: Hack so we can reuse the old functions without compiler warnings */
4557 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4558 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4559 #else
4560 # define XCAST(fun) (void *)
4561 #endif
4563 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4565 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4566 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4567 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4568 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4569 XCAST(Compact)IDirectDraw2Impl_Compact,
4570 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4571 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4572 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4573 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4574 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4575 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4576 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4577 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4578 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4579 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4580 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4581 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4582 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4583 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4584 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4585 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4586 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4587 DGA_IDirectDrawImpl_SetDisplayMode,
4588 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4591 #undef XCAST
4593 #endif /* defined(HAVE_LIBXXF86DGA) */
4595 /* Note: Hack so we can reuse the old functions without compiler warnings */
4596 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4597 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
4598 #else
4599 # define XCAST(fun) (void *)
4600 #endif
4602 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
4604 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4605 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4606 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4607 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4608 XCAST(Compact)IDirectDraw2Impl_Compact,
4609 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4610 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4611 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4612 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4613 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4614 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4615 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4616 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4617 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4618 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4619 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4620 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4621 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4622 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4623 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4624 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4625 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4626 Xlib_IDirectDrawImpl_SetDisplayMode,
4627 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4630 #undef XCAST
4632 /*****************************************************************************
4633 * IDirectDraw2
4638 #ifdef HAVE_LIBXXF86DGA
4639 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4640 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4642 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4644 #endif /* defined(HAVE_LIBXXF86DGA) */
4646 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4647 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4649 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4652 #ifdef HAVE_LIBXXF86DGA
4653 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4654 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4656 ICOM_THIS(IDirectDraw2Impl,iface);
4657 TRACE("(%p)->(%p,%p,%p)\n",
4658 This,ddscaps,total,free
4660 if (total) *total = This->e.dga.fb_memsize * 1024;
4661 if (free) *free = This->e.dga.fb_memsize * 1024;
4662 return DD_OK;
4664 #endif /* defined(HAVE_LIBXXF86DGA) */
4666 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4667 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4669 ICOM_THIS(IDirectDraw2Impl,iface);
4670 TRACE("(%p)->(%p,%p,%p)\n",
4671 This,ddscaps,total,free
4673 if (total) *total = 2048 * 1024;
4674 if (free) *free = 2048 * 1024;
4675 return DD_OK;
4678 #ifdef HAVE_LIBXXF86DGA
4679 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
4681 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4682 DGA_IDirectDraw2Impl_QueryInterface,
4683 IDirectDraw2Impl_AddRef,
4684 DGA_IDirectDraw2Impl_Release,
4685 IDirectDraw2Impl_Compact,
4686 IDirectDraw2Impl_CreateClipper,
4687 DGA_IDirectDraw2Impl_CreatePalette,
4688 DGA_IDirectDraw2Impl_CreateSurface,
4689 IDirectDraw2Impl_DuplicateSurface,
4690 DGA_IDirectDraw2Impl_EnumDisplayModes,
4691 IDirectDraw2Impl_EnumSurfaces,
4692 IDirectDraw2Impl_FlipToGDISurface,
4693 DGA_IDirectDraw2Impl_GetCaps,
4694 DGA_IDirectDraw2Impl_GetDisplayMode,
4695 IDirectDraw2Impl_GetFourCCCodes,
4696 IDirectDraw2Impl_GetGDISurface,
4697 IDirectDraw2Impl_GetMonitorFrequency,
4698 IDirectDraw2Impl_GetScanLine,
4699 IDirectDraw2Impl_GetVerticalBlankStatus,
4700 IDirectDraw2Impl_Initialize,
4701 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4702 IDirectDraw2Impl_SetCooperativeLevel,
4703 DGA_IDirectDraw2Impl_SetDisplayMode,
4704 IDirectDraw2Impl_WaitForVerticalBlank,
4705 DGA_IDirectDraw2Impl_GetAvailableVidMem
4707 #endif /* defined(HAVE_LIBXXF86DGA) */
4709 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
4711 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4712 Xlib_IDirectDraw2Impl_QueryInterface,
4713 IDirectDraw2Impl_AddRef,
4714 Xlib_IDirectDraw2Impl_Release,
4715 IDirectDraw2Impl_Compact,
4716 IDirectDraw2Impl_CreateClipper,
4717 Xlib_IDirectDraw2Impl_CreatePalette,
4718 Xlib_IDirectDraw2Impl_CreateSurface,
4719 IDirectDraw2Impl_DuplicateSurface,
4720 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4721 IDirectDraw2Impl_EnumSurfaces,
4722 IDirectDraw2Impl_FlipToGDISurface,
4723 Xlib_IDirectDraw2Impl_GetCaps,
4724 Xlib_IDirectDraw2Impl_GetDisplayMode,
4725 IDirectDraw2Impl_GetFourCCCodes,
4726 IDirectDraw2Impl_GetGDISurface,
4727 IDirectDraw2Impl_GetMonitorFrequency,
4728 IDirectDraw2Impl_GetScanLine,
4729 IDirectDraw2Impl_GetVerticalBlankStatus,
4730 IDirectDraw2Impl_Initialize,
4731 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4732 IDirectDraw2Impl_SetCooperativeLevel,
4733 Xlib_IDirectDraw2Impl_SetDisplayMode,
4734 IDirectDraw2Impl_WaitForVerticalBlank,
4735 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4738 /*****************************************************************************
4739 * IDirectDraw4
4743 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4744 HDC hdc,
4745 LPDIRECTDRAWSURFACE *lpDDS) {
4746 ICOM_THIS(IDirectDraw4Impl,iface);
4747 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4749 return DD_OK;
4752 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4753 ICOM_THIS(IDirectDraw4Impl,iface);
4754 FIXME("(%p)->()\n", This);
4756 return DD_OK;
4759 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4760 ICOM_THIS(IDirectDraw4Impl,iface);
4761 FIXME("(%p)->()\n", This);
4763 return DD_OK;
4766 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4767 LPDDDEVICEIDENTIFIER lpdddi,
4768 DWORD dwFlags) {
4769 ICOM_THIS(IDirectDraw4Impl,iface);
4770 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4772 return DD_OK;
4775 #ifdef HAVE_LIBXXF86DGA
4777 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4778 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4779 #else
4780 # define XCAST(fun) (void*)
4781 #endif
4783 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
4785 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4786 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4787 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4788 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4789 XCAST(Compact)IDirectDraw2Impl_Compact,
4790 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4791 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4792 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4793 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4794 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4795 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4796 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4797 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4798 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4799 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4800 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4801 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4802 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4803 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4804 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4805 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4806 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4807 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4808 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4809 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4810 IDirectDraw4Impl_GetSurfaceFromDC,
4811 IDirectDraw4Impl_RestoreAllSurfaces,
4812 IDirectDraw4Impl_TestCooperativeLevel,
4813 IDirectDraw4Impl_GetDeviceIdentifier
4816 #undef XCAST
4818 #endif /* defined(HAVE_LIBXXF86DGA) */
4820 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4821 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
4822 #else
4823 # define XCAST(fun) (void*)
4824 #endif
4826 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
4828 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4829 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4830 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4831 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4832 XCAST(Compact)IDirectDraw2Impl_Compact,
4833 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4834 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4835 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4836 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4837 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4838 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4839 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4840 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4841 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4842 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4843 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4844 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4845 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4846 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4847 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4848 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4849 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4850 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4851 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4852 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4853 IDirectDraw4Impl_GetSurfaceFromDC,
4854 IDirectDraw4Impl_RestoreAllSurfaces,
4855 IDirectDraw4Impl_TestCooperativeLevel,
4856 IDirectDraw4Impl_GetDeviceIdentifier
4859 #undef XCAST
4861 /******************************************************************************
4862 * DirectDrawCreate
4865 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4867 LRESULT ret;
4868 IDirectDrawImpl* ddraw = NULL;
4869 DWORD lastError;
4871 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4873 SetLastError( ERROR_SUCCESS );
4874 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4875 if( (!ddraw) &&
4876 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4879 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4882 if( ddraw )
4884 /* Perform any special direct draw functions */
4885 if (msg==WM_PAINT)
4886 ddraw->d.paintable = 1;
4888 /* Now let the application deal with the rest of this */
4889 if( ddraw->d.mainWindow )
4892 /* Don't think that we actually need to call this but...
4893 might as well be on the safe side of things... */
4895 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4896 it should be the procedures of our fake window that gets called
4897 instead of those of the window provided by the application.
4898 And with this patch, mouse clicks work with Monkey Island III
4899 - Lionel */
4900 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4902 if( !ret )
4904 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4905 /* We didn't handle the message - give it to the application */
4906 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4908 ret = CallWindowProcA(tmpWnd->winproc,
4909 ddraw->d.mainWindow, msg, wParam, lParam );
4911 WIN_ReleaseWndPtr(tmpWnd);
4915 } else {
4916 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4920 else
4922 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4925 return ret;
4928 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4929 #ifdef HAVE_LIBXXF86DGA
4930 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4931 int memsize,banksize,width,major,minor,flags,height;
4932 char *addr;
4933 int fd;
4934 int depth;
4936 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4937 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4938 close(fd);
4940 if (fd == -1) {
4941 MESSAGE("Must be able to access /dev/mem to use XF86DGA!\n");
4942 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4943 return E_UNEXPECTED;
4945 if (!DDRAW_DGA_Available()) {
4946 TRACE("No XF86DGA detected.\n");
4947 return DDERR_GENERIC;
4949 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4950 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
4951 (*ilplpDD)->ref = 1;
4952 TSXF86DGAQueryVersion(display,&major,&minor);
4953 TRACE("XF86DGA is version %d.%d\n",major,minor);
4954 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4955 if (!(flags & XF86DGADirectPresent))
4956 MESSAGE("direct video is NOT PRESENT.\n");
4957 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4958 (*ilplpDD)->e.dga.fb_width = width;
4959 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4960 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4961 (*ilplpDD)->e.dga.fb_height = height;
4962 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4963 addr,width,banksize,memsize
4965 TRACE("viewport height: %d\n",height);
4967 /* Get the screen dimensions as seen by Wine.
4968 In that case, it may be better to ignore the -desktop mode and return the
4969 real screen size => print a warning */
4970 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4971 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4972 if (((*ilplpDD)->d.height != height) ||
4973 ((*ilplpDD)->d.width != width))
4974 WARN("You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
4975 (*ilplpDD)->e.dga.fb_addr = addr;
4976 (*ilplpDD)->e.dga.fb_memsize = memsize;
4977 (*ilplpDD)->e.dga.fb_banksize = banksize;
4978 (*ilplpDD)->e.dga.vpmask = 0;
4980 /* just assume the default depth is the DGA depth too */
4981 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4982 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4983 #ifdef RESTORE_SIGNALS
4984 SIGNAL_Init();
4985 #endif
4987 return DD_OK;
4988 #else /* defined(HAVE_LIBXXF86DGA) */
4989 return DDERR_INVALIDDIRECTDRAWGUID;
4990 #endif /* defined(HAVE_LIBXXF86DGA) */
4993 static BOOL
4994 DDRAW_XSHM_Available(void)
4996 #ifdef HAVE_LIBXXSHM
4997 if (TSXShmQueryExtension(display))
4999 int major, minor;
5000 Bool shpix;
5002 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5003 (Options.noXSHM != 1))
5004 return 1;
5005 else
5006 return 0;
5008 else
5009 return 0;
5010 #else
5011 return 0;
5012 #endif
5015 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5016 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5017 int depth;
5019 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5020 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5021 (*ilplpDD)->ref = 1;
5022 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5024 /* At DirectDraw creation, the depth is the default depth */
5025 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5026 _common_depth_to_pixelformat(depth,
5027 &((*ilplpDD)->d.directdraw_pixelformat),
5028 &((*ilplpDD)->d.screen_pixelformat),
5029 &((*ilplpDD)->d.pixmap_depth));
5030 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5031 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5033 #ifdef HAVE_LIBXXSHM
5034 /* Test if XShm is available. */
5035 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5036 (*ilplpDD)->e.xlib.xshm_compl = 0;
5037 TRACE("Using XShm extension.\n");
5039 #endif
5041 return DD_OK;
5044 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5045 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5046 char xclsid[50];
5047 WNDCLASSA wc;
5048 /* WND* pParentWindow; */
5049 HRESULT ret;
5051 if (HIWORD(lpGUID))
5052 WINE_StringFromCLSID(lpGUID,xclsid);
5053 else {
5054 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
5055 lpGUID = NULL;
5058 TRACE("(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
5060 if ( ( !lpGUID ) ||
5061 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5062 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5063 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5064 /* if they didn't request a particular interface, use the best
5065 * supported one */
5066 if (DDRAW_DGA_Available())
5067 lpGUID = &DGA_DirectDraw_GUID;
5068 else
5069 lpGUID = &XLIB_DirectDraw_GUID;
5072 wc.style = CS_GLOBALCLASS;
5073 wc.lpfnWndProc = Xlib_DDWndProc;
5074 wc.cbClsExtra = 0;
5075 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
5076 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
5078 /* We can be a child of the desktop since we're really important */
5080 This code is not useful since hInstance is forced to 0 afterward
5081 pParentWindow = WIN_GetDesktop();
5082 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5084 wc.hInstance = 0;
5087 wc.hIcon = 0;
5088 wc.hCursor = (HCURSOR)IDC_ARROWA;
5089 wc.hbrBackground= NULL_BRUSH;
5090 wc.lpszMenuName = 0;
5091 wc.lpszClassName= "WINE_DirectDraw";
5092 RegisterClassA(&wc);
5094 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5095 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5097 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5098 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5100 else {
5101 goto err;
5105 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5106 return ret;
5108 err:
5109 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
5110 return DDERR_INVALIDDIRECTDRAWGUID;
5113 /*******************************************************************************
5114 * DirectDraw ClassFactory
5116 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5119 typedef struct
5121 /* IUnknown fields */
5122 ICOM_VFIELD(IClassFactory);
5123 DWORD ref;
5124 } IClassFactoryImpl;
5126 static HRESULT WINAPI
5127 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5128 ICOM_THIS(IClassFactoryImpl,iface);
5129 char buf[80];
5131 if (HIWORD(riid))
5132 WINE_StringFromCLSID(riid,buf);
5133 else
5134 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5135 FIXME("(%p)->(%s,%p),stub!\n",This,buf,ppobj);
5136 return E_NOINTERFACE;
5139 static ULONG WINAPI
5140 DDCF_AddRef(LPCLASSFACTORY iface) {
5141 ICOM_THIS(IClassFactoryImpl,iface);
5142 return ++(This->ref);
5145 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5146 ICOM_THIS(IClassFactoryImpl,iface);
5147 /* static class, won't be freed */
5148 return --(This->ref);
5151 static HRESULT WINAPI DDCF_CreateInstance(
5152 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5154 ICOM_THIS(IClassFactoryImpl,iface);
5155 char buf[80];
5157 WINE_StringFromCLSID(riid,buf);
5158 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
5159 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5160 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5161 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5162 /* FIXME: reuse already created DirectDraw if present? */
5163 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5165 return CLASS_E_CLASSNOTAVAILABLE;
5168 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5169 ICOM_THIS(IClassFactoryImpl,iface);
5170 FIXME("(%p)->(%d),stub!\n",This,dolock);
5171 return S_OK;
5174 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5176 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5177 DDCF_QueryInterface,
5178 DDCF_AddRef,
5179 DDCF_Release,
5180 DDCF_CreateInstance,
5181 DDCF_LockServer
5183 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5185 /*******************************************************************************
5186 * DllGetClassObject [DDRAW.13]
5187 * Retrieves class object from a DLL object
5189 * NOTES
5190 * Docs say returns STDAPI
5192 * PARAMS
5193 * rclsid [I] CLSID for the class object
5194 * riid [I] Reference to identifier of interface for class object
5195 * ppv [O] Address of variable to receive interface pointer for riid
5197 * RETURNS
5198 * Success: S_OK
5199 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5200 * E_UNEXPECTED
5202 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5204 char buf[80],xbuf[80];
5206 if (HIWORD(rclsid))
5207 WINE_StringFromCLSID(rclsid,xbuf);
5208 else
5209 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
5210 if (HIWORD(riid))
5211 WINE_StringFromCLSID(riid,buf);
5212 else
5213 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5214 WINE_StringFromCLSID(riid,xbuf);
5215 TRACE("(%p,%p,%p)\n", xbuf, buf, ppv);
5216 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5217 *ppv = (LPVOID)&DDRAW_CF;
5218 IClassFactory_AddRef((IClassFactory*)*ppv);
5219 return S_OK;
5221 FIXME("(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
5222 return CLASS_E_CLASSNOTAVAILABLE;
5226 /*******************************************************************************
5227 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5229 * RETURNS
5230 * Success: S_OK
5231 * Failure: S_FALSE
5233 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5235 FIXME("(void): stub\n");
5236 return S_FALSE;
5239 #else /* !defined(X_DISPLAY_MISSING) */
5241 #include "windef.h"
5242 #include "winerror.h"
5243 #include "wtypes.h"
5245 #define DD_OK 0
5247 typedef void *LPUNKNOWN;
5248 typedef void *LPDIRECTDRAW;
5249 typedef void *LPDIRECTDRAWCLIPPER;
5250 typedef void *LPDDENUMCALLBACKA;
5251 typedef void *LPDDENUMCALLBACKEXA;
5252 typedef void *LPDDENUMCALLBACKEXW;
5253 typedef void *LPDDENUMCALLBACKW;
5255 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5257 return DD_OK;
5260 HRESULT WINAPI DirectDrawCreate(
5261 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5263 return DD_OK;
5266 HRESULT WINAPI DirectDrawCreateClipper(
5267 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5269 return DD_OK;
5272 HRESULT WINAPI DirectDrawEnumerateA(
5273 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5275 return DD_OK;
5278 HRESULT WINAPI DirectDrawEnumerateExA(
5279 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5281 return DD_OK;
5284 HRESULT WINAPI DirectDrawEnumerateExW(
5285 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5287 return DD_OK;
5290 HRESULT WINAPI DirectDrawEnumerateW(
5291 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5293 return DD_OK;
5296 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5298 return CLASS_E_CLASSNOTAVAILABLE;
5301 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5303 return DD_OK;
5306 #endif /* !defined(X_DISPLAY_MISSING) */