Fixed unconditional use of JOYDEV.
[wine/testsucceed.git] / graphics / ddraw.c
blob265e4d7b2126f2a3b0907e0240c7452057eb81f2
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"
18 #include "winerror.h"
20 #ifndef X_DISPLAY_MISSING
22 #include "ts_xlib.h"
23 #include "ts_xutil.h"
25 #ifdef HAVE_LIBXXSHM
26 # include <sys/types.h>
27 # ifdef HAVE_SYS_IPC_H
28 # include <sys/ipc.h>
29 # endif
30 # ifdef HAVE_SYS_SHM_H
31 # include <sys/shm.h>
32 # endif
33 # include "ts_xshm.h"
34 #endif /* defined(HAVE_LIBXXSHM) */
36 #ifdef HAVE_LIBXXF86DGA
37 #include "ts_xf86dga.h"
38 #endif /* defined(HAVE_LIBXXF86DGA) */
40 #ifdef HAVE_LIBXXF86DGA2
41 #include "ts_xf86dga2.h"
42 #endif /* defined(HAVE_LIBXXF86DGA2) */
44 #ifdef HAVE_LIBXXF86VM
45 #include "ts_xf86vmode.h"
46 #endif /* defined(HAVE_LIBXXF86VM) */
48 #include "x11drv.h"
50 #include <unistd.h>
51 #include <assert.h>
52 #ifdef HAVE_SYS_SIGNAL_H
53 # include <sys/signal.h>
54 #endif
55 #include <fcntl.h>
56 #include <string.h>
57 #include <stdlib.h>
59 #include "gdi.h"
60 #include "heap.h"
61 #include "dc.h"
62 #include "win.h"
63 #include "wine/exception.h"
64 #include "ddraw.h"
65 #include "d3d.h"
66 #include "debugtools.h"
67 #include "spy.h"
68 #include "message.h"
69 #include "options.h"
70 #include "monitor.h"
72 static char *ddProp = "WINE_DDRAW_Property";
74 /* This for all the enumeration and creation of D3D-related objects */
75 #include "ddraw_private.h"
76 #include "d3d_private.h"
78 DEFAULT_DEBUG_CHANNEL(ddraw)
80 /* Restore signal handlers overwritten by XF86DGA
82 #define RESTORE_SIGNALS
84 /* Get DDSCAPS of surface (shortcutmacro) */
85 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
87 /* Get the number of bytes per pixel for a given surface */
88 #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
90 #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
92 /* Where do these GUIDs come from? mkuuid.
93 * They exist solely to distinguish between the targets Wine support,
94 * and should be different than any other GUIDs in existence.
96 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
97 0xe2dcb020,
98 0xdc60,
99 0x11d1,
100 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
103 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
104 0x1574a740,
105 0xdc61,
106 0x11d1,
107 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
110 #ifdef HAVE_LIBXXF86DGA
111 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt;
112 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt;
113 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt;
114 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt;
115 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt;
116 #endif /* defined(HAVE_LIBXXF86DGA) */
118 #ifdef HAVE_LIBXXF86DGA2
119 static struct ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt;
120 #endif /* defined(HAVE_LIBXXF86DGA2) */
122 static struct ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt;
123 static struct ICOM_VTABLE(IDirectDraw) xlib_ddvt;
124 static struct ICOM_VTABLE(IDirectDraw2) xlib_dd2vt;
125 static struct ICOM_VTABLE(IDirectDraw4) xlib_dd4vt;
126 static struct ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt;
128 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
129 static struct ICOM_VTABLE(IDirect3D) d3dvt;
130 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
132 /* This is for mode-emulation */
134 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
135 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
136 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
137 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
138 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
139 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
140 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
142 typedef struct {
143 unsigned short bpp;
144 unsigned short depth;
145 unsigned int rmask;
146 unsigned int gmask;
147 unsigned int bmask;
148 } ConvertMode;
150 typedef struct {
151 void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
152 void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
153 } ConvertFuncs;
155 typedef struct {
156 ConvertMode screen, dest;
157 ConvertFuncs funcs;
158 } Convert;
160 static Convert ModeEmulations[] = {
161 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
162 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
163 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
164 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
165 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
168 #ifdef HAVE_LIBXXF86VM
169 static XF86VidModeModeInfo *orig_mode = NULL;
170 #endif
172 #ifdef HAVE_LIBXXSHM
173 static int XShmErrorFlag = 0;
174 #endif
176 static BYTE
177 DDRAW_DGA_Available(void)
179 #ifdef HAVE_LIBXXF86DGA
180 int fd, evbase, evret, majver, minver;
181 static BYTE return_value = 0xFF;
183 /* This prevents from probing X times for DGA */
184 if (return_value != 0xFF)
185 return return_value;
187 if (Options.noDGA) {
188 return_value = 0;
189 return 0;
192 /* First, query the extenstion and its version */
193 if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) {
194 return_value = 0;
195 return 0;
198 if (!TSXF86DGAQueryVersion(display,&majver,&minver)) {
199 return_value = 0;
200 return 0;
203 #ifdef HAVE_LIBXXF86DGA2
204 if (majver >= 2) {
205 /* We have DGA 2.0 available ! */
206 if (TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
207 TSXDGACloseFramebuffer(display, DefaultScreen(display));
208 return_value = 2;
209 } else {
210 return_value = 0;
213 return return_value;
214 } else {
215 #endif /* defined(HAVE_LIBXXF86DGA2) */
217 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
218 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
219 /* others. --stephenc */
220 if ((fd = open("/dev/mem", O_RDWR)) != -1)
221 close(fd);
223 if (fd != -1)
224 return_value = 1;
225 else
226 return_value = 0;
228 return return_value;
229 #ifdef HAVE_LIBXXF86DGA2
231 #endif /* defined(HAVE_LIBXXF86DGA2) */
232 #else /* defined(HAVE_LIBXXF86DGA) */
233 return 0;
234 #endif /* defined(HAVE_LIBXXF86DGA) */
237 /**********************************************************************/
239 typedef struct {
240 LPVOID lpCallback;
241 LPVOID lpContext;
242 } DirectDrawEnumerateProcData;
244 /***********************************************************************
245 * DirectDrawEnumerateExA (DDRAW.*)
247 HRESULT WINAPI DirectDrawEnumerateExA(
248 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
250 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
252 if (TRACE_ON(ddraw)) {
253 DPRINTF(" Flags : ");
254 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
255 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
256 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
257 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
258 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
259 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
260 DPRINTF("\n");
263 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
264 /* For the moment, Wine does not support any 3D only accelerators */
265 return DD_OK;
267 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
268 /* For the moment, Wine does not support any attached secondary devices */
269 return DD_OK;
272 if (DDRAW_DGA_Available()) {
273 TRACE("Enumerating DGA interface\n");
274 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
275 return DD_OK;
278 TRACE("Enumerating Xlib interface\n");
279 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
280 return DD_OK;
282 TRACE("Enumerating Default interface\n");
283 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
284 return DD_OK;
286 return DD_OK;
289 /***********************************************************************
290 * DirectDrawEnumerateExW (DDRAW.*)
293 static BOOL CALLBACK DirectDrawEnumerateExProcW(
294 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
295 LPVOID lpContext, HMONITOR hm)
297 DirectDrawEnumerateProcData *pEPD =
298 (DirectDrawEnumerateProcData *) lpContext;
299 LPWSTR lpDriverDescriptionW =
300 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
301 LPWSTR lpDriverNameW =
302 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
304 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
305 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
307 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
308 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
310 return bResult;
313 /**********************************************************************/
315 HRESULT WINAPI DirectDrawEnumerateExW(
316 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
318 DirectDrawEnumerateProcData epd;
319 epd.lpCallback = (LPVOID) lpCallback;
320 epd.lpContext = lpContext;
322 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
323 (LPVOID) &epd, 0);
326 /***********************************************************************
327 * DirectDrawEnumerateA (DDRAW.*)
330 static BOOL CALLBACK DirectDrawEnumerateProcA(
331 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
332 LPVOID lpContext, HMONITOR hm)
334 DirectDrawEnumerateProcData *pEPD =
335 (DirectDrawEnumerateProcData *) lpContext;
337 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
338 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
341 /**********************************************************************/
343 HRESULT WINAPI DirectDrawEnumerateA(
344 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
346 DirectDrawEnumerateProcData epd;
347 epd.lpCallback = (LPVOID) lpCallback;
348 epd.lpContext = lpContext;
350 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
351 (LPVOID) &epd, 0);
354 /***********************************************************************
355 * DirectDrawEnumerateW (DDRAW.*)
358 static BOOL WINAPI DirectDrawEnumerateProcW(
359 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
360 LPVOID lpContext, HMONITOR hm)
362 DirectDrawEnumerateProcData *pEPD =
363 (DirectDrawEnumerateProcData *) lpContext;
365 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
366 lpGUID, lpDriverDescription, lpDriverName,
367 pEPD->lpContext);
370 /**********************************************************************/
372 HRESULT WINAPI DirectDrawEnumerateW(
373 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
375 DirectDrawEnumerateProcData epd;
376 epd.lpCallback = (LPVOID) lpCallback;
377 epd.lpContext = lpContext;
379 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
380 (LPVOID) &epd, 0);
383 /***********************************************************************
384 * DSoundHelp (DDRAW.?)
387 /* What is this doing here? */
388 HRESULT WINAPI
389 DSoundHelp(DWORD x,DWORD y,DWORD z) {
390 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
391 return 0;
394 /******************************************************************************
395 * internal helper functions
397 static void _dump_DDBLTFX(DWORD flagmask) {
398 int i;
399 const struct {
400 DWORD mask;
401 char *name;
402 } flags[] = {
403 #define FE(x) { x, #x},
404 FE(DDBLTFX_ARITHSTRETCHY)
405 FE(DDBLTFX_MIRRORLEFTRIGHT)
406 FE(DDBLTFX_MIRRORUPDOWN)
407 FE(DDBLTFX_NOTEARING)
408 FE(DDBLTFX_ROTATE180)
409 FE(DDBLTFX_ROTATE270)
410 FE(DDBLTFX_ROTATE90)
411 FE(DDBLTFX_ZBUFFERRANGE)
412 FE(DDBLTFX_ZBUFFERBASEDEST)
413 #undef FE
415 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
416 if (flags[i].mask & flagmask) {
417 DPRINTF("%s ",flags[i].name);
420 DPRINTF("\n");
424 static void _dump_DDBLTFAST(DWORD flagmask) {
425 int i;
426 const struct {
427 DWORD mask;
428 char *name;
429 } flags[] = {
430 #define FE(x) { x, #x},
431 FE(DDBLTFAST_NOCOLORKEY)
432 FE(DDBLTFAST_SRCCOLORKEY)
433 FE(DDBLTFAST_DESTCOLORKEY)
434 FE(DDBLTFAST_WAIT)
435 #undef FE
437 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
438 if (flags[i].mask & flagmask)
439 DPRINTF("%s ",flags[i].name);
440 DPRINTF("\n");
443 static void _dump_DDBLT(DWORD flagmask) {
444 int i;
445 const struct {
446 DWORD mask;
447 char *name;
448 } flags[] = {
449 #define FE(x) { x, #x},
450 FE(DDBLT_ALPHADEST)
451 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
452 FE(DDBLT_ALPHADESTNEG)
453 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
454 FE(DDBLT_ALPHAEDGEBLEND)
455 FE(DDBLT_ALPHASRC)
456 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
457 FE(DDBLT_ALPHASRCNEG)
458 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
459 FE(DDBLT_ASYNC)
460 FE(DDBLT_COLORFILL)
461 FE(DDBLT_DDFX)
462 FE(DDBLT_DDROPS)
463 FE(DDBLT_KEYDEST)
464 FE(DDBLT_KEYDESTOVERRIDE)
465 FE(DDBLT_KEYSRC)
466 FE(DDBLT_KEYSRCOVERRIDE)
467 FE(DDBLT_ROP)
468 FE(DDBLT_ROTATIONANGLE)
469 FE(DDBLT_ZBUFFER)
470 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
471 FE(DDBLT_ZBUFFERDESTOVERRIDE)
472 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
473 FE(DDBLT_ZBUFFERSRCOVERRIDE)
474 FE(DDBLT_WAIT)
475 FE(DDBLT_DEPTHFILL)
476 #undef FE
478 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
479 if (flags[i].mask & flagmask)
480 DPRINTF("%s ",flags[i].name);
481 DPRINTF("\n");
484 static void _dump_DDSCAPS(void *in) {
485 int i;
486 const struct {
487 DWORD mask;
488 char *name;
489 } flags[] = {
490 #define FE(x) { x, #x},
491 FE(DDSCAPS_RESERVED1)
492 FE(DDSCAPS_ALPHA)
493 FE(DDSCAPS_BACKBUFFER)
494 FE(DDSCAPS_COMPLEX)
495 FE(DDSCAPS_FLIP)
496 FE(DDSCAPS_FRONTBUFFER)
497 FE(DDSCAPS_OFFSCREENPLAIN)
498 FE(DDSCAPS_OVERLAY)
499 FE(DDSCAPS_PALETTE)
500 FE(DDSCAPS_PRIMARYSURFACE)
501 FE(DDSCAPS_PRIMARYSURFACELEFT)
502 FE(DDSCAPS_SYSTEMMEMORY)
503 FE(DDSCAPS_TEXTURE)
504 FE(DDSCAPS_3DDEVICE)
505 FE(DDSCAPS_VIDEOMEMORY)
506 FE(DDSCAPS_VISIBLE)
507 FE(DDSCAPS_WRITEONLY)
508 FE(DDSCAPS_ZBUFFER)
509 FE(DDSCAPS_OWNDC)
510 FE(DDSCAPS_LIVEVIDEO)
511 FE(DDSCAPS_HWCODEC)
512 FE(DDSCAPS_MODEX)
513 FE(DDSCAPS_MIPMAP)
514 FE(DDSCAPS_RESERVED2)
515 FE(DDSCAPS_ALLOCONLOAD)
516 FE(DDSCAPS_VIDEOPORT)
517 FE(DDSCAPS_LOCALVIDMEM)
518 FE(DDSCAPS_NONLOCALVIDMEM)
519 FE(DDSCAPS_STANDARDVGAMODE)
520 FE(DDSCAPS_OPTIMIZED)
521 #undef FE
523 DWORD flagmask = *((DWORD *) in);
524 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
525 if (flags[i].mask & flagmask)
526 DPRINTF("%s ",flags[i].name);
529 static void _dump_pixelformat_flag(DWORD flagmask) {
530 int i;
531 const struct {
532 DWORD mask;
533 char *name;
534 } flags[] = {
535 #define FE(x) { x, #x},
536 FE(DDPF_ALPHAPIXELS)
537 FE(DDPF_ALPHA)
538 FE(DDPF_FOURCC)
539 FE(DDPF_PALETTEINDEXED4)
540 FE(DDPF_PALETTEINDEXEDTO8)
541 FE(DDPF_PALETTEINDEXED8)
542 FE(DDPF_RGB)
543 FE(DDPF_COMPRESSED)
544 FE(DDPF_RGBTOYUV)
545 FE(DDPF_YUV)
546 FE(DDPF_ZBUFFER)
547 FE(DDPF_PALETTEINDEXED1)
548 FE(DDPF_PALETTEINDEXED2)
549 FE(DDPF_ZPIXELS)
550 #undef FE
552 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
553 if (flags[i].mask & flagmask)
554 DPRINTF("%s ",flags[i].name);
557 static void _dump_paletteformat(DWORD dwFlags) {
558 int i;
559 const struct {
560 DWORD mask;
561 char *name;
562 } flags[] = {
563 #define FE(x) { x, #x},
564 FE(DDPCAPS_4BIT)
565 FE(DDPCAPS_8BITENTRIES)
566 FE(DDPCAPS_8BIT)
567 FE(DDPCAPS_INITIALIZE)
568 FE(DDPCAPS_PRIMARYSURFACE)
569 FE(DDPCAPS_PRIMARYSURFACELEFT)
570 FE(DDPCAPS_ALLOW256)
571 FE(DDPCAPS_VSYNC)
572 FE(DDPCAPS_1BIT)
573 FE(DDPCAPS_2BIT)
574 FE(DDPCAPS_ALPHA)
575 #undef FE
577 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
578 if (flags[i].mask & dwFlags)
579 DPRINTF("%s ",flags[i].name);
580 DPRINTF("\n");
583 static void _dump_pixelformat(void *in) {
584 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
585 char *cmd;
587 DPRINTF("( ");
588 _dump_pixelformat_flag(pf->dwFlags);
589 if (pf->dwFlags & DDPF_FOURCC) {
590 DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
592 if (pf->dwFlags & DDPF_RGB) {
593 DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount);
594 switch (pf->u.dwRGBBitCount) {
595 case 4:
596 cmd = "%1lx";
597 break;
598 case 8:
599 cmd = "%02lx";
600 break;
601 case 16:
602 cmd = "%04lx";
603 break;
604 case 24:
605 cmd = "%06lx";
606 break;
607 case 32:
608 cmd = "%08lx";
609 break;
610 default:
611 ERR("Unexpected bit depth !\n");
612 cmd = "%d";
614 DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask);
615 DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask);
616 DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask);
617 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
618 DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask);
620 if (pf->dwFlags & DDPF_ZPIXELS) {
621 DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask);
624 if (pf->dwFlags & DDPF_ZBUFFER) {
625 DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth);
627 if (pf->dwFlags & DDPF_ALPHA) {
628 DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth);
630 DPRINTF(")");
633 static void _dump_colorkeyflag(DWORD ck) {
634 int i;
635 const struct {
636 DWORD mask;
637 char *name;
638 } flags[] = {
639 #define FE(x) { x, #x},
640 FE(DDCKEY_COLORSPACE)
641 FE(DDCKEY_DESTBLT)
642 FE(DDCKEY_DESTOVERLAY)
643 FE(DDCKEY_SRCBLT)
644 FE(DDCKEY_SRCOVERLAY)
645 #undef FE
647 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
648 if (flags[i].mask & ck)
649 DPRINTF("%s ",flags[i].name);
652 static void _dump_DWORD(void *in) {
653 DPRINTF("%ld", *((DWORD *) in));
655 static void _dump_PTR(void *in) {
656 DPRINTF("%p", *((void **) in));
658 static void _dump_DDCOLORKEY(void *in) {
659 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
661 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
664 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
665 int i;
666 struct {
667 DWORD mask;
668 char *name;
669 void (*func)(void *);
670 void *elt;
671 } flags[16], *fe = flags;
672 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
673 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
674 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
675 FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
676 FE(DDSD_PITCH, _dump_DWORD, lPitch);
677 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
678 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth);
679 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
680 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
681 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
682 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
683 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
684 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
685 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount);
686 FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate);
687 FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize);
688 FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface);
689 #undef FE
691 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
692 if (flags[i].mask & lpddsd->dwFlags) {
693 DPRINTF(" - %s : ",flags[i].name);
694 flags[i].func(flags[i].elt);
695 DPRINTF("\n");
700 /******************************************************************************
701 * IDirectDrawSurface methods
703 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
704 * DDS and DDS2 use those functions. (Function calls did not change (except
705 * using different DirectDrawSurfaceX version), just added flags and functions)
708 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
709 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
711 ICOM_THIS(IDirectDrawSurface4Impl,iface);
712 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
713 This,lprect,lpddsd,flags,(DWORD)hnd);
714 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
715 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
716 This,lprect,lpddsd,flags,(DWORD)hnd);
718 /* First, copy the Surface description */
719 *lpddsd = This->s.surface_desc;
720 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
721 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
723 /* If asked only for a part, change the surface pointer */
724 if (lprect) {
725 TRACE(" lprect: %dx%d-%dx%d\n",
726 lprect->top,lprect->left,lprect->bottom,lprect->right
728 if ((lprect->top < 0) ||
729 (lprect->left < 0) ||
730 (lprect->bottom < 0) ||
731 (lprect->right < 0)) {
732 ERR(" Negative values in LPRECT !!!\n");
733 return DDERR_INVALIDPARAMS;
736 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
737 (lprect->top*This->s.surface_desc.lPitch) +
738 lprect->left*GET_BPP(This->s.surface_desc));
739 } else {
740 assert(This->s.surface_desc.u1.lpSurface);
743 /* wait for any previous operations to complete */
744 #ifdef HAVE_LIBXXSHM
745 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE) &&
746 This->s.ddraw->e.xlib.xshm_active) {
748 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
749 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
751 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
753 #endif
754 return DD_OK;
757 #ifdef HAVE_LIBXXF86DGA
758 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
759 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
761 ICOM_THIS(IDirectDrawSurface4Impl,iface);
762 TRACE("(%p)->Unlock(%p)\n",This,surface);
763 return DD_OK;
765 #endif /* defined(HAVE_LIBXXF86DGA) */
767 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
768 if (This->s.ddraw->d.pixel_convert != NULL)
769 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
770 This->t.xlib.image->data,
771 This->s.surface_desc.dwWidth,
772 This->s.surface_desc.dwHeight,
773 This->s.surface_desc.lPitch,
774 This->s.palette);
776 #ifdef HAVE_LIBXXSHM
777 if (This->s.ddraw->e.xlib.xshm_active) {
779 X11DRV_EVENT_WaitReplaceShmCompletion( &This->s.ddraw->e.xlib.xshm_compl, This->s.ddraw->d.drawable );
781 /* let WaitShmCompletions track 'em for now */
782 /* (you may want to track it again whenever you implement DX7's partial surface locking,
783 where threads have concurrent access) */
784 X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
785 TSXShmPutImage(display,
786 This->s.ddraw->d.drawable,
787 DefaultGCOfScreen(X11DRV_GetXScreen()),
788 This->t.xlib.image,
789 0, 0, 0, 0,
790 This->t.xlib.image->width,
791 This->t.xlib.image->height,
792 True);
793 /* make sure the image is transferred ASAP */
794 TSXFlush(display);
796 else
797 #endif
798 TSXPutImage( display,
799 This->s.ddraw->d.drawable,
800 DefaultGCOfScreen(X11DRV_GetXScreen()),
801 This->t.xlib.image,
802 0, 0, 0, 0,
803 This->t.xlib.image->width,
804 This->t.xlib.image->height);
807 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
808 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
810 ICOM_THIS(IDirectDrawSurface4Impl,iface);
811 TRACE("(%p)->Unlock(%p)\n",This,surface);
813 if (!This->s.ddraw->d.paintable)
814 return DD_OK;
816 /* Only redraw the screen when unlocking the buffer that is on screen */
817 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
818 Xlib_copy_surface_on_screen(This);
820 if (This->s.palette && This->s.palette->cm)
821 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
823 return DD_OK;
826 static IDirectDrawSurface4Impl* _common_find_flipto(
827 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
829 int i,j,flipable=0;
830 struct _surface_chain *chain = This->s.chain;
832 /* if there was no override flipto, look for current backbuffer */
833 if (!flipto) {
834 /* walk the flip chain looking for backbuffer */
835 for (i=0;i<chain->nrofsurfaces;i++) {
836 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
837 flipable++;
838 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
839 flipto = chain->surfaces[i];
841 /* sanity checks ... */
842 if (!flipto) {
843 if (flipable>1) {
844 for (i=0;i<chain->nrofsurfaces;i++)
845 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
846 break;
847 if (i==chain->nrofsurfaces) {
848 /* we do not have a frontbuffer either */
849 for (i=0;i<chain->nrofsurfaces;i++)
850 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
851 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
852 break;
854 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
855 int k = j % chain->nrofsurfaces;
856 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
857 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
858 flipto = chain->surfaces[k];
859 break;
864 if (!flipto)
865 flipto = This;
867 TRACE("flipping to %p\n",flipto);
869 return flipto;
872 #ifdef HAVE_LIBXXF86DGA
873 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
874 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
876 ICOM_THIS(IDirectDrawSurface4Impl,iface);
877 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
878 DWORD xheight;
879 LPBYTE surf;
881 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
882 iflipto = _common_find_flipto(This,iflipto);
884 /* and flip! */
885 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
886 if (iflipto->s.palette && iflipto->s.palette->cm)
887 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
888 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
891 /* We need to switch the lowlevel surfaces, for DGA this is: */
893 /* The height within the framebuffer */
894 xheight = This->t.dga.fb_height;
895 This->t.dga.fb_height = iflipto->t.dga.fb_height;
896 iflipto->t.dga.fb_height = xheight;
898 /* And the assciated surface pointer */
899 surf = This->s.surface_desc.u1.lpSurface;
900 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
901 iflipto->s.surface_desc.u1.lpSurface = surf;
903 return DD_OK;
905 #endif /* defined(HAVE_LIBXXF86DGA) */
907 #ifdef HAVE_LIBXXF86DGA2
908 static HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
909 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
911 ICOM_THIS(IDirectDrawSurface4Impl,iface);
912 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
913 DWORD xheight;
914 LPBYTE surf;
916 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
917 iflipto = _common_find_flipto(This,iflipto);
919 /* and flip! */
920 TSXDGASetViewport(display,DefaultScreen(display),0,iflipto->t.dga.fb_height, XDGAFlipRetrace);
921 TSXDGASync(display,DefaultScreen(display));
922 TSXFlush(display);
923 if (iflipto->s.palette && iflipto->s.palette->cm)
924 TSXDGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
925 /* We need to switch the lowlevel surfaces, for DGA this is: */
927 /* The height within the framebuffer */
928 xheight = This->t.dga.fb_height;
929 This->t.dga.fb_height = iflipto->t.dga.fb_height;
930 iflipto->t.dga.fb_height = xheight;
932 /* And the assciated surface pointer */
933 surf = This->s.surface_desc.u1.lpSurface;
934 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
935 iflipto->s.surface_desc.u1.lpSurface = surf;
937 return DD_OK;
939 #endif /* defined(HAVE_LIBXXF86DGA2) */
941 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
942 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
944 ICOM_THIS(IDirectDrawSurface4Impl,iface);
945 XImage *image;
946 LPBYTE surf;
947 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
949 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
950 iflipto = _common_find_flipto(This,iflipto);
952 #if defined(HAVE_MESAGL) && 0 /* does not work */
953 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
954 TRACE(" - OpenGL flip\n");
955 ENTER_GL();
956 glXSwapBuffers(display, This->s.ddraw->d.drawable);
957 LEAVE_GL();
959 return DD_OK;
961 #endif /* defined(HAVE_MESAGL) */
963 if (!This->s.ddraw->d.paintable)
964 return DD_OK;
966 /* We need to switch the lowlevel surfaces, for xlib this is: */
967 /* The surface pointer */
968 surf = This->s.surface_desc.u1.lpSurface;
969 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
970 iflipto->s.surface_desc.u1.lpSurface = surf;
971 /* the associated ximage */
972 image = This->t.xlib.image;
973 This->t.xlib.image = iflipto->t.xlib.image;
974 iflipto->t.xlib.image = image;
976 #ifdef HAVE_LIBXXSHM
977 if (This->s.ddraw->e.xlib.xshm_active) {
979 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
980 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
982 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
984 #endif
985 Xlib_copy_surface_on_screen(This);
987 if (iflipto->s.palette && iflipto->s.palette->cm)
988 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
989 return DD_OK;
992 /* The IDirectDrawSurface4::SetPalette method attaches the specified
993 * DirectDrawPalette object to a surface. The surface uses this palette for all
994 * subsequent operations. The palette change takes place immediately.
996 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
997 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
999 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1000 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1001 int i;
1002 TRACE("(%p)->(%p)\n",This,ipal);
1004 if (ipal == NULL) {
1005 if( This->s.palette != NULL )
1006 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1007 This->s.palette = ipal;
1009 return DD_OK;
1012 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8))
1014 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
1015 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
1017 if (!Options.managed)
1018 TSXInstallColormap(display,ipal->cm);
1020 for (i=0;i<256;i++) {
1021 XColor xc;
1023 xc.red = ipal->palents[i].peRed<<8;
1024 xc.blue = ipal->palents[i].peBlue<<8;
1025 xc.green = ipal->palents[i].peGreen<<8;
1026 xc.flags = DoRed|DoBlue|DoGreen;
1027 xc.pixel = i;
1028 TSXStoreColor(display,ipal->cm,&xc);
1030 TSXInstallColormap(display,ipal->cm);
1033 /* According to spec, we are only supposed to
1034 * AddRef if this is not the same palette.
1036 if( This->s.palette != ipal )
1038 if( ipal != NULL )
1039 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1040 if( This->s.palette != NULL )
1041 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1042 This->s.palette = ipal;
1043 /* Perform the refresh */
1044 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
1046 return DD_OK;
1049 #ifdef HAVE_LIBXXF86DGA
1050 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
1051 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1053 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1054 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1055 TRACE("(%p)->(%p)\n",This,ipal);
1057 /* According to spec, we are only supposed to
1058 * AddRef if this is not the same palette.
1060 if( This->s.palette != ipal )
1062 if( ipal != NULL )
1063 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1064 if( This->s.palette != NULL )
1065 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1066 This->s.palette = ipal;
1067 #ifdef HAVE_LIBXXF86DGA2
1068 if (This->s.ddraw->e.dga.version == 2)
1069 TSXDGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1070 else
1071 #endif /* defined(HAVE_LIBXXF86DGA2) */
1072 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1074 return DD_OK;
1076 #endif /* defined(HAVE_LIBXXF86DGA) */
1078 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
1080 int x, y;
1081 LPBYTE first;
1083 /* Do first row */
1085 #define COLORFILL_ROW(type) { \
1086 type *d = (type *) buf; \
1087 for (x = 0; x < width; x++) \
1088 d[x] = (type) color; \
1089 break; \
1092 switch(bpp) {
1093 case 1: COLORFILL_ROW(BYTE)
1094 case 2: COLORFILL_ROW(WORD)
1095 case 4: COLORFILL_ROW(DWORD)
1096 default:
1097 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
1098 return DDERR_UNSUPPORTED;
1101 #undef COLORFILL_ROW
1103 /* Now copy first row */
1104 first = buf;
1105 for (y = 1; y < height; y++) {
1106 buf += lPitch;
1107 memcpy(buf, first, width * bpp);
1110 return DD_OK;
1113 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
1114 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
1116 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1117 RECT xdst,xsrc;
1118 DDSURFACEDESC ddesc,sdesc;
1119 HRESULT ret = DD_OK;
1120 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
1121 int x, y;
1122 LPBYTE dbuf, sbuf;
1124 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
1126 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
1127 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1129 if (TRACE_ON(ddraw)) {
1130 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1131 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1132 TRACE("\tflags: ");
1133 _dump_DDBLT(dwFlags);
1134 if (dwFlags & DDBLT_DDFX) {
1135 TRACE("\tblitfx: ");
1136 _dump_DDBLTFX(lpbltfx->dwDDFX);
1140 if (rdst) {
1141 if ((rdst->top < 0) ||
1142 (rdst->left < 0) ||
1143 (rdst->bottom < 0) ||
1144 (rdst->right < 0)) {
1145 ERR(" Negative values in LPRECT !!!\n");
1146 goto release;
1148 memcpy(&xdst,rdst,sizeof(xdst));
1149 } else {
1150 xdst.top = 0;
1151 xdst.bottom = ddesc.dwHeight;
1152 xdst.left = 0;
1153 xdst.right = ddesc.dwWidth;
1156 if (rsrc) {
1157 if ((rsrc->top < 0) ||
1158 (rsrc->left < 0) ||
1159 (rsrc->bottom < 0) ||
1160 (rsrc->right < 0)) {
1161 ERR(" Negative values in LPRECT !!!\n");
1162 goto release;
1164 memcpy(&xsrc,rsrc,sizeof(xsrc));
1165 } else {
1166 if (src) {
1167 xsrc.top = 0;
1168 xsrc.bottom = sdesc.dwHeight;
1169 xsrc.left = 0;
1170 xsrc.right = sdesc.dwWidth;
1171 } else {
1172 memset(&xsrc,0,sizeof(xsrc));
1176 bpp = GET_BPP(ddesc);
1177 srcheight = xsrc.bottom - xsrc.top;
1178 srcwidth = xsrc.right - xsrc.left;
1179 dstheight = xdst.bottom - xdst.top;
1180 dstwidth = xdst.right - xdst.left;
1181 width = (xdst.right - xdst.left) * bpp;
1182 dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1184 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1186 /* First, all the 'source-less' blits */
1187 if (dwFlags & DDBLT_COLORFILL) {
1188 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1189 ddesc.lPitch, lpbltfx->u4.dwFillColor);
1190 dwFlags &= ~DDBLT_COLORFILL;
1193 if (dwFlags & DDBLT_DEPTHFILL) {
1194 #ifdef HAVE_MESAGL
1195 GLboolean ztest;
1197 /* Clears the screen */
1198 TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
1199 glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1200 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1201 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1202 glClear(GL_DEPTH_BUFFER_BIT);
1203 glDepthMask(ztest);
1205 dwFlags &= ~(DDBLT_DEPTHFILL);
1206 #endif /* defined(HAVE_MESAGL) */
1209 if (dwFlags & DDBLT_ROP) {
1210 /* Catch some degenerate cases here */
1211 switch(lpbltfx->dwROP) {
1212 case BLACKNESS:
1213 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1214 break;
1215 case 0xAA0029: /* No-op */
1216 break;
1217 case WHITENESS:
1218 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1219 break;
1220 default:
1221 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
1222 goto error;
1224 dwFlags &= ~DDBLT_ROP;
1227 if (dwFlags & DDBLT_DDROPS) {
1228 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
1231 /* Now the 'with source' blits */
1232 if (src) {
1233 LPBYTE sbase;
1234 int sx, xinc, sy, yinc;
1236 sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1237 xinc = (srcwidth << 16) / dstwidth;
1238 yinc = (srcheight << 16) / dstheight;
1240 if (!dwFlags) {
1242 /* No effects, we can cheat here */
1243 if (dstwidth == srcwidth) {
1244 if (dstheight == srcheight) {
1245 /* No stretching in either direction. This needs to be as fast as possible */
1246 sbuf = sbase;
1247 for (y = 0; y < dstheight; y++) {
1248 memcpy(dbuf, sbuf, width);
1249 sbuf += sdesc.lPitch;
1250 dbuf += ddesc.lPitch;
1252 } else {
1253 /* Stretching in Y direction only */
1254 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1255 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1256 memcpy(dbuf, sbuf, width);
1257 dbuf += ddesc.lPitch;
1260 } else {
1261 /* Stretching in X direction */
1262 int last_sy = -1;
1263 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1264 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1266 if ((sy >> 16) == (last_sy >> 16)) {
1267 /* Same as last row - copy already stretched row */
1268 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1269 } else {
1271 #define STRETCH_ROW(type) { \
1272 type *s = (type *) sbuf, *d = (type *) dbuf; \
1273 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1274 d[x] = s[sx >> 16]; \
1275 break; }
1277 switch(bpp) {
1278 case 1: STRETCH_ROW(BYTE)
1279 case 2: STRETCH_ROW(WORD)
1280 case 4: STRETCH_ROW(DWORD)
1281 default:
1282 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1283 ret = DDERR_UNSUPPORTED;
1284 goto error;
1287 #undef STRETCH_ROW
1290 last_sy = sy;
1291 dbuf += ddesc.lPitch;
1294 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1295 DWORD keylow, keyhigh;
1297 if (dwFlags & DDBLT_KEYSRC) {
1298 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1299 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1300 } else {
1301 /* I'm not sure if this is correct */
1302 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1303 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1304 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1308 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1309 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1311 #define COPYROW_COLORKEY(type) { \
1312 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1313 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1314 tmp = s[sx >> 16]; \
1315 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1317 break; }
1319 switch (bpp) {
1320 case 1: COPYROW_COLORKEY(BYTE)
1321 case 2: COPYROW_COLORKEY(WORD)
1322 case 4: COPYROW_COLORKEY(DWORD)
1323 default:
1324 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1325 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1326 ret = DDERR_UNSUPPORTED;
1327 goto error;
1329 dbuf += ddesc.lPitch;
1332 #undef COPYROW_COLORKEY
1334 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1339 error:
1341 if (dwFlags && FIXME_ON(ddraw)) {
1342 FIXME("\tUnsupported flags: ");
1343 _dump_DDBLT(dwFlags);
1345 release:
1347 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1348 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1350 return DD_OK;
1353 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1354 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1356 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1357 int bpp, w, h, x, y;
1358 DDSURFACEDESC ddesc,sdesc;
1359 HRESULT ret = DD_OK;
1360 LPBYTE sbuf, dbuf;
1361 RECT rsrc2;
1364 if (TRACE_ON(ddraw)) {
1365 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1366 This,dstx,dsty,src,rsrc,trans
1368 FIXME(" trans:");
1369 if (FIXME_ON(ddraw))
1370 _dump_DDBLTFAST(trans);
1371 if (rsrc)
1372 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1373 else
1374 FIXME(" srcrect: NULL\n");
1377 /* We need to lock the surfaces, or we won't get refreshes when done. */
1378 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1379 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1381 if (!rsrc) {
1382 WARN("rsrc is NULL!\n");
1383 rsrc = &rsrc2;
1384 rsrc->left = rsrc->top = 0;
1385 rsrc->right = sdesc.dwWidth;
1386 rsrc->bottom = sdesc.dwHeight;
1389 bpp = GET_BPP(This->s.surface_desc);
1390 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1391 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1394 h=rsrc->bottom-rsrc->top;
1395 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1396 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1397 if (h<0) h=0;
1399 w=rsrc->right-rsrc->left;
1400 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1401 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1402 if (w<0) w=0;
1404 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1405 DWORD keylow, keyhigh;
1406 if (trans & DDBLTFAST_SRCCOLORKEY) {
1407 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1408 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1409 } else {
1410 /* I'm not sure if this is correct */
1411 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1412 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1413 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1416 #define COPYBOX_COLORKEY(type) { \
1417 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1418 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1419 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1420 for (y = 0; y < h; y++) { \
1421 for (x = 0; x < w; x++) { \
1422 tmp = s[x]; \
1423 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1425 (LPBYTE)s += sdesc.lPitch; \
1426 (LPBYTE)d += ddesc.lPitch; \
1428 break; \
1431 switch (bpp) {
1432 case 1: COPYBOX_COLORKEY(BYTE)
1433 case 2: COPYBOX_COLORKEY(WORD)
1434 case 4: COPYBOX_COLORKEY(DWORD)
1435 default:
1436 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1437 ret = DDERR_UNSUPPORTED;
1438 goto error;
1441 #undef COPYBOX_COLORKEY
1443 } else {
1444 int width = w * bpp;
1446 for (y = 0; y < h; y++) {
1447 memcpy(dbuf, sbuf, width);
1448 sbuf += sdesc.lPitch;
1449 dbuf += ddesc.lPitch;
1453 error:
1455 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1456 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1457 return ret;
1460 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1461 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1463 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1464 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1465 This,ddbltbatch,x,y
1467 return DD_OK;
1470 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1471 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1473 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1474 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1475 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1476 return DD_OK;
1479 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1480 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1481 ) {
1482 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1483 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1485 /* Simply copy the surface description stored in the object */
1486 *ddsd = This->s.surface_desc;
1488 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1490 return DD_OK;
1493 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1494 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1495 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1496 return ++(This->ref);
1499 #ifdef HAVE_LIBXXF86DGA
1500 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1501 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1503 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1505 if (--(This->ref))
1506 return This->ref;
1508 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1509 /* clear out of surface list */
1510 if (This->t.dga.fb_height == -1)
1511 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1512 else
1513 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1515 /* Free the DIBSection (if any) */
1516 if (This->s.hdc != 0) {
1517 SelectObject(This->s.hdc, This->s.holdbitmap);
1518 DeleteDC(This->s.hdc);
1519 DeleteObject(This->s.DIBsection);
1522 /* Free the clipper if attached to this surface */
1523 if( This->s.lpClipper )
1524 IDirectDrawClipper_Release(This->s.lpClipper);
1526 HeapFree(GetProcessHeap(),0,This);
1527 return S_OK;
1529 #endif /* defined(HAVE_LIBXXF86DGA) */
1531 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1532 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1534 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1536 if (--(This->ref))
1537 return This->ref;
1539 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1541 if (This->t.xlib.image != NULL) {
1542 if (This->s.ddraw->d.pixel_convert != NULL) {
1543 /* In pixel conversion mode, there are 2 buffers to release. */
1544 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1546 #ifdef HAVE_LIBXXSHM
1547 if (This->s.ddraw->e.xlib.xshm_active) {
1548 TSXShmDetach(display, &(This->t.xlib.shminfo));
1549 TSXDestroyImage(This->t.xlib.image);
1550 shmdt(This->t.xlib.shminfo.shmaddr);
1551 } else {
1552 #endif
1553 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1554 This->t.xlib.image->data = NULL;
1555 TSXDestroyImage(This->t.xlib.image);
1556 #ifdef HAVE_LIBXXSHM
1558 #endif
1559 } else {
1560 This->t.xlib.image->data = NULL;
1562 #ifdef HAVE_LIBXXSHM
1563 if (This->s.ddraw->e.xlib.xshm_active) {
1564 TSXShmDetach(display, &(This->t.xlib.shminfo));
1565 TSXDestroyImage(This->t.xlib.image);
1566 shmdt(This->t.xlib.shminfo.shmaddr);
1567 } else {
1568 #endif
1569 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1570 TSXDestroyImage(This->t.xlib.image);
1571 #ifdef HAVE_LIBXXSHM
1573 #endif
1575 This->t.xlib.image = 0;
1576 } else {
1577 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1580 if (This->s.palette)
1581 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1583 /* Free the DIBSection (if any) */
1584 if (This->s.hdc != 0) {
1585 SelectObject(This->s.hdc, This->s.holdbitmap);
1586 DeleteDC(This->s.hdc);
1587 DeleteObject(This->s.DIBsection);
1590 /* Free the clipper if present */
1591 if( This->s.lpClipper )
1592 IDirectDrawClipper_Release(This->s.lpClipper);
1594 HeapFree(GetProcessHeap(),0,This);
1595 return S_OK;
1598 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1599 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1601 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1602 int i,found = 0,xstart;
1603 struct _surface_chain *chain;
1605 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1606 if (TRACE_ON(ddraw)) {
1607 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1608 DPRINTF("\n");
1610 chain = This->s.chain;
1611 if (!chain)
1612 return DDERR_NOTFOUND;
1614 for (i=0;i<chain->nrofsurfaces;i++)
1615 if (chain->surfaces[i] == This)
1616 break;
1618 xstart = i;
1619 for (i=0;i<chain->nrofsurfaces;i++) {
1620 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1621 #if 0
1622 if (found) /* may not find the same caps twice, (doc) */
1623 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1624 #endif
1625 found = (i+1)+xstart;
1628 if (!found)
1629 return DDERR_NOTFOUND;
1630 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1631 /* FIXME: AddRef? */
1632 TRACE("found %p\n",*lpdsf);
1633 return DD_OK;
1636 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1637 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1639 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1640 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1642 return DDERR_ALREADYINITIALIZED;
1645 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1646 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1648 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1649 TRACE("(%p)->(%p)\n",This,pf);
1651 *pf = This->s.surface_desc.ddpfPixelFormat;
1652 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1653 return DD_OK;
1656 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1657 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1658 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1659 return DD_OK;
1662 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1663 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1665 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1666 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1667 return DD_OK;
1670 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1671 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
1673 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1674 TRACE("(%p)->(%p)!\n",This,lpClipper);
1676 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
1677 This->s.lpClipper = lpClipper;
1678 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
1679 return DD_OK;
1682 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1683 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1685 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1686 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1687 int i;
1688 struct _surface_chain *chain;
1690 FIXME("(%p)->(%p)\n",This,surf);
1691 chain = This->s.chain;
1693 /* IDirectDrawSurface4_AddRef(surf); */
1695 if (chain) {
1696 for (i=0;i<chain->nrofsurfaces;i++)
1697 if (chain->surfaces[i] == isurf)
1698 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1699 } else {
1700 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1701 chain->nrofsurfaces = 1;
1702 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1703 chain->surfaces[0] = This;
1704 This->s.chain = chain;
1707 if (chain->surfaces)
1708 chain->surfaces = HeapReAlloc(
1709 GetProcessHeap(),
1711 chain->surfaces,
1712 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1714 else
1715 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1716 isurf->s.chain = chain;
1717 chain->surfaces[chain->nrofsurfaces++] = isurf;
1718 return DD_OK;
1721 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1722 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1723 DDSURFACEDESC desc;
1724 BITMAPINFO *b_info;
1725 UINT usage;
1727 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1729 /* Creates a DIB Section of the same size / format as the surface */
1730 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1732 if (This->s.hdc == 0) {
1733 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1734 case 16:
1735 case 32:
1736 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1737 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1738 break;
1739 #endif
1741 case 24:
1742 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1743 break;
1745 default:
1746 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1747 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1748 break;
1751 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1752 b_info->bmiHeader.biWidth = desc.dwWidth;
1753 b_info->bmiHeader.biHeight = desc.dwHeight;
1754 b_info->bmiHeader.biPlanes = 1;
1755 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1756 #if 0
1757 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1758 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1759 #endif
1760 b_info->bmiHeader.biCompression = BI_RGB;
1761 #if 0
1762 else
1763 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1764 #endif
1765 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1766 b_info->bmiHeader.biXPelsPerMeter = 0;
1767 b_info->bmiHeader.biYPelsPerMeter = 0;
1768 b_info->bmiHeader.biClrUsed = 0;
1769 b_info->bmiHeader.biClrImportant = 0;
1771 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1772 case 16:
1773 case 32:
1774 #if 0
1776 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1778 usage = 0;
1779 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1780 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1781 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1783 break;
1784 #endif
1785 case 24:
1786 /* Nothing to do */
1787 usage = DIB_RGB_COLORS;
1788 break;
1790 default: {
1791 int i;
1793 /* Fill the palette */
1794 usage = DIB_RGB_COLORS;
1796 if (This->s.palette == NULL) {
1797 ERR("Bad palette !!!\n");
1798 } else {
1799 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1800 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1802 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1803 rgb[i].rgbBlue = pent[i].peBlue;
1804 rgb[i].rgbRed = pent[i].peRed;
1805 rgb[i].rgbGreen = pent[i].peGreen;
1809 break;
1811 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1812 b_info,
1813 usage,
1814 &(This->s.bitmap_data),
1818 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1819 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1821 /* b_info is not useful anymore */
1822 HeapFree(GetProcessHeap(), 0, b_info);
1824 /* Create the DC */
1825 This->s.hdc = CreateCompatibleDC(0);
1826 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1829 /* Copy our surface in the DIB section */
1830 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1831 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1832 else
1833 /* TODO */
1834 FIXME("This case has to be done :/\n");
1836 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1837 *lphdc = This->s.hdc;
1839 return DD_OK;
1842 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1843 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1845 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1846 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1847 /* Copy the DIB section to our surface */
1848 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1849 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1850 } else {
1851 /* TODO */
1852 FIXME("This case has to be done :/\n");
1854 /* Unlock the surface */
1855 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1856 return DD_OK;
1859 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1860 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1862 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
1864 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1865 * the same interface. And IUnknown does that too of course.
1867 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1868 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1869 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1870 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1871 IsEqualGUID( &IID_IUnknown, refiid )
1873 *obj = This;
1874 IDirectDrawSurface4_AddRef(iface);
1876 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1877 return S_OK;
1879 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1881 /* Texture interface */
1882 *obj = d3dtexture2_create(This);
1883 IDirectDrawSurface4_AddRef(iface);
1884 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1885 return S_OK;
1887 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1889 /* Texture interface */
1890 *obj = d3dtexture_create(This);
1891 IDirectDrawSurface4_AddRef(iface);
1893 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1895 return S_OK;
1897 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1898 /* It is the OpenGL Direct3D Device */
1899 IDirectDrawSurface4_AddRef(iface);
1900 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1901 return S_OK;
1904 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
1905 return OLE_E_ENUM_NOMORE;
1908 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1909 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1910 TRACE("(%p)->(), stub!\n",This);
1911 return DD_OK; /* hmm */
1914 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1915 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1916 int i;
1917 struct _surface_chain *chain = This->s.chain;
1919 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1920 for (i=0;i<chain->nrofsurfaces;i++) {
1921 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1922 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1923 return DD_OK; /* FIXME: return value correct? */
1925 return DD_OK;
1928 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1929 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1930 FIXME("(%p)->(),stub!\n",This);
1931 return DD_OK;
1934 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1935 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1937 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1938 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1939 if (TRACE_ON(ddraw)) {
1940 _dump_colorkeyflag(dwFlags);
1941 DPRINTF(" : ");
1942 _dump_DDCOLORKEY((void *) ckey);
1943 DPRINTF("\n");
1946 /* If this surface was loaded as a texture, call also the texture
1947 SetColorKey callback */
1948 if (This->s.texture) {
1949 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1952 if( dwFlags & DDCKEY_SRCBLT )
1954 dwFlags &= ~DDCKEY_SRCBLT;
1955 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1956 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1959 if( dwFlags & DDCKEY_DESTBLT )
1961 dwFlags &= ~DDCKEY_DESTBLT;
1962 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1963 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1966 if( dwFlags & DDCKEY_SRCOVERLAY )
1968 dwFlags &= ~DDCKEY_SRCOVERLAY;
1969 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1970 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1973 if( dwFlags & DDCKEY_DESTOVERLAY )
1975 dwFlags &= ~DDCKEY_DESTOVERLAY;
1976 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1977 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1980 if( dwFlags )
1982 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1985 return DD_OK;
1989 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1990 LPDIRECTDRAWSURFACE4 iface,
1991 LPRECT lpRect )
1993 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1994 FIXME("(%p)->(%p),stub!\n",This,lpRect);
1996 return DD_OK;
1999 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
2000 LPDIRECTDRAWSURFACE4 iface,
2001 DWORD dwFlags,
2002 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
2004 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2005 int i;
2006 struct _surface_chain *chain;
2008 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
2009 chain = This->s.chain;
2010 for (i=0;i<chain->nrofsurfaces;i++) {
2011 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
2012 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
2014 chain->surfaces[i]->s.chain = NULL;
2015 memcpy( chain->surfaces+i,
2016 chain->surfaces+(i+1),
2017 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
2019 chain->surfaces = HeapReAlloc(
2020 GetProcessHeap(),
2022 chain->surfaces,
2023 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
2025 chain->nrofsurfaces--;
2026 return DD_OK;
2029 return DD_OK;
2032 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
2033 LPDIRECTDRAWSURFACE4 iface,
2034 DWORD dwFlags,
2035 LPVOID lpContext,
2036 LPDDENUMSURFACESCALLBACK lpfnCallback )
2038 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2039 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
2040 lpContext, lpfnCallback );
2042 return DD_OK;
2045 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
2046 LPDIRECTDRAWSURFACE4 iface,
2047 LPDIRECTDRAWCLIPPER* lplpDDClipper )
2049 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2050 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
2052 return DD_OK;
2055 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
2056 LPDIRECTDRAWSURFACE4 iface,
2057 DWORD dwFlags,
2058 LPDDCOLORKEY lpDDColorKey )
2060 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2061 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
2063 if( dwFlags & DDCKEY_SRCBLT ) {
2064 dwFlags &= ~DDCKEY_SRCBLT;
2065 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
2068 if( dwFlags & DDCKEY_DESTBLT )
2070 dwFlags &= ~DDCKEY_DESTBLT;
2071 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
2074 if( dwFlags & DDCKEY_SRCOVERLAY )
2076 dwFlags &= ~DDCKEY_SRCOVERLAY;
2077 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
2080 if( dwFlags & DDCKEY_DESTOVERLAY )
2082 dwFlags &= ~DDCKEY_DESTOVERLAY;
2083 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
2086 if( dwFlags )
2088 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2091 return DD_OK;
2094 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
2095 LPDIRECTDRAWSURFACE4 iface,
2096 DWORD dwFlags )
2098 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2099 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2101 return DD_OK;
2104 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
2105 LPDIRECTDRAWSURFACE4 iface,
2106 LPDIRECTDRAWPALETTE* lplpDDPalette )
2108 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2109 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
2111 if (This->s.palette != NULL) {
2112 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
2114 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
2115 return DD_OK;
2116 } else {
2117 return DDERR_NOPALETTEATTACHED;
2121 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
2122 LPDIRECTDRAWSURFACE4 iface,
2123 LONG lX,
2124 LONG lY)
2126 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2127 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
2129 return DD_OK;
2132 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
2133 LPDIRECTDRAWSURFACE4 iface,
2134 LPRECT lpSrcRect,
2135 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
2136 LPRECT lpDestRect,
2137 DWORD dwFlags,
2138 LPDDOVERLAYFX lpDDOverlayFx )
2140 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2141 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
2142 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
2144 return DD_OK;
2147 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
2148 LPDIRECTDRAWSURFACE4 iface,
2149 DWORD dwFlags )
2151 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2152 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2154 return DD_OK;
2157 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2158 LPDIRECTDRAWSURFACE4 iface,
2159 DWORD dwFlags,
2160 LPDIRECTDRAWSURFACE4 lpDDSReference )
2162 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2163 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2165 return DD_OK;
2168 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2169 LPDIRECTDRAWSURFACE4 iface,
2170 LPVOID* lplpDD )
2172 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2173 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2175 /* Not sure about that... */
2176 *lplpDD = (void *) This->s.ddraw;
2178 return DD_OK;
2181 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2182 LPDIRECTDRAWSURFACE4 iface,
2183 DWORD dwFlags )
2185 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2186 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2188 return DD_OK;
2191 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2192 LPDIRECTDRAWSURFACE4 iface,
2193 DWORD dwFlags )
2195 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2196 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2198 return DD_OK;
2201 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2202 LPDIRECTDRAWSURFACE4 iface,
2203 LPDDSURFACEDESC lpDDSD,
2204 DWORD dwFlags )
2206 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2207 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2209 return DD_OK;
2212 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2213 REFGUID guidTag,
2214 LPVOID lpData,
2215 DWORD cbSize,
2216 DWORD dwFlags) {
2217 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2218 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2220 return DD_OK;
2223 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2224 REFGUID guidTag,
2225 LPVOID lpBuffer,
2226 LPDWORD lpcbBufferSize) {
2227 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2228 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2230 return DD_OK;
2233 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2234 REFGUID guidTag) {
2235 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2236 FIXME("(%p)->(%p)\n", This, guidTag);
2238 return DD_OK;
2241 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2242 LPDWORD lpValue) {
2243 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2244 FIXME("(%p)->(%p)\n", This, lpValue);
2246 return DD_OK;
2249 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2250 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2251 FIXME("(%p)\n", This);
2253 return DD_OK;
2256 #ifdef HAVE_LIBXXF86DGA
2257 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2259 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2260 IDirectDrawSurface4Impl_QueryInterface,
2261 IDirectDrawSurface4Impl_AddRef,
2262 DGA_IDirectDrawSurface4Impl_Release,
2263 IDirectDrawSurface4Impl_AddAttachedSurface,
2264 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2265 IDirectDrawSurface4Impl_Blt,
2266 IDirectDrawSurface4Impl_BltBatch,
2267 IDirectDrawSurface4Impl_BltFast,
2268 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2269 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2270 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2271 DGA_IDirectDrawSurface4Impl_Flip,
2272 IDirectDrawSurface4Impl_GetAttachedSurface,
2273 IDirectDrawSurface4Impl_GetBltStatus,
2274 IDirectDrawSurface4Impl_GetCaps,
2275 IDirectDrawSurface4Impl_GetClipper,
2276 IDirectDrawSurface4Impl_GetColorKey,
2277 IDirectDrawSurface4Impl_GetDC,
2278 IDirectDrawSurface4Impl_GetFlipStatus,
2279 IDirectDrawSurface4Impl_GetOverlayPosition,
2280 IDirectDrawSurface4Impl_GetPalette,
2281 IDirectDrawSurface4Impl_GetPixelFormat,
2282 IDirectDrawSurface4Impl_GetSurfaceDesc,
2283 IDirectDrawSurface4Impl_Initialize,
2284 IDirectDrawSurface4Impl_IsLost,
2285 IDirectDrawSurface4Impl_Lock,
2286 IDirectDrawSurface4Impl_ReleaseDC,
2287 IDirectDrawSurface4Impl_Restore,
2288 IDirectDrawSurface4Impl_SetClipper,
2289 IDirectDrawSurface4Impl_SetColorKey,
2290 IDirectDrawSurface4Impl_SetOverlayPosition,
2291 DGA_IDirectDrawSurface4Impl_SetPalette,
2292 DGA_IDirectDrawSurface4Impl_Unlock,
2293 IDirectDrawSurface4Impl_UpdateOverlay,
2294 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2295 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2296 IDirectDrawSurface4Impl_GetDDInterface,
2297 IDirectDrawSurface4Impl_PageLock,
2298 IDirectDrawSurface4Impl_PageUnlock,
2299 IDirectDrawSurface4Impl_SetSurfaceDesc,
2300 IDirectDrawSurface4Impl_SetPrivateData,
2301 IDirectDrawSurface4Impl_GetPrivateData,
2302 IDirectDrawSurface4Impl_FreePrivateData,
2303 IDirectDrawSurface4Impl_GetUniquenessValue,
2304 IDirectDrawSurface4Impl_ChangeUniquenessValue
2306 #endif /* defined(HAVE_LIBXXF86DGA) */
2308 #ifdef HAVE_LIBXXF86DGA2
2309 static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
2311 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2312 IDirectDrawSurface4Impl_QueryInterface,
2313 IDirectDrawSurface4Impl_AddRef,
2314 DGA_IDirectDrawSurface4Impl_Release,
2315 IDirectDrawSurface4Impl_AddAttachedSurface,
2316 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2317 IDirectDrawSurface4Impl_Blt,
2318 IDirectDrawSurface4Impl_BltBatch,
2319 IDirectDrawSurface4Impl_BltFast,
2320 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2321 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2322 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2323 DGA2_IDirectDrawSurface4Impl_Flip,
2324 IDirectDrawSurface4Impl_GetAttachedSurface,
2325 IDirectDrawSurface4Impl_GetBltStatus,
2326 IDirectDrawSurface4Impl_GetCaps,
2327 IDirectDrawSurface4Impl_GetClipper,
2328 IDirectDrawSurface4Impl_GetColorKey,
2329 IDirectDrawSurface4Impl_GetDC,
2330 IDirectDrawSurface4Impl_GetFlipStatus,
2331 IDirectDrawSurface4Impl_GetOverlayPosition,
2332 IDirectDrawSurface4Impl_GetPalette,
2333 IDirectDrawSurface4Impl_GetPixelFormat,
2334 IDirectDrawSurface4Impl_GetSurfaceDesc,
2335 IDirectDrawSurface4Impl_Initialize,
2336 IDirectDrawSurface4Impl_IsLost,
2337 IDirectDrawSurface4Impl_Lock,
2338 IDirectDrawSurface4Impl_ReleaseDC,
2339 IDirectDrawSurface4Impl_Restore,
2340 IDirectDrawSurface4Impl_SetClipper,
2341 IDirectDrawSurface4Impl_SetColorKey,
2342 IDirectDrawSurface4Impl_SetOverlayPosition,
2343 DGA_IDirectDrawSurface4Impl_SetPalette,
2344 DGA_IDirectDrawSurface4Impl_Unlock,
2345 IDirectDrawSurface4Impl_UpdateOverlay,
2346 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2347 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2348 IDirectDrawSurface4Impl_GetDDInterface,
2349 IDirectDrawSurface4Impl_PageLock,
2350 IDirectDrawSurface4Impl_PageUnlock,
2351 IDirectDrawSurface4Impl_SetSurfaceDesc,
2352 IDirectDrawSurface4Impl_SetPrivateData,
2353 IDirectDrawSurface4Impl_GetPrivateData,
2354 IDirectDrawSurface4Impl_FreePrivateData,
2355 IDirectDrawSurface4Impl_GetUniquenessValue,
2356 IDirectDrawSurface4Impl_ChangeUniquenessValue
2358 #endif /* defined(HAVE_LIBXXF86DGA2) */
2360 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2362 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2363 IDirectDrawSurface4Impl_QueryInterface,
2364 IDirectDrawSurface4Impl_AddRef,
2365 Xlib_IDirectDrawSurface4Impl_Release,
2366 IDirectDrawSurface4Impl_AddAttachedSurface,
2367 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2368 IDirectDrawSurface4Impl_Blt,
2369 IDirectDrawSurface4Impl_BltBatch,
2370 IDirectDrawSurface4Impl_BltFast,
2371 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2372 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2373 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2374 Xlib_IDirectDrawSurface4Impl_Flip,
2375 IDirectDrawSurface4Impl_GetAttachedSurface,
2376 IDirectDrawSurface4Impl_GetBltStatus,
2377 IDirectDrawSurface4Impl_GetCaps,
2378 IDirectDrawSurface4Impl_GetClipper,
2379 IDirectDrawSurface4Impl_GetColorKey,
2380 IDirectDrawSurface4Impl_GetDC,
2381 IDirectDrawSurface4Impl_GetFlipStatus,
2382 IDirectDrawSurface4Impl_GetOverlayPosition,
2383 IDirectDrawSurface4Impl_GetPalette,
2384 IDirectDrawSurface4Impl_GetPixelFormat,
2385 IDirectDrawSurface4Impl_GetSurfaceDesc,
2386 IDirectDrawSurface4Impl_Initialize,
2387 IDirectDrawSurface4Impl_IsLost,
2388 IDirectDrawSurface4Impl_Lock,
2389 IDirectDrawSurface4Impl_ReleaseDC,
2390 IDirectDrawSurface4Impl_Restore,
2391 IDirectDrawSurface4Impl_SetClipper,
2392 IDirectDrawSurface4Impl_SetColorKey,
2393 IDirectDrawSurface4Impl_SetOverlayPosition,
2394 Xlib_IDirectDrawSurface4Impl_SetPalette,
2395 Xlib_IDirectDrawSurface4Impl_Unlock,
2396 IDirectDrawSurface4Impl_UpdateOverlay,
2397 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2398 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2399 IDirectDrawSurface4Impl_GetDDInterface,
2400 IDirectDrawSurface4Impl_PageLock,
2401 IDirectDrawSurface4Impl_PageUnlock,
2402 IDirectDrawSurface4Impl_SetSurfaceDesc,
2403 IDirectDrawSurface4Impl_SetPrivateData,
2404 IDirectDrawSurface4Impl_GetPrivateData,
2405 IDirectDrawSurface4Impl_FreePrivateData,
2406 IDirectDrawSurface4Impl_GetUniquenessValue,
2407 IDirectDrawSurface4Impl_ChangeUniquenessValue
2410 /******************************************************************************
2411 * DirectDrawCreateClipper (DDRAW.7)
2413 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2414 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2415 LPUNKNOWN pUnkOuter)
2417 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2418 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2420 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2421 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2422 (*ilplpDDClipper)->ref = 1;
2424 (*ilplpDDClipper)->hWnd = 0;
2426 return DD_OK;
2429 /******************************************************************************
2430 * IDirectDrawClipper
2432 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2433 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
2435 ICOM_THIS(IDirectDrawClipperImpl,iface);
2437 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
2438 if( dwFlags ) {
2439 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
2440 return DDERR_INVALIDPARAMS;
2443 This->hWnd = hWnd;
2444 return DD_OK;
2447 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2448 ICOM_THIS(IDirectDrawClipperImpl,iface);
2449 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2451 This->ref--;
2452 if (This->ref)
2453 return This->ref;
2454 HeapFree(GetProcessHeap(),0,This);
2455 return S_OK;
2458 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2459 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2461 ICOM_THIS(IDirectDrawClipperImpl,iface);
2462 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2463 if (hmm) *hmm=0;
2464 return DD_OK;
2467 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2468 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2470 ICOM_THIS(IDirectDrawClipperImpl,iface);
2471 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2472 return DD_OK;
2475 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2476 LPDIRECTDRAWCLIPPER iface,
2477 REFIID riid,
2478 LPVOID* ppvObj )
2480 ICOM_THIS(IDirectDrawClipperImpl,iface);
2481 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2482 return OLE_E_ENUM_NOMORE;
2485 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2487 ICOM_THIS(IDirectDrawClipperImpl,iface);
2488 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2489 return ++(This->ref);
2492 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2493 LPDIRECTDRAWCLIPPER iface,
2494 HWND* hWndPtr )
2496 ICOM_THIS(IDirectDrawClipperImpl,iface);
2497 FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
2499 *hWndPtr = This->hWnd;
2501 return DD_OK;
2504 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2505 LPDIRECTDRAWCLIPPER iface,
2506 LPDIRECTDRAW lpDD,
2507 DWORD dwFlags )
2509 ICOM_THIS(IDirectDrawClipperImpl,iface);
2510 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2511 return DD_OK;
2514 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2515 LPDIRECTDRAWCLIPPER iface,
2516 BOOL* lpbChanged )
2518 ICOM_THIS(IDirectDrawClipperImpl,iface);
2519 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2520 return DD_OK;
2523 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2525 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2526 IDirectDrawClipperImpl_QueryInterface,
2527 IDirectDrawClipperImpl_AddRef,
2528 IDirectDrawClipperImpl_Release,
2529 IDirectDrawClipperImpl_GetClipList,
2530 IDirectDrawClipperImpl_GetHWnd,
2531 IDirectDrawClipperImpl_Initialize,
2532 IDirectDrawClipperImpl_IsClipListChanged,
2533 IDirectDrawClipperImpl_SetClipList,
2534 IDirectDrawClipperImpl_SetHwnd
2538 /******************************************************************************
2539 * IDirectDrawPalette
2541 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2542 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2544 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2545 int i;
2547 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2548 This,x,start,count,palent);
2550 /* No palette created and not in depth-convertion mode -> BUG ! */
2551 if ((This->cm == None) &&
2552 (This->ddraw->d.palette_convert == NULL))
2554 FIXME("app tried to read colormap for non-palettized mode\n");
2555 return DDERR_GENERIC;
2557 for (i=0;i<count;i++) {
2558 palent[i].peRed = This->palents[start+i].peRed;
2559 palent[i].peBlue = This->palents[start+i].peBlue;
2560 palent[i].peGreen = This->palents[start+i].peGreen;
2561 palent[i].peFlags = This->palents[start+i].peFlags;
2564 return DD_OK;
2567 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2568 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2570 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2571 XColor xc;
2572 int i;
2574 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2575 This,x,start,count,palent
2577 for (i=0;i<count;i++) {
2578 xc.red = palent[i].peRed<<8;
2579 xc.blue = palent[i].peBlue<<8;
2580 xc.green = palent[i].peGreen<<8;
2581 xc.flags = DoRed|DoBlue|DoGreen;
2582 xc.pixel = start+i;
2584 if (This->cm)
2585 TSXStoreColor(display,This->cm,&xc);
2587 This->palents[start+i].peRed = palent[i].peRed;
2588 This->palents[start+i].peBlue = palent[i].peBlue;
2589 This->palents[start+i].peGreen = palent[i].peGreen;
2590 This->palents[start+i].peFlags = palent[i].peFlags;
2593 /* Now, if we are in 'depth conversion mode', update the screen palette */
2594 /* FIXME: we need to update the image or we won't get palette fading. */
2595 if (This->ddraw->d.palette_convert != NULL)
2596 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2598 return DD_OK;
2601 #ifdef HAVE_LIBXXF86DGA
2602 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2603 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2605 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2606 XColor xc;
2607 Colormap cm;
2608 int i;
2610 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2611 This,x,start,count,palent
2613 if (!This->cm) /* should not happen */ {
2614 FIXME("app tried to set colormap in non-palettized mode\n");
2615 return DDERR_GENERIC;
2617 /* FIXME: free colorcells instead of freeing whole map */
2618 cm = This->cm;
2619 This->cm = TSXCopyColormapAndFree(display,This->cm);
2620 TSXFreeColormap(display,cm);
2622 for (i=0;i<count;i++) {
2623 xc.red = palent[i].peRed<<8;
2624 xc.blue = palent[i].peBlue<<8;
2625 xc.green = palent[i].peGreen<<8;
2626 xc.flags = DoRed|DoBlue|DoGreen;
2627 xc.pixel = i+start;
2629 TSXStoreColor(display,This->cm,&xc);
2631 This->palents[start+i].peRed = palent[i].peRed;
2632 This->palents[start+i].peBlue = palent[i].peBlue;
2633 This->palents[start+i].peGreen = palent[i].peGreen;
2634 This->palents[start+i].peFlags = palent[i].peFlags;
2636 #ifdef HAVE_LIBXXF86DGA2
2637 if (This->ddraw->e.dga.version == 2)
2638 TSXDGAInstallColormap(display,DefaultScreen(display),This->cm);
2639 else
2640 #endif /* defined(HAVE_LIBXXF86DGA2) */
2641 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2642 return DD_OK;
2644 #endif /* defined(HAVE_LIBXXF86DGA) */
2646 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2647 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2648 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2649 if (!--(This->ref)) {
2650 if (This->cm) {
2651 TSXFreeColormap(display,This->cm);
2652 This->cm = 0;
2654 HeapFree(GetProcessHeap(),0,This);
2655 return S_OK;
2657 return This->ref;
2660 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2661 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2663 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2664 return ++(This->ref);
2667 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2668 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2670 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2671 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2673 return DDERR_ALREADYINITIALIZED;
2676 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2677 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2679 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2680 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2681 return DD_OK;
2684 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2685 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2687 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2689 FIXME("(%p)->(%s,%p) stub.\n",This,debugstr_guid(refiid),obj);
2691 return S_OK;
2694 #ifdef HAVE_LIBXXF86DGA
2695 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2697 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2698 IDirectDrawPaletteImpl_QueryInterface,
2699 IDirectDrawPaletteImpl_AddRef,
2700 IDirectDrawPaletteImpl_Release,
2701 IDirectDrawPaletteImpl_GetCaps,
2702 IDirectDrawPaletteImpl_GetEntries,
2703 IDirectDrawPaletteImpl_Initialize,
2704 DGA_IDirectDrawPaletteImpl_SetEntries
2706 #endif /* defined(HAVE_LIBXXF86DGA) */
2708 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2710 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2711 IDirectDrawPaletteImpl_QueryInterface,
2712 IDirectDrawPaletteImpl_AddRef,
2713 IDirectDrawPaletteImpl_Release,
2714 IDirectDrawPaletteImpl_GetCaps,
2715 IDirectDrawPaletteImpl_GetEntries,
2716 IDirectDrawPaletteImpl_Initialize,
2717 Xlib_IDirectDrawPaletteImpl_SetEntries
2720 /*******************************************************************************
2721 * IDirect3D
2723 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2724 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2726 ICOM_THIS(IDirect3DImpl,iface);
2727 /* FIXME: Not sure if this is correct */
2729 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2730 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2731 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2732 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2733 *obj = This->ddraw;
2734 IDirect3D_AddRef(iface);
2736 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2738 return S_OK;
2740 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2741 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2742 *obj = This;
2743 IDirect3D_AddRef(iface);
2745 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2747 return S_OK;
2749 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2750 IDirect3D2Impl* d3d;
2752 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2753 d3d->ref = 1;
2754 d3d->ddraw = This->ddraw;
2755 IDirect3D_AddRef(iface);
2756 ICOM_VTBL(d3d) = &d3d2vt;
2757 *obj = d3d;
2759 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2761 return S_OK;
2763 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2764 return OLE_E_ENUM_NOMORE;
2767 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2768 ICOM_THIS(IDirect3DImpl,iface);
2769 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2771 return ++(This->ref);
2774 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2776 ICOM_THIS(IDirect3DImpl,iface);
2777 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2779 if (!--(This->ref)) {
2780 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2781 HeapFree(GetProcessHeap(),0,This);
2782 return S_OK;
2784 return This->ref;
2787 static HRESULT WINAPI IDirect3DImpl_Initialize(
2788 LPDIRECT3D iface, REFIID refiid )
2790 ICOM_THIS(IDirect3DImpl,iface);
2791 /* FIXME: Not sure if this is correct */
2793 FIXME("(%p)->(%s):stub.\n",This,debugstr_guid(refiid));
2795 return DDERR_ALREADYINITIALIZED;
2798 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2799 LPD3DENUMDEVICESCALLBACK cb,
2800 LPVOID context) {
2801 ICOM_THIS(IDirect3DImpl,iface);
2802 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2804 /* Call functions defined in d3ddevices.c */
2805 if (!d3d_OpenGL_dx3(cb, context))
2806 return DD_OK;
2808 return DD_OK;
2811 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2812 LPDIRECT3DLIGHT *lplight,
2813 IUnknown *lpunk)
2815 ICOM_THIS(IDirect3DImpl,iface);
2816 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2818 /* Call the creation function that is located in d3dlight.c */
2819 *lplight = d3dlight_create_dx3(This);
2821 return DD_OK;
2824 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2825 LPDIRECT3DMATERIAL *lpmaterial,
2826 IUnknown *lpunk)
2828 ICOM_THIS(IDirect3DImpl,iface);
2829 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2831 /* Call the creation function that is located in d3dviewport.c */
2832 *lpmaterial = d3dmaterial_create(This);
2834 return DD_OK;
2837 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2838 LPDIRECT3DVIEWPORT *lpviewport,
2839 IUnknown *lpunk)
2841 ICOM_THIS(IDirect3DImpl,iface);
2842 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2844 /* Call the creation function that is located in d3dviewport.c */
2845 *lpviewport = d3dviewport_create(This);
2847 return DD_OK;
2850 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2851 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2852 LPD3DFINDDEVICERESULT lpfinddevrst)
2854 ICOM_THIS(IDirect3DImpl,iface);
2855 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2857 return DD_OK;
2860 static ICOM_VTABLE(IDirect3D) d3dvt =
2862 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2863 IDirect3DImpl_QueryInterface,
2864 IDirect3DImpl_AddRef,
2865 IDirect3DImpl_Release,
2866 IDirect3DImpl_Initialize,
2867 IDirect3DImpl_EnumDevices,
2868 IDirect3DImpl_CreateLight,
2869 IDirect3DImpl_CreateMaterial,
2870 IDirect3DImpl_CreateViewport,
2871 IDirect3DImpl_FindDevice
2874 /*******************************************************************************
2875 * IDirect3D2
2877 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2878 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2879 ICOM_THIS(IDirect3D2Impl,iface);
2881 /* FIXME: Not sure if this is correct */
2883 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2884 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2885 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2886 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2887 *obj = This->ddraw;
2888 IDirect3D2_AddRef(iface);
2890 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2892 return S_OK;
2894 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2895 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2896 *obj = This;
2897 IDirect3D2_AddRef(iface);
2899 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2901 return S_OK;
2903 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2904 IDirect3DImpl* d3d;
2906 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2907 d3d->ref = 1;
2908 d3d->ddraw = This->ddraw;
2909 IDirect3D2_AddRef(iface);
2910 ICOM_VTBL(d3d) = &d3dvt;
2911 *obj = d3d;
2913 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2915 return S_OK;
2917 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2918 return OLE_E_ENUM_NOMORE;
2921 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2922 ICOM_THIS(IDirect3D2Impl,iface);
2923 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2925 return ++(This->ref);
2928 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2929 ICOM_THIS(IDirect3D2Impl,iface);
2930 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2932 if (!--(This->ref)) {
2933 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2934 HeapFree(GetProcessHeap(),0,This);
2935 return S_OK;
2937 return This->ref;
2940 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2941 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2943 ICOM_THIS(IDirect3D2Impl,iface);
2944 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2946 /* Call functions defined in d3ddevices.c */
2947 if (!d3d_OpenGL(cb, context))
2948 return DD_OK;
2950 return DD_OK;
2953 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2954 LPDIRECT3DLIGHT *lplight,
2955 IUnknown *lpunk)
2957 ICOM_THIS(IDirect3D2Impl,iface);
2958 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2960 /* Call the creation function that is located in d3dlight.c */
2961 *lplight = d3dlight_create(This);
2963 return DD_OK;
2966 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2967 LPDIRECT3DMATERIAL2 *lpmaterial,
2968 IUnknown *lpunk)
2970 ICOM_THIS(IDirect3D2Impl,iface);
2971 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2973 /* Call the creation function that is located in d3dviewport.c */
2974 *lpmaterial = d3dmaterial2_create(This);
2976 return DD_OK;
2979 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2980 LPDIRECT3DVIEWPORT2 *lpviewport,
2981 IUnknown *lpunk)
2983 ICOM_THIS(IDirect3D2Impl,iface);
2984 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2986 /* Call the creation function that is located in d3dviewport.c */
2987 *lpviewport = d3dviewport2_create(This);
2989 return DD_OK;
2992 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2993 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2994 LPD3DFINDDEVICERESULT lpfinddevrst)
2996 ICOM_THIS(IDirect3D2Impl,iface);
2997 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2999 return DD_OK;
3002 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
3003 REFCLSID rguid,
3004 LPDIRECTDRAWSURFACE surface,
3005 LPDIRECT3DDEVICE2 *device)
3007 ICOM_THIS(IDirect3D2Impl,iface);
3009 FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
3011 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
3012 IDirect3D2_AddRef(iface);
3013 return DD_OK;
3016 return DDERR_INVALIDPARAMS;
3019 static ICOM_VTABLE(IDirect3D2) d3d2vt =
3021 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3022 IDirect3D2Impl_QueryInterface,
3023 IDirect3D2Impl_AddRef,
3024 IDirect3D2Impl_Release,
3025 IDirect3D2Impl_EnumDevices,
3026 IDirect3D2Impl_CreateLight,
3027 IDirect3D2Impl_CreateMaterial,
3028 IDirect3D2Impl_CreateViewport,
3029 IDirect3D2Impl_FindDevice,
3030 IDirect3D2Impl_CreateDevice
3033 /*******************************************************************************
3034 * IDirectDraw
3037 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
3038 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
3040 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
3041 IDirectDrawSurfaceImpl* lpdsf)
3043 int bpp;
3045 /* The surface was already allocated when entering in this function */
3046 TRACE("using system memory for a surface (%p) \n", lpdsf);
3048 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
3049 /* This is a Z Buffer */
3050 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
3051 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
3052 } else {
3053 /* This is a standard image */
3054 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
3055 /* No pixel format => use DirectDraw's format */
3056 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3057 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
3059 bpp = GET_BPP(lpdsf->s.surface_desc);
3062 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
3063 /* The surface was preallocated : seems that we have nothing to do :-) */
3064 ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
3067 assert(bpp);
3068 FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf->s.surface_desc.dwWidth,lpdsf->s.surface_desc.dwHeight,bpp);
3070 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
3071 lpdsf->s.surface_desc.u1.lpSurface =
3072 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
3073 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
3075 return DD_OK;
3078 #ifdef HAVE_LIBXXF86DGA
3079 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
3080 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3082 ICOM_THIS(IDirectDraw2Impl,iface);
3083 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3084 int i, fbheight = This->e.dga.fb_height;
3086 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
3087 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3089 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3090 GetProcessHeap(),
3091 HEAP_ZERO_MEMORY,
3092 sizeof(IDirectDrawSurfaceImpl)
3094 IDirectDraw2_AddRef(iface);
3096 (*ilpdsf)->ref = 1;
3097 #ifdef HAVE_LIBXXF86DGA2
3098 if (This->e.dga.version == 2)
3099 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
3100 else
3101 #endif /* defined(HAVE_LIBXXF86DGA2) */
3102 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
3103 (*ilpdsf)->s.ddraw = This;
3104 (*ilpdsf)->s.palette = NULL;
3105 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
3106 (*ilpdsf)->s.lpClipper = NULL;
3108 /* Copy the surface description */
3109 (*ilpdsf)->s.surface_desc = *lpddsd;
3111 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3112 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3113 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3114 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3116 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3118 /* Check if this a 'primary surface' or not */
3119 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3120 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3121 /* This is THE primary surface => there is DGA-specific code */
3123 /* First, store the surface description */
3124 (*ilpdsf)->s.surface_desc = *lpddsd;
3126 /* Find a viewport */
3127 for (i=0;i<32;i++)
3128 if (!(This->e.dga.vpmask & (1<<i)))
3129 break;
3130 TRACE("using viewport %d for a primary surface\n",i);
3131 /* if i == 32 or maximum ... return error */
3132 This->e.dga.vpmask|=(1<<i);
3133 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
3134 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
3136 (*ilpdsf)->s.surface_desc.u1.lpSurface =
3137 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3139 (*ilpdsf)->t.dga.fb_height = i*fbheight;
3141 /* Add flags if there were not present */
3142 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3143 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3144 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3145 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
3146 /* We put our surface always in video memory */
3147 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3148 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3149 (*ilpdsf)->s.chain = NULL;
3151 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3152 IDirectDrawSurface4Impl* back;
3153 int bbc;
3155 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
3156 int i;
3158 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3159 GetProcessHeap(),
3160 HEAP_ZERO_MEMORY,
3161 sizeof(IDirectDrawSurface4Impl)
3163 IDirectDraw2_AddRef(iface);
3164 back->ref = 1;
3165 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
3166 for (i=0;i<32;i++)
3167 if (!(This->e.dga.vpmask & (1<<i)))
3168 break;
3169 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
3170 /* if i == 32 or maximum ... return error */
3171 This->e.dga.vpmask|=(1<<i);
3172 back->t.dga.fb_height = i*fbheight;
3173 /* Copy the surface description from the front buffer */
3174 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3175 /* Change the parameters that are not the same */
3176 back->s.surface_desc.u1.lpSurface =
3177 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3179 back->s.ddraw = This;
3180 /* Add relevant info to front and back buffers */
3181 /* FIXME: backbuffer/frontbuffer handling broken here, but
3182 * will be fixed up in _Flip().
3184 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3185 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
3186 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3187 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3188 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3191 } else {
3192 /* There is no DGA-specific code here...
3193 Go to the common surface creation function */
3194 return common_off_screen_CreateSurface(This, *ilpdsf);
3196 return DD_OK;
3198 #endif /* defined(HAVE_LIBXXF86DGA) */
3200 #ifdef HAVE_LIBXXSHM
3201 /* Error handlers for Image creation */
3202 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
3203 XShmErrorFlag = 1;
3204 return 0;
3207 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3208 XImage *img;
3209 int (*WineXHandler)(Display *, XErrorEvent *);
3211 img = TSXShmCreateImage(display,
3212 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3213 This->d.pixmap_depth,
3214 ZPixmap,
3215 NULL,
3216 &(lpdsf->t.xlib.shminfo),
3217 lpdsf->s.surface_desc.dwWidth,
3218 lpdsf->s.surface_desc.dwHeight
3221 if (img == NULL) {
3222 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3223 This->e.xlib.xshm_active = 0;
3224 return NULL;
3227 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3228 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3229 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3230 This->e.xlib.xshm_active = 0;
3231 TSXDestroyImage(img);
3232 return NULL;
3235 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3237 if (img->data == (char *) -1) {
3238 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3239 This->e.xlib.xshm_active = 0;
3240 TSXDestroyImage(img);
3241 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3242 return NULL;
3244 lpdsf->t.xlib.shminfo.readOnly = False;
3246 /* This is where things start to get trickier....
3247 * First, we flush the current X connections to be sure to catch all
3248 * non-XShm related errors
3250 TSXSync(display, False);
3251 /* Then we enter in the non-thread safe part of the tests */
3252 EnterCriticalSection( &X11DRV_CritSection );
3254 /* Reset the error flag, sets our new error handler and try to attach
3255 * the surface
3257 XShmErrorFlag = 0;
3258 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3259 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3260 XSync(display, False);
3262 /* Check the error flag */
3263 if (XShmErrorFlag) {
3264 /* An error occured */
3265 XFlush(display);
3266 XShmErrorFlag = 0;
3267 XDestroyImage(img);
3268 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3269 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3270 XSetErrorHandler(WineXHandler);
3272 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3273 This->e.xlib.xshm_active = 0;
3275 /* Leave the critical section */
3276 LeaveCriticalSection( &X11DRV_CritSection );
3277 return NULL;
3279 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3280 * this works, but it may be a bit overkill....
3282 XSetErrorHandler(WineXHandler);
3283 LeaveCriticalSection( &X11DRV_CritSection );
3285 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3287 if (This->d.pixel_convert != NULL) {
3288 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3289 GetProcessHeap(),
3290 HEAP_ZERO_MEMORY,
3291 lpdsf->s.surface_desc.dwWidth *
3292 lpdsf->s.surface_desc.dwHeight *
3293 PFGET_BPP(This->d.directdraw_pixelformat)
3295 } else {
3296 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3298 return img;
3300 #endif /* HAVE_LIBXXSHM */
3302 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3303 XImage *img = NULL;
3304 void *img_data;
3306 #ifdef HAVE_LIBXXSHM
3307 if (This->e.xlib.xshm_active)
3308 img = create_xshmimage(This, lpdsf);
3310 if (img == NULL) {
3311 #endif
3312 /* Allocate surface memory */
3313 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3314 GetProcessHeap(),HEAP_ZERO_MEMORY,
3315 lpdsf->s.surface_desc.dwWidth *
3316 lpdsf->s.surface_desc.dwHeight *
3317 PFGET_BPP(This->d.directdraw_pixelformat)
3320 if (This->d.pixel_convert != NULL) {
3321 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3322 lpdsf->s.surface_desc.dwWidth *
3323 lpdsf->s.surface_desc.dwHeight *
3324 PFGET_BPP(This->d.screen_pixelformat)
3326 } else {
3327 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3330 /* In this case, create an XImage */
3331 img = TSXCreateImage(display,
3332 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3333 This->d.pixmap_depth,
3334 ZPixmap,
3336 img_data,
3337 lpdsf->s.surface_desc.dwWidth,
3338 lpdsf->s.surface_desc.dwHeight,
3340 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3342 #ifdef HAVE_LIBXXSHM
3344 #endif
3345 if (This->d.pixel_convert != NULL)
3346 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3347 else
3348 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3349 return img;
3352 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3353 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3355 ICOM_THIS(IDirectDraw2Impl,iface);
3356 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3358 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3360 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3362 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3363 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3366 IDirectDraw2_AddRef(iface);
3368 (*ilpdsf)->s.ddraw = This;
3369 (*ilpdsf)->ref = 1;
3370 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3371 (*ilpdsf)->s.palette = NULL;
3372 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3373 (*ilpdsf)->s.lpClipper = NULL;
3375 /* Copy the surface description */
3376 (*ilpdsf)->s.surface_desc = *lpddsd;
3378 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3379 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3380 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3381 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3382 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3384 /* Check if this a 'primary surface' or not */
3385 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3386 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3387 XImage *img;
3389 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3390 /* Create the XImage */
3391 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3392 if (img == NULL)
3393 return DDERR_OUTOFMEMORY;
3394 (*ilpdsf)->t.xlib.image = img;
3396 /* Add flags if there were not present */
3397 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3398 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3399 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3400 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3401 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3403 /* Check for backbuffers */
3404 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3405 IDirectDrawSurface4Impl* back;
3406 XImage *img;
3407 int i;
3409 for (i=lpddsd->dwBackBufferCount;i--;) {
3410 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3411 GetProcessHeap(),HEAP_ZERO_MEMORY,
3412 sizeof(IDirectDrawSurface4Impl)
3415 TRACE("allocated back-buffer (%p)\n", back);
3417 IDirectDraw2_AddRef(iface);
3418 back->s.ddraw = This;
3420 back->ref = 1;
3421 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3422 /* Copy the surface description from the front buffer */
3423 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3425 /* Create the XImage */
3426 img = create_ximage(This, back);
3427 if (img == NULL)
3428 return DDERR_OUTOFMEMORY;
3429 back->t.xlib.image = img;
3431 /* Add relevant info to front and back buffers */
3432 /* FIXME: backbuffer/frontbuffer handling broken here, but
3433 * will be fixed up in _Flip().
3435 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3436 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3437 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3438 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3439 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3442 } else {
3443 /* There is no Xlib-specific code here...
3444 Go to the common surface creation function */
3445 return common_off_screen_CreateSurface(This, *ilpdsf);
3447 return DD_OK;
3450 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3451 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3453 ICOM_THIS(IDirectDraw2Impl,iface);
3454 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3455 *dst = src; /* FIXME */
3456 return DD_OK;
3460 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3461 * even when the approbiate bitmasks are not specified.
3463 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3464 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3466 ICOM_THIS(IDirectDraw2Impl,iface);
3467 int i;
3468 const struct {
3469 int mask;
3470 char *name;
3471 } flags[] = {
3472 #define FE(x) { x, #x},
3473 FE(DDSCL_FULLSCREEN)
3474 FE(DDSCL_ALLOWREBOOT)
3475 FE(DDSCL_NOWINDOWCHANGES)
3476 FE(DDSCL_NORMAL)
3477 FE(DDSCL_ALLOWMODEX)
3478 FE(DDSCL_EXCLUSIVE)
3479 FE(DDSCL_SETFOCUSWINDOW)
3480 FE(DDSCL_SETDEVICEWINDOW)
3481 FE(DDSCL_CREATEDEVICEWINDOW)
3482 #undef FE
3485 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3486 if (TRACE_ON(ddraw)) {
3487 DPRINTF(" - ");
3488 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
3489 if (flags[i].mask & cooplevel) {
3490 DPRINTF("%s ",flags[i].name);
3493 DPRINTF("\n");
3495 This->d.mainWindow = hwnd;
3497 /* This will be overwritten in the case of Full Screen mode.
3498 Windowed games could work with that :-) */
3499 if (hwnd)
3501 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3502 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3503 WIN_ReleaseWndPtr(tmpWnd);
3505 if( !This->d.drawable ) {
3506 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3507 WIN_ReleaseDesktop();
3509 TRACE("Setting drawable to %ld\n", This->d.drawable);
3512 return DD_OK;
3515 #ifdef HAVE_LIBXXF86DGA2
3516 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel(
3517 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3519 ICOM_THIS(IDirectDraw2Impl,iface);
3520 HRESULT ret;
3521 int evbase, erbase;
3523 ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel);
3525 if (This->e.dga.version != 2) {
3526 return ret;
3527 } else {
3528 if (ret != DD_OK)
3529 return ret;
3531 TSXDGAQueryExtension(display, &evbase, &erbase);
3533 /* Now, start handling of DGA events giving the handle to the DDraw window
3534 as the window for which the event will be reported */
3535 TSXDGASelectInput(display, DefaultScreen(display),
3536 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3537 X11DRV_EVENT_SetDGAStatus(hwnd, evbase);
3539 return DD_OK;
3542 #endif
3544 /* Small helper to either use the cooperative window or create a new
3545 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3547 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3548 RECT rect;
3550 /* Do destroy only our window */
3551 if (This->d.window && GetPropA(This->d.window,ddProp)) {
3552 DestroyWindow(This->d.window);
3553 This->d.window = 0;
3555 /* Sanity check cooperative window before assigning it to drawing. */
3556 if ( IsWindow(This->d.mainWindow) &&
3557 IsWindowVisible(This->d.mainWindow)
3559 /* if it does not fit, resize the cooperative window.
3560 * and hope the app likes it
3562 GetWindowRect(This->d.mainWindow,&rect);
3563 if ((((rect.right-rect.left) >= This->d.width) &&
3564 ((rect.bottom-rect.top) >= This->d.height))
3566 This->d.window = This->d.mainWindow;
3567 /* SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOOWNERZORDER); */
3568 This->d.paintable = 1;
3571 /* ... failed, create new one. */
3572 if (!This->d.window) {
3573 This->d.window = CreateWindowExA(
3575 "WINE_DirectDraw",
3576 "WINE_DirectDraw",
3577 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3578 0,0,
3579 This->d.width,
3580 This->d.height,
3584 NULL
3586 /*Store THIS with the window. We'll use it in the window procedure*/
3587 SetPropA(This->d.window,ddProp,(LONG)This);
3588 ShowWindow(This->d.window,TRUE);
3589 UpdateWindow(This->d.window);
3591 SetFocus(This->d.window);
3594 static int _common_depth_to_pixelformat(DWORD depth,
3595 DDPIXELFORMAT *pixelformat,
3596 DDPIXELFORMAT *screen_pixelformat,
3597 int *pix_depth) {
3598 XVisualInfo *vi;
3599 XPixmapFormatValues *pf;
3600 XVisualInfo vt;
3601 int nvisuals, npixmap, i;
3602 int match = 0;
3603 int index = -2;
3605 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3606 pf = XListPixmapFormats(display, &npixmap);
3608 for (i = 0; i < npixmap; i++) {
3609 if (pf[i].depth == depth) {
3610 int j;
3612 for (j = 0; j < nvisuals; j++) {
3613 if (vi[j].depth == pf[i].depth) {
3614 pixelformat->dwSize = sizeof(*pixelformat);
3615 if (depth == 8) {
3616 pixelformat->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
3617 pixelformat->u1.dwRBitMask = 0;
3618 pixelformat->u2.dwGBitMask = 0;
3619 pixelformat->u3.dwBBitMask = 0;
3620 } else {
3621 pixelformat->dwFlags = DDPF_RGB;
3622 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3623 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3624 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3626 pixelformat->dwFourCC = 0;
3627 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3628 pixelformat->u4.dwRGBAlphaBitMask= 0;
3630 *screen_pixelformat = *pixelformat;
3632 if (pix_depth != NULL)
3633 *pix_depth = vi[j].depth;
3635 match = 1;
3636 index = -1;
3638 goto clean_up_and_exit;
3642 ERR("No visual corresponding to pixmap format !\n");
3646 if (match == 0) {
3647 /* We try now to find an emulated mode */
3648 int c;
3650 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3651 if (ModeEmulations[c].dest.depth == depth) {
3652 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3653 for (i = 0; i < npixmap; i++) {
3654 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3655 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3656 int j;
3658 for (j = 0; j < nvisuals; j++) {
3659 if (vi[j].depth == pf[i].depth) {
3660 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3661 screen_pixelformat->dwFlags = DDPF_RGB;
3662 screen_pixelformat->dwFourCC = 0;
3663 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3664 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3665 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3666 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3667 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3669 pixelformat->dwSize = sizeof(*pixelformat);
3670 pixelformat->dwFourCC = 0;
3671 if (depth == 8) {
3672 pixelformat->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
3673 pixelformat->u.dwRGBBitCount = 8;
3674 pixelformat->u1.dwRBitMask = 0;
3675 pixelformat->u2.dwGBitMask = 0;
3676 pixelformat->u3.dwBBitMask = 0;
3677 } else {
3678 pixelformat->dwFlags = DDPF_RGB;
3679 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3680 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3681 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3682 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3684 pixelformat->u4.dwRGBAlphaBitMask= 0;
3686 if (pix_depth != NULL)
3687 *pix_depth = vi[j].depth;
3689 match = 2;
3690 index = c;
3692 goto clean_up_and_exit;
3695 ERR("No visual corresponding to pixmap format !\n");
3703 clean_up_and_exit:
3704 TSXFree(vi);
3705 TSXFree(pf);
3707 return index;
3710 #ifdef HAVE_LIBXXF86DGA2
3711 static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl *This, int mode) {
3712 DDPIXELFORMAT *pf = &(This->d.directdraw_pixelformat);
3714 /* Now, get the device / mode description */
3715 This->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode);
3717 This->e.dga.fb_width = This->e.dga.dev->mode.imageWidth;
3718 TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
3719 This->e.dga.fb_height = This->e.dga.dev->mode.viewportHeight;
3720 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
3721 This->e.dga.dev->data,
3722 This->e.dga.dev->mode.imageWidth,
3723 (This->e.dga.dev->mode.imageWidth *
3724 This->e.dga.dev->mode.imageHeight *
3725 (This->e.dga.dev->mode.bitsPerPixel / 8))
3727 TRACE("viewport height: %d\n", This->e.dga.dev->mode.viewportHeight);
3728 /* Get the screen dimensions as seen by Wine.
3729 In that case, it may be better to ignore the -desktop mode and return the
3730 real screen size => print a warning */
3731 This->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3732 This->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3733 This->e.dga.fb_addr = This->e.dga.dev->data;
3734 This->e.dga.fb_memsize = (This->e.dga.dev->mode.imageWidth *
3735 This->e.dga.dev->mode.imageHeight *
3736 (This->e.dga.dev->mode.bitsPerPixel / 8));
3737 This->e.dga.vpmask = 0;
3739 /* Fill the screen pixelformat */
3740 pf->dwSize = sizeof(DDPIXELFORMAT);
3741 pf->dwFourCC = 0;
3742 pf->u.dwRGBBitCount = This->e.dga.dev->mode.bitsPerPixel;
3743 if (This->e.dga.dev->mode.depth == 8) {
3744 pf->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
3745 pf->u1.dwRBitMask = 0;
3746 pf->u2.dwGBitMask = 0;
3747 pf->u3.dwBBitMask = 0;
3748 } else {
3749 pf->dwFlags = DDPF_RGB;
3750 pf->u1.dwRBitMask = This->e.dga.dev->mode.redMask;
3751 pf->u2.dwGBitMask = This->e.dga.dev->mode.greenMask;
3752 pf->u3.dwBBitMask = This->e.dga.dev->mode.blueMask;
3754 pf->u4.dwRGBAlphaBitMask= 0;
3756 This->d.screen_pixelformat = *pf;
3758 #endif /* defined(HAVE_LIBXXF86DGA2) */
3760 #ifdef HAVE_LIBXXF86DGA
3761 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3762 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3764 ICOM_THIS(IDirectDrawImpl,iface);
3765 int i,mode_count;
3767 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3769 #ifdef HAVE_LIBXXF86DGA2
3770 if (This->e.dga.version == 2) {
3771 XDGAMode *modes = This->e.dga.modes;
3772 int mode_to_use = -1;
3774 /* Search in the list a display mode that corresponds to what is requested */
3775 for (i = 0; i < This->e.dga.num_modes; i++) {
3776 if ((height == modes[i].viewportHeight) &&
3777 (width == modes[i].viewportWidth) &&
3778 (depth == modes[i].depth)) {
3779 mode_to_use = modes[i].num;
3783 if (mode_to_use < 0) {
3784 ERR("Could not find matching mode !!!\n");
3785 return DDERR_UNSUPPORTEDMODE;
3786 } else {
3787 TRACE("Using mode number %d\n", mode_to_use);
3789 TSXDGACloseFramebuffer(display, DefaultScreen(display));
3791 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
3792 ERR("Error opening the frame buffer !!!\n");
3794 return DDERR_GENERIC;
3797 /* Initialize the frame buffer */
3798 _DGA_Initialize_FrameBuffer(This, mode_to_use);
3800 /* Re-get (if necessary) the DGA events */
3801 TSXDGASelectInput(display, DefaultScreen(display),
3802 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3805 return DD_OK;
3807 #endif /* defined(HAVE_LIBXXF86DGA2) */
3809 /* We hope getting the asked for depth */
3810 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3811 /* I.e. no visual found or emulated */
3812 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3813 return DDERR_UNSUPPORTEDMODE;
3816 if (This->d.width < width) {
3817 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3818 return DDERR_UNSUPPORTEDMODE;
3820 This->d.width = width;
3821 This->d.height = height;
3823 /* adjust fb_height, so we don't overlap */
3824 if (This->e.dga.fb_height < height)
3825 This->e.dga.fb_height = height;
3826 _common_IDirectDrawImpl_SetDisplayMode(This);
3828 #ifdef HAVE_LIBXXF86VM
3829 #ifdef HAVE_LIBXXF86DGA2
3830 if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3831 #endif /* defined(HAVE_LIBXXF86DGA2) */
3833 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3834 XF86VidModeModeLine mod_tmp;
3835 /* int dotclock_tmp; */
3837 /* save original video mode and set fullscreen if available*/
3838 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3839 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3840 orig_mode->hdisplay = mod_tmp.hdisplay;
3841 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3842 orig_mode->hsyncend = mod_tmp.hsyncend;
3843 orig_mode->htotal = mod_tmp.htotal;
3844 orig_mode->vdisplay = mod_tmp.vdisplay;
3845 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3846 orig_mode->vsyncend = mod_tmp.vsyncend;
3847 orig_mode->vtotal = mod_tmp.vtotal;
3848 orig_mode->flags = mod_tmp.flags;
3849 orig_mode->private = mod_tmp.private;
3851 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3852 for (i=0;i<mode_count;i++)
3854 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3856 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3857 *vidmode = *(all_modes[i]);
3858 break;
3859 } else
3860 TSXFree(all_modes[i]->private);
3862 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3863 TSXFree(all_modes);
3865 if (!vidmode)
3866 WARN("Fullscreen mode not available!\n");
3868 if (vidmode)
3870 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3871 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3872 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3873 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3874 #endif
3877 #endif
3879 /* FIXME: this function OVERWRITES several signal handlers.
3880 * can we save them? and restore them later? In a way that
3881 * it works for the library too?
3883 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3884 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3886 #ifdef RESTORE_SIGNALS
3887 SIGNAL_Init();
3888 #endif
3889 return DD_OK;
3891 #endif /* defined(HAVE_LIBXXF86DGA) */
3893 /* *************************************
3894 16 / 15 bpp to palettized 8 bpp
3895 ************************************* */
3896 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3897 unsigned char *c_src = (unsigned char *) src;
3898 unsigned short *c_dst = (unsigned short *) dst;
3899 int y;
3901 if (palette != NULL) {
3902 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3904 for (y = height; y--; ) {
3905 #if defined(__i386__) && defined(__GNUC__)
3906 /* gcc generates slightly inefficient code for the the copy / lookup,
3907 * it generates one excess memory access (to pal) per pixel. Since
3908 * we know that pal is not modified by the memory write we can
3909 * put it into a register and reduce the number of memory accesses
3910 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3911 * (This is not guaranteed to be the fastest method.)
3913 __asm__ __volatile__(
3914 "xor %%eax,%%eax\n"
3915 "1:\n"
3916 " lodsb\n"
3917 " movw (%%edx,%%eax,2),%%ax\n"
3918 " stosw\n"
3919 " xor %%eax,%%eax\n"
3920 " loop 1b\n"
3921 : "=S" (c_src), "=D" (c_dst)
3922 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3923 : "eax", "cc", "memory"
3925 c_src+=(pitch-width);
3926 #else
3927 unsigned char * srclineend = c_src+width;
3928 while (c_src < srclineend)
3929 *c_dst++ = pal[*c_src++];
3930 c_src+=(pitch-width);
3931 #endif
3933 } else {
3934 WARN("No palette set...\n");
3935 memset(dst, 0, width * height * 2);
3938 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3939 int i;
3940 unsigned short *pal = (unsigned short *) screen_palette;
3942 for (i = 0; i < count; i++)
3943 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3944 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3945 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3947 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3948 int i;
3949 unsigned short *pal = (unsigned short *) screen_palette;
3951 for (i = 0; i < count; i++)
3952 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3953 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3954 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3957 /* *************************************
3958 24 to palettized 8 bpp
3959 ************************************* */
3960 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3961 unsigned char *c_src = (unsigned char *) src;
3962 unsigned char *c_dst = (unsigned char *) dst;
3963 int y;
3965 if (palette != NULL) {
3966 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3968 for (y = height; y--; ) {
3969 unsigned char * srclineend = c_src+width;
3970 while (c_src < srclineend ) {
3971 register long pixel = pal[*c_src++];
3972 *c_dst++ = pixel;
3973 *c_dst++ = pixel>>8;
3974 *c_dst++ = pixel>>16;
3976 c_src+=(pitch-width);
3978 } else {
3979 WARN("No palette set...\n");
3980 memset(dst, 0, width * height * 4);
3983 /* *************************************
3984 32 bpp to palettized 8 bpp
3985 ************************************* */
3986 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3987 unsigned char *c_src = (unsigned char *) src;
3988 unsigned int *c_dst = (unsigned int *) dst;
3989 int y;
3991 if (palette != NULL) {
3992 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3994 for (y = height; y--; ) {
3995 #if defined(__i386__) && defined(__GNUC__)
3996 /* See comment in pixel_convert_16_to_8 */
3997 __asm__ __volatile__(
3998 "xor %%eax,%%eax\n"
3999 "1:\n"
4000 " lodsb\n"
4001 " movl (%%edx,%%eax,4),%%eax\n"
4002 " stosl\n"
4003 " xor %%eax,%%eax\n"
4004 " loop 1b\n"
4005 : "=S" (c_src), "=D" (c_dst)
4006 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
4007 : "eax", "cc", "memory"
4009 c_src+=(pitch-width);
4010 #else
4011 unsigned char * srclineend = c_src+width;
4012 while (c_src < srclineend )
4013 *c_dst++ = pal[*c_src++];
4014 c_src+=(pitch-width);
4015 #endif
4017 } else {
4018 WARN("No palette set...\n");
4019 memset(dst, 0, width * height * 4);
4023 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
4024 int i;
4025 unsigned int *pal = (unsigned int *) screen_palette;
4027 for (i = 0; i < count; i++)
4028 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
4029 (((unsigned int) palent[i].peGreen) << 8) |
4030 ((unsigned int) palent[i].peBlue));
4033 /* *************************************
4034 32 bpp to 16 bpp
4035 ************************************* */
4036 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4037 unsigned short *c_src = (unsigned short *) src;
4038 unsigned int *c_dst = (unsigned int *) dst;
4039 int y;
4041 for (y = height; y--; ) {
4042 unsigned short * srclineend = c_src+width;
4043 while (c_src < srclineend ) {
4044 *c_dst++ = (((*c_src & 0xF800) << 8) |
4045 ((*c_src & 0x07E0) << 5) |
4046 ((*c_src & 0x001F) << 3));
4047 c_src++;
4049 c_src+=((pitch/2)-width);
4054 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
4055 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
4057 ICOM_THIS(IDirectDrawImpl,iface);
4058 char buf[200];
4059 WND *tmpWnd;
4060 int c;
4062 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
4063 This, width, height, depth);
4065 switch ((c = _common_depth_to_pixelformat(depth,
4066 &(This->d.directdraw_pixelformat),
4067 &(This->d.screen_pixelformat),
4068 &(This->d.pixmap_depth)))) {
4069 case -2:
4070 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
4071 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
4072 return DDERR_UNSUPPORTEDMODE;
4074 case -1:
4075 /* No convertion */
4076 This->d.pixel_convert = NULL;
4077 This->d.palette_convert = NULL;
4078 break;
4080 default:
4081 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
4083 /* Set the depth convertion routines */
4084 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
4085 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
4088 This->d.width = width;
4089 This->d.height = height;
4091 _common_IDirectDrawImpl_SetDisplayMode(This);
4093 tmpWnd = WIN_FindWndPtr(This->d.window);
4094 This->d.paintable = 1;
4095 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
4096 WIN_ReleaseWndPtr(tmpWnd);
4098 /* We don't have a context for this window. Host off the desktop */
4099 if( !This->d.drawable )
4101 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
4102 WIN_ReleaseDesktop();
4104 TRACE("Setting drawable to %ld\n", This->d.drawable);
4106 if (Options.DXGrab) {
4107 /* Confine cursor movement (risky, but the user asked for it) */
4108 TSXGrabPointer(display, This->d.drawable, True, 0, GrabModeAsync, GrabModeAsync, This->d.drawable, None, CurrentTime);
4111 return DD_OK;
4114 #ifdef HAVE_LIBXXF86DGA
4115 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
4116 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4118 ICOM_THIS(IDirectDraw2Impl,iface);
4119 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4120 if (!caps1 && !caps2)
4121 return DDERR_INVALIDPARAMS;
4122 if (caps1) {
4123 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
4124 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4125 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4127 if (caps2) {
4128 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
4129 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4130 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4132 return DD_OK;
4134 #endif /* defined(HAVE_LIBXXF86DGA) */
4136 static void fill_caps(LPDDCAPS caps) {
4137 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4138 Need to be fixed, though.. */
4139 if (caps == NULL)
4140 return;
4142 caps->dwSize = sizeof(*caps);
4143 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
4144 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
4145 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
4146 caps->dwFXCaps = 0;
4147 caps->dwFXAlphaCaps = 0;
4148 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
4149 caps->dwSVCaps = 0;
4150 caps->dwZBufferBitDepths = DDBD_16;
4151 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4152 to put textures in video memory.
4153 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4154 for example) ? */
4155 caps->dwVidMemTotal = 8192 * 1024;
4156 caps->dwVidMemFree = 8192 * 1024;
4157 /* These are all the supported capabilities of the surfaces */
4158 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
4159 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
4160 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
4161 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
4162 #ifdef HAVE_MESAGL
4163 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
4164 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
4165 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
4166 #endif
4169 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
4170 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4172 ICOM_THIS(IDirectDraw2Impl,iface);
4173 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4175 /* Put the same caps for the two capabilities */
4176 fill_caps(caps1);
4177 fill_caps(caps2);
4179 return DD_OK;
4182 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
4183 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
4185 ICOM_THIS(IDirectDraw2Impl,iface);
4186 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
4187 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4188 This,x,ilpddclip,lpunk
4190 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
4191 (*ilpddclip)->ref = 1;
4192 ICOM_VTBL(*ilpddclip) = &ddclipvt;
4193 return DD_OK;
4196 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
4197 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
4199 int size = 0;
4201 if (TRACE_ON(ddraw))
4202 _dump_paletteformat(dwFlags);
4204 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
4205 if (*lpddpal == NULL) return E_OUTOFMEMORY;
4206 (*lpddpal)->ref = 1;
4207 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
4208 (*lpddpal)->installed = 0;
4210 if (dwFlags & DDPCAPS_1BIT)
4211 size = 2;
4212 else if (dwFlags & DDPCAPS_2BIT)
4213 size = 4;
4214 else if (dwFlags & DDPCAPS_4BIT)
4215 size = 16;
4216 else if (dwFlags & DDPCAPS_8BIT)
4217 size = 256;
4218 else
4219 ERR("unhandled palette format\n");
4220 *psize = size;
4222 if (palent)
4224 /* Now, if we are in 'depth conversion mode', create the screen palette */
4225 if (This->d.palette_convert != NULL)
4226 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
4228 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
4229 } else if (This->d.palette_convert != NULL) {
4230 /* In that case, put all 0xFF */
4231 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
4234 return DD_OK;
4237 #ifdef HAVE_LIBXXF86DGA
4238 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
4239 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4241 ICOM_THIS(IDirectDraw2Impl,iface);
4242 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4243 HRESULT res;
4244 int xsize = 0,i;
4246 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4247 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4248 if (res != 0) return res;
4249 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
4250 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
4251 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
4252 } else {
4253 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4254 (*ilpddpal)->cm = 0;
4256 if (((*ilpddpal)->cm)&&xsize) {
4257 for (i=0;i<xsize;i++) {
4258 XColor xc;
4260 xc.red = (*ilpddpal)->palents[i].peRed<<8;
4261 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
4262 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
4263 xc.flags = DoRed|DoBlue|DoGreen;
4264 xc.pixel = i;
4265 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
4268 return DD_OK;
4270 #endif /* defined(HAVE_LIBXXF86DGA) */
4272 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
4273 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4275 ICOM_THIS(IDirectDraw2Impl,iface);
4276 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4277 int xsize;
4278 HRESULT res;
4280 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4281 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4282 if (res != 0) return res;
4283 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
4284 return DD_OK;
4287 #ifdef HAVE_LIBXXF86DGA
4288 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4289 ICOM_THIS(IDirectDraw2Impl,iface);
4290 TRACE("(%p)->()\n",This);
4291 Sleep(1000);
4292 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4293 #ifdef RESTORE_SIGNALS
4294 SIGNAL_Init();
4295 #endif
4296 return DD_OK;
4298 #endif /* defined(HAVE_LIBXXF86DGA) */
4300 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4301 ICOM_THIS(IDirectDraw2Impl,iface);
4302 TRACE("(%p)->RestoreDisplayMode()\n", This);
4303 Sleep(1000);
4304 return DD_OK;
4307 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
4308 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
4310 ICOM_THIS(IDirectDraw2Impl,iface);
4311 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
4312 return DD_OK;
4315 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
4316 ICOM_THIS(IDirectDraw2Impl,iface);
4317 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
4319 return ++(This->ref);
4322 #ifdef HAVE_LIBXXF86DGA
4323 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4324 ICOM_THIS(IDirectDraw2Impl,iface);
4325 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4327 if (!--(This->ref)) {
4328 #ifdef HAVE_LIBXXF86DGA2
4329 if (This->e.dga.version == 2) {
4330 TRACE("Closing access to the FrameBuffer\n");
4331 TSXDGACloseFramebuffer(display, DefaultScreen(display));
4332 TRACE("Going back to normal X mode of operation\n");
4333 TSXDGASetMode(display, DefaultScreen(display), 0);
4335 /* Set the input handling back to absolute */
4336 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
4338 /* Remove the handling of DGA2 events */
4339 X11DRV_EVENT_SetDGAStatus(0, -1);
4341 /* Free the modes list */
4342 TSXFree(This->e.dga.modes);
4343 } else
4344 #endif /* defined(HAVE_LIBXXF86DGA2) */
4345 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4346 if (This->d.window && GetPropA(This->d.window,ddProp))
4347 DestroyWindow(This->d.window);
4348 #ifdef HAVE_LIBXXF86VM
4349 if (orig_mode) {
4350 TSXF86VidModeSwitchToMode(
4351 display,
4352 DefaultScreen(display),
4353 orig_mode);
4354 if (orig_mode->privsize)
4355 TSXFree(orig_mode->private);
4356 free(orig_mode);
4357 orig_mode = NULL;
4359 #endif
4361 #ifdef RESTORE_SIGNALS
4362 SIGNAL_Init();
4363 #endif
4364 HeapFree(GetProcessHeap(),0,This);
4365 return S_OK;
4367 return This->ref;
4369 #endif /* defined(HAVE_LIBXXF86DGA) */
4371 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4372 ICOM_THIS(IDirectDraw2Impl,iface);
4373 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4375 if (!--(This->ref)) {
4376 if (This->d.window && GetPropA(This->d.window,ddProp))
4377 DestroyWindow(This->d.window);
4378 HeapFree(GetProcessHeap(),0,This);
4379 return S_OK;
4381 /* FIXME: destroy window ... */
4382 return This->ref;
4385 #ifdef HAVE_LIBXXF86DGA
4386 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4387 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4389 ICOM_THIS(IDirectDraw2Impl,iface);
4391 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4392 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4393 *obj = This;
4394 IDirectDraw2_AddRef(iface);
4396 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4398 return S_OK;
4400 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4401 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4402 IDirectDraw2_AddRef(iface);
4403 *obj = This;
4405 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4407 return S_OK;
4409 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4410 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4411 IDirectDraw2_AddRef(iface);
4412 *obj = This;
4414 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4416 return S_OK;
4418 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4419 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4420 IDirectDraw2_AddRef(iface);
4421 *obj = This;
4423 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4425 return S_OK;
4427 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4428 IDirect3DImpl* d3d;
4430 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4431 d3d->ref = 1;
4432 d3d->ddraw = (IDirectDrawImpl*)This;
4433 IDirectDraw2_AddRef(iface);
4434 ICOM_VTBL(d3d) = &d3dvt;
4435 *obj = d3d;
4437 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4439 return S_OK;
4441 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4442 IDirect3D2Impl* d3d;
4444 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4445 d3d->ref = 1;
4446 d3d->ddraw = (IDirectDrawImpl*)This;
4447 IDirectDraw2_AddRef(iface);
4448 ICOM_VTBL(d3d) = &d3d2vt;
4449 *obj = d3d;
4451 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4453 return S_OK;
4455 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4456 return OLE_E_ENUM_NOMORE;
4458 #endif /* defined(HAVE_LIBXXF86DGA) */
4460 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4461 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4463 ICOM_THIS(IDirectDraw2Impl,iface);
4465 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4466 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4467 *obj = This;
4468 IDirectDraw2_AddRef(iface);
4470 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4472 return S_OK;
4474 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4475 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4476 IDirectDraw2_AddRef(iface);
4477 *obj = This;
4479 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4481 return S_OK;
4483 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4484 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4485 IDirectDraw2_AddRef(iface);
4486 *obj = This;
4488 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4490 return S_OK;
4492 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4493 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4494 IDirectDraw2_AddRef(iface);
4495 *obj = This;
4497 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4499 return S_OK;
4501 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4502 IDirect3DImpl* d3d;
4504 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4505 d3d->ref = 1;
4506 d3d->ddraw = (IDirectDrawImpl*)This;
4507 IDirectDraw2_AddRef(iface);
4508 ICOM_VTBL(d3d) = &d3dvt;
4509 *obj = d3d;
4511 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4513 return S_OK;
4515 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4516 IDirect3D2Impl* d3d;
4518 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4519 d3d->ref = 1;
4520 d3d->ddraw = (IDirectDrawImpl*)This;
4521 IDirectDraw2_AddRef(iface);
4522 ICOM_VTBL(d3d) = &d3d2vt;
4523 *obj = d3d;
4525 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4527 return S_OK;
4529 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4530 return OLE_E_ENUM_NOMORE;
4533 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4534 LPDIRECTDRAW2 iface,BOOL *status
4536 ICOM_THIS(IDirectDraw2Impl,iface);
4537 TRACE("(%p)->(%p)\n",This,status);
4538 *status = TRUE;
4539 return DD_OK;
4542 #ifdef HAVE_LIBXXF86DGA
4543 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4544 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4546 ICOM_THIS(IDirectDraw2Impl,iface);
4547 DDSURFACEDESC ddsfd;
4548 static struct {
4549 int w,h;
4550 } modes[5] = { /* some of the usual modes */
4551 {512,384},
4552 {640,400},
4553 {640,480},
4554 {800,600},
4555 {1024,768},
4557 static int depths[4] = {8,16,24,32};
4558 int i,j;
4560 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4561 ddsfd.dwSize = sizeof(ddsfd);
4562 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4563 if (dwFlags & DDEDM_REFRESHRATES) {
4564 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4565 ddsfd.u.dwRefreshRate = 60;
4567 ddsfd.ddsCaps.dwCaps = 0;
4568 ddsfd.dwBackBufferCount = 1;
4570 #ifdef HAVE_LIBXXF86DGA2
4571 if (This->e.dga.version == 2) {
4572 XDGAMode *modes = This->e.dga.modes;
4574 ddsfd.dwFlags |= DDSD_PITCH;
4575 for (i = 0; i < This->e.dga.num_modes; i++) {
4576 if (TRACE_ON(ddraw)) {
4577 DPRINTF(" Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
4578 modes[i].num,
4579 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
4580 modes[i].viewportWidth, modes[i].viewportHeight,
4581 modes[i].depth);
4582 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
4583 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
4584 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
4585 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
4586 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
4587 DPRINTF("\n");
4589 /* Fill the pixel format */
4590 ddsfd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
4591 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4592 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4593 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = modes[i].bitsPerPixel;
4594 if (modes[i].depth == 8) {
4595 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4596 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4597 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4598 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4599 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4600 } else {
4601 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4602 ddsfd.ddpfPixelFormat.u1.dwRBitMask = modes[i].redMask;
4603 ddsfd.ddpfPixelFormat.u2.dwGBitMask = modes[i].greenMask;
4604 ddsfd.ddpfPixelFormat.u3.dwBBitMask = modes[i].blueMask;
4607 ddsfd.dwWidth = modes[i].viewportWidth;
4608 ddsfd.dwHeight = modes[i].viewportHeight;
4609 ddsfd.lPitch = modes[i].imageWidth;
4611 /* Send mode to the application */
4612 if (!modescb(&ddsfd,context)) return DD_OK;
4614 } else {
4615 #endif
4616 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4617 ddsfd.dwBackBufferCount = 1;
4618 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4619 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4620 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4621 /* FIXME: those masks would have to be set in depth > 8 */
4622 if (depths[i]==8) {
4623 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4624 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4625 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4626 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4627 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4628 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4629 } else {
4630 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4632 /* FIXME: We should query those from X itself */
4633 switch (depths[i]) {
4634 case 16:
4635 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4636 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4637 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4638 break;
4639 case 24:
4640 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4641 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4642 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4643 break;
4644 case 32:
4645 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4646 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4647 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4648 break;
4652 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4653 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4654 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4655 if (!modescb(&ddsfd,context)) return DD_OK;
4657 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4658 ddsfd.dwWidth = modes[j].w;
4659 ddsfd.dwHeight = modes[j].h;
4660 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4661 if (!modescb(&ddsfd,context)) return DD_OK;
4664 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4665 /* modeX is not standard VGA */
4667 ddsfd.dwHeight = 200;
4668 ddsfd.dwWidth = 320;
4669 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4670 if (!modescb(&ddsfd,context)) return DD_OK;
4673 #ifdef HAVE_LIBXXF86DGA2
4675 #endif
4676 return DD_OK;
4678 #endif /* defined(HAVE_LIBXXF86DGA) */
4680 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4681 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4683 ICOM_THIS(IDirectDraw2Impl,iface);
4684 XVisualInfo *vi;
4685 XPixmapFormatValues *pf;
4686 XVisualInfo vt;
4687 int xbpp, nvisuals, npixmap, i, emu;
4688 int has_mode[] = { 0, 0, 0, 0 };
4689 int has_depth[] = { 8, 15, 16, 24 };
4690 DDSURFACEDESC ddsfd;
4691 static struct {
4692 int w,h;
4693 } modes[] = { /* some of the usual modes */
4694 {512,384},
4695 {640,400},
4696 {640,480},
4697 {800,600},
4698 {1024,768},
4699 {1280,1024}
4701 DWORD maxWidth, maxHeight;
4703 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4704 ddsfd.dwSize = sizeof(ddsfd);
4705 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_PITCH;
4706 if (dwFlags & DDEDM_REFRESHRATES) {
4707 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4708 ddsfd.u.dwRefreshRate = 60;
4710 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4711 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4713 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4714 pf = XListPixmapFormats(display, &npixmap);
4716 i = 0;
4717 emu = 0;
4718 while ((i < npixmap) || (emu != 4)) {
4719 int mode_index = 0;
4720 int send_mode = 0;
4721 int j;
4723 if (i < npixmap) {
4724 for (j = 0; j < 4; j++) {
4725 if (has_depth[j] == pf[i].depth) {
4726 mode_index = j;
4727 break;
4730 if (j == 4) {
4731 i++;
4732 continue;
4736 if (has_mode[mode_index] == 0) {
4737 if (mode_index == 0) {
4738 send_mode = 1;
4740 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4741 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4742 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4743 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4744 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4745 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4746 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4747 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4748 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4750 xbpp = 1;
4752 has_mode[mode_index] = 1;
4753 } else {
4754 /* All the 'true color' depths (15, 16 and 24)
4755 First, find the corresponding visual to extract the bit masks */
4756 for (j = 0; j < nvisuals; j++) {
4757 if (vi[j].depth == pf[i].depth) {
4758 ddsfd.ddsCaps.dwCaps = 0;
4759 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4760 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4761 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4762 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4763 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4764 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4765 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4766 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4768 xbpp = pf[i].bits_per_pixel/8;
4770 send_mode = 1;
4771 has_mode[mode_index] = 1;
4772 break;
4775 if (j == nvisuals)
4776 ERR("Did not find visual corresponding the the pixmap format !\n");
4779 i++;
4780 } else {
4781 /* Now to emulated modes */
4782 if (has_mode[emu] == 0) {
4783 int c;
4784 int l;
4785 int depth = has_depth[emu];
4787 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4788 if (ModeEmulations[c].dest.depth == depth) {
4789 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4790 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4791 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4792 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4793 int j;
4794 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4795 if ((vi[j].depth == pf[l].depth) &&
4796 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4797 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4798 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4799 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4800 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4801 if (depth == 8) {
4802 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4803 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4804 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4805 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4806 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4807 } else {
4808 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4809 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4810 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4811 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4812 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4814 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4815 send_mode = 1;
4818 if (send_mode == 0)
4819 ERR("No visual corresponding to pixmap format !\n");
4827 emu++;
4830 if (send_mode) {
4831 int mode;
4833 if (TRACE_ON(ddraw)) {
4834 TRACE("Enumerating with pixel format : \n");
4835 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4836 DPRINTF("\n");
4839 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4840 /* Do not enumerate modes we cannot handle anyway */
4841 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4842 break;
4844 ddsfd.dwWidth = modes[mode].w;
4845 ddsfd.dwHeight= modes[mode].h;
4846 ddsfd.lPitch = ddsfd.dwWidth * xbpp;
4848 /* Now, send the mode description to the application */
4849 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4850 if (!modescb(&ddsfd, context))
4851 goto exit_enum;
4854 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4855 /* modeX is not standard VGA */
4856 ddsfd.dwWidth = 320;
4857 ddsfd.dwHeight = 200;
4858 ddsfd.lPitch = 320 * xbpp;
4859 if (!modescb(&ddsfd, context))
4860 goto exit_enum;
4864 exit_enum:
4865 TSXFree(vi);
4866 TSXFree(pf);
4868 return DD_OK;
4871 #ifdef HAVE_LIBXXF86DGA
4872 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4873 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4875 ICOM_THIS(IDirectDraw2Impl,iface);
4876 TRACE("(%p)->(%p)\n",This,lpddsfd);
4877 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4878 lpddsfd->dwHeight = This->d.height;
4879 lpddsfd->dwWidth = This->d.width;
4880 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4881 lpddsfd->dwBackBufferCount = 2;
4882 lpddsfd->u.dwRefreshRate = 60;
4883 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4884 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4885 if (TRACE_ON(ddraw)) {
4886 _dump_surface_desc(lpddsfd);
4888 return DD_OK;
4890 #endif /* defined(HAVE_LIBXXF86DGA) */
4892 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4893 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4895 ICOM_THIS(IDirectDraw2Impl,iface);
4896 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4897 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4898 lpddsfd->dwHeight = This->d.height;
4899 lpddsfd->dwWidth = This->d.width;
4900 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4901 lpddsfd->dwBackBufferCount = 2;
4902 lpddsfd->u.dwRefreshRate = 60;
4903 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4904 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4905 if (TRACE_ON(ddraw)) {
4906 _dump_surface_desc(lpddsfd);
4908 return DD_OK;
4911 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4912 ICOM_THIS(IDirectDraw2Impl,iface);
4913 TRACE("(%p)->()\n",This);
4914 return DD_OK;
4917 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4918 LPDIRECTDRAW2 iface,LPDWORD freq
4920 ICOM_THIS(IDirectDraw2Impl,iface);
4921 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4922 *freq = 60*100; /* 60 Hz */
4923 return DD_OK;
4926 /* what can we directly decompress? */
4927 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4928 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4930 ICOM_THIS(IDirectDraw2Impl,iface);
4931 FIXME("(%p,%p,%p), stub\n",This,x,y);
4932 return DD_OK;
4935 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4936 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4938 ICOM_THIS(IDirectDraw2Impl,iface);
4939 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4940 return DD_OK;
4943 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4944 LPDIRECTDRAW2 iface )
4946 ICOM_THIS(IDirectDraw2Impl,iface);
4947 FIXME("(%p)->()\n", This );
4949 return DD_OK;
4952 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4953 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4954 ICOM_THIS(IDirectDraw2Impl,iface);
4955 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4957 return DD_OK;
4960 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4961 LPDWORD lpdwScanLine) {
4962 ICOM_THIS(IDirectDraw2Impl,iface);
4963 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4965 if (lpdwScanLine)
4966 *lpdwScanLine = 0;
4967 return DD_OK;
4970 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4971 GUID *lpGUID) {
4972 ICOM_THIS(IDirectDraw2Impl,iface);
4973 FIXME("(%p)->(%p)\n", This, lpGUID);
4975 return DD_OK;
4978 #ifdef HAVE_LIBXXF86DGA
4980 /* Note: Hack so we can reuse the old functions without compiler warnings */
4981 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4982 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4983 #else
4984 # define XCAST(fun) (void *)
4985 #endif
4987 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4989 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4990 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4991 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4992 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4993 XCAST(Compact)IDirectDraw2Impl_Compact,
4994 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4995 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4996 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4997 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4998 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4999 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5000 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5001 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5002 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5003 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5004 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5005 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5006 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5007 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5008 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5009 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5010 #ifdef HAVE_LIBXXF86DGA2
5011 XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
5012 #else
5013 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5014 #endif
5015 DGA_IDirectDrawImpl_SetDisplayMode,
5016 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5019 #undef XCAST
5021 #endif /* defined(HAVE_LIBXXF86DGA) */
5023 /* Note: Hack so we can reuse the old functions without compiler warnings */
5024 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5025 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
5026 #else
5027 # define XCAST(fun) (void *)
5028 #endif
5030 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
5032 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5033 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5034 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5035 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5036 XCAST(Compact)IDirectDraw2Impl_Compact,
5037 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5038 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5039 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5040 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5041 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5042 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5043 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5044 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5045 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5046 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5047 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5048 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5049 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5050 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5051 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5052 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5053 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5054 Xlib_IDirectDrawImpl_SetDisplayMode,
5055 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5058 #undef XCAST
5060 /*****************************************************************************
5061 * IDirectDraw2
5065 #ifdef HAVE_LIBXXF86DGA
5066 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
5067 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
5069 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5070 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5072 #endif /* defined(HAVE_LIBXXF86DGA) */
5074 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
5075 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
5077 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5078 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5081 #ifdef HAVE_LIBXXF86DGA
5082 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
5083 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5085 ICOM_THIS(IDirectDraw2Impl,iface);
5086 TRACE("(%p)->(%p,%p,%p)\n",
5087 This,ddscaps,total,free
5089 if (total) *total = This->e.dga.fb_memsize * 1024;
5090 if (free) *free = This->e.dga.fb_memsize * 1024;
5091 return DD_OK;
5093 #endif /* defined(HAVE_LIBXXF86DGA) */
5095 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
5096 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5098 ICOM_THIS(IDirectDraw2Impl,iface);
5099 TRACE("(%p)->(%p,%p,%p)\n",
5100 This,ddscaps,total,free
5102 if (total) *total = 2048 * 1024;
5103 if (free) *free = 2048 * 1024;
5104 return DD_OK;
5107 #ifdef HAVE_LIBXXF86DGA
5108 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
5110 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5111 DGA_IDirectDraw2Impl_QueryInterface,
5112 IDirectDraw2Impl_AddRef,
5113 DGA_IDirectDraw2Impl_Release,
5114 IDirectDraw2Impl_Compact,
5115 IDirectDraw2Impl_CreateClipper,
5116 DGA_IDirectDraw2Impl_CreatePalette,
5117 DGA_IDirectDraw2Impl_CreateSurface,
5118 IDirectDraw2Impl_DuplicateSurface,
5119 DGA_IDirectDraw2Impl_EnumDisplayModes,
5120 IDirectDraw2Impl_EnumSurfaces,
5121 IDirectDraw2Impl_FlipToGDISurface,
5122 DGA_IDirectDraw2Impl_GetCaps,
5123 DGA_IDirectDraw2Impl_GetDisplayMode,
5124 IDirectDraw2Impl_GetFourCCCodes,
5125 IDirectDraw2Impl_GetGDISurface,
5126 IDirectDraw2Impl_GetMonitorFrequency,
5127 IDirectDraw2Impl_GetScanLine,
5128 IDirectDraw2Impl_GetVerticalBlankStatus,
5129 IDirectDraw2Impl_Initialize,
5130 DGA_IDirectDraw2Impl_RestoreDisplayMode,
5131 IDirectDraw2Impl_SetCooperativeLevel,
5132 DGA_IDirectDraw2Impl_SetDisplayMode,
5133 IDirectDraw2Impl_WaitForVerticalBlank,
5134 DGA_IDirectDraw2Impl_GetAvailableVidMem
5136 #endif /* defined(HAVE_LIBXXF86DGA) */
5138 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
5140 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5141 Xlib_IDirectDraw2Impl_QueryInterface,
5142 IDirectDraw2Impl_AddRef,
5143 Xlib_IDirectDraw2Impl_Release,
5144 IDirectDraw2Impl_Compact,
5145 IDirectDraw2Impl_CreateClipper,
5146 Xlib_IDirectDraw2Impl_CreatePalette,
5147 Xlib_IDirectDraw2Impl_CreateSurface,
5148 IDirectDraw2Impl_DuplicateSurface,
5149 Xlib_IDirectDraw2Impl_EnumDisplayModes,
5150 IDirectDraw2Impl_EnumSurfaces,
5151 IDirectDraw2Impl_FlipToGDISurface,
5152 Xlib_IDirectDraw2Impl_GetCaps,
5153 Xlib_IDirectDraw2Impl_GetDisplayMode,
5154 IDirectDraw2Impl_GetFourCCCodes,
5155 IDirectDraw2Impl_GetGDISurface,
5156 IDirectDraw2Impl_GetMonitorFrequency,
5157 IDirectDraw2Impl_GetScanLine,
5158 IDirectDraw2Impl_GetVerticalBlankStatus,
5159 IDirectDraw2Impl_Initialize,
5160 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5161 IDirectDraw2Impl_SetCooperativeLevel,
5162 Xlib_IDirectDraw2Impl_SetDisplayMode,
5163 IDirectDraw2Impl_WaitForVerticalBlank,
5164 Xlib_IDirectDraw2Impl_GetAvailableVidMem
5167 /*****************************************************************************
5168 * IDirectDraw4
5172 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
5173 HDC hdc,
5174 LPDIRECTDRAWSURFACE *lpDDS) {
5175 ICOM_THIS(IDirectDraw4Impl,iface);
5176 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
5178 return DD_OK;
5181 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
5182 ICOM_THIS(IDirectDraw4Impl,iface);
5183 FIXME("(%p)->()\n", This);
5185 return DD_OK;
5188 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
5189 ICOM_THIS(IDirectDraw4Impl,iface);
5190 FIXME("(%p)->()\n", This);
5192 return DD_OK;
5195 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5196 LPDDDEVICEIDENTIFIER lpdddi,
5197 DWORD dwFlags) {
5198 ICOM_THIS(IDirectDraw4Impl,iface);
5199 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5201 return DD_OK;
5204 #ifdef HAVE_LIBXXF86DGA
5206 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5207 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5208 #else
5209 # define XCAST(fun) (void*)
5210 #endif
5212 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5214 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5215 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5216 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5217 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5218 XCAST(Compact)IDirectDraw2Impl_Compact,
5219 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5220 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5221 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5222 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5223 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5224 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5225 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5226 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5227 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5228 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5229 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5230 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5231 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5232 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5233 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5234 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5235 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5236 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5237 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5238 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5239 IDirectDraw4Impl_GetSurfaceFromDC,
5240 IDirectDraw4Impl_RestoreAllSurfaces,
5241 IDirectDraw4Impl_TestCooperativeLevel,
5242 IDirectDraw4Impl_GetDeviceIdentifier
5245 #undef XCAST
5247 #endif /* defined(HAVE_LIBXXF86DGA) */
5249 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5250 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5251 #else
5252 # define XCAST(fun) (void*)
5253 #endif
5255 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5257 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5258 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5259 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5260 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5261 XCAST(Compact)IDirectDraw2Impl_Compact,
5262 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5263 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5264 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5265 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5266 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5267 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5268 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5269 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5270 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5271 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5272 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5273 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5274 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5275 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5276 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5277 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5278 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5279 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5280 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5281 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5282 IDirectDraw4Impl_GetSurfaceFromDC,
5283 IDirectDraw4Impl_RestoreAllSurfaces,
5284 IDirectDraw4Impl_TestCooperativeLevel,
5285 IDirectDraw4Impl_GetDeviceIdentifier
5288 #undef XCAST
5290 /******************************************************************************
5291 * DirectDrawCreate
5294 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5296 LRESULT ret;
5297 IDirectDrawImpl* ddraw = NULL;
5298 DWORD lastError;
5300 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5302 SetLastError( ERROR_SUCCESS );
5303 ddraw = (IDirectDrawImpl*)GetPropA( hwnd, ddProp );
5304 if( (!ddraw) && ( ( lastError = GetLastError() ) != ERROR_SUCCESS ))
5306 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5309 if( ddraw )
5311 /* Perform any special direct draw functions */
5312 if (msg==WM_PAINT)
5313 ddraw->d.paintable = 1;
5315 /* Now let the application deal with the rest of this */
5316 if( ddraw->d.mainWindow )
5319 /* Don't think that we actually need to call this but...
5320 might as well be on the safe side of things... */
5322 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5323 it should be the procedures of our fake window that gets called
5324 instead of those of the window provided by the application.
5325 And with this patch, mouse clicks work with Monkey Island III
5326 - Lionel */
5327 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5329 if( !ret )
5331 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5332 /* We didn't handle the message - give it to the application */
5333 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5335 ret = CallWindowProcA(tmpWnd->winproc,
5336 ddraw->d.mainWindow, msg, wParam, lParam );
5338 WIN_ReleaseWndPtr(tmpWnd);
5342 } else {
5343 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5347 else
5349 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5352 return ret;
5355 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5356 #ifdef HAVE_LIBXXF86DGA
5357 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5358 int memsize,banksize,major,minor,flags;
5359 char *addr;
5360 int depth;
5361 int dga_version;
5362 int width, height;
5364 /* Get DGA availability / version */
5365 dga_version = DDRAW_DGA_Available();
5367 if (dga_version == 0) {
5368 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5369 return DDERR_GENERIC;
5372 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5373 (*ilplpDD)->ref = 1;
5374 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5375 #ifdef HAVE_LIBXXF86DGA2
5376 if (dga_version == 1) {
5377 (*ilplpDD)->e.dga.version = 1;
5378 #endif /* defined(HAVE_LIBXXF86DGA2) */
5379 TSXF86DGAQueryVersion(display,&major,&minor);
5380 TRACE("XF86DGA is version %d.%d\n",major,minor);
5381 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5382 if (!(flags & XF86DGADirectPresent))
5383 MESSAGE("direct video is NOT PRESENT.\n");
5384 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5385 (*ilplpDD)->e.dga.fb_width = width;
5386 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5387 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5388 (*ilplpDD)->e.dga.fb_height = height;
5389 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5390 addr,width,banksize,memsize
5392 TRACE("viewport height: %d\n",height);
5393 /* Get the screen dimensions as seen by Wine.
5394 In that case, it may be better to ignore the -desktop mode and return the
5395 real screen size => print a warning */
5396 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5397 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5398 if (((*ilplpDD)->d.height != height) ||
5399 ((*ilplpDD)->d.width != width))
5400 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5401 (*ilplpDD)->e.dga.fb_addr = addr;
5402 (*ilplpDD)->e.dga.fb_memsize = memsize;
5403 (*ilplpDD)->e.dga.vpmask = 0;
5405 /* just assume the default depth is the DGA depth too */
5406 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5407 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
5408 #ifdef RESTORE_SIGNALS
5409 SIGNAL_Init();
5410 #endif
5411 #ifdef HAVE_LIBXXF86DGA2
5412 } else {
5413 XDGAMode *modes;
5414 int i, num_modes;
5415 int mode_to_use = 0;
5417 (*ilplpDD)->e.dga.version = 2;
5419 TSXDGAQueryVersion(display,&major,&minor);
5420 TRACE("XDGA is version %d.%d\n",major,minor);
5422 TRACE("Opening the frame buffer.\n");
5423 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5424 ERR("Error opening the frame buffer !!!\n");
5426 return DDERR_GENERIC;
5429 /* List all available modes */
5430 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5431 (*ilplpDD)->e.dga.modes = modes;
5432 (*ilplpDD)->e.dga.num_modes = num_modes;
5433 if (TRACE_ON(ddraw)) {
5434 TRACE("Available modes :\n");
5435 for (i = 0; i < num_modes; i++) {
5436 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5437 modes[i].num,
5438 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5439 modes[i].viewportWidth, modes[i].viewportHeight,
5440 modes[i].depth);
5441 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5442 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5443 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5444 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5445 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5446 DPRINTF("\n");
5448 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5449 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5450 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5451 mode_to_use = modes[i].num;
5455 if (mode_to_use == 0) {
5456 ERR("Could not find mode !\n");
5457 mode_to_use = 1;
5458 } else {
5459 DPRINTF("Using mode number %d\n", mode_to_use);
5462 /* Initialize the frame buffer */
5463 _DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
5464 /* Set the input handling for relative mouse movements */
5465 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5467 #endif /* defined(HAVE_LIBXXF86DGA2) */
5468 return DD_OK;
5469 #else /* defined(HAVE_LIBXXF86DGA) */
5470 return DDERR_INVALIDDIRECTDRAWGUID;
5471 #endif /* defined(HAVE_LIBXXF86DGA) */
5474 static BOOL
5475 DDRAW_XSHM_Available(void)
5477 #ifdef HAVE_LIBXXSHM
5478 if (TSXShmQueryExtension(display))
5480 int major, minor;
5481 Bool shpix;
5483 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5484 (Options.noXSHM != 1))
5485 return 1;
5486 else
5487 return 0;
5489 else
5490 return 0;
5491 #else
5492 return 0;
5493 #endif
5496 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5497 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5498 int depth;
5500 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5501 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5502 (*ilplpDD)->ref = 1;
5503 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5505 /* At DirectDraw creation, the depth is the default depth */
5506 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5507 _common_depth_to_pixelformat(depth,
5508 &((*ilplpDD)->d.directdraw_pixelformat),
5509 &((*ilplpDD)->d.screen_pixelformat),
5510 &((*ilplpDD)->d.pixmap_depth));
5511 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5512 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5514 #ifdef HAVE_LIBXXSHM
5515 /* Test if XShm is available. */
5516 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5517 (*ilplpDD)->e.xlib.xshm_compl = 0;
5518 TRACE("Using XShm extension.\n");
5520 #endif
5522 return DD_OK;
5525 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5526 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5527 WNDCLASSA wc;
5528 /* WND* pParentWindow; */
5529 HRESULT ret;
5531 if (!HIWORD(lpGUID)) lpGUID = NULL;
5533 TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID),ilplpDD,pUnkOuter);
5535 if ( ( !lpGUID ) ||
5536 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5537 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5538 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5539 /* if they didn't request a particular interface, use the best
5540 * supported one */
5541 if (DDRAW_DGA_Available())
5542 lpGUID = &DGA_DirectDraw_GUID;
5543 else
5544 lpGUID = &XLIB_DirectDraw_GUID;
5547 wc.style = CS_GLOBALCLASS;
5548 wc.lpfnWndProc = Xlib_DDWndProc;
5549 wc.cbClsExtra = 0;
5550 wc.cbWndExtra = 0;
5552 /* We can be a child of the desktop since we're really important */
5554 This code is not useful since hInstance is forced to 0 afterward
5555 pParentWindow = WIN_GetDesktop();
5556 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5558 wc.hInstance = 0;
5561 wc.hIcon = 0;
5562 wc.hCursor = (HCURSOR)IDC_ARROWA;
5563 wc.hbrBackground= NULL_BRUSH;
5564 wc.lpszMenuName = 0;
5565 wc.lpszClassName= "WINE_DirectDraw";
5566 RegisterClassA(&wc);
5568 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5569 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5571 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5572 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5574 else {
5575 goto err;
5579 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5580 return ret;
5582 err:
5583 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",
5584 debugstr_guid(lpGUID),lplpDD,pUnkOuter);
5585 return DDERR_INVALIDDIRECTDRAWGUID;
5588 /*******************************************************************************
5589 * DirectDraw ClassFactory
5591 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5594 typedef struct
5596 /* IUnknown fields */
5597 ICOM_VFIELD(IClassFactory);
5598 DWORD ref;
5599 } IClassFactoryImpl;
5601 static HRESULT WINAPI
5602 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5603 ICOM_THIS(IClassFactoryImpl,iface);
5605 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
5606 return E_NOINTERFACE;
5609 static ULONG WINAPI
5610 DDCF_AddRef(LPCLASSFACTORY iface) {
5611 ICOM_THIS(IClassFactoryImpl,iface);
5612 return ++(This->ref);
5615 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5616 ICOM_THIS(IClassFactoryImpl,iface);
5617 /* static class, won't be freed */
5618 return --(This->ref);
5621 static HRESULT WINAPI DDCF_CreateInstance(
5622 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5624 ICOM_THIS(IClassFactoryImpl,iface);
5626 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
5627 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5628 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5629 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5630 /* FIXME: reuse already created DirectDraw if present? */
5631 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5633 return CLASS_E_CLASSNOTAVAILABLE;
5636 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5637 ICOM_THIS(IClassFactoryImpl,iface);
5638 FIXME("(%p)->(%d),stub!\n",This,dolock);
5639 return S_OK;
5642 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5644 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5645 DDCF_QueryInterface,
5646 DDCF_AddRef,
5647 DDCF_Release,
5648 DDCF_CreateInstance,
5649 DDCF_LockServer
5651 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5653 /*******************************************************************************
5654 * DllGetClassObject [DDRAW.13]
5655 * Retrieves class object from a DLL object
5657 * NOTES
5658 * Docs say returns STDAPI
5660 * PARAMS
5661 * rclsid [I] CLSID for the class object
5662 * riid [I] Reference to identifier of interface for class object
5663 * ppv [O] Address of variable to receive interface pointer for riid
5665 * RETURNS
5666 * Success: S_OK
5667 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5668 * E_UNEXPECTED
5670 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5672 TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5673 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5674 *ppv = (LPVOID)&DDRAW_CF;
5675 IClassFactory_AddRef((IClassFactory*)*ppv);
5676 return S_OK;
5678 FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5679 return CLASS_E_CLASSNOTAVAILABLE;
5683 /*******************************************************************************
5684 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5686 * RETURNS
5687 * Success: S_OK
5688 * Failure: S_FALSE
5690 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5692 FIXME("(void): stub\n");
5693 return S_FALSE;
5696 #else /* !defined(X_DISPLAY_MISSING) */
5698 #include "windef.h"
5699 #include "wtypes.h"
5701 #define DD_OK 0
5703 typedef void *LPUNKNOWN;
5704 typedef void *LPDIRECTDRAW;
5705 typedef void *LPDIRECTDRAWCLIPPER;
5706 typedef void *LPDDENUMCALLBACKA;
5707 typedef void *LPDDENUMCALLBACKEXA;
5708 typedef void *LPDDENUMCALLBACKEXW;
5709 typedef void *LPDDENUMCALLBACKW;
5711 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5713 return DD_OK;
5716 HRESULT WINAPI DirectDrawCreate(
5717 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5719 return DD_OK;
5722 HRESULT WINAPI DirectDrawCreateClipper(
5723 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5725 return DD_OK;
5728 HRESULT WINAPI DirectDrawEnumerateA(
5729 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5731 return DD_OK;
5734 HRESULT WINAPI DirectDrawEnumerateExA(
5735 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5737 return DD_OK;
5740 HRESULT WINAPI DirectDrawEnumerateExW(
5741 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5743 return DD_OK;
5746 HRESULT WINAPI DirectDrawEnumerateW(
5747 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5749 return DD_OK;
5752 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5754 return CLASS_E_CLASSNOTAVAILABLE;
5757 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5759 return DD_OK;
5762 #endif /* !defined(X_DISPLAY_MISSING) */