Got rid of PROFILE_ functions, now accessing Wine config options
[wine.git] / graphics / ddraw.c
blob2472d5197e072bb4f050920135427cd435c392af
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>
58 #include <stdio.h>
60 #include "gdi.h"
61 #include "heap.h"
62 #include "dc.h"
63 #include "win.h"
64 #include "wine/exception.h"
65 #include "ddraw.h"
66 #include "d3d.h"
67 #include "debugtools.h"
68 #include "spy.h"
69 #include "message.h"
70 #include "options.h"
71 #include "monitor.h"
73 static char *ddProp = "WINE_DDRAW_Property";
75 /* This for all the enumeration and creation of D3D-related objects */
76 #include "ddraw_private.h"
77 #include "d3d_private.h"
79 DEFAULT_DEBUG_CHANNEL(ddraw);
81 /* Restore signal handlers overwritten by XF86DGA
83 #define RESTORE_SIGNALS
85 /* Get DDSCAPS of surface (shortcutmacro) */
86 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
88 /* Get the number of bytes per pixel for a given surface */
89 #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
91 #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
93 /* Where do these GUIDs come from? mkuuid.
94 * They exist solely to distinguish between the targets Wine support,
95 * and should be different than any other GUIDs in existence.
97 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
98 0xe2dcb020,
99 0xdc60,
100 0x11d1,
101 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
104 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
105 0x1574a740,
106 0xdc61,
107 0x11d1,
108 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
111 #ifdef HAVE_LIBXXF86DGA
112 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt;
113 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt;
114 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt;
115 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt;
116 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt;
117 #endif /* defined(HAVE_LIBXXF86DGA) */
119 #ifdef HAVE_LIBXXF86DGA2
120 static struct ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt;
121 #endif /* defined(HAVE_LIBXXF86DGA2) */
123 static struct ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt;
124 static struct ICOM_VTABLE(IDirectDraw) xlib_ddvt;
125 static struct ICOM_VTABLE(IDirectDraw2) xlib_dd2vt;
126 static struct ICOM_VTABLE(IDirectDraw4) xlib_dd4vt;
127 static struct ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt;
129 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
130 static struct ICOM_VTABLE(IDirect3D) d3dvt;
131 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
133 /* This is for mode-emulation */
135 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
136 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
137 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
138 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
139 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
140 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
141 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
143 typedef struct {
144 unsigned short bpp;
145 unsigned short depth;
146 unsigned int rmask;
147 unsigned int gmask;
148 unsigned int bmask;
149 } ConvertMode;
151 typedef struct {
152 void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
153 void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
154 } ConvertFuncs;
156 typedef struct {
157 ConvertMode screen, dest;
158 ConvertFuncs funcs;
159 } Convert;
161 static Convert ModeEmulations[] = {
162 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
163 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
164 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
165 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
166 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
169 #ifdef HAVE_LIBXXF86VM
170 static XF86VidModeModeInfo *orig_mode = NULL;
171 #endif
173 #ifdef HAVE_LIBXXSHM
174 static int XShmErrorFlag = 0;
175 #endif
177 static BYTE
178 DDRAW_DGA_Available(void)
180 #ifdef HAVE_LIBXXF86DGA
181 int fd, evbase, evret, majver, minver;
182 static BYTE return_value = 0xFF;
184 /* This prevents from probing X times for DGA */
185 if (return_value != 0xFF)
186 return return_value;
188 if (Options.noDGA) {
189 return_value = 0;
190 return 0;
193 /* First, query the extenstion and its version */
194 if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) {
195 return_value = 0;
196 return 0;
199 if (!TSXF86DGAQueryVersion(display,&majver,&minver)) {
200 return_value = 0;
201 return 0;
204 #ifdef HAVE_LIBXXF86DGA2
205 if (majver >= 2) {
206 /* We have DGA 2.0 available ! */
207 if (TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
208 TSXDGACloseFramebuffer(display, DefaultScreen(display));
209 return_value = 2;
210 } else {
211 return_value = 0;
214 return return_value;
215 } else {
216 #endif /* defined(HAVE_LIBXXF86DGA2) */
218 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
219 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
220 /* others. --stephenc */
221 if ((fd = open("/dev/mem", O_RDWR)) != -1)
222 close(fd);
224 if (fd != -1)
225 return_value = 1;
226 else
227 return_value = 0;
229 return return_value;
230 #ifdef HAVE_LIBXXF86DGA2
232 #endif /* defined(HAVE_LIBXXF86DGA2) */
233 #else /* defined(HAVE_LIBXXF86DGA) */
234 return 0;
235 #endif /* defined(HAVE_LIBXXF86DGA) */
238 /**********************************************************************/
240 typedef struct {
241 LPVOID lpCallback;
242 LPVOID lpContext;
243 } DirectDrawEnumerateProcData;
245 /***********************************************************************
246 * DirectDrawEnumerateExA (DDRAW.*)
248 HRESULT WINAPI DirectDrawEnumerateExA(
249 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
251 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
253 if (TRACE_ON(ddraw)) {
254 DPRINTF(" Flags : ");
255 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
256 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
257 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
258 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
259 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
260 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
261 DPRINTF("\n");
264 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
265 /* For the moment, Wine does not support any 3D only accelerators */
266 return DD_OK;
268 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
269 /* For the moment, Wine does not support any attached secondary devices */
270 return DD_OK;
273 if (DDRAW_DGA_Available()) {
274 TRACE("Enumerating DGA interface\n");
275 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
276 return DD_OK;
279 TRACE("Enumerating Xlib interface\n");
280 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
281 return DD_OK;
283 TRACE("Enumerating Default interface\n");
284 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
285 return DD_OK;
287 return DD_OK;
290 /***********************************************************************
291 * DirectDrawEnumerateExW (DDRAW.*)
294 static BOOL CALLBACK DirectDrawEnumerateExProcW(
295 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
296 LPVOID lpContext, HMONITOR hm)
298 DirectDrawEnumerateProcData *pEPD =
299 (DirectDrawEnumerateProcData *) lpContext;
300 LPWSTR lpDriverDescriptionW =
301 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
302 LPWSTR lpDriverNameW =
303 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
305 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
306 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
308 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
309 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
311 return bResult;
314 /**********************************************************************/
316 HRESULT WINAPI DirectDrawEnumerateExW(
317 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
319 DirectDrawEnumerateProcData epd;
320 epd.lpCallback = (LPVOID) lpCallback;
321 epd.lpContext = lpContext;
323 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
324 (LPVOID) &epd, 0);
327 /***********************************************************************
328 * DirectDrawEnumerateA (DDRAW.*)
331 static BOOL CALLBACK DirectDrawEnumerateProcA(
332 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
333 LPVOID lpContext, HMONITOR hm)
335 DirectDrawEnumerateProcData *pEPD =
336 (DirectDrawEnumerateProcData *) lpContext;
338 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
339 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
342 /**********************************************************************/
344 HRESULT WINAPI DirectDrawEnumerateA(
345 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
347 DirectDrawEnumerateProcData epd;
348 epd.lpCallback = (LPVOID) lpCallback;
349 epd.lpContext = lpContext;
351 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
352 (LPVOID) &epd, 0);
355 /***********************************************************************
356 * DirectDrawEnumerateW (DDRAW.*)
359 static BOOL WINAPI DirectDrawEnumerateProcW(
360 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
361 LPVOID lpContext, HMONITOR hm)
363 DirectDrawEnumerateProcData *pEPD =
364 (DirectDrawEnumerateProcData *) lpContext;
366 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
367 lpGUID, lpDriverDescription, lpDriverName,
368 pEPD->lpContext);
371 /**********************************************************************/
373 HRESULT WINAPI DirectDrawEnumerateW(
374 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
376 DirectDrawEnumerateProcData epd;
377 epd.lpCallback = (LPVOID) lpCallback;
378 epd.lpContext = lpContext;
380 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
381 (LPVOID) &epd, 0);
384 /***********************************************************************
385 * DSoundHelp (DDRAW.?)
388 /* What is this doing here? */
389 HRESULT WINAPI
390 DSoundHelp(DWORD x,DWORD y,DWORD z) {
391 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
392 return 0;
395 /******************************************************************************
396 * internal helper functions
398 static void _dump_DDBLTFX(DWORD flagmask) {
399 int i;
400 const struct {
401 DWORD mask;
402 char *name;
403 } flags[] = {
404 #define FE(x) { x, #x},
405 FE(DDBLTFX_ARITHSTRETCHY)
406 FE(DDBLTFX_MIRRORLEFTRIGHT)
407 FE(DDBLTFX_MIRRORUPDOWN)
408 FE(DDBLTFX_NOTEARING)
409 FE(DDBLTFX_ROTATE180)
410 FE(DDBLTFX_ROTATE270)
411 FE(DDBLTFX_ROTATE90)
412 FE(DDBLTFX_ZBUFFERRANGE)
413 FE(DDBLTFX_ZBUFFERBASEDEST)
414 #undef FE
416 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
417 if (flags[i].mask & flagmask) {
418 DPRINTF("%s ",flags[i].name);
421 DPRINTF("\n");
425 static void _dump_DDBLTFAST(DWORD flagmask) {
426 int i;
427 const struct {
428 DWORD mask;
429 char *name;
430 } flags[] = {
431 #define FE(x) { x, #x},
432 FE(DDBLTFAST_NOCOLORKEY)
433 FE(DDBLTFAST_SRCCOLORKEY)
434 FE(DDBLTFAST_DESTCOLORKEY)
435 FE(DDBLTFAST_WAIT)
436 #undef FE
438 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
439 if (flags[i].mask & flagmask)
440 DPRINTF("%s ",flags[i].name);
441 DPRINTF("\n");
444 static void _dump_DDBLT(DWORD flagmask) {
445 int i;
446 const struct {
447 DWORD mask;
448 char *name;
449 } flags[] = {
450 #define FE(x) { x, #x},
451 FE(DDBLT_ALPHADEST)
452 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
453 FE(DDBLT_ALPHADESTNEG)
454 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
455 FE(DDBLT_ALPHAEDGEBLEND)
456 FE(DDBLT_ALPHASRC)
457 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
458 FE(DDBLT_ALPHASRCNEG)
459 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
460 FE(DDBLT_ASYNC)
461 FE(DDBLT_COLORFILL)
462 FE(DDBLT_DDFX)
463 FE(DDBLT_DDROPS)
464 FE(DDBLT_KEYDEST)
465 FE(DDBLT_KEYDESTOVERRIDE)
466 FE(DDBLT_KEYSRC)
467 FE(DDBLT_KEYSRCOVERRIDE)
468 FE(DDBLT_ROP)
469 FE(DDBLT_ROTATIONANGLE)
470 FE(DDBLT_ZBUFFER)
471 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
472 FE(DDBLT_ZBUFFERDESTOVERRIDE)
473 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
474 FE(DDBLT_ZBUFFERSRCOVERRIDE)
475 FE(DDBLT_WAIT)
476 FE(DDBLT_DEPTHFILL)
477 #undef FE
479 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
480 if (flags[i].mask & flagmask)
481 DPRINTF("%s ",flags[i].name);
482 DPRINTF("\n");
485 static void _dump_DDSCAPS(void *in) {
486 int i;
487 const struct {
488 DWORD mask;
489 char *name;
490 } flags[] = {
491 #define FE(x) { x, #x},
492 FE(DDSCAPS_RESERVED1)
493 FE(DDSCAPS_ALPHA)
494 FE(DDSCAPS_BACKBUFFER)
495 FE(DDSCAPS_COMPLEX)
496 FE(DDSCAPS_FLIP)
497 FE(DDSCAPS_FRONTBUFFER)
498 FE(DDSCAPS_OFFSCREENPLAIN)
499 FE(DDSCAPS_OVERLAY)
500 FE(DDSCAPS_PALETTE)
501 FE(DDSCAPS_PRIMARYSURFACE)
502 FE(DDSCAPS_PRIMARYSURFACELEFT)
503 FE(DDSCAPS_SYSTEMMEMORY)
504 FE(DDSCAPS_TEXTURE)
505 FE(DDSCAPS_3DDEVICE)
506 FE(DDSCAPS_VIDEOMEMORY)
507 FE(DDSCAPS_VISIBLE)
508 FE(DDSCAPS_WRITEONLY)
509 FE(DDSCAPS_ZBUFFER)
510 FE(DDSCAPS_OWNDC)
511 FE(DDSCAPS_LIVEVIDEO)
512 FE(DDSCAPS_HWCODEC)
513 FE(DDSCAPS_MODEX)
514 FE(DDSCAPS_MIPMAP)
515 FE(DDSCAPS_RESERVED2)
516 FE(DDSCAPS_ALLOCONLOAD)
517 FE(DDSCAPS_VIDEOPORT)
518 FE(DDSCAPS_LOCALVIDMEM)
519 FE(DDSCAPS_NONLOCALVIDMEM)
520 FE(DDSCAPS_STANDARDVGAMODE)
521 FE(DDSCAPS_OPTIMIZED)
522 #undef FE
524 DWORD flagmask = *((DWORD *) in);
525 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
526 if (flags[i].mask & flagmask)
527 DPRINTF("%s ",flags[i].name);
530 static void _dump_pixelformat_flag(DWORD flagmask) {
531 int i;
532 const struct {
533 DWORD mask;
534 char *name;
535 } flags[] = {
536 #define FE(x) { x, #x},
537 FE(DDPF_ALPHAPIXELS)
538 FE(DDPF_ALPHA)
539 FE(DDPF_FOURCC)
540 FE(DDPF_PALETTEINDEXED4)
541 FE(DDPF_PALETTEINDEXEDTO8)
542 FE(DDPF_PALETTEINDEXED8)
543 FE(DDPF_RGB)
544 FE(DDPF_COMPRESSED)
545 FE(DDPF_RGBTOYUV)
546 FE(DDPF_YUV)
547 FE(DDPF_ZBUFFER)
548 FE(DDPF_PALETTEINDEXED1)
549 FE(DDPF_PALETTEINDEXED2)
550 FE(DDPF_ZPIXELS)
551 #undef FE
553 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
554 if (flags[i].mask & flagmask)
555 DPRINTF("%s ",flags[i].name);
558 static void _dump_paletteformat(DWORD dwFlags) {
559 int i;
560 const struct {
561 DWORD mask;
562 char *name;
563 } flags[] = {
564 #define FE(x) { x, #x},
565 FE(DDPCAPS_4BIT)
566 FE(DDPCAPS_8BITENTRIES)
567 FE(DDPCAPS_8BIT)
568 FE(DDPCAPS_INITIALIZE)
569 FE(DDPCAPS_PRIMARYSURFACE)
570 FE(DDPCAPS_PRIMARYSURFACELEFT)
571 FE(DDPCAPS_ALLOW256)
572 FE(DDPCAPS_VSYNC)
573 FE(DDPCAPS_1BIT)
574 FE(DDPCAPS_2BIT)
575 FE(DDPCAPS_ALPHA)
576 #undef FE
578 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
579 if (flags[i].mask & dwFlags)
580 DPRINTF("%s ",flags[i].name);
581 DPRINTF("\n");
584 static void _dump_pixelformat(void *in) {
585 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
586 char *cmd;
588 DPRINTF("( ");
589 _dump_pixelformat_flag(pf->dwFlags);
590 if (pf->dwFlags & DDPF_FOURCC) {
591 DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
593 if (pf->dwFlags & DDPF_RGB) {
594 DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount);
595 switch (pf->u.dwRGBBitCount) {
596 case 4:
597 cmd = "%1lx";
598 break;
599 case 8:
600 cmd = "%02lx";
601 break;
602 case 16:
603 cmd = "%04lx";
604 break;
605 case 24:
606 cmd = "%06lx";
607 break;
608 case 32:
609 cmd = "%08lx";
610 break;
611 default:
612 ERR("Unexpected bit depth !\n");
613 cmd = "%d";
615 DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask);
616 DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask);
617 DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask);
618 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
619 DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask);
621 if (pf->dwFlags & DDPF_ZPIXELS) {
622 DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask);
625 if (pf->dwFlags & DDPF_ZBUFFER) {
626 DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth);
628 if (pf->dwFlags & DDPF_ALPHA) {
629 DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth);
631 DPRINTF(")");
634 static void _dump_colorkeyflag(DWORD ck) {
635 int i;
636 const struct {
637 DWORD mask;
638 char *name;
639 } flags[] = {
640 #define FE(x) { x, #x},
641 FE(DDCKEY_COLORSPACE)
642 FE(DDCKEY_DESTBLT)
643 FE(DDCKEY_DESTOVERLAY)
644 FE(DDCKEY_SRCBLT)
645 FE(DDCKEY_SRCOVERLAY)
646 #undef FE
648 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
649 if (flags[i].mask & ck)
650 DPRINTF("%s ",flags[i].name);
653 static void _dump_DWORD(void *in) {
654 DPRINTF("%ld", *((DWORD *) in));
656 static void _dump_PTR(void *in) {
657 DPRINTF("%p", *((void **) in));
659 static void _dump_DDCOLORKEY(void *in) {
660 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
662 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
665 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
666 int i;
667 struct {
668 DWORD mask;
669 char *name;
670 void (*func)(void *);
671 void *elt;
672 } flags[16], *fe = flags;
673 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
674 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
675 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
676 FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
677 FE(DDSD_PITCH, _dump_DWORD, lPitch);
678 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
679 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth);
680 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
681 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
682 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
683 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
684 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
685 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
686 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount);
687 FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate);
688 FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize);
689 FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface);
690 #undef FE
692 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
693 if (flags[i].mask & lpddsd->dwFlags) {
694 DPRINTF(" - %s : ",flags[i].name);
695 flags[i].func(flags[i].elt);
696 DPRINTF("\n");
701 /******************************************************************************
702 * IDirectDrawSurface methods
704 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
705 * DDS and DDS2 use those functions. (Function calls did not change (except
706 * using different DirectDrawSurfaceX version), just added flags and functions)
709 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
710 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
712 ICOM_THIS(IDirectDrawSurface4Impl,iface);
713 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
714 This,lprect,lpddsd,flags,(DWORD)hnd);
715 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
716 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
717 This,lprect,lpddsd,flags,(DWORD)hnd);
719 /* First, copy the Surface description */
720 *lpddsd = This->s.surface_desc;
721 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
722 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
724 /* If asked only for a part, change the surface pointer */
725 if (lprect) {
726 TRACE(" lprect: %dx%d-%dx%d\n",
727 lprect->top,lprect->left,lprect->bottom,lprect->right
729 if ((lprect->top < 0) ||
730 (lprect->left < 0) ||
731 (lprect->bottom < 0) ||
732 (lprect->right < 0)) {
733 ERR(" Negative values in LPRECT !!!\n");
734 return DDERR_INVALIDPARAMS;
737 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
738 (lprect->top*This->s.surface_desc.lPitch) +
739 lprect->left*GET_BPP(This->s.surface_desc));
740 } else {
741 assert(This->s.surface_desc.u1.lpSurface);
744 /* wait for any previous operations to complete */
745 #ifdef HAVE_LIBXXSHM
746 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE) &&
747 This->s.ddraw->e.xlib.xshm_active) {
749 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
750 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
752 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
754 #endif
755 return DD_OK;
758 #ifdef HAVE_LIBXXF86DGA
759 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
760 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
762 ICOM_THIS(IDirectDrawSurface4Impl,iface);
763 TRACE("(%p)->Unlock(%p)\n",This,surface);
764 return DD_OK;
766 #endif /* defined(HAVE_LIBXXF86DGA) */
768 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
769 if (This->s.ddraw->d.pixel_convert != NULL)
770 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
771 This->t.xlib.image->data,
772 This->s.surface_desc.dwWidth,
773 This->s.surface_desc.dwHeight,
774 This->s.surface_desc.lPitch,
775 This->s.palette);
777 #ifdef HAVE_LIBXXSHM
778 if (This->s.ddraw->e.xlib.xshm_active) {
780 X11DRV_EVENT_WaitReplaceShmCompletion( &This->s.ddraw->e.xlib.xshm_compl, This->s.ddraw->d.drawable );
782 /* let WaitShmCompletions track 'em for now */
783 /* (you may want to track it again whenever you implement DX7's partial surface locking,
784 where threads have concurrent access) */
785 X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
786 TSXShmPutImage(display,
787 This->s.ddraw->d.drawable,
788 DefaultGCOfScreen(X11DRV_GetXScreen()),
789 This->t.xlib.image,
790 0, 0, 0, 0,
791 This->t.xlib.image->width,
792 This->t.xlib.image->height,
793 True);
794 /* make sure the image is transferred ASAP */
795 TSXFlush(display);
797 else
798 #endif
799 TSXPutImage( display,
800 This->s.ddraw->d.drawable,
801 DefaultGCOfScreen(X11DRV_GetXScreen()),
802 This->t.xlib.image,
803 0, 0, 0, 0,
804 This->t.xlib.image->width,
805 This->t.xlib.image->height);
808 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
809 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
811 ICOM_THIS(IDirectDrawSurface4Impl,iface);
812 TRACE("(%p)->Unlock(%p)\n",This,surface);
814 if (!This->s.ddraw->d.paintable)
815 return DD_OK;
817 /* Only redraw the screen when unlocking the buffer that is on screen */
818 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
819 Xlib_copy_surface_on_screen(This);
821 if (This->s.palette && This->s.palette->cm)
822 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
824 return DD_OK;
827 static IDirectDrawSurface4Impl* _common_find_flipto(
828 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
830 int i,j,flipable=0;
831 struct _surface_chain *chain = This->s.chain;
833 /* if there was no override flipto, look for current backbuffer */
834 if (!flipto) {
835 /* walk the flip chain looking for backbuffer */
836 for (i=0;i<chain->nrofsurfaces;i++) {
837 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
838 flipable++;
839 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
840 flipto = chain->surfaces[i];
842 /* sanity checks ... */
843 if (!flipto) {
844 if (flipable>1) {
845 for (i=0;i<chain->nrofsurfaces;i++)
846 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
847 break;
848 if (i==chain->nrofsurfaces) {
849 /* we do not have a frontbuffer either */
850 for (i=0;i<chain->nrofsurfaces;i++)
851 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
852 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
853 break;
855 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
856 int k = j % chain->nrofsurfaces;
857 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
858 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
859 flipto = chain->surfaces[k];
860 break;
865 if (!flipto)
866 flipto = This;
868 TRACE("flipping to %p\n",flipto);
870 return flipto;
873 #ifdef HAVE_LIBXXF86DGA
874 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
875 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
877 ICOM_THIS(IDirectDrawSurface4Impl,iface);
878 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
879 DWORD xheight;
880 LPBYTE surf;
882 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
883 iflipto = _common_find_flipto(This,iflipto);
885 /* and flip! */
886 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
887 if (iflipto->s.palette && iflipto->s.palette->cm)
888 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
889 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
892 /* We need to switch the lowlevel surfaces, for DGA this is: */
894 /* The height within the framebuffer */
895 xheight = This->t.dga.fb_height;
896 This->t.dga.fb_height = iflipto->t.dga.fb_height;
897 iflipto->t.dga.fb_height = xheight;
899 /* And the assciated surface pointer */
900 surf = This->s.surface_desc.u1.lpSurface;
901 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
902 iflipto->s.surface_desc.u1.lpSurface = surf;
904 return DD_OK;
906 #endif /* defined(HAVE_LIBXXF86DGA) */
908 #ifdef HAVE_LIBXXF86DGA2
909 static HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
910 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
912 ICOM_THIS(IDirectDrawSurface4Impl,iface);
913 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
914 DWORD xheight;
915 LPBYTE surf;
917 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
918 iflipto = _common_find_flipto(This,iflipto);
920 /* and flip! */
921 TSXDGASetViewport(display,DefaultScreen(display),0,iflipto->t.dga.fb_height, XDGAFlipRetrace);
922 TSXDGASync(display,DefaultScreen(display));
923 TSXFlush(display);
924 if (iflipto->s.palette && iflipto->s.palette->cm)
925 TSXDGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
926 /* We need to switch the lowlevel surfaces, for DGA this is: */
928 /* The height within the framebuffer */
929 xheight = This->t.dga.fb_height;
930 This->t.dga.fb_height = iflipto->t.dga.fb_height;
931 iflipto->t.dga.fb_height = xheight;
933 /* And the assciated surface pointer */
934 surf = This->s.surface_desc.u1.lpSurface;
935 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
936 iflipto->s.surface_desc.u1.lpSurface = surf;
938 return DD_OK;
940 #endif /* defined(HAVE_LIBXXF86DGA2) */
942 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
943 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
945 ICOM_THIS(IDirectDrawSurface4Impl,iface);
946 XImage *image;
947 LPBYTE surf;
948 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
950 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
951 iflipto = _common_find_flipto(This,iflipto);
953 #if defined(HAVE_MESAGL) && 0 /* does not work */
954 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
955 TRACE(" - OpenGL flip\n");
956 ENTER_GL();
957 glXSwapBuffers(display, This->s.ddraw->d.drawable);
958 LEAVE_GL();
960 return DD_OK;
962 #endif /* defined(HAVE_MESAGL) */
964 if (!This->s.ddraw->d.paintable)
965 return DD_OK;
967 /* We need to switch the lowlevel surfaces, for xlib this is: */
968 /* The surface pointer */
969 surf = This->s.surface_desc.u1.lpSurface;
970 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
971 iflipto->s.surface_desc.u1.lpSurface = surf;
972 /* the associated ximage */
973 image = This->t.xlib.image;
974 This->t.xlib.image = iflipto->t.xlib.image;
975 iflipto->t.xlib.image = image;
977 #ifdef HAVE_LIBXXSHM
978 if (This->s.ddraw->e.xlib.xshm_active) {
980 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
981 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
983 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
985 #endif
986 Xlib_copy_surface_on_screen(This);
988 if (iflipto->s.palette && iflipto->s.palette->cm)
989 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
990 return DD_OK;
993 /* The IDirectDrawSurface4::SetPalette method attaches the specified
994 * DirectDrawPalette object to a surface. The surface uses this palette for all
995 * subsequent operations. The palette change takes place immediately.
997 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
998 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1000 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1001 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1002 int i;
1003 TRACE("(%p)->(%p)\n",This,ipal);
1005 if (ipal == NULL) {
1006 if( This->s.palette != NULL )
1007 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1008 This->s.palette = ipal;
1010 return DD_OK;
1013 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8))
1015 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
1016 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
1018 if (!Options.managed)
1019 TSXInstallColormap(display,ipal->cm);
1021 for (i=0;i<256;i++) {
1022 XColor xc;
1024 xc.red = ipal->palents[i].peRed<<8;
1025 xc.blue = ipal->palents[i].peBlue<<8;
1026 xc.green = ipal->palents[i].peGreen<<8;
1027 xc.flags = DoRed|DoBlue|DoGreen;
1028 xc.pixel = i;
1029 TSXStoreColor(display,ipal->cm,&xc);
1031 TSXInstallColormap(display,ipal->cm);
1034 /* According to spec, we are only supposed to
1035 * AddRef if this is not the same palette.
1037 if( This->s.palette != ipal )
1039 if( ipal != NULL )
1040 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1041 if( This->s.palette != NULL )
1042 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1043 This->s.palette = ipal;
1044 /* Perform the refresh */
1045 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
1047 return DD_OK;
1050 #ifdef HAVE_LIBXXF86DGA
1051 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
1052 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1054 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1055 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1056 TRACE("(%p)->(%p)\n",This,ipal);
1058 /* According to spec, we are only supposed to
1059 * AddRef if this is not the same palette.
1061 if( This->s.palette != ipal )
1063 if( ipal != NULL )
1064 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1065 if( This->s.palette != NULL )
1066 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1067 This->s.palette = ipal;
1068 #ifdef HAVE_LIBXXF86DGA2
1069 if (This->s.ddraw->e.dga.version == 2)
1070 TSXDGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1071 else
1072 #endif /* defined(HAVE_LIBXXF86DGA2) */
1073 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1075 return DD_OK;
1077 #endif /* defined(HAVE_LIBXXF86DGA) */
1079 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
1081 int x, y;
1082 LPBYTE first;
1084 /* Do first row */
1086 #define COLORFILL_ROW(type) { \
1087 type *d = (type *) buf; \
1088 for (x = 0; x < width; x++) \
1089 d[x] = (type) color; \
1090 break; \
1093 switch(bpp) {
1094 case 1: COLORFILL_ROW(BYTE)
1095 case 2: COLORFILL_ROW(WORD)
1096 case 4: COLORFILL_ROW(DWORD)
1097 default:
1098 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
1099 return DDERR_UNSUPPORTED;
1102 #undef COLORFILL_ROW
1104 /* Now copy first row */
1105 first = buf;
1106 for (y = 1; y < height; y++) {
1107 buf += lPitch;
1108 memcpy(buf, first, width * bpp);
1111 return DD_OK;
1114 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
1115 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
1117 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1118 RECT xdst,xsrc;
1119 DDSURFACEDESC ddesc,sdesc;
1120 HRESULT ret = DD_OK;
1121 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
1122 int x, y;
1123 LPBYTE dbuf, sbuf;
1125 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
1127 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
1128 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1130 if (TRACE_ON(ddraw)) {
1131 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1132 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1133 TRACE("\tflags: ");
1134 _dump_DDBLT(dwFlags);
1135 if (dwFlags & DDBLT_DDFX) {
1136 TRACE("\tblitfx: ");
1137 _dump_DDBLTFX(lpbltfx->dwDDFX);
1141 if (rdst) {
1142 if ((rdst->top < 0) ||
1143 (rdst->left < 0) ||
1144 (rdst->bottom < 0) ||
1145 (rdst->right < 0)) {
1146 ERR(" Negative values in LPRECT !!!\n");
1147 goto release;
1149 memcpy(&xdst,rdst,sizeof(xdst));
1150 } else {
1151 xdst.top = 0;
1152 xdst.bottom = ddesc.dwHeight;
1153 xdst.left = 0;
1154 xdst.right = ddesc.dwWidth;
1157 if (rsrc) {
1158 if ((rsrc->top < 0) ||
1159 (rsrc->left < 0) ||
1160 (rsrc->bottom < 0) ||
1161 (rsrc->right < 0)) {
1162 ERR(" Negative values in LPRECT !!!\n");
1163 goto release;
1165 memcpy(&xsrc,rsrc,sizeof(xsrc));
1166 } else {
1167 if (src) {
1168 xsrc.top = 0;
1169 xsrc.bottom = sdesc.dwHeight;
1170 xsrc.left = 0;
1171 xsrc.right = sdesc.dwWidth;
1172 } else {
1173 memset(&xsrc,0,sizeof(xsrc));
1177 bpp = GET_BPP(ddesc);
1178 srcheight = xsrc.bottom - xsrc.top;
1179 srcwidth = xsrc.right - xsrc.left;
1180 dstheight = xdst.bottom - xdst.top;
1181 dstwidth = xdst.right - xdst.left;
1182 width = (xdst.right - xdst.left) * bpp;
1183 dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1185 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1187 /* First, all the 'source-less' blits */
1188 if (dwFlags & DDBLT_COLORFILL) {
1189 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1190 ddesc.lPitch, lpbltfx->u4.dwFillColor);
1191 dwFlags &= ~DDBLT_COLORFILL;
1194 if (dwFlags & DDBLT_DEPTHFILL) {
1195 #ifdef HAVE_MESAGL
1196 GLboolean ztest;
1198 /* Clears the screen */
1199 TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
1200 glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1201 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1202 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1203 glClear(GL_DEPTH_BUFFER_BIT);
1204 glDepthMask(ztest);
1206 dwFlags &= ~(DDBLT_DEPTHFILL);
1207 #endif /* defined(HAVE_MESAGL) */
1210 if (dwFlags & DDBLT_ROP) {
1211 /* Catch some degenerate cases here */
1212 switch(lpbltfx->dwROP) {
1213 case BLACKNESS:
1214 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1215 break;
1216 case 0xAA0029: /* No-op */
1217 break;
1218 case WHITENESS:
1219 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1220 break;
1221 default:
1222 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
1223 goto error;
1225 dwFlags &= ~DDBLT_ROP;
1228 if (dwFlags & DDBLT_DDROPS) {
1229 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
1232 /* Now the 'with source' blits */
1233 if (src) {
1234 LPBYTE sbase;
1235 int sx, xinc, sy, yinc;
1237 sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1238 xinc = (srcwidth << 16) / dstwidth;
1239 yinc = (srcheight << 16) / dstheight;
1241 if (!dwFlags) {
1243 /* No effects, we can cheat here */
1244 if (dstwidth == srcwidth) {
1245 if (dstheight == srcheight) {
1246 /* No stretching in either direction. This needs to be as fast as possible */
1247 sbuf = sbase;
1248 for (y = 0; y < dstheight; y++) {
1249 memcpy(dbuf, sbuf, width);
1250 sbuf += sdesc.lPitch;
1251 dbuf += ddesc.lPitch;
1253 } else {
1254 /* Stretching in Y direction only */
1255 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1256 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1257 memcpy(dbuf, sbuf, width);
1258 dbuf += ddesc.lPitch;
1261 } else {
1262 /* Stretching in X direction */
1263 int last_sy = -1;
1264 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1265 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1267 if ((sy >> 16) == (last_sy >> 16)) {
1268 /* Same as last row - copy already stretched row */
1269 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1270 } else {
1272 #define STRETCH_ROW(type) { \
1273 type *s = (type *) sbuf, *d = (type *) dbuf; \
1274 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1275 d[x] = s[sx >> 16]; \
1276 break; }
1278 switch(bpp) {
1279 case 1: STRETCH_ROW(BYTE)
1280 case 2: STRETCH_ROW(WORD)
1281 case 4: STRETCH_ROW(DWORD)
1282 default:
1283 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1284 ret = DDERR_UNSUPPORTED;
1285 goto error;
1288 #undef STRETCH_ROW
1291 last_sy = sy;
1292 dbuf += ddesc.lPitch;
1295 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1296 DWORD keylow, keyhigh;
1298 if (dwFlags & DDBLT_KEYSRC) {
1299 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1300 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1301 } else {
1302 /* I'm not sure if this is correct */
1303 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1304 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1305 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1309 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1310 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1312 #define COPYROW_COLORKEY(type) { \
1313 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1314 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1315 tmp = s[sx >> 16]; \
1316 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1318 break; }
1320 switch (bpp) {
1321 case 1: COPYROW_COLORKEY(BYTE)
1322 case 2: COPYROW_COLORKEY(WORD)
1323 case 4: COPYROW_COLORKEY(DWORD)
1324 default:
1325 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1326 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1327 ret = DDERR_UNSUPPORTED;
1328 goto error;
1330 dbuf += ddesc.lPitch;
1333 #undef COPYROW_COLORKEY
1335 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1340 error:
1342 if (dwFlags && FIXME_ON(ddraw)) {
1343 FIXME("\tUnsupported flags: ");
1344 _dump_DDBLT(dwFlags);
1346 release:
1348 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1349 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1351 return DD_OK;
1354 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1355 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1357 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1358 int bpp, w, h, x, y;
1359 DDSURFACEDESC ddesc,sdesc;
1360 HRESULT ret = DD_OK;
1361 LPBYTE sbuf, dbuf;
1362 RECT rsrc2;
1365 if (TRACE_ON(ddraw)) {
1366 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1367 This,dstx,dsty,src,rsrc,trans
1369 FIXME(" trans:");
1370 if (FIXME_ON(ddraw))
1371 _dump_DDBLTFAST(trans);
1372 if (rsrc)
1373 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1374 else
1375 FIXME(" srcrect: NULL\n");
1378 /* We need to lock the surfaces, or we won't get refreshes when done. */
1379 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1380 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1382 if (!rsrc) {
1383 WARN("rsrc is NULL!\n");
1384 rsrc = &rsrc2;
1385 rsrc->left = rsrc->top = 0;
1386 rsrc->right = sdesc.dwWidth;
1387 rsrc->bottom = sdesc.dwHeight;
1390 bpp = GET_BPP(This->s.surface_desc);
1391 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1392 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1395 h=rsrc->bottom-rsrc->top;
1396 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1397 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1398 if (h<0) h=0;
1400 w=rsrc->right-rsrc->left;
1401 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1402 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1403 if (w<0) w=0;
1405 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1406 DWORD keylow, keyhigh;
1407 if (trans & DDBLTFAST_SRCCOLORKEY) {
1408 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1409 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1410 } else {
1411 /* I'm not sure if this is correct */
1412 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1413 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1414 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1417 #define COPYBOX_COLORKEY(type) { \
1418 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1419 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1420 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1421 for (y = 0; y < h; y++) { \
1422 for (x = 0; x < w; x++) { \
1423 tmp = s[x]; \
1424 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1426 (LPBYTE)s += sdesc.lPitch; \
1427 (LPBYTE)d += ddesc.lPitch; \
1429 break; \
1432 switch (bpp) {
1433 case 1: COPYBOX_COLORKEY(BYTE)
1434 case 2: COPYBOX_COLORKEY(WORD)
1435 case 4: COPYBOX_COLORKEY(DWORD)
1436 default:
1437 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1438 ret = DDERR_UNSUPPORTED;
1439 goto error;
1442 #undef COPYBOX_COLORKEY
1444 } else {
1445 int width = w * bpp;
1447 for (y = 0; y < h; y++) {
1448 memcpy(dbuf, sbuf, width);
1449 sbuf += sdesc.lPitch;
1450 dbuf += ddesc.lPitch;
1454 error:
1456 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1457 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1458 return ret;
1461 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1462 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1464 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1465 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1466 This,ddbltbatch,x,y
1468 return DD_OK;
1471 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1472 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1474 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1475 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1476 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1477 return DD_OK;
1480 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1481 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1482 ) {
1483 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1484 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1486 /* Simply copy the surface description stored in the object */
1487 *ddsd = This->s.surface_desc;
1489 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1491 return DD_OK;
1494 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1495 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1496 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1497 return ++(This->ref);
1500 #ifdef HAVE_LIBXXF86DGA
1501 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1502 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1504 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1506 if (--(This->ref))
1507 return This->ref;
1509 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1510 /* clear out of surface list */
1511 if (This->t.dga.fb_height == -1)
1512 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1513 else
1514 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1516 /* Free the DIBSection (if any) */
1517 if (This->s.hdc != 0) {
1518 SelectObject(This->s.hdc, This->s.holdbitmap);
1519 DeleteDC(This->s.hdc);
1520 DeleteObject(This->s.DIBsection);
1523 /* Free the clipper if attached to this surface */
1524 if( This->s.lpClipper )
1525 IDirectDrawClipper_Release(This->s.lpClipper);
1527 HeapFree(GetProcessHeap(),0,This);
1528 return S_OK;
1530 #endif /* defined(HAVE_LIBXXF86DGA) */
1532 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1533 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1535 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1537 if (--(This->ref))
1538 return This->ref;
1540 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1542 if (This->t.xlib.image != NULL) {
1543 if (This->s.ddraw->d.pixel_convert != NULL) {
1544 /* In pixel conversion mode, there are 2 buffers to release. */
1545 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1547 #ifdef HAVE_LIBXXSHM
1548 if (This->s.ddraw->e.xlib.xshm_active) {
1549 TSXShmDetach(display, &(This->t.xlib.shminfo));
1550 TSXDestroyImage(This->t.xlib.image);
1551 shmdt(This->t.xlib.shminfo.shmaddr);
1552 } else {
1553 #endif
1554 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1555 This->t.xlib.image->data = NULL;
1556 TSXDestroyImage(This->t.xlib.image);
1557 #ifdef HAVE_LIBXXSHM
1559 #endif
1560 } else {
1561 This->t.xlib.image->data = NULL;
1563 #ifdef HAVE_LIBXXSHM
1564 if (This->s.ddraw->e.xlib.xshm_active) {
1565 TSXShmDetach(display, &(This->t.xlib.shminfo));
1566 TSXDestroyImage(This->t.xlib.image);
1567 shmdt(This->t.xlib.shminfo.shmaddr);
1568 } else {
1569 #endif
1570 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1571 TSXDestroyImage(This->t.xlib.image);
1572 #ifdef HAVE_LIBXXSHM
1574 #endif
1576 This->t.xlib.image = 0;
1577 } else {
1578 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1581 if (This->s.palette)
1582 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1584 /* Free the DIBSection (if any) */
1585 if (This->s.hdc != 0) {
1586 SelectObject(This->s.hdc, This->s.holdbitmap);
1587 DeleteDC(This->s.hdc);
1588 DeleteObject(This->s.DIBsection);
1591 /* Free the clipper if present */
1592 if( This->s.lpClipper )
1593 IDirectDrawClipper_Release(This->s.lpClipper);
1595 HeapFree(GetProcessHeap(),0,This);
1596 return S_OK;
1599 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1600 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1602 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1603 int i,found = 0,xstart;
1604 struct _surface_chain *chain;
1606 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1607 if (TRACE_ON(ddraw)) {
1608 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1609 DPRINTF("\n");
1611 chain = This->s.chain;
1612 if (!chain)
1613 return DDERR_NOTFOUND;
1615 for (i=0;i<chain->nrofsurfaces;i++)
1616 if (chain->surfaces[i] == This)
1617 break;
1619 xstart = i;
1620 for (i=0;i<chain->nrofsurfaces;i++) {
1621 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1622 #if 0
1623 if (found) /* may not find the same caps twice, (doc) */
1624 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1625 #endif
1626 found = (i+1)+xstart;
1629 if (!found)
1630 return DDERR_NOTFOUND;
1631 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1632 /* FIXME: AddRef? */
1633 TRACE("found %p\n",*lpdsf);
1634 return DD_OK;
1637 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1638 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1640 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1641 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1643 return DDERR_ALREADYINITIALIZED;
1646 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1647 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1649 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1650 TRACE("(%p)->(%p)\n",This,pf);
1652 *pf = This->s.surface_desc.ddpfPixelFormat;
1653 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1654 return DD_OK;
1657 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1658 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1659 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1660 return DD_OK;
1663 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1664 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1666 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1667 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1668 return DD_OK;
1671 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1672 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
1674 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1675 TRACE("(%p)->(%p)!\n",This,lpClipper);
1677 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
1678 This->s.lpClipper = lpClipper;
1679 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
1680 return DD_OK;
1683 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1684 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1686 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1687 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1688 int i;
1689 struct _surface_chain *chain;
1691 FIXME("(%p)->(%p)\n",This,surf);
1692 chain = This->s.chain;
1694 /* IDirectDrawSurface4_AddRef(surf); */
1696 if (chain) {
1697 for (i=0;i<chain->nrofsurfaces;i++)
1698 if (chain->surfaces[i] == isurf)
1699 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1700 } else {
1701 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1702 chain->nrofsurfaces = 1;
1703 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1704 chain->surfaces[0] = This;
1705 This->s.chain = chain;
1708 if (chain->surfaces)
1709 chain->surfaces = HeapReAlloc(
1710 GetProcessHeap(),
1712 chain->surfaces,
1713 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1715 else
1716 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1717 isurf->s.chain = chain;
1718 chain->surfaces[chain->nrofsurfaces++] = isurf;
1719 return DD_OK;
1722 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1723 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1724 DDSURFACEDESC desc;
1725 BITMAPINFO *b_info;
1726 UINT usage;
1728 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1730 /* Creates a DIB Section of the same size / format as the surface */
1731 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1733 if (This->s.hdc == 0) {
1734 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1735 case 16:
1736 case 32:
1737 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1738 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1739 break;
1740 #endif
1742 case 24:
1743 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1744 break;
1746 default:
1747 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1748 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1749 break;
1752 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1753 b_info->bmiHeader.biWidth = desc.dwWidth;
1754 b_info->bmiHeader.biHeight = desc.dwHeight;
1755 b_info->bmiHeader.biPlanes = 1;
1756 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1757 #if 0
1758 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1759 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1760 #endif
1761 b_info->bmiHeader.biCompression = BI_RGB;
1762 #if 0
1763 else
1764 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1765 #endif
1766 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1767 b_info->bmiHeader.biXPelsPerMeter = 0;
1768 b_info->bmiHeader.biYPelsPerMeter = 0;
1769 b_info->bmiHeader.biClrUsed = 0;
1770 b_info->bmiHeader.biClrImportant = 0;
1772 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1773 case 16:
1774 case 32:
1775 #if 0
1777 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1779 usage = 0;
1780 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1781 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1782 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1784 break;
1785 #endif
1786 case 24:
1787 /* Nothing to do */
1788 usage = DIB_RGB_COLORS;
1789 break;
1791 default: {
1792 int i;
1794 /* Fill the palette */
1795 usage = DIB_RGB_COLORS;
1797 if (This->s.palette == NULL) {
1798 ERR("Bad palette !!!\n");
1799 } else {
1800 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1801 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1803 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1804 rgb[i].rgbBlue = pent[i].peBlue;
1805 rgb[i].rgbRed = pent[i].peRed;
1806 rgb[i].rgbGreen = pent[i].peGreen;
1810 break;
1812 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1813 b_info,
1814 usage,
1815 &(This->s.bitmap_data),
1819 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1820 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1822 /* b_info is not useful anymore */
1823 HeapFree(GetProcessHeap(), 0, b_info);
1825 /* Create the DC */
1826 This->s.hdc = CreateCompatibleDC(0);
1827 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1830 /* Copy our surface in the DIB section */
1831 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1832 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1833 else
1834 /* TODO */
1835 FIXME("This case has to be done :/\n");
1837 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1838 *lphdc = This->s.hdc;
1840 return DD_OK;
1843 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1844 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1846 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1847 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1848 /* Copy the DIB section to our surface */
1849 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1850 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1851 } else {
1852 /* TODO */
1853 FIXME("This case has to be done :/\n");
1855 /* Unlock the surface */
1856 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1857 return DD_OK;
1860 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1861 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1863 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
1865 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1866 * the same interface. And IUnknown does that too of course.
1868 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1869 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1870 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1871 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1872 IsEqualGUID( &IID_IUnknown, refiid )
1874 *obj = This;
1875 IDirectDrawSurface4_AddRef(iface);
1877 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1878 return S_OK;
1880 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1882 /* Texture interface */
1883 *obj = d3dtexture2_create(This);
1884 IDirectDrawSurface4_AddRef(iface);
1885 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1886 return S_OK;
1888 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1890 /* Texture interface */
1891 *obj = d3dtexture_create(This);
1892 IDirectDrawSurface4_AddRef(iface);
1894 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1896 return S_OK;
1898 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1899 /* It is the OpenGL Direct3D Device */
1900 IDirectDrawSurface4_AddRef(iface);
1901 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1902 return S_OK;
1905 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
1906 return OLE_E_ENUM_NOMORE;
1909 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1910 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1911 TRACE("(%p)->(), stub!\n",This);
1912 return DD_OK; /* hmm */
1915 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1916 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1917 int i;
1918 struct _surface_chain *chain = This->s.chain;
1920 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1921 for (i=0;i<chain->nrofsurfaces;i++) {
1922 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1923 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1924 return DD_OK; /* FIXME: return value correct? */
1926 return DD_OK;
1929 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1930 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1931 FIXME("(%p)->(),stub!\n",This);
1932 return DD_OK;
1935 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1936 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1938 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1939 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1940 if (TRACE_ON(ddraw)) {
1941 _dump_colorkeyflag(dwFlags);
1942 DPRINTF(" : ");
1943 _dump_DDCOLORKEY((void *) ckey);
1944 DPRINTF("\n");
1947 /* If this surface was loaded as a texture, call also the texture
1948 SetColorKey callback */
1949 if (This->s.texture) {
1950 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1953 if( dwFlags & DDCKEY_SRCBLT )
1955 dwFlags &= ~DDCKEY_SRCBLT;
1956 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1957 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1960 if( dwFlags & DDCKEY_DESTBLT )
1962 dwFlags &= ~DDCKEY_DESTBLT;
1963 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1964 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1967 if( dwFlags & DDCKEY_SRCOVERLAY )
1969 dwFlags &= ~DDCKEY_SRCOVERLAY;
1970 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1971 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1974 if( dwFlags & DDCKEY_DESTOVERLAY )
1976 dwFlags &= ~DDCKEY_DESTOVERLAY;
1977 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1978 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1981 if( dwFlags )
1983 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1986 return DD_OK;
1990 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1991 LPDIRECTDRAWSURFACE4 iface,
1992 LPRECT lpRect )
1994 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1995 FIXME("(%p)->(%p),stub!\n",This,lpRect);
1997 return DD_OK;
2000 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
2001 LPDIRECTDRAWSURFACE4 iface,
2002 DWORD dwFlags,
2003 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
2005 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2006 int i;
2007 struct _surface_chain *chain;
2009 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
2010 chain = This->s.chain;
2011 for (i=0;i<chain->nrofsurfaces;i++) {
2012 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
2013 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
2015 chain->surfaces[i]->s.chain = NULL;
2016 memcpy( chain->surfaces+i,
2017 chain->surfaces+(i+1),
2018 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
2020 chain->surfaces = HeapReAlloc(
2021 GetProcessHeap(),
2023 chain->surfaces,
2024 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
2026 chain->nrofsurfaces--;
2027 return DD_OK;
2030 return DD_OK;
2033 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
2034 LPDIRECTDRAWSURFACE4 iface,
2035 DWORD dwFlags,
2036 LPVOID lpContext,
2037 LPDDENUMSURFACESCALLBACK lpfnCallback )
2039 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2040 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
2041 lpContext, lpfnCallback );
2043 return DD_OK;
2046 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
2047 LPDIRECTDRAWSURFACE4 iface,
2048 LPDIRECTDRAWCLIPPER* lplpDDClipper )
2050 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2051 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
2053 return DD_OK;
2056 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
2057 LPDIRECTDRAWSURFACE4 iface,
2058 DWORD dwFlags,
2059 LPDDCOLORKEY lpDDColorKey )
2061 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2062 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
2064 if( dwFlags & DDCKEY_SRCBLT ) {
2065 dwFlags &= ~DDCKEY_SRCBLT;
2066 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
2069 if( dwFlags & DDCKEY_DESTBLT )
2071 dwFlags &= ~DDCKEY_DESTBLT;
2072 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
2075 if( dwFlags & DDCKEY_SRCOVERLAY )
2077 dwFlags &= ~DDCKEY_SRCOVERLAY;
2078 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
2081 if( dwFlags & DDCKEY_DESTOVERLAY )
2083 dwFlags &= ~DDCKEY_DESTOVERLAY;
2084 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
2087 if( dwFlags )
2089 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2092 return DD_OK;
2095 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
2096 LPDIRECTDRAWSURFACE4 iface,
2097 DWORD dwFlags )
2099 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2100 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2102 return DD_OK;
2105 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
2106 LPDIRECTDRAWSURFACE4 iface,
2107 LPDIRECTDRAWPALETTE* lplpDDPalette )
2109 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2110 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
2112 if (This->s.palette != NULL) {
2113 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
2115 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
2116 return DD_OK;
2117 } else {
2118 return DDERR_NOPALETTEATTACHED;
2122 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
2123 LPDIRECTDRAWSURFACE4 iface,
2124 LONG lX,
2125 LONG lY)
2127 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2128 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
2130 return DD_OK;
2133 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
2134 LPDIRECTDRAWSURFACE4 iface,
2135 LPRECT lpSrcRect,
2136 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
2137 LPRECT lpDestRect,
2138 DWORD dwFlags,
2139 LPDDOVERLAYFX lpDDOverlayFx )
2141 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2142 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
2143 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
2145 return DD_OK;
2148 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
2149 LPDIRECTDRAWSURFACE4 iface,
2150 DWORD dwFlags )
2152 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2153 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2155 return DD_OK;
2158 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2159 LPDIRECTDRAWSURFACE4 iface,
2160 DWORD dwFlags,
2161 LPDIRECTDRAWSURFACE4 lpDDSReference )
2163 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2164 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2166 return DD_OK;
2169 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2170 LPDIRECTDRAWSURFACE4 iface,
2171 LPVOID* lplpDD )
2173 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2174 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2176 /* Not sure about that... */
2177 *lplpDD = (void *) This->s.ddraw;
2179 return DD_OK;
2182 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2183 LPDIRECTDRAWSURFACE4 iface,
2184 DWORD dwFlags )
2186 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2187 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2189 return DD_OK;
2192 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2193 LPDIRECTDRAWSURFACE4 iface,
2194 DWORD dwFlags )
2196 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2197 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2199 return DD_OK;
2202 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2203 LPDIRECTDRAWSURFACE4 iface,
2204 LPDDSURFACEDESC lpDDSD,
2205 DWORD dwFlags )
2207 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2208 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2210 return DD_OK;
2213 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2214 REFGUID guidTag,
2215 LPVOID lpData,
2216 DWORD cbSize,
2217 DWORD dwFlags) {
2218 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2219 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2221 return DD_OK;
2224 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2225 REFGUID guidTag,
2226 LPVOID lpBuffer,
2227 LPDWORD lpcbBufferSize) {
2228 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2229 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2231 return DD_OK;
2234 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2235 REFGUID guidTag) {
2236 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2237 FIXME("(%p)->(%p)\n", This, guidTag);
2239 return DD_OK;
2242 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2243 LPDWORD lpValue) {
2244 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2245 FIXME("(%p)->(%p)\n", This, lpValue);
2247 return DD_OK;
2250 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2251 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2252 FIXME("(%p)\n", This);
2254 return DD_OK;
2257 #ifdef HAVE_LIBXXF86DGA
2258 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2260 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2261 IDirectDrawSurface4Impl_QueryInterface,
2262 IDirectDrawSurface4Impl_AddRef,
2263 DGA_IDirectDrawSurface4Impl_Release,
2264 IDirectDrawSurface4Impl_AddAttachedSurface,
2265 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2266 IDirectDrawSurface4Impl_Blt,
2267 IDirectDrawSurface4Impl_BltBatch,
2268 IDirectDrawSurface4Impl_BltFast,
2269 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2270 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2271 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2272 DGA_IDirectDrawSurface4Impl_Flip,
2273 IDirectDrawSurface4Impl_GetAttachedSurface,
2274 IDirectDrawSurface4Impl_GetBltStatus,
2275 IDirectDrawSurface4Impl_GetCaps,
2276 IDirectDrawSurface4Impl_GetClipper,
2277 IDirectDrawSurface4Impl_GetColorKey,
2278 IDirectDrawSurface4Impl_GetDC,
2279 IDirectDrawSurface4Impl_GetFlipStatus,
2280 IDirectDrawSurface4Impl_GetOverlayPosition,
2281 IDirectDrawSurface4Impl_GetPalette,
2282 IDirectDrawSurface4Impl_GetPixelFormat,
2283 IDirectDrawSurface4Impl_GetSurfaceDesc,
2284 IDirectDrawSurface4Impl_Initialize,
2285 IDirectDrawSurface4Impl_IsLost,
2286 IDirectDrawSurface4Impl_Lock,
2287 IDirectDrawSurface4Impl_ReleaseDC,
2288 IDirectDrawSurface4Impl_Restore,
2289 IDirectDrawSurface4Impl_SetClipper,
2290 IDirectDrawSurface4Impl_SetColorKey,
2291 IDirectDrawSurface4Impl_SetOverlayPosition,
2292 DGA_IDirectDrawSurface4Impl_SetPalette,
2293 DGA_IDirectDrawSurface4Impl_Unlock,
2294 IDirectDrawSurface4Impl_UpdateOverlay,
2295 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2296 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2297 IDirectDrawSurface4Impl_GetDDInterface,
2298 IDirectDrawSurface4Impl_PageLock,
2299 IDirectDrawSurface4Impl_PageUnlock,
2300 IDirectDrawSurface4Impl_SetSurfaceDesc,
2301 IDirectDrawSurface4Impl_SetPrivateData,
2302 IDirectDrawSurface4Impl_GetPrivateData,
2303 IDirectDrawSurface4Impl_FreePrivateData,
2304 IDirectDrawSurface4Impl_GetUniquenessValue,
2305 IDirectDrawSurface4Impl_ChangeUniquenessValue
2307 #endif /* defined(HAVE_LIBXXF86DGA) */
2309 #ifdef HAVE_LIBXXF86DGA2
2310 static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
2312 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2313 IDirectDrawSurface4Impl_QueryInterface,
2314 IDirectDrawSurface4Impl_AddRef,
2315 DGA_IDirectDrawSurface4Impl_Release,
2316 IDirectDrawSurface4Impl_AddAttachedSurface,
2317 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2318 IDirectDrawSurface4Impl_Blt,
2319 IDirectDrawSurface4Impl_BltBatch,
2320 IDirectDrawSurface4Impl_BltFast,
2321 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2322 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2323 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2324 DGA2_IDirectDrawSurface4Impl_Flip,
2325 IDirectDrawSurface4Impl_GetAttachedSurface,
2326 IDirectDrawSurface4Impl_GetBltStatus,
2327 IDirectDrawSurface4Impl_GetCaps,
2328 IDirectDrawSurface4Impl_GetClipper,
2329 IDirectDrawSurface4Impl_GetColorKey,
2330 IDirectDrawSurface4Impl_GetDC,
2331 IDirectDrawSurface4Impl_GetFlipStatus,
2332 IDirectDrawSurface4Impl_GetOverlayPosition,
2333 IDirectDrawSurface4Impl_GetPalette,
2334 IDirectDrawSurface4Impl_GetPixelFormat,
2335 IDirectDrawSurface4Impl_GetSurfaceDesc,
2336 IDirectDrawSurface4Impl_Initialize,
2337 IDirectDrawSurface4Impl_IsLost,
2338 IDirectDrawSurface4Impl_Lock,
2339 IDirectDrawSurface4Impl_ReleaseDC,
2340 IDirectDrawSurface4Impl_Restore,
2341 IDirectDrawSurface4Impl_SetClipper,
2342 IDirectDrawSurface4Impl_SetColorKey,
2343 IDirectDrawSurface4Impl_SetOverlayPosition,
2344 DGA_IDirectDrawSurface4Impl_SetPalette,
2345 DGA_IDirectDrawSurface4Impl_Unlock,
2346 IDirectDrawSurface4Impl_UpdateOverlay,
2347 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2348 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2349 IDirectDrawSurface4Impl_GetDDInterface,
2350 IDirectDrawSurface4Impl_PageLock,
2351 IDirectDrawSurface4Impl_PageUnlock,
2352 IDirectDrawSurface4Impl_SetSurfaceDesc,
2353 IDirectDrawSurface4Impl_SetPrivateData,
2354 IDirectDrawSurface4Impl_GetPrivateData,
2355 IDirectDrawSurface4Impl_FreePrivateData,
2356 IDirectDrawSurface4Impl_GetUniquenessValue,
2357 IDirectDrawSurface4Impl_ChangeUniquenessValue
2359 #endif /* defined(HAVE_LIBXXF86DGA2) */
2361 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2363 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2364 IDirectDrawSurface4Impl_QueryInterface,
2365 IDirectDrawSurface4Impl_AddRef,
2366 Xlib_IDirectDrawSurface4Impl_Release,
2367 IDirectDrawSurface4Impl_AddAttachedSurface,
2368 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2369 IDirectDrawSurface4Impl_Blt,
2370 IDirectDrawSurface4Impl_BltBatch,
2371 IDirectDrawSurface4Impl_BltFast,
2372 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2373 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2374 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2375 Xlib_IDirectDrawSurface4Impl_Flip,
2376 IDirectDrawSurface4Impl_GetAttachedSurface,
2377 IDirectDrawSurface4Impl_GetBltStatus,
2378 IDirectDrawSurface4Impl_GetCaps,
2379 IDirectDrawSurface4Impl_GetClipper,
2380 IDirectDrawSurface4Impl_GetColorKey,
2381 IDirectDrawSurface4Impl_GetDC,
2382 IDirectDrawSurface4Impl_GetFlipStatus,
2383 IDirectDrawSurface4Impl_GetOverlayPosition,
2384 IDirectDrawSurface4Impl_GetPalette,
2385 IDirectDrawSurface4Impl_GetPixelFormat,
2386 IDirectDrawSurface4Impl_GetSurfaceDesc,
2387 IDirectDrawSurface4Impl_Initialize,
2388 IDirectDrawSurface4Impl_IsLost,
2389 IDirectDrawSurface4Impl_Lock,
2390 IDirectDrawSurface4Impl_ReleaseDC,
2391 IDirectDrawSurface4Impl_Restore,
2392 IDirectDrawSurface4Impl_SetClipper,
2393 IDirectDrawSurface4Impl_SetColorKey,
2394 IDirectDrawSurface4Impl_SetOverlayPosition,
2395 Xlib_IDirectDrawSurface4Impl_SetPalette,
2396 Xlib_IDirectDrawSurface4Impl_Unlock,
2397 IDirectDrawSurface4Impl_UpdateOverlay,
2398 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2399 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2400 IDirectDrawSurface4Impl_GetDDInterface,
2401 IDirectDrawSurface4Impl_PageLock,
2402 IDirectDrawSurface4Impl_PageUnlock,
2403 IDirectDrawSurface4Impl_SetSurfaceDesc,
2404 IDirectDrawSurface4Impl_SetPrivateData,
2405 IDirectDrawSurface4Impl_GetPrivateData,
2406 IDirectDrawSurface4Impl_FreePrivateData,
2407 IDirectDrawSurface4Impl_GetUniquenessValue,
2408 IDirectDrawSurface4Impl_ChangeUniquenessValue
2411 /******************************************************************************
2412 * DirectDrawCreateClipper (DDRAW.7)
2414 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2415 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2416 LPUNKNOWN pUnkOuter)
2418 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2419 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2421 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2422 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2423 (*ilplpDDClipper)->ref = 1;
2425 (*ilplpDDClipper)->hWnd = 0;
2427 return DD_OK;
2430 /******************************************************************************
2431 * IDirectDrawClipper
2433 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2434 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
2436 ICOM_THIS(IDirectDrawClipperImpl,iface);
2438 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
2439 if( dwFlags ) {
2440 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
2441 return DDERR_INVALIDPARAMS;
2444 This->hWnd = hWnd;
2445 return DD_OK;
2448 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2449 ICOM_THIS(IDirectDrawClipperImpl,iface);
2450 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2452 This->ref--;
2453 if (This->ref)
2454 return This->ref;
2455 HeapFree(GetProcessHeap(),0,This);
2456 return S_OK;
2459 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2460 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2462 ICOM_THIS(IDirectDrawClipperImpl,iface);
2463 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2464 if (hmm) *hmm=0;
2465 return DD_OK;
2468 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2469 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2471 ICOM_THIS(IDirectDrawClipperImpl,iface);
2472 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2473 return DD_OK;
2476 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2477 LPDIRECTDRAWCLIPPER iface,
2478 REFIID riid,
2479 LPVOID* ppvObj )
2481 ICOM_THIS(IDirectDrawClipperImpl,iface);
2482 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2483 return OLE_E_ENUM_NOMORE;
2486 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2488 ICOM_THIS(IDirectDrawClipperImpl,iface);
2489 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2490 return ++(This->ref);
2493 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2494 LPDIRECTDRAWCLIPPER iface,
2495 HWND* hWndPtr )
2497 ICOM_THIS(IDirectDrawClipperImpl,iface);
2498 FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
2500 *hWndPtr = This->hWnd;
2502 return DD_OK;
2505 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2506 LPDIRECTDRAWCLIPPER iface,
2507 LPDIRECTDRAW lpDD,
2508 DWORD dwFlags )
2510 ICOM_THIS(IDirectDrawClipperImpl,iface);
2511 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2512 return DD_OK;
2515 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2516 LPDIRECTDRAWCLIPPER iface,
2517 BOOL* lpbChanged )
2519 ICOM_THIS(IDirectDrawClipperImpl,iface);
2520 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2521 return DD_OK;
2524 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2526 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2527 IDirectDrawClipperImpl_QueryInterface,
2528 IDirectDrawClipperImpl_AddRef,
2529 IDirectDrawClipperImpl_Release,
2530 IDirectDrawClipperImpl_GetClipList,
2531 IDirectDrawClipperImpl_GetHWnd,
2532 IDirectDrawClipperImpl_Initialize,
2533 IDirectDrawClipperImpl_IsClipListChanged,
2534 IDirectDrawClipperImpl_SetClipList,
2535 IDirectDrawClipperImpl_SetHwnd
2539 /******************************************************************************
2540 * IDirectDrawPalette
2542 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2543 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2545 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2546 int i;
2548 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2549 This,x,start,count,palent);
2551 /* No palette created and not in depth-convertion mode -> BUG ! */
2552 if ((This->cm == None) &&
2553 (This->ddraw->d.palette_convert == NULL))
2555 FIXME("app tried to read colormap for non-palettized mode\n");
2556 return DDERR_GENERIC;
2558 for (i=0;i<count;i++) {
2559 palent[i].peRed = This->palents[start+i].peRed;
2560 palent[i].peBlue = This->palents[start+i].peBlue;
2561 palent[i].peGreen = This->palents[start+i].peGreen;
2562 palent[i].peFlags = This->palents[start+i].peFlags;
2565 return DD_OK;
2568 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2569 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2571 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2572 XColor xc;
2573 int i;
2575 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2576 This,x,start,count,palent
2578 for (i=0;i<count;i++) {
2579 xc.red = palent[i].peRed<<8;
2580 xc.blue = palent[i].peBlue<<8;
2581 xc.green = palent[i].peGreen<<8;
2582 xc.flags = DoRed|DoBlue|DoGreen;
2583 xc.pixel = start+i;
2585 if (This->cm)
2586 TSXStoreColor(display,This->cm,&xc);
2588 This->palents[start+i].peRed = palent[i].peRed;
2589 This->palents[start+i].peBlue = palent[i].peBlue;
2590 This->palents[start+i].peGreen = palent[i].peGreen;
2591 This->palents[start+i].peFlags = palent[i].peFlags;
2594 /* Now, if we are in 'depth conversion mode', update the screen palette */
2595 /* FIXME: we need to update the image or we won't get palette fading. */
2596 if (This->ddraw->d.palette_convert != NULL)
2597 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2599 return DD_OK;
2602 #ifdef HAVE_LIBXXF86DGA
2603 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2604 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2606 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2607 XColor xc;
2608 Colormap cm;
2609 int i;
2611 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2612 This,x,start,count,palent
2614 if (!This->cm) /* should not happen */ {
2615 FIXME("app tried to set colormap in non-palettized mode\n");
2616 return DDERR_GENERIC;
2618 /* FIXME: free colorcells instead of freeing whole map */
2619 cm = This->cm;
2620 This->cm = TSXCopyColormapAndFree(display,This->cm);
2621 TSXFreeColormap(display,cm);
2623 for (i=0;i<count;i++) {
2624 xc.red = palent[i].peRed<<8;
2625 xc.blue = palent[i].peBlue<<8;
2626 xc.green = palent[i].peGreen<<8;
2627 xc.flags = DoRed|DoBlue|DoGreen;
2628 xc.pixel = i+start;
2630 TSXStoreColor(display,This->cm,&xc);
2632 This->palents[start+i].peRed = palent[i].peRed;
2633 This->palents[start+i].peBlue = palent[i].peBlue;
2634 This->palents[start+i].peGreen = palent[i].peGreen;
2635 This->palents[start+i].peFlags = palent[i].peFlags;
2637 #ifdef HAVE_LIBXXF86DGA2
2638 if (This->ddraw->e.dga.version == 2)
2639 TSXDGAInstallColormap(display,DefaultScreen(display),This->cm);
2640 else
2641 #endif /* defined(HAVE_LIBXXF86DGA2) */
2642 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2643 return DD_OK;
2645 #endif /* defined(HAVE_LIBXXF86DGA) */
2647 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2648 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2649 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2650 if (!--(This->ref)) {
2651 if (This->cm) {
2652 TSXFreeColormap(display,This->cm);
2653 This->cm = 0;
2655 HeapFree(GetProcessHeap(),0,This);
2656 return S_OK;
2658 return This->ref;
2661 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2662 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2664 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2665 return ++(This->ref);
2668 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2669 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2671 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2672 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2674 return DDERR_ALREADYINITIALIZED;
2677 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2678 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2680 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2681 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2682 return DD_OK;
2685 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2686 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2688 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2690 FIXME("(%p)->(%s,%p) stub.\n",This,debugstr_guid(refiid),obj);
2692 return S_OK;
2695 #ifdef HAVE_LIBXXF86DGA
2696 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2698 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2699 IDirectDrawPaletteImpl_QueryInterface,
2700 IDirectDrawPaletteImpl_AddRef,
2701 IDirectDrawPaletteImpl_Release,
2702 IDirectDrawPaletteImpl_GetCaps,
2703 IDirectDrawPaletteImpl_GetEntries,
2704 IDirectDrawPaletteImpl_Initialize,
2705 DGA_IDirectDrawPaletteImpl_SetEntries
2707 #endif /* defined(HAVE_LIBXXF86DGA) */
2709 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2711 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2712 IDirectDrawPaletteImpl_QueryInterface,
2713 IDirectDrawPaletteImpl_AddRef,
2714 IDirectDrawPaletteImpl_Release,
2715 IDirectDrawPaletteImpl_GetCaps,
2716 IDirectDrawPaletteImpl_GetEntries,
2717 IDirectDrawPaletteImpl_Initialize,
2718 Xlib_IDirectDrawPaletteImpl_SetEntries
2721 /*******************************************************************************
2722 * IDirect3D
2724 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2725 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2727 ICOM_THIS(IDirect3DImpl,iface);
2728 /* FIXME: Not sure if this is correct */
2730 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2731 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2732 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2733 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2734 *obj = This->ddraw;
2735 IDirect3D_AddRef(iface);
2737 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2739 return S_OK;
2741 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2742 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2743 *obj = This;
2744 IDirect3D_AddRef(iface);
2746 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2748 return S_OK;
2750 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2751 IDirect3D2Impl* d3d;
2753 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2754 d3d->ref = 1;
2755 d3d->ddraw = This->ddraw;
2756 IDirect3D_AddRef(iface);
2757 ICOM_VTBL(d3d) = &d3d2vt;
2758 *obj = d3d;
2760 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2762 return S_OK;
2764 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2765 return OLE_E_ENUM_NOMORE;
2768 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2769 ICOM_THIS(IDirect3DImpl,iface);
2770 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2772 return ++(This->ref);
2775 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2777 ICOM_THIS(IDirect3DImpl,iface);
2778 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2780 if (!--(This->ref)) {
2781 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2782 HeapFree(GetProcessHeap(),0,This);
2783 return S_OK;
2785 return This->ref;
2788 static HRESULT WINAPI IDirect3DImpl_Initialize(
2789 LPDIRECT3D iface, REFIID refiid )
2791 ICOM_THIS(IDirect3DImpl,iface);
2792 /* FIXME: Not sure if this is correct */
2794 FIXME("(%p)->(%s):stub.\n",This,debugstr_guid(refiid));
2796 return DDERR_ALREADYINITIALIZED;
2799 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2800 LPD3DENUMDEVICESCALLBACK cb,
2801 LPVOID context) {
2802 ICOM_THIS(IDirect3DImpl,iface);
2803 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2805 /* Call functions defined in d3ddevices.c */
2806 if (!d3d_OpenGL_dx3(cb, context))
2807 return DD_OK;
2809 return DD_OK;
2812 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2813 LPDIRECT3DLIGHT *lplight,
2814 IUnknown *lpunk)
2816 ICOM_THIS(IDirect3DImpl,iface);
2817 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2819 /* Call the creation function that is located in d3dlight.c */
2820 *lplight = d3dlight_create_dx3(This);
2822 return DD_OK;
2825 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2826 LPDIRECT3DMATERIAL *lpmaterial,
2827 IUnknown *lpunk)
2829 ICOM_THIS(IDirect3DImpl,iface);
2830 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2832 /* Call the creation function that is located in d3dviewport.c */
2833 *lpmaterial = d3dmaterial_create(This);
2835 return DD_OK;
2838 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2839 LPDIRECT3DVIEWPORT *lpviewport,
2840 IUnknown *lpunk)
2842 ICOM_THIS(IDirect3DImpl,iface);
2843 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2845 /* Call the creation function that is located in d3dviewport.c */
2846 *lpviewport = d3dviewport_create(This);
2848 return DD_OK;
2851 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2852 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2853 LPD3DFINDDEVICERESULT lpfinddevrst)
2855 ICOM_THIS(IDirect3DImpl,iface);
2856 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2858 return DD_OK;
2861 static ICOM_VTABLE(IDirect3D) d3dvt =
2863 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2864 IDirect3DImpl_QueryInterface,
2865 IDirect3DImpl_AddRef,
2866 IDirect3DImpl_Release,
2867 IDirect3DImpl_Initialize,
2868 IDirect3DImpl_EnumDevices,
2869 IDirect3DImpl_CreateLight,
2870 IDirect3DImpl_CreateMaterial,
2871 IDirect3DImpl_CreateViewport,
2872 IDirect3DImpl_FindDevice
2875 /*******************************************************************************
2876 * IDirect3D2
2878 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2879 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2880 ICOM_THIS(IDirect3D2Impl,iface);
2882 /* FIXME: Not sure if this is correct */
2884 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2885 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2886 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2887 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2888 *obj = This->ddraw;
2889 IDirect3D2_AddRef(iface);
2891 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2893 return S_OK;
2895 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2896 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2897 *obj = This;
2898 IDirect3D2_AddRef(iface);
2900 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2902 return S_OK;
2904 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2905 IDirect3DImpl* d3d;
2907 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2908 d3d->ref = 1;
2909 d3d->ddraw = This->ddraw;
2910 IDirect3D2_AddRef(iface);
2911 ICOM_VTBL(d3d) = &d3dvt;
2912 *obj = d3d;
2914 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2916 return S_OK;
2918 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2919 return OLE_E_ENUM_NOMORE;
2922 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2923 ICOM_THIS(IDirect3D2Impl,iface);
2924 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2926 return ++(This->ref);
2929 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2930 ICOM_THIS(IDirect3D2Impl,iface);
2931 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2933 if (!--(This->ref)) {
2934 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2935 HeapFree(GetProcessHeap(),0,This);
2936 return S_OK;
2938 return This->ref;
2941 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2942 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2944 ICOM_THIS(IDirect3D2Impl,iface);
2945 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2947 /* Call functions defined in d3ddevices.c */
2948 if (!d3d_OpenGL(cb, context))
2949 return DD_OK;
2951 return DD_OK;
2954 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2955 LPDIRECT3DLIGHT *lplight,
2956 IUnknown *lpunk)
2958 ICOM_THIS(IDirect3D2Impl,iface);
2959 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2961 /* Call the creation function that is located in d3dlight.c */
2962 *lplight = d3dlight_create(This);
2964 return DD_OK;
2967 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2968 LPDIRECT3DMATERIAL2 *lpmaterial,
2969 IUnknown *lpunk)
2971 ICOM_THIS(IDirect3D2Impl,iface);
2972 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2974 /* Call the creation function that is located in d3dviewport.c */
2975 *lpmaterial = d3dmaterial2_create(This);
2977 return DD_OK;
2980 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2981 LPDIRECT3DVIEWPORT2 *lpviewport,
2982 IUnknown *lpunk)
2984 ICOM_THIS(IDirect3D2Impl,iface);
2985 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2987 /* Call the creation function that is located in d3dviewport.c */
2988 *lpviewport = d3dviewport2_create(This);
2990 return DD_OK;
2993 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2994 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2995 LPD3DFINDDEVICERESULT lpfinddevrst)
2997 ICOM_THIS(IDirect3D2Impl,iface);
2998 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
3000 return DD_OK;
3003 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
3004 REFCLSID rguid,
3005 LPDIRECTDRAWSURFACE surface,
3006 LPDIRECT3DDEVICE2 *device)
3008 ICOM_THIS(IDirect3D2Impl,iface);
3010 FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
3012 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
3013 IDirect3D2_AddRef(iface);
3014 return DD_OK;
3017 return DDERR_INVALIDPARAMS;
3020 static ICOM_VTABLE(IDirect3D2) d3d2vt =
3022 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3023 IDirect3D2Impl_QueryInterface,
3024 IDirect3D2Impl_AddRef,
3025 IDirect3D2Impl_Release,
3026 IDirect3D2Impl_EnumDevices,
3027 IDirect3D2Impl_CreateLight,
3028 IDirect3D2Impl_CreateMaterial,
3029 IDirect3D2Impl_CreateViewport,
3030 IDirect3D2Impl_FindDevice,
3031 IDirect3D2Impl_CreateDevice
3034 /*******************************************************************************
3035 * IDirectDraw
3038 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
3039 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
3041 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
3042 IDirectDrawSurfaceImpl* lpdsf)
3044 int bpp;
3046 /* The surface was already allocated when entering in this function */
3047 TRACE("using system memory for a surface (%p) \n", lpdsf);
3049 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
3050 /* This is a Z Buffer */
3051 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
3052 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
3053 } else {
3054 /* This is a standard image */
3055 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
3056 /* No pixel format => use DirectDraw's format */
3057 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3058 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
3060 bpp = GET_BPP(lpdsf->s.surface_desc);
3063 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
3064 /* The surface was preallocated : seems that we have nothing to do :-) */
3065 ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
3068 assert(bpp);
3069 FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf->s.surface_desc.dwWidth,lpdsf->s.surface_desc.dwHeight,bpp);
3071 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
3072 lpdsf->s.surface_desc.u1.lpSurface =
3073 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
3074 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
3076 return DD_OK;
3079 #ifdef HAVE_LIBXXF86DGA
3080 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
3081 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3083 ICOM_THIS(IDirectDraw2Impl,iface);
3084 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3085 int i, fbheight = This->e.dga.fb_height;
3087 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
3088 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3090 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3091 GetProcessHeap(),
3092 HEAP_ZERO_MEMORY,
3093 sizeof(IDirectDrawSurfaceImpl)
3095 IDirectDraw2_AddRef(iface);
3097 (*ilpdsf)->ref = 1;
3098 #ifdef HAVE_LIBXXF86DGA2
3099 if (This->e.dga.version == 2)
3100 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
3101 else
3102 #endif /* defined(HAVE_LIBXXF86DGA2) */
3103 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
3104 (*ilpdsf)->s.ddraw = This;
3105 (*ilpdsf)->s.palette = NULL;
3106 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
3107 (*ilpdsf)->s.lpClipper = NULL;
3109 /* Copy the surface description */
3110 (*ilpdsf)->s.surface_desc = *lpddsd;
3112 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3113 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3114 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3115 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3117 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3119 /* Check if this a 'primary surface' or not */
3120 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3121 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3122 /* This is THE primary surface => there is DGA-specific code */
3124 /* First, store the surface description */
3125 (*ilpdsf)->s.surface_desc = *lpddsd;
3127 /* Find a viewport */
3128 for (i=0;i<32;i++)
3129 if (!(This->e.dga.vpmask & (1<<i)))
3130 break;
3131 TRACE("using viewport %d for a primary surface\n",i);
3132 /* if i == 32 or maximum ... return error */
3133 This->e.dga.vpmask|=(1<<i);
3134 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
3135 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
3137 (*ilpdsf)->s.surface_desc.u1.lpSurface =
3138 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3140 (*ilpdsf)->t.dga.fb_height = i*fbheight;
3142 /* Add flags if there were not present */
3143 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3144 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3145 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3146 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
3147 /* We put our surface always in video memory */
3148 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3149 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3150 (*ilpdsf)->s.chain = NULL;
3152 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3153 IDirectDrawSurface4Impl* back;
3154 int bbc;
3156 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
3157 int i;
3159 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3160 GetProcessHeap(),
3161 HEAP_ZERO_MEMORY,
3162 sizeof(IDirectDrawSurface4Impl)
3164 IDirectDraw2_AddRef(iface);
3165 back->ref = 1;
3166 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
3167 for (i=0;i<32;i++)
3168 if (!(This->e.dga.vpmask & (1<<i)))
3169 break;
3170 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
3171 /* if i == 32 or maximum ... return error */
3172 This->e.dga.vpmask|=(1<<i);
3173 back->t.dga.fb_height = i*fbheight;
3174 /* Copy the surface description from the front buffer */
3175 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3176 /* Change the parameters that are not the same */
3177 back->s.surface_desc.u1.lpSurface =
3178 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3180 back->s.ddraw = This;
3181 /* Add relevant info to front and back buffers */
3182 /* FIXME: backbuffer/frontbuffer handling broken here, but
3183 * will be fixed up in _Flip().
3185 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3186 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
3187 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3188 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3189 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3192 } else {
3193 /* There is no DGA-specific code here...
3194 Go to the common surface creation function */
3195 return common_off_screen_CreateSurface(This, *ilpdsf);
3197 return DD_OK;
3199 #endif /* defined(HAVE_LIBXXF86DGA) */
3201 #ifdef HAVE_LIBXXSHM
3202 /* Error handlers for Image creation */
3203 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
3204 XShmErrorFlag = 1;
3205 return 0;
3208 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3209 XImage *img;
3210 int (*WineXHandler)(Display *, XErrorEvent *);
3212 img = TSXShmCreateImage(display,
3213 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3214 This->d.pixmap_depth,
3215 ZPixmap,
3216 NULL,
3217 &(lpdsf->t.xlib.shminfo),
3218 lpdsf->s.surface_desc.dwWidth,
3219 lpdsf->s.surface_desc.dwHeight
3222 if (img == NULL) {
3223 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3224 This->e.xlib.xshm_active = 0;
3225 return NULL;
3228 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3229 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3230 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3231 This->e.xlib.xshm_active = 0;
3232 TSXDestroyImage(img);
3233 return NULL;
3236 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3238 if (img->data == (char *) -1) {
3239 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3240 This->e.xlib.xshm_active = 0;
3241 TSXDestroyImage(img);
3242 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3243 return NULL;
3245 lpdsf->t.xlib.shminfo.readOnly = False;
3247 /* This is where things start to get trickier....
3248 * First, we flush the current X connections to be sure to catch all
3249 * non-XShm related errors
3251 TSXSync(display, False);
3252 /* Then we enter in the non-thread safe part of the tests */
3253 EnterCriticalSection( &X11DRV_CritSection );
3255 /* Reset the error flag, sets our new error handler and try to attach
3256 * the surface
3258 XShmErrorFlag = 0;
3259 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3260 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3261 XSync(display, False);
3263 /* Check the error flag */
3264 if (XShmErrorFlag) {
3265 /* An error occured */
3266 XFlush(display);
3267 XShmErrorFlag = 0;
3268 XDestroyImage(img);
3269 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3270 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3271 XSetErrorHandler(WineXHandler);
3273 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3274 This->e.xlib.xshm_active = 0;
3276 /* Leave the critical section */
3277 LeaveCriticalSection( &X11DRV_CritSection );
3278 return NULL;
3280 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3281 * this works, but it may be a bit overkill....
3283 XSetErrorHandler(WineXHandler);
3284 LeaveCriticalSection( &X11DRV_CritSection );
3286 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3288 if (This->d.pixel_convert != NULL) {
3289 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3290 GetProcessHeap(),
3291 HEAP_ZERO_MEMORY,
3292 lpdsf->s.surface_desc.dwWidth *
3293 lpdsf->s.surface_desc.dwHeight *
3294 PFGET_BPP(This->d.directdraw_pixelformat)
3296 } else {
3297 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3299 return img;
3301 #endif /* HAVE_LIBXXSHM */
3303 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3304 XImage *img = NULL;
3305 void *img_data;
3307 #ifdef HAVE_LIBXXSHM
3308 if (This->e.xlib.xshm_active)
3309 img = create_xshmimage(This, lpdsf);
3311 if (img == NULL) {
3312 #endif
3313 /* Allocate surface memory */
3314 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3315 GetProcessHeap(),HEAP_ZERO_MEMORY,
3316 lpdsf->s.surface_desc.dwWidth *
3317 lpdsf->s.surface_desc.dwHeight *
3318 PFGET_BPP(This->d.directdraw_pixelformat)
3321 if (This->d.pixel_convert != NULL) {
3322 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3323 lpdsf->s.surface_desc.dwWidth *
3324 lpdsf->s.surface_desc.dwHeight *
3325 PFGET_BPP(This->d.screen_pixelformat)
3327 } else {
3328 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3331 /* In this case, create an XImage */
3332 img = TSXCreateImage(display,
3333 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3334 This->d.pixmap_depth,
3335 ZPixmap,
3337 img_data,
3338 lpdsf->s.surface_desc.dwWidth,
3339 lpdsf->s.surface_desc.dwHeight,
3341 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3343 #ifdef HAVE_LIBXXSHM
3345 #endif
3346 if (This->d.pixel_convert != NULL)
3347 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3348 else
3349 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3350 return img;
3353 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3354 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3356 ICOM_THIS(IDirectDraw2Impl,iface);
3357 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3359 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3361 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3363 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3364 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3367 IDirectDraw2_AddRef(iface);
3369 (*ilpdsf)->s.ddraw = This;
3370 (*ilpdsf)->ref = 1;
3371 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3372 (*ilpdsf)->s.palette = NULL;
3373 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3374 (*ilpdsf)->s.lpClipper = NULL;
3376 /* Copy the surface description */
3377 (*ilpdsf)->s.surface_desc = *lpddsd;
3379 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3380 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3381 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3382 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3383 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3385 /* Check if this a 'primary surface' or not */
3386 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3387 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3388 XImage *img;
3390 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3391 /* Create the XImage */
3392 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3393 if (img == NULL)
3394 return DDERR_OUTOFMEMORY;
3395 (*ilpdsf)->t.xlib.image = img;
3397 /* Add flags if there were not present */
3398 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3399 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3400 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3401 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3402 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3404 /* Check for backbuffers */
3405 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3406 IDirectDrawSurface4Impl* back;
3407 XImage *img;
3408 int i;
3410 for (i=lpddsd->dwBackBufferCount;i--;) {
3411 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3412 GetProcessHeap(),HEAP_ZERO_MEMORY,
3413 sizeof(IDirectDrawSurface4Impl)
3416 TRACE("allocated back-buffer (%p)\n", back);
3418 IDirectDraw2_AddRef(iface);
3419 back->s.ddraw = This;
3421 back->ref = 1;
3422 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3423 /* Copy the surface description from the front buffer */
3424 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3426 /* Create the XImage */
3427 img = create_ximage(This, back);
3428 if (img == NULL)
3429 return DDERR_OUTOFMEMORY;
3430 back->t.xlib.image = img;
3432 /* Add relevant info to front and back buffers */
3433 /* FIXME: backbuffer/frontbuffer handling broken here, but
3434 * will be fixed up in _Flip().
3436 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3437 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3438 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3439 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3440 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3443 } else {
3444 /* There is no Xlib-specific code here...
3445 Go to the common surface creation function */
3446 return common_off_screen_CreateSurface(This, *ilpdsf);
3448 return DD_OK;
3451 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3452 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3454 ICOM_THIS(IDirectDraw2Impl,iface);
3455 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3456 *dst = src; /* FIXME */
3457 return DD_OK;
3461 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3462 * even when the approbiate bitmasks are not specified.
3464 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3465 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3467 ICOM_THIS(IDirectDraw2Impl,iface);
3468 int i;
3469 const struct {
3470 int mask;
3471 char *name;
3472 } flags[] = {
3473 #define FE(x) { x, #x},
3474 FE(DDSCL_FULLSCREEN)
3475 FE(DDSCL_ALLOWREBOOT)
3476 FE(DDSCL_NOWINDOWCHANGES)
3477 FE(DDSCL_NORMAL)
3478 FE(DDSCL_ALLOWMODEX)
3479 FE(DDSCL_EXCLUSIVE)
3480 FE(DDSCL_SETFOCUSWINDOW)
3481 FE(DDSCL_SETDEVICEWINDOW)
3482 FE(DDSCL_CREATEDEVICEWINDOW)
3483 #undef FE
3486 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3487 if (TRACE_ON(ddraw)) {
3488 DPRINTF(" - ");
3489 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
3490 if (flags[i].mask & cooplevel) {
3491 DPRINTF("%s ",flags[i].name);
3494 DPRINTF("\n");
3496 This->d.mainWindow = hwnd;
3498 /* This will be overwritten in the case of Full Screen mode.
3499 Windowed games could work with that :-) */
3500 if (hwnd)
3502 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3503 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3504 WIN_ReleaseWndPtr(tmpWnd);
3506 if( !This->d.drawable ) {
3507 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3508 WIN_ReleaseDesktop();
3510 TRACE("Setting drawable to %ld\n", This->d.drawable);
3513 return DD_OK;
3516 #ifdef HAVE_LIBXXF86DGA2
3517 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel(
3518 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3520 ICOM_THIS(IDirectDraw2Impl,iface);
3521 HRESULT ret;
3522 int evbase, erbase;
3524 ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel);
3526 if (This->e.dga.version != 2) {
3527 return ret;
3528 } else {
3529 if (ret != DD_OK)
3530 return ret;
3532 TSXDGAQueryExtension(display, &evbase, &erbase);
3534 /* Now, start handling of DGA events giving the handle to the DDraw window
3535 as the window for which the event will be reported */
3536 TSXDGASelectInput(display, DefaultScreen(display),
3537 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3538 X11DRV_EVENT_SetDGAStatus(hwnd, evbase);
3540 return DD_OK;
3543 #endif
3545 /* Small helper to either use the cooperative window or create a new
3546 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3548 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3549 RECT rect;
3551 /* Do destroy only our window */
3552 if (This->d.window && GetPropA(This->d.window,ddProp)) {
3553 DestroyWindow(This->d.window);
3554 This->d.window = 0;
3556 /* Sanity check cooperative window before assigning it to drawing. */
3557 if ( IsWindow(This->d.mainWindow) &&
3558 IsWindowVisible(This->d.mainWindow)
3560 /* if it does not fit, resize the cooperative window.
3561 * and hope the app likes it
3563 GetWindowRect(This->d.mainWindow,&rect);
3564 if ((((rect.right-rect.left) >= This->d.width) &&
3565 ((rect.bottom-rect.top) >= This->d.height))
3567 This->d.window = This->d.mainWindow;
3568 /* SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOOWNERZORDER); */
3569 This->d.paintable = 1;
3572 /* ... failed, create new one. */
3573 if (!This->d.window) {
3574 This->d.window = CreateWindowExA(
3576 "WINE_DirectDraw",
3577 "WINE_DirectDraw",
3578 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3579 0,0,
3580 This->d.width,
3581 This->d.height,
3585 NULL
3587 /*Store THIS with the window. We'll use it in the window procedure*/
3588 SetPropA(This->d.window,ddProp,(LONG)This);
3589 ShowWindow(This->d.window,TRUE);
3590 UpdateWindow(This->d.window);
3592 SetFocus(This->d.window);
3595 static int _common_depth_to_pixelformat(DWORD depth,
3596 DDPIXELFORMAT *pixelformat,
3597 DDPIXELFORMAT *screen_pixelformat,
3598 int *pix_depth) {
3599 XVisualInfo *vi;
3600 XPixmapFormatValues *pf;
3601 XVisualInfo vt;
3602 int nvisuals, npixmap, i;
3603 int match = 0;
3604 int index = -2;
3606 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3607 pf = XListPixmapFormats(display, &npixmap);
3609 for (i = 0; i < npixmap; i++) {
3610 if (pf[i].depth == depth) {
3611 int j;
3613 for (j = 0; j < nvisuals; j++) {
3614 if (vi[j].depth == pf[i].depth) {
3615 pixelformat->dwSize = sizeof(*pixelformat);
3616 if (depth == 8) {
3617 pixelformat->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
3618 pixelformat->u1.dwRBitMask = 0;
3619 pixelformat->u2.dwGBitMask = 0;
3620 pixelformat->u3.dwBBitMask = 0;
3621 } else {
3622 pixelformat->dwFlags = DDPF_RGB;
3623 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3624 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3625 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3627 pixelformat->dwFourCC = 0;
3628 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3629 pixelformat->u4.dwRGBAlphaBitMask= 0;
3631 *screen_pixelformat = *pixelformat;
3633 if (pix_depth != NULL)
3634 *pix_depth = vi[j].depth;
3636 match = 1;
3637 index = -1;
3639 goto clean_up_and_exit;
3643 ERR("No visual corresponding to pixmap format !\n");
3647 if (match == 0) {
3648 /* We try now to find an emulated mode */
3649 int c;
3651 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3652 if (ModeEmulations[c].dest.depth == depth) {
3653 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3654 for (i = 0; i < npixmap; i++) {
3655 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3656 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3657 int j;
3659 for (j = 0; j < nvisuals; j++) {
3660 if (vi[j].depth == pf[i].depth) {
3661 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3662 screen_pixelformat->dwFlags = DDPF_RGB;
3663 screen_pixelformat->dwFourCC = 0;
3664 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3665 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3666 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3667 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3668 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3670 pixelformat->dwSize = sizeof(*pixelformat);
3671 pixelformat->dwFourCC = 0;
3672 if (depth == 8) {
3673 pixelformat->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
3674 pixelformat->u.dwRGBBitCount = 8;
3675 pixelformat->u1.dwRBitMask = 0;
3676 pixelformat->u2.dwGBitMask = 0;
3677 pixelformat->u3.dwBBitMask = 0;
3678 } else {
3679 pixelformat->dwFlags = DDPF_RGB;
3680 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3681 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3682 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3683 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3685 pixelformat->u4.dwRGBAlphaBitMask= 0;
3687 if (pix_depth != NULL)
3688 *pix_depth = vi[j].depth;
3690 match = 2;
3691 index = c;
3693 goto clean_up_and_exit;
3696 ERR("No visual corresponding to pixmap format !\n");
3704 clean_up_and_exit:
3705 TSXFree(vi);
3706 TSXFree(pf);
3708 return index;
3711 #ifdef HAVE_LIBXXF86DGA2
3712 static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl *This, int mode) {
3713 DDPIXELFORMAT *pf = &(This->d.directdraw_pixelformat);
3715 /* Now, get the device / mode description */
3716 This->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode);
3718 This->e.dga.fb_width = This->e.dga.dev->mode.imageWidth;
3719 TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
3720 This->e.dga.fb_height = This->e.dga.dev->mode.viewportHeight;
3721 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
3722 This->e.dga.dev->data,
3723 This->e.dga.dev->mode.imageWidth,
3724 (This->e.dga.dev->mode.imageWidth *
3725 This->e.dga.dev->mode.imageHeight *
3726 (This->e.dga.dev->mode.bitsPerPixel / 8))
3728 TRACE("viewport height: %d\n", This->e.dga.dev->mode.viewportHeight);
3729 /* Get the screen dimensions as seen by Wine.
3730 In that case, it may be better to ignore the -desktop mode and return the
3731 real screen size => print a warning */
3732 This->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3733 This->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3734 This->e.dga.fb_addr = This->e.dga.dev->data;
3735 This->e.dga.fb_memsize = (This->e.dga.dev->mode.imageWidth *
3736 This->e.dga.dev->mode.imageHeight *
3737 (This->e.dga.dev->mode.bitsPerPixel / 8));
3738 This->e.dga.vpmask = 0;
3740 /* Fill the screen pixelformat */
3741 pf->dwSize = sizeof(DDPIXELFORMAT);
3742 pf->dwFourCC = 0;
3743 pf->u.dwRGBBitCount = This->e.dga.dev->mode.bitsPerPixel;
3744 if (This->e.dga.dev->mode.depth == 8) {
3745 pf->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
3746 pf->u1.dwRBitMask = 0;
3747 pf->u2.dwGBitMask = 0;
3748 pf->u3.dwBBitMask = 0;
3749 } else {
3750 pf->dwFlags = DDPF_RGB;
3751 pf->u1.dwRBitMask = This->e.dga.dev->mode.redMask;
3752 pf->u2.dwGBitMask = This->e.dga.dev->mode.greenMask;
3753 pf->u3.dwBBitMask = This->e.dga.dev->mode.blueMask;
3755 pf->u4.dwRGBAlphaBitMask= 0;
3757 This->d.screen_pixelformat = *pf;
3759 #endif /* defined(HAVE_LIBXXF86DGA2) */
3761 #ifdef HAVE_LIBXXF86DGA
3762 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3763 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3765 ICOM_THIS(IDirectDrawImpl,iface);
3766 int i,mode_count;
3768 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3770 #ifdef HAVE_LIBXXF86DGA2
3771 if (This->e.dga.version == 2) {
3772 XDGAMode *modes = This->e.dga.modes;
3773 int mode_to_use = -1;
3775 /* Search in the list a display mode that corresponds to what is requested */
3776 for (i = 0; i < This->e.dga.num_modes; i++) {
3777 if ((height == modes[i].viewportHeight) &&
3778 (width == modes[i].viewportWidth) &&
3779 (depth == modes[i].depth)) {
3780 mode_to_use = modes[i].num;
3784 if (mode_to_use < 0) {
3785 ERR("Could not find matching mode !!!\n");
3786 return DDERR_UNSUPPORTEDMODE;
3787 } else {
3788 TRACE("Using mode number %d\n", mode_to_use);
3790 TSXDGACloseFramebuffer(display, DefaultScreen(display));
3792 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
3793 ERR("Error opening the frame buffer !!!\n");
3795 return DDERR_GENERIC;
3798 /* Initialize the frame buffer */
3799 _DGA_Initialize_FrameBuffer(This, mode_to_use);
3801 /* Re-get (if necessary) the DGA events */
3802 TSXDGASelectInput(display, DefaultScreen(display),
3803 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3806 return DD_OK;
3808 #endif /* defined(HAVE_LIBXXF86DGA2) */
3810 /* We hope getting the asked for depth */
3811 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3812 /* I.e. no visual found or emulated */
3813 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3814 return DDERR_UNSUPPORTEDMODE;
3817 if (This->d.width < width) {
3818 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3819 return DDERR_UNSUPPORTEDMODE;
3821 This->d.width = width;
3822 This->d.height = height;
3824 /* adjust fb_height, so we don't overlap */
3825 if (This->e.dga.fb_height < height)
3826 This->e.dga.fb_height = height;
3827 _common_IDirectDrawImpl_SetDisplayMode(This);
3829 #ifdef HAVE_LIBXXF86VM
3830 #ifdef HAVE_LIBXXF86DGA2
3831 if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3832 #endif /* defined(HAVE_LIBXXF86DGA2) */
3834 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3835 XF86VidModeModeLine mod_tmp;
3836 /* int dotclock_tmp; */
3838 /* save original video mode and set fullscreen if available*/
3839 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3840 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3841 orig_mode->hdisplay = mod_tmp.hdisplay;
3842 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3843 orig_mode->hsyncend = mod_tmp.hsyncend;
3844 orig_mode->htotal = mod_tmp.htotal;
3845 orig_mode->vdisplay = mod_tmp.vdisplay;
3846 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3847 orig_mode->vsyncend = mod_tmp.vsyncend;
3848 orig_mode->vtotal = mod_tmp.vtotal;
3849 orig_mode->flags = mod_tmp.flags;
3850 orig_mode->private = mod_tmp.private;
3852 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3853 for (i=0;i<mode_count;i++)
3855 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3857 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3858 *vidmode = *(all_modes[i]);
3859 break;
3860 } else
3861 TSXFree(all_modes[i]->private);
3863 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3864 TSXFree(all_modes);
3866 if (!vidmode)
3867 WARN("Fullscreen mode not available!\n");
3869 if (vidmode)
3871 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3872 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3873 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3874 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3875 #endif
3878 #endif
3880 /* FIXME: this function OVERWRITES several signal handlers.
3881 * can we save them? and restore them later? In a way that
3882 * it works for the library too?
3884 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3885 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3887 #ifdef RESTORE_SIGNALS
3888 SIGNAL_Init();
3889 #endif
3890 return DD_OK;
3892 #endif /* defined(HAVE_LIBXXF86DGA) */
3894 /* *************************************
3895 16 / 15 bpp to palettized 8 bpp
3896 ************************************* */
3897 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3898 unsigned char *c_src = (unsigned char *) src;
3899 unsigned short *c_dst = (unsigned short *) dst;
3900 int y;
3902 if (palette != NULL) {
3903 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3905 for (y = height; y--; ) {
3906 #if defined(__i386__) && defined(__GNUC__)
3907 /* gcc generates slightly inefficient code for the the copy / lookup,
3908 * it generates one excess memory access (to pal) per pixel. Since
3909 * we know that pal is not modified by the memory write we can
3910 * put it into a register and reduce the number of memory accesses
3911 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3912 * (This is not guaranteed to be the fastest method.)
3914 __asm__ __volatile__(
3915 "xor %%eax,%%eax\n"
3916 "1:\n"
3917 " lodsb\n"
3918 " movw (%%edx,%%eax,2),%%ax\n"
3919 " stosw\n"
3920 " xor %%eax,%%eax\n"
3921 " loop 1b\n"
3922 : "=S" (c_src), "=D" (c_dst)
3923 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3924 : "eax", "cc", "memory"
3926 c_src+=(pitch-width);
3927 #else
3928 unsigned char * srclineend = c_src+width;
3929 while (c_src < srclineend)
3930 *c_dst++ = pal[*c_src++];
3931 c_src+=(pitch-width);
3932 #endif
3934 } else {
3935 WARN("No palette set...\n");
3936 memset(dst, 0, width * height * 2);
3939 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3940 int i;
3941 unsigned short *pal = (unsigned short *) screen_palette;
3943 for (i = 0; i < count; i++)
3944 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3945 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3946 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3948 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3949 int i;
3950 unsigned short *pal = (unsigned short *) screen_palette;
3952 for (i = 0; i < count; i++)
3953 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3954 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3955 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3958 /* *************************************
3959 24 to palettized 8 bpp
3960 ************************************* */
3961 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3962 unsigned char *c_src = (unsigned char *) src;
3963 unsigned char *c_dst = (unsigned char *) dst;
3964 int y;
3966 if (palette != NULL) {
3967 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3969 for (y = height; y--; ) {
3970 unsigned char * srclineend = c_src+width;
3971 while (c_src < srclineend ) {
3972 register long pixel = pal[*c_src++];
3973 *c_dst++ = pixel;
3974 *c_dst++ = pixel>>8;
3975 *c_dst++ = pixel>>16;
3977 c_src+=(pitch-width);
3979 } else {
3980 WARN("No palette set...\n");
3981 memset(dst, 0, width * height * 4);
3984 /* *************************************
3985 32 bpp to palettized 8 bpp
3986 ************************************* */
3987 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3988 unsigned char *c_src = (unsigned char *) src;
3989 unsigned int *c_dst = (unsigned int *) dst;
3990 int y;
3992 if (palette != NULL) {
3993 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3995 for (y = height; y--; ) {
3996 #if defined(__i386__) && defined(__GNUC__)
3997 /* See comment in pixel_convert_16_to_8 */
3998 __asm__ __volatile__(
3999 "xor %%eax,%%eax\n"
4000 "1:\n"
4001 " lodsb\n"
4002 " movl (%%edx,%%eax,4),%%eax\n"
4003 " stosl\n"
4004 " xor %%eax,%%eax\n"
4005 " loop 1b\n"
4006 : "=S" (c_src), "=D" (c_dst)
4007 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
4008 : "eax", "cc", "memory"
4010 c_src+=(pitch-width);
4011 #else
4012 unsigned char * srclineend = c_src+width;
4013 while (c_src < srclineend )
4014 *c_dst++ = pal[*c_src++];
4015 c_src+=(pitch-width);
4016 #endif
4018 } else {
4019 WARN("No palette set...\n");
4020 memset(dst, 0, width * height * 4);
4024 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
4025 int i;
4026 unsigned int *pal = (unsigned int *) screen_palette;
4028 for (i = 0; i < count; i++)
4029 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
4030 (((unsigned int) palent[i].peGreen) << 8) |
4031 ((unsigned int) palent[i].peBlue));
4034 /* *************************************
4035 32 bpp to 16 bpp
4036 ************************************* */
4037 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4038 unsigned short *c_src = (unsigned short *) src;
4039 unsigned int *c_dst = (unsigned int *) dst;
4040 int y;
4042 for (y = height; y--; ) {
4043 unsigned short * srclineend = c_src+width;
4044 while (c_src < srclineend ) {
4045 *c_dst++ = (((*c_src & 0xF800) << 8) |
4046 ((*c_src & 0x07E0) << 5) |
4047 ((*c_src & 0x001F) << 3));
4048 c_src++;
4050 c_src+=((pitch/2)-width);
4055 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
4056 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
4058 ICOM_THIS(IDirectDrawImpl,iface);
4059 char buf[200];
4060 WND *tmpWnd;
4061 int c;
4063 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
4064 This, width, height, depth);
4066 switch ((c = _common_depth_to_pixelformat(depth,
4067 &(This->d.directdraw_pixelformat),
4068 &(This->d.screen_pixelformat),
4069 &(This->d.pixmap_depth)))) {
4070 case -2:
4071 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
4072 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
4073 return DDERR_UNSUPPORTEDMODE;
4075 case -1:
4076 /* No convertion */
4077 This->d.pixel_convert = NULL;
4078 This->d.palette_convert = NULL;
4079 break;
4081 default:
4082 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
4084 /* Set the depth convertion routines */
4085 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
4086 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
4089 This->d.width = width;
4090 This->d.height = height;
4092 _common_IDirectDrawImpl_SetDisplayMode(This);
4094 tmpWnd = WIN_FindWndPtr(This->d.window);
4095 This->d.paintable = 1;
4096 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
4097 WIN_ReleaseWndPtr(tmpWnd);
4099 /* We don't have a context for this window. Host off the desktop */
4100 if( !This->d.drawable )
4102 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
4103 WIN_ReleaseDesktop();
4105 TRACE("Setting drawable to %ld\n", This->d.drawable);
4107 if (Options.DXGrab) {
4108 /* Confine cursor movement (risky, but the user asked for it) */
4109 TSXGrabPointer(display, This->d.drawable, True, 0, GrabModeAsync, GrabModeAsync, This->d.drawable, None, CurrentTime);
4112 return DD_OK;
4115 #ifdef HAVE_LIBXXF86DGA
4116 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
4117 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4119 ICOM_THIS(IDirectDraw2Impl,iface);
4120 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4121 if (!caps1 && !caps2)
4122 return DDERR_INVALIDPARAMS;
4123 if (caps1) {
4124 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
4125 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4126 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4128 if (caps2) {
4129 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
4130 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4131 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4133 return DD_OK;
4135 #endif /* defined(HAVE_LIBXXF86DGA) */
4137 static void fill_caps(LPDDCAPS caps) {
4138 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4139 Need to be fixed, though.. */
4140 if (caps == NULL)
4141 return;
4143 caps->dwSize = sizeof(*caps);
4144 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
4145 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
4146 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
4147 caps->dwFXCaps = 0;
4148 caps->dwFXAlphaCaps = 0;
4149 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
4150 caps->dwSVCaps = 0;
4151 caps->dwZBufferBitDepths = DDBD_16;
4152 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4153 to put textures in video memory.
4154 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4155 for example) ? */
4156 caps->dwVidMemTotal = 8192 * 1024;
4157 caps->dwVidMemFree = 8192 * 1024;
4158 /* These are all the supported capabilities of the surfaces */
4159 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
4160 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
4161 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
4162 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
4163 #ifdef HAVE_MESAGL
4164 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
4165 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
4166 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
4167 #endif
4170 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
4171 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4173 ICOM_THIS(IDirectDraw2Impl,iface);
4174 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4176 /* Put the same caps for the two capabilities */
4177 fill_caps(caps1);
4178 fill_caps(caps2);
4180 return DD_OK;
4183 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
4184 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
4186 ICOM_THIS(IDirectDraw2Impl,iface);
4187 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
4188 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4189 This,x,ilpddclip,lpunk
4191 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
4192 (*ilpddclip)->ref = 1;
4193 ICOM_VTBL(*ilpddclip) = &ddclipvt;
4194 return DD_OK;
4197 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
4198 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
4200 int size = 0;
4202 if (TRACE_ON(ddraw))
4203 _dump_paletteformat(dwFlags);
4205 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
4206 if (*lpddpal == NULL) return E_OUTOFMEMORY;
4207 (*lpddpal)->ref = 1;
4208 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
4209 (*lpddpal)->installed = 0;
4211 if (dwFlags & DDPCAPS_1BIT)
4212 size = 2;
4213 else if (dwFlags & DDPCAPS_2BIT)
4214 size = 4;
4215 else if (dwFlags & DDPCAPS_4BIT)
4216 size = 16;
4217 else if (dwFlags & DDPCAPS_8BIT)
4218 size = 256;
4219 else
4220 ERR("unhandled palette format\n");
4221 *psize = size;
4223 if (palent)
4225 /* Now, if we are in 'depth conversion mode', create the screen palette */
4226 if (This->d.palette_convert != NULL)
4227 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
4229 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
4230 } else if (This->d.palette_convert != NULL) {
4231 /* In that case, put all 0xFF */
4232 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
4235 return DD_OK;
4238 #ifdef HAVE_LIBXXF86DGA
4239 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
4240 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4242 ICOM_THIS(IDirectDraw2Impl,iface);
4243 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4244 HRESULT res;
4245 int xsize = 0,i;
4247 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4248 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4249 if (res != 0) return res;
4250 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
4251 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
4252 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
4253 } else {
4254 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4255 (*ilpddpal)->cm = 0;
4257 if (((*ilpddpal)->cm)&&xsize) {
4258 for (i=0;i<xsize;i++) {
4259 XColor xc;
4261 xc.red = (*ilpddpal)->palents[i].peRed<<8;
4262 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
4263 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
4264 xc.flags = DoRed|DoBlue|DoGreen;
4265 xc.pixel = i;
4266 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
4269 return DD_OK;
4271 #endif /* defined(HAVE_LIBXXF86DGA) */
4273 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
4274 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4276 ICOM_THIS(IDirectDraw2Impl,iface);
4277 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4278 int xsize;
4279 HRESULT res;
4281 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4282 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4283 if (res != 0) return res;
4284 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
4285 return DD_OK;
4288 #ifdef HAVE_LIBXXF86DGA
4289 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4290 ICOM_THIS(IDirectDraw2Impl,iface);
4291 TRACE("(%p)->()\n",This);
4292 Sleep(1000);
4293 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4294 #ifdef RESTORE_SIGNALS
4295 SIGNAL_Init();
4296 #endif
4297 return DD_OK;
4299 #endif /* defined(HAVE_LIBXXF86DGA) */
4301 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4302 ICOM_THIS(IDirectDraw2Impl,iface);
4303 TRACE("(%p)->RestoreDisplayMode()\n", This);
4304 Sleep(1000);
4305 return DD_OK;
4308 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
4309 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
4311 ICOM_THIS(IDirectDraw2Impl,iface);
4312 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
4313 return DD_OK;
4316 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
4317 ICOM_THIS(IDirectDraw2Impl,iface);
4318 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
4320 return ++(This->ref);
4323 #ifdef HAVE_LIBXXF86DGA
4324 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4325 ICOM_THIS(IDirectDraw2Impl,iface);
4326 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4328 if (!--(This->ref)) {
4329 #ifdef HAVE_LIBXXF86DGA2
4330 if (This->e.dga.version == 2) {
4331 TRACE("Closing access to the FrameBuffer\n");
4332 TSXDGACloseFramebuffer(display, DefaultScreen(display));
4333 TRACE("Going back to normal X mode of operation\n");
4334 TSXDGASetMode(display, DefaultScreen(display), 0);
4336 /* Set the input handling back to absolute */
4337 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
4339 /* Remove the handling of DGA2 events */
4340 X11DRV_EVENT_SetDGAStatus(0, -1);
4342 /* Free the modes list */
4343 TSXFree(This->e.dga.modes);
4344 } else
4345 #endif /* defined(HAVE_LIBXXF86DGA2) */
4346 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4347 if (This->d.window && GetPropA(This->d.window,ddProp))
4348 DestroyWindow(This->d.window);
4349 #ifdef HAVE_LIBXXF86VM
4350 if (orig_mode) {
4351 TSXF86VidModeSwitchToMode(
4352 display,
4353 DefaultScreen(display),
4354 orig_mode);
4355 if (orig_mode->privsize)
4356 TSXFree(orig_mode->private);
4357 free(orig_mode);
4358 orig_mode = NULL;
4360 #endif
4362 #ifdef RESTORE_SIGNALS
4363 SIGNAL_Init();
4364 #endif
4365 HeapFree(GetProcessHeap(),0,This);
4366 return S_OK;
4368 return This->ref;
4370 #endif /* defined(HAVE_LIBXXF86DGA) */
4372 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4373 ICOM_THIS(IDirectDraw2Impl,iface);
4374 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4376 if (!--(This->ref)) {
4377 if (This->d.window && GetPropA(This->d.window,ddProp))
4378 DestroyWindow(This->d.window);
4379 HeapFree(GetProcessHeap(),0,This);
4380 return S_OK;
4382 /* FIXME: destroy window ... */
4383 return This->ref;
4386 #ifdef HAVE_LIBXXF86DGA
4387 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4388 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4390 ICOM_THIS(IDirectDraw2Impl,iface);
4392 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4393 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4394 *obj = This;
4395 IDirectDraw2_AddRef(iface);
4397 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4399 return S_OK;
4401 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4402 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4403 IDirectDraw2_AddRef(iface);
4404 *obj = This;
4406 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4408 return S_OK;
4410 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4411 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4412 IDirectDraw2_AddRef(iface);
4413 *obj = This;
4415 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4417 return S_OK;
4419 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4420 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4421 IDirectDraw2_AddRef(iface);
4422 *obj = This;
4424 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4426 return S_OK;
4428 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4429 IDirect3DImpl* d3d;
4431 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4432 d3d->ref = 1;
4433 d3d->ddraw = (IDirectDrawImpl*)This;
4434 IDirectDraw2_AddRef(iface);
4435 ICOM_VTBL(d3d) = &d3dvt;
4436 *obj = d3d;
4438 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4440 return S_OK;
4442 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4443 IDirect3D2Impl* d3d;
4445 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4446 d3d->ref = 1;
4447 d3d->ddraw = (IDirectDrawImpl*)This;
4448 IDirectDraw2_AddRef(iface);
4449 ICOM_VTBL(d3d) = &d3d2vt;
4450 *obj = d3d;
4452 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4454 return S_OK;
4456 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4457 return OLE_E_ENUM_NOMORE;
4459 #endif /* defined(HAVE_LIBXXF86DGA) */
4461 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4462 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4464 ICOM_THIS(IDirectDraw2Impl,iface);
4466 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4467 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4468 *obj = This;
4469 IDirectDraw2_AddRef(iface);
4471 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4473 return S_OK;
4475 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4476 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4477 IDirectDraw2_AddRef(iface);
4478 *obj = This;
4480 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4482 return S_OK;
4484 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4485 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4486 IDirectDraw2_AddRef(iface);
4487 *obj = This;
4489 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4491 return S_OK;
4493 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4494 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4495 IDirectDraw2_AddRef(iface);
4496 *obj = This;
4498 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4500 return S_OK;
4502 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4503 IDirect3DImpl* d3d;
4505 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4506 d3d->ref = 1;
4507 d3d->ddraw = (IDirectDrawImpl*)This;
4508 IDirectDraw2_AddRef(iface);
4509 ICOM_VTBL(d3d) = &d3dvt;
4510 *obj = d3d;
4512 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4514 return S_OK;
4516 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4517 IDirect3D2Impl* d3d;
4519 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4520 d3d->ref = 1;
4521 d3d->ddraw = (IDirectDrawImpl*)This;
4522 IDirectDraw2_AddRef(iface);
4523 ICOM_VTBL(d3d) = &d3d2vt;
4524 *obj = d3d;
4526 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4528 return S_OK;
4530 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4531 return OLE_E_ENUM_NOMORE;
4534 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4535 LPDIRECTDRAW2 iface,BOOL *status
4537 ICOM_THIS(IDirectDraw2Impl,iface);
4538 TRACE("(%p)->(%p)\n",This,status);
4539 *status = TRUE;
4540 return DD_OK;
4543 #ifdef HAVE_LIBXXF86DGA
4544 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4545 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4547 ICOM_THIS(IDirectDraw2Impl,iface);
4548 DDSURFACEDESC ddsfd;
4549 static struct {
4550 int w,h;
4551 } modes[5] = { /* some of the usual modes */
4552 {512,384},
4553 {640,400},
4554 {640,480},
4555 {800,600},
4556 {1024,768},
4558 static int depths[4] = {8,16,24,32};
4559 int i,j;
4561 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4562 ddsfd.dwSize = sizeof(ddsfd);
4563 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4564 if (dwFlags & DDEDM_REFRESHRATES) {
4565 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4566 ddsfd.u.dwRefreshRate = 60;
4568 ddsfd.ddsCaps.dwCaps = 0;
4569 ddsfd.dwBackBufferCount = 1;
4571 #ifdef HAVE_LIBXXF86DGA2
4572 if (This->e.dga.version == 2) {
4573 XDGAMode *modes = This->e.dga.modes;
4575 ddsfd.dwFlags |= DDSD_PITCH;
4576 for (i = 0; i < This->e.dga.num_modes; i++) {
4577 if (TRACE_ON(ddraw)) {
4578 DPRINTF(" Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
4579 modes[i].num,
4580 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
4581 modes[i].viewportWidth, modes[i].viewportHeight,
4582 modes[i].depth);
4583 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
4584 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
4585 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
4586 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
4587 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
4588 DPRINTF("\n");
4590 /* Fill the pixel format */
4591 ddsfd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
4592 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4593 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4594 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = modes[i].bitsPerPixel;
4595 if (modes[i].depth == 8) {
4596 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4597 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4598 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4599 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4600 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4601 } else {
4602 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4603 ddsfd.ddpfPixelFormat.u1.dwRBitMask = modes[i].redMask;
4604 ddsfd.ddpfPixelFormat.u2.dwGBitMask = modes[i].greenMask;
4605 ddsfd.ddpfPixelFormat.u3.dwBBitMask = modes[i].blueMask;
4608 ddsfd.dwWidth = modes[i].viewportWidth;
4609 ddsfd.dwHeight = modes[i].viewportHeight;
4610 ddsfd.lPitch = modes[i].imageWidth;
4612 /* Send mode to the application */
4613 if (!modescb(&ddsfd,context)) return DD_OK;
4615 } else {
4616 #endif
4617 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4618 ddsfd.dwBackBufferCount = 1;
4619 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4620 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4621 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4622 /* FIXME: those masks would have to be set in depth > 8 */
4623 if (depths[i]==8) {
4624 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4625 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4626 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4627 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4628 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4629 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4630 } else {
4631 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4633 /* FIXME: We should query those from X itself */
4634 switch (depths[i]) {
4635 case 16:
4636 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4637 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4638 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4639 break;
4640 case 24:
4641 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4642 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4643 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4644 break;
4645 case 32:
4646 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4647 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4648 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4649 break;
4653 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4654 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4655 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4656 if (!modescb(&ddsfd,context)) return DD_OK;
4658 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4659 ddsfd.dwWidth = modes[j].w;
4660 ddsfd.dwHeight = modes[j].h;
4661 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4662 if (!modescb(&ddsfd,context)) return DD_OK;
4665 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4666 /* modeX is not standard VGA */
4668 ddsfd.dwHeight = 200;
4669 ddsfd.dwWidth = 320;
4670 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4671 if (!modescb(&ddsfd,context)) return DD_OK;
4674 #ifdef HAVE_LIBXXF86DGA2
4676 #endif
4677 return DD_OK;
4679 #endif /* defined(HAVE_LIBXXF86DGA) */
4681 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4682 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4684 ICOM_THIS(IDirectDraw2Impl,iface);
4685 XVisualInfo *vi;
4686 XPixmapFormatValues *pf;
4687 XVisualInfo vt;
4688 int xbpp, nvisuals, npixmap, i, emu;
4689 int has_mode[] = { 0, 0, 0, 0 };
4690 int has_depth[] = { 8, 15, 16, 24 };
4691 DDSURFACEDESC ddsfd;
4692 static struct {
4693 int w,h;
4694 } modes[] = { /* some of the usual modes */
4695 {512,384},
4696 {640,400},
4697 {640,480},
4698 {800,600},
4699 {1024,768},
4700 {1280,1024}
4702 DWORD maxWidth, maxHeight;
4704 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4705 ddsfd.dwSize = sizeof(ddsfd);
4706 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_PITCH;
4707 if (dwFlags & DDEDM_REFRESHRATES) {
4708 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4709 ddsfd.u.dwRefreshRate = 60;
4711 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4712 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4714 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4715 pf = XListPixmapFormats(display, &npixmap);
4717 i = 0;
4718 emu = 0;
4719 while ((i < npixmap) || (emu != 4)) {
4720 int mode_index = 0;
4721 int send_mode = 0;
4722 int j;
4724 if (i < npixmap) {
4725 for (j = 0; j < 4; j++) {
4726 if (has_depth[j] == pf[i].depth) {
4727 mode_index = j;
4728 break;
4731 if (j == 4) {
4732 i++;
4733 continue;
4737 if (has_mode[mode_index] == 0) {
4738 if (mode_index == 0) {
4739 send_mode = 1;
4741 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4742 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4743 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4744 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4745 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4746 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4747 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4748 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4749 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4751 xbpp = 1;
4753 has_mode[mode_index] = 1;
4754 } else {
4755 /* All the 'true color' depths (15, 16 and 24)
4756 First, find the corresponding visual to extract the bit masks */
4757 for (j = 0; j < nvisuals; j++) {
4758 if (vi[j].depth == pf[i].depth) {
4759 ddsfd.ddsCaps.dwCaps = 0;
4760 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4761 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4762 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4763 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4764 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4765 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4766 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4767 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4769 xbpp = pf[i].bits_per_pixel/8;
4771 send_mode = 1;
4772 has_mode[mode_index] = 1;
4773 break;
4776 if (j == nvisuals)
4777 ERR("Did not find visual corresponding the the pixmap format !\n");
4780 i++;
4781 } else {
4782 /* Now to emulated modes */
4783 if (has_mode[emu] == 0) {
4784 int c;
4785 int l;
4786 int depth = has_depth[emu];
4788 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4789 if (ModeEmulations[c].dest.depth == depth) {
4790 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4791 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4792 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4793 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4794 int j;
4795 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4796 if ((vi[j].depth == pf[l].depth) &&
4797 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4798 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4799 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4800 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4801 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4802 if (depth == 8) {
4803 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4804 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4805 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4806 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4807 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4808 } else {
4809 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4810 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4811 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4812 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4813 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4815 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4816 send_mode = 1;
4819 if (send_mode == 0)
4820 ERR("No visual corresponding to pixmap format !\n");
4828 emu++;
4831 if (send_mode) {
4832 int mode;
4834 if (TRACE_ON(ddraw)) {
4835 TRACE("Enumerating with pixel format : \n");
4836 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4837 DPRINTF("\n");
4840 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4841 /* Do not enumerate modes we cannot handle anyway */
4842 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4843 break;
4845 ddsfd.dwWidth = modes[mode].w;
4846 ddsfd.dwHeight= modes[mode].h;
4847 ddsfd.lPitch = ddsfd.dwWidth * xbpp;
4849 /* Now, send the mode description to the application */
4850 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4851 if (!modescb(&ddsfd, context))
4852 goto exit_enum;
4855 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4856 /* modeX is not standard VGA */
4857 ddsfd.dwWidth = 320;
4858 ddsfd.dwHeight = 200;
4859 ddsfd.lPitch = 320 * xbpp;
4860 if (!modescb(&ddsfd, context))
4861 goto exit_enum;
4865 exit_enum:
4866 TSXFree(vi);
4867 TSXFree(pf);
4869 return DD_OK;
4872 #ifdef HAVE_LIBXXF86DGA
4873 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4874 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4876 ICOM_THIS(IDirectDraw2Impl,iface);
4877 TRACE("(%p)->(%p)\n",This,lpddsfd);
4878 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4879 lpddsfd->dwHeight = This->d.height;
4880 lpddsfd->dwWidth = This->d.width;
4881 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4882 lpddsfd->dwBackBufferCount = 2;
4883 lpddsfd->u.dwRefreshRate = 60;
4884 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4885 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4886 if (TRACE_ON(ddraw)) {
4887 _dump_surface_desc(lpddsfd);
4889 return DD_OK;
4891 #endif /* defined(HAVE_LIBXXF86DGA) */
4893 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4894 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4896 ICOM_THIS(IDirectDraw2Impl,iface);
4897 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4898 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4899 lpddsfd->dwHeight = This->d.height;
4900 lpddsfd->dwWidth = This->d.width;
4901 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4902 lpddsfd->dwBackBufferCount = 2;
4903 lpddsfd->u.dwRefreshRate = 60;
4904 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4905 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4906 if (TRACE_ON(ddraw)) {
4907 _dump_surface_desc(lpddsfd);
4909 return DD_OK;
4912 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4913 ICOM_THIS(IDirectDraw2Impl,iface);
4914 TRACE("(%p)->()\n",This);
4915 return DD_OK;
4918 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4919 LPDIRECTDRAW2 iface,LPDWORD freq
4921 ICOM_THIS(IDirectDraw2Impl,iface);
4922 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4923 *freq = 60*100; /* 60 Hz */
4924 return DD_OK;
4927 /* what can we directly decompress? */
4928 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4929 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4931 ICOM_THIS(IDirectDraw2Impl,iface);
4932 FIXME("(%p,%p,%p), stub\n",This,x,y);
4933 return DD_OK;
4936 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4937 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4939 ICOM_THIS(IDirectDraw2Impl,iface);
4940 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4941 return DD_OK;
4944 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4945 LPDIRECTDRAW2 iface )
4947 ICOM_THIS(IDirectDraw2Impl,iface);
4948 FIXME("(%p)->()\n", This );
4950 return DD_OK;
4953 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4954 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4955 ICOM_THIS(IDirectDraw2Impl,iface);
4956 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4958 return DD_OK;
4961 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4962 LPDWORD lpdwScanLine) {
4963 ICOM_THIS(IDirectDraw2Impl,iface);
4964 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4966 if (lpdwScanLine)
4967 *lpdwScanLine = 0;
4968 return DD_OK;
4971 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4972 GUID *lpGUID) {
4973 ICOM_THIS(IDirectDraw2Impl,iface);
4974 FIXME("(%p)->(%p)\n", This, lpGUID);
4976 return DD_OK;
4979 #ifdef HAVE_LIBXXF86DGA
4981 /* Note: Hack so we can reuse the old functions without compiler warnings */
4982 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4983 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4984 #else
4985 # define XCAST(fun) (void *)
4986 #endif
4988 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4990 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4991 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4992 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4993 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4994 XCAST(Compact)IDirectDraw2Impl_Compact,
4995 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4996 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4997 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4998 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4999 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5000 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5001 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5002 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5003 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5004 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5005 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5006 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5007 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5008 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5009 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5010 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5011 #ifdef HAVE_LIBXXF86DGA2
5012 XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
5013 #else
5014 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5015 #endif
5016 DGA_IDirectDrawImpl_SetDisplayMode,
5017 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5020 #undef XCAST
5022 #endif /* defined(HAVE_LIBXXF86DGA) */
5024 /* Note: Hack so we can reuse the old functions without compiler warnings */
5025 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5026 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
5027 #else
5028 # define XCAST(fun) (void *)
5029 #endif
5031 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
5033 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5034 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5035 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5036 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5037 XCAST(Compact)IDirectDraw2Impl_Compact,
5038 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5039 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5040 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5041 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5042 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5043 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5044 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5045 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5046 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5047 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5048 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5049 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5050 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5051 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5052 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5053 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5054 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5055 Xlib_IDirectDrawImpl_SetDisplayMode,
5056 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5059 #undef XCAST
5061 /*****************************************************************************
5062 * IDirectDraw2
5066 #ifdef HAVE_LIBXXF86DGA
5067 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
5068 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
5070 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5071 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5073 #endif /* defined(HAVE_LIBXXF86DGA) */
5075 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
5076 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
5078 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5079 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5082 #ifdef HAVE_LIBXXF86DGA
5083 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
5084 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5086 ICOM_THIS(IDirectDraw2Impl,iface);
5087 TRACE("(%p)->(%p,%p,%p)\n",
5088 This,ddscaps,total,free
5090 if (total) *total = This->e.dga.fb_memsize * 1024;
5091 if (free) *free = This->e.dga.fb_memsize * 1024;
5092 return DD_OK;
5094 #endif /* defined(HAVE_LIBXXF86DGA) */
5096 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
5097 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5099 ICOM_THIS(IDirectDraw2Impl,iface);
5100 TRACE("(%p)->(%p,%p,%p)\n",
5101 This,ddscaps,total,free
5103 if (total) *total = 2048 * 1024;
5104 if (free) *free = 2048 * 1024;
5105 return DD_OK;
5108 #ifdef HAVE_LIBXXF86DGA
5109 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
5111 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5112 DGA_IDirectDraw2Impl_QueryInterface,
5113 IDirectDraw2Impl_AddRef,
5114 DGA_IDirectDraw2Impl_Release,
5115 IDirectDraw2Impl_Compact,
5116 IDirectDraw2Impl_CreateClipper,
5117 DGA_IDirectDraw2Impl_CreatePalette,
5118 DGA_IDirectDraw2Impl_CreateSurface,
5119 IDirectDraw2Impl_DuplicateSurface,
5120 DGA_IDirectDraw2Impl_EnumDisplayModes,
5121 IDirectDraw2Impl_EnumSurfaces,
5122 IDirectDraw2Impl_FlipToGDISurface,
5123 DGA_IDirectDraw2Impl_GetCaps,
5124 DGA_IDirectDraw2Impl_GetDisplayMode,
5125 IDirectDraw2Impl_GetFourCCCodes,
5126 IDirectDraw2Impl_GetGDISurface,
5127 IDirectDraw2Impl_GetMonitorFrequency,
5128 IDirectDraw2Impl_GetScanLine,
5129 IDirectDraw2Impl_GetVerticalBlankStatus,
5130 IDirectDraw2Impl_Initialize,
5131 DGA_IDirectDraw2Impl_RestoreDisplayMode,
5132 IDirectDraw2Impl_SetCooperativeLevel,
5133 DGA_IDirectDraw2Impl_SetDisplayMode,
5134 IDirectDraw2Impl_WaitForVerticalBlank,
5135 DGA_IDirectDraw2Impl_GetAvailableVidMem
5137 #endif /* defined(HAVE_LIBXXF86DGA) */
5139 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
5141 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5142 Xlib_IDirectDraw2Impl_QueryInterface,
5143 IDirectDraw2Impl_AddRef,
5144 Xlib_IDirectDraw2Impl_Release,
5145 IDirectDraw2Impl_Compact,
5146 IDirectDraw2Impl_CreateClipper,
5147 Xlib_IDirectDraw2Impl_CreatePalette,
5148 Xlib_IDirectDraw2Impl_CreateSurface,
5149 IDirectDraw2Impl_DuplicateSurface,
5150 Xlib_IDirectDraw2Impl_EnumDisplayModes,
5151 IDirectDraw2Impl_EnumSurfaces,
5152 IDirectDraw2Impl_FlipToGDISurface,
5153 Xlib_IDirectDraw2Impl_GetCaps,
5154 Xlib_IDirectDraw2Impl_GetDisplayMode,
5155 IDirectDraw2Impl_GetFourCCCodes,
5156 IDirectDraw2Impl_GetGDISurface,
5157 IDirectDraw2Impl_GetMonitorFrequency,
5158 IDirectDraw2Impl_GetScanLine,
5159 IDirectDraw2Impl_GetVerticalBlankStatus,
5160 IDirectDraw2Impl_Initialize,
5161 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5162 IDirectDraw2Impl_SetCooperativeLevel,
5163 Xlib_IDirectDraw2Impl_SetDisplayMode,
5164 IDirectDraw2Impl_WaitForVerticalBlank,
5165 Xlib_IDirectDraw2Impl_GetAvailableVidMem
5168 /*****************************************************************************
5169 * IDirectDraw4
5173 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
5174 HDC hdc,
5175 LPDIRECTDRAWSURFACE *lpDDS) {
5176 ICOM_THIS(IDirectDraw4Impl,iface);
5177 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
5179 return DD_OK;
5182 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
5183 ICOM_THIS(IDirectDraw4Impl,iface);
5184 FIXME("(%p)->()\n", This);
5186 return DD_OK;
5189 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
5190 ICOM_THIS(IDirectDraw4Impl,iface);
5191 FIXME("(%p)->()\n", This);
5193 return DD_OK;
5196 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5197 LPDDDEVICEIDENTIFIER lpdddi,
5198 DWORD dwFlags) {
5199 ICOM_THIS(IDirectDraw4Impl,iface);
5200 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5202 return DD_OK;
5205 #ifdef HAVE_LIBXXF86DGA
5207 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5208 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5209 #else
5210 # define XCAST(fun) (void*)
5211 #endif
5213 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5215 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5216 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5217 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5218 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5219 XCAST(Compact)IDirectDraw2Impl_Compact,
5220 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5221 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5222 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5223 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5224 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5225 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5226 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5227 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5228 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5229 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5230 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5231 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5232 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5233 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5234 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5235 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5236 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5237 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5238 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5239 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5240 IDirectDraw4Impl_GetSurfaceFromDC,
5241 IDirectDraw4Impl_RestoreAllSurfaces,
5242 IDirectDraw4Impl_TestCooperativeLevel,
5243 IDirectDraw4Impl_GetDeviceIdentifier
5246 #undef XCAST
5248 #endif /* defined(HAVE_LIBXXF86DGA) */
5250 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5251 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5252 #else
5253 # define XCAST(fun) (void*)
5254 #endif
5256 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5258 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5259 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5260 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5261 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5262 XCAST(Compact)IDirectDraw2Impl_Compact,
5263 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5264 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5265 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5266 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5267 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5268 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5269 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5270 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5271 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5272 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5273 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5274 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5275 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5276 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5277 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5278 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5279 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5280 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5281 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5282 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5283 IDirectDraw4Impl_GetSurfaceFromDC,
5284 IDirectDraw4Impl_RestoreAllSurfaces,
5285 IDirectDraw4Impl_TestCooperativeLevel,
5286 IDirectDraw4Impl_GetDeviceIdentifier
5289 #undef XCAST
5291 /******************************************************************************
5292 * DirectDrawCreate
5295 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5297 LRESULT ret;
5298 IDirectDrawImpl* ddraw = NULL;
5299 DWORD lastError;
5301 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5303 SetLastError( ERROR_SUCCESS );
5304 ddraw = (IDirectDrawImpl*)GetPropA( hwnd, ddProp );
5305 if( (!ddraw) && ( ( lastError = GetLastError() ) != ERROR_SUCCESS ))
5307 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5310 if( ddraw )
5312 /* Perform any special direct draw functions */
5313 if (msg==WM_PAINT)
5314 ddraw->d.paintable = 1;
5316 /* Now let the application deal with the rest of this */
5317 if( ddraw->d.mainWindow )
5320 /* Don't think that we actually need to call this but...
5321 might as well be on the safe side of things... */
5323 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5324 it should be the procedures of our fake window that gets called
5325 instead of those of the window provided by the application.
5326 And with this patch, mouse clicks work with Monkey Island III
5327 - Lionel */
5328 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5330 if( !ret )
5332 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5333 /* We didn't handle the message - give it to the application */
5334 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5336 ret = CallWindowProcA(tmpWnd->winproc,
5337 ddraw->d.mainWindow, msg, wParam, lParam );
5339 WIN_ReleaseWndPtr(tmpWnd);
5343 } else {
5344 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5348 else
5350 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5353 return ret;
5356 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5357 #ifdef HAVE_LIBXXF86DGA
5358 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5359 int memsize,banksize,major,minor,flags;
5360 char *addr;
5361 int depth;
5362 int dga_version;
5363 int width, height;
5365 /* Get DGA availability / version */
5366 dga_version = DDRAW_DGA_Available();
5368 if (dga_version == 0) {
5369 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5370 return DDERR_GENERIC;
5373 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5374 (*ilplpDD)->ref = 1;
5375 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5376 #ifdef HAVE_LIBXXF86DGA2
5377 if (dga_version == 1) {
5378 (*ilplpDD)->e.dga.version = 1;
5379 #endif /* defined(HAVE_LIBXXF86DGA2) */
5380 TSXF86DGAQueryVersion(display,&major,&minor);
5381 TRACE("XF86DGA is version %d.%d\n",major,minor);
5382 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5383 if (!(flags & XF86DGADirectPresent))
5384 MESSAGE("direct video is NOT PRESENT.\n");
5385 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5386 (*ilplpDD)->e.dga.fb_width = width;
5387 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5388 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5389 (*ilplpDD)->e.dga.fb_height = height;
5390 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5391 addr,width,banksize,memsize
5393 TRACE("viewport height: %d\n",height);
5394 /* Get the screen dimensions as seen by Wine.
5395 In that case, it may be better to ignore the -desktop mode and return the
5396 real screen size => print a warning */
5397 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5398 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5399 if (((*ilplpDD)->d.height != height) ||
5400 ((*ilplpDD)->d.width != width))
5401 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5402 (*ilplpDD)->e.dga.fb_addr = addr;
5403 (*ilplpDD)->e.dga.fb_memsize = memsize;
5404 (*ilplpDD)->e.dga.vpmask = 0;
5406 /* just assume the default depth is the DGA depth too */
5407 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5408 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
5409 #ifdef RESTORE_SIGNALS
5410 SIGNAL_Init();
5411 #endif
5412 #ifdef HAVE_LIBXXF86DGA2
5413 } else {
5414 XDGAMode *modes;
5415 int i, num_modes;
5416 int mode_to_use = 0;
5418 (*ilplpDD)->e.dga.version = 2;
5420 TSXDGAQueryVersion(display,&major,&minor);
5421 TRACE("XDGA is version %d.%d\n",major,minor);
5423 TRACE("Opening the frame buffer.\n");
5424 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5425 ERR("Error opening the frame buffer !!!\n");
5427 return DDERR_GENERIC;
5430 /* List all available modes */
5431 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5432 (*ilplpDD)->e.dga.modes = modes;
5433 (*ilplpDD)->e.dga.num_modes = num_modes;
5434 if (TRACE_ON(ddraw)) {
5435 TRACE("Available modes :\n");
5436 for (i = 0; i < num_modes; i++) {
5437 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5438 modes[i].num,
5439 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5440 modes[i].viewportWidth, modes[i].viewportHeight,
5441 modes[i].depth);
5442 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5443 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5444 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5445 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5446 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5447 DPRINTF("\n");
5449 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5450 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5451 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5452 mode_to_use = modes[i].num;
5456 if (mode_to_use == 0) {
5457 ERR("Could not find mode !\n");
5458 mode_to_use = 1;
5459 } else {
5460 DPRINTF("Using mode number %d\n", mode_to_use);
5463 /* Initialize the frame buffer */
5464 _DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
5465 /* Set the input handling for relative mouse movements */
5466 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5468 #endif /* defined(HAVE_LIBXXF86DGA2) */
5469 return DD_OK;
5470 #else /* defined(HAVE_LIBXXF86DGA) */
5471 return DDERR_INVALIDDIRECTDRAWGUID;
5472 #endif /* defined(HAVE_LIBXXF86DGA) */
5475 static BOOL
5476 DDRAW_XSHM_Available(void)
5478 #ifdef HAVE_LIBXXSHM
5479 if (TSXShmQueryExtension(display))
5481 int major, minor;
5482 Bool shpix;
5484 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5485 (Options.noXSHM != 1))
5486 return 1;
5487 else
5488 return 0;
5490 else
5491 return 0;
5492 #else
5493 return 0;
5494 #endif
5497 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5498 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5499 int depth;
5501 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5502 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5503 (*ilplpDD)->ref = 1;
5504 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5506 /* At DirectDraw creation, the depth is the default depth */
5507 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5508 _common_depth_to_pixelformat(depth,
5509 &((*ilplpDD)->d.directdraw_pixelformat),
5510 &((*ilplpDD)->d.screen_pixelformat),
5511 &((*ilplpDD)->d.pixmap_depth));
5512 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5513 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5515 #ifdef HAVE_LIBXXSHM
5516 /* Test if XShm is available. */
5517 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5518 (*ilplpDD)->e.xlib.xshm_compl = 0;
5519 TRACE("Using XShm extension.\n");
5521 #endif
5523 return DD_OK;
5526 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5527 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5528 WNDCLASSA wc;
5529 /* WND* pParentWindow; */
5530 HRESULT ret;
5532 if (!HIWORD(lpGUID)) lpGUID = NULL;
5534 TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID),ilplpDD,pUnkOuter);
5536 if ( ( !lpGUID ) ||
5537 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5538 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5539 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5540 /* if they didn't request a particular interface, use the best
5541 * supported one */
5542 if (DDRAW_DGA_Available())
5543 lpGUID = &DGA_DirectDraw_GUID;
5544 else
5545 lpGUID = &XLIB_DirectDraw_GUID;
5548 wc.style = CS_GLOBALCLASS;
5549 wc.lpfnWndProc = Xlib_DDWndProc;
5550 wc.cbClsExtra = 0;
5551 wc.cbWndExtra = 0;
5553 /* We can be a child of the desktop since we're really important */
5555 This code is not useful since hInstance is forced to 0 afterward
5556 pParentWindow = WIN_GetDesktop();
5557 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5559 wc.hInstance = 0;
5562 wc.hIcon = 0;
5563 wc.hCursor = (HCURSOR)IDC_ARROWA;
5564 wc.hbrBackground= NULL_BRUSH;
5565 wc.lpszMenuName = 0;
5566 wc.lpszClassName= "WINE_DirectDraw";
5567 RegisterClassA(&wc);
5569 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5570 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5572 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5573 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5575 else {
5576 goto err;
5580 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5581 return ret;
5583 err:
5584 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",
5585 debugstr_guid(lpGUID),lplpDD,pUnkOuter);
5586 return DDERR_INVALIDDIRECTDRAWGUID;
5589 /*******************************************************************************
5590 * DirectDraw ClassFactory
5592 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5595 typedef struct
5597 /* IUnknown fields */
5598 ICOM_VFIELD(IClassFactory);
5599 DWORD ref;
5600 } IClassFactoryImpl;
5602 static HRESULT WINAPI
5603 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5604 ICOM_THIS(IClassFactoryImpl,iface);
5606 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
5607 return E_NOINTERFACE;
5610 static ULONG WINAPI
5611 DDCF_AddRef(LPCLASSFACTORY iface) {
5612 ICOM_THIS(IClassFactoryImpl,iface);
5613 return ++(This->ref);
5616 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5617 ICOM_THIS(IClassFactoryImpl,iface);
5618 /* static class, won't be freed */
5619 return --(This->ref);
5622 static HRESULT WINAPI DDCF_CreateInstance(
5623 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5625 ICOM_THIS(IClassFactoryImpl,iface);
5627 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
5628 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5629 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5630 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5631 /* FIXME: reuse already created DirectDraw if present? */
5632 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5634 return CLASS_E_CLASSNOTAVAILABLE;
5637 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5638 ICOM_THIS(IClassFactoryImpl,iface);
5639 FIXME("(%p)->(%d),stub!\n",This,dolock);
5640 return S_OK;
5643 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5645 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5646 DDCF_QueryInterface,
5647 DDCF_AddRef,
5648 DDCF_Release,
5649 DDCF_CreateInstance,
5650 DDCF_LockServer
5652 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5654 /*******************************************************************************
5655 * DllGetClassObject [DDRAW.13]
5656 * Retrieves class object from a DLL object
5658 * NOTES
5659 * Docs say returns STDAPI
5661 * PARAMS
5662 * rclsid [I] CLSID for the class object
5663 * riid [I] Reference to identifier of interface for class object
5664 * ppv [O] Address of variable to receive interface pointer for riid
5666 * RETURNS
5667 * Success: S_OK
5668 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5669 * E_UNEXPECTED
5671 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5673 TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5674 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5675 *ppv = (LPVOID)&DDRAW_CF;
5676 IClassFactory_AddRef((IClassFactory*)*ppv);
5677 return S_OK;
5679 FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5680 return CLASS_E_CLASSNOTAVAILABLE;
5684 /*******************************************************************************
5685 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5687 * RETURNS
5688 * Success: S_OK
5689 * Failure: S_FALSE
5691 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5693 FIXME("(void): stub\n");
5694 return S_FALSE;
5697 #else /* !defined(X_DISPLAY_MISSING) */
5699 #include "windef.h"
5700 #include "wtypes.h"
5702 #define DD_OK 0
5704 typedef void *LPUNKNOWN;
5705 typedef void *LPDIRECTDRAW;
5706 typedef void *LPDIRECTDRAWCLIPPER;
5707 typedef void *LPDDENUMCALLBACKA;
5708 typedef void *LPDDENUMCALLBACKEXA;
5709 typedef void *LPDDENUMCALLBACKEXW;
5710 typedef void *LPDDENUMCALLBACKW;
5712 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5714 return DD_OK;
5717 HRESULT WINAPI DirectDrawCreate(
5718 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5720 return DD_OK;
5723 HRESULT WINAPI DirectDrawCreateClipper(
5724 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5726 return DD_OK;
5729 HRESULT WINAPI DirectDrawEnumerateA(
5730 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5732 return DD_OK;
5735 HRESULT WINAPI DirectDrawEnumerateExA(
5736 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5738 return DD_OK;
5741 HRESULT WINAPI DirectDrawEnumerateExW(
5742 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5744 return DD_OK;
5747 HRESULT WINAPI DirectDrawEnumerateW(
5748 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5750 return DD_OK;
5753 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5755 return CLASS_E_CLASSNOTAVAILABLE;
5758 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5760 return DD_OK;
5763 #endif /* !defined(X_DISPLAY_MISSING) */