Made MPR a separate dll.
[wine.git] / graphics / ddraw.c
blob5e5936b6ff56fd23edf64077d5b93969994b3a51
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 case 3: {
1283 LPBYTE s,d;
1284 for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
1285 DWORD pixel;
1287 s = sbuf+3*(sx>>16);
1288 d = dbuf+3*x;
1289 pixel = (s[0]<<16)|(s[1]<<8)|s[2];
1290 d[0] = (pixel>>16)&0xff;
1291 d[1] = (pixel>> 8)&0xff;
1292 d[2] = (pixel )&0xff;
1294 break;
1296 default:
1297 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1298 ret = DDERR_UNSUPPORTED;
1299 goto error;
1302 #undef STRETCH_ROW
1305 last_sy = sy;
1306 dbuf += ddesc.lPitch;
1309 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1310 DWORD keylow, keyhigh;
1312 if (dwFlags & DDBLT_KEYSRC) {
1313 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1314 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1315 } else {
1316 /* I'm not sure if this is correct */
1317 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1318 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1319 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1323 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1324 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1326 #define COPYROW_COLORKEY(type) { \
1327 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1328 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1329 tmp = s[sx >> 16]; \
1330 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1332 break; }
1334 switch (bpp) {
1335 case 1: COPYROW_COLORKEY(BYTE)
1336 case 2: COPYROW_COLORKEY(WORD)
1337 case 4: COPYROW_COLORKEY(DWORD)
1338 default:
1339 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1340 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1341 ret = DDERR_UNSUPPORTED;
1342 goto error;
1344 dbuf += ddesc.lPitch;
1347 #undef COPYROW_COLORKEY
1349 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1354 error:
1356 if (dwFlags && FIXME_ON(ddraw)) {
1357 FIXME("\tUnsupported flags: ");
1358 _dump_DDBLT(dwFlags);
1360 release:
1362 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1363 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1365 return DD_OK;
1368 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1369 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1371 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1372 int bpp, w, h, x, y;
1373 DDSURFACEDESC ddesc,sdesc;
1374 HRESULT ret = DD_OK;
1375 LPBYTE sbuf, dbuf;
1376 RECT rsrc2;
1379 if (TRACE_ON(ddraw)) {
1380 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1381 This,dstx,dsty,src,rsrc,trans
1383 FIXME(" trans:");
1384 if (FIXME_ON(ddraw))
1385 _dump_DDBLTFAST(trans);
1386 if (rsrc)
1387 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1388 else
1389 FIXME(" srcrect: NULL\n");
1392 /* We need to lock the surfaces, or we won't get refreshes when done. */
1393 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1394 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1396 if (!rsrc) {
1397 WARN("rsrc is NULL!\n");
1398 rsrc = &rsrc2;
1399 rsrc->left = rsrc->top = 0;
1400 rsrc->right = sdesc.dwWidth;
1401 rsrc->bottom = sdesc.dwHeight;
1404 bpp = GET_BPP(This->s.surface_desc);
1405 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1406 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1409 h=rsrc->bottom-rsrc->top;
1410 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1411 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1412 if (h<0) h=0;
1414 w=rsrc->right-rsrc->left;
1415 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1416 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1417 if (w<0) w=0;
1419 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1420 DWORD keylow, keyhigh;
1421 if (trans & DDBLTFAST_SRCCOLORKEY) {
1422 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1423 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1424 } else {
1425 /* I'm not sure if this is correct */
1426 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1427 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1428 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1431 #define COPYBOX_COLORKEY(type) { \
1432 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1433 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1434 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1435 for (y = 0; y < h; y++) { \
1436 for (x = 0; x < w; x++) { \
1437 tmp = s[x]; \
1438 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1440 (LPBYTE)s += sdesc.lPitch; \
1441 (LPBYTE)d += ddesc.lPitch; \
1443 break; \
1446 switch (bpp) {
1447 case 1: COPYBOX_COLORKEY(BYTE)
1448 case 2: COPYBOX_COLORKEY(WORD)
1449 case 4: COPYBOX_COLORKEY(DWORD)
1450 default:
1451 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1452 ret = DDERR_UNSUPPORTED;
1453 goto error;
1456 #undef COPYBOX_COLORKEY
1458 } else {
1459 int width = w * bpp;
1461 for (y = 0; y < h; y++) {
1462 memcpy(dbuf, sbuf, width);
1463 sbuf += sdesc.lPitch;
1464 dbuf += ddesc.lPitch;
1468 error:
1470 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1471 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1472 return ret;
1475 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1476 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1478 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1479 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1480 This,ddbltbatch,x,y
1482 return DD_OK;
1485 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1486 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1488 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1489 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1490 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1491 return DD_OK;
1494 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1495 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1496 ) {
1497 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1498 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1500 /* Simply copy the surface description stored in the object */
1501 *ddsd = This->s.surface_desc;
1503 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1505 return DD_OK;
1508 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1509 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1510 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1511 return ++(This->ref);
1514 #ifdef HAVE_LIBXXF86DGA
1515 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1516 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1518 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1520 if (--(This->ref))
1521 return This->ref;
1523 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1524 /* clear out of surface list */
1525 if (This->t.dga.fb_height == -1)
1526 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1527 else
1528 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1530 /* Free the DIBSection (if any) */
1531 if (This->s.hdc != 0) {
1532 SelectObject(This->s.hdc, This->s.holdbitmap);
1533 DeleteDC(This->s.hdc);
1534 DeleteObject(This->s.DIBsection);
1537 /* Free the clipper if attached to this surface */
1538 if( This->s.lpClipper )
1539 IDirectDrawClipper_Release(This->s.lpClipper);
1541 HeapFree(GetProcessHeap(),0,This);
1542 return S_OK;
1544 #endif /* defined(HAVE_LIBXXF86DGA) */
1546 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1547 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1549 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1551 if (--(This->ref))
1552 return This->ref;
1554 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1556 if (This->t.xlib.image != NULL) {
1557 if (This->s.ddraw->d.pixel_convert != NULL) {
1558 /* In pixel conversion mode, there are 2 buffers to release. */
1559 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1561 #ifdef HAVE_LIBXXSHM
1562 if (This->s.ddraw->e.xlib.xshm_active) {
1563 TSXShmDetach(display, &(This->t.xlib.shminfo));
1564 TSXDestroyImage(This->t.xlib.image);
1565 shmdt(This->t.xlib.shminfo.shmaddr);
1566 } else {
1567 #endif
1568 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1569 This->t.xlib.image->data = NULL;
1570 TSXDestroyImage(This->t.xlib.image);
1571 #ifdef HAVE_LIBXXSHM
1573 #endif
1574 } else {
1575 This->t.xlib.image->data = NULL;
1577 #ifdef HAVE_LIBXXSHM
1578 if (This->s.ddraw->e.xlib.xshm_active) {
1579 TSXShmDetach(display, &(This->t.xlib.shminfo));
1580 TSXDestroyImage(This->t.xlib.image);
1581 shmdt(This->t.xlib.shminfo.shmaddr);
1582 } else {
1583 #endif
1584 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1585 TSXDestroyImage(This->t.xlib.image);
1586 #ifdef HAVE_LIBXXSHM
1588 #endif
1590 This->t.xlib.image = 0;
1591 } else {
1592 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1595 if (This->s.palette)
1596 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1598 /* Free the DIBSection (if any) */
1599 if (This->s.hdc != 0) {
1600 SelectObject(This->s.hdc, This->s.holdbitmap);
1601 DeleteDC(This->s.hdc);
1602 DeleteObject(This->s.DIBsection);
1605 /* Free the clipper if present */
1606 if( This->s.lpClipper )
1607 IDirectDrawClipper_Release(This->s.lpClipper);
1609 HeapFree(GetProcessHeap(),0,This);
1610 return S_OK;
1613 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1614 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1616 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1617 int i,found = 0,xstart;
1618 struct _surface_chain *chain;
1620 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1621 if (TRACE_ON(ddraw)) {
1622 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1623 DPRINTF("\n");
1625 chain = This->s.chain;
1626 if (!chain)
1627 return DDERR_NOTFOUND;
1629 for (i=0;i<chain->nrofsurfaces;i++)
1630 if (chain->surfaces[i] == This)
1631 break;
1633 xstart = i;
1634 for (i=0;i<chain->nrofsurfaces;i++) {
1635 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1636 #if 0
1637 if (found) /* may not find the same caps twice, (doc) */
1638 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1639 #endif
1640 found = (i+1)+xstart;
1643 if (!found)
1644 return DDERR_NOTFOUND;
1645 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1646 /* FIXME: AddRef? */
1647 TRACE("found %p\n",*lpdsf);
1648 return DD_OK;
1651 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1652 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1654 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1655 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1657 return DDERR_ALREADYINITIALIZED;
1660 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1661 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1663 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1664 TRACE("(%p)->(%p)\n",This,pf);
1666 *pf = This->s.surface_desc.ddpfPixelFormat;
1667 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1668 return DD_OK;
1671 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1672 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1673 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1674 return DD_OK;
1677 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1678 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1680 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1681 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1682 return DD_OK;
1685 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1686 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
1688 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1689 TRACE("(%p)->(%p)!\n",This,lpClipper);
1691 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
1692 This->s.lpClipper = lpClipper;
1693 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
1694 return DD_OK;
1697 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1698 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1700 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1701 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1702 int i;
1703 struct _surface_chain *chain;
1705 FIXME("(%p)->(%p)\n",This,surf);
1706 chain = This->s.chain;
1708 /* IDirectDrawSurface4_AddRef(surf); */
1710 if (chain) {
1711 for (i=0;i<chain->nrofsurfaces;i++)
1712 if (chain->surfaces[i] == isurf)
1713 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1714 } else {
1715 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1716 chain->nrofsurfaces = 1;
1717 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1718 chain->surfaces[0] = This;
1719 This->s.chain = chain;
1722 if (chain->surfaces)
1723 chain->surfaces = HeapReAlloc(
1724 GetProcessHeap(),
1726 chain->surfaces,
1727 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1729 else
1730 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1731 isurf->s.chain = chain;
1732 chain->surfaces[chain->nrofsurfaces++] = isurf;
1733 return DD_OK;
1736 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1737 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1738 DDSURFACEDESC desc;
1739 BITMAPINFO *b_info;
1740 UINT usage;
1742 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1744 /* Creates a DIB Section of the same size / format as the surface */
1745 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1747 if (This->s.hdc == 0) {
1748 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1749 case 16:
1750 case 32:
1751 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1752 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1753 break;
1754 #endif
1756 case 24:
1757 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1758 break;
1760 default:
1761 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1762 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1763 break;
1766 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1767 b_info->bmiHeader.biWidth = desc.dwWidth;
1768 b_info->bmiHeader.biHeight = desc.dwHeight;
1769 b_info->bmiHeader.biPlanes = 1;
1770 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1771 #if 0
1772 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1773 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1774 #endif
1775 b_info->bmiHeader.biCompression = BI_RGB;
1776 #if 0
1777 else
1778 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1779 #endif
1780 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1781 b_info->bmiHeader.biXPelsPerMeter = 0;
1782 b_info->bmiHeader.biYPelsPerMeter = 0;
1783 b_info->bmiHeader.biClrUsed = 0;
1784 b_info->bmiHeader.biClrImportant = 0;
1786 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1787 case 16:
1788 case 32:
1789 #if 0
1791 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1793 usage = 0;
1794 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1795 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1796 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1798 break;
1799 #endif
1800 case 24:
1801 /* Nothing to do */
1802 usage = DIB_RGB_COLORS;
1803 break;
1805 default: {
1806 int i;
1808 /* Fill the palette */
1809 usage = DIB_RGB_COLORS;
1811 if (This->s.palette == NULL) {
1812 ERR("Bad palette !!!\n");
1813 } else {
1814 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1815 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1817 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1818 rgb[i].rgbBlue = pent[i].peBlue;
1819 rgb[i].rgbRed = pent[i].peRed;
1820 rgb[i].rgbGreen = pent[i].peGreen;
1824 break;
1826 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1827 b_info,
1828 usage,
1829 &(This->s.bitmap_data),
1833 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1834 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1836 /* b_info is not useful anymore */
1837 HeapFree(GetProcessHeap(), 0, b_info);
1839 /* Create the DC */
1840 This->s.hdc = CreateCompatibleDC(0);
1841 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1844 /* Copy our surface in the DIB section */
1845 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1846 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1847 else
1848 /* TODO */
1849 FIXME("This case has to be done :/\n");
1851 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1852 *lphdc = This->s.hdc;
1854 return DD_OK;
1857 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1858 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1860 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1861 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1862 /* Copy the DIB section to our surface */
1863 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1864 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1865 } else {
1866 /* TODO */
1867 FIXME("This case has to be done :/\n");
1869 /* Unlock the surface */
1870 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1871 return DD_OK;
1874 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1875 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1877 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
1879 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1880 * the same interface. And IUnknown does that too of course.
1882 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1883 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1884 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1885 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1886 IsEqualGUID( &IID_IUnknown, refiid )
1888 *obj = This;
1889 IDirectDrawSurface4_AddRef(iface);
1891 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1892 return S_OK;
1894 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1896 /* Texture interface */
1897 *obj = d3dtexture2_create(This);
1898 IDirectDrawSurface4_AddRef(iface);
1899 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1900 return S_OK;
1902 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1904 /* Texture interface */
1905 *obj = d3dtexture_create(This);
1906 IDirectDrawSurface4_AddRef(iface);
1908 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1910 return S_OK;
1912 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1913 /* It is the OpenGL Direct3D Device */
1914 IDirectDrawSurface4_AddRef(iface);
1915 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1916 return S_OK;
1919 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
1920 return OLE_E_ENUM_NOMORE;
1923 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1924 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1925 TRACE("(%p)->(), stub!\n",This);
1926 return DD_OK; /* hmm */
1929 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1930 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1931 int i;
1932 struct _surface_chain *chain = This->s.chain;
1934 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1935 for (i=0;i<chain->nrofsurfaces;i++) {
1936 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1937 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1938 return DD_OK; /* FIXME: return value correct? */
1940 return DD_OK;
1943 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1944 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1945 FIXME("(%p)->(),stub!\n",This);
1946 return DD_OK;
1949 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1950 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1952 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1953 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1954 if (TRACE_ON(ddraw)) {
1955 _dump_colorkeyflag(dwFlags);
1956 DPRINTF(" : ");
1957 _dump_DDCOLORKEY((void *) ckey);
1958 DPRINTF("\n");
1961 /* If this surface was loaded as a texture, call also the texture
1962 SetColorKey callback */
1963 if (This->s.texture) {
1964 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1967 if( dwFlags & DDCKEY_SRCBLT )
1969 dwFlags &= ~DDCKEY_SRCBLT;
1970 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1971 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1974 if( dwFlags & DDCKEY_DESTBLT )
1976 dwFlags &= ~DDCKEY_DESTBLT;
1977 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1978 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1981 if( dwFlags & DDCKEY_SRCOVERLAY )
1983 dwFlags &= ~DDCKEY_SRCOVERLAY;
1984 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1985 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1988 if( dwFlags & DDCKEY_DESTOVERLAY )
1990 dwFlags &= ~DDCKEY_DESTOVERLAY;
1991 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1992 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1995 if( dwFlags )
1997 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2000 return DD_OK;
2004 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
2005 LPDIRECTDRAWSURFACE4 iface,
2006 LPRECT lpRect )
2008 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2009 FIXME("(%p)->(%p),stub!\n",This,lpRect);
2011 return DD_OK;
2014 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
2015 LPDIRECTDRAWSURFACE4 iface,
2016 DWORD dwFlags,
2017 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
2019 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2020 int i;
2021 struct _surface_chain *chain;
2023 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
2024 chain = This->s.chain;
2025 for (i=0;i<chain->nrofsurfaces;i++) {
2026 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
2027 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
2029 chain->surfaces[i]->s.chain = NULL;
2030 memcpy( chain->surfaces+i,
2031 chain->surfaces+(i+1),
2032 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
2034 chain->surfaces = HeapReAlloc(
2035 GetProcessHeap(),
2037 chain->surfaces,
2038 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
2040 chain->nrofsurfaces--;
2041 return DD_OK;
2044 return DD_OK;
2047 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
2048 LPDIRECTDRAWSURFACE4 iface,
2049 DWORD dwFlags,
2050 LPVOID lpContext,
2051 LPDDENUMSURFACESCALLBACK lpfnCallback )
2053 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2054 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
2055 lpContext, lpfnCallback );
2057 return DD_OK;
2060 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
2061 LPDIRECTDRAWSURFACE4 iface,
2062 LPDIRECTDRAWCLIPPER* lplpDDClipper )
2064 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2065 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
2067 return DD_OK;
2070 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
2071 LPDIRECTDRAWSURFACE4 iface,
2072 DWORD dwFlags,
2073 LPDDCOLORKEY lpDDColorKey )
2075 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2076 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
2078 if( dwFlags & DDCKEY_SRCBLT ) {
2079 dwFlags &= ~DDCKEY_SRCBLT;
2080 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
2083 if( dwFlags & DDCKEY_DESTBLT )
2085 dwFlags &= ~DDCKEY_DESTBLT;
2086 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
2089 if( dwFlags & DDCKEY_SRCOVERLAY )
2091 dwFlags &= ~DDCKEY_SRCOVERLAY;
2092 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
2095 if( dwFlags & DDCKEY_DESTOVERLAY )
2097 dwFlags &= ~DDCKEY_DESTOVERLAY;
2098 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
2101 if( dwFlags )
2103 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2106 return DD_OK;
2109 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
2110 LPDIRECTDRAWSURFACE4 iface,
2111 DWORD dwFlags )
2113 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2114 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2116 return DD_OK;
2119 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
2120 LPDIRECTDRAWSURFACE4 iface,
2121 LPDIRECTDRAWPALETTE* lplpDDPalette )
2123 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2124 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
2126 if (This->s.palette != NULL) {
2127 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
2129 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
2130 return DD_OK;
2131 } else {
2132 return DDERR_NOPALETTEATTACHED;
2136 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
2137 LPDIRECTDRAWSURFACE4 iface,
2138 LONG lX,
2139 LONG lY)
2141 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2142 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
2144 return DD_OK;
2147 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
2148 LPDIRECTDRAWSURFACE4 iface,
2149 LPRECT lpSrcRect,
2150 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
2151 LPRECT lpDestRect,
2152 DWORD dwFlags,
2153 LPDDOVERLAYFX lpDDOverlayFx )
2155 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2156 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
2157 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
2159 return DD_OK;
2162 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
2163 LPDIRECTDRAWSURFACE4 iface,
2164 DWORD dwFlags )
2166 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2167 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2169 return DD_OK;
2172 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2173 LPDIRECTDRAWSURFACE4 iface,
2174 DWORD dwFlags,
2175 LPDIRECTDRAWSURFACE4 lpDDSReference )
2177 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2178 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2180 return DD_OK;
2183 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2184 LPDIRECTDRAWSURFACE4 iface,
2185 LPVOID* lplpDD )
2187 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2188 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2190 /* Not sure about that... */
2191 *lplpDD = (void *) This->s.ddraw;
2193 return DD_OK;
2196 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2197 LPDIRECTDRAWSURFACE4 iface,
2198 DWORD dwFlags )
2200 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2201 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2203 return DD_OK;
2206 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2207 LPDIRECTDRAWSURFACE4 iface,
2208 DWORD dwFlags )
2210 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2211 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2213 return DD_OK;
2216 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2217 LPDIRECTDRAWSURFACE4 iface,
2218 LPDDSURFACEDESC lpDDSD,
2219 DWORD dwFlags )
2221 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2222 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2224 return DD_OK;
2227 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2228 REFGUID guidTag,
2229 LPVOID lpData,
2230 DWORD cbSize,
2231 DWORD dwFlags) {
2232 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2233 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2235 return DD_OK;
2238 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2239 REFGUID guidTag,
2240 LPVOID lpBuffer,
2241 LPDWORD lpcbBufferSize) {
2242 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2243 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2245 return DD_OK;
2248 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2249 REFGUID guidTag) {
2250 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2251 FIXME("(%p)->(%p)\n", This, guidTag);
2253 return DD_OK;
2256 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2257 LPDWORD lpValue) {
2258 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2259 FIXME("(%p)->(%p)\n", This, lpValue);
2261 return DD_OK;
2264 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2265 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2266 FIXME("(%p)\n", This);
2268 return DD_OK;
2271 #ifdef HAVE_LIBXXF86DGA
2272 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2274 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2275 IDirectDrawSurface4Impl_QueryInterface,
2276 IDirectDrawSurface4Impl_AddRef,
2277 DGA_IDirectDrawSurface4Impl_Release,
2278 IDirectDrawSurface4Impl_AddAttachedSurface,
2279 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2280 IDirectDrawSurface4Impl_Blt,
2281 IDirectDrawSurface4Impl_BltBatch,
2282 IDirectDrawSurface4Impl_BltFast,
2283 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2284 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2285 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2286 DGA_IDirectDrawSurface4Impl_Flip,
2287 IDirectDrawSurface4Impl_GetAttachedSurface,
2288 IDirectDrawSurface4Impl_GetBltStatus,
2289 IDirectDrawSurface4Impl_GetCaps,
2290 IDirectDrawSurface4Impl_GetClipper,
2291 IDirectDrawSurface4Impl_GetColorKey,
2292 IDirectDrawSurface4Impl_GetDC,
2293 IDirectDrawSurface4Impl_GetFlipStatus,
2294 IDirectDrawSurface4Impl_GetOverlayPosition,
2295 IDirectDrawSurface4Impl_GetPalette,
2296 IDirectDrawSurface4Impl_GetPixelFormat,
2297 IDirectDrawSurface4Impl_GetSurfaceDesc,
2298 IDirectDrawSurface4Impl_Initialize,
2299 IDirectDrawSurface4Impl_IsLost,
2300 IDirectDrawSurface4Impl_Lock,
2301 IDirectDrawSurface4Impl_ReleaseDC,
2302 IDirectDrawSurface4Impl_Restore,
2303 IDirectDrawSurface4Impl_SetClipper,
2304 IDirectDrawSurface4Impl_SetColorKey,
2305 IDirectDrawSurface4Impl_SetOverlayPosition,
2306 DGA_IDirectDrawSurface4Impl_SetPalette,
2307 DGA_IDirectDrawSurface4Impl_Unlock,
2308 IDirectDrawSurface4Impl_UpdateOverlay,
2309 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2310 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2311 IDirectDrawSurface4Impl_GetDDInterface,
2312 IDirectDrawSurface4Impl_PageLock,
2313 IDirectDrawSurface4Impl_PageUnlock,
2314 IDirectDrawSurface4Impl_SetSurfaceDesc,
2315 IDirectDrawSurface4Impl_SetPrivateData,
2316 IDirectDrawSurface4Impl_GetPrivateData,
2317 IDirectDrawSurface4Impl_FreePrivateData,
2318 IDirectDrawSurface4Impl_GetUniquenessValue,
2319 IDirectDrawSurface4Impl_ChangeUniquenessValue
2321 #endif /* defined(HAVE_LIBXXF86DGA) */
2323 #ifdef HAVE_LIBXXF86DGA2
2324 static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
2326 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2327 IDirectDrawSurface4Impl_QueryInterface,
2328 IDirectDrawSurface4Impl_AddRef,
2329 DGA_IDirectDrawSurface4Impl_Release,
2330 IDirectDrawSurface4Impl_AddAttachedSurface,
2331 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2332 IDirectDrawSurface4Impl_Blt,
2333 IDirectDrawSurface4Impl_BltBatch,
2334 IDirectDrawSurface4Impl_BltFast,
2335 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2336 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2337 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2338 DGA2_IDirectDrawSurface4Impl_Flip,
2339 IDirectDrawSurface4Impl_GetAttachedSurface,
2340 IDirectDrawSurface4Impl_GetBltStatus,
2341 IDirectDrawSurface4Impl_GetCaps,
2342 IDirectDrawSurface4Impl_GetClipper,
2343 IDirectDrawSurface4Impl_GetColorKey,
2344 IDirectDrawSurface4Impl_GetDC,
2345 IDirectDrawSurface4Impl_GetFlipStatus,
2346 IDirectDrawSurface4Impl_GetOverlayPosition,
2347 IDirectDrawSurface4Impl_GetPalette,
2348 IDirectDrawSurface4Impl_GetPixelFormat,
2349 IDirectDrawSurface4Impl_GetSurfaceDesc,
2350 IDirectDrawSurface4Impl_Initialize,
2351 IDirectDrawSurface4Impl_IsLost,
2352 IDirectDrawSurface4Impl_Lock,
2353 IDirectDrawSurface4Impl_ReleaseDC,
2354 IDirectDrawSurface4Impl_Restore,
2355 IDirectDrawSurface4Impl_SetClipper,
2356 IDirectDrawSurface4Impl_SetColorKey,
2357 IDirectDrawSurface4Impl_SetOverlayPosition,
2358 DGA_IDirectDrawSurface4Impl_SetPalette,
2359 DGA_IDirectDrawSurface4Impl_Unlock,
2360 IDirectDrawSurface4Impl_UpdateOverlay,
2361 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2362 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2363 IDirectDrawSurface4Impl_GetDDInterface,
2364 IDirectDrawSurface4Impl_PageLock,
2365 IDirectDrawSurface4Impl_PageUnlock,
2366 IDirectDrawSurface4Impl_SetSurfaceDesc,
2367 IDirectDrawSurface4Impl_SetPrivateData,
2368 IDirectDrawSurface4Impl_GetPrivateData,
2369 IDirectDrawSurface4Impl_FreePrivateData,
2370 IDirectDrawSurface4Impl_GetUniquenessValue,
2371 IDirectDrawSurface4Impl_ChangeUniquenessValue
2373 #endif /* defined(HAVE_LIBXXF86DGA2) */
2375 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2377 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2378 IDirectDrawSurface4Impl_QueryInterface,
2379 IDirectDrawSurface4Impl_AddRef,
2380 Xlib_IDirectDrawSurface4Impl_Release,
2381 IDirectDrawSurface4Impl_AddAttachedSurface,
2382 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2383 IDirectDrawSurface4Impl_Blt,
2384 IDirectDrawSurface4Impl_BltBatch,
2385 IDirectDrawSurface4Impl_BltFast,
2386 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2387 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2388 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2389 Xlib_IDirectDrawSurface4Impl_Flip,
2390 IDirectDrawSurface4Impl_GetAttachedSurface,
2391 IDirectDrawSurface4Impl_GetBltStatus,
2392 IDirectDrawSurface4Impl_GetCaps,
2393 IDirectDrawSurface4Impl_GetClipper,
2394 IDirectDrawSurface4Impl_GetColorKey,
2395 IDirectDrawSurface4Impl_GetDC,
2396 IDirectDrawSurface4Impl_GetFlipStatus,
2397 IDirectDrawSurface4Impl_GetOverlayPosition,
2398 IDirectDrawSurface4Impl_GetPalette,
2399 IDirectDrawSurface4Impl_GetPixelFormat,
2400 IDirectDrawSurface4Impl_GetSurfaceDesc,
2401 IDirectDrawSurface4Impl_Initialize,
2402 IDirectDrawSurface4Impl_IsLost,
2403 IDirectDrawSurface4Impl_Lock,
2404 IDirectDrawSurface4Impl_ReleaseDC,
2405 IDirectDrawSurface4Impl_Restore,
2406 IDirectDrawSurface4Impl_SetClipper,
2407 IDirectDrawSurface4Impl_SetColorKey,
2408 IDirectDrawSurface4Impl_SetOverlayPosition,
2409 Xlib_IDirectDrawSurface4Impl_SetPalette,
2410 Xlib_IDirectDrawSurface4Impl_Unlock,
2411 IDirectDrawSurface4Impl_UpdateOverlay,
2412 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2413 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2414 IDirectDrawSurface4Impl_GetDDInterface,
2415 IDirectDrawSurface4Impl_PageLock,
2416 IDirectDrawSurface4Impl_PageUnlock,
2417 IDirectDrawSurface4Impl_SetSurfaceDesc,
2418 IDirectDrawSurface4Impl_SetPrivateData,
2419 IDirectDrawSurface4Impl_GetPrivateData,
2420 IDirectDrawSurface4Impl_FreePrivateData,
2421 IDirectDrawSurface4Impl_GetUniquenessValue,
2422 IDirectDrawSurface4Impl_ChangeUniquenessValue
2425 /******************************************************************************
2426 * DirectDrawCreateClipper (DDRAW.7)
2428 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2429 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2430 LPUNKNOWN pUnkOuter)
2432 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2433 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2435 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2436 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2437 (*ilplpDDClipper)->ref = 1;
2439 (*ilplpDDClipper)->hWnd = 0;
2441 return DD_OK;
2444 /******************************************************************************
2445 * IDirectDrawClipper
2447 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2448 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
2450 ICOM_THIS(IDirectDrawClipperImpl,iface);
2452 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
2453 if( dwFlags ) {
2454 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
2455 return DDERR_INVALIDPARAMS;
2458 This->hWnd = hWnd;
2459 return DD_OK;
2462 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2463 ICOM_THIS(IDirectDrawClipperImpl,iface);
2464 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2466 This->ref--;
2467 if (This->ref)
2468 return This->ref;
2469 HeapFree(GetProcessHeap(),0,This);
2470 return S_OK;
2473 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2474 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2476 ICOM_THIS(IDirectDrawClipperImpl,iface);
2477 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2478 if (hmm) *hmm=0;
2479 return DD_OK;
2482 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2483 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2485 ICOM_THIS(IDirectDrawClipperImpl,iface);
2486 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2487 return DD_OK;
2490 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2491 LPDIRECTDRAWCLIPPER iface,
2492 REFIID riid,
2493 LPVOID* ppvObj )
2495 ICOM_THIS(IDirectDrawClipperImpl,iface);
2496 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2497 return OLE_E_ENUM_NOMORE;
2500 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2502 ICOM_THIS(IDirectDrawClipperImpl,iface);
2503 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2504 return ++(This->ref);
2507 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2508 LPDIRECTDRAWCLIPPER iface,
2509 HWND* hWndPtr )
2511 ICOM_THIS(IDirectDrawClipperImpl,iface);
2512 FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
2514 *hWndPtr = This->hWnd;
2516 return DD_OK;
2519 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2520 LPDIRECTDRAWCLIPPER iface,
2521 LPDIRECTDRAW lpDD,
2522 DWORD dwFlags )
2524 ICOM_THIS(IDirectDrawClipperImpl,iface);
2525 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2526 return DD_OK;
2529 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2530 LPDIRECTDRAWCLIPPER iface,
2531 BOOL* lpbChanged )
2533 ICOM_THIS(IDirectDrawClipperImpl,iface);
2534 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2535 return DD_OK;
2538 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2540 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2541 IDirectDrawClipperImpl_QueryInterface,
2542 IDirectDrawClipperImpl_AddRef,
2543 IDirectDrawClipperImpl_Release,
2544 IDirectDrawClipperImpl_GetClipList,
2545 IDirectDrawClipperImpl_GetHWnd,
2546 IDirectDrawClipperImpl_Initialize,
2547 IDirectDrawClipperImpl_IsClipListChanged,
2548 IDirectDrawClipperImpl_SetClipList,
2549 IDirectDrawClipperImpl_SetHwnd
2553 /******************************************************************************
2554 * IDirectDrawPalette
2556 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2557 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2559 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2560 int i;
2562 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2563 This,x,start,count,palent);
2565 /* No palette created and not in depth-convertion mode -> BUG ! */
2566 if ((This->cm == None) &&
2567 (This->ddraw->d.palette_convert == NULL))
2569 FIXME("app tried to read colormap for non-palettized mode\n");
2570 return DDERR_GENERIC;
2572 for (i=0;i<count;i++) {
2573 palent[i].peRed = This->palents[start+i].peRed;
2574 palent[i].peBlue = This->palents[start+i].peBlue;
2575 palent[i].peGreen = This->palents[start+i].peGreen;
2576 palent[i].peFlags = This->palents[start+i].peFlags;
2579 return DD_OK;
2582 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2583 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2585 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2586 XColor xc;
2587 int i;
2589 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2590 This,x,start,count,palent
2592 for (i=0;i<count;i++) {
2593 xc.red = palent[i].peRed<<8;
2594 xc.blue = palent[i].peBlue<<8;
2595 xc.green = palent[i].peGreen<<8;
2596 xc.flags = DoRed|DoBlue|DoGreen;
2597 xc.pixel = start+i;
2599 if (This->cm)
2600 TSXStoreColor(display,This->cm,&xc);
2602 This->palents[start+i].peRed = palent[i].peRed;
2603 This->palents[start+i].peBlue = palent[i].peBlue;
2604 This->palents[start+i].peGreen = palent[i].peGreen;
2605 This->palents[start+i].peFlags = palent[i].peFlags;
2608 /* Now, if we are in 'depth conversion mode', update the screen palette */
2609 /* FIXME: we need to update the image or we won't get palette fading. */
2610 if (This->ddraw->d.palette_convert != NULL)
2611 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2613 return DD_OK;
2616 #ifdef HAVE_LIBXXF86DGA
2617 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2618 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2620 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2621 XColor xc;
2622 Colormap cm;
2623 int i;
2625 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2626 This,x,start,count,palent
2628 if (!This->cm) /* should not happen */ {
2629 FIXME("app tried to set colormap in non-palettized mode\n");
2630 return DDERR_GENERIC;
2632 /* FIXME: free colorcells instead of freeing whole map */
2633 cm = This->cm;
2634 This->cm = TSXCopyColormapAndFree(display,This->cm);
2635 TSXFreeColormap(display,cm);
2637 for (i=0;i<count;i++) {
2638 xc.red = palent[i].peRed<<8;
2639 xc.blue = palent[i].peBlue<<8;
2640 xc.green = palent[i].peGreen<<8;
2641 xc.flags = DoRed|DoBlue|DoGreen;
2642 xc.pixel = i+start;
2644 TSXStoreColor(display,This->cm,&xc);
2646 This->palents[start+i].peRed = palent[i].peRed;
2647 This->palents[start+i].peBlue = palent[i].peBlue;
2648 This->palents[start+i].peGreen = palent[i].peGreen;
2649 This->palents[start+i].peFlags = palent[i].peFlags;
2651 #ifdef HAVE_LIBXXF86DGA2
2652 if (This->ddraw->e.dga.version == 2)
2653 TSXDGAInstallColormap(display,DefaultScreen(display),This->cm);
2654 else
2655 #endif /* defined(HAVE_LIBXXF86DGA2) */
2656 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2657 return DD_OK;
2659 #endif /* defined(HAVE_LIBXXF86DGA) */
2661 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2662 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2663 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2664 if (!--(This->ref)) {
2665 if (This->cm) {
2666 TSXFreeColormap(display,This->cm);
2667 This->cm = 0;
2669 HeapFree(GetProcessHeap(),0,This);
2670 return S_OK;
2672 return This->ref;
2675 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2676 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2678 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2679 return ++(This->ref);
2682 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2683 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2685 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2686 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2688 return DDERR_ALREADYINITIALIZED;
2691 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2692 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2694 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2695 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2696 return DD_OK;
2699 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2700 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2702 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2704 FIXME("(%p)->(%s,%p) stub.\n",This,debugstr_guid(refiid),obj);
2706 return S_OK;
2709 #ifdef HAVE_LIBXXF86DGA
2710 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2712 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2713 IDirectDrawPaletteImpl_QueryInterface,
2714 IDirectDrawPaletteImpl_AddRef,
2715 IDirectDrawPaletteImpl_Release,
2716 IDirectDrawPaletteImpl_GetCaps,
2717 IDirectDrawPaletteImpl_GetEntries,
2718 IDirectDrawPaletteImpl_Initialize,
2719 DGA_IDirectDrawPaletteImpl_SetEntries
2721 #endif /* defined(HAVE_LIBXXF86DGA) */
2723 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2725 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2726 IDirectDrawPaletteImpl_QueryInterface,
2727 IDirectDrawPaletteImpl_AddRef,
2728 IDirectDrawPaletteImpl_Release,
2729 IDirectDrawPaletteImpl_GetCaps,
2730 IDirectDrawPaletteImpl_GetEntries,
2731 IDirectDrawPaletteImpl_Initialize,
2732 Xlib_IDirectDrawPaletteImpl_SetEntries
2735 /*******************************************************************************
2736 * IDirect3D
2738 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2739 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2741 ICOM_THIS(IDirect3DImpl,iface);
2742 /* FIXME: Not sure if this is correct */
2744 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2745 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2746 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2747 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2748 *obj = This->ddraw;
2749 IDirect3D_AddRef(iface);
2751 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2753 return S_OK;
2755 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2756 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2757 *obj = This;
2758 IDirect3D_AddRef(iface);
2760 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2762 return S_OK;
2764 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2765 IDirect3D2Impl* d3d;
2767 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2768 d3d->ref = 1;
2769 d3d->ddraw = This->ddraw;
2770 IDirect3D_AddRef(iface);
2771 ICOM_VTBL(d3d) = &d3d2vt;
2772 *obj = d3d;
2774 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2776 return S_OK;
2778 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2779 return OLE_E_ENUM_NOMORE;
2782 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2783 ICOM_THIS(IDirect3DImpl,iface);
2784 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2786 return ++(This->ref);
2789 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2791 ICOM_THIS(IDirect3DImpl,iface);
2792 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2794 if (!--(This->ref)) {
2795 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2796 HeapFree(GetProcessHeap(),0,This);
2797 return S_OK;
2799 return This->ref;
2802 static HRESULT WINAPI IDirect3DImpl_Initialize(
2803 LPDIRECT3D iface, REFIID refiid )
2805 ICOM_THIS(IDirect3DImpl,iface);
2806 /* FIXME: Not sure if this is correct */
2808 FIXME("(%p)->(%s):stub.\n",This,debugstr_guid(refiid));
2810 return DDERR_ALREADYINITIALIZED;
2813 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2814 LPD3DENUMDEVICESCALLBACK cb,
2815 LPVOID context) {
2816 ICOM_THIS(IDirect3DImpl,iface);
2817 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2819 /* Call functions defined in d3ddevices.c */
2820 if (!d3d_OpenGL_dx3(cb, context))
2821 return DD_OK;
2823 return DD_OK;
2826 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2827 LPDIRECT3DLIGHT *lplight,
2828 IUnknown *lpunk)
2830 ICOM_THIS(IDirect3DImpl,iface);
2831 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2833 /* Call the creation function that is located in d3dlight.c */
2834 *lplight = d3dlight_create_dx3(This);
2836 return DD_OK;
2839 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2840 LPDIRECT3DMATERIAL *lpmaterial,
2841 IUnknown *lpunk)
2843 ICOM_THIS(IDirect3DImpl,iface);
2844 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2846 /* Call the creation function that is located in d3dviewport.c */
2847 *lpmaterial = d3dmaterial_create(This);
2849 return DD_OK;
2852 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2853 LPDIRECT3DVIEWPORT *lpviewport,
2854 IUnknown *lpunk)
2856 ICOM_THIS(IDirect3DImpl,iface);
2857 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2859 /* Call the creation function that is located in d3dviewport.c */
2860 *lpviewport = d3dviewport_create(This);
2862 return DD_OK;
2865 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2866 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2867 LPD3DFINDDEVICERESULT lpfinddevrst)
2869 ICOM_THIS(IDirect3DImpl,iface);
2870 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2872 return DD_OK;
2875 static ICOM_VTABLE(IDirect3D) d3dvt =
2877 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2878 IDirect3DImpl_QueryInterface,
2879 IDirect3DImpl_AddRef,
2880 IDirect3DImpl_Release,
2881 IDirect3DImpl_Initialize,
2882 IDirect3DImpl_EnumDevices,
2883 IDirect3DImpl_CreateLight,
2884 IDirect3DImpl_CreateMaterial,
2885 IDirect3DImpl_CreateViewport,
2886 IDirect3DImpl_FindDevice
2889 /*******************************************************************************
2890 * IDirect3D2
2892 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2893 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2894 ICOM_THIS(IDirect3D2Impl,iface);
2896 /* FIXME: Not sure if this is correct */
2898 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2899 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2900 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2901 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2902 *obj = This->ddraw;
2903 IDirect3D2_AddRef(iface);
2905 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2907 return S_OK;
2909 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2910 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2911 *obj = This;
2912 IDirect3D2_AddRef(iface);
2914 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2916 return S_OK;
2918 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2919 IDirect3DImpl* d3d;
2921 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2922 d3d->ref = 1;
2923 d3d->ddraw = This->ddraw;
2924 IDirect3D2_AddRef(iface);
2925 ICOM_VTBL(d3d) = &d3dvt;
2926 *obj = d3d;
2928 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2930 return S_OK;
2932 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2933 return OLE_E_ENUM_NOMORE;
2936 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2937 ICOM_THIS(IDirect3D2Impl,iface);
2938 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2940 return ++(This->ref);
2943 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2944 ICOM_THIS(IDirect3D2Impl,iface);
2945 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2947 if (!--(This->ref)) {
2948 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2949 HeapFree(GetProcessHeap(),0,This);
2950 return S_OK;
2952 return This->ref;
2955 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2956 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2958 ICOM_THIS(IDirect3D2Impl,iface);
2959 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2961 /* Call functions defined in d3ddevices.c */
2962 if (!d3d_OpenGL(cb, context))
2963 return DD_OK;
2965 return DD_OK;
2968 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2969 LPDIRECT3DLIGHT *lplight,
2970 IUnknown *lpunk)
2972 ICOM_THIS(IDirect3D2Impl,iface);
2973 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2975 /* Call the creation function that is located in d3dlight.c */
2976 *lplight = d3dlight_create(This);
2978 return DD_OK;
2981 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2982 LPDIRECT3DMATERIAL2 *lpmaterial,
2983 IUnknown *lpunk)
2985 ICOM_THIS(IDirect3D2Impl,iface);
2986 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2988 /* Call the creation function that is located in d3dviewport.c */
2989 *lpmaterial = d3dmaterial2_create(This);
2991 return DD_OK;
2994 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2995 LPDIRECT3DVIEWPORT2 *lpviewport,
2996 IUnknown *lpunk)
2998 ICOM_THIS(IDirect3D2Impl,iface);
2999 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
3001 /* Call the creation function that is located in d3dviewport.c */
3002 *lpviewport = d3dviewport2_create(This);
3004 return DD_OK;
3007 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
3008 LPD3DFINDDEVICESEARCH lpfinddevsrc,
3009 LPD3DFINDDEVICERESULT lpfinddevrst)
3011 ICOM_THIS(IDirect3D2Impl,iface);
3012 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
3014 return DD_OK;
3017 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
3018 REFCLSID rguid,
3019 LPDIRECTDRAWSURFACE surface,
3020 LPDIRECT3DDEVICE2 *device)
3022 ICOM_THIS(IDirect3D2Impl,iface);
3024 FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
3026 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
3027 IDirect3D2_AddRef(iface);
3028 return DD_OK;
3031 return DDERR_INVALIDPARAMS;
3034 static ICOM_VTABLE(IDirect3D2) d3d2vt =
3036 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3037 IDirect3D2Impl_QueryInterface,
3038 IDirect3D2Impl_AddRef,
3039 IDirect3D2Impl_Release,
3040 IDirect3D2Impl_EnumDevices,
3041 IDirect3D2Impl_CreateLight,
3042 IDirect3D2Impl_CreateMaterial,
3043 IDirect3D2Impl_CreateViewport,
3044 IDirect3D2Impl_FindDevice,
3045 IDirect3D2Impl_CreateDevice
3048 /*******************************************************************************
3049 * IDirectDraw
3052 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
3053 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
3055 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
3056 IDirectDrawSurfaceImpl* lpdsf)
3058 int bpp;
3060 /* The surface was already allocated when entering in this function */
3061 TRACE("using system memory for a surface (%p) \n", lpdsf);
3063 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
3064 /* This is a Z Buffer */
3065 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
3066 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
3067 } else {
3068 /* This is a standard image */
3069 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
3070 /* No pixel format => use DirectDraw's format */
3071 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3072 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
3074 bpp = GET_BPP(lpdsf->s.surface_desc);
3077 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
3078 /* The surface was preallocated : seems that we have nothing to do :-) */
3079 ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
3082 assert(bpp);
3083 FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf->s.surface_desc.dwWidth,lpdsf->s.surface_desc.dwHeight,bpp);
3085 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
3086 lpdsf->s.surface_desc.u1.lpSurface =
3087 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
3088 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
3090 return DD_OK;
3093 #ifdef HAVE_LIBXXF86DGA
3094 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
3095 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3097 ICOM_THIS(IDirectDraw2Impl,iface);
3098 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3099 int i, fbheight = This->e.dga.fb_height;
3101 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
3102 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3104 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3105 GetProcessHeap(),
3106 HEAP_ZERO_MEMORY,
3107 sizeof(IDirectDrawSurfaceImpl)
3109 IDirectDraw2_AddRef(iface);
3111 (*ilpdsf)->ref = 1;
3112 #ifdef HAVE_LIBXXF86DGA2
3113 if (This->e.dga.version == 2)
3114 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
3115 else
3116 #endif /* defined(HAVE_LIBXXF86DGA2) */
3117 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
3118 (*ilpdsf)->s.ddraw = This;
3119 (*ilpdsf)->s.palette = NULL;
3120 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
3121 (*ilpdsf)->s.lpClipper = NULL;
3123 /* Copy the surface description */
3124 (*ilpdsf)->s.surface_desc = *lpddsd;
3126 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3127 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3128 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3129 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3131 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3133 /* Check if this a 'primary surface' or not */
3134 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3135 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3136 /* This is THE primary surface => there is DGA-specific code */
3138 /* First, store the surface description */
3139 (*ilpdsf)->s.surface_desc = *lpddsd;
3141 /* Find a viewport */
3142 for (i=0;i<32;i++)
3143 if (!(This->e.dga.vpmask & (1<<i)))
3144 break;
3145 TRACE("using viewport %d for a primary surface\n",i);
3146 /* if i == 32 or maximum ... return error */
3147 This->e.dga.vpmask|=(1<<i);
3148 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
3149 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
3151 (*ilpdsf)->s.surface_desc.u1.lpSurface =
3152 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3154 (*ilpdsf)->t.dga.fb_height = i*fbheight;
3156 /* Add flags if there were not present */
3157 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3158 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3159 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3160 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
3161 /* We put our surface always in video memory */
3162 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3163 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3164 (*ilpdsf)->s.chain = NULL;
3166 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3167 IDirectDrawSurface4Impl* back;
3168 int bbc;
3170 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
3171 int i;
3173 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3174 GetProcessHeap(),
3175 HEAP_ZERO_MEMORY,
3176 sizeof(IDirectDrawSurface4Impl)
3178 IDirectDraw2_AddRef(iface);
3179 back->ref = 1;
3180 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
3181 for (i=0;i<32;i++)
3182 if (!(This->e.dga.vpmask & (1<<i)))
3183 break;
3184 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
3185 /* if i == 32 or maximum ... return error */
3186 This->e.dga.vpmask|=(1<<i);
3187 back->t.dga.fb_height = i*fbheight;
3188 /* Copy the surface description from the front buffer */
3189 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3190 /* Change the parameters that are not the same */
3191 back->s.surface_desc.u1.lpSurface =
3192 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3194 back->s.ddraw = This;
3195 /* Add relevant info to front and back buffers */
3196 /* FIXME: backbuffer/frontbuffer handling broken here, but
3197 * will be fixed up in _Flip().
3199 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3200 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
3201 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3202 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3203 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3206 } else {
3207 /* There is no DGA-specific code here...
3208 Go to the common surface creation function */
3209 return common_off_screen_CreateSurface(This, *ilpdsf);
3211 return DD_OK;
3213 #endif /* defined(HAVE_LIBXXF86DGA) */
3215 #ifdef HAVE_LIBXXSHM
3216 /* Error handlers for Image creation */
3217 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
3218 XShmErrorFlag = 1;
3219 return 0;
3222 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3223 XImage *img;
3224 int (*WineXHandler)(Display *, XErrorEvent *);
3226 img = TSXShmCreateImage(display,
3227 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3228 This->d.pixmap_depth,
3229 ZPixmap,
3230 NULL,
3231 &(lpdsf->t.xlib.shminfo),
3232 lpdsf->s.surface_desc.dwWidth,
3233 lpdsf->s.surface_desc.dwHeight
3236 if (img == NULL) {
3237 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3238 This->e.xlib.xshm_active = 0;
3239 return NULL;
3242 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3243 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3244 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3245 This->e.xlib.xshm_active = 0;
3246 TSXDestroyImage(img);
3247 return NULL;
3250 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3252 if (img->data == (char *) -1) {
3253 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3254 This->e.xlib.xshm_active = 0;
3255 TSXDestroyImage(img);
3256 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3257 return NULL;
3259 lpdsf->t.xlib.shminfo.readOnly = False;
3261 /* This is where things start to get trickier....
3262 * First, we flush the current X connections to be sure to catch all
3263 * non-XShm related errors
3265 TSXSync(display, False);
3266 /* Then we enter in the non-thread safe part of the tests */
3267 EnterCriticalSection( &X11DRV_CritSection );
3269 /* Reset the error flag, sets our new error handler and try to attach
3270 * the surface
3272 XShmErrorFlag = 0;
3273 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3274 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3275 XSync(display, False);
3277 /* Check the error flag */
3278 if (XShmErrorFlag) {
3279 /* An error occured */
3280 XFlush(display);
3281 XShmErrorFlag = 0;
3282 XDestroyImage(img);
3283 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3284 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3285 XSetErrorHandler(WineXHandler);
3287 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3288 This->e.xlib.xshm_active = 0;
3290 /* Leave the critical section */
3291 LeaveCriticalSection( &X11DRV_CritSection );
3292 return NULL;
3294 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3295 * this works, but it may be a bit overkill....
3297 XSetErrorHandler(WineXHandler);
3298 LeaveCriticalSection( &X11DRV_CritSection );
3300 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3302 if (This->d.pixel_convert != NULL) {
3303 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3304 GetProcessHeap(),
3305 HEAP_ZERO_MEMORY,
3306 lpdsf->s.surface_desc.dwWidth *
3307 lpdsf->s.surface_desc.dwHeight *
3308 PFGET_BPP(This->d.directdraw_pixelformat)
3310 } else {
3311 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3313 return img;
3315 #endif /* HAVE_LIBXXSHM */
3317 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3318 XImage *img = NULL;
3319 void *img_data;
3321 #ifdef HAVE_LIBXXSHM
3322 if (This->e.xlib.xshm_active)
3323 img = create_xshmimage(This, lpdsf);
3325 if (img == NULL) {
3326 #endif
3327 /* Allocate surface memory */
3328 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3329 GetProcessHeap(),HEAP_ZERO_MEMORY,
3330 lpdsf->s.surface_desc.dwWidth *
3331 lpdsf->s.surface_desc.dwHeight *
3332 PFGET_BPP(This->d.directdraw_pixelformat)
3335 if (This->d.pixel_convert != NULL) {
3336 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3337 lpdsf->s.surface_desc.dwWidth *
3338 lpdsf->s.surface_desc.dwHeight *
3339 PFGET_BPP(This->d.screen_pixelformat)
3341 } else {
3342 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3345 /* In this case, create an XImage */
3346 img = TSXCreateImage(display,
3347 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3348 This->d.pixmap_depth,
3349 ZPixmap,
3351 img_data,
3352 lpdsf->s.surface_desc.dwWidth,
3353 lpdsf->s.surface_desc.dwHeight,
3355 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3357 #ifdef HAVE_LIBXXSHM
3359 #endif
3360 if (This->d.pixel_convert != NULL)
3361 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3362 else
3363 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3364 return img;
3367 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3368 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3370 ICOM_THIS(IDirectDraw2Impl,iface);
3371 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3373 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3375 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3377 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3378 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3381 IDirectDraw2_AddRef(iface);
3383 (*ilpdsf)->s.ddraw = This;
3384 (*ilpdsf)->ref = 1;
3385 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3386 (*ilpdsf)->s.palette = NULL;
3387 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3388 (*ilpdsf)->s.lpClipper = NULL;
3390 /* Copy the surface description */
3391 (*ilpdsf)->s.surface_desc = *lpddsd;
3393 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3394 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3395 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3396 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3397 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3399 /* Check if this a 'primary surface' or not */
3400 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3401 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3402 XImage *img;
3404 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3405 /* Create the XImage */
3406 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3407 if (img == NULL)
3408 return DDERR_OUTOFMEMORY;
3409 (*ilpdsf)->t.xlib.image = img;
3411 /* Add flags if there were not present */
3412 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3413 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3414 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3415 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3416 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3418 /* Check for backbuffers */
3419 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3420 IDirectDrawSurface4Impl* back;
3421 XImage *img;
3422 int i;
3424 for (i=lpddsd->dwBackBufferCount;i--;) {
3425 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3426 GetProcessHeap(),HEAP_ZERO_MEMORY,
3427 sizeof(IDirectDrawSurface4Impl)
3430 TRACE("allocated back-buffer (%p)\n", back);
3432 IDirectDraw2_AddRef(iface);
3433 back->s.ddraw = This;
3435 back->ref = 1;
3436 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3437 /* Copy the surface description from the front buffer */
3438 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3440 /* Create the XImage */
3441 img = create_ximage(This, back);
3442 if (img == NULL)
3443 return DDERR_OUTOFMEMORY;
3444 back->t.xlib.image = img;
3446 /* Add relevant info to front and back buffers */
3447 /* FIXME: backbuffer/frontbuffer handling broken here, but
3448 * will be fixed up in _Flip().
3450 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3451 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3452 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3453 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3454 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3457 } else {
3458 /* There is no Xlib-specific code here...
3459 Go to the common surface creation function */
3460 return common_off_screen_CreateSurface(This, *ilpdsf);
3462 return DD_OK;
3465 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3466 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3468 ICOM_THIS(IDirectDraw2Impl,iface);
3469 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3470 *dst = src; /* FIXME */
3471 return DD_OK;
3475 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3476 * even when the approbiate bitmasks are not specified.
3478 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3479 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3481 ICOM_THIS(IDirectDraw2Impl,iface);
3482 int i;
3483 const struct {
3484 int mask;
3485 char *name;
3486 } flags[] = {
3487 #define FE(x) { x, #x},
3488 FE(DDSCL_FULLSCREEN)
3489 FE(DDSCL_ALLOWREBOOT)
3490 FE(DDSCL_NOWINDOWCHANGES)
3491 FE(DDSCL_NORMAL)
3492 FE(DDSCL_ALLOWMODEX)
3493 FE(DDSCL_EXCLUSIVE)
3494 FE(DDSCL_SETFOCUSWINDOW)
3495 FE(DDSCL_SETDEVICEWINDOW)
3496 FE(DDSCL_CREATEDEVICEWINDOW)
3497 #undef FE
3500 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3501 if (TRACE_ON(ddraw)) {
3502 DPRINTF(" - ");
3503 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
3504 if (flags[i].mask & cooplevel) {
3505 DPRINTF("%s ",flags[i].name);
3508 DPRINTF("\n");
3510 This->d.mainWindow = hwnd;
3512 /* This will be overwritten in the case of Full Screen mode.
3513 Windowed games could work with that :-) */
3514 if (hwnd)
3516 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3517 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3518 WIN_ReleaseWndPtr(tmpWnd);
3520 if( !This->d.drawable ) {
3521 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3522 WIN_ReleaseDesktop();
3524 TRACE("Setting drawable to %ld\n", This->d.drawable);
3527 return DD_OK;
3530 #ifdef HAVE_LIBXXF86DGA2
3531 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel(
3532 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3534 ICOM_THIS(IDirectDraw2Impl,iface);
3535 HRESULT ret;
3536 int evbase, erbase;
3538 ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel);
3540 if (This->e.dga.version != 2) {
3541 return ret;
3542 } else {
3543 if (ret != DD_OK)
3544 return ret;
3546 TSXDGAQueryExtension(display, &evbase, &erbase);
3548 /* Now, start handling of DGA events giving the handle to the DDraw window
3549 as the window for which the event will be reported */
3550 TSXDGASelectInput(display, DefaultScreen(display),
3551 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3552 X11DRV_EVENT_SetDGAStatus(hwnd, evbase);
3554 return DD_OK;
3557 #endif
3559 /* Small helper to either use the cooperative window or create a new
3560 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3562 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3563 RECT rect;
3565 /* Do destroy only our window */
3566 if (This->d.window && GetPropA(This->d.window,ddProp)) {
3567 DestroyWindow(This->d.window);
3568 This->d.window = 0;
3570 /* Sanity check cooperative window before assigning it to drawing. */
3571 if ( IsWindow(This->d.mainWindow) &&
3572 IsWindowVisible(This->d.mainWindow)
3574 /* if it does not fit, resize the cooperative window.
3575 * and hope the app likes it
3577 GetWindowRect(This->d.mainWindow,&rect);
3578 if ((((rect.right-rect.left) >= This->d.width) &&
3579 ((rect.bottom-rect.top) >= This->d.height))
3581 This->d.window = This->d.mainWindow;
3582 /* SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOOWNERZORDER); */
3583 This->d.paintable = 1;
3586 /* ... failed, create new one. */
3587 if (!This->d.window) {
3588 This->d.window = CreateWindowExA(
3590 "WINE_DirectDraw",
3591 "WINE_DirectDraw",
3592 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3593 0,0,
3594 This->d.width,
3595 This->d.height,
3599 NULL
3601 /*Store THIS with the window. We'll use it in the window procedure*/
3602 SetPropA(This->d.window,ddProp,(LONG)This);
3603 ShowWindow(This->d.window,TRUE);
3604 UpdateWindow(This->d.window);
3606 SetFocus(This->d.window);
3609 static int _common_depth_to_pixelformat(DWORD depth,
3610 DDPIXELFORMAT *pixelformat,
3611 DDPIXELFORMAT *screen_pixelformat,
3612 int *pix_depth) {
3613 XVisualInfo *vi;
3614 XPixmapFormatValues *pf;
3615 XVisualInfo vt;
3616 int nvisuals, npixmap, i;
3617 int match = 0;
3618 int index = -2;
3620 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3621 pf = XListPixmapFormats(display, &npixmap);
3623 for (i = 0; i < npixmap; i++) {
3624 if (pf[i].depth == depth) {
3625 int j;
3627 for (j = 0; j < nvisuals; j++) {
3628 if (vi[j].depth == pf[i].depth) {
3629 pixelformat->dwSize = sizeof(*pixelformat);
3630 if (depth == 8) {
3631 pixelformat->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
3632 pixelformat->u1.dwRBitMask = 0;
3633 pixelformat->u2.dwGBitMask = 0;
3634 pixelformat->u3.dwBBitMask = 0;
3635 } else {
3636 pixelformat->dwFlags = DDPF_RGB;
3637 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3638 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3639 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3641 pixelformat->dwFourCC = 0;
3642 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3643 pixelformat->u4.dwRGBAlphaBitMask= 0;
3645 *screen_pixelformat = *pixelformat;
3647 if (pix_depth != NULL)
3648 *pix_depth = vi[j].depth;
3650 match = 1;
3651 index = -1;
3653 goto clean_up_and_exit;
3657 ERR("No visual corresponding to pixmap format !\n");
3661 if (match == 0) {
3662 /* We try now to find an emulated mode */
3663 int c;
3665 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3666 if (ModeEmulations[c].dest.depth == depth) {
3667 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3668 for (i = 0; i < npixmap; i++) {
3669 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3670 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3671 int j;
3673 for (j = 0; j < nvisuals; j++) {
3674 if (vi[j].depth == pf[i].depth) {
3675 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3676 screen_pixelformat->dwFlags = DDPF_RGB;
3677 screen_pixelformat->dwFourCC = 0;
3678 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3679 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3680 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3681 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3682 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3684 pixelformat->dwSize = sizeof(*pixelformat);
3685 pixelformat->dwFourCC = 0;
3686 if (depth == 8) {
3687 pixelformat->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
3688 pixelformat->u.dwRGBBitCount = 8;
3689 pixelformat->u1.dwRBitMask = 0;
3690 pixelformat->u2.dwGBitMask = 0;
3691 pixelformat->u3.dwBBitMask = 0;
3692 } else {
3693 pixelformat->dwFlags = DDPF_RGB;
3694 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3695 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3696 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3697 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3699 pixelformat->u4.dwRGBAlphaBitMask= 0;
3701 if (pix_depth != NULL)
3702 *pix_depth = vi[j].depth;
3704 match = 2;
3705 index = c;
3707 goto clean_up_and_exit;
3710 ERR("No visual corresponding to pixmap format !\n");
3718 clean_up_and_exit:
3719 TSXFree(vi);
3720 TSXFree(pf);
3722 return index;
3725 #ifdef HAVE_LIBXXF86DGA2
3726 static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl *This, int mode) {
3727 DDPIXELFORMAT *pf = &(This->d.directdraw_pixelformat);
3729 /* Now, get the device / mode description */
3730 This->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode);
3732 This->e.dga.fb_width = This->e.dga.dev->mode.imageWidth;
3733 TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
3734 This->e.dga.fb_height = This->e.dga.dev->mode.viewportHeight;
3735 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
3736 This->e.dga.dev->data,
3737 This->e.dga.dev->mode.imageWidth,
3738 (This->e.dga.dev->mode.imageWidth *
3739 This->e.dga.dev->mode.imageHeight *
3740 (This->e.dga.dev->mode.bitsPerPixel / 8))
3742 TRACE("viewport height: %d\n", This->e.dga.dev->mode.viewportHeight);
3743 /* Get the screen dimensions as seen by Wine.
3744 In that case, it may be better to ignore the -desktop mode and return the
3745 real screen size => print a warning */
3746 This->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3747 This->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3748 This->e.dga.fb_addr = This->e.dga.dev->data;
3749 This->e.dga.fb_memsize = (This->e.dga.dev->mode.imageWidth *
3750 This->e.dga.dev->mode.imageHeight *
3751 (This->e.dga.dev->mode.bitsPerPixel / 8));
3752 This->e.dga.vpmask = 0;
3754 /* Fill the screen pixelformat */
3755 pf->dwSize = sizeof(DDPIXELFORMAT);
3756 pf->dwFourCC = 0;
3757 pf->u.dwRGBBitCount = This->e.dga.dev->mode.bitsPerPixel;
3758 if (This->e.dga.dev->mode.depth == 8) {
3759 pf->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
3760 pf->u1.dwRBitMask = 0;
3761 pf->u2.dwGBitMask = 0;
3762 pf->u3.dwBBitMask = 0;
3763 } else {
3764 pf->dwFlags = DDPF_RGB;
3765 pf->u1.dwRBitMask = This->e.dga.dev->mode.redMask;
3766 pf->u2.dwGBitMask = This->e.dga.dev->mode.greenMask;
3767 pf->u3.dwBBitMask = This->e.dga.dev->mode.blueMask;
3769 pf->u4.dwRGBAlphaBitMask= 0;
3771 This->d.screen_pixelformat = *pf;
3773 #endif /* defined(HAVE_LIBXXF86DGA2) */
3775 #ifdef HAVE_LIBXXF86DGA
3776 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3777 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3779 ICOM_THIS(IDirectDrawImpl,iface);
3780 int i,mode_count;
3782 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3784 #ifdef HAVE_LIBXXF86DGA2
3785 if (This->e.dga.version == 2) {
3786 XDGAMode *modes = This->e.dga.modes;
3787 int mode_to_use = -1;
3789 /* Search in the list a display mode that corresponds to what is requested */
3790 for (i = 0; i < This->e.dga.num_modes; i++) {
3791 if ((height == modes[i].viewportHeight) &&
3792 (width == modes[i].viewportWidth) &&
3793 (depth == modes[i].depth)) {
3794 mode_to_use = modes[i].num;
3798 if (mode_to_use < 0) {
3799 ERR("Could not find matching mode !!!\n");
3800 return DDERR_UNSUPPORTEDMODE;
3801 } else {
3802 TRACE("Using mode number %d\n", mode_to_use);
3804 TSXDGACloseFramebuffer(display, DefaultScreen(display));
3806 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
3807 ERR("Error opening the frame buffer !!!\n");
3809 return DDERR_GENERIC;
3812 /* Initialize the frame buffer */
3813 _DGA_Initialize_FrameBuffer(This, mode_to_use);
3815 /* Re-get (if necessary) the DGA events */
3816 TSXDGASelectInput(display, DefaultScreen(display),
3817 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3820 return DD_OK;
3822 #endif /* defined(HAVE_LIBXXF86DGA2) */
3824 /* We hope getting the asked for depth */
3825 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3826 /* I.e. no visual found or emulated */
3827 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3828 return DDERR_UNSUPPORTEDMODE;
3831 if (This->d.width < width) {
3832 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3833 return DDERR_UNSUPPORTEDMODE;
3835 This->d.width = width;
3836 This->d.height = height;
3838 /* adjust fb_height, so we don't overlap */
3839 if (This->e.dga.fb_height < height)
3840 This->e.dga.fb_height = height;
3841 _common_IDirectDrawImpl_SetDisplayMode(This);
3843 #ifdef HAVE_LIBXXF86VM
3844 #ifdef HAVE_LIBXXF86DGA2
3845 if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3846 #endif /* defined(HAVE_LIBXXF86DGA2) */
3848 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3849 XF86VidModeModeLine mod_tmp;
3850 /* int dotclock_tmp; */
3852 /* save original video mode and set fullscreen if available*/
3853 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3854 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3855 orig_mode->hdisplay = mod_tmp.hdisplay;
3856 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3857 orig_mode->hsyncend = mod_tmp.hsyncend;
3858 orig_mode->htotal = mod_tmp.htotal;
3859 orig_mode->vdisplay = mod_tmp.vdisplay;
3860 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3861 orig_mode->vsyncend = mod_tmp.vsyncend;
3862 orig_mode->vtotal = mod_tmp.vtotal;
3863 orig_mode->flags = mod_tmp.flags;
3864 orig_mode->private = mod_tmp.private;
3866 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3867 for (i=0;i<mode_count;i++)
3869 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3871 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3872 *vidmode = *(all_modes[i]);
3873 break;
3874 } else
3875 TSXFree(all_modes[i]->private);
3877 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3878 TSXFree(all_modes);
3880 if (!vidmode)
3881 WARN("Fullscreen mode not available!\n");
3883 if (vidmode)
3885 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3886 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3887 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3888 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3889 #endif
3892 #endif
3894 /* FIXME: this function OVERWRITES several signal handlers.
3895 * can we save them? and restore them later? In a way that
3896 * it works for the library too?
3898 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3899 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3901 #ifdef RESTORE_SIGNALS
3902 SIGNAL_Init();
3903 #endif
3904 return DD_OK;
3906 #endif /* defined(HAVE_LIBXXF86DGA) */
3908 /* *************************************
3909 16 / 15 bpp to palettized 8 bpp
3910 ************************************* */
3911 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3912 unsigned char *c_src = (unsigned char *) src;
3913 unsigned short *c_dst = (unsigned short *) dst;
3914 int y;
3916 if (palette != NULL) {
3917 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3919 for (y = height; y--; ) {
3920 #if defined(__i386__) && defined(__GNUC__)
3921 /* gcc generates slightly inefficient code for the the copy / lookup,
3922 * it generates one excess memory access (to pal) per pixel. Since
3923 * we know that pal is not modified by the memory write we can
3924 * put it into a register and reduce the number of memory accesses
3925 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3926 * (This is not guaranteed to be the fastest method.)
3928 __asm__ __volatile__(
3929 "xor %%eax,%%eax\n"
3930 "1:\n"
3931 " lodsb\n"
3932 " movw (%%edx,%%eax,2),%%ax\n"
3933 " stosw\n"
3934 " xor %%eax,%%eax\n"
3935 " loop 1b\n"
3936 : "=S" (c_src), "=D" (c_dst)
3937 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3938 : "eax", "cc", "memory"
3940 c_src+=(pitch-width);
3941 #else
3942 unsigned char * srclineend = c_src+width;
3943 while (c_src < srclineend)
3944 *c_dst++ = pal[*c_src++];
3945 c_src+=(pitch-width);
3946 #endif
3948 } else {
3949 WARN("No palette set...\n");
3950 memset(dst, 0, width * height * 2);
3953 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3954 int i;
3955 unsigned short *pal = (unsigned short *) screen_palette;
3957 for (i = 0; i < count; i++)
3958 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3959 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3960 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3962 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3963 int i;
3964 unsigned short *pal = (unsigned short *) screen_palette;
3966 for (i = 0; i < count; i++)
3967 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3968 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3969 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3972 /* *************************************
3973 24 to palettized 8 bpp
3974 ************************************* */
3975 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3976 unsigned char *c_src = (unsigned char *) src;
3977 unsigned char *c_dst = (unsigned char *) dst;
3978 int y;
3980 if (palette != NULL) {
3981 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3983 for (y = height; y--; ) {
3984 unsigned char * srclineend = c_src+width;
3985 while (c_src < srclineend ) {
3986 register long pixel = pal[*c_src++];
3987 *c_dst++ = pixel;
3988 *c_dst++ = pixel>>8;
3989 *c_dst++ = pixel>>16;
3991 c_src+=(pitch-width);
3993 } else {
3994 WARN("No palette set...\n");
3995 memset(dst, 0, width * height * 4);
3998 /* *************************************
3999 32 bpp to palettized 8 bpp
4000 ************************************* */
4001 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4002 unsigned char *c_src = (unsigned char *) src;
4003 unsigned int *c_dst = (unsigned int *) dst;
4004 int y;
4006 if (palette != NULL) {
4007 const unsigned int *pal = (unsigned int *) palette->screen_palents;
4009 for (y = height; y--; ) {
4010 #if defined(__i386__) && defined(__GNUC__)
4011 /* See comment in pixel_convert_16_to_8 */
4012 __asm__ __volatile__(
4013 "xor %%eax,%%eax\n"
4014 "1:\n"
4015 " lodsb\n"
4016 " movl (%%edx,%%eax,4),%%eax\n"
4017 " stosl\n"
4018 " xor %%eax,%%eax\n"
4019 " loop 1b\n"
4020 : "=S" (c_src), "=D" (c_dst)
4021 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
4022 : "eax", "cc", "memory"
4024 c_src+=(pitch-width);
4025 #else
4026 unsigned char * srclineend = c_src+width;
4027 while (c_src < srclineend )
4028 *c_dst++ = pal[*c_src++];
4029 c_src+=(pitch-width);
4030 #endif
4032 } else {
4033 WARN("No palette set...\n");
4034 memset(dst, 0, width * height * 4);
4038 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
4039 int i;
4040 unsigned int *pal = (unsigned int *) screen_palette;
4042 for (i = 0; i < count; i++)
4043 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
4044 (((unsigned int) palent[i].peGreen) << 8) |
4045 ((unsigned int) palent[i].peBlue));
4048 /* *************************************
4049 32 bpp to 16 bpp
4050 ************************************* */
4051 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4052 unsigned short *c_src = (unsigned short *) src;
4053 unsigned int *c_dst = (unsigned int *) dst;
4054 int y;
4056 for (y = height; y--; ) {
4057 unsigned short * srclineend = c_src+width;
4058 while (c_src < srclineend ) {
4059 *c_dst++ = (((*c_src & 0xF800) << 8) |
4060 ((*c_src & 0x07E0) << 5) |
4061 ((*c_src & 0x001F) << 3));
4062 c_src++;
4064 c_src+=((pitch/2)-width);
4069 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
4070 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
4072 ICOM_THIS(IDirectDrawImpl,iface);
4073 char buf[200];
4074 WND *tmpWnd;
4075 int c;
4077 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
4078 This, width, height, depth);
4080 switch ((c = _common_depth_to_pixelformat(depth,
4081 &(This->d.directdraw_pixelformat),
4082 &(This->d.screen_pixelformat),
4083 &(This->d.pixmap_depth)))) {
4084 case -2:
4085 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
4086 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
4087 return DDERR_UNSUPPORTEDMODE;
4089 case -1:
4090 /* No convertion */
4091 This->d.pixel_convert = NULL;
4092 This->d.palette_convert = NULL;
4093 break;
4095 default:
4096 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
4098 /* Set the depth convertion routines */
4099 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
4100 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
4103 This->d.width = width;
4104 This->d.height = height;
4106 _common_IDirectDrawImpl_SetDisplayMode(This);
4108 tmpWnd = WIN_FindWndPtr(This->d.window);
4109 This->d.paintable = 1;
4110 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
4111 WIN_ReleaseWndPtr(tmpWnd);
4113 /* We don't have a context for this window. Host off the desktop */
4114 if( !This->d.drawable )
4116 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
4117 WIN_ReleaseDesktop();
4119 TRACE("Setting drawable to %ld\n", This->d.drawable);
4121 if (Options.DXGrab) {
4122 /* Confine cursor movement (risky, but the user asked for it) */
4123 TSXGrabPointer(display, This->d.drawable, True, 0, GrabModeAsync, GrabModeAsync, This->d.drawable, None, CurrentTime);
4126 return DD_OK;
4129 #ifdef HAVE_LIBXXF86DGA
4130 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
4131 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4133 ICOM_THIS(IDirectDraw2Impl,iface);
4134 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4135 if (!caps1 && !caps2)
4136 return DDERR_INVALIDPARAMS;
4137 if (caps1) {
4138 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
4139 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4140 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4142 if (caps2) {
4143 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
4144 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4145 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4147 return DD_OK;
4149 #endif /* defined(HAVE_LIBXXF86DGA) */
4151 static void fill_caps(LPDDCAPS caps) {
4152 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4153 Need to be fixed, though.. */
4154 if (caps == NULL)
4155 return;
4157 caps->dwSize = sizeof(*caps);
4158 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
4159 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
4160 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
4161 caps->dwFXCaps = 0;
4162 caps->dwFXAlphaCaps = 0;
4163 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
4164 caps->dwSVCaps = 0;
4165 caps->dwZBufferBitDepths = DDBD_16;
4166 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4167 to put textures in video memory.
4168 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4169 for example) ? */
4170 caps->dwVidMemTotal = 8192 * 1024;
4171 caps->dwVidMemFree = 8192 * 1024;
4172 /* These are all the supported capabilities of the surfaces */
4173 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
4174 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
4175 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
4176 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
4177 #ifdef HAVE_MESAGL
4178 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
4179 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
4180 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
4181 #endif
4184 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
4185 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4187 ICOM_THIS(IDirectDraw2Impl,iface);
4188 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4190 /* Put the same caps for the two capabilities */
4191 fill_caps(caps1);
4192 fill_caps(caps2);
4194 return DD_OK;
4197 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
4198 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
4200 ICOM_THIS(IDirectDraw2Impl,iface);
4201 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
4202 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4203 This,x,ilpddclip,lpunk
4205 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
4206 (*ilpddclip)->ref = 1;
4207 ICOM_VTBL(*ilpddclip) = &ddclipvt;
4208 return DD_OK;
4211 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
4212 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
4214 int size = 0;
4216 if (TRACE_ON(ddraw))
4217 _dump_paletteformat(dwFlags);
4219 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
4220 if (*lpddpal == NULL) return E_OUTOFMEMORY;
4221 (*lpddpal)->ref = 1;
4222 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
4223 (*lpddpal)->installed = 0;
4225 if (dwFlags & DDPCAPS_1BIT)
4226 size = 2;
4227 else if (dwFlags & DDPCAPS_2BIT)
4228 size = 4;
4229 else if (dwFlags & DDPCAPS_4BIT)
4230 size = 16;
4231 else if (dwFlags & DDPCAPS_8BIT)
4232 size = 256;
4233 else
4234 ERR("unhandled palette format\n");
4235 *psize = size;
4237 if (palent)
4239 /* Now, if we are in 'depth conversion mode', create the screen palette */
4240 if (This->d.palette_convert != NULL)
4241 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
4243 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
4244 } else if (This->d.palette_convert != NULL) {
4245 /* In that case, put all 0xFF */
4246 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
4249 return DD_OK;
4252 #ifdef HAVE_LIBXXF86DGA
4253 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
4254 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4256 ICOM_THIS(IDirectDraw2Impl,iface);
4257 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4258 HRESULT res;
4259 int xsize = 0,i;
4261 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4262 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4263 if (res != 0) return res;
4264 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
4265 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
4266 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
4267 } else {
4268 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4269 (*ilpddpal)->cm = 0;
4271 if (((*ilpddpal)->cm)&&xsize) {
4272 for (i=0;i<xsize;i++) {
4273 XColor xc;
4275 xc.red = (*ilpddpal)->palents[i].peRed<<8;
4276 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
4277 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
4278 xc.flags = DoRed|DoBlue|DoGreen;
4279 xc.pixel = i;
4280 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
4283 return DD_OK;
4285 #endif /* defined(HAVE_LIBXXF86DGA) */
4287 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
4288 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4290 ICOM_THIS(IDirectDraw2Impl,iface);
4291 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4292 int xsize;
4293 HRESULT res;
4295 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4296 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4297 if (res != 0) return res;
4298 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
4299 return DD_OK;
4302 #ifdef HAVE_LIBXXF86DGA
4303 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4304 ICOM_THIS(IDirectDraw2Impl,iface);
4305 TRACE("(%p)->()\n",This);
4306 Sleep(1000);
4307 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4308 #ifdef RESTORE_SIGNALS
4309 SIGNAL_Init();
4310 #endif
4311 return DD_OK;
4313 #endif /* defined(HAVE_LIBXXF86DGA) */
4315 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4316 ICOM_THIS(IDirectDraw2Impl,iface);
4317 TRACE("(%p)->RestoreDisplayMode()\n", This);
4318 Sleep(1000);
4319 return DD_OK;
4322 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
4323 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
4325 ICOM_THIS(IDirectDraw2Impl,iface);
4326 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
4327 return DD_OK;
4330 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
4331 ICOM_THIS(IDirectDraw2Impl,iface);
4332 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
4334 return ++(This->ref);
4337 #ifdef HAVE_LIBXXF86DGA
4338 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4339 ICOM_THIS(IDirectDraw2Impl,iface);
4340 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4342 if (!--(This->ref)) {
4343 #ifdef HAVE_LIBXXF86DGA2
4344 if (This->e.dga.version == 2) {
4345 TRACE("Closing access to the FrameBuffer\n");
4346 TSXDGACloseFramebuffer(display, DefaultScreen(display));
4347 TRACE("Going back to normal X mode of operation\n");
4348 TSXDGASetMode(display, DefaultScreen(display), 0);
4350 /* Set the input handling back to absolute */
4351 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
4353 /* Remove the handling of DGA2 events */
4354 X11DRV_EVENT_SetDGAStatus(0, -1);
4356 /* Free the modes list */
4357 TSXFree(This->e.dga.modes);
4358 } else
4359 #endif /* defined(HAVE_LIBXXF86DGA2) */
4360 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4361 if (This->d.window && GetPropA(This->d.window,ddProp))
4362 DestroyWindow(This->d.window);
4363 #ifdef HAVE_LIBXXF86VM
4364 if (orig_mode) {
4365 TSXF86VidModeSwitchToMode(
4366 display,
4367 DefaultScreen(display),
4368 orig_mode);
4369 if (orig_mode->privsize)
4370 TSXFree(orig_mode->private);
4371 free(orig_mode);
4372 orig_mode = NULL;
4374 #endif
4376 #ifdef RESTORE_SIGNALS
4377 SIGNAL_Init();
4378 #endif
4379 HeapFree(GetProcessHeap(),0,This);
4380 return S_OK;
4382 return This->ref;
4384 #endif /* defined(HAVE_LIBXXF86DGA) */
4386 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4387 ICOM_THIS(IDirectDraw2Impl,iface);
4388 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4390 if (!--(This->ref)) {
4391 if (This->d.window && GetPropA(This->d.window,ddProp))
4392 DestroyWindow(This->d.window);
4393 HeapFree(GetProcessHeap(),0,This);
4394 return S_OK;
4396 /* FIXME: destroy window ... */
4397 return This->ref;
4400 #ifdef HAVE_LIBXXF86DGA
4401 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4402 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4404 ICOM_THIS(IDirectDraw2Impl,iface);
4406 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4407 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4408 *obj = This;
4409 IDirectDraw2_AddRef(iface);
4411 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4413 return S_OK;
4415 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4416 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4417 IDirectDraw2_AddRef(iface);
4418 *obj = This;
4420 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4422 return S_OK;
4424 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4425 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4426 IDirectDraw2_AddRef(iface);
4427 *obj = This;
4429 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4431 return S_OK;
4433 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4434 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4435 IDirectDraw2_AddRef(iface);
4436 *obj = This;
4438 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4440 return S_OK;
4442 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4443 IDirect3DImpl* 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) = &d3dvt;
4450 *obj = d3d;
4452 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4454 return S_OK;
4456 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4457 IDirect3D2Impl* d3d;
4459 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4460 d3d->ref = 1;
4461 d3d->ddraw = (IDirectDrawImpl*)This;
4462 IDirectDraw2_AddRef(iface);
4463 ICOM_VTBL(d3d) = &d3d2vt;
4464 *obj = d3d;
4466 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4468 return S_OK;
4470 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4471 return OLE_E_ENUM_NOMORE;
4473 #endif /* defined(HAVE_LIBXXF86DGA) */
4475 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4476 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4478 ICOM_THIS(IDirectDraw2Impl,iface);
4480 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4481 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4482 *obj = This;
4483 IDirectDraw2_AddRef(iface);
4485 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4487 return S_OK;
4489 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4490 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4491 IDirectDraw2_AddRef(iface);
4492 *obj = This;
4494 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4496 return S_OK;
4498 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4499 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4500 IDirectDraw2_AddRef(iface);
4501 *obj = This;
4503 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4505 return S_OK;
4507 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4508 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4509 IDirectDraw2_AddRef(iface);
4510 *obj = This;
4512 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4514 return S_OK;
4516 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4517 IDirect3DImpl* 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) = &d3dvt;
4524 *obj = d3d;
4526 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4528 return S_OK;
4530 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4531 IDirect3D2Impl* d3d;
4533 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4534 d3d->ref = 1;
4535 d3d->ddraw = (IDirectDrawImpl*)This;
4536 IDirectDraw2_AddRef(iface);
4537 ICOM_VTBL(d3d) = &d3d2vt;
4538 *obj = d3d;
4540 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4542 return S_OK;
4544 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4545 return OLE_E_ENUM_NOMORE;
4548 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4549 LPDIRECTDRAW2 iface,BOOL *status
4551 ICOM_THIS(IDirectDraw2Impl,iface);
4552 TRACE("(%p)->(%p)\n",This,status);
4553 *status = TRUE;
4554 return DD_OK;
4557 #ifdef HAVE_LIBXXF86DGA
4558 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4559 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4561 ICOM_THIS(IDirectDraw2Impl,iface);
4562 DDSURFACEDESC ddsfd;
4563 static struct {
4564 int w,h;
4565 } modes[5] = { /* some of the usual modes */
4566 {512,384},
4567 {640,400},
4568 {640,480},
4569 {800,600},
4570 {1024,768},
4572 static int depths[4] = {8,16,24,32};
4573 int i,j;
4575 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4576 ddsfd.dwSize = sizeof(ddsfd);
4577 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4578 if (dwFlags & DDEDM_REFRESHRATES) {
4579 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4580 ddsfd.u.dwRefreshRate = 60;
4582 ddsfd.ddsCaps.dwCaps = 0;
4583 ddsfd.dwBackBufferCount = 1;
4585 #ifdef HAVE_LIBXXF86DGA2
4586 if (This->e.dga.version == 2) {
4587 XDGAMode *modes = This->e.dga.modes;
4589 ddsfd.dwFlags |= DDSD_PITCH;
4590 for (i = 0; i < This->e.dga.num_modes; i++) {
4591 if (TRACE_ON(ddraw)) {
4592 DPRINTF(" Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
4593 modes[i].num,
4594 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
4595 modes[i].viewportWidth, modes[i].viewportHeight,
4596 modes[i].depth);
4597 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
4598 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
4599 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
4600 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
4601 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
4602 DPRINTF("\n");
4604 /* Fill the pixel format */
4605 ddsfd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
4606 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4607 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4608 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = modes[i].bitsPerPixel;
4609 if (modes[i].depth == 8) {
4610 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4611 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4612 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4613 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4614 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4615 } else {
4616 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4617 ddsfd.ddpfPixelFormat.u1.dwRBitMask = modes[i].redMask;
4618 ddsfd.ddpfPixelFormat.u2.dwGBitMask = modes[i].greenMask;
4619 ddsfd.ddpfPixelFormat.u3.dwBBitMask = modes[i].blueMask;
4622 ddsfd.dwWidth = modes[i].viewportWidth;
4623 ddsfd.dwHeight = modes[i].viewportHeight;
4624 ddsfd.lPitch = modes[i].imageWidth;
4626 /* Send mode to the application */
4627 if (!modescb(&ddsfd,context)) return DD_OK;
4629 } else {
4630 #endif
4631 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4632 ddsfd.dwBackBufferCount = 1;
4633 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4634 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4635 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4636 /* FIXME: those masks would have to be set in depth > 8 */
4637 if (depths[i]==8) {
4638 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4639 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4640 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4641 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4642 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4643 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4644 } else {
4645 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4647 /* FIXME: We should query those from X itself */
4648 switch (depths[i]) {
4649 case 16:
4650 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4651 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4652 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4653 break;
4654 case 24:
4655 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4656 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4657 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4658 break;
4659 case 32:
4660 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4661 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4662 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4663 break;
4667 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4668 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4669 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4670 if (!modescb(&ddsfd,context)) return DD_OK;
4672 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4673 ddsfd.dwWidth = modes[j].w;
4674 ddsfd.dwHeight = modes[j].h;
4675 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4676 if (!modescb(&ddsfd,context)) return DD_OK;
4679 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4680 /* modeX is not standard VGA */
4682 ddsfd.dwHeight = 200;
4683 ddsfd.dwWidth = 320;
4684 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4685 if (!modescb(&ddsfd,context)) return DD_OK;
4688 #ifdef HAVE_LIBXXF86DGA2
4690 #endif
4691 return DD_OK;
4693 #endif /* defined(HAVE_LIBXXF86DGA) */
4695 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4696 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4698 ICOM_THIS(IDirectDraw2Impl,iface);
4699 XVisualInfo *vi;
4700 XPixmapFormatValues *pf;
4701 XVisualInfo vt;
4702 int xbpp = 1, nvisuals, npixmap, i, emu;
4703 int has_mode[] = { 0, 0, 0, 0 };
4704 int has_depth[] = { 8, 15, 16, 24 };
4705 DDSURFACEDESC ddsfd;
4706 static struct {
4707 int w,h;
4708 } modes[] = { /* some of the usual modes */
4709 {512,384},
4710 {640,400},
4711 {640,480},
4712 {800,600},
4713 {1024,768},
4714 {1280,1024}
4716 DWORD maxWidth, maxHeight;
4718 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4719 ddsfd.dwSize = sizeof(ddsfd);
4720 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_PITCH;
4721 if (dwFlags & DDEDM_REFRESHRATES) {
4722 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4723 ddsfd.u.dwRefreshRate = 60;
4725 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4726 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4728 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4729 pf = XListPixmapFormats(display, &npixmap);
4731 i = 0;
4732 emu = 0;
4733 while ((i < npixmap) || (emu != 4)) {
4734 int mode_index = 0;
4735 int send_mode = 0;
4736 int j;
4738 if (i < npixmap) {
4739 for (j = 0; j < 4; j++) {
4740 if (has_depth[j] == pf[i].depth) {
4741 mode_index = j;
4742 break;
4745 if (j == 4) {
4746 i++;
4747 continue;
4751 if (has_mode[mode_index] == 0) {
4752 if (mode_index == 0) {
4753 send_mode = 1;
4755 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4756 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4757 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4758 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4759 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4760 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4761 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4762 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4763 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4765 xbpp = 1;
4767 has_mode[mode_index] = 1;
4768 } else {
4769 /* All the 'true color' depths (15, 16 and 24)
4770 First, find the corresponding visual to extract the bit masks */
4771 for (j = 0; j < nvisuals; j++) {
4772 if (vi[j].depth == pf[i].depth) {
4773 ddsfd.ddsCaps.dwCaps = 0;
4774 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4775 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4776 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4777 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4778 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4779 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4780 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4781 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4783 xbpp = pf[i].bits_per_pixel/8;
4785 send_mode = 1;
4786 has_mode[mode_index] = 1;
4787 break;
4790 if (j == nvisuals)
4791 ERR("Did not find visual corresponding the the pixmap format !\n");
4794 i++;
4795 } else {
4796 /* Now to emulated modes */
4797 if (has_mode[emu] == 0) {
4798 int c;
4799 int l;
4800 int depth = has_depth[emu];
4802 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4803 if (ModeEmulations[c].dest.depth == depth) {
4804 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4805 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4806 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4807 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4808 int j;
4809 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4810 if ((vi[j].depth == pf[l].depth) &&
4811 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4812 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4813 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4814 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4815 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4816 if (depth == 8) {
4817 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4818 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4819 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4820 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4821 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4822 } else {
4823 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4824 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4825 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4826 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4827 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4829 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4830 send_mode = 1;
4833 if (send_mode == 0)
4834 ERR("No visual corresponding to pixmap format !\n");
4842 emu++;
4845 if (send_mode) {
4846 int mode;
4848 if (TRACE_ON(ddraw)) {
4849 TRACE("Enumerating with pixel format : \n");
4850 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4851 DPRINTF("\n");
4854 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4855 /* Do not enumerate modes we cannot handle anyway */
4856 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4857 break;
4859 ddsfd.dwWidth = modes[mode].w;
4860 ddsfd.dwHeight= modes[mode].h;
4861 ddsfd.lPitch = ddsfd.dwWidth * xbpp;
4863 /* Now, send the mode description to the application */
4864 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4865 if (!modescb(&ddsfd, context))
4866 goto exit_enum;
4869 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4870 /* modeX is not standard VGA */
4871 ddsfd.dwWidth = 320;
4872 ddsfd.dwHeight = 200;
4873 ddsfd.lPitch = 320 * xbpp;
4874 if (!modescb(&ddsfd, context))
4875 goto exit_enum;
4879 exit_enum:
4880 TSXFree(vi);
4881 TSXFree(pf);
4883 return DD_OK;
4886 #ifdef HAVE_LIBXXF86DGA
4887 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4888 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4890 ICOM_THIS(IDirectDraw2Impl,iface);
4891 TRACE("(%p)->(%p)\n",This,lpddsfd);
4892 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4893 lpddsfd->dwHeight = This->d.height;
4894 lpddsfd->dwWidth = This->d.width;
4895 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4896 lpddsfd->dwBackBufferCount = 2;
4897 lpddsfd->u.dwRefreshRate = 60;
4898 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4899 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4900 if (TRACE_ON(ddraw)) {
4901 _dump_surface_desc(lpddsfd);
4903 return DD_OK;
4905 #endif /* defined(HAVE_LIBXXF86DGA) */
4907 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4908 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4910 ICOM_THIS(IDirectDraw2Impl,iface);
4911 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4912 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4913 lpddsfd->dwHeight = This->d.height;
4914 lpddsfd->dwWidth = This->d.width;
4915 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4916 lpddsfd->dwBackBufferCount = 2;
4917 lpddsfd->u.dwRefreshRate = 60;
4918 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4919 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4920 if (TRACE_ON(ddraw)) {
4921 _dump_surface_desc(lpddsfd);
4923 return DD_OK;
4926 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4927 ICOM_THIS(IDirectDraw2Impl,iface);
4928 TRACE("(%p)->()\n",This);
4929 return DD_OK;
4932 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4933 LPDIRECTDRAW2 iface,LPDWORD freq
4935 ICOM_THIS(IDirectDraw2Impl,iface);
4936 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4937 *freq = 60*100; /* 60 Hz */
4938 return DD_OK;
4941 /* what can we directly decompress? */
4942 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4943 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4945 ICOM_THIS(IDirectDraw2Impl,iface);
4946 FIXME("(%p,%p,%p), stub\n",This,x,y);
4947 return DD_OK;
4950 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4951 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4953 ICOM_THIS(IDirectDraw2Impl,iface);
4954 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4955 return DD_OK;
4958 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4959 LPDIRECTDRAW2 iface )
4961 ICOM_THIS(IDirectDraw2Impl,iface);
4962 FIXME("(%p)->()\n", This );
4964 return DD_OK;
4967 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4968 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4969 ICOM_THIS(IDirectDraw2Impl,iface);
4970 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4972 return DD_OK;
4975 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4976 LPDWORD lpdwScanLine) {
4977 ICOM_THIS(IDirectDraw2Impl,iface);
4978 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4980 if (lpdwScanLine)
4981 *lpdwScanLine = 0;
4982 return DD_OK;
4985 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4986 GUID *lpGUID) {
4987 ICOM_THIS(IDirectDraw2Impl,iface);
4988 FIXME("(%p)->(%p)\n", This, lpGUID);
4990 return DD_OK;
4993 #ifdef HAVE_LIBXXF86DGA
4995 /* Note: Hack so we can reuse the old functions without compiler warnings */
4996 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4997 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4998 #else
4999 # define XCAST(fun) (void *)
5000 #endif
5002 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
5004 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5005 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5006 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5007 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5008 XCAST(Compact)IDirectDraw2Impl_Compact,
5009 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5010 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5011 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5012 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5013 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5014 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5015 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5016 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5017 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5018 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5019 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5020 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5021 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5022 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5023 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5024 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5025 #ifdef HAVE_LIBXXF86DGA2
5026 XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
5027 #else
5028 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5029 #endif
5030 DGA_IDirectDrawImpl_SetDisplayMode,
5031 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5034 #undef XCAST
5036 #endif /* defined(HAVE_LIBXXF86DGA) */
5038 /* Note: Hack so we can reuse the old functions without compiler warnings */
5039 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5040 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
5041 #else
5042 # define XCAST(fun) (void *)
5043 #endif
5045 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
5047 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5048 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5049 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5050 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5051 XCAST(Compact)IDirectDraw2Impl_Compact,
5052 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5053 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5054 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5055 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5056 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5057 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5058 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5059 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5060 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5061 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5062 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5063 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5064 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5065 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5066 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5067 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5068 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5069 Xlib_IDirectDrawImpl_SetDisplayMode,
5070 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5073 #undef XCAST
5075 /*****************************************************************************
5076 * IDirectDraw2
5080 #ifdef HAVE_LIBXXF86DGA
5081 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
5082 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
5084 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5085 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5087 #endif /* defined(HAVE_LIBXXF86DGA) */
5089 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
5090 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
5092 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5093 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5096 #ifdef HAVE_LIBXXF86DGA
5097 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
5098 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5100 ICOM_THIS(IDirectDraw2Impl,iface);
5101 TRACE("(%p)->(%p,%p,%p)\n",
5102 This,ddscaps,total,free
5104 if (total) *total = This->e.dga.fb_memsize * 1024;
5105 if (free) *free = This->e.dga.fb_memsize * 1024;
5106 return DD_OK;
5108 #endif /* defined(HAVE_LIBXXF86DGA) */
5110 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
5111 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5113 ICOM_THIS(IDirectDraw2Impl,iface);
5114 TRACE("(%p)->(%p,%p,%p)\n",
5115 This,ddscaps,total,free
5117 if (total) *total = 2048 * 1024;
5118 if (free) *free = 2048 * 1024;
5119 return DD_OK;
5122 #ifdef HAVE_LIBXXF86DGA
5123 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
5125 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5126 DGA_IDirectDraw2Impl_QueryInterface,
5127 IDirectDraw2Impl_AddRef,
5128 DGA_IDirectDraw2Impl_Release,
5129 IDirectDraw2Impl_Compact,
5130 IDirectDraw2Impl_CreateClipper,
5131 DGA_IDirectDraw2Impl_CreatePalette,
5132 DGA_IDirectDraw2Impl_CreateSurface,
5133 IDirectDraw2Impl_DuplicateSurface,
5134 DGA_IDirectDraw2Impl_EnumDisplayModes,
5135 IDirectDraw2Impl_EnumSurfaces,
5136 IDirectDraw2Impl_FlipToGDISurface,
5137 DGA_IDirectDraw2Impl_GetCaps,
5138 DGA_IDirectDraw2Impl_GetDisplayMode,
5139 IDirectDraw2Impl_GetFourCCCodes,
5140 IDirectDraw2Impl_GetGDISurface,
5141 IDirectDraw2Impl_GetMonitorFrequency,
5142 IDirectDraw2Impl_GetScanLine,
5143 IDirectDraw2Impl_GetVerticalBlankStatus,
5144 IDirectDraw2Impl_Initialize,
5145 DGA_IDirectDraw2Impl_RestoreDisplayMode,
5146 IDirectDraw2Impl_SetCooperativeLevel,
5147 DGA_IDirectDraw2Impl_SetDisplayMode,
5148 IDirectDraw2Impl_WaitForVerticalBlank,
5149 DGA_IDirectDraw2Impl_GetAvailableVidMem
5151 #endif /* defined(HAVE_LIBXXF86DGA) */
5153 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
5155 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5156 Xlib_IDirectDraw2Impl_QueryInterface,
5157 IDirectDraw2Impl_AddRef,
5158 Xlib_IDirectDraw2Impl_Release,
5159 IDirectDraw2Impl_Compact,
5160 IDirectDraw2Impl_CreateClipper,
5161 Xlib_IDirectDraw2Impl_CreatePalette,
5162 Xlib_IDirectDraw2Impl_CreateSurface,
5163 IDirectDraw2Impl_DuplicateSurface,
5164 Xlib_IDirectDraw2Impl_EnumDisplayModes,
5165 IDirectDraw2Impl_EnumSurfaces,
5166 IDirectDraw2Impl_FlipToGDISurface,
5167 Xlib_IDirectDraw2Impl_GetCaps,
5168 Xlib_IDirectDraw2Impl_GetDisplayMode,
5169 IDirectDraw2Impl_GetFourCCCodes,
5170 IDirectDraw2Impl_GetGDISurface,
5171 IDirectDraw2Impl_GetMonitorFrequency,
5172 IDirectDraw2Impl_GetScanLine,
5173 IDirectDraw2Impl_GetVerticalBlankStatus,
5174 IDirectDraw2Impl_Initialize,
5175 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5176 IDirectDraw2Impl_SetCooperativeLevel,
5177 Xlib_IDirectDraw2Impl_SetDisplayMode,
5178 IDirectDraw2Impl_WaitForVerticalBlank,
5179 Xlib_IDirectDraw2Impl_GetAvailableVidMem
5182 /*****************************************************************************
5183 * IDirectDraw4
5187 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
5188 HDC hdc,
5189 LPDIRECTDRAWSURFACE *lpDDS) {
5190 ICOM_THIS(IDirectDraw4Impl,iface);
5191 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
5193 return DD_OK;
5196 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
5197 ICOM_THIS(IDirectDraw4Impl,iface);
5198 FIXME("(%p)->()\n", This);
5200 return DD_OK;
5203 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
5204 ICOM_THIS(IDirectDraw4Impl,iface);
5205 FIXME("(%p)->()\n", This);
5207 return DD_OK;
5210 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5211 LPDDDEVICEIDENTIFIER lpdddi,
5212 DWORD dwFlags) {
5213 ICOM_THIS(IDirectDraw4Impl,iface);
5214 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5216 return DD_OK;
5219 #ifdef HAVE_LIBXXF86DGA
5221 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5222 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5223 #else
5224 # define XCAST(fun) (void*)
5225 #endif
5227 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5229 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5230 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5231 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5232 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5233 XCAST(Compact)IDirectDraw2Impl_Compact,
5234 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5235 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5236 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5237 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5238 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5239 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5240 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5241 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5242 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5243 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5244 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5245 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5246 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5247 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5248 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5249 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5250 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5251 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5252 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5253 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5254 IDirectDraw4Impl_GetSurfaceFromDC,
5255 IDirectDraw4Impl_RestoreAllSurfaces,
5256 IDirectDraw4Impl_TestCooperativeLevel,
5257 IDirectDraw4Impl_GetDeviceIdentifier
5260 #undef XCAST
5262 #endif /* defined(HAVE_LIBXXF86DGA) */
5264 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5265 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5266 #else
5267 # define XCAST(fun) (void*)
5268 #endif
5270 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5272 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5273 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5274 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5275 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5276 XCAST(Compact)IDirectDraw2Impl_Compact,
5277 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5278 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5279 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5280 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5281 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5282 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5283 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5284 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5285 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5286 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5287 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5288 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5289 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5290 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5291 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5292 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5293 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5294 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5295 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5296 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5297 IDirectDraw4Impl_GetSurfaceFromDC,
5298 IDirectDraw4Impl_RestoreAllSurfaces,
5299 IDirectDraw4Impl_TestCooperativeLevel,
5300 IDirectDraw4Impl_GetDeviceIdentifier
5303 #undef XCAST
5305 /******************************************************************************
5306 * DirectDrawCreate
5309 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5311 LRESULT ret;
5312 IDirectDrawImpl* ddraw = NULL;
5313 DWORD lastError;
5315 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5317 SetLastError( ERROR_SUCCESS );
5318 ddraw = (IDirectDrawImpl*)GetPropA( hwnd, ddProp );
5319 if( (!ddraw) && ( ( lastError = GetLastError() ) != ERROR_SUCCESS ))
5321 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5324 if( ddraw )
5326 /* Perform any special direct draw functions */
5327 if (msg==WM_PAINT)
5328 ddraw->d.paintable = 1;
5330 /* Now let the application deal with the rest of this */
5331 if( ddraw->d.mainWindow )
5334 /* Don't think that we actually need to call this but...
5335 might as well be on the safe side of things... */
5337 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5338 it should be the procedures of our fake window that gets called
5339 instead of those of the window provided by the application.
5340 And with this patch, mouse clicks work with Monkey Island III
5341 - Lionel */
5342 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5344 if( !ret )
5346 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5347 /* We didn't handle the message - give it to the application */
5348 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5350 ret = CallWindowProcA(tmpWnd->winproc,
5351 ddraw->d.mainWindow, msg, wParam, lParam );
5353 WIN_ReleaseWndPtr(tmpWnd);
5357 } else {
5358 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5362 else
5364 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5367 return ret;
5370 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5371 #ifdef HAVE_LIBXXF86DGA
5372 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5373 int memsize,banksize,major,minor,flags;
5374 char *addr;
5375 int depth;
5376 int dga_version;
5377 int width, height;
5379 /* Get DGA availability / version */
5380 dga_version = DDRAW_DGA_Available();
5382 if (dga_version == 0) {
5383 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5384 return DDERR_GENERIC;
5387 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5388 (*ilplpDD)->ref = 1;
5389 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5390 #ifdef HAVE_LIBXXF86DGA2
5391 if (dga_version == 1) {
5392 (*ilplpDD)->e.dga.version = 1;
5393 #endif /* defined(HAVE_LIBXXF86DGA2) */
5394 TSXF86DGAQueryVersion(display,&major,&minor);
5395 TRACE("XF86DGA is version %d.%d\n",major,minor);
5396 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5397 if (!(flags & XF86DGADirectPresent))
5398 MESSAGE("direct video is NOT PRESENT.\n");
5399 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5400 (*ilplpDD)->e.dga.fb_width = width;
5401 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5402 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5403 (*ilplpDD)->e.dga.fb_height = height;
5404 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5405 addr,width,banksize,memsize
5407 TRACE("viewport height: %d\n",height);
5408 /* Get the screen dimensions as seen by Wine.
5409 In that case, it may be better to ignore the -desktop mode and return the
5410 real screen size => print a warning */
5411 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5412 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5413 if (((*ilplpDD)->d.height != height) ||
5414 ((*ilplpDD)->d.width != width))
5415 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5416 (*ilplpDD)->e.dga.fb_addr = addr;
5417 (*ilplpDD)->e.dga.fb_memsize = memsize;
5418 (*ilplpDD)->e.dga.vpmask = 0;
5420 /* just assume the default depth is the DGA depth too */
5421 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5422 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
5423 #ifdef RESTORE_SIGNALS
5424 SIGNAL_Init();
5425 #endif
5426 #ifdef HAVE_LIBXXF86DGA2
5427 } else {
5428 XDGAMode *modes;
5429 int i, num_modes;
5430 int mode_to_use = 0;
5432 (*ilplpDD)->e.dga.version = 2;
5434 TSXDGAQueryVersion(display,&major,&minor);
5435 TRACE("XDGA is version %d.%d\n",major,minor);
5437 TRACE("Opening the frame buffer.\n");
5438 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5439 ERR("Error opening the frame buffer !!!\n");
5441 return DDERR_GENERIC;
5444 /* List all available modes */
5445 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5446 (*ilplpDD)->e.dga.modes = modes;
5447 (*ilplpDD)->e.dga.num_modes = num_modes;
5448 if (TRACE_ON(ddraw)) {
5449 TRACE("Available modes :\n");
5450 for (i = 0; i < num_modes; i++) {
5451 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5452 modes[i].num,
5453 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5454 modes[i].viewportWidth, modes[i].viewportHeight,
5455 modes[i].depth);
5456 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5457 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5458 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5459 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5460 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5461 DPRINTF("\n");
5463 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5464 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5465 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5466 mode_to_use = modes[i].num;
5470 if (mode_to_use == 0) {
5471 ERR("Could not find mode !\n");
5472 mode_to_use = 1;
5473 } else {
5474 DPRINTF("Using mode number %d\n", mode_to_use);
5477 /* Initialize the frame buffer */
5478 _DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
5479 /* Set the input handling for relative mouse movements */
5480 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5482 #endif /* defined(HAVE_LIBXXF86DGA2) */
5483 return DD_OK;
5484 #else /* defined(HAVE_LIBXXF86DGA) */
5485 return DDERR_INVALIDDIRECTDRAWGUID;
5486 #endif /* defined(HAVE_LIBXXF86DGA) */
5489 static BOOL
5490 DDRAW_XSHM_Available(void)
5492 #ifdef HAVE_LIBXXSHM
5493 if (TSXShmQueryExtension(display))
5495 int major, minor;
5496 Bool shpix;
5498 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5499 (Options.noXSHM != 1))
5500 return 1;
5501 else
5502 return 0;
5504 else
5505 return 0;
5506 #else
5507 return 0;
5508 #endif
5511 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5512 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5513 int depth;
5515 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5516 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5517 (*ilplpDD)->ref = 1;
5518 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5520 /* At DirectDraw creation, the depth is the default depth */
5521 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5522 _common_depth_to_pixelformat(depth,
5523 &((*ilplpDD)->d.directdraw_pixelformat),
5524 &((*ilplpDD)->d.screen_pixelformat),
5525 &((*ilplpDD)->d.pixmap_depth));
5526 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5527 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5529 #ifdef HAVE_LIBXXSHM
5530 /* Test if XShm is available. */
5531 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5532 (*ilplpDD)->e.xlib.xshm_compl = 0;
5533 TRACE("Using XShm extension.\n");
5535 #endif
5537 return DD_OK;
5540 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5541 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5542 WNDCLASSA wc;
5543 /* WND* pParentWindow; */
5544 HRESULT ret;
5546 if (!HIWORD(lpGUID)) lpGUID = NULL;
5548 TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID),ilplpDD,pUnkOuter);
5550 if ( ( !lpGUID ) ||
5551 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5552 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5553 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5554 /* if they didn't request a particular interface, use the best
5555 * supported one */
5556 if (DDRAW_DGA_Available())
5557 lpGUID = &DGA_DirectDraw_GUID;
5558 else
5559 lpGUID = &XLIB_DirectDraw_GUID;
5562 wc.style = CS_GLOBALCLASS;
5563 wc.lpfnWndProc = Xlib_DDWndProc;
5564 wc.cbClsExtra = 0;
5565 wc.cbWndExtra = 0;
5567 /* We can be a child of the desktop since we're really important */
5569 This code is not useful since hInstance is forced to 0 afterward
5570 pParentWindow = WIN_GetDesktop();
5571 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5573 wc.hInstance = 0;
5576 wc.hIcon = 0;
5577 wc.hCursor = (HCURSOR)IDC_ARROWA;
5578 wc.hbrBackground= NULL_BRUSH;
5579 wc.lpszMenuName = 0;
5580 wc.lpszClassName= "WINE_DirectDraw";
5581 RegisterClassA(&wc);
5583 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5584 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5586 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5587 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5589 else {
5590 goto err;
5594 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5595 return ret;
5597 err:
5598 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",
5599 debugstr_guid(lpGUID),lplpDD,pUnkOuter);
5600 return DDERR_INVALIDDIRECTDRAWGUID;
5603 /*******************************************************************************
5604 * DirectDraw ClassFactory
5606 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5609 typedef struct
5611 /* IUnknown fields */
5612 ICOM_VFIELD(IClassFactory);
5613 DWORD ref;
5614 } IClassFactoryImpl;
5616 static HRESULT WINAPI
5617 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5618 ICOM_THIS(IClassFactoryImpl,iface);
5620 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
5621 return E_NOINTERFACE;
5624 static ULONG WINAPI
5625 DDCF_AddRef(LPCLASSFACTORY iface) {
5626 ICOM_THIS(IClassFactoryImpl,iface);
5627 return ++(This->ref);
5630 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5631 ICOM_THIS(IClassFactoryImpl,iface);
5632 /* static class, won't be freed */
5633 return --(This->ref);
5636 static HRESULT WINAPI DDCF_CreateInstance(
5637 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5639 ICOM_THIS(IClassFactoryImpl,iface);
5641 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
5642 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5643 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5644 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5645 /* FIXME: reuse already created DirectDraw if present? */
5646 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5648 return CLASS_E_CLASSNOTAVAILABLE;
5651 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5652 ICOM_THIS(IClassFactoryImpl,iface);
5653 FIXME("(%p)->(%d),stub!\n",This,dolock);
5654 return S_OK;
5657 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5659 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5660 DDCF_QueryInterface,
5661 DDCF_AddRef,
5662 DDCF_Release,
5663 DDCF_CreateInstance,
5664 DDCF_LockServer
5666 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5668 /*******************************************************************************
5669 * DllGetClassObject [DDRAW.13]
5670 * Retrieves class object from a DLL object
5672 * NOTES
5673 * Docs say returns STDAPI
5675 * PARAMS
5676 * rclsid [I] CLSID for the class object
5677 * riid [I] Reference to identifier of interface for class object
5678 * ppv [O] Address of variable to receive interface pointer for riid
5680 * RETURNS
5681 * Success: S_OK
5682 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5683 * E_UNEXPECTED
5685 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5687 TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5688 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5689 *ppv = (LPVOID)&DDRAW_CF;
5690 IClassFactory_AddRef((IClassFactory*)*ppv);
5691 return S_OK;
5693 FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5694 return CLASS_E_CLASSNOTAVAILABLE;
5698 /*******************************************************************************
5699 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5701 * RETURNS
5702 * Success: S_OK
5703 * Failure: S_FALSE
5705 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5707 FIXME("(void): stub\n");
5708 return S_FALSE;
5711 #else /* !defined(X_DISPLAY_MISSING) */
5713 #include "windef.h"
5714 #include "wtypes.h"
5716 #define DD_OK 0
5718 typedef void *LPUNKNOWN;
5719 typedef void *LPDIRECTDRAW;
5720 typedef void *LPDIRECTDRAWCLIPPER;
5721 typedef void *LPDDENUMCALLBACKA;
5722 typedef void *LPDDENUMCALLBACKEXA;
5723 typedef void *LPDDENUMCALLBACKEXW;
5724 typedef void *LPDDENUMCALLBACKW;
5726 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5728 return DD_OK;
5731 HRESULT WINAPI DirectDrawCreate(
5732 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5734 return DD_OK;
5737 HRESULT WINAPI DirectDrawCreateClipper(
5738 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5740 return DD_OK;
5743 HRESULT WINAPI DirectDrawEnumerateA(
5744 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5746 return DD_OK;
5749 HRESULT WINAPI DirectDrawEnumerateExA(
5750 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5752 return DD_OK;
5755 HRESULT WINAPI DirectDrawEnumerateExW(
5756 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5758 return DD_OK;
5761 HRESULT WINAPI DirectDrawEnumerateW(
5762 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5764 return DD_OK;
5767 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5769 return CLASS_E_CLASSNOTAVAILABLE;
5772 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5774 return DD_OK;
5777 #endif /* !defined(X_DISPLAY_MISSING) */