Moved command-line option handling out of the X11 driver.
[wine/multimedia.git] / dlls / ddraw / ddraw_main.c
blob0ab3ed7f8c7ed5d6af5e661e04a5914a99926c31
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 inline BOOL get_option( const char *name, BOOL def )
179 return PROFILE_GetWineIniBool( "x11drv", name, def );
182 static BYTE
183 DDRAW_DGA_Available(void)
185 #ifdef HAVE_LIBXXF86DGA
186 int fd, evbase, evret, majver, minver;
187 static BYTE return_value = 0xFF;
189 /* This prevents from probing X times for DGA */
190 if (return_value != 0xFF)
191 return return_value;
193 if (!get_option( "UseDGA", 1 )) {
194 return_value = 0;
195 return 0;
198 /* First, query the extenstion and its version */
199 if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) {
200 return_value = 0;
201 return 0;
204 if (!TSXF86DGAQueryVersion(display,&majver,&minver)) {
205 return_value = 0;
206 return 0;
209 #ifdef HAVE_LIBXXF86DGA2
210 if (majver >= 2) {
211 /* We have DGA 2.0 available ! */
212 if (TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
213 TSXDGACloseFramebuffer(display, DefaultScreen(display));
214 return_value = 2;
215 } else {
216 return_value = 0;
219 return return_value;
220 } else {
221 #endif /* defined(HAVE_LIBXXF86DGA2) */
223 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
224 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
225 /* others. --stephenc */
226 if ((fd = open("/dev/mem", O_RDWR)) != -1)
227 close(fd);
229 if (fd != -1)
230 return_value = 1;
231 else
232 return_value = 0;
234 return return_value;
235 #ifdef HAVE_LIBXXF86DGA2
237 #endif /* defined(HAVE_LIBXXF86DGA2) */
238 #else /* defined(HAVE_LIBXXF86DGA) */
239 return 0;
240 #endif /* defined(HAVE_LIBXXF86DGA) */
243 /**********************************************************************/
245 typedef struct {
246 LPVOID lpCallback;
247 LPVOID lpContext;
248 } DirectDrawEnumerateProcData;
250 /***********************************************************************
251 * DirectDrawEnumerateExA (DDRAW.*)
253 HRESULT WINAPI DirectDrawEnumerateExA(
254 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
256 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
258 if (TRACE_ON(ddraw)) {
259 DPRINTF(" Flags : ");
260 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
261 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
262 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
263 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
264 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
265 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
266 DPRINTF("\n");
269 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
270 /* For the moment, Wine does not support any 3D only accelerators */
271 return DD_OK;
273 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
274 /* For the moment, Wine does not support any attached secondary devices */
275 return DD_OK;
278 if (DDRAW_DGA_Available()) {
279 TRACE("Enumerating DGA interface\n");
280 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
281 return DD_OK;
284 TRACE("Enumerating Xlib interface\n");
285 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
286 return DD_OK;
288 TRACE("Enumerating Default interface\n");
289 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
290 return DD_OK;
292 return DD_OK;
295 /***********************************************************************
296 * DirectDrawEnumerateExW (DDRAW.*)
299 static BOOL CALLBACK DirectDrawEnumerateExProcW(
300 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
301 LPVOID lpContext, HMONITOR hm)
303 DirectDrawEnumerateProcData *pEPD =
304 (DirectDrawEnumerateProcData *) lpContext;
305 LPWSTR lpDriverDescriptionW =
306 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
307 LPWSTR lpDriverNameW =
308 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
310 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
311 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
313 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
314 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
316 return bResult;
319 /**********************************************************************/
321 HRESULT WINAPI DirectDrawEnumerateExW(
322 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
324 DirectDrawEnumerateProcData epd;
325 epd.lpCallback = (LPVOID) lpCallback;
326 epd.lpContext = lpContext;
328 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
329 (LPVOID) &epd, 0);
332 /***********************************************************************
333 * DirectDrawEnumerateA (DDRAW.*)
336 static BOOL CALLBACK DirectDrawEnumerateProcA(
337 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
338 LPVOID lpContext, HMONITOR hm)
340 DirectDrawEnumerateProcData *pEPD =
341 (DirectDrawEnumerateProcData *) lpContext;
343 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
344 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
347 /**********************************************************************/
349 HRESULT WINAPI DirectDrawEnumerateA(
350 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
352 DirectDrawEnumerateProcData epd;
353 epd.lpCallback = (LPVOID) lpCallback;
354 epd.lpContext = lpContext;
356 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
357 (LPVOID) &epd, 0);
360 /***********************************************************************
361 * DirectDrawEnumerateW (DDRAW.*)
364 static BOOL WINAPI DirectDrawEnumerateProcW(
365 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
366 LPVOID lpContext, HMONITOR hm)
368 DirectDrawEnumerateProcData *pEPD =
369 (DirectDrawEnumerateProcData *) lpContext;
371 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
372 lpGUID, lpDriverDescription, lpDriverName,
373 pEPD->lpContext);
376 /**********************************************************************/
378 HRESULT WINAPI DirectDrawEnumerateW(
379 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
381 DirectDrawEnumerateProcData epd;
382 epd.lpCallback = (LPVOID) lpCallback;
383 epd.lpContext = lpContext;
385 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
386 (LPVOID) &epd, 0);
389 /***********************************************************************
390 * DSoundHelp (DDRAW.?)
393 /* What is this doing here? */
394 HRESULT WINAPI
395 DSoundHelp(DWORD x,DWORD y,DWORD z) {
396 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
397 return 0;
400 /******************************************************************************
401 * internal helper functions
403 static void _dump_DDBLTFX(DWORD flagmask) {
404 int i;
405 const struct {
406 DWORD mask;
407 char *name;
408 } flags[] = {
409 #define FE(x) { x, #x},
410 FE(DDBLTFX_ARITHSTRETCHY)
411 FE(DDBLTFX_MIRRORLEFTRIGHT)
412 FE(DDBLTFX_MIRRORUPDOWN)
413 FE(DDBLTFX_NOTEARING)
414 FE(DDBLTFX_ROTATE180)
415 FE(DDBLTFX_ROTATE270)
416 FE(DDBLTFX_ROTATE90)
417 FE(DDBLTFX_ZBUFFERRANGE)
418 FE(DDBLTFX_ZBUFFERBASEDEST)
419 #undef FE
421 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
422 if (flags[i].mask & flagmask) {
423 DPRINTF("%s ",flags[i].name);
426 DPRINTF("\n");
430 static void _dump_DDBLTFAST(DWORD flagmask) {
431 int i;
432 const struct {
433 DWORD mask;
434 char *name;
435 } flags[] = {
436 #define FE(x) { x, #x},
437 FE(DDBLTFAST_NOCOLORKEY)
438 FE(DDBLTFAST_SRCCOLORKEY)
439 FE(DDBLTFAST_DESTCOLORKEY)
440 FE(DDBLTFAST_WAIT)
441 #undef FE
443 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
444 if (flags[i].mask & flagmask)
445 DPRINTF("%s ",flags[i].name);
446 DPRINTF("\n");
449 static void _dump_DDBLT(DWORD flagmask) {
450 int i;
451 const struct {
452 DWORD mask;
453 char *name;
454 } flags[] = {
455 #define FE(x) { x, #x},
456 FE(DDBLT_ALPHADEST)
457 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
458 FE(DDBLT_ALPHADESTNEG)
459 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
460 FE(DDBLT_ALPHAEDGEBLEND)
461 FE(DDBLT_ALPHASRC)
462 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
463 FE(DDBLT_ALPHASRCNEG)
464 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
465 FE(DDBLT_ASYNC)
466 FE(DDBLT_COLORFILL)
467 FE(DDBLT_DDFX)
468 FE(DDBLT_DDROPS)
469 FE(DDBLT_KEYDEST)
470 FE(DDBLT_KEYDESTOVERRIDE)
471 FE(DDBLT_KEYSRC)
472 FE(DDBLT_KEYSRCOVERRIDE)
473 FE(DDBLT_ROP)
474 FE(DDBLT_ROTATIONANGLE)
475 FE(DDBLT_ZBUFFER)
476 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
477 FE(DDBLT_ZBUFFERDESTOVERRIDE)
478 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
479 FE(DDBLT_ZBUFFERSRCOVERRIDE)
480 FE(DDBLT_WAIT)
481 FE(DDBLT_DEPTHFILL)
482 #undef FE
484 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
485 if (flags[i].mask & flagmask)
486 DPRINTF("%s ",flags[i].name);
487 DPRINTF("\n");
490 static void _dump_DDSCAPS(void *in) {
491 int i;
492 const struct {
493 DWORD mask;
494 char *name;
495 } flags[] = {
496 #define FE(x) { x, #x},
497 FE(DDSCAPS_RESERVED1)
498 FE(DDSCAPS_ALPHA)
499 FE(DDSCAPS_BACKBUFFER)
500 FE(DDSCAPS_COMPLEX)
501 FE(DDSCAPS_FLIP)
502 FE(DDSCAPS_FRONTBUFFER)
503 FE(DDSCAPS_OFFSCREENPLAIN)
504 FE(DDSCAPS_OVERLAY)
505 FE(DDSCAPS_PALETTE)
506 FE(DDSCAPS_PRIMARYSURFACE)
507 FE(DDSCAPS_PRIMARYSURFACELEFT)
508 FE(DDSCAPS_SYSTEMMEMORY)
509 FE(DDSCAPS_TEXTURE)
510 FE(DDSCAPS_3DDEVICE)
511 FE(DDSCAPS_VIDEOMEMORY)
512 FE(DDSCAPS_VISIBLE)
513 FE(DDSCAPS_WRITEONLY)
514 FE(DDSCAPS_ZBUFFER)
515 FE(DDSCAPS_OWNDC)
516 FE(DDSCAPS_LIVEVIDEO)
517 FE(DDSCAPS_HWCODEC)
518 FE(DDSCAPS_MODEX)
519 FE(DDSCAPS_MIPMAP)
520 FE(DDSCAPS_RESERVED2)
521 FE(DDSCAPS_ALLOCONLOAD)
522 FE(DDSCAPS_VIDEOPORT)
523 FE(DDSCAPS_LOCALVIDMEM)
524 FE(DDSCAPS_NONLOCALVIDMEM)
525 FE(DDSCAPS_STANDARDVGAMODE)
526 FE(DDSCAPS_OPTIMIZED)
527 #undef FE
529 DWORD flagmask = *((DWORD *) in);
530 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
531 if (flags[i].mask & flagmask)
532 DPRINTF("%s ",flags[i].name);
535 static void _dump_pixelformat_flag(DWORD flagmask) {
536 int i;
537 const struct {
538 DWORD mask;
539 char *name;
540 } flags[] = {
541 #define FE(x) { x, #x},
542 FE(DDPF_ALPHAPIXELS)
543 FE(DDPF_ALPHA)
544 FE(DDPF_FOURCC)
545 FE(DDPF_PALETTEINDEXED4)
546 FE(DDPF_PALETTEINDEXEDTO8)
547 FE(DDPF_PALETTEINDEXED8)
548 FE(DDPF_RGB)
549 FE(DDPF_COMPRESSED)
550 FE(DDPF_RGBTOYUV)
551 FE(DDPF_YUV)
552 FE(DDPF_ZBUFFER)
553 FE(DDPF_PALETTEINDEXED1)
554 FE(DDPF_PALETTEINDEXED2)
555 FE(DDPF_ZPIXELS)
556 #undef FE
558 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
559 if (flags[i].mask & flagmask)
560 DPRINTF("%s ",flags[i].name);
563 static void _dump_paletteformat(DWORD dwFlags) {
564 int i;
565 const struct {
566 DWORD mask;
567 char *name;
568 } flags[] = {
569 #define FE(x) { x, #x},
570 FE(DDPCAPS_4BIT)
571 FE(DDPCAPS_8BITENTRIES)
572 FE(DDPCAPS_8BIT)
573 FE(DDPCAPS_INITIALIZE)
574 FE(DDPCAPS_PRIMARYSURFACE)
575 FE(DDPCAPS_PRIMARYSURFACELEFT)
576 FE(DDPCAPS_ALLOW256)
577 FE(DDPCAPS_VSYNC)
578 FE(DDPCAPS_1BIT)
579 FE(DDPCAPS_2BIT)
580 FE(DDPCAPS_ALPHA)
581 #undef FE
583 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
584 if (flags[i].mask & dwFlags)
585 DPRINTF("%s ",flags[i].name);
586 DPRINTF("\n");
589 static void _dump_pixelformat(void *in) {
590 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
591 char *cmd;
593 DPRINTF("( ");
594 _dump_pixelformat_flag(pf->dwFlags);
595 if (pf->dwFlags & DDPF_FOURCC) {
596 DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
598 if (pf->dwFlags & DDPF_RGB) {
599 DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount);
600 switch (pf->u.dwRGBBitCount) {
601 case 4:
602 cmd = "%1lx";
603 break;
604 case 8:
605 cmd = "%02lx";
606 break;
607 case 16:
608 cmd = "%04lx";
609 break;
610 case 24:
611 cmd = "%06lx";
612 break;
613 case 32:
614 cmd = "%08lx";
615 break;
616 default:
617 ERR("Unexpected bit depth !\n");
618 cmd = "%d";
620 DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask);
621 DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask);
622 DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask);
623 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
624 DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask);
626 if (pf->dwFlags & DDPF_ZPIXELS) {
627 DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask);
630 if (pf->dwFlags & DDPF_ZBUFFER) {
631 DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth);
633 if (pf->dwFlags & DDPF_ALPHA) {
634 DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth);
636 DPRINTF(")");
639 static void _dump_colorkeyflag(DWORD ck) {
640 int i;
641 const struct {
642 DWORD mask;
643 char *name;
644 } flags[] = {
645 #define FE(x) { x, #x},
646 FE(DDCKEY_COLORSPACE)
647 FE(DDCKEY_DESTBLT)
648 FE(DDCKEY_DESTOVERLAY)
649 FE(DDCKEY_SRCBLT)
650 FE(DDCKEY_SRCOVERLAY)
651 #undef FE
653 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
654 if (flags[i].mask & ck)
655 DPRINTF("%s ",flags[i].name);
658 static void _dump_DWORD(void *in) {
659 DPRINTF("%ld", *((DWORD *) in));
661 static void _dump_PTR(void *in) {
662 DPRINTF("%p", *((void **) in));
664 static void _dump_DDCOLORKEY(void *in) {
665 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
667 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
670 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
671 int i;
672 struct {
673 DWORD mask;
674 char *name;
675 void (*func)(void *);
676 void *elt;
677 } flags[16], *fe = flags;
678 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
679 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
680 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
681 FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
682 FE(DDSD_PITCH, _dump_DWORD, lPitch);
683 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
684 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth);
685 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
686 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
687 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
688 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
689 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
690 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
691 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount);
692 FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate);
693 FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize);
694 FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface);
695 #undef FE
697 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
698 if (flags[i].mask & lpddsd->dwFlags) {
699 DPRINTF(" - %s : ",flags[i].name);
700 flags[i].func(flags[i].elt);
701 DPRINTF("\n");
706 /******************************************************************************
707 * IDirectDrawSurface methods
709 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
710 * DDS and DDS2 use those functions. (Function calls did not change (except
711 * using different DirectDrawSurfaceX version), just added flags and functions)
714 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
715 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
717 ICOM_THIS(IDirectDrawSurface4Impl,iface);
718 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
719 This,lprect,lpddsd,flags,(DWORD)hnd);
720 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
721 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
722 This,lprect,lpddsd,flags,(DWORD)hnd);
724 /* First, copy the Surface description */
725 *lpddsd = This->s.surface_desc;
726 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
727 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
729 /* If asked only for a part, change the surface pointer */
730 if (lprect) {
731 TRACE(" lprect: %dx%d-%dx%d\n",
732 lprect->top,lprect->left,lprect->bottom,lprect->right
734 if ((lprect->top < 0) ||
735 (lprect->left < 0) ||
736 (lprect->bottom < 0) ||
737 (lprect->right < 0)) {
738 ERR(" Negative values in LPRECT !!!\n");
739 return DDERR_INVALIDPARAMS;
742 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
743 (lprect->top*This->s.surface_desc.lPitch) +
744 lprect->left*GET_BPP(This->s.surface_desc));
745 } else {
746 assert(This->s.surface_desc.u1.lpSurface);
749 /* wait for any previous operations to complete */
750 #ifdef HAVE_LIBXXSHM
751 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE) &&
752 This->s.ddraw->e.xlib.xshm_active) {
754 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
755 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
757 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
759 #endif
760 return DD_OK;
763 #ifdef HAVE_LIBXXF86DGA
764 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
765 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
767 ICOM_THIS(IDirectDrawSurface4Impl,iface);
768 TRACE("(%p)->Unlock(%p)\n",This,surface);
769 return DD_OK;
771 #endif /* defined(HAVE_LIBXXF86DGA) */
773 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
774 if (This->s.ddraw->d.pixel_convert != NULL)
775 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
776 This->t.xlib.image->data,
777 This->s.surface_desc.dwWidth,
778 This->s.surface_desc.dwHeight,
779 This->s.surface_desc.lPitch,
780 This->s.palette);
782 #ifdef HAVE_LIBXXSHM
783 if (This->s.ddraw->e.xlib.xshm_active) {
785 X11DRV_EVENT_WaitReplaceShmCompletion( &This->s.ddraw->e.xlib.xshm_compl, This->s.ddraw->d.drawable );
787 /* let WaitShmCompletions track 'em for now */
788 /* (you may want to track it again whenever you implement DX7's partial surface locking,
789 where threads have concurrent access) */
790 X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
791 TSXShmPutImage(display,
792 This->s.ddraw->d.drawable,
793 DefaultGCOfScreen(X11DRV_GetXScreen()),
794 This->t.xlib.image,
795 0, 0, 0, 0,
796 This->t.xlib.image->width,
797 This->t.xlib.image->height,
798 True);
799 /* make sure the image is transferred ASAP */
800 TSXFlush(display);
802 else
803 #endif
804 TSXPutImage( display,
805 This->s.ddraw->d.drawable,
806 DefaultGCOfScreen(X11DRV_GetXScreen()),
807 This->t.xlib.image,
808 0, 0, 0, 0,
809 This->t.xlib.image->width,
810 This->t.xlib.image->height);
813 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
814 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
816 ICOM_THIS(IDirectDrawSurface4Impl,iface);
817 TRACE("(%p)->Unlock(%p)\n",This,surface);
819 if (!This->s.ddraw->d.paintable)
820 return DD_OK;
822 /* Only redraw the screen when unlocking the buffer that is on screen */
823 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
824 Xlib_copy_surface_on_screen(This);
826 if (This->s.palette && This->s.palette->cm)
827 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
829 return DD_OK;
832 static IDirectDrawSurface4Impl* _common_find_flipto(
833 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
835 int i,j,flipable=0;
836 struct _surface_chain *chain = This->s.chain;
838 /* if there was no override flipto, look for current backbuffer */
839 if (!flipto) {
840 /* walk the flip chain looking for backbuffer */
841 for (i=0;i<chain->nrofsurfaces;i++) {
842 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
843 flipable++;
844 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
845 flipto = chain->surfaces[i];
847 /* sanity checks ... */
848 if (!flipto) {
849 if (flipable>1) {
850 for (i=0;i<chain->nrofsurfaces;i++)
851 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
852 break;
853 if (i==chain->nrofsurfaces) {
854 /* we do not have a frontbuffer either */
855 for (i=0;i<chain->nrofsurfaces;i++)
856 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
857 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
858 break;
860 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
861 int k = j % chain->nrofsurfaces;
862 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
863 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
864 flipto = chain->surfaces[k];
865 break;
870 if (!flipto)
871 flipto = This;
873 TRACE("flipping to %p\n",flipto);
875 return flipto;
878 #ifdef HAVE_LIBXXF86DGA
879 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
880 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
882 ICOM_THIS(IDirectDrawSurface4Impl,iface);
883 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
884 DWORD xheight;
885 LPBYTE surf;
887 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
888 iflipto = _common_find_flipto(This,iflipto);
890 /* and flip! */
891 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
892 if (iflipto->s.palette && iflipto->s.palette->cm)
893 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
894 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
897 /* We need to switch the lowlevel surfaces, for DGA this is: */
899 /* The height within the framebuffer */
900 xheight = This->t.dga.fb_height;
901 This->t.dga.fb_height = iflipto->t.dga.fb_height;
902 iflipto->t.dga.fb_height = xheight;
904 /* And the assciated surface pointer */
905 surf = This->s.surface_desc.u1.lpSurface;
906 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
907 iflipto->s.surface_desc.u1.lpSurface = surf;
909 return DD_OK;
911 #endif /* defined(HAVE_LIBXXF86DGA) */
913 #ifdef HAVE_LIBXXF86DGA2
914 static HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
915 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
917 ICOM_THIS(IDirectDrawSurface4Impl,iface);
918 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
919 DWORD xheight;
920 LPBYTE surf;
922 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
923 iflipto = _common_find_flipto(This,iflipto);
925 /* and flip! */
926 TSXDGASetViewport(display,DefaultScreen(display),0,iflipto->t.dga.fb_height, XDGAFlipRetrace);
927 TSXDGASync(display,DefaultScreen(display));
928 TSXFlush(display);
929 if (iflipto->s.palette && iflipto->s.palette->cm)
930 TSXDGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
931 /* We need to switch the lowlevel surfaces, for DGA this is: */
933 /* The height within the framebuffer */
934 xheight = This->t.dga.fb_height;
935 This->t.dga.fb_height = iflipto->t.dga.fb_height;
936 iflipto->t.dga.fb_height = xheight;
938 /* And the assciated surface pointer */
939 surf = This->s.surface_desc.u1.lpSurface;
940 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
941 iflipto->s.surface_desc.u1.lpSurface = surf;
943 return DD_OK;
945 #endif /* defined(HAVE_LIBXXF86DGA2) */
947 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
948 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
950 ICOM_THIS(IDirectDrawSurface4Impl,iface);
951 XImage *image;
952 LPBYTE surf;
953 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
955 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
956 iflipto = _common_find_flipto(This,iflipto);
958 #if defined(HAVE_MESAGL) && 0 /* does not work */
959 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
960 TRACE(" - OpenGL flip\n");
961 ENTER_GL();
962 glXSwapBuffers(display, This->s.ddraw->d.drawable);
963 LEAVE_GL();
965 return DD_OK;
967 #endif /* defined(HAVE_MESAGL) */
969 if (!This->s.ddraw->d.paintable)
970 return DD_OK;
972 /* We need to switch the lowlevel surfaces, for xlib this is: */
973 /* The surface pointer */
974 surf = This->s.surface_desc.u1.lpSurface;
975 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
976 iflipto->s.surface_desc.u1.lpSurface = surf;
977 /* the associated ximage */
978 image = This->t.xlib.image;
979 This->t.xlib.image = iflipto->t.xlib.image;
980 iflipto->t.xlib.image = image;
982 #ifdef HAVE_LIBXXSHM
983 if (This->s.ddraw->e.xlib.xshm_active) {
985 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
986 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
988 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
990 #endif
991 Xlib_copy_surface_on_screen(This);
993 if (iflipto->s.palette && iflipto->s.palette->cm)
994 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
995 return DD_OK;
998 /* The IDirectDrawSurface4::SetPalette method attaches the specified
999 * DirectDrawPalette object to a surface. The surface uses this palette for all
1000 * subsequent operations. The palette change takes place immediately.
1002 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
1003 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1005 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1006 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1007 int i;
1008 TRACE("(%p)->(%p)\n",This,ipal);
1010 if (ipal == NULL) {
1011 if( This->s.palette != NULL )
1012 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1013 This->s.palette = ipal;
1015 return DD_OK;
1018 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8))
1020 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
1021 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
1023 if (!Options.managed)
1024 TSXInstallColormap(display,ipal->cm);
1026 for (i=0;i<256;i++) {
1027 XColor xc;
1029 xc.red = ipal->palents[i].peRed<<8;
1030 xc.blue = ipal->palents[i].peBlue<<8;
1031 xc.green = ipal->palents[i].peGreen<<8;
1032 xc.flags = DoRed|DoBlue|DoGreen;
1033 xc.pixel = i;
1034 TSXStoreColor(display,ipal->cm,&xc);
1036 TSXInstallColormap(display,ipal->cm);
1039 /* According to spec, we are only supposed to
1040 * AddRef if this is not the same palette.
1042 if( This->s.palette != ipal )
1044 if( ipal != NULL )
1045 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1046 if( This->s.palette != NULL )
1047 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1048 This->s.palette = ipal;
1049 /* Perform the refresh */
1050 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
1052 return DD_OK;
1055 #ifdef HAVE_LIBXXF86DGA
1056 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
1057 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1059 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1060 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1061 TRACE("(%p)->(%p)\n",This,ipal);
1063 /* According to spec, we are only supposed to
1064 * AddRef if this is not the same palette.
1066 if( This->s.palette != ipal )
1068 if( ipal != NULL )
1069 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1070 if( This->s.palette != NULL )
1071 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1072 This->s.palette = ipal;
1073 #ifdef HAVE_LIBXXF86DGA2
1074 if (This->s.ddraw->e.dga.version == 2)
1075 TSXDGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1076 else
1077 #endif /* defined(HAVE_LIBXXF86DGA2) */
1078 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1080 return DD_OK;
1082 #endif /* defined(HAVE_LIBXXF86DGA) */
1084 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
1086 int x, y;
1087 LPBYTE first;
1089 /* Do first row */
1091 #define COLORFILL_ROW(type) { \
1092 type *d = (type *) buf; \
1093 for (x = 0; x < width; x++) \
1094 d[x] = (type) color; \
1095 break; \
1098 switch(bpp) {
1099 case 1: COLORFILL_ROW(BYTE)
1100 case 2: COLORFILL_ROW(WORD)
1101 case 4: COLORFILL_ROW(DWORD)
1102 default:
1103 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
1104 return DDERR_UNSUPPORTED;
1107 #undef COLORFILL_ROW
1109 /* Now copy first row */
1110 first = buf;
1111 for (y = 1; y < height; y++) {
1112 buf += lPitch;
1113 memcpy(buf, first, width * bpp);
1116 return DD_OK;
1119 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
1120 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
1122 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1123 RECT xdst,xsrc;
1124 DDSURFACEDESC ddesc,sdesc;
1125 HRESULT ret = DD_OK;
1126 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
1127 int x, y;
1128 LPBYTE dbuf, sbuf;
1130 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
1132 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
1133 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1135 if (TRACE_ON(ddraw)) {
1136 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1137 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1138 TRACE("\tflags: ");
1139 _dump_DDBLT(dwFlags);
1140 if (dwFlags & DDBLT_DDFX) {
1141 TRACE("\tblitfx: ");
1142 _dump_DDBLTFX(lpbltfx->dwDDFX);
1146 if (rdst) {
1147 if ((rdst->top < 0) ||
1148 (rdst->left < 0) ||
1149 (rdst->bottom < 0) ||
1150 (rdst->right < 0)) {
1151 ERR(" Negative values in LPRECT !!!\n");
1152 goto release;
1154 memcpy(&xdst,rdst,sizeof(xdst));
1155 } else {
1156 xdst.top = 0;
1157 xdst.bottom = ddesc.dwHeight;
1158 xdst.left = 0;
1159 xdst.right = ddesc.dwWidth;
1162 if (rsrc) {
1163 if ((rsrc->top < 0) ||
1164 (rsrc->left < 0) ||
1165 (rsrc->bottom < 0) ||
1166 (rsrc->right < 0)) {
1167 ERR(" Negative values in LPRECT !!!\n");
1168 goto release;
1170 memcpy(&xsrc,rsrc,sizeof(xsrc));
1171 } else {
1172 if (src) {
1173 xsrc.top = 0;
1174 xsrc.bottom = sdesc.dwHeight;
1175 xsrc.left = 0;
1176 xsrc.right = sdesc.dwWidth;
1177 } else {
1178 memset(&xsrc,0,sizeof(xsrc));
1182 bpp = GET_BPP(ddesc);
1183 srcheight = xsrc.bottom - xsrc.top;
1184 srcwidth = xsrc.right - xsrc.left;
1185 dstheight = xdst.bottom - xdst.top;
1186 dstwidth = xdst.right - xdst.left;
1187 width = (xdst.right - xdst.left) * bpp;
1188 dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1190 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1192 /* First, all the 'source-less' blits */
1193 if (dwFlags & DDBLT_COLORFILL) {
1194 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1195 ddesc.lPitch, lpbltfx->u4.dwFillColor);
1196 dwFlags &= ~DDBLT_COLORFILL;
1199 if (dwFlags & DDBLT_DEPTHFILL) {
1200 #ifdef HAVE_MESAGL
1201 GLboolean ztest;
1203 /* Clears the screen */
1204 TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
1205 glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1206 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1207 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1208 glClear(GL_DEPTH_BUFFER_BIT);
1209 glDepthMask(ztest);
1211 dwFlags &= ~(DDBLT_DEPTHFILL);
1212 #endif /* defined(HAVE_MESAGL) */
1215 if (dwFlags & DDBLT_ROP) {
1216 /* Catch some degenerate cases here */
1217 switch(lpbltfx->dwROP) {
1218 case BLACKNESS:
1219 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1220 break;
1221 case 0xAA0029: /* No-op */
1222 break;
1223 case WHITENESS:
1224 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1225 break;
1226 default:
1227 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
1228 goto error;
1230 dwFlags &= ~DDBLT_ROP;
1233 if (dwFlags & DDBLT_DDROPS) {
1234 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
1237 /* Now the 'with source' blits */
1238 if (src) {
1239 LPBYTE sbase;
1240 int sx, xinc, sy, yinc;
1242 sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1243 xinc = (srcwidth << 16) / dstwidth;
1244 yinc = (srcheight << 16) / dstheight;
1246 if (!dwFlags) {
1248 /* No effects, we can cheat here */
1249 if (dstwidth == srcwidth) {
1250 if (dstheight == srcheight) {
1251 /* No stretching in either direction. This needs to be as fast as possible */
1252 sbuf = sbase;
1253 for (y = 0; y < dstheight; y++) {
1254 memcpy(dbuf, sbuf, width);
1255 sbuf += sdesc.lPitch;
1256 dbuf += ddesc.lPitch;
1258 } else {
1259 /* Stretching in Y direction only */
1260 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1261 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1262 memcpy(dbuf, sbuf, width);
1263 dbuf += ddesc.lPitch;
1266 } else {
1267 /* Stretching in X direction */
1268 int last_sy = -1;
1269 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1270 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1272 if ((sy >> 16) == (last_sy >> 16)) {
1273 /* Same as last row - copy already stretched row */
1274 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1275 } else {
1277 #define STRETCH_ROW(type) { \
1278 type *s = (type *) sbuf, *d = (type *) dbuf; \
1279 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1280 d[x] = s[sx >> 16]; \
1281 break; }
1283 switch(bpp) {
1284 case 1: STRETCH_ROW(BYTE)
1285 case 2: STRETCH_ROW(WORD)
1286 case 4: STRETCH_ROW(DWORD)
1287 case 3: {
1288 LPBYTE s,d;
1289 for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
1290 DWORD pixel;
1292 s = sbuf+3*(sx>>16);
1293 d = dbuf+3*x;
1294 pixel = (s[0]<<16)|(s[1]<<8)|s[2];
1295 d[0] = (pixel>>16)&0xff;
1296 d[1] = (pixel>> 8)&0xff;
1297 d[2] = (pixel )&0xff;
1299 break;
1301 default:
1302 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1303 ret = DDERR_UNSUPPORTED;
1304 goto error;
1307 #undef STRETCH_ROW
1310 last_sy = sy;
1311 dbuf += ddesc.lPitch;
1314 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1315 DWORD keylow, keyhigh;
1317 if (dwFlags & DDBLT_KEYSRC) {
1318 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1319 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1320 } else {
1321 /* I'm not sure if this is correct */
1322 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1323 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1324 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1328 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1329 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1331 #define COPYROW_COLORKEY(type) { \
1332 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1333 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1334 tmp = s[sx >> 16]; \
1335 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1337 break; }
1339 switch (bpp) {
1340 case 1: COPYROW_COLORKEY(BYTE)
1341 case 2: COPYROW_COLORKEY(WORD)
1342 case 4: COPYROW_COLORKEY(DWORD)
1343 default:
1344 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1345 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1346 ret = DDERR_UNSUPPORTED;
1347 goto error;
1349 dbuf += ddesc.lPitch;
1352 #undef COPYROW_COLORKEY
1354 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1359 error:
1361 if (dwFlags && FIXME_ON(ddraw)) {
1362 FIXME("\tUnsupported flags: ");
1363 _dump_DDBLT(dwFlags);
1365 release:
1367 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1368 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1370 return DD_OK;
1373 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1374 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1376 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1377 int bpp, w, h, x, y;
1378 DDSURFACEDESC ddesc,sdesc;
1379 HRESULT ret = DD_OK;
1380 LPBYTE sbuf, dbuf;
1381 RECT rsrc2;
1384 if (TRACE_ON(ddraw)) {
1385 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1386 This,dstx,dsty,src,rsrc,trans
1388 FIXME(" trans:");
1389 if (FIXME_ON(ddraw))
1390 _dump_DDBLTFAST(trans);
1391 if (rsrc)
1392 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1393 else
1394 FIXME(" srcrect: NULL\n");
1397 /* We need to lock the surfaces, or we won't get refreshes when done. */
1398 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1399 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1401 if (!rsrc) {
1402 WARN("rsrc is NULL!\n");
1403 rsrc = &rsrc2;
1404 rsrc->left = rsrc->top = 0;
1405 rsrc->right = sdesc.dwWidth;
1406 rsrc->bottom = sdesc.dwHeight;
1409 bpp = GET_BPP(This->s.surface_desc);
1410 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1411 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1414 h=rsrc->bottom-rsrc->top;
1415 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1416 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1417 if (h<0) h=0;
1419 w=rsrc->right-rsrc->left;
1420 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1421 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1422 if (w<0) w=0;
1424 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1425 DWORD keylow, keyhigh;
1426 if (trans & DDBLTFAST_SRCCOLORKEY) {
1427 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1428 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1429 } else {
1430 /* I'm not sure if this is correct */
1431 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1432 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1433 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1436 #define COPYBOX_COLORKEY(type) { \
1437 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1438 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1439 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1440 for (y = 0; y < h; y++) { \
1441 for (x = 0; x < w; x++) { \
1442 tmp = s[x]; \
1443 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1445 (LPBYTE)s += sdesc.lPitch; \
1446 (LPBYTE)d += ddesc.lPitch; \
1448 break; \
1451 switch (bpp) {
1452 case 1: COPYBOX_COLORKEY(BYTE)
1453 case 2: COPYBOX_COLORKEY(WORD)
1454 case 4: COPYBOX_COLORKEY(DWORD)
1455 default:
1456 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1457 ret = DDERR_UNSUPPORTED;
1458 goto error;
1461 #undef COPYBOX_COLORKEY
1463 } else {
1464 int width = w * bpp;
1466 for (y = 0; y < h; y++) {
1467 memcpy(dbuf, sbuf, width);
1468 sbuf += sdesc.lPitch;
1469 dbuf += ddesc.lPitch;
1473 error:
1475 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1476 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1477 return ret;
1480 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1481 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1483 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1484 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1485 This,ddbltbatch,x,y
1487 return DD_OK;
1490 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1491 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1493 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1494 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1495 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1496 return DD_OK;
1499 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1500 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1501 ) {
1502 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1503 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1505 /* Simply copy the surface description stored in the object */
1506 *ddsd = This->s.surface_desc;
1508 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1510 return DD_OK;
1513 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1514 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1515 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1516 return ++(This->ref);
1519 #ifdef HAVE_LIBXXF86DGA
1520 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1521 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1523 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1525 if (--(This->ref))
1526 return This->ref;
1528 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1529 /* clear out of surface list */
1530 if (This->t.dga.fb_height == -1)
1531 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1532 else
1533 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1535 /* Free the DIBSection (if any) */
1536 if (This->s.hdc != 0) {
1537 SelectObject(This->s.hdc, This->s.holdbitmap);
1538 DeleteDC(This->s.hdc);
1539 DeleteObject(This->s.DIBsection);
1542 /* Free the clipper if attached to this surface */
1543 if( This->s.lpClipper )
1544 IDirectDrawClipper_Release(This->s.lpClipper);
1546 HeapFree(GetProcessHeap(),0,This);
1547 return S_OK;
1549 #endif /* defined(HAVE_LIBXXF86DGA) */
1551 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1552 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1554 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1556 if (--(This->ref))
1557 return This->ref;
1559 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1561 if (This->t.xlib.image != NULL) {
1562 if (This->s.ddraw->d.pixel_convert != NULL) {
1563 /* In pixel conversion mode, there are 2 buffers to release. */
1564 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1566 #ifdef HAVE_LIBXXSHM
1567 if (This->s.ddraw->e.xlib.xshm_active) {
1568 TSXShmDetach(display, &(This->t.xlib.shminfo));
1569 TSXDestroyImage(This->t.xlib.image);
1570 shmdt(This->t.xlib.shminfo.shmaddr);
1571 } else {
1572 #endif
1573 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1574 This->t.xlib.image->data = NULL;
1575 TSXDestroyImage(This->t.xlib.image);
1576 #ifdef HAVE_LIBXXSHM
1578 #endif
1579 } else {
1580 This->t.xlib.image->data = NULL;
1582 #ifdef HAVE_LIBXXSHM
1583 if (This->s.ddraw->e.xlib.xshm_active) {
1584 TSXShmDetach(display, &(This->t.xlib.shminfo));
1585 TSXDestroyImage(This->t.xlib.image);
1586 shmdt(This->t.xlib.shminfo.shmaddr);
1587 } else {
1588 #endif
1589 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1590 TSXDestroyImage(This->t.xlib.image);
1591 #ifdef HAVE_LIBXXSHM
1593 #endif
1595 This->t.xlib.image = 0;
1596 } else {
1597 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1600 if (This->s.palette)
1601 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1603 /* Free the DIBSection (if any) */
1604 if (This->s.hdc != 0) {
1605 SelectObject(This->s.hdc, This->s.holdbitmap);
1606 DeleteDC(This->s.hdc);
1607 DeleteObject(This->s.DIBsection);
1610 /* Free the clipper if present */
1611 if( This->s.lpClipper )
1612 IDirectDrawClipper_Release(This->s.lpClipper);
1614 HeapFree(GetProcessHeap(),0,This);
1615 return S_OK;
1618 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1619 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1621 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1622 int i,found = 0,xstart;
1623 struct _surface_chain *chain;
1625 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1626 if (TRACE_ON(ddraw)) {
1627 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1628 DPRINTF("\n");
1630 chain = This->s.chain;
1631 if (!chain)
1632 return DDERR_NOTFOUND;
1634 for (i=0;i<chain->nrofsurfaces;i++)
1635 if (chain->surfaces[i] == This)
1636 break;
1638 xstart = i;
1639 for (i=0;i<chain->nrofsurfaces;i++) {
1640 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1641 #if 0
1642 if (found) /* may not find the same caps twice, (doc) */
1643 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1644 #endif
1645 found = (i+1)+xstart;
1648 if (!found)
1649 return DDERR_NOTFOUND;
1650 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1651 /* FIXME: AddRef? */
1652 TRACE("found %p\n",*lpdsf);
1653 return DD_OK;
1656 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1657 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1659 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1660 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1662 return DDERR_ALREADYINITIALIZED;
1665 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1666 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1668 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1669 TRACE("(%p)->(%p)\n",This,pf);
1671 *pf = This->s.surface_desc.ddpfPixelFormat;
1672 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1673 return DD_OK;
1676 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1677 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1678 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1679 return DD_OK;
1682 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1683 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1685 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1686 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1687 return DD_OK;
1690 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1691 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
1693 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1694 TRACE("(%p)->(%p)!\n",This,lpClipper);
1696 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
1697 This->s.lpClipper = lpClipper;
1698 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
1699 return DD_OK;
1702 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1703 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1705 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1706 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1707 int i;
1708 struct _surface_chain *chain;
1710 FIXME("(%p)->(%p)\n",This,surf);
1711 chain = This->s.chain;
1713 /* IDirectDrawSurface4_AddRef(surf); */
1715 if (chain) {
1716 for (i=0;i<chain->nrofsurfaces;i++)
1717 if (chain->surfaces[i] == isurf)
1718 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1719 } else {
1720 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1721 chain->nrofsurfaces = 1;
1722 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1723 chain->surfaces[0] = This;
1724 This->s.chain = chain;
1727 if (chain->surfaces)
1728 chain->surfaces = HeapReAlloc(
1729 GetProcessHeap(),
1731 chain->surfaces,
1732 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1734 else
1735 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1736 isurf->s.chain = chain;
1737 chain->surfaces[chain->nrofsurfaces++] = isurf;
1738 return DD_OK;
1741 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1742 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1743 DDSURFACEDESC desc;
1744 BITMAPINFO *b_info;
1745 UINT usage;
1747 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1749 /* Creates a DIB Section of the same size / format as the surface */
1750 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1752 if (This->s.hdc == 0) {
1753 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1754 case 16:
1755 case 32:
1756 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1757 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1758 break;
1759 #endif
1761 case 24:
1762 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1763 break;
1765 default:
1766 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1767 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1768 break;
1771 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1772 b_info->bmiHeader.biWidth = desc.dwWidth;
1773 b_info->bmiHeader.biHeight = desc.dwHeight;
1774 b_info->bmiHeader.biPlanes = 1;
1775 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1776 #if 0
1777 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1778 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1779 #endif
1780 b_info->bmiHeader.biCompression = BI_RGB;
1781 #if 0
1782 else
1783 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1784 #endif
1785 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1786 b_info->bmiHeader.biXPelsPerMeter = 0;
1787 b_info->bmiHeader.biYPelsPerMeter = 0;
1788 b_info->bmiHeader.biClrUsed = 0;
1789 b_info->bmiHeader.biClrImportant = 0;
1791 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1792 case 16:
1793 case 32:
1794 #if 0
1796 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1798 usage = 0;
1799 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1800 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1801 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1803 break;
1804 #endif
1805 case 24:
1806 /* Nothing to do */
1807 usage = DIB_RGB_COLORS;
1808 break;
1810 default: {
1811 int i;
1813 /* Fill the palette */
1814 usage = DIB_RGB_COLORS;
1816 if (This->s.palette == NULL) {
1817 ERR("Bad palette !!!\n");
1818 } else {
1819 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1820 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1822 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1823 rgb[i].rgbBlue = pent[i].peBlue;
1824 rgb[i].rgbRed = pent[i].peRed;
1825 rgb[i].rgbGreen = pent[i].peGreen;
1829 break;
1831 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1832 b_info,
1833 usage,
1834 &(This->s.bitmap_data),
1838 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1839 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1841 /* b_info is not useful anymore */
1842 HeapFree(GetProcessHeap(), 0, b_info);
1844 /* Create the DC */
1845 This->s.hdc = CreateCompatibleDC(0);
1846 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1849 /* Copy our surface in the DIB section */
1850 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1851 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1852 else
1853 /* TODO */
1854 FIXME("This case has to be done :/\n");
1856 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1857 *lphdc = This->s.hdc;
1859 return DD_OK;
1862 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1863 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1865 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1866 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1867 /* Copy the DIB section to our surface */
1868 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1869 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1870 } else {
1871 /* TODO */
1872 FIXME("This case has to be done :/\n");
1874 /* Unlock the surface */
1875 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1876 return DD_OK;
1879 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1880 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1882 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
1884 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1885 * the same interface. And IUnknown does that too of course.
1887 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1888 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1889 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1890 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1891 IsEqualGUID( &IID_IUnknown, refiid )
1893 *obj = This;
1894 IDirectDrawSurface4_AddRef(iface);
1896 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1897 return S_OK;
1899 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1901 /* Texture interface */
1902 *obj = d3dtexture2_create(This);
1903 IDirectDrawSurface4_AddRef(iface);
1904 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1905 return S_OK;
1907 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1909 /* Texture interface */
1910 *obj = d3dtexture_create(This);
1911 IDirectDrawSurface4_AddRef(iface);
1913 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1915 return S_OK;
1917 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1918 /* It is the OpenGL Direct3D Device */
1919 IDirectDrawSurface4_AddRef(iface);
1920 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1921 return S_OK;
1924 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
1925 return OLE_E_ENUM_NOMORE;
1928 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1929 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1930 TRACE("(%p)->(), stub!\n",This);
1931 return DD_OK; /* hmm */
1934 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1935 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1936 int i;
1937 struct _surface_chain *chain = This->s.chain;
1939 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1940 for (i=0;i<chain->nrofsurfaces;i++) {
1941 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1942 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1943 return DD_OK; /* FIXME: return value correct? */
1945 return DD_OK;
1948 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1949 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1950 FIXME("(%p)->(),stub!\n",This);
1951 return DD_OK;
1954 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1955 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1957 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1958 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1959 if (TRACE_ON(ddraw)) {
1960 _dump_colorkeyflag(dwFlags);
1961 DPRINTF(" : ");
1962 _dump_DDCOLORKEY((void *) ckey);
1963 DPRINTF("\n");
1966 /* If this surface was loaded as a texture, call also the texture
1967 SetColorKey callback */
1968 if (This->s.texture) {
1969 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1972 if( dwFlags & DDCKEY_SRCBLT )
1974 dwFlags &= ~DDCKEY_SRCBLT;
1975 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1976 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1979 if( dwFlags & DDCKEY_DESTBLT )
1981 dwFlags &= ~DDCKEY_DESTBLT;
1982 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1983 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1986 if( dwFlags & DDCKEY_SRCOVERLAY )
1988 dwFlags &= ~DDCKEY_SRCOVERLAY;
1989 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1990 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1993 if( dwFlags & DDCKEY_DESTOVERLAY )
1995 dwFlags &= ~DDCKEY_DESTOVERLAY;
1996 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1997 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
2000 if( dwFlags )
2002 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2005 return DD_OK;
2009 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
2010 LPDIRECTDRAWSURFACE4 iface,
2011 LPRECT lpRect )
2013 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2014 FIXME("(%p)->(%p),stub!\n",This,lpRect);
2016 return DD_OK;
2019 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
2020 LPDIRECTDRAWSURFACE4 iface,
2021 DWORD dwFlags,
2022 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
2024 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2025 int i;
2026 struct _surface_chain *chain;
2028 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
2029 chain = This->s.chain;
2030 for (i=0;i<chain->nrofsurfaces;i++) {
2031 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
2032 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
2034 chain->surfaces[i]->s.chain = NULL;
2035 memcpy( chain->surfaces+i,
2036 chain->surfaces+(i+1),
2037 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
2039 chain->surfaces = HeapReAlloc(
2040 GetProcessHeap(),
2042 chain->surfaces,
2043 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
2045 chain->nrofsurfaces--;
2046 return DD_OK;
2049 return DD_OK;
2052 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
2053 LPDIRECTDRAWSURFACE4 iface,
2054 DWORD dwFlags,
2055 LPVOID lpContext,
2056 LPDDENUMSURFACESCALLBACK lpfnCallback )
2058 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2059 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
2060 lpContext, lpfnCallback );
2062 return DD_OK;
2065 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
2066 LPDIRECTDRAWSURFACE4 iface,
2067 LPDIRECTDRAWCLIPPER* lplpDDClipper )
2069 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2070 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
2072 return DD_OK;
2075 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
2076 LPDIRECTDRAWSURFACE4 iface,
2077 DWORD dwFlags,
2078 LPDDCOLORKEY lpDDColorKey )
2080 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2081 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
2083 if( dwFlags & DDCKEY_SRCBLT ) {
2084 dwFlags &= ~DDCKEY_SRCBLT;
2085 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
2088 if( dwFlags & DDCKEY_DESTBLT )
2090 dwFlags &= ~DDCKEY_DESTBLT;
2091 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
2094 if( dwFlags & DDCKEY_SRCOVERLAY )
2096 dwFlags &= ~DDCKEY_SRCOVERLAY;
2097 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
2100 if( dwFlags & DDCKEY_DESTOVERLAY )
2102 dwFlags &= ~DDCKEY_DESTOVERLAY;
2103 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
2106 if( dwFlags )
2108 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2111 return DD_OK;
2114 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
2115 LPDIRECTDRAWSURFACE4 iface,
2116 DWORD dwFlags )
2118 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2119 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2121 return DD_OK;
2124 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
2125 LPDIRECTDRAWSURFACE4 iface,
2126 LPDIRECTDRAWPALETTE* lplpDDPalette )
2128 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2129 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
2131 if (This->s.palette != NULL) {
2132 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
2134 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
2135 return DD_OK;
2136 } else {
2137 return DDERR_NOPALETTEATTACHED;
2141 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
2142 LPDIRECTDRAWSURFACE4 iface,
2143 LONG lX,
2144 LONG lY)
2146 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2147 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
2149 return DD_OK;
2152 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
2153 LPDIRECTDRAWSURFACE4 iface,
2154 LPRECT lpSrcRect,
2155 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
2156 LPRECT lpDestRect,
2157 DWORD dwFlags,
2158 LPDDOVERLAYFX lpDDOverlayFx )
2160 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2161 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
2162 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
2164 return DD_OK;
2167 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
2168 LPDIRECTDRAWSURFACE4 iface,
2169 DWORD dwFlags )
2171 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2172 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2174 return DD_OK;
2177 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2178 LPDIRECTDRAWSURFACE4 iface,
2179 DWORD dwFlags,
2180 LPDIRECTDRAWSURFACE4 lpDDSReference )
2182 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2183 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2185 return DD_OK;
2188 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2189 LPDIRECTDRAWSURFACE4 iface,
2190 LPVOID* lplpDD )
2192 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2193 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2195 /* Not sure about that... */
2196 *lplpDD = (void *) This->s.ddraw;
2198 return DD_OK;
2201 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2202 LPDIRECTDRAWSURFACE4 iface,
2203 DWORD dwFlags )
2205 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2206 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2208 return DD_OK;
2211 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2212 LPDIRECTDRAWSURFACE4 iface,
2213 DWORD dwFlags )
2215 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2216 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2218 return DD_OK;
2221 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2222 LPDIRECTDRAWSURFACE4 iface,
2223 LPDDSURFACEDESC lpDDSD,
2224 DWORD dwFlags )
2226 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2227 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2229 return DD_OK;
2232 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2233 REFGUID guidTag,
2234 LPVOID lpData,
2235 DWORD cbSize,
2236 DWORD dwFlags) {
2237 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2238 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2240 return DD_OK;
2243 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2244 REFGUID guidTag,
2245 LPVOID lpBuffer,
2246 LPDWORD lpcbBufferSize) {
2247 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2248 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2250 return DD_OK;
2253 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2254 REFGUID guidTag) {
2255 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2256 FIXME("(%p)->(%p)\n", This, guidTag);
2258 return DD_OK;
2261 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2262 LPDWORD lpValue) {
2263 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2264 FIXME("(%p)->(%p)\n", This, lpValue);
2266 return DD_OK;
2269 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2270 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2271 FIXME("(%p)\n", This);
2273 return DD_OK;
2276 #ifdef HAVE_LIBXXF86DGA
2277 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2279 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2280 IDirectDrawSurface4Impl_QueryInterface,
2281 IDirectDrawSurface4Impl_AddRef,
2282 DGA_IDirectDrawSurface4Impl_Release,
2283 IDirectDrawSurface4Impl_AddAttachedSurface,
2284 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2285 IDirectDrawSurface4Impl_Blt,
2286 IDirectDrawSurface4Impl_BltBatch,
2287 IDirectDrawSurface4Impl_BltFast,
2288 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2289 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2290 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2291 DGA_IDirectDrawSurface4Impl_Flip,
2292 IDirectDrawSurface4Impl_GetAttachedSurface,
2293 IDirectDrawSurface4Impl_GetBltStatus,
2294 IDirectDrawSurface4Impl_GetCaps,
2295 IDirectDrawSurface4Impl_GetClipper,
2296 IDirectDrawSurface4Impl_GetColorKey,
2297 IDirectDrawSurface4Impl_GetDC,
2298 IDirectDrawSurface4Impl_GetFlipStatus,
2299 IDirectDrawSurface4Impl_GetOverlayPosition,
2300 IDirectDrawSurface4Impl_GetPalette,
2301 IDirectDrawSurface4Impl_GetPixelFormat,
2302 IDirectDrawSurface4Impl_GetSurfaceDesc,
2303 IDirectDrawSurface4Impl_Initialize,
2304 IDirectDrawSurface4Impl_IsLost,
2305 IDirectDrawSurface4Impl_Lock,
2306 IDirectDrawSurface4Impl_ReleaseDC,
2307 IDirectDrawSurface4Impl_Restore,
2308 IDirectDrawSurface4Impl_SetClipper,
2309 IDirectDrawSurface4Impl_SetColorKey,
2310 IDirectDrawSurface4Impl_SetOverlayPosition,
2311 DGA_IDirectDrawSurface4Impl_SetPalette,
2312 DGA_IDirectDrawSurface4Impl_Unlock,
2313 IDirectDrawSurface4Impl_UpdateOverlay,
2314 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2315 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2316 IDirectDrawSurface4Impl_GetDDInterface,
2317 IDirectDrawSurface4Impl_PageLock,
2318 IDirectDrawSurface4Impl_PageUnlock,
2319 IDirectDrawSurface4Impl_SetSurfaceDesc,
2320 IDirectDrawSurface4Impl_SetPrivateData,
2321 IDirectDrawSurface4Impl_GetPrivateData,
2322 IDirectDrawSurface4Impl_FreePrivateData,
2323 IDirectDrawSurface4Impl_GetUniquenessValue,
2324 IDirectDrawSurface4Impl_ChangeUniquenessValue
2326 #endif /* defined(HAVE_LIBXXF86DGA) */
2328 #ifdef HAVE_LIBXXF86DGA2
2329 static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
2331 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2332 IDirectDrawSurface4Impl_QueryInterface,
2333 IDirectDrawSurface4Impl_AddRef,
2334 DGA_IDirectDrawSurface4Impl_Release,
2335 IDirectDrawSurface4Impl_AddAttachedSurface,
2336 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2337 IDirectDrawSurface4Impl_Blt,
2338 IDirectDrawSurface4Impl_BltBatch,
2339 IDirectDrawSurface4Impl_BltFast,
2340 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2341 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2342 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2343 DGA2_IDirectDrawSurface4Impl_Flip,
2344 IDirectDrawSurface4Impl_GetAttachedSurface,
2345 IDirectDrawSurface4Impl_GetBltStatus,
2346 IDirectDrawSurface4Impl_GetCaps,
2347 IDirectDrawSurface4Impl_GetClipper,
2348 IDirectDrawSurface4Impl_GetColorKey,
2349 IDirectDrawSurface4Impl_GetDC,
2350 IDirectDrawSurface4Impl_GetFlipStatus,
2351 IDirectDrawSurface4Impl_GetOverlayPosition,
2352 IDirectDrawSurface4Impl_GetPalette,
2353 IDirectDrawSurface4Impl_GetPixelFormat,
2354 IDirectDrawSurface4Impl_GetSurfaceDesc,
2355 IDirectDrawSurface4Impl_Initialize,
2356 IDirectDrawSurface4Impl_IsLost,
2357 IDirectDrawSurface4Impl_Lock,
2358 IDirectDrawSurface4Impl_ReleaseDC,
2359 IDirectDrawSurface4Impl_Restore,
2360 IDirectDrawSurface4Impl_SetClipper,
2361 IDirectDrawSurface4Impl_SetColorKey,
2362 IDirectDrawSurface4Impl_SetOverlayPosition,
2363 DGA_IDirectDrawSurface4Impl_SetPalette,
2364 DGA_IDirectDrawSurface4Impl_Unlock,
2365 IDirectDrawSurface4Impl_UpdateOverlay,
2366 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2367 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2368 IDirectDrawSurface4Impl_GetDDInterface,
2369 IDirectDrawSurface4Impl_PageLock,
2370 IDirectDrawSurface4Impl_PageUnlock,
2371 IDirectDrawSurface4Impl_SetSurfaceDesc,
2372 IDirectDrawSurface4Impl_SetPrivateData,
2373 IDirectDrawSurface4Impl_GetPrivateData,
2374 IDirectDrawSurface4Impl_FreePrivateData,
2375 IDirectDrawSurface4Impl_GetUniquenessValue,
2376 IDirectDrawSurface4Impl_ChangeUniquenessValue
2378 #endif /* defined(HAVE_LIBXXF86DGA2) */
2380 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2382 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2383 IDirectDrawSurface4Impl_QueryInterface,
2384 IDirectDrawSurface4Impl_AddRef,
2385 Xlib_IDirectDrawSurface4Impl_Release,
2386 IDirectDrawSurface4Impl_AddAttachedSurface,
2387 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2388 IDirectDrawSurface4Impl_Blt,
2389 IDirectDrawSurface4Impl_BltBatch,
2390 IDirectDrawSurface4Impl_BltFast,
2391 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2392 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2393 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2394 Xlib_IDirectDrawSurface4Impl_Flip,
2395 IDirectDrawSurface4Impl_GetAttachedSurface,
2396 IDirectDrawSurface4Impl_GetBltStatus,
2397 IDirectDrawSurface4Impl_GetCaps,
2398 IDirectDrawSurface4Impl_GetClipper,
2399 IDirectDrawSurface4Impl_GetColorKey,
2400 IDirectDrawSurface4Impl_GetDC,
2401 IDirectDrawSurface4Impl_GetFlipStatus,
2402 IDirectDrawSurface4Impl_GetOverlayPosition,
2403 IDirectDrawSurface4Impl_GetPalette,
2404 IDirectDrawSurface4Impl_GetPixelFormat,
2405 IDirectDrawSurface4Impl_GetSurfaceDesc,
2406 IDirectDrawSurface4Impl_Initialize,
2407 IDirectDrawSurface4Impl_IsLost,
2408 IDirectDrawSurface4Impl_Lock,
2409 IDirectDrawSurface4Impl_ReleaseDC,
2410 IDirectDrawSurface4Impl_Restore,
2411 IDirectDrawSurface4Impl_SetClipper,
2412 IDirectDrawSurface4Impl_SetColorKey,
2413 IDirectDrawSurface4Impl_SetOverlayPosition,
2414 Xlib_IDirectDrawSurface4Impl_SetPalette,
2415 Xlib_IDirectDrawSurface4Impl_Unlock,
2416 IDirectDrawSurface4Impl_UpdateOverlay,
2417 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2418 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2419 IDirectDrawSurface4Impl_GetDDInterface,
2420 IDirectDrawSurface4Impl_PageLock,
2421 IDirectDrawSurface4Impl_PageUnlock,
2422 IDirectDrawSurface4Impl_SetSurfaceDesc,
2423 IDirectDrawSurface4Impl_SetPrivateData,
2424 IDirectDrawSurface4Impl_GetPrivateData,
2425 IDirectDrawSurface4Impl_FreePrivateData,
2426 IDirectDrawSurface4Impl_GetUniquenessValue,
2427 IDirectDrawSurface4Impl_ChangeUniquenessValue
2430 /******************************************************************************
2431 * DirectDrawCreateClipper (DDRAW.7)
2433 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2434 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2435 LPUNKNOWN pUnkOuter)
2437 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2438 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2440 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2441 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2442 (*ilplpDDClipper)->ref = 1;
2444 (*ilplpDDClipper)->hWnd = 0;
2446 return DD_OK;
2449 /******************************************************************************
2450 * IDirectDrawClipper
2452 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2453 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
2455 ICOM_THIS(IDirectDrawClipperImpl,iface);
2457 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
2458 if( dwFlags ) {
2459 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
2460 return DDERR_INVALIDPARAMS;
2463 This->hWnd = hWnd;
2464 return DD_OK;
2467 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2468 ICOM_THIS(IDirectDrawClipperImpl,iface);
2469 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2471 This->ref--;
2472 if (This->ref)
2473 return This->ref;
2474 HeapFree(GetProcessHeap(),0,This);
2475 return S_OK;
2478 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2479 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2481 ICOM_THIS(IDirectDrawClipperImpl,iface);
2482 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2483 if (hmm) *hmm=0;
2484 return DD_OK;
2487 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2488 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2490 ICOM_THIS(IDirectDrawClipperImpl,iface);
2491 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2492 return DD_OK;
2495 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2496 LPDIRECTDRAWCLIPPER iface,
2497 REFIID riid,
2498 LPVOID* ppvObj )
2500 ICOM_THIS(IDirectDrawClipperImpl,iface);
2501 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2502 return OLE_E_ENUM_NOMORE;
2505 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2507 ICOM_THIS(IDirectDrawClipperImpl,iface);
2508 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2509 return ++(This->ref);
2512 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2513 LPDIRECTDRAWCLIPPER iface,
2514 HWND* hWndPtr )
2516 ICOM_THIS(IDirectDrawClipperImpl,iface);
2517 FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
2519 *hWndPtr = This->hWnd;
2521 return DD_OK;
2524 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2525 LPDIRECTDRAWCLIPPER iface,
2526 LPDIRECTDRAW lpDD,
2527 DWORD dwFlags )
2529 ICOM_THIS(IDirectDrawClipperImpl,iface);
2530 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2531 return DD_OK;
2534 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2535 LPDIRECTDRAWCLIPPER iface,
2536 BOOL* lpbChanged )
2538 ICOM_THIS(IDirectDrawClipperImpl,iface);
2539 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2540 return DD_OK;
2543 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2545 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2546 IDirectDrawClipperImpl_QueryInterface,
2547 IDirectDrawClipperImpl_AddRef,
2548 IDirectDrawClipperImpl_Release,
2549 IDirectDrawClipperImpl_GetClipList,
2550 IDirectDrawClipperImpl_GetHWnd,
2551 IDirectDrawClipperImpl_Initialize,
2552 IDirectDrawClipperImpl_IsClipListChanged,
2553 IDirectDrawClipperImpl_SetClipList,
2554 IDirectDrawClipperImpl_SetHwnd
2558 /******************************************************************************
2559 * IDirectDrawPalette
2561 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2562 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2564 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2565 int i;
2567 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2568 This,x,start,count,palent);
2570 /* No palette created and not in depth-convertion mode -> BUG ! */
2571 if ((This->cm == None) &&
2572 (This->ddraw->d.palette_convert == NULL))
2574 FIXME("app tried to read colormap for non-palettized mode\n");
2575 return DDERR_GENERIC;
2577 for (i=0;i<count;i++) {
2578 palent[i].peRed = This->palents[start+i].peRed;
2579 palent[i].peBlue = This->palents[start+i].peBlue;
2580 palent[i].peGreen = This->palents[start+i].peGreen;
2581 palent[i].peFlags = This->palents[start+i].peFlags;
2584 return DD_OK;
2587 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2588 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2590 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2591 XColor xc;
2592 int i;
2594 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2595 This,x,start,count,palent
2597 for (i=0;i<count;i++) {
2598 xc.red = palent[i].peRed<<8;
2599 xc.blue = palent[i].peBlue<<8;
2600 xc.green = palent[i].peGreen<<8;
2601 xc.flags = DoRed|DoBlue|DoGreen;
2602 xc.pixel = start+i;
2604 if (This->cm)
2605 TSXStoreColor(display,This->cm,&xc);
2607 This->palents[start+i].peRed = palent[i].peRed;
2608 This->palents[start+i].peBlue = palent[i].peBlue;
2609 This->palents[start+i].peGreen = palent[i].peGreen;
2610 This->palents[start+i].peFlags = palent[i].peFlags;
2613 /* Now, if we are in 'depth conversion mode', update the screen palette */
2614 /* FIXME: we need to update the image or we won't get palette fading. */
2615 if (This->ddraw->d.palette_convert != NULL)
2616 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2618 return DD_OK;
2621 #ifdef HAVE_LIBXXF86DGA
2622 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2623 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2625 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2626 XColor xc;
2627 Colormap cm;
2628 int i;
2630 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2631 This,x,start,count,palent
2633 if (!This->cm) /* should not happen */ {
2634 FIXME("app tried to set colormap in non-palettized mode\n");
2635 return DDERR_GENERIC;
2637 /* FIXME: free colorcells instead of freeing whole map */
2638 cm = This->cm;
2639 This->cm = TSXCopyColormapAndFree(display,This->cm);
2640 TSXFreeColormap(display,cm);
2642 for (i=0;i<count;i++) {
2643 xc.red = palent[i].peRed<<8;
2644 xc.blue = palent[i].peBlue<<8;
2645 xc.green = palent[i].peGreen<<8;
2646 xc.flags = DoRed|DoBlue|DoGreen;
2647 xc.pixel = i+start;
2649 TSXStoreColor(display,This->cm,&xc);
2651 This->palents[start+i].peRed = palent[i].peRed;
2652 This->palents[start+i].peBlue = palent[i].peBlue;
2653 This->palents[start+i].peGreen = palent[i].peGreen;
2654 This->palents[start+i].peFlags = palent[i].peFlags;
2656 #ifdef HAVE_LIBXXF86DGA2
2657 if (This->ddraw->e.dga.version == 2)
2658 TSXDGAInstallColormap(display,DefaultScreen(display),This->cm);
2659 else
2660 #endif /* defined(HAVE_LIBXXF86DGA2) */
2661 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2662 return DD_OK;
2664 #endif /* defined(HAVE_LIBXXF86DGA) */
2666 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2667 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2668 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2669 if (!--(This->ref)) {
2670 if (This->cm) {
2671 TSXFreeColormap(display,This->cm);
2672 This->cm = 0;
2674 HeapFree(GetProcessHeap(),0,This);
2675 return S_OK;
2677 return This->ref;
2680 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2681 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2683 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2684 return ++(This->ref);
2687 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2688 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2690 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2691 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2693 return DDERR_ALREADYINITIALIZED;
2696 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2697 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2699 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2700 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2701 return DD_OK;
2704 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2705 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2707 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2709 FIXME("(%p)->(%s,%p) stub.\n",This,debugstr_guid(refiid),obj);
2711 return S_OK;
2714 #ifdef HAVE_LIBXXF86DGA
2715 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2717 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2718 IDirectDrawPaletteImpl_QueryInterface,
2719 IDirectDrawPaletteImpl_AddRef,
2720 IDirectDrawPaletteImpl_Release,
2721 IDirectDrawPaletteImpl_GetCaps,
2722 IDirectDrawPaletteImpl_GetEntries,
2723 IDirectDrawPaletteImpl_Initialize,
2724 DGA_IDirectDrawPaletteImpl_SetEntries
2726 #endif /* defined(HAVE_LIBXXF86DGA) */
2728 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2730 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2731 IDirectDrawPaletteImpl_QueryInterface,
2732 IDirectDrawPaletteImpl_AddRef,
2733 IDirectDrawPaletteImpl_Release,
2734 IDirectDrawPaletteImpl_GetCaps,
2735 IDirectDrawPaletteImpl_GetEntries,
2736 IDirectDrawPaletteImpl_Initialize,
2737 Xlib_IDirectDrawPaletteImpl_SetEntries
2740 /*******************************************************************************
2741 * IDirect3D
2743 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2744 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2746 ICOM_THIS(IDirect3DImpl,iface);
2747 /* FIXME: Not sure if this is correct */
2749 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2750 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2751 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2752 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2753 *obj = This->ddraw;
2754 IDirect3D_AddRef(iface);
2756 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2758 return S_OK;
2760 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2761 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2762 *obj = This;
2763 IDirect3D_AddRef(iface);
2765 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2767 return S_OK;
2769 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2770 IDirect3D2Impl* d3d;
2772 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2773 d3d->ref = 1;
2774 d3d->ddraw = This->ddraw;
2775 IDirect3D_AddRef(iface);
2776 ICOM_VTBL(d3d) = &d3d2vt;
2777 *obj = d3d;
2779 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2781 return S_OK;
2783 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2784 return OLE_E_ENUM_NOMORE;
2787 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2788 ICOM_THIS(IDirect3DImpl,iface);
2789 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2791 return ++(This->ref);
2794 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2796 ICOM_THIS(IDirect3DImpl,iface);
2797 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2799 if (!--(This->ref)) {
2800 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2801 HeapFree(GetProcessHeap(),0,This);
2802 return S_OK;
2804 return This->ref;
2807 static HRESULT WINAPI IDirect3DImpl_Initialize(
2808 LPDIRECT3D iface, REFIID refiid )
2810 ICOM_THIS(IDirect3DImpl,iface);
2811 /* FIXME: Not sure if this is correct */
2813 FIXME("(%p)->(%s):stub.\n",This,debugstr_guid(refiid));
2815 return DDERR_ALREADYINITIALIZED;
2818 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2819 LPD3DENUMDEVICESCALLBACK cb,
2820 LPVOID context) {
2821 ICOM_THIS(IDirect3DImpl,iface);
2822 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2824 /* Call functions defined in d3ddevices.c */
2825 if (!d3d_OpenGL_dx3(cb, context))
2826 return DD_OK;
2828 return DD_OK;
2831 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2832 LPDIRECT3DLIGHT *lplight,
2833 IUnknown *lpunk)
2835 ICOM_THIS(IDirect3DImpl,iface);
2836 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2838 /* Call the creation function that is located in d3dlight.c */
2839 *lplight = d3dlight_create_dx3(This);
2841 return DD_OK;
2844 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2845 LPDIRECT3DMATERIAL *lpmaterial,
2846 IUnknown *lpunk)
2848 ICOM_THIS(IDirect3DImpl,iface);
2849 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2851 /* Call the creation function that is located in d3dviewport.c */
2852 *lpmaterial = d3dmaterial_create(This);
2854 return DD_OK;
2857 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2858 LPDIRECT3DVIEWPORT *lpviewport,
2859 IUnknown *lpunk)
2861 ICOM_THIS(IDirect3DImpl,iface);
2862 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2864 /* Call the creation function that is located in d3dviewport.c */
2865 *lpviewport = d3dviewport_create(This);
2867 return DD_OK;
2870 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2871 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2872 LPD3DFINDDEVICERESULT lpfinddevrst)
2874 ICOM_THIS(IDirect3DImpl,iface);
2875 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2877 return DD_OK;
2880 static ICOM_VTABLE(IDirect3D) d3dvt =
2882 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2883 IDirect3DImpl_QueryInterface,
2884 IDirect3DImpl_AddRef,
2885 IDirect3DImpl_Release,
2886 IDirect3DImpl_Initialize,
2887 IDirect3DImpl_EnumDevices,
2888 IDirect3DImpl_CreateLight,
2889 IDirect3DImpl_CreateMaterial,
2890 IDirect3DImpl_CreateViewport,
2891 IDirect3DImpl_FindDevice
2894 /*******************************************************************************
2895 * IDirect3D2
2897 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2898 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2899 ICOM_THIS(IDirect3D2Impl,iface);
2901 /* FIXME: Not sure if this is correct */
2903 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2904 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2905 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2906 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2907 *obj = This->ddraw;
2908 IDirect3D2_AddRef(iface);
2910 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2912 return S_OK;
2914 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2915 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2916 *obj = This;
2917 IDirect3D2_AddRef(iface);
2919 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2921 return S_OK;
2923 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2924 IDirect3DImpl* d3d;
2926 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2927 d3d->ref = 1;
2928 d3d->ddraw = This->ddraw;
2929 IDirect3D2_AddRef(iface);
2930 ICOM_VTBL(d3d) = &d3dvt;
2931 *obj = d3d;
2933 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2935 return S_OK;
2937 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2938 return OLE_E_ENUM_NOMORE;
2941 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2942 ICOM_THIS(IDirect3D2Impl,iface);
2943 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2945 return ++(This->ref);
2948 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2949 ICOM_THIS(IDirect3D2Impl,iface);
2950 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2952 if (!--(This->ref)) {
2953 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2954 HeapFree(GetProcessHeap(),0,This);
2955 return S_OK;
2957 return This->ref;
2960 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2961 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2963 ICOM_THIS(IDirect3D2Impl,iface);
2964 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2966 /* Call functions defined in d3ddevices.c */
2967 if (!d3d_OpenGL(cb, context))
2968 return DD_OK;
2970 return DD_OK;
2973 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2974 LPDIRECT3DLIGHT *lplight,
2975 IUnknown *lpunk)
2977 ICOM_THIS(IDirect3D2Impl,iface);
2978 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2980 /* Call the creation function that is located in d3dlight.c */
2981 *lplight = d3dlight_create(This);
2983 return DD_OK;
2986 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2987 LPDIRECT3DMATERIAL2 *lpmaterial,
2988 IUnknown *lpunk)
2990 ICOM_THIS(IDirect3D2Impl,iface);
2991 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2993 /* Call the creation function that is located in d3dviewport.c */
2994 *lpmaterial = d3dmaterial2_create(This);
2996 return DD_OK;
2999 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
3000 LPDIRECT3DVIEWPORT2 *lpviewport,
3001 IUnknown *lpunk)
3003 ICOM_THIS(IDirect3D2Impl,iface);
3004 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
3006 /* Call the creation function that is located in d3dviewport.c */
3007 *lpviewport = d3dviewport2_create(This);
3009 return DD_OK;
3012 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
3013 LPD3DFINDDEVICESEARCH lpfinddevsrc,
3014 LPD3DFINDDEVICERESULT lpfinddevrst)
3016 ICOM_THIS(IDirect3D2Impl,iface);
3017 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
3019 return DD_OK;
3022 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
3023 REFCLSID rguid,
3024 LPDIRECTDRAWSURFACE surface,
3025 LPDIRECT3DDEVICE2 *device)
3027 ICOM_THIS(IDirect3D2Impl,iface);
3029 FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
3031 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
3032 IDirect3D2_AddRef(iface);
3033 return DD_OK;
3036 return DDERR_INVALIDPARAMS;
3039 static ICOM_VTABLE(IDirect3D2) d3d2vt =
3041 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3042 IDirect3D2Impl_QueryInterface,
3043 IDirect3D2Impl_AddRef,
3044 IDirect3D2Impl_Release,
3045 IDirect3D2Impl_EnumDevices,
3046 IDirect3D2Impl_CreateLight,
3047 IDirect3D2Impl_CreateMaterial,
3048 IDirect3D2Impl_CreateViewport,
3049 IDirect3D2Impl_FindDevice,
3050 IDirect3D2Impl_CreateDevice
3053 /*******************************************************************************
3054 * IDirectDraw
3057 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
3058 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
3060 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
3061 IDirectDrawSurfaceImpl* lpdsf)
3063 int bpp;
3065 /* The surface was already allocated when entering in this function */
3066 TRACE("using system memory for a surface (%p) \n", lpdsf);
3068 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
3069 /* This is a Z Buffer */
3070 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
3071 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
3072 } else {
3073 /* This is a standard image */
3074 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
3075 /* No pixel format => use DirectDraw's format */
3076 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3077 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
3079 bpp = GET_BPP(lpdsf->s.surface_desc);
3082 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
3083 /* The surface was preallocated : seems that we have nothing to do :-) */
3084 ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
3087 assert(bpp);
3088 FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf->s.surface_desc.dwWidth,lpdsf->s.surface_desc.dwHeight,bpp);
3090 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
3091 lpdsf->s.surface_desc.u1.lpSurface =
3092 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
3093 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
3095 return DD_OK;
3098 #ifdef HAVE_LIBXXF86DGA
3099 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
3100 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3102 ICOM_THIS(IDirectDraw2Impl,iface);
3103 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3104 int i, fbheight = This->e.dga.fb_height;
3106 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
3107 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3109 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3110 GetProcessHeap(),
3111 HEAP_ZERO_MEMORY,
3112 sizeof(IDirectDrawSurfaceImpl)
3114 IDirectDraw2_AddRef(iface);
3116 (*ilpdsf)->ref = 1;
3117 #ifdef HAVE_LIBXXF86DGA2
3118 if (This->e.dga.version == 2)
3119 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
3120 else
3121 #endif /* defined(HAVE_LIBXXF86DGA2) */
3122 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
3123 (*ilpdsf)->s.ddraw = This;
3124 (*ilpdsf)->s.palette = NULL;
3125 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
3126 (*ilpdsf)->s.lpClipper = NULL;
3128 /* Copy the surface description */
3129 (*ilpdsf)->s.surface_desc = *lpddsd;
3131 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3132 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3133 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3134 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3136 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3138 /* Check if this a 'primary surface' or not */
3139 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3140 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3141 /* This is THE primary surface => there is DGA-specific code */
3143 /* First, store the surface description */
3144 (*ilpdsf)->s.surface_desc = *lpddsd;
3146 /* Find a viewport */
3147 for (i=0;i<32;i++)
3148 if (!(This->e.dga.vpmask & (1<<i)))
3149 break;
3150 TRACE("using viewport %d for a primary surface\n",i);
3151 /* if i == 32 or maximum ... return error */
3152 This->e.dga.vpmask|=(1<<i);
3153 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
3154 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
3156 (*ilpdsf)->s.surface_desc.u1.lpSurface =
3157 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3159 (*ilpdsf)->t.dga.fb_height = i*fbheight;
3161 /* Add flags if there were not present */
3162 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3163 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3164 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3165 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
3166 /* We put our surface always in video memory */
3167 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3168 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3169 (*ilpdsf)->s.chain = NULL;
3171 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3172 IDirectDrawSurface4Impl* back;
3173 int bbc;
3175 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
3176 int i;
3178 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3179 GetProcessHeap(),
3180 HEAP_ZERO_MEMORY,
3181 sizeof(IDirectDrawSurface4Impl)
3183 IDirectDraw2_AddRef(iface);
3184 back->ref = 1;
3185 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
3186 for (i=0;i<32;i++)
3187 if (!(This->e.dga.vpmask & (1<<i)))
3188 break;
3189 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
3190 /* if i == 32 or maximum ... return error */
3191 This->e.dga.vpmask|=(1<<i);
3192 back->t.dga.fb_height = i*fbheight;
3193 /* Copy the surface description from the front buffer */
3194 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3195 /* Change the parameters that are not the same */
3196 back->s.surface_desc.u1.lpSurface =
3197 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3199 back->s.ddraw = This;
3200 /* Add relevant info to front and back buffers */
3201 /* FIXME: backbuffer/frontbuffer handling broken here, but
3202 * will be fixed up in _Flip().
3204 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3205 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
3206 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3207 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3208 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3211 } else {
3212 /* There is no DGA-specific code here...
3213 Go to the common surface creation function */
3214 return common_off_screen_CreateSurface(This, *ilpdsf);
3216 return DD_OK;
3218 #endif /* defined(HAVE_LIBXXF86DGA) */
3220 #ifdef HAVE_LIBXXSHM
3221 /* Error handlers for Image creation */
3222 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
3223 XShmErrorFlag = 1;
3224 return 0;
3227 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3228 XImage *img;
3229 int (*WineXHandler)(Display *, XErrorEvent *);
3231 img = TSXShmCreateImage(display,
3232 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3233 This->d.pixmap_depth,
3234 ZPixmap,
3235 NULL,
3236 &(lpdsf->t.xlib.shminfo),
3237 lpdsf->s.surface_desc.dwWidth,
3238 lpdsf->s.surface_desc.dwHeight
3241 if (img == NULL) {
3242 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3243 This->e.xlib.xshm_active = 0;
3244 return NULL;
3247 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3248 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3249 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3250 This->e.xlib.xshm_active = 0;
3251 TSXDestroyImage(img);
3252 return NULL;
3255 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3257 if (img->data == (char *) -1) {
3258 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3259 This->e.xlib.xshm_active = 0;
3260 TSXDestroyImage(img);
3261 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3262 return NULL;
3264 lpdsf->t.xlib.shminfo.readOnly = False;
3266 /* This is where things start to get trickier....
3267 * First, we flush the current X connections to be sure to catch all
3268 * non-XShm related errors
3270 TSXSync(display, False);
3271 /* Then we enter in the non-thread safe part of the tests */
3272 EnterCriticalSection( &X11DRV_CritSection );
3274 /* Reset the error flag, sets our new error handler and try to attach
3275 * the surface
3277 XShmErrorFlag = 0;
3278 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3279 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3280 XSync(display, False);
3282 /* Check the error flag */
3283 if (XShmErrorFlag) {
3284 /* An error occured */
3285 XFlush(display);
3286 XShmErrorFlag = 0;
3287 XDestroyImage(img);
3288 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3289 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3290 XSetErrorHandler(WineXHandler);
3292 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3293 This->e.xlib.xshm_active = 0;
3295 /* Leave the critical section */
3296 LeaveCriticalSection( &X11DRV_CritSection );
3297 return NULL;
3299 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3300 * this works, but it may be a bit overkill....
3302 XSetErrorHandler(WineXHandler);
3303 LeaveCriticalSection( &X11DRV_CritSection );
3305 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3307 if (This->d.pixel_convert != NULL) {
3308 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3309 GetProcessHeap(),
3310 HEAP_ZERO_MEMORY,
3311 lpdsf->s.surface_desc.dwWidth *
3312 lpdsf->s.surface_desc.dwHeight *
3313 PFGET_BPP(This->d.directdraw_pixelformat)
3315 } else {
3316 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3318 return img;
3320 #endif /* HAVE_LIBXXSHM */
3322 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3323 XImage *img = NULL;
3324 void *img_data;
3326 #ifdef HAVE_LIBXXSHM
3327 if (This->e.xlib.xshm_active)
3328 img = create_xshmimage(This, lpdsf);
3330 if (img == NULL) {
3331 #endif
3332 /* Allocate surface memory */
3333 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3334 GetProcessHeap(),HEAP_ZERO_MEMORY,
3335 lpdsf->s.surface_desc.dwWidth *
3336 lpdsf->s.surface_desc.dwHeight *
3337 PFGET_BPP(This->d.directdraw_pixelformat)
3340 if (This->d.pixel_convert != NULL) {
3341 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3342 lpdsf->s.surface_desc.dwWidth *
3343 lpdsf->s.surface_desc.dwHeight *
3344 PFGET_BPP(This->d.screen_pixelformat)
3346 } else {
3347 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3350 /* In this case, create an XImage */
3351 img = TSXCreateImage(display,
3352 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3353 This->d.pixmap_depth,
3354 ZPixmap,
3356 img_data,
3357 lpdsf->s.surface_desc.dwWidth,
3358 lpdsf->s.surface_desc.dwHeight,
3360 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3362 #ifdef HAVE_LIBXXSHM
3364 #endif
3365 if (This->d.pixel_convert != NULL)
3366 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3367 else
3368 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3369 return img;
3372 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3373 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3375 ICOM_THIS(IDirectDraw2Impl,iface);
3376 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3378 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3380 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3382 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3383 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3386 IDirectDraw2_AddRef(iface);
3388 (*ilpdsf)->s.ddraw = This;
3389 (*ilpdsf)->ref = 1;
3390 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3391 (*ilpdsf)->s.palette = NULL;
3392 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3393 (*ilpdsf)->s.lpClipper = NULL;
3395 /* Copy the surface description */
3396 (*ilpdsf)->s.surface_desc = *lpddsd;
3398 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3399 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3400 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3401 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3402 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3404 /* Check if this a 'primary surface' or not */
3405 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3406 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3407 XImage *img;
3409 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3410 /* Create the XImage */
3411 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3412 if (img == NULL)
3413 return DDERR_OUTOFMEMORY;
3414 (*ilpdsf)->t.xlib.image = img;
3416 /* Add flags if there were not present */
3417 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3418 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3419 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3420 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3421 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3423 /* Check for backbuffers */
3424 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3425 IDirectDrawSurface4Impl* back;
3426 XImage *img;
3427 int i;
3429 for (i=lpddsd->dwBackBufferCount;i--;) {
3430 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3431 GetProcessHeap(),HEAP_ZERO_MEMORY,
3432 sizeof(IDirectDrawSurface4Impl)
3435 TRACE("allocated back-buffer (%p)\n", back);
3437 IDirectDraw2_AddRef(iface);
3438 back->s.ddraw = This;
3440 back->ref = 1;
3441 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3442 /* Copy the surface description from the front buffer */
3443 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3445 /* Create the XImage */
3446 img = create_ximage(This, back);
3447 if (img == NULL)
3448 return DDERR_OUTOFMEMORY;
3449 back->t.xlib.image = img;
3451 /* Add relevant info to front and back buffers */
3452 /* FIXME: backbuffer/frontbuffer handling broken here, but
3453 * will be fixed up in _Flip().
3455 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3456 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3457 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3458 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3459 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3462 } else {
3463 /* There is no Xlib-specific code here...
3464 Go to the common surface creation function */
3465 return common_off_screen_CreateSurface(This, *ilpdsf);
3467 return DD_OK;
3470 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3471 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3473 ICOM_THIS(IDirectDraw2Impl,iface);
3474 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3475 *dst = src; /* FIXME */
3476 return DD_OK;
3480 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3481 * even when the approbiate bitmasks are not specified.
3483 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3484 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3486 ICOM_THIS(IDirectDraw2Impl,iface);
3487 int i;
3488 const struct {
3489 int mask;
3490 char *name;
3491 } flags[] = {
3492 #define FE(x) { x, #x},
3493 FE(DDSCL_FULLSCREEN)
3494 FE(DDSCL_ALLOWREBOOT)
3495 FE(DDSCL_NOWINDOWCHANGES)
3496 FE(DDSCL_NORMAL)
3497 FE(DDSCL_ALLOWMODEX)
3498 FE(DDSCL_EXCLUSIVE)
3499 FE(DDSCL_SETFOCUSWINDOW)
3500 FE(DDSCL_SETDEVICEWINDOW)
3501 FE(DDSCL_CREATEDEVICEWINDOW)
3502 #undef FE
3505 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3506 if (TRACE_ON(ddraw)) {
3507 DPRINTF(" - ");
3508 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
3509 if (flags[i].mask & cooplevel) {
3510 DPRINTF("%s ",flags[i].name);
3513 DPRINTF("\n");
3515 This->d.mainWindow = hwnd;
3517 /* This will be overwritten in the case of Full Screen mode.
3518 Windowed games could work with that :-) */
3519 if (hwnd)
3521 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3522 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3523 WIN_ReleaseWndPtr(tmpWnd);
3525 if( !This->d.drawable ) {
3526 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3527 WIN_ReleaseDesktop();
3529 TRACE("Setting drawable to %ld\n", This->d.drawable);
3532 return DD_OK;
3535 #ifdef HAVE_LIBXXF86DGA2
3536 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel(
3537 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3539 ICOM_THIS(IDirectDraw2Impl,iface);
3540 HRESULT ret;
3541 int evbase, erbase;
3543 ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel);
3545 if (This->e.dga.version != 2) {
3546 return ret;
3547 } else {
3548 if (ret != DD_OK)
3549 return ret;
3551 TSXDGAQueryExtension(display, &evbase, &erbase);
3553 /* Now, start handling of DGA events giving the handle to the DDraw window
3554 as the window for which the event will be reported */
3555 TSXDGASelectInput(display, DefaultScreen(display),
3556 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3557 X11DRV_EVENT_SetDGAStatus(hwnd, evbase);
3559 return DD_OK;
3562 #endif
3564 /* Small helper to either use the cooperative window or create a new
3565 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3567 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3568 RECT rect;
3570 /* Do destroy only our window */
3571 if (This->d.window && GetPropA(This->d.window,ddProp)) {
3572 DestroyWindow(This->d.window);
3573 This->d.window = 0;
3575 /* Sanity check cooperative window before assigning it to drawing. */
3576 if ( IsWindow(This->d.mainWindow) &&
3577 IsWindowVisible(This->d.mainWindow)
3579 /* if it does not fit, resize the cooperative window.
3580 * and hope the app likes it
3582 GetWindowRect(This->d.mainWindow,&rect);
3583 if ((((rect.right-rect.left) >= This->d.width) &&
3584 ((rect.bottom-rect.top) >= This->d.height))
3586 This->d.window = This->d.mainWindow;
3587 /* SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOOWNERZORDER); */
3588 This->d.paintable = 1;
3591 /* ... failed, create new one. */
3592 if (!This->d.window) {
3593 This->d.window = CreateWindowExA(
3595 "WINE_DirectDraw",
3596 "WINE_DirectDraw",
3597 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3598 0,0,
3599 This->d.width,
3600 This->d.height,
3604 NULL
3606 /*Store THIS with the window. We'll use it in the window procedure*/
3607 SetPropA(This->d.window,ddProp,(LONG)This);
3608 ShowWindow(This->d.window,TRUE);
3609 UpdateWindow(This->d.window);
3611 SetFocus(This->d.window);
3614 static int _common_depth_to_pixelformat(DWORD depth,
3615 DDPIXELFORMAT *pixelformat,
3616 DDPIXELFORMAT *screen_pixelformat,
3617 int *pix_depth) {
3618 XVisualInfo *vi;
3619 XPixmapFormatValues *pf;
3620 XVisualInfo vt;
3621 int nvisuals, npixmap, i;
3622 int match = 0;
3623 int index = -2;
3625 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3626 pf = XListPixmapFormats(display, &npixmap);
3628 for (i = 0; i < npixmap; i++) {
3629 if (pf[i].depth == depth) {
3630 int j;
3632 for (j = 0; j < nvisuals; j++) {
3633 if (vi[j].depth == pf[i].depth) {
3634 pixelformat->dwSize = sizeof(*pixelformat);
3635 if (depth == 8) {
3636 pixelformat->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
3637 pixelformat->u1.dwRBitMask = 0;
3638 pixelformat->u2.dwGBitMask = 0;
3639 pixelformat->u3.dwBBitMask = 0;
3640 } else {
3641 pixelformat->dwFlags = DDPF_RGB;
3642 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3643 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3644 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3646 pixelformat->dwFourCC = 0;
3647 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3648 pixelformat->u4.dwRGBAlphaBitMask= 0;
3650 *screen_pixelformat = *pixelformat;
3652 if (pix_depth != NULL)
3653 *pix_depth = vi[j].depth;
3655 match = 1;
3656 index = -1;
3658 goto clean_up_and_exit;
3662 ERR("No visual corresponding to pixmap format !\n");
3666 if (match == 0) {
3667 /* We try now to find an emulated mode */
3668 int c;
3670 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3671 if (ModeEmulations[c].dest.depth == depth) {
3672 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3673 for (i = 0; i < npixmap; i++) {
3674 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3675 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3676 int j;
3678 for (j = 0; j < nvisuals; j++) {
3679 if (vi[j].depth == pf[i].depth) {
3680 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3681 screen_pixelformat->dwFlags = DDPF_RGB;
3682 screen_pixelformat->dwFourCC = 0;
3683 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3684 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3685 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3686 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3687 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3689 pixelformat->dwSize = sizeof(*pixelformat);
3690 pixelformat->dwFourCC = 0;
3691 if (depth == 8) {
3692 pixelformat->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
3693 pixelformat->u.dwRGBBitCount = 8;
3694 pixelformat->u1.dwRBitMask = 0;
3695 pixelformat->u2.dwGBitMask = 0;
3696 pixelformat->u3.dwBBitMask = 0;
3697 } else {
3698 pixelformat->dwFlags = DDPF_RGB;
3699 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3700 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3701 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3702 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3704 pixelformat->u4.dwRGBAlphaBitMask= 0;
3706 if (pix_depth != NULL)
3707 *pix_depth = vi[j].depth;
3709 match = 2;
3710 index = c;
3712 goto clean_up_and_exit;
3715 ERR("No visual corresponding to pixmap format !\n");
3723 clean_up_and_exit:
3724 TSXFree(vi);
3725 TSXFree(pf);
3727 return index;
3730 #ifdef HAVE_LIBXXF86DGA2
3731 static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl *This, int mode) {
3732 DDPIXELFORMAT *pf = &(This->d.directdraw_pixelformat);
3734 /* Now, get the device / mode description */
3735 This->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode);
3737 This->e.dga.fb_width = This->e.dga.dev->mode.imageWidth;
3738 TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
3739 This->e.dga.fb_height = This->e.dga.dev->mode.viewportHeight;
3740 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
3741 This->e.dga.dev->data,
3742 This->e.dga.dev->mode.imageWidth,
3743 (This->e.dga.dev->mode.imageWidth *
3744 This->e.dga.dev->mode.imageHeight *
3745 (This->e.dga.dev->mode.bitsPerPixel / 8))
3747 TRACE("viewport height: %d\n", This->e.dga.dev->mode.viewportHeight);
3748 /* Get the screen dimensions as seen by Wine.
3749 In that case, it may be better to ignore the -desktop mode and return the
3750 real screen size => print a warning */
3751 This->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3752 This->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3753 This->e.dga.fb_addr = This->e.dga.dev->data;
3754 This->e.dga.fb_memsize = (This->e.dga.dev->mode.imageWidth *
3755 This->e.dga.dev->mode.imageHeight *
3756 (This->e.dga.dev->mode.bitsPerPixel / 8));
3757 This->e.dga.vpmask = 0;
3759 /* Fill the screen pixelformat */
3760 pf->dwSize = sizeof(DDPIXELFORMAT);
3761 pf->dwFourCC = 0;
3762 pf->u.dwRGBBitCount = This->e.dga.dev->mode.bitsPerPixel;
3763 if (This->e.dga.dev->mode.depth == 8) {
3764 pf->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
3765 pf->u1.dwRBitMask = 0;
3766 pf->u2.dwGBitMask = 0;
3767 pf->u3.dwBBitMask = 0;
3768 } else {
3769 pf->dwFlags = DDPF_RGB;
3770 pf->u1.dwRBitMask = This->e.dga.dev->mode.redMask;
3771 pf->u2.dwGBitMask = This->e.dga.dev->mode.greenMask;
3772 pf->u3.dwBBitMask = This->e.dga.dev->mode.blueMask;
3774 pf->u4.dwRGBAlphaBitMask= 0;
3776 This->d.screen_pixelformat = *pf;
3778 #endif /* defined(HAVE_LIBXXF86DGA2) */
3780 #ifdef HAVE_LIBXXF86DGA
3781 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3782 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3784 ICOM_THIS(IDirectDrawImpl,iface);
3785 int i,mode_count;
3787 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3789 #ifdef HAVE_LIBXXF86DGA2
3790 if (This->e.dga.version == 2) {
3791 XDGAMode *modes = This->e.dga.modes;
3792 int mode_to_use = -1;
3794 /* Search in the list a display mode that corresponds to what is requested */
3795 for (i = 0; i < This->e.dga.num_modes; i++) {
3796 if ((height == modes[i].viewportHeight) &&
3797 (width == modes[i].viewportWidth) &&
3798 (depth == modes[i].depth)) {
3799 mode_to_use = modes[i].num;
3803 if (mode_to_use < 0) {
3804 ERR("Could not find matching mode !!!\n");
3805 return DDERR_UNSUPPORTEDMODE;
3806 } else {
3807 TRACE("Using mode number %d\n", mode_to_use);
3809 TSXDGACloseFramebuffer(display, DefaultScreen(display));
3811 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
3812 ERR("Error opening the frame buffer !!!\n");
3814 return DDERR_GENERIC;
3817 /* Initialize the frame buffer */
3818 _DGA_Initialize_FrameBuffer(This, mode_to_use);
3820 /* Re-get (if necessary) the DGA events */
3821 TSXDGASelectInput(display, DefaultScreen(display),
3822 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3825 return DD_OK;
3827 #endif /* defined(HAVE_LIBXXF86DGA2) */
3829 /* We hope getting the asked for depth */
3830 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3831 /* I.e. no visual found or emulated */
3832 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3833 return DDERR_UNSUPPORTEDMODE;
3836 if (This->d.width < width) {
3837 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3838 return DDERR_UNSUPPORTEDMODE;
3840 This->d.width = width;
3841 This->d.height = height;
3843 /* adjust fb_height, so we don't overlap */
3844 if (This->e.dga.fb_height < height)
3845 This->e.dga.fb_height = height;
3846 _common_IDirectDrawImpl_SetDisplayMode(This);
3848 #ifdef HAVE_LIBXXF86VM
3849 #ifdef HAVE_LIBXXF86DGA2
3850 if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3851 #endif /* defined(HAVE_LIBXXF86DGA2) */
3853 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3854 XF86VidModeModeLine mod_tmp;
3855 /* int dotclock_tmp; */
3857 /* save original video mode and set fullscreen if available*/
3858 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3859 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3860 orig_mode->hdisplay = mod_tmp.hdisplay;
3861 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3862 orig_mode->hsyncend = mod_tmp.hsyncend;
3863 orig_mode->htotal = mod_tmp.htotal;
3864 orig_mode->vdisplay = mod_tmp.vdisplay;
3865 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3866 orig_mode->vsyncend = mod_tmp.vsyncend;
3867 orig_mode->vtotal = mod_tmp.vtotal;
3868 orig_mode->flags = mod_tmp.flags;
3869 orig_mode->private = mod_tmp.private;
3871 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3872 for (i=0;i<mode_count;i++)
3874 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3876 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3877 *vidmode = *(all_modes[i]);
3878 break;
3879 } else
3880 TSXFree(all_modes[i]->private);
3882 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3883 TSXFree(all_modes);
3885 if (!vidmode)
3886 WARN("Fullscreen mode not available!\n");
3888 if (vidmode)
3890 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3891 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3892 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3893 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3894 #endif
3897 #endif
3899 /* FIXME: this function OVERWRITES several signal handlers.
3900 * can we save them? and restore them later? In a way that
3901 * it works for the library too?
3903 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3904 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3906 #ifdef RESTORE_SIGNALS
3907 SIGNAL_Init();
3908 #endif
3909 return DD_OK;
3911 #endif /* defined(HAVE_LIBXXF86DGA) */
3913 /* *************************************
3914 16 / 15 bpp to palettized 8 bpp
3915 ************************************* */
3916 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3917 unsigned char *c_src = (unsigned char *) src;
3918 unsigned short *c_dst = (unsigned short *) dst;
3919 int y;
3921 if (palette != NULL) {
3922 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3924 for (y = height; y--; ) {
3925 #if defined(__i386__) && defined(__GNUC__)
3926 /* gcc generates slightly inefficient code for the the copy / lookup,
3927 * it generates one excess memory access (to pal) per pixel. Since
3928 * we know that pal is not modified by the memory write we can
3929 * put it into a register and reduce the number of memory accesses
3930 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3931 * (This is not guaranteed to be the fastest method.)
3933 __asm__ __volatile__(
3934 "xor %%eax,%%eax\n"
3935 "1:\n"
3936 " lodsb\n"
3937 " movw (%%edx,%%eax,2),%%ax\n"
3938 " stosw\n"
3939 " xor %%eax,%%eax\n"
3940 " loop 1b\n"
3941 : "=S" (c_src), "=D" (c_dst)
3942 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3943 : "eax", "cc", "memory"
3945 c_src+=(pitch-width);
3946 #else
3947 unsigned char * srclineend = c_src+width;
3948 while (c_src < srclineend)
3949 *c_dst++ = pal[*c_src++];
3950 c_src+=(pitch-width);
3951 #endif
3953 } else {
3954 WARN("No palette set...\n");
3955 memset(dst, 0, width * height * 2);
3958 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3959 int i;
3960 unsigned short *pal = (unsigned short *) screen_palette;
3962 for (i = 0; i < count; i++)
3963 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3964 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3965 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3967 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3968 int i;
3969 unsigned short *pal = (unsigned short *) screen_palette;
3971 for (i = 0; i < count; i++)
3972 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3973 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3974 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3977 /* *************************************
3978 24 to palettized 8 bpp
3979 ************************************* */
3980 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3981 unsigned char *c_src = (unsigned char *) src;
3982 unsigned char *c_dst = (unsigned char *) dst;
3983 int y;
3985 if (palette != NULL) {
3986 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3988 for (y = height; y--; ) {
3989 unsigned char * srclineend = c_src+width;
3990 while (c_src < srclineend ) {
3991 register long pixel = pal[*c_src++];
3992 *c_dst++ = pixel;
3993 *c_dst++ = pixel>>8;
3994 *c_dst++ = pixel>>16;
3996 c_src+=(pitch-width);
3998 } else {
3999 WARN("No palette set...\n");
4000 memset(dst, 0, width * height * 4);
4003 /* *************************************
4004 32 bpp to palettized 8 bpp
4005 ************************************* */
4006 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4007 unsigned char *c_src = (unsigned char *) src;
4008 unsigned int *c_dst = (unsigned int *) dst;
4009 int y;
4011 if (palette != NULL) {
4012 const unsigned int *pal = (unsigned int *) palette->screen_palents;
4014 for (y = height; y--; ) {
4015 #if defined(__i386__) && defined(__GNUC__)
4016 /* See comment in pixel_convert_16_to_8 */
4017 __asm__ __volatile__(
4018 "xor %%eax,%%eax\n"
4019 "1:\n"
4020 " lodsb\n"
4021 " movl (%%edx,%%eax,4),%%eax\n"
4022 " stosl\n"
4023 " xor %%eax,%%eax\n"
4024 " loop 1b\n"
4025 : "=S" (c_src), "=D" (c_dst)
4026 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
4027 : "eax", "cc", "memory"
4029 c_src+=(pitch-width);
4030 #else
4031 unsigned char * srclineend = c_src+width;
4032 while (c_src < srclineend )
4033 *c_dst++ = pal[*c_src++];
4034 c_src+=(pitch-width);
4035 #endif
4037 } else {
4038 WARN("No palette set...\n");
4039 memset(dst, 0, width * height * 4);
4043 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
4044 int i;
4045 unsigned int *pal = (unsigned int *) screen_palette;
4047 for (i = 0; i < count; i++)
4048 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
4049 (((unsigned int) palent[i].peGreen) << 8) |
4050 ((unsigned int) palent[i].peBlue));
4053 /* *************************************
4054 32 bpp to 16 bpp
4055 ************************************* */
4056 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4057 unsigned short *c_src = (unsigned short *) src;
4058 unsigned int *c_dst = (unsigned int *) dst;
4059 int y;
4061 for (y = height; y--; ) {
4062 unsigned short * srclineend = c_src+width;
4063 while (c_src < srclineend ) {
4064 *c_dst++ = (((*c_src & 0xF800) << 8) |
4065 ((*c_src & 0x07E0) << 5) |
4066 ((*c_src & 0x001F) << 3));
4067 c_src++;
4069 c_src+=((pitch/2)-width);
4074 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
4075 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
4077 ICOM_THIS(IDirectDrawImpl,iface);
4078 char buf[200];
4079 WND *tmpWnd;
4080 int c;
4082 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
4083 This, width, height, depth);
4085 switch ((c = _common_depth_to_pixelformat(depth,
4086 &(This->d.directdraw_pixelformat),
4087 &(This->d.screen_pixelformat),
4088 &(This->d.pixmap_depth)))) {
4089 case -2:
4090 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
4091 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
4092 return DDERR_UNSUPPORTEDMODE;
4094 case -1:
4095 /* No convertion */
4096 This->d.pixel_convert = NULL;
4097 This->d.palette_convert = NULL;
4098 break;
4100 default:
4101 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
4103 /* Set the depth convertion routines */
4104 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
4105 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
4108 This->d.width = width;
4109 This->d.height = height;
4111 _common_IDirectDrawImpl_SetDisplayMode(This);
4113 tmpWnd = WIN_FindWndPtr(This->d.window);
4114 This->d.paintable = 1;
4115 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
4116 WIN_ReleaseWndPtr(tmpWnd);
4118 /* We don't have a context for this window. Host off the desktop */
4119 if( !This->d.drawable )
4121 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
4122 WIN_ReleaseDesktop();
4124 TRACE("Setting drawable to %ld\n", This->d.drawable);
4126 if (get_option( "DXGrab", 0 )) {
4127 /* Confine cursor movement (risky, but the user asked for it) */
4128 TSXGrabPointer(display, This->d.drawable, True, 0, GrabModeAsync, GrabModeAsync, This->d.drawable, None, CurrentTime);
4131 return DD_OK;
4134 #ifdef HAVE_LIBXXF86DGA
4135 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
4136 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4138 ICOM_THIS(IDirectDraw2Impl,iface);
4139 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4140 if (!caps1 && !caps2)
4141 return DDERR_INVALIDPARAMS;
4142 if (caps1) {
4143 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
4144 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4145 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4147 if (caps2) {
4148 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
4149 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4150 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4152 return DD_OK;
4154 #endif /* defined(HAVE_LIBXXF86DGA) */
4156 static void fill_caps(LPDDCAPS caps) {
4157 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4158 Need to be fixed, though.. */
4159 if (caps == NULL)
4160 return;
4162 caps->dwSize = sizeof(*caps);
4163 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
4164 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
4165 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
4166 caps->dwFXCaps = 0;
4167 caps->dwFXAlphaCaps = 0;
4168 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
4169 caps->dwSVCaps = 0;
4170 caps->dwZBufferBitDepths = DDBD_16;
4171 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4172 to put textures in video memory.
4173 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4174 for example) ? */
4175 caps->dwVidMemTotal = 8192 * 1024;
4176 caps->dwVidMemFree = 8192 * 1024;
4177 /* These are all the supported capabilities of the surfaces */
4178 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
4179 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
4180 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
4181 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
4182 #ifdef HAVE_MESAGL
4183 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
4184 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
4185 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
4186 #endif
4189 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
4190 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4192 ICOM_THIS(IDirectDraw2Impl,iface);
4193 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4195 /* Put the same caps for the two capabilities */
4196 fill_caps(caps1);
4197 fill_caps(caps2);
4199 return DD_OK;
4202 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
4203 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
4205 ICOM_THIS(IDirectDraw2Impl,iface);
4206 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
4207 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4208 This,x,ilpddclip,lpunk
4210 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
4211 (*ilpddclip)->ref = 1;
4212 ICOM_VTBL(*ilpddclip) = &ddclipvt;
4213 return DD_OK;
4216 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
4217 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
4219 int size = 0;
4221 if (TRACE_ON(ddraw))
4222 _dump_paletteformat(dwFlags);
4224 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
4225 if (*lpddpal == NULL) return E_OUTOFMEMORY;
4226 (*lpddpal)->ref = 1;
4227 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
4228 (*lpddpal)->installed = 0;
4230 if (dwFlags & DDPCAPS_1BIT)
4231 size = 2;
4232 else if (dwFlags & DDPCAPS_2BIT)
4233 size = 4;
4234 else if (dwFlags & DDPCAPS_4BIT)
4235 size = 16;
4236 else if (dwFlags & DDPCAPS_8BIT)
4237 size = 256;
4238 else
4239 ERR("unhandled palette format\n");
4240 *psize = size;
4242 if (palent)
4244 /* Now, if we are in 'depth conversion mode', create the screen palette */
4245 if (This->d.palette_convert != NULL)
4246 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
4248 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
4249 } else if (This->d.palette_convert != NULL) {
4250 /* In that case, put all 0xFF */
4251 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
4254 return DD_OK;
4257 #ifdef HAVE_LIBXXF86DGA
4258 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
4259 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4261 ICOM_THIS(IDirectDraw2Impl,iface);
4262 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4263 HRESULT res;
4264 int xsize = 0,i;
4266 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4267 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4268 if (res != 0) return res;
4269 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
4270 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
4271 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
4272 } else {
4273 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4274 (*ilpddpal)->cm = 0;
4276 if (((*ilpddpal)->cm)&&xsize) {
4277 for (i=0;i<xsize;i++) {
4278 XColor xc;
4280 xc.red = (*ilpddpal)->palents[i].peRed<<8;
4281 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
4282 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
4283 xc.flags = DoRed|DoBlue|DoGreen;
4284 xc.pixel = i;
4285 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
4288 return DD_OK;
4290 #endif /* defined(HAVE_LIBXXF86DGA) */
4292 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
4293 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4295 ICOM_THIS(IDirectDraw2Impl,iface);
4296 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4297 int xsize;
4298 HRESULT res;
4300 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4301 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4302 if (res != 0) return res;
4303 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
4304 return DD_OK;
4307 #ifdef HAVE_LIBXXF86DGA
4308 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4309 ICOM_THIS(IDirectDraw2Impl,iface);
4310 TRACE("(%p)->()\n",This);
4311 Sleep(1000);
4312 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4313 #ifdef RESTORE_SIGNALS
4314 SIGNAL_Init();
4315 #endif
4316 return DD_OK;
4318 #endif /* defined(HAVE_LIBXXF86DGA) */
4320 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4321 ICOM_THIS(IDirectDraw2Impl,iface);
4322 TRACE("(%p)->RestoreDisplayMode()\n", This);
4323 Sleep(1000);
4324 return DD_OK;
4327 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
4328 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
4330 ICOM_THIS(IDirectDraw2Impl,iface);
4331 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
4332 return DD_OK;
4335 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
4336 ICOM_THIS(IDirectDraw2Impl,iface);
4337 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
4339 return ++(This->ref);
4342 #ifdef HAVE_LIBXXF86DGA
4343 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4344 ICOM_THIS(IDirectDraw2Impl,iface);
4345 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4347 if (!--(This->ref)) {
4348 #ifdef HAVE_LIBXXF86DGA2
4349 if (This->e.dga.version == 2) {
4350 TRACE("Closing access to the FrameBuffer\n");
4351 TSXDGACloseFramebuffer(display, DefaultScreen(display));
4352 TRACE("Going back to normal X mode of operation\n");
4353 TSXDGASetMode(display, DefaultScreen(display), 0);
4355 /* Set the input handling back to absolute */
4356 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
4358 /* Remove the handling of DGA2 events */
4359 X11DRV_EVENT_SetDGAStatus(0, -1);
4361 /* Free the modes list */
4362 TSXFree(This->e.dga.modes);
4363 } else
4364 #endif /* defined(HAVE_LIBXXF86DGA2) */
4365 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4366 if (This->d.window && GetPropA(This->d.window,ddProp))
4367 DestroyWindow(This->d.window);
4368 #ifdef HAVE_LIBXXF86VM
4369 if (orig_mode) {
4370 TSXF86VidModeSwitchToMode(
4371 display,
4372 DefaultScreen(display),
4373 orig_mode);
4374 if (orig_mode->privsize)
4375 TSXFree(orig_mode->private);
4376 free(orig_mode);
4377 orig_mode = NULL;
4379 #endif
4381 #ifdef RESTORE_SIGNALS
4382 SIGNAL_Init();
4383 #endif
4384 HeapFree(GetProcessHeap(),0,This);
4385 return S_OK;
4387 return This->ref;
4389 #endif /* defined(HAVE_LIBXXF86DGA) */
4391 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4392 ICOM_THIS(IDirectDraw2Impl,iface);
4393 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4395 if (!--(This->ref)) {
4396 if (This->d.window && GetPropA(This->d.window,ddProp))
4397 DestroyWindow(This->d.window);
4398 HeapFree(GetProcessHeap(),0,This);
4399 return S_OK;
4401 /* FIXME: destroy window ... */
4402 return This->ref;
4405 #ifdef HAVE_LIBXXF86DGA
4406 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4407 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4409 ICOM_THIS(IDirectDraw2Impl,iface);
4411 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4412 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4413 *obj = This;
4414 IDirectDraw2_AddRef(iface);
4416 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4418 return S_OK;
4420 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4421 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4422 IDirectDraw2_AddRef(iface);
4423 *obj = This;
4425 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4427 return S_OK;
4429 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4430 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4431 IDirectDraw2_AddRef(iface);
4432 *obj = This;
4434 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4436 return S_OK;
4438 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4439 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4440 IDirectDraw2_AddRef(iface);
4441 *obj = This;
4443 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4445 return S_OK;
4447 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4448 IDirect3DImpl* d3d;
4450 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4451 d3d->ref = 1;
4452 d3d->ddraw = (IDirectDrawImpl*)This;
4453 IDirectDraw2_AddRef(iface);
4454 ICOM_VTBL(d3d) = &d3dvt;
4455 *obj = d3d;
4457 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4459 return S_OK;
4461 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4462 IDirect3D2Impl* d3d;
4464 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4465 d3d->ref = 1;
4466 d3d->ddraw = (IDirectDrawImpl*)This;
4467 IDirectDraw2_AddRef(iface);
4468 ICOM_VTBL(d3d) = &d3d2vt;
4469 *obj = d3d;
4471 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4473 return S_OK;
4475 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4476 return OLE_E_ENUM_NOMORE;
4478 #endif /* defined(HAVE_LIBXXF86DGA) */
4480 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4481 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4483 ICOM_THIS(IDirectDraw2Impl,iface);
4485 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4486 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4487 *obj = This;
4488 IDirectDraw2_AddRef(iface);
4490 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4492 return S_OK;
4494 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4495 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4496 IDirectDraw2_AddRef(iface);
4497 *obj = This;
4499 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4501 return S_OK;
4503 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4504 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4505 IDirectDraw2_AddRef(iface);
4506 *obj = This;
4508 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4510 return S_OK;
4512 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4513 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4514 IDirectDraw2_AddRef(iface);
4515 *obj = This;
4517 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4519 return S_OK;
4521 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4522 IDirect3DImpl* d3d;
4524 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4525 d3d->ref = 1;
4526 d3d->ddraw = (IDirectDrawImpl*)This;
4527 IDirectDraw2_AddRef(iface);
4528 ICOM_VTBL(d3d) = &d3dvt;
4529 *obj = d3d;
4531 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4533 return S_OK;
4535 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4536 IDirect3D2Impl* d3d;
4538 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4539 d3d->ref = 1;
4540 d3d->ddraw = (IDirectDrawImpl*)This;
4541 IDirectDraw2_AddRef(iface);
4542 ICOM_VTBL(d3d) = &d3d2vt;
4543 *obj = d3d;
4545 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4547 return S_OK;
4549 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4550 return OLE_E_ENUM_NOMORE;
4553 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4554 LPDIRECTDRAW2 iface,BOOL *status
4556 ICOM_THIS(IDirectDraw2Impl,iface);
4557 TRACE("(%p)->(%p)\n",This,status);
4558 *status = TRUE;
4559 return DD_OK;
4562 #ifdef HAVE_LIBXXF86DGA
4563 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4564 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4566 ICOM_THIS(IDirectDraw2Impl,iface);
4567 DDSURFACEDESC ddsfd;
4568 static struct {
4569 int w,h;
4570 } modes[5] = { /* some of the usual modes */
4571 {512,384},
4572 {640,400},
4573 {640,480},
4574 {800,600},
4575 {1024,768},
4577 static int depths[4] = {8,16,24,32};
4578 int i,j;
4580 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4581 ddsfd.dwSize = sizeof(ddsfd);
4582 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4583 if (dwFlags & DDEDM_REFRESHRATES) {
4584 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4585 ddsfd.u.dwRefreshRate = 60;
4587 ddsfd.ddsCaps.dwCaps = 0;
4588 ddsfd.dwBackBufferCount = 1;
4590 #ifdef HAVE_LIBXXF86DGA2
4591 if (This->e.dga.version == 2) {
4592 XDGAMode *modes = This->e.dga.modes;
4594 ddsfd.dwFlags |= DDSD_PITCH;
4595 for (i = 0; i < This->e.dga.num_modes; i++) {
4596 if (TRACE_ON(ddraw)) {
4597 DPRINTF(" Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
4598 modes[i].num,
4599 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
4600 modes[i].viewportWidth, modes[i].viewportHeight,
4601 modes[i].depth);
4602 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
4603 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
4604 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
4605 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
4606 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
4607 DPRINTF("\n");
4609 /* Fill the pixel format */
4610 ddsfd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
4611 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4612 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4613 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = modes[i].bitsPerPixel;
4614 if (modes[i].depth == 8) {
4615 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4616 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4617 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4618 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4619 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4620 } else {
4621 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4622 ddsfd.ddpfPixelFormat.u1.dwRBitMask = modes[i].redMask;
4623 ddsfd.ddpfPixelFormat.u2.dwGBitMask = modes[i].greenMask;
4624 ddsfd.ddpfPixelFormat.u3.dwBBitMask = modes[i].blueMask;
4627 ddsfd.dwWidth = modes[i].viewportWidth;
4628 ddsfd.dwHeight = modes[i].viewportHeight;
4629 ddsfd.lPitch = modes[i].imageWidth;
4631 /* Send mode to the application */
4632 if (!modescb(&ddsfd,context)) return DD_OK;
4634 } else {
4635 #endif
4636 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4637 ddsfd.dwBackBufferCount = 1;
4638 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4639 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4640 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4641 /* FIXME: those masks would have to be set in depth > 8 */
4642 if (depths[i]==8) {
4643 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4644 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4645 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4646 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4647 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4648 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4649 } else {
4650 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4652 /* FIXME: We should query those from X itself */
4653 switch (depths[i]) {
4654 case 16:
4655 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4656 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4657 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4658 break;
4659 case 24:
4660 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4661 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4662 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4663 break;
4664 case 32:
4665 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4666 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4667 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4668 break;
4672 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4673 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4674 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4675 if (!modescb(&ddsfd,context)) return DD_OK;
4677 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4678 ddsfd.dwWidth = modes[j].w;
4679 ddsfd.dwHeight = modes[j].h;
4680 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4681 if (!modescb(&ddsfd,context)) return DD_OK;
4684 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4685 /* modeX is not standard VGA */
4687 ddsfd.dwHeight = 200;
4688 ddsfd.dwWidth = 320;
4689 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4690 if (!modescb(&ddsfd,context)) return DD_OK;
4693 #ifdef HAVE_LIBXXF86DGA2
4695 #endif
4696 return DD_OK;
4698 #endif /* defined(HAVE_LIBXXF86DGA) */
4700 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4701 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4703 ICOM_THIS(IDirectDraw2Impl,iface);
4704 XVisualInfo *vi;
4705 XPixmapFormatValues *pf;
4706 XVisualInfo vt;
4707 int xbpp = 1, nvisuals, npixmap, i, emu;
4708 int has_mode[] = { 0, 0, 0, 0 };
4709 int has_depth[] = { 8, 15, 16, 24 };
4710 DDSURFACEDESC ddsfd;
4711 static struct {
4712 int w,h;
4713 } modes[] = { /* some of the usual modes */
4714 {512,384},
4715 {640,400},
4716 {640,480},
4717 {800,600},
4718 {1024,768},
4719 {1280,1024}
4721 DWORD maxWidth, maxHeight;
4723 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4724 ddsfd.dwSize = sizeof(ddsfd);
4725 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_PITCH;
4726 if (dwFlags & DDEDM_REFRESHRATES) {
4727 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4728 ddsfd.u.dwRefreshRate = 60;
4730 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4731 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4733 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4734 pf = XListPixmapFormats(display, &npixmap);
4736 i = 0;
4737 emu = 0;
4738 while ((i < npixmap) || (emu != 4)) {
4739 int mode_index = 0;
4740 int send_mode = 0;
4741 int j;
4743 if (i < npixmap) {
4744 for (j = 0; j < 4; j++) {
4745 if (has_depth[j] == pf[i].depth) {
4746 mode_index = j;
4747 break;
4750 if (j == 4) {
4751 i++;
4752 continue;
4756 if (has_mode[mode_index] == 0) {
4757 if (mode_index == 0) {
4758 send_mode = 1;
4760 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4761 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4762 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4763 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4764 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4765 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4766 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4767 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4768 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4770 xbpp = 1;
4772 has_mode[mode_index] = 1;
4773 } else {
4774 /* All the 'true color' depths (15, 16 and 24)
4775 First, find the corresponding visual to extract the bit masks */
4776 for (j = 0; j < nvisuals; j++) {
4777 if (vi[j].depth == pf[i].depth) {
4778 ddsfd.ddsCaps.dwCaps = 0;
4779 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4780 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4781 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4782 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4783 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4784 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4785 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4786 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4788 xbpp = pf[i].bits_per_pixel/8;
4790 send_mode = 1;
4791 has_mode[mode_index] = 1;
4792 break;
4795 if (j == nvisuals)
4796 ERR("Did not find visual corresponding the the pixmap format !\n");
4799 i++;
4800 } else {
4801 /* Now to emulated modes */
4802 if (has_mode[emu] == 0) {
4803 int c;
4804 int l;
4805 int depth = has_depth[emu];
4807 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4808 if (ModeEmulations[c].dest.depth == depth) {
4809 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4810 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4811 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4812 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4813 int j;
4814 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4815 if ((vi[j].depth == pf[l].depth) &&
4816 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4817 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4818 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4819 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4820 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4821 if (depth == 8) {
4822 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4823 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4824 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4825 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4826 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4827 } else {
4828 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4829 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4830 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4831 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4832 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4834 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4835 send_mode = 1;
4838 if (send_mode == 0)
4839 ERR("No visual corresponding to pixmap format !\n");
4847 emu++;
4850 if (send_mode) {
4851 int mode;
4853 if (TRACE_ON(ddraw)) {
4854 TRACE("Enumerating with pixel format : \n");
4855 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4856 DPRINTF("\n");
4859 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4860 /* Do not enumerate modes we cannot handle anyway */
4861 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4862 break;
4864 ddsfd.dwWidth = modes[mode].w;
4865 ddsfd.dwHeight= modes[mode].h;
4866 ddsfd.lPitch = ddsfd.dwWidth * xbpp;
4868 /* Now, send the mode description to the application */
4869 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4870 if (!modescb(&ddsfd, context))
4871 goto exit_enum;
4874 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4875 /* modeX is not standard VGA */
4876 ddsfd.dwWidth = 320;
4877 ddsfd.dwHeight = 200;
4878 ddsfd.lPitch = 320 * xbpp;
4879 if (!modescb(&ddsfd, context))
4880 goto exit_enum;
4884 exit_enum:
4885 TSXFree(vi);
4886 TSXFree(pf);
4888 return DD_OK;
4891 #ifdef HAVE_LIBXXF86DGA
4892 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4893 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4895 ICOM_THIS(IDirectDraw2Impl,iface);
4896 TRACE("(%p)->(%p)\n",This,lpddsfd);
4897 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4898 lpddsfd->dwHeight = This->d.height;
4899 lpddsfd->dwWidth = This->d.width;
4900 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4901 lpddsfd->dwBackBufferCount = 2;
4902 lpddsfd->u.dwRefreshRate = 60;
4903 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4904 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4905 if (TRACE_ON(ddraw)) {
4906 _dump_surface_desc(lpddsfd);
4908 return DD_OK;
4910 #endif /* defined(HAVE_LIBXXF86DGA) */
4912 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4913 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4915 ICOM_THIS(IDirectDraw2Impl,iface);
4916 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4917 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4918 lpddsfd->dwHeight = This->d.height;
4919 lpddsfd->dwWidth = This->d.width;
4920 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4921 lpddsfd->dwBackBufferCount = 2;
4922 lpddsfd->u.dwRefreshRate = 60;
4923 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4924 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4925 if (TRACE_ON(ddraw)) {
4926 _dump_surface_desc(lpddsfd);
4928 return DD_OK;
4931 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4932 ICOM_THIS(IDirectDraw2Impl,iface);
4933 TRACE("(%p)->()\n",This);
4934 return DD_OK;
4937 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4938 LPDIRECTDRAW2 iface,LPDWORD freq
4940 ICOM_THIS(IDirectDraw2Impl,iface);
4941 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4942 *freq = 60*100; /* 60 Hz */
4943 return DD_OK;
4946 /* what can we directly decompress? */
4947 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4948 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4950 ICOM_THIS(IDirectDraw2Impl,iface);
4951 FIXME("(%p,%p,%p), stub\n",This,x,y);
4952 return DD_OK;
4955 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4956 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4958 ICOM_THIS(IDirectDraw2Impl,iface);
4959 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4960 return DD_OK;
4963 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4964 LPDIRECTDRAW2 iface )
4966 ICOM_THIS(IDirectDraw2Impl,iface);
4967 FIXME("(%p)->()\n", This );
4969 return DD_OK;
4972 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4973 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4974 ICOM_THIS(IDirectDraw2Impl,iface);
4975 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4977 return DD_OK;
4980 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4981 LPDWORD lpdwScanLine) {
4982 ICOM_THIS(IDirectDraw2Impl,iface);
4983 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4985 if (lpdwScanLine)
4986 *lpdwScanLine = 0;
4987 return DD_OK;
4990 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4991 GUID *lpGUID) {
4992 ICOM_THIS(IDirectDraw2Impl,iface);
4993 FIXME("(%p)->(%p)\n", This, lpGUID);
4995 return DD_OK;
4998 #ifdef HAVE_LIBXXF86DGA
5000 /* Note: Hack so we can reuse the old functions without compiler warnings */
5001 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5002 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
5003 #else
5004 # define XCAST(fun) (void *)
5005 #endif
5007 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
5009 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5010 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5011 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5012 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5013 XCAST(Compact)IDirectDraw2Impl_Compact,
5014 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5015 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5016 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5017 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5018 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5019 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5020 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5021 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5022 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5023 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5024 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5025 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5026 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5027 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5028 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5029 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5030 #ifdef HAVE_LIBXXF86DGA2
5031 XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
5032 #else
5033 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5034 #endif
5035 DGA_IDirectDrawImpl_SetDisplayMode,
5036 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5039 #undef XCAST
5041 #endif /* defined(HAVE_LIBXXF86DGA) */
5043 /* Note: Hack so we can reuse the old functions without compiler warnings */
5044 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5045 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
5046 #else
5047 # define XCAST(fun) (void *)
5048 #endif
5050 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
5052 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5053 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5054 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5055 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5056 XCAST(Compact)IDirectDraw2Impl_Compact,
5057 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5058 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5059 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5060 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5061 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5062 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5063 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5064 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5065 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5066 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5067 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5068 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5069 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5070 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5071 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5072 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5073 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5074 Xlib_IDirectDrawImpl_SetDisplayMode,
5075 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5078 #undef XCAST
5080 /*****************************************************************************
5081 * IDirectDraw2
5085 #ifdef HAVE_LIBXXF86DGA
5086 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
5087 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
5089 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5090 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5092 #endif /* defined(HAVE_LIBXXF86DGA) */
5094 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
5095 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
5097 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5098 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5101 #ifdef HAVE_LIBXXF86DGA
5102 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
5103 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5105 ICOM_THIS(IDirectDraw2Impl,iface);
5106 TRACE("(%p)->(%p,%p,%p)\n",
5107 This,ddscaps,total,free
5109 if (total) *total = This->e.dga.fb_memsize * 1024;
5110 if (free) *free = This->e.dga.fb_memsize * 1024;
5111 return DD_OK;
5113 #endif /* defined(HAVE_LIBXXF86DGA) */
5115 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
5116 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5118 ICOM_THIS(IDirectDraw2Impl,iface);
5119 TRACE("(%p)->(%p,%p,%p)\n",
5120 This,ddscaps,total,free
5122 if (total) *total = 2048 * 1024;
5123 if (free) *free = 2048 * 1024;
5124 return DD_OK;
5127 #ifdef HAVE_LIBXXF86DGA
5128 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
5130 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5131 DGA_IDirectDraw2Impl_QueryInterface,
5132 IDirectDraw2Impl_AddRef,
5133 DGA_IDirectDraw2Impl_Release,
5134 IDirectDraw2Impl_Compact,
5135 IDirectDraw2Impl_CreateClipper,
5136 DGA_IDirectDraw2Impl_CreatePalette,
5137 DGA_IDirectDraw2Impl_CreateSurface,
5138 IDirectDraw2Impl_DuplicateSurface,
5139 DGA_IDirectDraw2Impl_EnumDisplayModes,
5140 IDirectDraw2Impl_EnumSurfaces,
5141 IDirectDraw2Impl_FlipToGDISurface,
5142 DGA_IDirectDraw2Impl_GetCaps,
5143 DGA_IDirectDraw2Impl_GetDisplayMode,
5144 IDirectDraw2Impl_GetFourCCCodes,
5145 IDirectDraw2Impl_GetGDISurface,
5146 IDirectDraw2Impl_GetMonitorFrequency,
5147 IDirectDraw2Impl_GetScanLine,
5148 IDirectDraw2Impl_GetVerticalBlankStatus,
5149 IDirectDraw2Impl_Initialize,
5150 DGA_IDirectDraw2Impl_RestoreDisplayMode,
5151 IDirectDraw2Impl_SetCooperativeLevel,
5152 DGA_IDirectDraw2Impl_SetDisplayMode,
5153 IDirectDraw2Impl_WaitForVerticalBlank,
5154 DGA_IDirectDraw2Impl_GetAvailableVidMem
5156 #endif /* defined(HAVE_LIBXXF86DGA) */
5158 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
5160 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5161 Xlib_IDirectDraw2Impl_QueryInterface,
5162 IDirectDraw2Impl_AddRef,
5163 Xlib_IDirectDraw2Impl_Release,
5164 IDirectDraw2Impl_Compact,
5165 IDirectDraw2Impl_CreateClipper,
5166 Xlib_IDirectDraw2Impl_CreatePalette,
5167 Xlib_IDirectDraw2Impl_CreateSurface,
5168 IDirectDraw2Impl_DuplicateSurface,
5169 Xlib_IDirectDraw2Impl_EnumDisplayModes,
5170 IDirectDraw2Impl_EnumSurfaces,
5171 IDirectDraw2Impl_FlipToGDISurface,
5172 Xlib_IDirectDraw2Impl_GetCaps,
5173 Xlib_IDirectDraw2Impl_GetDisplayMode,
5174 IDirectDraw2Impl_GetFourCCCodes,
5175 IDirectDraw2Impl_GetGDISurface,
5176 IDirectDraw2Impl_GetMonitorFrequency,
5177 IDirectDraw2Impl_GetScanLine,
5178 IDirectDraw2Impl_GetVerticalBlankStatus,
5179 IDirectDraw2Impl_Initialize,
5180 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5181 IDirectDraw2Impl_SetCooperativeLevel,
5182 Xlib_IDirectDraw2Impl_SetDisplayMode,
5183 IDirectDraw2Impl_WaitForVerticalBlank,
5184 Xlib_IDirectDraw2Impl_GetAvailableVidMem
5187 /*****************************************************************************
5188 * IDirectDraw4
5192 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
5193 HDC hdc,
5194 LPDIRECTDRAWSURFACE *lpDDS) {
5195 ICOM_THIS(IDirectDraw4Impl,iface);
5196 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
5198 return DD_OK;
5201 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
5202 ICOM_THIS(IDirectDraw4Impl,iface);
5203 FIXME("(%p)->()\n", This);
5205 return DD_OK;
5208 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
5209 ICOM_THIS(IDirectDraw4Impl,iface);
5210 FIXME("(%p)->()\n", This);
5212 return DD_OK;
5215 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5216 LPDDDEVICEIDENTIFIER lpdddi,
5217 DWORD dwFlags) {
5218 ICOM_THIS(IDirectDraw4Impl,iface);
5219 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5221 return DD_OK;
5224 #ifdef HAVE_LIBXXF86DGA
5226 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5227 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5228 #else
5229 # define XCAST(fun) (void*)
5230 #endif
5232 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5234 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5235 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5236 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5237 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5238 XCAST(Compact)IDirectDraw2Impl_Compact,
5239 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5240 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5241 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5242 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5243 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5244 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5245 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5246 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5247 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5248 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5249 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5250 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5251 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5252 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5253 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5254 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5255 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5256 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5257 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5258 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5259 IDirectDraw4Impl_GetSurfaceFromDC,
5260 IDirectDraw4Impl_RestoreAllSurfaces,
5261 IDirectDraw4Impl_TestCooperativeLevel,
5262 IDirectDraw4Impl_GetDeviceIdentifier
5265 #undef XCAST
5267 #endif /* defined(HAVE_LIBXXF86DGA) */
5269 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5270 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5271 #else
5272 # define XCAST(fun) (void*)
5273 #endif
5275 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5277 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5278 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5279 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5280 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5281 XCAST(Compact)IDirectDraw2Impl_Compact,
5282 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5283 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5284 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5285 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5286 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5287 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5288 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5289 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5290 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5291 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5292 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5293 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5294 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5295 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5296 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5297 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5298 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5299 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5300 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5301 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5302 IDirectDraw4Impl_GetSurfaceFromDC,
5303 IDirectDraw4Impl_RestoreAllSurfaces,
5304 IDirectDraw4Impl_TestCooperativeLevel,
5305 IDirectDraw4Impl_GetDeviceIdentifier
5308 #undef XCAST
5310 /******************************************************************************
5311 * DirectDrawCreate
5314 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5316 LRESULT ret;
5317 IDirectDrawImpl* ddraw = NULL;
5318 DWORD lastError;
5320 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5322 SetLastError( ERROR_SUCCESS );
5323 ddraw = (IDirectDrawImpl*)GetPropA( hwnd, ddProp );
5324 if( (!ddraw) && ( ( lastError = GetLastError() ) != ERROR_SUCCESS ))
5326 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5329 if( ddraw )
5331 /* Perform any special direct draw functions */
5332 if (msg==WM_PAINT)
5333 ddraw->d.paintable = 1;
5335 /* Now let the application deal with the rest of this */
5336 if( ddraw->d.mainWindow )
5339 /* Don't think that we actually need to call this but...
5340 might as well be on the safe side of things... */
5342 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5343 it should be the procedures of our fake window that gets called
5344 instead of those of the window provided by the application.
5345 And with this patch, mouse clicks work with Monkey Island III
5346 - Lionel */
5347 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5349 if( !ret )
5351 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5352 /* We didn't handle the message - give it to the application */
5353 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5355 ret = CallWindowProcA(tmpWnd->winproc,
5356 ddraw->d.mainWindow, msg, wParam, lParam );
5358 WIN_ReleaseWndPtr(tmpWnd);
5362 } else {
5363 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5367 else
5369 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5372 return ret;
5375 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5376 #ifdef HAVE_LIBXXF86DGA
5377 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5378 int memsize,banksize,major,minor,flags;
5379 char *addr;
5380 int depth;
5381 int dga_version;
5382 int width, height;
5384 /* Get DGA availability / version */
5385 dga_version = DDRAW_DGA_Available();
5387 if (dga_version == 0) {
5388 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5389 return DDERR_GENERIC;
5392 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5393 (*ilplpDD)->ref = 1;
5394 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5395 #ifdef HAVE_LIBXXF86DGA2
5396 if (dga_version == 1) {
5397 (*ilplpDD)->e.dga.version = 1;
5398 #endif /* defined(HAVE_LIBXXF86DGA2) */
5399 TSXF86DGAQueryVersion(display,&major,&minor);
5400 TRACE("XF86DGA is version %d.%d\n",major,minor);
5401 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5402 if (!(flags & XF86DGADirectPresent))
5403 MESSAGE("direct video is NOT PRESENT.\n");
5404 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5405 (*ilplpDD)->e.dga.fb_width = width;
5406 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5407 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5408 (*ilplpDD)->e.dga.fb_height = height;
5409 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5410 addr,width,banksize,memsize
5412 TRACE("viewport height: %d\n",height);
5413 /* Get the screen dimensions as seen by Wine.
5414 In that case, it may be better to ignore the -desktop mode and return the
5415 real screen size => print a warning */
5416 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5417 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5418 if (((*ilplpDD)->d.height != height) ||
5419 ((*ilplpDD)->d.width != width))
5420 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5421 (*ilplpDD)->e.dga.fb_addr = addr;
5422 (*ilplpDD)->e.dga.fb_memsize = memsize;
5423 (*ilplpDD)->e.dga.vpmask = 0;
5425 /* just assume the default depth is the DGA depth too */
5426 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5427 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
5428 #ifdef RESTORE_SIGNALS
5429 SIGNAL_Init();
5430 #endif
5431 #ifdef HAVE_LIBXXF86DGA2
5432 } else {
5433 XDGAMode *modes;
5434 int i, num_modes;
5435 int mode_to_use = 0;
5437 (*ilplpDD)->e.dga.version = 2;
5439 TSXDGAQueryVersion(display,&major,&minor);
5440 TRACE("XDGA is version %d.%d\n",major,minor);
5442 TRACE("Opening the frame buffer.\n");
5443 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5444 ERR("Error opening the frame buffer !!!\n");
5446 return DDERR_GENERIC;
5449 /* List all available modes */
5450 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5451 (*ilplpDD)->e.dga.modes = modes;
5452 (*ilplpDD)->e.dga.num_modes = num_modes;
5453 if (TRACE_ON(ddraw)) {
5454 TRACE("Available modes :\n");
5455 for (i = 0; i < num_modes; i++) {
5456 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5457 modes[i].num,
5458 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5459 modes[i].viewportWidth, modes[i].viewportHeight,
5460 modes[i].depth);
5461 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5462 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5463 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5464 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5465 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5466 DPRINTF("\n");
5468 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5469 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5470 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5471 mode_to_use = modes[i].num;
5475 if (mode_to_use == 0) {
5476 ERR("Could not find mode !\n");
5477 mode_to_use = 1;
5478 } else {
5479 DPRINTF("Using mode number %d\n", mode_to_use);
5482 /* Initialize the frame buffer */
5483 _DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
5484 /* Set the input handling for relative mouse movements */
5485 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5487 #endif /* defined(HAVE_LIBXXF86DGA2) */
5488 return DD_OK;
5489 #else /* defined(HAVE_LIBXXF86DGA) */
5490 return DDERR_INVALIDDIRECTDRAWGUID;
5491 #endif /* defined(HAVE_LIBXXF86DGA) */
5494 static BOOL
5495 DDRAW_XSHM_Available(void)
5497 #ifdef HAVE_LIBXXSHM
5498 if (get_option( "UseXShm", 1 ))
5500 if (TSXShmQueryExtension(display))
5502 int major, minor;
5503 Bool shpix;
5504 if (TSXShmQueryVersion(display, &major, &minor, &shpix)) return TRUE;
5507 #endif
5508 return FALSE;
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) */