Supercharged XShm implementation for DirectDraw.
[wine.git] / graphics / ddraw.c
blob804df3f0286a596eb4422368803f80d22b9dbbc4
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997-1999 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
5 */
6 /* XF86DGA:
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
10 * is running.
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
17 #include "config.h"
18 #include "winerror.h"
20 #ifndef X_DISPLAY_MISSING
22 #include "ts_xlib.h"
23 #include "ts_xutil.h"
25 #ifdef HAVE_LIBXXSHM
26 # include <sys/types.h>
27 # ifdef HAVE_SYS_IPC_H
28 # include <sys/ipc.h>
29 # endif
30 # ifdef HAVE_SYS_SHM_H
31 # include <sys/shm.h>
32 # endif
33 # include "ts_xshm.h"
34 #endif /* defined(HAVE_LIBXXSHM) */
36 #ifdef HAVE_LIBXXF86DGA
37 #include "ts_xf86dga.h"
38 #endif /* defined(HAVE_LIBXXF86DGA) */
40 #ifdef HAVE_LIBXXF86DGA2
41 #include "ts_xf86dga2.h"
42 #endif /* defined(HAVE_LIBXXF86DGA2) */
44 #ifdef HAVE_LIBXXF86VM
45 #include "ts_xf86vmode.h"
46 #endif /* defined(HAVE_LIBXXF86VM) */
48 #include "x11drv.h"
50 #include <unistd.h>
51 #include <assert.h>
52 #ifdef HAVE_SYS_SIGNAL_H
53 # include <sys/signal.h>
54 #endif
55 #include <fcntl.h>
56 #include <string.h>
57 #include <stdlib.h>
59 #include "gdi.h"
60 #include "heap.h"
61 #include "dc.h"
62 #include "win.h"
63 #include "wine/exception.h"
64 #include "ddraw.h"
65 #include "d3d.h"
66 #include "debugtools.h"
67 #include "spy.h"
68 #include "message.h"
69 #include "options.h"
70 #include "monitor.h"
72 /* This for all the enumeration and creation of D3D-related objects */
73 #include "ddraw_private.h"
74 #include "d3d_private.h"
76 DEFAULT_DEBUG_CHANNEL(ddraw)
78 /* Restore signal handlers overwritten by XF86DGA
80 #define RESTORE_SIGNALS
82 /* Get DDSCAPS of surface (shortcutmacro) */
83 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
85 /* Get the number of bytes per pixel for a given surface */
86 #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
88 #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
90 /* Where do these GUIDs come from? mkuuid.
91 * They exist solely to distinguish between the targets Wine support,
92 * and should be different than any other GUIDs in existence.
94 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
95 0xe2dcb020,
96 0xdc60,
97 0x11d1,
98 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
101 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
102 0x1574a740,
103 0xdc61,
104 0x11d1,
105 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
108 #ifdef HAVE_LIBXXF86DGA
109 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt;
110 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt;
111 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt;
112 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt;
113 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt;
114 #endif /* defined(HAVE_LIBXXF86DGA) */
116 #ifdef HAVE_LIBXXF86DGA2
117 static struct ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt;
118 #endif /* defined(HAVE_LIBXXF86DGA2) */
120 static struct ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt;
121 static struct ICOM_VTABLE(IDirectDraw) xlib_ddvt;
122 static struct ICOM_VTABLE(IDirectDraw2) xlib_dd2vt;
123 static struct ICOM_VTABLE(IDirectDraw4) xlib_dd4vt;
124 static struct ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt;
126 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
127 static struct ICOM_VTABLE(IDirect3D) d3dvt;
128 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
130 /* This is for mode-emulation */
132 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
133 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
134 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
135 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
136 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
137 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
138 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
140 typedef struct {
141 unsigned short bpp;
142 unsigned short depth;
143 unsigned int rmask;
144 unsigned int gmask;
145 unsigned int bmask;
146 } ConvertMode;
148 typedef struct {
149 void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
150 void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
151 } ConvertFuncs;
153 typedef struct {
154 ConvertMode screen, dest;
155 ConvertFuncs funcs;
156 } Convert;
158 static Convert ModeEmulations[] = {
159 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
160 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
161 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
162 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
163 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
166 #ifdef HAVE_LIBXXF86VM
167 static XF86VidModeModeInfo *orig_mode = NULL;
168 #endif
170 #ifdef HAVE_LIBXXSHM
171 static int XShmErrorFlag = 0;
172 #endif
174 static BYTE
175 DDRAW_DGA_Available(void)
177 #ifdef HAVE_LIBXXF86DGA
178 int fd, evbase, evret, majver, minver;
179 static BYTE return_value = 0xFF;
181 /* This prevents from probing X times for DGA */
182 if (return_value != 0xFF)
183 return return_value;
185 if (Options.noDGA) {
186 return_value = 0;
187 return 0;
190 /* First, query the extenstion and its version */
191 if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) {
192 return_value = 0;
193 return 0;
196 if (!TSXF86DGAQueryVersion(display,&majver,&minver)) {
197 return_value = 0;
198 return 0;
201 #ifdef HAVE_LIBXXF86DGA2
202 if (majver >= 2) {
203 /* We have DGA 2.0 available ! */
204 if (TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
205 TSXDGACloseFramebuffer(display, DefaultScreen(display));
206 return_value = 2;
207 } else {
208 return_value = 0;
211 return return_value;
212 } else {
213 #endif /* defined(HAVE_LIBXXF86DGA2) */
215 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
216 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
217 /* others. --stephenc */
218 if ((fd = open("/dev/mem", O_RDWR)) != -1)
219 close(fd);
221 if (fd != -1)
222 return_value = 1;
223 else
224 return_value = 0;
226 return return_value;
227 #ifdef HAVE_LIBXXF86DGA2
229 #endif /* defined(HAVE_LIBXXF86DGA2) */
230 #else /* defined(HAVE_LIBXXF86DGA) */
231 return 0;
232 #endif /* defined(HAVE_LIBXXF86DGA) */
235 /**********************************************************************/
237 typedef struct {
238 LPVOID lpCallback;
239 LPVOID lpContext;
240 } DirectDrawEnumerateProcData;
242 /***********************************************************************
243 * DirectDrawEnumerateExA (DDRAW.*)
245 HRESULT WINAPI DirectDrawEnumerateExA(
246 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
248 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
250 if (TRACE_ON(ddraw)) {
251 DPRINTF(" Flags : ");
252 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
253 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
254 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
255 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
256 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
257 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
258 DPRINTF("\n");
261 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
262 /* For the moment, Wine does not support any 3D only accelerators */
263 return DD_OK;
265 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
266 /* For the moment, Wine does not support any attached secondary devices */
267 return DD_OK;
270 if (DDRAW_DGA_Available()) {
271 TRACE("Enumerating DGA interface\n");
272 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
273 return DD_OK;
276 TRACE("Enumerating Xlib interface\n");
277 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
278 return DD_OK;
280 TRACE("Enumerating Default interface\n");
281 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
282 return DD_OK;
284 return DD_OK;
287 /***********************************************************************
288 * DirectDrawEnumerateExW (DDRAW.*)
291 static BOOL CALLBACK DirectDrawEnumerateExProcW(
292 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
293 LPVOID lpContext, HMONITOR hm)
295 DirectDrawEnumerateProcData *pEPD =
296 (DirectDrawEnumerateProcData *) lpContext;
297 LPWSTR lpDriverDescriptionW =
298 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
299 LPWSTR lpDriverNameW =
300 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
302 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
303 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
305 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
306 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
308 return bResult;
311 /**********************************************************************/
313 HRESULT WINAPI DirectDrawEnumerateExW(
314 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
316 DirectDrawEnumerateProcData epd;
317 epd.lpCallback = (LPVOID) lpCallback;
318 epd.lpContext = lpContext;
320 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
321 (LPVOID) &epd, 0);
324 /***********************************************************************
325 * DirectDrawEnumerateA (DDRAW.*)
328 static BOOL CALLBACK DirectDrawEnumerateProcA(
329 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
330 LPVOID lpContext, HMONITOR hm)
332 DirectDrawEnumerateProcData *pEPD =
333 (DirectDrawEnumerateProcData *) lpContext;
335 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
336 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
339 /**********************************************************************/
341 HRESULT WINAPI DirectDrawEnumerateA(
342 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
344 DirectDrawEnumerateProcData epd;
345 epd.lpCallback = (LPVOID) lpCallback;
346 epd.lpContext = lpContext;
348 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
349 (LPVOID) &epd, 0);
352 /***********************************************************************
353 * DirectDrawEnumerateW (DDRAW.*)
356 static BOOL WINAPI DirectDrawEnumerateProcW(
357 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
358 LPVOID lpContext, HMONITOR hm)
360 DirectDrawEnumerateProcData *pEPD =
361 (DirectDrawEnumerateProcData *) lpContext;
363 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
364 lpGUID, lpDriverDescription, lpDriverName,
365 pEPD->lpContext);
368 /**********************************************************************/
370 HRESULT WINAPI DirectDrawEnumerateW(
371 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
373 DirectDrawEnumerateProcData epd;
374 epd.lpCallback = (LPVOID) lpCallback;
375 epd.lpContext = lpContext;
377 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
378 (LPVOID) &epd, 0);
381 /***********************************************************************
382 * DSoundHelp (DDRAW.?)
385 /* What is this doing here? */
386 HRESULT WINAPI
387 DSoundHelp(DWORD x,DWORD y,DWORD z) {
388 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
389 return 0;
392 /******************************************************************************
393 * internal helper functions
395 static void _dump_DDBLTFX(DWORD flagmask) {
396 int i;
397 const struct {
398 DWORD mask;
399 char *name;
400 } flags[] = {
401 #define FE(x) { x, #x},
402 FE(DDBLTFX_ARITHSTRETCHY)
403 FE(DDBLTFX_MIRRORLEFTRIGHT)
404 FE(DDBLTFX_MIRRORUPDOWN)
405 FE(DDBLTFX_NOTEARING)
406 FE(DDBLTFX_ROTATE180)
407 FE(DDBLTFX_ROTATE270)
408 FE(DDBLTFX_ROTATE90)
409 FE(DDBLTFX_ZBUFFERRANGE)
410 FE(DDBLTFX_ZBUFFERBASEDEST)
411 #undef FE
413 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
414 if (flags[i].mask & flagmask) {
415 DPRINTF("%s ",flags[i].name);
418 DPRINTF("\n");
422 static void _dump_DDBLTFAST(DWORD flagmask) {
423 int i;
424 const struct {
425 DWORD mask;
426 char *name;
427 } flags[] = {
428 #define FE(x) { x, #x},
429 FE(DDBLTFAST_NOCOLORKEY)
430 FE(DDBLTFAST_SRCCOLORKEY)
431 FE(DDBLTFAST_DESTCOLORKEY)
432 FE(DDBLTFAST_WAIT)
433 #undef FE
435 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
436 if (flags[i].mask & flagmask)
437 DPRINTF("%s ",flags[i].name);
438 DPRINTF("\n");
441 static void _dump_DDBLT(DWORD flagmask) {
442 int i;
443 const struct {
444 DWORD mask;
445 char *name;
446 } flags[] = {
447 #define FE(x) { x, #x},
448 FE(DDBLT_ALPHADEST)
449 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
450 FE(DDBLT_ALPHADESTNEG)
451 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
452 FE(DDBLT_ALPHAEDGEBLEND)
453 FE(DDBLT_ALPHASRC)
454 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
455 FE(DDBLT_ALPHASRCNEG)
456 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
457 FE(DDBLT_ASYNC)
458 FE(DDBLT_COLORFILL)
459 FE(DDBLT_DDFX)
460 FE(DDBLT_DDROPS)
461 FE(DDBLT_KEYDEST)
462 FE(DDBLT_KEYDESTOVERRIDE)
463 FE(DDBLT_KEYSRC)
464 FE(DDBLT_KEYSRCOVERRIDE)
465 FE(DDBLT_ROP)
466 FE(DDBLT_ROTATIONANGLE)
467 FE(DDBLT_ZBUFFER)
468 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
469 FE(DDBLT_ZBUFFERDESTOVERRIDE)
470 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
471 FE(DDBLT_ZBUFFERSRCOVERRIDE)
472 FE(DDBLT_WAIT)
473 FE(DDBLT_DEPTHFILL)
474 #undef FE
476 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
477 if (flags[i].mask & flagmask)
478 DPRINTF("%s ",flags[i].name);
479 DPRINTF("\n");
482 static void _dump_DDSCAPS(void *in) {
483 int i;
484 const struct {
485 DWORD mask;
486 char *name;
487 } flags[] = {
488 #define FE(x) { x, #x},
489 FE(DDSCAPS_RESERVED1)
490 FE(DDSCAPS_ALPHA)
491 FE(DDSCAPS_BACKBUFFER)
492 FE(DDSCAPS_COMPLEX)
493 FE(DDSCAPS_FLIP)
494 FE(DDSCAPS_FRONTBUFFER)
495 FE(DDSCAPS_OFFSCREENPLAIN)
496 FE(DDSCAPS_OVERLAY)
497 FE(DDSCAPS_PALETTE)
498 FE(DDSCAPS_PRIMARYSURFACE)
499 FE(DDSCAPS_PRIMARYSURFACELEFT)
500 FE(DDSCAPS_SYSTEMMEMORY)
501 FE(DDSCAPS_TEXTURE)
502 FE(DDSCAPS_3DDEVICE)
503 FE(DDSCAPS_VIDEOMEMORY)
504 FE(DDSCAPS_VISIBLE)
505 FE(DDSCAPS_WRITEONLY)
506 FE(DDSCAPS_ZBUFFER)
507 FE(DDSCAPS_OWNDC)
508 FE(DDSCAPS_LIVEVIDEO)
509 FE(DDSCAPS_HWCODEC)
510 FE(DDSCAPS_MODEX)
511 FE(DDSCAPS_MIPMAP)
512 FE(DDSCAPS_RESERVED2)
513 FE(DDSCAPS_ALLOCONLOAD)
514 FE(DDSCAPS_VIDEOPORT)
515 FE(DDSCAPS_LOCALVIDMEM)
516 FE(DDSCAPS_NONLOCALVIDMEM)
517 FE(DDSCAPS_STANDARDVGAMODE)
518 FE(DDSCAPS_OPTIMIZED)
519 #undef FE
521 DWORD flagmask = *((DWORD *) in);
522 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
523 if (flags[i].mask & flagmask)
524 DPRINTF("%s ",flags[i].name);
527 static void _dump_pixelformat_flag(DWORD flagmask) {
528 int i;
529 const struct {
530 DWORD mask;
531 char *name;
532 } flags[] = {
533 #define FE(x) { x, #x},
534 FE(DDPF_ALPHAPIXELS)
535 FE(DDPF_ALPHA)
536 FE(DDPF_FOURCC)
537 FE(DDPF_PALETTEINDEXED4)
538 FE(DDPF_PALETTEINDEXEDTO8)
539 FE(DDPF_PALETTEINDEXED8)
540 FE(DDPF_RGB)
541 FE(DDPF_COMPRESSED)
542 FE(DDPF_RGBTOYUV)
543 FE(DDPF_YUV)
544 FE(DDPF_ZBUFFER)
545 FE(DDPF_PALETTEINDEXED1)
546 FE(DDPF_PALETTEINDEXED2)
547 FE(DDPF_ZPIXELS)
548 #undef FE
550 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
551 if (flags[i].mask & flagmask)
552 DPRINTF("%s ",flags[i].name);
555 static void _dump_paletteformat(DWORD dwFlags) {
556 int i;
557 const struct {
558 DWORD mask;
559 char *name;
560 } flags[] = {
561 #define FE(x) { x, #x},
562 FE(DDPCAPS_4BIT)
563 FE(DDPCAPS_8BITENTRIES)
564 FE(DDPCAPS_8BIT)
565 FE(DDPCAPS_INITIALIZE)
566 FE(DDPCAPS_PRIMARYSURFACE)
567 FE(DDPCAPS_PRIMARYSURFACELEFT)
568 FE(DDPCAPS_ALLOW256)
569 FE(DDPCAPS_VSYNC)
570 FE(DDPCAPS_1BIT)
571 FE(DDPCAPS_2BIT)
572 FE(DDPCAPS_ALPHA)
573 #undef FE
575 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
576 if (flags[i].mask & dwFlags)
577 DPRINTF("%s ",flags[i].name);
578 DPRINTF("\n");
581 static void _dump_pixelformat(void *in) {
582 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
583 char *cmd;
585 DPRINTF("( ");
586 _dump_pixelformat_flag(pf->dwFlags);
587 if (pf->dwFlags & DDPF_FOURCC) {
588 DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
590 if (pf->dwFlags & DDPF_RGB) {
591 DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount);
592 switch (pf->u.dwRGBBitCount) {
593 case 4:
594 cmd = "%1lx";
595 break;
596 case 8:
597 cmd = "%02lx";
598 break;
599 case 16:
600 cmd = "%04lx";
601 break;
602 case 24:
603 cmd = "%06lx";
604 break;
605 case 32:
606 cmd = "%08lx";
607 break;
608 default:
609 ERR("Unexpected bit depth !\n");
610 cmd = "%d";
612 DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask);
613 DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask);
614 DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask);
615 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
616 DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask);
618 if (pf->dwFlags & DDPF_ZPIXELS) {
619 DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask);
622 if (pf->dwFlags & DDPF_ZBUFFER) {
623 DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth);
625 if (pf->dwFlags & DDPF_ALPHA) {
626 DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth);
628 DPRINTF(")");
631 static void _dump_colorkeyflag(DWORD ck) {
632 int i;
633 const struct {
634 DWORD mask;
635 char *name;
636 } flags[] = {
637 #define FE(x) { x, #x},
638 FE(DDCKEY_COLORSPACE)
639 FE(DDCKEY_DESTBLT)
640 FE(DDCKEY_DESTOVERLAY)
641 FE(DDCKEY_SRCBLT)
642 FE(DDCKEY_SRCOVERLAY)
643 #undef FE
645 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
646 if (flags[i].mask & ck)
647 DPRINTF("%s ",flags[i].name);
650 static void _dump_DWORD(void *in) {
651 DPRINTF("%ld", *((DWORD *) in));
653 static void _dump_PTR(void *in) {
654 DPRINTF("%p", *((void **) in));
656 static void _dump_DDCOLORKEY(void *in) {
657 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
659 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
662 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
663 int i;
664 struct {
665 DWORD mask;
666 char *name;
667 void (*func)(void *);
668 void *elt;
669 } flags[16], *fe = flags;
670 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
671 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
672 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
673 FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
674 FE(DDSD_PITCH, _dump_DWORD, lPitch);
675 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
676 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth);
677 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
678 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
679 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
680 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
681 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
682 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
683 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount);
684 FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate);
685 FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize);
686 FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface);
687 #undef FE
689 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
690 if (flags[i].mask & lpddsd->dwFlags) {
691 DPRINTF(" - %s : ",flags[i].name);
692 flags[i].func(flags[i].elt);
693 DPRINTF("\n");
698 /******************************************************************************
699 * IDirectDrawSurface methods
701 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
702 * DDS and DDS2 use those functions. (Function calls did not change (except
703 * using different DirectDrawSurfaceX version), just added flags and functions)
706 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
707 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
709 ICOM_THIS(IDirectDrawSurface4Impl,iface);
710 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
711 This,lprect,lpddsd,flags,(DWORD)hnd);
712 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
713 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
714 This,lprect,lpddsd,flags,(DWORD)hnd);
716 /* First, copy the Surface description */
717 *lpddsd = This->s.surface_desc;
718 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
719 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
721 /* If asked only for a part, change the surface pointer */
722 if (lprect) {
723 TRACE(" lprect: %dx%d-%dx%d\n",
724 lprect->top,lprect->left,lprect->bottom,lprect->right
726 if ((lprect->top < 0) ||
727 (lprect->left < 0) ||
728 (lprect->bottom < 0) ||
729 (lprect->right < 0)) {
730 ERR(" Negative values in LPRECT !!!\n");
731 return DDERR_INVALIDPARAMS;
734 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
735 (lprect->top*This->s.surface_desc.lPitch) +
736 lprect->left*GET_BPP(This->s.surface_desc));
737 } else {
738 assert(This->s.surface_desc.u1.lpSurface);
741 /* wait for any previous operations to complete */
742 #ifdef HAVE_LIBXXSHM
743 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE) &&
744 This->s.ddraw->e.xlib.xshm_active) {
746 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
747 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
749 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
751 #endif
752 return DD_OK;
755 #ifdef HAVE_LIBXXF86DGA
756 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
757 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
759 ICOM_THIS(IDirectDrawSurface4Impl,iface);
760 TRACE("(%p)->Unlock(%p)\n",This,surface);
761 return DD_OK;
763 #endif /* defined(HAVE_LIBXXF86DGA) */
765 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
766 if (This->s.ddraw->d.pixel_convert != NULL)
767 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
768 This->t.xlib.image->data,
769 This->s.surface_desc.dwWidth,
770 This->s.surface_desc.dwHeight,
771 This->s.surface_desc.lPitch,
772 This->s.palette);
774 #ifdef HAVE_LIBXXSHM
775 if (This->s.ddraw->e.xlib.xshm_active) {
777 X11DRV_EVENT_WaitReplaceShmCompletion( &This->s.ddraw->e.xlib.xshm_compl, This->s.ddraw->d.drawable );
779 /* let WaitShmCompletions track 'em for now */
780 /* (you may want to track it again whenever you implement DX7's partial surface locking,
781 where threads have concurrent access) */
782 X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
783 TSXShmPutImage(display,
784 This->s.ddraw->d.drawable,
785 DefaultGCOfScreen(X11DRV_GetXScreen()),
786 This->t.xlib.image,
787 0, 0, 0, 0,
788 This->t.xlib.image->width,
789 This->t.xlib.image->height,
790 True);
791 /* make sure the image is transferred ASAP */
792 TSXFlush(display);
794 else
795 #endif
796 TSXPutImage( display,
797 This->s.ddraw->d.drawable,
798 DefaultGCOfScreen(X11DRV_GetXScreen()),
799 This->t.xlib.image,
800 0, 0, 0, 0,
801 This->t.xlib.image->width,
802 This->t.xlib.image->height);
805 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
806 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
808 ICOM_THIS(IDirectDrawSurface4Impl,iface);
809 TRACE("(%p)->Unlock(%p)\n",This,surface);
811 if (!This->s.ddraw->d.paintable)
812 return DD_OK;
814 /* Only redraw the screen when unlocking the buffer that is on screen */
815 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
816 Xlib_copy_surface_on_screen(This);
818 if (This->s.palette && This->s.palette->cm)
819 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
821 return DD_OK;
824 static IDirectDrawSurface4Impl* _common_find_flipto(
825 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
827 int i,j,flipable=0;
828 struct _surface_chain *chain = This->s.chain;
830 /* if there was no override flipto, look for current backbuffer */
831 if (!flipto) {
832 /* walk the flip chain looking for backbuffer */
833 for (i=0;i<chain->nrofsurfaces;i++) {
834 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
835 flipable++;
836 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
837 flipto = chain->surfaces[i];
839 /* sanity checks ... */
840 if (!flipto) {
841 if (flipable>1) {
842 for (i=0;i<chain->nrofsurfaces;i++)
843 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
844 break;
845 if (i==chain->nrofsurfaces) {
846 /* we do not have a frontbuffer either */
847 for (i=0;i<chain->nrofsurfaces;i++)
848 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
849 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
850 break;
852 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
853 int k = j % chain->nrofsurfaces;
854 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
855 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
856 flipto = chain->surfaces[k];
857 break;
862 if (!flipto)
863 flipto = This;
865 TRACE("flipping to %p\n",flipto);
867 return flipto;
870 #ifdef HAVE_LIBXXF86DGA
871 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
872 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
874 ICOM_THIS(IDirectDrawSurface4Impl,iface);
875 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
876 DWORD xheight;
877 LPBYTE surf;
879 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
880 iflipto = _common_find_flipto(This,iflipto);
882 /* and flip! */
883 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
884 if (iflipto->s.palette && iflipto->s.palette->cm)
885 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
886 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
889 /* We need to switch the lowlevel surfaces, for DGA this is: */
891 /* The height within the framebuffer */
892 xheight = This->t.dga.fb_height;
893 This->t.dga.fb_height = iflipto->t.dga.fb_height;
894 iflipto->t.dga.fb_height = xheight;
896 /* And the assciated surface pointer */
897 surf = This->s.surface_desc.u1.lpSurface;
898 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
899 iflipto->s.surface_desc.u1.lpSurface = surf;
901 return DD_OK;
903 #endif /* defined(HAVE_LIBXXF86DGA) */
905 #ifdef HAVE_LIBXXF86DGA2
906 static HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
907 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
909 ICOM_THIS(IDirectDrawSurface4Impl,iface);
910 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
911 DWORD xheight;
912 LPBYTE surf;
914 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
915 iflipto = _common_find_flipto(This,iflipto);
917 /* and flip! */
918 TSXDGASetViewport(display,DefaultScreen(display),0,iflipto->t.dga.fb_height, XDGAFlipRetrace);
919 TSXDGASync(display,DefaultScreen(display));
920 TSXFlush(display);
921 if (iflipto->s.palette && iflipto->s.palette->cm)
922 TSXDGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
923 /* We need to switch the lowlevel surfaces, for DGA this is: */
925 /* The height within the framebuffer */
926 xheight = This->t.dga.fb_height;
927 This->t.dga.fb_height = iflipto->t.dga.fb_height;
928 iflipto->t.dga.fb_height = xheight;
930 /* And the assciated surface pointer */
931 surf = This->s.surface_desc.u1.lpSurface;
932 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
933 iflipto->s.surface_desc.u1.lpSurface = surf;
935 return DD_OK;
937 #endif /* defined(HAVE_LIBXXF86DGA2) */
939 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
940 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
942 ICOM_THIS(IDirectDrawSurface4Impl,iface);
943 XImage *image;
944 LPBYTE surf;
945 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
947 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
948 iflipto = _common_find_flipto(This,iflipto);
950 #if defined(HAVE_MESAGL) && 0 /* does not work */
951 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
952 TRACE(" - OpenGL flip\n");
953 ENTER_GL();
954 glXSwapBuffers(display, This->s.ddraw->d.drawable);
955 LEAVE_GL();
957 return DD_OK;
959 #endif /* defined(HAVE_MESAGL) */
961 if (!This->s.ddraw->d.paintable)
962 return DD_OK;
964 /* We need to switch the lowlevel surfaces, for xlib this is: */
965 /* The surface pointer */
966 surf = This->s.surface_desc.u1.lpSurface;
967 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
968 iflipto->s.surface_desc.u1.lpSurface = surf;
969 /* the associated ximage */
970 image = This->t.xlib.image;
971 This->t.xlib.image = iflipto->t.xlib.image;
972 iflipto->t.xlib.image = image;
974 Xlib_copy_surface_on_screen(This);
976 if (iflipto->s.palette && iflipto->s.palette->cm)
977 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
978 return DD_OK;
981 /* The IDirectDrawSurface4::SetPalette method attaches the specified
982 * DirectDrawPalette object to a surface. The surface uses this palette for all
983 * subsequent operations. The palette change takes place immediately.
985 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
986 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
988 ICOM_THIS(IDirectDrawSurface4Impl,iface);
989 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
990 int i;
991 TRACE("(%p)->(%p)\n",This,ipal);
993 if (ipal == NULL) {
994 if( This->s.palette != NULL )
995 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
996 This->s.palette = ipal;
998 return DD_OK;
1001 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8))
1003 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
1004 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
1006 if (!Options.managed)
1007 TSXInstallColormap(display,ipal->cm);
1009 for (i=0;i<256;i++) {
1010 XColor xc;
1012 xc.red = ipal->palents[i].peRed<<8;
1013 xc.blue = ipal->palents[i].peBlue<<8;
1014 xc.green = ipal->palents[i].peGreen<<8;
1015 xc.flags = DoRed|DoBlue|DoGreen;
1016 xc.pixel = i;
1017 TSXStoreColor(display,ipal->cm,&xc);
1019 TSXInstallColormap(display,ipal->cm);
1022 /* According to spec, we are only supposed to
1023 * AddRef if this is not the same palette.
1025 if( This->s.palette != ipal )
1027 if( ipal != NULL )
1028 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1029 if( This->s.palette != NULL )
1030 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1031 This->s.palette = ipal;
1032 /* Perform the refresh */
1033 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
1035 return DD_OK;
1038 #ifdef HAVE_LIBXXF86DGA
1039 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
1040 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1042 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1043 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1044 TRACE("(%p)->(%p)\n",This,ipal);
1046 /* According to spec, we are only supposed to
1047 * AddRef if this is not the same palette.
1049 if( This->s.palette != ipal )
1051 if( ipal != NULL )
1052 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1053 if( This->s.palette != NULL )
1054 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1055 This->s.palette = ipal;
1056 #ifdef HAVE_LIBXXF86DGA2
1057 if (This->s.ddraw->e.dga.version == 2)
1058 TSXDGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1059 else
1060 #endif /* defined(HAVE_LIBXXF86DGA2) */
1061 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1063 return DD_OK;
1065 #endif /* defined(HAVE_LIBXXF86DGA) */
1067 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
1069 int x, y;
1070 LPBYTE first;
1072 /* Do first row */
1074 #define COLORFILL_ROW(type) { \
1075 type *d = (type *) buf; \
1076 for (x = 0; x < width; x++) \
1077 d[x] = (type) color; \
1078 break; \
1081 switch(bpp) {
1082 case 1: COLORFILL_ROW(BYTE)
1083 case 2: COLORFILL_ROW(WORD)
1084 case 4: COLORFILL_ROW(DWORD)
1085 default:
1086 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
1087 return DDERR_UNSUPPORTED;
1090 #undef COLORFILL_ROW
1092 /* Now copy first row */
1093 first = buf;
1094 for (y = 1; y < height; y++) {
1095 buf += lPitch;
1096 memcpy(buf, first, width * bpp);
1099 return DD_OK;
1102 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
1103 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
1105 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1106 RECT xdst,xsrc;
1107 DDSURFACEDESC ddesc,sdesc;
1108 HRESULT ret = DD_OK;
1109 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
1110 int x, y;
1111 LPBYTE dbuf, sbuf;
1113 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
1115 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
1116 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1118 if (TRACE_ON(ddraw)) {
1119 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1120 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1121 TRACE("\tflags: ");
1122 _dump_DDBLT(dwFlags);
1123 if (dwFlags & DDBLT_DDFX) {
1124 TRACE("\tblitfx: ");
1125 _dump_DDBLTFX(lpbltfx->dwDDFX);
1129 if (rdst) {
1130 if ((rdst->top < 0) ||
1131 (rdst->left < 0) ||
1132 (rdst->bottom < 0) ||
1133 (rdst->right < 0)) {
1134 ERR(" Negative values in LPRECT !!!\n");
1135 goto release;
1137 memcpy(&xdst,rdst,sizeof(xdst));
1138 } else {
1139 xdst.top = 0;
1140 xdst.bottom = ddesc.dwHeight;
1141 xdst.left = 0;
1142 xdst.right = ddesc.dwWidth;
1145 if (rsrc) {
1146 if ((rsrc->top < 0) ||
1147 (rsrc->left < 0) ||
1148 (rsrc->bottom < 0) ||
1149 (rsrc->right < 0)) {
1150 ERR(" Negative values in LPRECT !!!\n");
1151 goto release;
1153 memcpy(&xsrc,rsrc,sizeof(xsrc));
1154 } else {
1155 if (src) {
1156 xsrc.top = 0;
1157 xsrc.bottom = sdesc.dwHeight;
1158 xsrc.left = 0;
1159 xsrc.right = sdesc.dwWidth;
1160 } else {
1161 memset(&xsrc,0,sizeof(xsrc));
1165 bpp = GET_BPP(ddesc);
1166 srcheight = xsrc.bottom - xsrc.top;
1167 srcwidth = xsrc.right - xsrc.left;
1168 dstheight = xdst.bottom - xdst.top;
1169 dstwidth = xdst.right - xdst.left;
1170 width = (xdst.right - xdst.left) * bpp;
1171 dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1173 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1175 /* First, all the 'source-less' blits */
1176 if (dwFlags & DDBLT_COLORFILL) {
1177 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1178 ddesc.lPitch, lpbltfx->u4.dwFillColor);
1179 dwFlags &= ~DDBLT_COLORFILL;
1182 if (dwFlags & DDBLT_DEPTHFILL) {
1183 #ifdef HAVE_MESAGL
1184 GLboolean ztest;
1186 /* Clears the screen */
1187 TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
1188 glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1189 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1190 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1191 glClear(GL_DEPTH_BUFFER_BIT);
1192 glDepthMask(ztest);
1194 dwFlags &= ~(DDBLT_DEPTHFILL);
1195 #endif /* defined(HAVE_MESAGL) */
1198 if (dwFlags & DDBLT_ROP) {
1199 /* Catch some degenerate cases here */
1200 switch(lpbltfx->dwROP) {
1201 case BLACKNESS:
1202 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1203 break;
1204 case 0xAA0029: /* No-op */
1205 break;
1206 case WHITENESS:
1207 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1208 break;
1209 default:
1210 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
1211 goto error;
1213 dwFlags &= ~DDBLT_ROP;
1216 if (dwFlags & DDBLT_DDROPS) {
1217 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
1220 /* Now the 'with source' blits */
1221 if (src) {
1222 LPBYTE sbase;
1223 int sx, xinc, sy, yinc;
1225 sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1226 xinc = (srcwidth << 16) / dstwidth;
1227 yinc = (srcheight << 16) / dstheight;
1229 if (!dwFlags) {
1231 /* No effects, we can cheat here */
1232 if (dstwidth == srcwidth) {
1233 if (dstheight == srcheight) {
1234 /* No stretching in either direction. This needs to be as fast as possible */
1235 sbuf = sbase;
1236 for (y = 0; y < dstheight; y++) {
1237 memcpy(dbuf, sbuf, width);
1238 sbuf += sdesc.lPitch;
1239 dbuf += ddesc.lPitch;
1241 } else {
1242 /* Stretching in Y direction only */
1243 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1244 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1245 memcpy(dbuf, sbuf, width);
1246 dbuf += ddesc.lPitch;
1249 } else {
1250 /* Stretching in X direction */
1251 int last_sy = -1;
1252 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1253 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1255 if ((sy >> 16) == (last_sy >> 16)) {
1256 /* Same as last row - copy already stretched row */
1257 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1258 } else {
1260 #define STRETCH_ROW(type) { \
1261 type *s = (type *) sbuf, *d = (type *) dbuf; \
1262 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1263 d[x] = s[sx >> 16]; \
1264 break; }
1266 switch(bpp) {
1267 case 1: STRETCH_ROW(BYTE)
1268 case 2: STRETCH_ROW(WORD)
1269 case 4: STRETCH_ROW(DWORD)
1270 default:
1271 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1272 ret = DDERR_UNSUPPORTED;
1273 goto error;
1276 #undef STRETCH_ROW
1279 last_sy = sy;
1280 dbuf += ddesc.lPitch;
1283 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1284 DWORD keylow, keyhigh;
1286 if (dwFlags & DDBLT_KEYSRC) {
1287 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1288 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1289 } else {
1290 /* I'm not sure if this is correct */
1291 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1292 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1293 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1297 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1298 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1300 #define COPYROW_COLORKEY(type) { \
1301 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1302 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1303 tmp = s[sx >> 16]; \
1304 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1306 break; }
1308 switch (bpp) {
1309 case 1: COPYROW_COLORKEY(BYTE)
1310 case 2: COPYROW_COLORKEY(WORD)
1311 case 4: COPYROW_COLORKEY(DWORD)
1312 default:
1313 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1314 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1315 ret = DDERR_UNSUPPORTED;
1316 goto error;
1318 dbuf += ddesc.lPitch;
1321 #undef COPYROW_COLORKEY
1323 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1328 error:
1330 if (dwFlags && FIXME_ON(ddraw)) {
1331 FIXME("\tUnsupported flags: ");
1332 _dump_DDBLT(dwFlags);
1334 release:
1336 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1337 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1339 return DD_OK;
1342 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1343 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1345 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1346 int bpp, w, h, x, y;
1347 DDSURFACEDESC ddesc,sdesc;
1348 HRESULT ret = DD_OK;
1349 LPBYTE sbuf, dbuf;
1350 RECT rsrc2;
1353 if (TRACE_ON(ddraw)) {
1354 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1355 This,dstx,dsty,src,rsrc,trans
1357 FIXME(" trans:");
1358 if (FIXME_ON(ddraw))
1359 _dump_DDBLTFAST(trans);
1360 if (rsrc)
1361 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1362 else
1363 FIXME(" srcrect: NULL\n");
1366 /* We need to lock the surfaces, or we won't get refreshes when done. */
1367 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1368 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1370 if (!rsrc) {
1371 WARN("rsrc is NULL!\n");
1372 rsrc = &rsrc2;
1373 rsrc->left = rsrc->top = 0;
1374 rsrc->right = sdesc.dwWidth;
1375 rsrc->bottom = sdesc.dwHeight;
1378 bpp = GET_BPP(This->s.surface_desc);
1379 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1380 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1383 h=rsrc->bottom-rsrc->top;
1384 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1385 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1386 if (h<0) h=0;
1388 w=rsrc->right-rsrc->left;
1389 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1390 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1391 if (w<0) w=0;
1393 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1394 DWORD keylow, keyhigh;
1395 if (trans & DDBLTFAST_SRCCOLORKEY) {
1396 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1397 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1398 } else {
1399 /* I'm not sure if this is correct */
1400 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1401 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1402 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1405 #define COPYBOX_COLORKEY(type) { \
1406 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1407 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1408 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1409 for (y = 0; y < h; y++) { \
1410 for (x = 0; x < w; x++) { \
1411 tmp = s[x]; \
1412 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1414 (LPBYTE)s += sdesc.lPitch; \
1415 (LPBYTE)d += ddesc.lPitch; \
1417 break; \
1420 switch (bpp) {
1421 case 1: COPYBOX_COLORKEY(BYTE)
1422 case 2: COPYBOX_COLORKEY(WORD)
1423 case 4: COPYBOX_COLORKEY(DWORD)
1424 default:
1425 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1426 ret = DDERR_UNSUPPORTED;
1427 goto error;
1430 #undef COPYBOX_COLORKEY
1432 } else {
1433 int width = w * bpp;
1435 for (y = 0; y < h; y++) {
1436 memcpy(dbuf, sbuf, width);
1437 sbuf += sdesc.lPitch;
1438 dbuf += ddesc.lPitch;
1442 error:
1444 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1445 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1446 return ret;
1449 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1450 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1452 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1453 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1454 This,ddbltbatch,x,y
1456 return DD_OK;
1459 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1460 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1462 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1463 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1464 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1465 return DD_OK;
1468 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1469 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1470 ) {
1471 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1472 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1474 /* Simply copy the surface description stored in the object */
1475 *ddsd = This->s.surface_desc;
1477 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1479 return DD_OK;
1482 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1483 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1484 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1485 return ++(This->ref);
1488 #ifdef HAVE_LIBXXF86DGA
1489 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1490 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1492 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1494 if (--(This->ref))
1495 return This->ref;
1497 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1498 /* clear out of surface list */
1499 if (This->t.dga.fb_height == -1)
1500 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1501 else
1502 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1504 /* Free the DIBSection (if any) */
1505 if (This->s.hdc != 0) {
1506 SelectObject(This->s.hdc, This->s.holdbitmap);
1507 DeleteDC(This->s.hdc);
1508 DeleteObject(This->s.DIBsection);
1511 /* Free the clipper if attached to this surface */
1512 if( This->s.lpClipper )
1513 IDirectDrawClipper_Release(This->s.lpClipper);
1515 HeapFree(GetProcessHeap(),0,This);
1516 return S_OK;
1518 #endif /* defined(HAVE_LIBXXF86DGA) */
1520 static ULONG WINAPI Xlib_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);
1530 if (This->t.xlib.image != NULL) {
1531 if (This->s.ddraw->d.pixel_convert != NULL) {
1532 /* In pixel conversion mode, there are 2 buffers to release. */
1533 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1535 #ifdef HAVE_LIBXXSHM
1536 if (This->s.ddraw->e.xlib.xshm_active) {
1537 TSXShmDetach(display, &(This->t.xlib.shminfo));
1538 TSXDestroyImage(This->t.xlib.image);
1539 shmdt(This->t.xlib.shminfo.shmaddr);
1540 } else {
1541 #endif
1542 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1543 This->t.xlib.image->data = NULL;
1544 TSXDestroyImage(This->t.xlib.image);
1545 #ifdef HAVE_LIBXXSHM
1547 #endif
1548 } else {
1549 This->t.xlib.image->data = NULL;
1551 #ifdef HAVE_LIBXXSHM
1552 if (This->s.ddraw->e.xlib.xshm_active) {
1553 TSXShmDetach(display, &(This->t.xlib.shminfo));
1554 TSXDestroyImage(This->t.xlib.image);
1555 shmdt(This->t.xlib.shminfo.shmaddr);
1556 } else {
1557 #endif
1558 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1559 TSXDestroyImage(This->t.xlib.image);
1560 #ifdef HAVE_LIBXXSHM
1562 #endif
1564 This->t.xlib.image = 0;
1565 } else {
1566 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1569 if (This->s.palette)
1570 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1572 /* Free the DIBSection (if any) */
1573 if (This->s.hdc != 0) {
1574 SelectObject(This->s.hdc, This->s.holdbitmap);
1575 DeleteDC(This->s.hdc);
1576 DeleteObject(This->s.DIBsection);
1579 /* Free the clipper if present */
1580 if( This->s.lpClipper )
1581 IDirectDrawClipper_Release(This->s.lpClipper);
1583 HeapFree(GetProcessHeap(),0,This);
1584 return S_OK;
1587 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1588 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1590 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1591 int i,found = 0,xstart;
1592 struct _surface_chain *chain;
1594 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1595 if (TRACE_ON(ddraw)) {
1596 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1597 DPRINTF("\n");
1599 chain = This->s.chain;
1600 if (!chain)
1601 return DDERR_NOTFOUND;
1603 for (i=0;i<chain->nrofsurfaces;i++)
1604 if (chain->surfaces[i] == This)
1605 break;
1607 xstart = i;
1608 for (i=0;i<chain->nrofsurfaces;i++) {
1609 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1610 #if 0
1611 if (found) /* may not find the same caps twice, (doc) */
1612 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1613 #endif
1614 found = (i+1)+xstart;
1617 if (!found)
1618 return DDERR_NOTFOUND;
1619 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1620 /* FIXME: AddRef? */
1621 TRACE("found %p\n",*lpdsf);
1622 return DD_OK;
1625 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1626 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1628 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1629 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1631 return DDERR_ALREADYINITIALIZED;
1634 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1635 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1637 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1638 TRACE("(%p)->(%p)\n",This,pf);
1640 *pf = This->s.surface_desc.ddpfPixelFormat;
1641 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1642 return DD_OK;
1645 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1646 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1647 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1648 return DD_OK;
1651 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1652 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1654 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1655 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1656 return DD_OK;
1659 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1660 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
1662 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1663 TRACE("(%p)->(%p)!\n",This,lpClipper);
1665 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
1666 This->s.lpClipper = lpClipper;
1667 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
1668 return DD_OK;
1671 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1672 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1674 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1675 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1676 int i;
1677 struct _surface_chain *chain;
1679 FIXME("(%p)->(%p)\n",This,surf);
1680 chain = This->s.chain;
1682 /* IDirectDrawSurface4_AddRef(surf); */
1684 if (chain) {
1685 for (i=0;i<chain->nrofsurfaces;i++)
1686 if (chain->surfaces[i] == isurf)
1687 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1688 } else {
1689 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1690 chain->nrofsurfaces = 1;
1691 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1692 chain->surfaces[0] = This;
1693 This->s.chain = chain;
1696 if (chain->surfaces)
1697 chain->surfaces = HeapReAlloc(
1698 GetProcessHeap(),
1700 chain->surfaces,
1701 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1703 else
1704 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1705 isurf->s.chain = chain;
1706 chain->surfaces[chain->nrofsurfaces++] = isurf;
1707 return DD_OK;
1710 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1711 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1712 DDSURFACEDESC desc;
1713 BITMAPINFO *b_info;
1714 UINT usage;
1716 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1718 /* Creates a DIB Section of the same size / format as the surface */
1719 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1721 if (This->s.hdc == 0) {
1722 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1723 case 16:
1724 case 32:
1725 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1726 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1727 break;
1728 #endif
1730 case 24:
1731 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1732 break;
1734 default:
1735 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1736 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1737 break;
1740 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1741 b_info->bmiHeader.biWidth = desc.dwWidth;
1742 b_info->bmiHeader.biHeight = desc.dwHeight;
1743 b_info->bmiHeader.biPlanes = 1;
1744 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1745 #if 0
1746 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1747 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1748 #endif
1749 b_info->bmiHeader.biCompression = BI_RGB;
1750 #if 0
1751 else
1752 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1753 #endif
1754 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1755 b_info->bmiHeader.biXPelsPerMeter = 0;
1756 b_info->bmiHeader.biYPelsPerMeter = 0;
1757 b_info->bmiHeader.biClrUsed = 0;
1758 b_info->bmiHeader.biClrImportant = 0;
1760 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1761 case 16:
1762 case 32:
1763 #if 0
1765 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1767 usage = 0;
1768 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1769 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1770 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1772 break;
1773 #endif
1774 case 24:
1775 /* Nothing to do */
1776 usage = DIB_RGB_COLORS;
1777 break;
1779 default: {
1780 int i;
1782 /* Fill the palette */
1783 usage = DIB_RGB_COLORS;
1785 if (This->s.palette == NULL) {
1786 ERR("Bad palette !!!\n");
1787 } else {
1788 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1789 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1791 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1792 rgb[i].rgbBlue = pent[i].peBlue;
1793 rgb[i].rgbRed = pent[i].peRed;
1794 rgb[i].rgbGreen = pent[i].peGreen;
1798 break;
1800 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1801 b_info,
1802 usage,
1803 &(This->s.bitmap_data),
1807 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1808 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1810 /* b_info is not useful anymore */
1811 HeapFree(GetProcessHeap(), 0, b_info);
1813 /* Create the DC */
1814 This->s.hdc = CreateCompatibleDC(0);
1815 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1818 /* Copy our surface in the DIB section */
1819 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1820 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1821 else
1822 /* TODO */
1823 FIXME("This case has to be done :/\n");
1825 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1826 *lphdc = This->s.hdc;
1828 return DD_OK;
1831 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1832 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1834 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1835 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1836 /* Copy the DIB section to our surface */
1837 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1838 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1839 } else {
1840 /* TODO */
1841 FIXME("This case has to be done :/\n");
1843 /* Unlock the surface */
1844 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1845 return DD_OK;
1848 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1849 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1851 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
1853 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1854 * the same interface. And IUnknown does that too of course.
1856 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1857 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1858 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1859 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1860 IsEqualGUID( &IID_IUnknown, refiid )
1862 *obj = This;
1863 IDirectDrawSurface4_AddRef(iface);
1865 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1866 return S_OK;
1868 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1870 /* Texture interface */
1871 *obj = d3dtexture2_create(This);
1872 IDirectDrawSurface4_AddRef(iface);
1873 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1874 return S_OK;
1876 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1878 /* Texture interface */
1879 *obj = d3dtexture_create(This);
1880 IDirectDrawSurface4_AddRef(iface);
1882 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1884 return S_OK;
1886 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1887 /* It is the OpenGL Direct3D Device */
1888 IDirectDrawSurface4_AddRef(iface);
1889 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1890 return S_OK;
1893 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
1894 return OLE_E_ENUM_NOMORE;
1897 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1898 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1899 TRACE("(%p)->(), stub!\n",This);
1900 return DD_OK; /* hmm */
1903 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1904 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1905 int i;
1906 struct _surface_chain *chain = This->s.chain;
1908 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1909 for (i=0;i<chain->nrofsurfaces;i++) {
1910 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1911 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1912 return DD_OK; /* FIXME: return value correct? */
1914 return DD_OK;
1917 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1918 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1919 FIXME("(%p)->(),stub!\n",This);
1920 return DD_OK;
1923 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1924 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1926 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1927 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1928 if (TRACE_ON(ddraw)) {
1929 _dump_colorkeyflag(dwFlags);
1930 DPRINTF(" : ");
1931 _dump_DDCOLORKEY((void *) ckey);
1932 DPRINTF("\n");
1935 /* If this surface was loaded as a texture, call also the texture
1936 SetColorKey callback */
1937 if (This->s.texture) {
1938 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1941 if( dwFlags & DDCKEY_SRCBLT )
1943 dwFlags &= ~DDCKEY_SRCBLT;
1944 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1945 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1948 if( dwFlags & DDCKEY_DESTBLT )
1950 dwFlags &= ~DDCKEY_DESTBLT;
1951 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1952 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1955 if( dwFlags & DDCKEY_SRCOVERLAY )
1957 dwFlags &= ~DDCKEY_SRCOVERLAY;
1958 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1959 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1962 if( dwFlags & DDCKEY_DESTOVERLAY )
1964 dwFlags &= ~DDCKEY_DESTOVERLAY;
1965 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1966 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1969 if( dwFlags )
1971 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1974 return DD_OK;
1978 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1979 LPDIRECTDRAWSURFACE4 iface,
1980 LPRECT lpRect )
1982 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1983 FIXME("(%p)->(%p),stub!\n",This,lpRect);
1985 return DD_OK;
1988 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1989 LPDIRECTDRAWSURFACE4 iface,
1990 DWORD dwFlags,
1991 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1993 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1994 int i;
1995 struct _surface_chain *chain;
1997 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
1998 chain = This->s.chain;
1999 for (i=0;i<chain->nrofsurfaces;i++) {
2000 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
2001 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
2003 chain->surfaces[i]->s.chain = NULL;
2004 memcpy( chain->surfaces+i,
2005 chain->surfaces+(i+1),
2006 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
2008 chain->surfaces = HeapReAlloc(
2009 GetProcessHeap(),
2011 chain->surfaces,
2012 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
2014 chain->nrofsurfaces--;
2015 return DD_OK;
2018 return DD_OK;
2021 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
2022 LPDIRECTDRAWSURFACE4 iface,
2023 DWORD dwFlags,
2024 LPVOID lpContext,
2025 LPDDENUMSURFACESCALLBACK lpfnCallback )
2027 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2028 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
2029 lpContext, lpfnCallback );
2031 return DD_OK;
2034 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
2035 LPDIRECTDRAWSURFACE4 iface,
2036 LPDIRECTDRAWCLIPPER* lplpDDClipper )
2038 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2039 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
2041 return DD_OK;
2044 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
2045 LPDIRECTDRAWSURFACE4 iface,
2046 DWORD dwFlags,
2047 LPDDCOLORKEY lpDDColorKey )
2049 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2050 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
2052 if( dwFlags & DDCKEY_SRCBLT ) {
2053 dwFlags &= ~DDCKEY_SRCBLT;
2054 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
2057 if( dwFlags & DDCKEY_DESTBLT )
2059 dwFlags &= ~DDCKEY_DESTBLT;
2060 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
2063 if( dwFlags & DDCKEY_SRCOVERLAY )
2065 dwFlags &= ~DDCKEY_SRCOVERLAY;
2066 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
2069 if( dwFlags & DDCKEY_DESTOVERLAY )
2071 dwFlags &= ~DDCKEY_DESTOVERLAY;
2072 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
2075 if( dwFlags )
2077 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2080 return DD_OK;
2083 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
2084 LPDIRECTDRAWSURFACE4 iface,
2085 DWORD dwFlags )
2087 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2088 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2090 return DD_OK;
2093 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
2094 LPDIRECTDRAWSURFACE4 iface,
2095 LPDIRECTDRAWPALETTE* lplpDDPalette )
2097 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2098 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
2100 if (This->s.palette != NULL) {
2101 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
2103 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
2104 return DD_OK;
2105 } else {
2106 return DDERR_NOPALETTEATTACHED;
2110 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
2111 LPDIRECTDRAWSURFACE4 iface,
2112 LONG lX,
2113 LONG lY)
2115 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2116 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
2118 return DD_OK;
2121 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
2122 LPDIRECTDRAWSURFACE4 iface,
2123 LPRECT lpSrcRect,
2124 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
2125 LPRECT lpDestRect,
2126 DWORD dwFlags,
2127 LPDDOVERLAYFX lpDDOverlayFx )
2129 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2130 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
2131 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
2133 return DD_OK;
2136 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
2137 LPDIRECTDRAWSURFACE4 iface,
2138 DWORD dwFlags )
2140 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2141 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2143 return DD_OK;
2146 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2147 LPDIRECTDRAWSURFACE4 iface,
2148 DWORD dwFlags,
2149 LPDIRECTDRAWSURFACE4 lpDDSReference )
2151 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2152 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2154 return DD_OK;
2157 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2158 LPDIRECTDRAWSURFACE4 iface,
2159 LPVOID* lplpDD )
2161 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2162 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2164 /* Not sure about that... */
2165 *lplpDD = (void *) This->s.ddraw;
2167 return DD_OK;
2170 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2171 LPDIRECTDRAWSURFACE4 iface,
2172 DWORD dwFlags )
2174 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2175 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2177 return DD_OK;
2180 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2181 LPDIRECTDRAWSURFACE4 iface,
2182 DWORD dwFlags )
2184 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2185 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2187 return DD_OK;
2190 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2191 LPDIRECTDRAWSURFACE4 iface,
2192 LPDDSURFACEDESC lpDDSD,
2193 DWORD dwFlags )
2195 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2196 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2198 return DD_OK;
2201 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2202 REFGUID guidTag,
2203 LPVOID lpData,
2204 DWORD cbSize,
2205 DWORD dwFlags) {
2206 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2207 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2209 return DD_OK;
2212 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2213 REFGUID guidTag,
2214 LPVOID lpBuffer,
2215 LPDWORD lpcbBufferSize) {
2216 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2217 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2219 return DD_OK;
2222 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2223 REFGUID guidTag) {
2224 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2225 FIXME("(%p)->(%p)\n", This, guidTag);
2227 return DD_OK;
2230 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2231 LPDWORD lpValue) {
2232 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2233 FIXME("(%p)->(%p)\n", This, lpValue);
2235 return DD_OK;
2238 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2239 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2240 FIXME("(%p)\n", This);
2242 return DD_OK;
2245 #ifdef HAVE_LIBXXF86DGA
2246 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2248 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2249 IDirectDrawSurface4Impl_QueryInterface,
2250 IDirectDrawSurface4Impl_AddRef,
2251 DGA_IDirectDrawSurface4Impl_Release,
2252 IDirectDrawSurface4Impl_AddAttachedSurface,
2253 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2254 IDirectDrawSurface4Impl_Blt,
2255 IDirectDrawSurface4Impl_BltBatch,
2256 IDirectDrawSurface4Impl_BltFast,
2257 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2258 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2259 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2260 DGA_IDirectDrawSurface4Impl_Flip,
2261 IDirectDrawSurface4Impl_GetAttachedSurface,
2262 IDirectDrawSurface4Impl_GetBltStatus,
2263 IDirectDrawSurface4Impl_GetCaps,
2264 IDirectDrawSurface4Impl_GetClipper,
2265 IDirectDrawSurface4Impl_GetColorKey,
2266 IDirectDrawSurface4Impl_GetDC,
2267 IDirectDrawSurface4Impl_GetFlipStatus,
2268 IDirectDrawSurface4Impl_GetOverlayPosition,
2269 IDirectDrawSurface4Impl_GetPalette,
2270 IDirectDrawSurface4Impl_GetPixelFormat,
2271 IDirectDrawSurface4Impl_GetSurfaceDesc,
2272 IDirectDrawSurface4Impl_Initialize,
2273 IDirectDrawSurface4Impl_IsLost,
2274 IDirectDrawSurface4Impl_Lock,
2275 IDirectDrawSurface4Impl_ReleaseDC,
2276 IDirectDrawSurface4Impl_Restore,
2277 IDirectDrawSurface4Impl_SetClipper,
2278 IDirectDrawSurface4Impl_SetColorKey,
2279 IDirectDrawSurface4Impl_SetOverlayPosition,
2280 DGA_IDirectDrawSurface4Impl_SetPalette,
2281 DGA_IDirectDrawSurface4Impl_Unlock,
2282 IDirectDrawSurface4Impl_UpdateOverlay,
2283 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2284 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2285 IDirectDrawSurface4Impl_GetDDInterface,
2286 IDirectDrawSurface4Impl_PageLock,
2287 IDirectDrawSurface4Impl_PageUnlock,
2288 IDirectDrawSurface4Impl_SetSurfaceDesc,
2289 IDirectDrawSurface4Impl_SetPrivateData,
2290 IDirectDrawSurface4Impl_GetPrivateData,
2291 IDirectDrawSurface4Impl_FreePrivateData,
2292 IDirectDrawSurface4Impl_GetUniquenessValue,
2293 IDirectDrawSurface4Impl_ChangeUniquenessValue
2295 #endif /* defined(HAVE_LIBXXF86DGA) */
2297 #ifdef HAVE_LIBXXF86DGA2
2298 static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
2300 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2301 IDirectDrawSurface4Impl_QueryInterface,
2302 IDirectDrawSurface4Impl_AddRef,
2303 DGA_IDirectDrawSurface4Impl_Release,
2304 IDirectDrawSurface4Impl_AddAttachedSurface,
2305 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2306 IDirectDrawSurface4Impl_Blt,
2307 IDirectDrawSurface4Impl_BltBatch,
2308 IDirectDrawSurface4Impl_BltFast,
2309 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2310 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2311 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2312 DGA2_IDirectDrawSurface4Impl_Flip,
2313 IDirectDrawSurface4Impl_GetAttachedSurface,
2314 IDirectDrawSurface4Impl_GetBltStatus,
2315 IDirectDrawSurface4Impl_GetCaps,
2316 IDirectDrawSurface4Impl_GetClipper,
2317 IDirectDrawSurface4Impl_GetColorKey,
2318 IDirectDrawSurface4Impl_GetDC,
2319 IDirectDrawSurface4Impl_GetFlipStatus,
2320 IDirectDrawSurface4Impl_GetOverlayPosition,
2321 IDirectDrawSurface4Impl_GetPalette,
2322 IDirectDrawSurface4Impl_GetPixelFormat,
2323 IDirectDrawSurface4Impl_GetSurfaceDesc,
2324 IDirectDrawSurface4Impl_Initialize,
2325 IDirectDrawSurface4Impl_IsLost,
2326 IDirectDrawSurface4Impl_Lock,
2327 IDirectDrawSurface4Impl_ReleaseDC,
2328 IDirectDrawSurface4Impl_Restore,
2329 IDirectDrawSurface4Impl_SetClipper,
2330 IDirectDrawSurface4Impl_SetColorKey,
2331 IDirectDrawSurface4Impl_SetOverlayPosition,
2332 DGA_IDirectDrawSurface4Impl_SetPalette,
2333 DGA_IDirectDrawSurface4Impl_Unlock,
2334 IDirectDrawSurface4Impl_UpdateOverlay,
2335 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2336 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2337 IDirectDrawSurface4Impl_GetDDInterface,
2338 IDirectDrawSurface4Impl_PageLock,
2339 IDirectDrawSurface4Impl_PageUnlock,
2340 IDirectDrawSurface4Impl_SetSurfaceDesc,
2341 IDirectDrawSurface4Impl_SetPrivateData,
2342 IDirectDrawSurface4Impl_GetPrivateData,
2343 IDirectDrawSurface4Impl_FreePrivateData,
2344 IDirectDrawSurface4Impl_GetUniquenessValue,
2345 IDirectDrawSurface4Impl_ChangeUniquenessValue
2347 #endif /* defined(HAVE_LIBXXF86DGA2) */
2349 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2351 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2352 IDirectDrawSurface4Impl_QueryInterface,
2353 IDirectDrawSurface4Impl_AddRef,
2354 Xlib_IDirectDrawSurface4Impl_Release,
2355 IDirectDrawSurface4Impl_AddAttachedSurface,
2356 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2357 IDirectDrawSurface4Impl_Blt,
2358 IDirectDrawSurface4Impl_BltBatch,
2359 IDirectDrawSurface4Impl_BltFast,
2360 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2361 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2362 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2363 Xlib_IDirectDrawSurface4Impl_Flip,
2364 IDirectDrawSurface4Impl_GetAttachedSurface,
2365 IDirectDrawSurface4Impl_GetBltStatus,
2366 IDirectDrawSurface4Impl_GetCaps,
2367 IDirectDrawSurface4Impl_GetClipper,
2368 IDirectDrawSurface4Impl_GetColorKey,
2369 IDirectDrawSurface4Impl_GetDC,
2370 IDirectDrawSurface4Impl_GetFlipStatus,
2371 IDirectDrawSurface4Impl_GetOverlayPosition,
2372 IDirectDrawSurface4Impl_GetPalette,
2373 IDirectDrawSurface4Impl_GetPixelFormat,
2374 IDirectDrawSurface4Impl_GetSurfaceDesc,
2375 IDirectDrawSurface4Impl_Initialize,
2376 IDirectDrawSurface4Impl_IsLost,
2377 IDirectDrawSurface4Impl_Lock,
2378 IDirectDrawSurface4Impl_ReleaseDC,
2379 IDirectDrawSurface4Impl_Restore,
2380 IDirectDrawSurface4Impl_SetClipper,
2381 IDirectDrawSurface4Impl_SetColorKey,
2382 IDirectDrawSurface4Impl_SetOverlayPosition,
2383 Xlib_IDirectDrawSurface4Impl_SetPalette,
2384 Xlib_IDirectDrawSurface4Impl_Unlock,
2385 IDirectDrawSurface4Impl_UpdateOverlay,
2386 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2387 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2388 IDirectDrawSurface4Impl_GetDDInterface,
2389 IDirectDrawSurface4Impl_PageLock,
2390 IDirectDrawSurface4Impl_PageUnlock,
2391 IDirectDrawSurface4Impl_SetSurfaceDesc,
2392 IDirectDrawSurface4Impl_SetPrivateData,
2393 IDirectDrawSurface4Impl_GetPrivateData,
2394 IDirectDrawSurface4Impl_FreePrivateData,
2395 IDirectDrawSurface4Impl_GetUniquenessValue,
2396 IDirectDrawSurface4Impl_ChangeUniquenessValue
2399 /******************************************************************************
2400 * DirectDrawCreateClipper (DDRAW.7)
2402 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2403 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2404 LPUNKNOWN pUnkOuter)
2406 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2407 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2409 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2410 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2411 (*ilplpDDClipper)->ref = 1;
2413 (*ilplpDDClipper)->hWnd = 0;
2415 return DD_OK;
2418 /******************************************************************************
2419 * IDirectDrawClipper
2421 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2422 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
2424 ICOM_THIS(IDirectDrawClipperImpl,iface);
2426 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
2427 if( dwFlags ) {
2428 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
2429 return DDERR_INVALIDPARAMS;
2432 This->hWnd = hWnd;
2433 return DD_OK;
2436 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2437 ICOM_THIS(IDirectDrawClipperImpl,iface);
2438 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2440 This->ref--;
2441 if (This->ref)
2442 return This->ref;
2443 HeapFree(GetProcessHeap(),0,This);
2444 return S_OK;
2447 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2448 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2450 ICOM_THIS(IDirectDrawClipperImpl,iface);
2451 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2452 if (hmm) *hmm=0;
2453 return DD_OK;
2456 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2457 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2459 ICOM_THIS(IDirectDrawClipperImpl,iface);
2460 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2461 return DD_OK;
2464 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2465 LPDIRECTDRAWCLIPPER iface,
2466 REFIID riid,
2467 LPVOID* ppvObj )
2469 ICOM_THIS(IDirectDrawClipperImpl,iface);
2470 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2471 return OLE_E_ENUM_NOMORE;
2474 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2476 ICOM_THIS(IDirectDrawClipperImpl,iface);
2477 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2478 return ++(This->ref);
2481 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2482 LPDIRECTDRAWCLIPPER iface,
2483 HWND* hWndPtr )
2485 ICOM_THIS(IDirectDrawClipperImpl,iface);
2486 FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
2488 *hWndPtr = This->hWnd;
2490 return DD_OK;
2493 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2494 LPDIRECTDRAWCLIPPER iface,
2495 LPDIRECTDRAW lpDD,
2496 DWORD dwFlags )
2498 ICOM_THIS(IDirectDrawClipperImpl,iface);
2499 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2500 return DD_OK;
2503 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2504 LPDIRECTDRAWCLIPPER iface,
2505 BOOL* lpbChanged )
2507 ICOM_THIS(IDirectDrawClipperImpl,iface);
2508 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2509 return DD_OK;
2512 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2514 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2515 IDirectDrawClipperImpl_QueryInterface,
2516 IDirectDrawClipperImpl_AddRef,
2517 IDirectDrawClipperImpl_Release,
2518 IDirectDrawClipperImpl_GetClipList,
2519 IDirectDrawClipperImpl_GetHWnd,
2520 IDirectDrawClipperImpl_Initialize,
2521 IDirectDrawClipperImpl_IsClipListChanged,
2522 IDirectDrawClipperImpl_SetClipList,
2523 IDirectDrawClipperImpl_SetHwnd
2527 /******************************************************************************
2528 * IDirectDrawPalette
2530 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2531 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2533 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2534 int i;
2536 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2537 This,x,start,count,palent);
2539 /* No palette created and not in depth-convertion mode -> BUG ! */
2540 if ((This->cm == None) &&
2541 (This->ddraw->d.palette_convert == NULL))
2543 FIXME("app tried to read colormap for non-palettized mode\n");
2544 return DDERR_GENERIC;
2546 for (i=0;i<count;i++) {
2547 palent[i].peRed = This->palents[start+i].peRed;
2548 palent[i].peBlue = This->palents[start+i].peBlue;
2549 palent[i].peGreen = This->palents[start+i].peGreen;
2550 palent[i].peFlags = This->palents[start+i].peFlags;
2553 return DD_OK;
2556 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2557 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2559 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2560 XColor xc;
2561 int i;
2563 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2564 This,x,start,count,palent
2566 for (i=0;i<count;i++) {
2567 xc.red = palent[i].peRed<<8;
2568 xc.blue = palent[i].peBlue<<8;
2569 xc.green = palent[i].peGreen<<8;
2570 xc.flags = DoRed|DoBlue|DoGreen;
2571 xc.pixel = start+i;
2573 if (This->cm)
2574 TSXStoreColor(display,This->cm,&xc);
2576 This->palents[start+i].peRed = palent[i].peRed;
2577 This->palents[start+i].peBlue = palent[i].peBlue;
2578 This->palents[start+i].peGreen = palent[i].peGreen;
2579 This->palents[start+i].peFlags = palent[i].peFlags;
2582 /* Now, if we are in 'depth conversion mode', update the screen palette */
2583 /* FIXME: we need to update the image or we won't get palette fading. */
2584 if (This->ddraw->d.palette_convert != NULL)
2585 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2587 return DD_OK;
2590 #ifdef HAVE_LIBXXF86DGA
2591 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2592 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2594 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2595 XColor xc;
2596 Colormap cm;
2597 int i;
2599 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2600 This,x,start,count,palent
2602 if (!This->cm) /* should not happen */ {
2603 FIXME("app tried to set colormap in non-palettized mode\n");
2604 return DDERR_GENERIC;
2606 /* FIXME: free colorcells instead of freeing whole map */
2607 cm = This->cm;
2608 This->cm = TSXCopyColormapAndFree(display,This->cm);
2609 TSXFreeColormap(display,cm);
2611 for (i=0;i<count;i++) {
2612 xc.red = palent[i].peRed<<8;
2613 xc.blue = palent[i].peBlue<<8;
2614 xc.green = palent[i].peGreen<<8;
2615 xc.flags = DoRed|DoBlue|DoGreen;
2616 xc.pixel = i+start;
2618 TSXStoreColor(display,This->cm,&xc);
2620 This->palents[start+i].peRed = palent[i].peRed;
2621 This->palents[start+i].peBlue = palent[i].peBlue;
2622 This->palents[start+i].peGreen = palent[i].peGreen;
2623 This->palents[start+i].peFlags = palent[i].peFlags;
2625 #ifdef HAVE_LIBXXF86DGA2
2626 if (This->ddraw->e.dga.version == 2)
2627 TSXDGAInstallColormap(display,DefaultScreen(display),This->cm);
2628 else
2629 #endif /* defined(HAVE_LIBXXF86DGA2) */
2630 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2631 return DD_OK;
2633 #endif /* defined(HAVE_LIBXXF86DGA) */
2635 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2636 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2637 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2638 if (!--(This->ref)) {
2639 if (This->cm) {
2640 TSXFreeColormap(display,This->cm);
2641 This->cm = 0;
2643 HeapFree(GetProcessHeap(),0,This);
2644 return S_OK;
2646 return This->ref;
2649 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2650 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2652 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2653 return ++(This->ref);
2656 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2657 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2659 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2660 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2662 return DDERR_ALREADYINITIALIZED;
2665 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2666 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2668 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2669 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2670 return DD_OK;
2673 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2674 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2676 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2678 FIXME("(%p)->(%s,%p) stub.\n",This,debugstr_guid(refiid),obj);
2680 return S_OK;
2683 #ifdef HAVE_LIBXXF86DGA
2684 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2686 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2687 IDirectDrawPaletteImpl_QueryInterface,
2688 IDirectDrawPaletteImpl_AddRef,
2689 IDirectDrawPaletteImpl_Release,
2690 IDirectDrawPaletteImpl_GetCaps,
2691 IDirectDrawPaletteImpl_GetEntries,
2692 IDirectDrawPaletteImpl_Initialize,
2693 DGA_IDirectDrawPaletteImpl_SetEntries
2695 #endif /* defined(HAVE_LIBXXF86DGA) */
2697 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2699 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2700 IDirectDrawPaletteImpl_QueryInterface,
2701 IDirectDrawPaletteImpl_AddRef,
2702 IDirectDrawPaletteImpl_Release,
2703 IDirectDrawPaletteImpl_GetCaps,
2704 IDirectDrawPaletteImpl_GetEntries,
2705 IDirectDrawPaletteImpl_Initialize,
2706 Xlib_IDirectDrawPaletteImpl_SetEntries
2709 /*******************************************************************************
2710 * IDirect3D
2712 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2713 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2715 ICOM_THIS(IDirect3DImpl,iface);
2716 /* FIXME: Not sure if this is correct */
2718 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2719 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2720 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2721 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2722 *obj = This->ddraw;
2723 IDirect3D_AddRef(iface);
2725 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2727 return S_OK;
2729 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2730 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2731 *obj = This;
2732 IDirect3D_AddRef(iface);
2734 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2736 return S_OK;
2738 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2739 IDirect3D2Impl* d3d;
2741 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2742 d3d->ref = 1;
2743 d3d->ddraw = This->ddraw;
2744 IDirect3D_AddRef(iface);
2745 ICOM_VTBL(d3d) = &d3d2vt;
2746 *obj = d3d;
2748 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2750 return S_OK;
2752 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2753 return OLE_E_ENUM_NOMORE;
2756 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2757 ICOM_THIS(IDirect3DImpl,iface);
2758 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2760 return ++(This->ref);
2763 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2765 ICOM_THIS(IDirect3DImpl,iface);
2766 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2768 if (!--(This->ref)) {
2769 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2770 HeapFree(GetProcessHeap(),0,This);
2771 return S_OK;
2773 return This->ref;
2776 static HRESULT WINAPI IDirect3DImpl_Initialize(
2777 LPDIRECT3D iface, REFIID refiid )
2779 ICOM_THIS(IDirect3DImpl,iface);
2780 /* FIXME: Not sure if this is correct */
2782 FIXME("(%p)->(%s):stub.\n",This,debugstr_guid(refiid));
2784 return DDERR_ALREADYINITIALIZED;
2787 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2788 LPD3DENUMDEVICESCALLBACK cb,
2789 LPVOID context) {
2790 ICOM_THIS(IDirect3DImpl,iface);
2791 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2793 /* Call functions defined in d3ddevices.c */
2794 if (!d3d_OpenGL_dx3(cb, context))
2795 return DD_OK;
2797 return DD_OK;
2800 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2801 LPDIRECT3DLIGHT *lplight,
2802 IUnknown *lpunk)
2804 ICOM_THIS(IDirect3DImpl,iface);
2805 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2807 /* Call the creation function that is located in d3dlight.c */
2808 *lplight = d3dlight_create_dx3(This);
2810 return DD_OK;
2813 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2814 LPDIRECT3DMATERIAL *lpmaterial,
2815 IUnknown *lpunk)
2817 ICOM_THIS(IDirect3DImpl,iface);
2818 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2820 /* Call the creation function that is located in d3dviewport.c */
2821 *lpmaterial = d3dmaterial_create(This);
2823 return DD_OK;
2826 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2827 LPDIRECT3DVIEWPORT *lpviewport,
2828 IUnknown *lpunk)
2830 ICOM_THIS(IDirect3DImpl,iface);
2831 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2833 /* Call the creation function that is located in d3dviewport.c */
2834 *lpviewport = d3dviewport_create(This);
2836 return DD_OK;
2839 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2840 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2841 LPD3DFINDDEVICERESULT lpfinddevrst)
2843 ICOM_THIS(IDirect3DImpl,iface);
2844 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2846 return DD_OK;
2849 static ICOM_VTABLE(IDirect3D) d3dvt =
2851 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2852 IDirect3DImpl_QueryInterface,
2853 IDirect3DImpl_AddRef,
2854 IDirect3DImpl_Release,
2855 IDirect3DImpl_Initialize,
2856 IDirect3DImpl_EnumDevices,
2857 IDirect3DImpl_CreateLight,
2858 IDirect3DImpl_CreateMaterial,
2859 IDirect3DImpl_CreateViewport,
2860 IDirect3DImpl_FindDevice
2863 /*******************************************************************************
2864 * IDirect3D2
2866 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2867 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2868 ICOM_THIS(IDirect3D2Impl,iface);
2870 /* FIXME: Not sure if this is correct */
2872 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2873 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2874 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2875 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2876 *obj = This->ddraw;
2877 IDirect3D2_AddRef(iface);
2879 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2881 return S_OK;
2883 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2884 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2885 *obj = This;
2886 IDirect3D2_AddRef(iface);
2888 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2890 return S_OK;
2892 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2893 IDirect3DImpl* d3d;
2895 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2896 d3d->ref = 1;
2897 d3d->ddraw = This->ddraw;
2898 IDirect3D2_AddRef(iface);
2899 ICOM_VTBL(d3d) = &d3dvt;
2900 *obj = d3d;
2902 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2904 return S_OK;
2906 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2907 return OLE_E_ENUM_NOMORE;
2910 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2911 ICOM_THIS(IDirect3D2Impl,iface);
2912 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2914 return ++(This->ref);
2917 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2918 ICOM_THIS(IDirect3D2Impl,iface);
2919 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2921 if (!--(This->ref)) {
2922 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2923 HeapFree(GetProcessHeap(),0,This);
2924 return S_OK;
2926 return This->ref;
2929 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2930 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2932 ICOM_THIS(IDirect3D2Impl,iface);
2933 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2935 /* Call functions defined in d3ddevices.c */
2936 if (!d3d_OpenGL(cb, context))
2937 return DD_OK;
2939 return DD_OK;
2942 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2943 LPDIRECT3DLIGHT *lplight,
2944 IUnknown *lpunk)
2946 ICOM_THIS(IDirect3D2Impl,iface);
2947 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2949 /* Call the creation function that is located in d3dlight.c */
2950 *lplight = d3dlight_create(This);
2952 return DD_OK;
2955 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2956 LPDIRECT3DMATERIAL2 *lpmaterial,
2957 IUnknown *lpunk)
2959 ICOM_THIS(IDirect3D2Impl,iface);
2960 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2962 /* Call the creation function that is located in d3dviewport.c */
2963 *lpmaterial = d3dmaterial2_create(This);
2965 return DD_OK;
2968 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2969 LPDIRECT3DVIEWPORT2 *lpviewport,
2970 IUnknown *lpunk)
2972 ICOM_THIS(IDirect3D2Impl,iface);
2973 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2975 /* Call the creation function that is located in d3dviewport.c */
2976 *lpviewport = d3dviewport2_create(This);
2978 return DD_OK;
2981 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2982 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2983 LPD3DFINDDEVICERESULT lpfinddevrst)
2985 ICOM_THIS(IDirect3D2Impl,iface);
2986 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2988 return DD_OK;
2991 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2992 REFCLSID rguid,
2993 LPDIRECTDRAWSURFACE surface,
2994 LPDIRECT3DDEVICE2 *device)
2996 ICOM_THIS(IDirect3D2Impl,iface);
2998 FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
3000 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
3001 IDirect3D2_AddRef(iface);
3002 return DD_OK;
3005 return DDERR_INVALIDPARAMS;
3008 static ICOM_VTABLE(IDirect3D2) d3d2vt =
3010 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3011 IDirect3D2Impl_QueryInterface,
3012 IDirect3D2Impl_AddRef,
3013 IDirect3D2Impl_Release,
3014 IDirect3D2Impl_EnumDevices,
3015 IDirect3D2Impl_CreateLight,
3016 IDirect3D2Impl_CreateMaterial,
3017 IDirect3D2Impl_CreateViewport,
3018 IDirect3D2Impl_FindDevice,
3019 IDirect3D2Impl_CreateDevice
3022 /*******************************************************************************
3023 * IDirectDraw
3026 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
3027 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
3029 static INT ddrawXlibThisOffset = 0;
3031 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
3032 IDirectDrawSurfaceImpl* lpdsf)
3034 int bpp;
3036 /* The surface was already allocated when entering in this function */
3037 TRACE("using system memory for a surface (%p) \n", lpdsf);
3039 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
3040 /* This is a Z Buffer */
3041 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
3042 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
3043 } else {
3044 /* This is a standard image */
3045 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
3046 /* No pixel format => use DirectDraw's format */
3047 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3048 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
3050 bpp = GET_BPP(lpdsf->s.surface_desc);
3053 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
3054 /* The surface was preallocated : seems that we have nothing to do :-) */
3055 ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
3058 assert(bpp);
3059 FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf->s.surface_desc.dwWidth,lpdsf->s.surface_desc.dwHeight,bpp);
3061 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
3062 lpdsf->s.surface_desc.u1.lpSurface =
3063 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
3064 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
3066 return DD_OK;
3069 #ifdef HAVE_LIBXXF86DGA
3070 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
3071 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3073 ICOM_THIS(IDirectDraw2Impl,iface);
3074 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3075 int i, fbheight = This->e.dga.fb_height;
3077 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
3078 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3080 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3081 GetProcessHeap(),
3082 HEAP_ZERO_MEMORY,
3083 sizeof(IDirectDrawSurfaceImpl)
3085 IDirectDraw2_AddRef(iface);
3087 (*ilpdsf)->ref = 1;
3088 #ifdef HAVE_LIBXXF86DGA2
3089 if (This->e.dga.version == 2)
3090 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
3091 else
3092 #endif /* defined(HAVE_LIBXXF86DGA2) */
3093 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
3094 (*ilpdsf)->s.ddraw = This;
3095 (*ilpdsf)->s.palette = NULL;
3096 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
3097 (*ilpdsf)->s.lpClipper = NULL;
3099 /* Copy the surface description */
3100 (*ilpdsf)->s.surface_desc = *lpddsd;
3102 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3103 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3104 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3105 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3107 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3109 /* Check if this a 'primary surface' or not */
3110 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3111 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3112 /* This is THE primary surface => there is DGA-specific code */
3114 /* First, store the surface description */
3115 (*ilpdsf)->s.surface_desc = *lpddsd;
3117 /* Find a viewport */
3118 for (i=0;i<32;i++)
3119 if (!(This->e.dga.vpmask & (1<<i)))
3120 break;
3121 TRACE("using viewport %d for a primary surface\n",i);
3122 /* if i == 32 or maximum ... return error */
3123 This->e.dga.vpmask|=(1<<i);
3124 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
3125 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
3127 (*ilpdsf)->s.surface_desc.u1.lpSurface =
3128 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3130 (*ilpdsf)->t.dga.fb_height = i*fbheight;
3132 /* Add flags if there were not present */
3133 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3134 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3135 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3136 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
3137 /* We put our surface always in video memory */
3138 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3139 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3140 (*ilpdsf)->s.chain = NULL;
3142 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3143 IDirectDrawSurface4Impl* back;
3144 int bbc;
3146 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
3147 int i;
3149 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3150 GetProcessHeap(),
3151 HEAP_ZERO_MEMORY,
3152 sizeof(IDirectDrawSurface4Impl)
3154 IDirectDraw2_AddRef(iface);
3155 back->ref = 1;
3156 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
3157 for (i=0;i<32;i++)
3158 if (!(This->e.dga.vpmask & (1<<i)))
3159 break;
3160 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
3161 /* if i == 32 or maximum ... return error */
3162 This->e.dga.vpmask|=(1<<i);
3163 back->t.dga.fb_height = i*fbheight;
3164 /* Copy the surface description from the front buffer */
3165 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3166 /* Change the parameters that are not the same */
3167 back->s.surface_desc.u1.lpSurface =
3168 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3170 back->s.ddraw = This;
3171 /* Add relevant info to front and back buffers */
3172 /* FIXME: backbuffer/frontbuffer handling broken here, but
3173 * will be fixed up in _Flip().
3175 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3176 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
3177 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3178 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3179 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3182 } else {
3183 /* There is no DGA-specific code here...
3184 Go to the common surface creation function */
3185 return common_off_screen_CreateSurface(This, *ilpdsf);
3187 return DD_OK;
3189 #endif /* defined(HAVE_LIBXXF86DGA) */
3191 #ifdef HAVE_LIBXXSHM
3192 /* Error handlers for Image creation */
3193 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
3194 XShmErrorFlag = 1;
3195 return 0;
3198 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3199 XImage *img;
3200 int (*WineXHandler)(Display *, XErrorEvent *);
3202 img = TSXShmCreateImage(display,
3203 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3204 This->d.pixmap_depth,
3205 ZPixmap,
3206 NULL,
3207 &(lpdsf->t.xlib.shminfo),
3208 lpdsf->s.surface_desc.dwWidth,
3209 lpdsf->s.surface_desc.dwHeight
3212 if (img == NULL) {
3213 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3214 This->e.xlib.xshm_active = 0;
3215 return NULL;
3218 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3219 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3220 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3221 This->e.xlib.xshm_active = 0;
3222 TSXDestroyImage(img);
3223 return NULL;
3226 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3228 if (img->data == (char *) -1) {
3229 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3230 This->e.xlib.xshm_active = 0;
3231 TSXDestroyImage(img);
3232 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3233 return NULL;
3235 lpdsf->t.xlib.shminfo.readOnly = False;
3237 /* This is where things start to get trickier....
3238 * First, we flush the current X connections to be sure to catch all
3239 * non-XShm related errors
3241 TSXSync(display, False);
3242 /* Then we enter in the non-thread safe part of the tests */
3243 EnterCriticalSection( &X11DRV_CritSection );
3245 /* Reset the error flag, sets our new error handler and try to attach
3246 * the surface
3248 XShmErrorFlag = 0;
3249 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3250 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3251 XSync(display, False);
3253 /* Check the error flag */
3254 if (XShmErrorFlag) {
3255 /* An error occured */
3256 XFlush(display);
3257 XShmErrorFlag = 0;
3258 XDestroyImage(img);
3259 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3260 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3261 XSetErrorHandler(WineXHandler);
3263 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3264 This->e.xlib.xshm_active = 0;
3266 /* Leave the critical section */
3267 LeaveCriticalSection( &X11DRV_CritSection );
3268 return NULL;
3270 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3271 * this works, but it may be a bit overkill....
3273 XSetErrorHandler(WineXHandler);
3274 LeaveCriticalSection( &X11DRV_CritSection );
3276 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3278 if (This->d.pixel_convert != NULL) {
3279 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3280 GetProcessHeap(),
3281 HEAP_ZERO_MEMORY,
3282 lpdsf->s.surface_desc.dwWidth *
3283 lpdsf->s.surface_desc.dwHeight *
3284 PFGET_BPP(This->d.directdraw_pixelformat)
3286 } else {
3287 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3289 return img;
3291 #endif /* HAVE_LIBXXSHM */
3293 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3294 XImage *img = NULL;
3295 void *img_data;
3297 #ifdef HAVE_LIBXXSHM
3298 if (This->e.xlib.xshm_active)
3299 img = create_xshmimage(This, lpdsf);
3301 if (img == NULL) {
3302 #endif
3303 /* Allocate surface memory */
3304 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3305 GetProcessHeap(),HEAP_ZERO_MEMORY,
3306 lpdsf->s.surface_desc.dwWidth *
3307 lpdsf->s.surface_desc.dwHeight *
3308 PFGET_BPP(This->d.directdraw_pixelformat)
3311 if (This->d.pixel_convert != NULL) {
3312 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3313 lpdsf->s.surface_desc.dwWidth *
3314 lpdsf->s.surface_desc.dwHeight *
3315 PFGET_BPP(This->d.screen_pixelformat)
3317 } else {
3318 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3321 /* In this case, create an XImage */
3322 img = TSXCreateImage(display,
3323 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3324 This->d.pixmap_depth,
3325 ZPixmap,
3327 img_data,
3328 lpdsf->s.surface_desc.dwWidth,
3329 lpdsf->s.surface_desc.dwHeight,
3331 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3333 #ifdef HAVE_LIBXXSHM
3335 #endif
3336 if (This->d.pixel_convert != NULL)
3337 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3338 else
3339 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3340 return img;
3343 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3344 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3346 ICOM_THIS(IDirectDraw2Impl,iface);
3347 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3349 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3351 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3353 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3354 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3357 IDirectDraw2_AddRef(iface);
3359 (*ilpdsf)->s.ddraw = This;
3360 (*ilpdsf)->ref = 1;
3361 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3362 (*ilpdsf)->s.palette = NULL;
3363 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3364 (*ilpdsf)->s.lpClipper = NULL;
3366 /* Copy the surface description */
3367 (*ilpdsf)->s.surface_desc = *lpddsd;
3369 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3370 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3371 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3372 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3373 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3375 /* Check if this a 'primary surface' or not */
3376 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3377 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3378 XImage *img;
3380 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3381 /* Create the XImage */
3382 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3383 if (img == NULL)
3384 return DDERR_OUTOFMEMORY;
3385 (*ilpdsf)->t.xlib.image = img;
3387 /* Add flags if there were not present */
3388 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3389 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3390 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3391 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3392 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3394 /* Check for backbuffers */
3395 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3396 IDirectDrawSurface4Impl* back;
3397 XImage *img;
3398 int i;
3400 for (i=lpddsd->dwBackBufferCount;i--;) {
3401 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3402 GetProcessHeap(),HEAP_ZERO_MEMORY,
3403 sizeof(IDirectDrawSurface4Impl)
3406 TRACE("allocated back-buffer (%p)\n", back);
3408 IDirectDraw2_AddRef(iface);
3409 back->s.ddraw = This;
3411 back->ref = 1;
3412 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3413 /* Copy the surface description from the front buffer */
3414 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3416 /* Create the XImage */
3417 img = create_ximage(This, back);
3418 if (img == NULL)
3419 return DDERR_OUTOFMEMORY;
3420 back->t.xlib.image = img;
3422 /* Add relevant info to front and back buffers */
3423 /* FIXME: backbuffer/frontbuffer handling broken here, but
3424 * will be fixed up in _Flip().
3426 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3427 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3428 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3429 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3430 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3433 } else {
3434 /* There is no Xlib-specific code here...
3435 Go to the common surface creation function */
3436 return common_off_screen_CreateSurface(This, *ilpdsf);
3438 return DD_OK;
3441 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3442 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3444 ICOM_THIS(IDirectDraw2Impl,iface);
3445 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3446 *dst = src; /* FIXME */
3447 return DD_OK;
3451 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3452 * even when the approbiate bitmasks are not specified.
3454 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3455 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3457 ICOM_THIS(IDirectDraw2Impl,iface);
3458 int i;
3459 const struct {
3460 int mask;
3461 char *name;
3462 } flags[] = {
3463 #define FE(x) { x, #x},
3464 FE(DDSCL_FULLSCREEN)
3465 FE(DDSCL_ALLOWREBOOT)
3466 FE(DDSCL_NOWINDOWCHANGES)
3467 FE(DDSCL_NORMAL)
3468 FE(DDSCL_ALLOWMODEX)
3469 FE(DDSCL_EXCLUSIVE)
3470 FE(DDSCL_SETFOCUSWINDOW)
3471 FE(DDSCL_SETDEVICEWINDOW)
3472 FE(DDSCL_CREATEDEVICEWINDOW)
3473 #undef FE
3476 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3477 if (TRACE_ON(ddraw)) {
3478 DPRINTF(" - ");
3479 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
3480 if (flags[i].mask & cooplevel) {
3481 DPRINTF("%s ",flags[i].name);
3484 DPRINTF("\n");
3486 This->d.mainWindow = hwnd;
3488 /* This will be overwritten in the case of Full Screen mode.
3489 Windowed games could work with that :-) */
3490 if (hwnd)
3492 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3493 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3494 WIN_ReleaseWndPtr(tmpWnd);
3496 if( !This->d.drawable ) {
3497 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3498 WIN_ReleaseDesktop();
3500 TRACE("Setting drawable to %ld\n", This->d.drawable);
3503 return DD_OK;
3506 #ifdef HAVE_LIBXXF86DGA2
3507 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel(
3508 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3510 ICOM_THIS(IDirectDraw2Impl,iface);
3511 HRESULT ret;
3512 int evbase, erbase;
3514 ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel);
3516 if (This->e.dga.version != 2) {
3517 return ret;
3518 } else {
3519 if (ret != DD_OK)
3520 return ret;
3522 TSXDGAQueryExtension(display, &evbase, &erbase);
3524 /* Now, start handling of DGA events giving the handle to the DDraw window
3525 as the window for which the event will be reported */
3526 TSXDGASelectInput(display, DefaultScreen(display),
3527 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3528 X11DRV_EVENT_SetDGAStatus(hwnd, evbase);
3530 return DD_OK;
3533 #endif
3535 /* Small helper to either use the cooperative window or create a new
3536 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3538 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3539 RECT rect;
3541 /* Do not destroy the application supplied cooperative window */
3542 if (This->d.window && This->d.window != This->d.mainWindow) {
3543 DestroyWindow(This->d.window);
3544 This->d.window = 0;
3546 /* Sanity check cooperative window before assigning it to drawing. */
3547 if ( IsWindow(This->d.mainWindow) &&
3548 IsWindowVisible(This->d.mainWindow)
3550 /* if it does not fit, resize the cooperative window.
3551 * and hope the app likes it
3553 GetWindowRect(This->d.mainWindow,&rect);
3554 if ((((rect.right-rect.left) >= This->d.width) &&
3555 ((rect.bottom-rect.top) >= This->d.height))
3557 This->d.window = This->d.mainWindow;
3558 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3562 /* ... failed, create new one. */
3563 if (!This->d.window) {
3564 This->d.window = CreateWindowExA(
3566 "WINE_DirectDraw",
3567 "WINE_DirectDraw",
3568 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3569 0,0,
3570 This->d.width,
3571 This->d.height,
3575 NULL
3577 /*Store THIS with the window. We'll use it in the window procedure*/
3578 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3579 ShowWindow(This->d.window,TRUE);
3580 UpdateWindow(This->d.window);
3582 SetFocus(This->d.window);
3585 static int _common_depth_to_pixelformat(DWORD depth,
3586 DDPIXELFORMAT *pixelformat,
3587 DDPIXELFORMAT *screen_pixelformat,
3588 int *pix_depth) {
3589 XVisualInfo *vi;
3590 XPixmapFormatValues *pf;
3591 XVisualInfo vt;
3592 int nvisuals, npixmap, i;
3593 int match = 0;
3594 int index = -2;
3596 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3597 pf = XListPixmapFormats(display, &npixmap);
3599 for (i = 0; i < npixmap; i++) {
3600 if (pf[i].depth == depth) {
3601 int j;
3603 for (j = 0; j < nvisuals; j++) {
3604 if (vi[j].depth == pf[i].depth) {
3605 pixelformat->dwSize = sizeof(*pixelformat);
3606 if (depth == 8) {
3607 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3608 pixelformat->u1.dwRBitMask = 0;
3609 pixelformat->u2.dwGBitMask = 0;
3610 pixelformat->u3.dwBBitMask = 0;
3611 } else {
3612 pixelformat->dwFlags = DDPF_RGB;
3613 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3614 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3615 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3617 pixelformat->dwFourCC = 0;
3618 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3619 pixelformat->u4.dwRGBAlphaBitMask= 0;
3621 *screen_pixelformat = *pixelformat;
3623 if (pix_depth != NULL)
3624 *pix_depth = vi[j].depth;
3626 match = 1;
3627 index = -1;
3629 goto clean_up_and_exit;
3633 ERR("No visual corresponding to pixmap format !\n");
3637 if (match == 0) {
3638 /* We try now to find an emulated mode */
3639 int c;
3641 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3642 if (ModeEmulations[c].dest.depth == depth) {
3643 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3644 for (i = 0; i < npixmap; i++) {
3645 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3646 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3647 int j;
3649 for (j = 0; j < nvisuals; j++) {
3650 if (vi[j].depth == pf[i].depth) {
3651 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3652 screen_pixelformat->dwFlags = DDPF_RGB;
3653 screen_pixelformat->dwFourCC = 0;
3654 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3655 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3656 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3657 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3658 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3660 pixelformat->dwSize = sizeof(*pixelformat);
3661 pixelformat->dwFourCC = 0;
3662 if (depth == 8) {
3663 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3664 pixelformat->u.dwRGBBitCount = 8;
3665 pixelformat->u1.dwRBitMask = 0;
3666 pixelformat->u2.dwGBitMask = 0;
3667 pixelformat->u3.dwBBitMask = 0;
3668 } else {
3669 pixelformat->dwFlags = DDPF_RGB;
3670 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3671 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3672 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3673 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3675 pixelformat->u4.dwRGBAlphaBitMask= 0;
3677 if (pix_depth != NULL)
3678 *pix_depth = vi[j].depth;
3680 match = 2;
3681 index = c;
3683 goto clean_up_and_exit;
3686 ERR("No visual corresponding to pixmap format !\n");
3694 clean_up_and_exit:
3695 TSXFree(vi);
3696 TSXFree(pf);
3698 return index;
3701 #ifdef HAVE_LIBXXF86DGA2
3702 static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl *This, int mode) {
3703 DDPIXELFORMAT *pf = &(This->d.directdraw_pixelformat);
3705 /* Now, get the device / mode description */
3706 This->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode);
3708 This->e.dga.fb_width = This->e.dga.dev->mode.imageWidth;
3709 TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
3710 This->e.dga.fb_height = This->e.dga.dev->mode.viewportHeight;
3711 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
3712 This->e.dga.dev->data,
3713 This->e.dga.dev->mode.imageWidth,
3714 (This->e.dga.dev->mode.imageWidth *
3715 This->e.dga.dev->mode.imageHeight *
3716 (This->e.dga.dev->mode.bitsPerPixel / 8))
3718 TRACE("viewport height: %d\n", This->e.dga.dev->mode.viewportHeight);
3719 /* Get the screen dimensions as seen by Wine.
3720 In that case, it may be better to ignore the -desktop mode and return the
3721 real screen size => print a warning */
3722 This->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3723 This->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3724 This->e.dga.fb_addr = This->e.dga.dev->data;
3725 This->e.dga.fb_memsize = (This->e.dga.dev->mode.imageWidth *
3726 This->e.dga.dev->mode.imageHeight *
3727 (This->e.dga.dev->mode.bitsPerPixel / 8));
3728 This->e.dga.vpmask = 0;
3730 /* Fill the screen pixelformat */
3731 pf->dwSize = sizeof(DDPIXELFORMAT);
3732 pf->dwFourCC = 0;
3733 pf->u.dwRGBBitCount = This->e.dga.dev->mode.bitsPerPixel;
3734 if (This->e.dga.dev->mode.depth == 8) {
3735 pf->dwFlags = DDPF_PALETTEINDEXED8;
3736 pf->u1.dwRBitMask = 0;
3737 pf->u2.dwGBitMask = 0;
3738 pf->u3.dwBBitMask = 0;
3739 } else {
3740 pf->dwFlags = DDPF_RGB;
3741 pf->u1.dwRBitMask = This->e.dga.dev->mode.redMask;
3742 pf->u2.dwGBitMask = This->e.dga.dev->mode.greenMask;
3743 pf->u3.dwBBitMask = This->e.dga.dev->mode.blueMask;
3745 pf->u4.dwRGBAlphaBitMask= 0;
3747 This->d.screen_pixelformat = *pf;
3749 #endif /* defined(HAVE_LIBXXF86DGA2) */
3751 #ifdef HAVE_LIBXXF86DGA
3752 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3753 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3755 ICOM_THIS(IDirectDrawImpl,iface);
3756 int i,mode_count;
3758 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3760 #ifdef HAVE_LIBXXF86DGA2
3761 if (This->e.dga.version == 2) {
3762 XDGAMode *modes = This->e.dga.modes;
3763 int mode_to_use = -1;
3765 /* Search in the list a display mode that corresponds to what is requested */
3766 for (i = 0; i < This->e.dga.num_modes; i++) {
3767 if ((height == modes[i].viewportHeight) &&
3768 (width == modes[i].viewportWidth) &&
3769 (depth == modes[i].depth)) {
3770 mode_to_use = modes[i].num;
3774 if (mode_to_use < 0) {
3775 ERR("Could not find matching mode !!!\n");
3776 return DDERR_UNSUPPORTEDMODE;
3777 } else {
3778 TRACE("Using mode number %d\n", mode_to_use);
3780 TSXDGACloseFramebuffer(display, DefaultScreen(display));
3782 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
3783 ERR("Error opening the frame buffer !!!\n");
3785 return DDERR_GENERIC;
3788 /* Initialize the frame buffer */
3789 _DGA_Initialize_FrameBuffer(This, mode_to_use);
3791 /* Re-get (if necessary) the DGA events */
3792 TSXDGASelectInput(display, DefaultScreen(display),
3793 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3796 return DD_OK;
3798 #endif /* defined(HAVE_LIBXXF86DGA2) */
3800 /* We hope getting the asked for depth */
3801 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3802 /* I.e. no visual found or emulated */
3803 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3804 return DDERR_UNSUPPORTEDMODE;
3807 if (This->d.width < width) {
3808 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3809 return DDERR_UNSUPPORTEDMODE;
3811 This->d.width = width;
3812 This->d.height = height;
3814 /* adjust fb_height, so we don't overlap */
3815 if (This->e.dga.fb_height < height)
3816 This->e.dga.fb_height = height;
3817 _common_IDirectDrawImpl_SetDisplayMode(This);
3819 #ifdef HAVE_LIBXXF86VM
3820 #ifdef HAVE_LIBXXF86DGA2
3821 if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3822 #endif /* defined(HAVE_LIBXXF86DGA2) */
3824 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3825 XF86VidModeModeLine mod_tmp;
3826 /* int dotclock_tmp; */
3828 /* save original video mode and set fullscreen if available*/
3829 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3830 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3831 orig_mode->hdisplay = mod_tmp.hdisplay;
3832 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3833 orig_mode->hsyncend = mod_tmp.hsyncend;
3834 orig_mode->htotal = mod_tmp.htotal;
3835 orig_mode->vdisplay = mod_tmp.vdisplay;
3836 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3837 orig_mode->vsyncend = mod_tmp.vsyncend;
3838 orig_mode->vtotal = mod_tmp.vtotal;
3839 orig_mode->flags = mod_tmp.flags;
3840 orig_mode->private = mod_tmp.private;
3842 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3843 for (i=0;i<mode_count;i++)
3845 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3847 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3848 *vidmode = *(all_modes[i]);
3849 break;
3850 } else
3851 TSXFree(all_modes[i]->private);
3853 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3854 TSXFree(all_modes);
3856 if (!vidmode)
3857 WARN("Fullscreen mode not available!\n");
3859 if (vidmode)
3861 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3862 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3863 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3864 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3865 #endif
3868 #endif
3870 /* FIXME: this function OVERWRITES several signal handlers.
3871 * can we save them? and restore them later? In a way that
3872 * it works for the library too?
3874 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3875 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3877 #ifdef RESTORE_SIGNALS
3878 SIGNAL_Init();
3879 #endif
3880 return DD_OK;
3882 #endif /* defined(HAVE_LIBXXF86DGA) */
3884 /* *************************************
3885 16 / 15 bpp to palettized 8 bpp
3886 ************************************* */
3887 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3888 unsigned char *c_src = (unsigned char *) src;
3889 unsigned short *c_dst = (unsigned short *) dst;
3890 int y;
3892 if (palette != NULL) {
3893 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3895 for (y = height; y--; ) {
3896 #if defined(__i386__) && defined(__GNUC__)
3897 /* gcc generates slightly inefficient code for the the copy / lookup,
3898 * it generates one excess memory access (to pal) per pixel. Since
3899 * we know that pal is not modified by the memory write we can
3900 * put it into a register and reduce the number of memory accesses
3901 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3902 * (This is not guaranteed to be the fastest method.)
3904 __asm__ __volatile__(
3905 "xor %%eax,%%eax\n"
3906 "1:\n"
3907 " lodsb\n"
3908 " movw (%%edx,%%eax,2),%%ax\n"
3909 " stosw\n"
3910 " xor %%eax,%%eax\n"
3911 " loop 1b\n"
3912 : "=S" (c_src), "=D" (c_dst)
3913 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3914 : "eax", "cc", "memory"
3916 c_src+=(pitch-width);
3917 #else
3918 unsigned char * srclineend = c_src+width;
3919 while (c_src < srclineend)
3920 *c_dst++ = pal[*c_src++];
3921 c_src+=(pitch-width);
3922 #endif
3924 } else {
3925 WARN("No palette set...\n");
3926 memset(dst, 0, width * height * 2);
3929 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3930 int i;
3931 unsigned short *pal = (unsigned short *) screen_palette;
3933 for (i = 0; i < count; i++)
3934 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3935 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3936 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3938 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3939 int i;
3940 unsigned short *pal = (unsigned short *) screen_palette;
3942 for (i = 0; i < count; i++)
3943 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3944 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3945 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3948 /* *************************************
3949 24 to palettized 8 bpp
3950 ************************************* */
3951 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3952 unsigned char *c_src = (unsigned char *) src;
3953 unsigned char *c_dst = (unsigned char *) dst;
3954 int y;
3956 if (palette != NULL) {
3957 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3959 for (y = height; y--; ) {
3960 unsigned char * srclineend = c_src+width;
3961 while (c_src < srclineend ) {
3962 register long pixel = pal[*c_src++];
3963 *c_dst++ = pixel;
3964 *c_dst++ = pixel>>8;
3965 *c_dst++ = pixel>>16;
3967 c_src+=(pitch-width);
3969 } else {
3970 WARN("No palette set...\n");
3971 memset(dst, 0, width * height * 4);
3974 /* *************************************
3975 32 bpp to palettized 8 bpp
3976 ************************************* */
3977 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3978 unsigned char *c_src = (unsigned char *) src;
3979 unsigned int *c_dst = (unsigned int *) dst;
3980 int y;
3982 if (palette != NULL) {
3983 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3985 for (y = height; y--; ) {
3986 #if defined(__i386__) && defined(__GNUC__)
3987 /* See comment in pixel_convert_16_to_8 */
3988 __asm__ __volatile__(
3989 "xor %%eax,%%eax\n"
3990 "1:\n"
3991 " lodsb\n"
3992 " movl (%%edx,%%eax,4),%%eax\n"
3993 " stosl\n"
3994 " xor %%eax,%%eax\n"
3995 " loop 1b\n"
3996 : "=S" (c_src), "=D" (c_dst)
3997 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3998 : "eax", "cc", "memory"
4000 c_src+=(pitch-width);
4001 #else
4002 unsigned char * srclineend = c_src+width;
4003 while (c_src < srclineend )
4004 *c_dst++ = pal[*c_src++];
4005 c_src+=(pitch-width);
4006 #endif
4008 } else {
4009 WARN("No palette set...\n");
4010 memset(dst, 0, width * height * 4);
4014 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
4015 int i;
4016 unsigned int *pal = (unsigned int *) screen_palette;
4018 for (i = 0; i < count; i++)
4019 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
4020 (((unsigned int) palent[i].peGreen) << 8) |
4021 ((unsigned int) palent[i].peBlue));
4024 /* *************************************
4025 32 bpp to 16 bpp
4026 ************************************* */
4027 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4028 unsigned short *c_src = (unsigned short *) src;
4029 unsigned int *c_dst = (unsigned int *) dst;
4030 int y;
4032 for (y = height; y--; ) {
4033 unsigned short * srclineend = c_src+width;
4034 while (c_src < srclineend ) {
4035 *c_dst++ = (((*c_src & 0xF800) << 8) |
4036 ((*c_src & 0x07E0) << 5) |
4037 ((*c_src & 0x001F) << 3));
4038 c_src++;
4040 c_src+=((pitch/2)-width);
4045 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
4046 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
4048 ICOM_THIS(IDirectDrawImpl,iface);
4049 char buf[200];
4050 WND *tmpWnd;
4051 int c;
4053 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
4054 This, width, height, depth);
4056 switch ((c = _common_depth_to_pixelformat(depth,
4057 &(This->d.directdraw_pixelformat),
4058 &(This->d.screen_pixelformat),
4059 &(This->d.pixmap_depth)))) {
4060 case -2:
4061 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
4062 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
4063 return DDERR_UNSUPPORTEDMODE;
4065 case -1:
4066 /* No convertion */
4067 This->d.pixel_convert = NULL;
4068 This->d.palette_convert = NULL;
4069 break;
4071 default:
4072 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
4074 /* Set the depth convertion routines */
4075 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
4076 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
4079 This->d.width = width;
4080 This->d.height = height;
4082 _common_IDirectDrawImpl_SetDisplayMode(This);
4084 tmpWnd = WIN_FindWndPtr(This->d.window);
4085 This->d.paintable = 1;
4086 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
4087 WIN_ReleaseWndPtr(tmpWnd);
4089 /* We don't have a context for this window. Host off the desktop */
4090 if( !This->d.drawable )
4092 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
4093 WIN_ReleaseDesktop();
4095 TRACE("Setting drawable to %ld\n", This->d.drawable);
4097 return DD_OK;
4100 #ifdef HAVE_LIBXXF86DGA
4101 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
4102 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4104 ICOM_THIS(IDirectDraw2Impl,iface);
4105 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4106 if (!caps1 && !caps2)
4107 return DDERR_INVALIDPARAMS;
4108 if (caps1) {
4109 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
4110 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4111 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4113 if (caps2) {
4114 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
4115 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4116 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4118 return DD_OK;
4120 #endif /* defined(HAVE_LIBXXF86DGA) */
4122 static void fill_caps(LPDDCAPS caps) {
4123 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4124 Need to be fixed, though.. */
4125 if (caps == NULL)
4126 return;
4128 caps->dwSize = sizeof(*caps);
4129 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
4130 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
4131 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
4132 caps->dwFXCaps = 0;
4133 caps->dwFXAlphaCaps = 0;
4134 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
4135 caps->dwSVCaps = 0;
4136 caps->dwZBufferBitDepths = DDBD_16;
4137 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4138 to put textures in video memory.
4139 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4140 for example) ? */
4141 caps->dwVidMemTotal = 8192 * 1024;
4142 caps->dwVidMemFree = 8192 * 1024;
4143 /* These are all the supported capabilities of the surfaces */
4144 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
4145 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
4146 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
4147 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
4148 #ifdef HAVE_MESAGL
4149 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
4150 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
4151 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
4152 #endif
4155 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
4156 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4158 ICOM_THIS(IDirectDraw2Impl,iface);
4159 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4161 /* Put the same caps for the two capabilities */
4162 fill_caps(caps1);
4163 fill_caps(caps2);
4165 return DD_OK;
4168 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
4169 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
4171 ICOM_THIS(IDirectDraw2Impl,iface);
4172 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
4173 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4174 This,x,ilpddclip,lpunk
4176 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
4177 (*ilpddclip)->ref = 1;
4178 ICOM_VTBL(*ilpddclip) = &ddclipvt;
4179 return DD_OK;
4182 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
4183 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
4185 int size = 0;
4187 if (TRACE_ON(ddraw))
4188 _dump_paletteformat(dwFlags);
4190 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
4191 if (*lpddpal == NULL) return E_OUTOFMEMORY;
4192 (*lpddpal)->ref = 1;
4193 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
4194 (*lpddpal)->installed = 0;
4196 if (dwFlags & DDPCAPS_1BIT)
4197 size = 2;
4198 else if (dwFlags & DDPCAPS_2BIT)
4199 size = 4;
4200 else if (dwFlags & DDPCAPS_4BIT)
4201 size = 16;
4202 else if (dwFlags & DDPCAPS_8BIT)
4203 size = 256;
4204 else
4205 ERR("unhandled palette format\n");
4206 *psize = size;
4208 if (palent)
4210 /* Now, if we are in 'depth conversion mode', create the screen palette */
4211 if (This->d.palette_convert != NULL)
4212 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
4214 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
4215 } else if (This->d.palette_convert != NULL) {
4216 /* In that case, put all 0xFF */
4217 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
4220 return DD_OK;
4223 #ifdef HAVE_LIBXXF86DGA
4224 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
4225 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4227 ICOM_THIS(IDirectDraw2Impl,iface);
4228 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4229 HRESULT res;
4230 int xsize = 0,i;
4232 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4233 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4234 if (res != 0) return res;
4235 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
4236 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
4237 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
4238 } else {
4239 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4240 (*ilpddpal)->cm = 0;
4242 if (((*ilpddpal)->cm)&&xsize) {
4243 for (i=0;i<xsize;i++) {
4244 XColor xc;
4246 xc.red = (*ilpddpal)->palents[i].peRed<<8;
4247 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
4248 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
4249 xc.flags = DoRed|DoBlue|DoGreen;
4250 xc.pixel = i;
4251 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
4254 return DD_OK;
4256 #endif /* defined(HAVE_LIBXXF86DGA) */
4258 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
4259 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4261 ICOM_THIS(IDirectDraw2Impl,iface);
4262 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4263 int xsize;
4264 HRESULT res;
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) = &xlib_ddpalvt;
4270 return DD_OK;
4273 #ifdef HAVE_LIBXXF86DGA
4274 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4275 ICOM_THIS(IDirectDraw2Impl,iface);
4276 TRACE("(%p)->()\n",This);
4277 Sleep(1000);
4278 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4279 #ifdef RESTORE_SIGNALS
4280 SIGNAL_Init();
4281 #endif
4282 return DD_OK;
4284 #endif /* defined(HAVE_LIBXXF86DGA) */
4286 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4287 ICOM_THIS(IDirectDraw2Impl,iface);
4288 TRACE("(%p)->RestoreDisplayMode()\n", This);
4289 Sleep(1000);
4290 return DD_OK;
4293 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
4294 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
4296 ICOM_THIS(IDirectDraw2Impl,iface);
4297 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
4298 return DD_OK;
4301 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
4302 ICOM_THIS(IDirectDraw2Impl,iface);
4303 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
4305 return ++(This->ref);
4308 #ifdef HAVE_LIBXXF86DGA
4309 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4310 ICOM_THIS(IDirectDraw2Impl,iface);
4311 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4313 if (!--(This->ref)) {
4314 #ifdef HAVE_LIBXXF86DGA2
4315 if (This->e.dga.version == 2) {
4316 TRACE("Closing access to the FrameBuffer\n");
4317 TSXDGACloseFramebuffer(display, DefaultScreen(display));
4318 TRACE("Going back to normal X mode of operation\n");
4319 TSXDGASetMode(display, DefaultScreen(display), 0);
4321 /* Set the input handling back to absolute */
4322 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
4324 /* Remove the handling of DGA2 events */
4325 X11DRV_EVENT_SetDGAStatus(0, -1);
4327 /* Free the modes list */
4328 TSXFree(This->e.dga.modes);
4329 } else
4330 #endif /* defined(HAVE_LIBXXF86DGA2) */
4331 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4332 if (This->d.window && (This->d.mainWindow != This->d.window))
4333 DestroyWindow(This->d.window);
4334 #ifdef HAVE_LIBXXF86VM
4335 if (orig_mode) {
4336 TSXF86VidModeSwitchToMode(
4337 display,
4338 DefaultScreen(display),
4339 orig_mode);
4340 if (orig_mode->privsize)
4341 TSXFree(orig_mode->private);
4342 free(orig_mode);
4343 orig_mode = NULL;
4345 #endif
4347 #ifdef RESTORE_SIGNALS
4348 SIGNAL_Init();
4349 #endif
4350 HeapFree(GetProcessHeap(),0,This);
4351 return S_OK;
4353 return This->ref;
4355 #endif /* defined(HAVE_LIBXXF86DGA) */
4357 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4358 ICOM_THIS(IDirectDraw2Impl,iface);
4359 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4361 if (!--(This->ref)) {
4362 if (This->d.window && (This->d.mainWindow != This->d.window))
4363 DestroyWindow(This->d.window);
4364 HeapFree(GetProcessHeap(),0,This);
4365 return S_OK;
4367 /* FIXME: destroy window ... */
4368 return This->ref;
4371 #ifdef HAVE_LIBXXF86DGA
4372 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4373 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4375 ICOM_THIS(IDirectDraw2Impl,iface);
4377 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4378 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4379 *obj = This;
4380 IDirectDraw2_AddRef(iface);
4382 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4384 return S_OK;
4386 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4387 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4388 IDirectDraw2_AddRef(iface);
4389 *obj = This;
4391 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4393 return S_OK;
4395 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4396 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4397 IDirectDraw2_AddRef(iface);
4398 *obj = This;
4400 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4402 return S_OK;
4404 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4405 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4406 IDirectDraw2_AddRef(iface);
4407 *obj = This;
4409 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4411 return S_OK;
4413 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4414 IDirect3DImpl* d3d;
4416 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4417 d3d->ref = 1;
4418 d3d->ddraw = (IDirectDrawImpl*)This;
4419 IDirectDraw2_AddRef(iface);
4420 ICOM_VTBL(d3d) = &d3dvt;
4421 *obj = d3d;
4423 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4425 return S_OK;
4427 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4428 IDirect3D2Impl* d3d;
4430 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4431 d3d->ref = 1;
4432 d3d->ddraw = (IDirectDrawImpl*)This;
4433 IDirectDraw2_AddRef(iface);
4434 ICOM_VTBL(d3d) = &d3d2vt;
4435 *obj = d3d;
4437 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4439 return S_OK;
4441 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4442 return OLE_E_ENUM_NOMORE;
4444 #endif /* defined(HAVE_LIBXXF86DGA) */
4446 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4447 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4449 ICOM_THIS(IDirectDraw2Impl,iface);
4451 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4452 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4453 *obj = This;
4454 IDirectDraw2_AddRef(iface);
4456 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4458 return S_OK;
4460 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4461 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4462 IDirectDraw2_AddRef(iface);
4463 *obj = This;
4465 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4467 return S_OK;
4469 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4470 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4471 IDirectDraw2_AddRef(iface);
4472 *obj = This;
4474 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4476 return S_OK;
4478 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4479 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4480 IDirectDraw2_AddRef(iface);
4481 *obj = This;
4483 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4485 return S_OK;
4487 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4488 IDirect3DImpl* d3d;
4490 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4491 d3d->ref = 1;
4492 d3d->ddraw = (IDirectDrawImpl*)This;
4493 IDirectDraw2_AddRef(iface);
4494 ICOM_VTBL(d3d) = &d3dvt;
4495 *obj = d3d;
4497 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4499 return S_OK;
4501 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4502 IDirect3D2Impl* d3d;
4504 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4505 d3d->ref = 1;
4506 d3d->ddraw = (IDirectDrawImpl*)This;
4507 IDirectDraw2_AddRef(iface);
4508 ICOM_VTBL(d3d) = &d3d2vt;
4509 *obj = d3d;
4511 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4513 return S_OK;
4515 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4516 return OLE_E_ENUM_NOMORE;
4519 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4520 LPDIRECTDRAW2 iface,BOOL *status
4522 ICOM_THIS(IDirectDraw2Impl,iface);
4523 TRACE("(%p)->(%p)\n",This,status);
4524 *status = TRUE;
4525 return DD_OK;
4528 #ifdef HAVE_LIBXXF86DGA
4529 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4530 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4532 ICOM_THIS(IDirectDraw2Impl,iface);
4533 DDSURFACEDESC ddsfd;
4534 static struct {
4535 int w,h;
4536 } modes[5] = { /* some of the usual modes */
4537 {512,384},
4538 {640,400},
4539 {640,480},
4540 {800,600},
4541 {1024,768},
4543 static int depths[4] = {8,16,24,32};
4544 int i,j;
4546 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4547 ddsfd.dwSize = sizeof(ddsfd);
4548 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4549 if (dwFlags & DDEDM_REFRESHRATES) {
4550 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4551 ddsfd.u.dwRefreshRate = 60;
4553 ddsfd.ddsCaps.dwCaps = 0;
4554 ddsfd.dwBackBufferCount = 1;
4556 #ifdef HAVE_LIBXXF86DGA2
4557 if (This->e.dga.version == 2) {
4558 XDGAMode *modes = This->e.dga.modes;
4560 ddsfd.dwFlags |= DDSD_PITCH;
4561 for (i = 0; i < This->e.dga.num_modes; i++) {
4562 if (TRACE_ON(ddraw)) {
4563 DPRINTF(" Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
4564 modes[i].num,
4565 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
4566 modes[i].viewportWidth, modes[i].viewportHeight,
4567 modes[i].depth);
4568 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
4569 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
4570 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
4571 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
4572 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
4573 DPRINTF("\n");
4575 /* Fill the pixel format */
4576 ddsfd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
4577 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4578 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4579 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = modes[i].bitsPerPixel;
4580 if (modes[i].depth == 8) {
4581 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4582 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4583 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4584 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4585 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4586 } else {
4587 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4588 ddsfd.ddpfPixelFormat.u1.dwRBitMask = modes[i].redMask;
4589 ddsfd.ddpfPixelFormat.u2.dwGBitMask = modes[i].greenMask;
4590 ddsfd.ddpfPixelFormat.u3.dwBBitMask = modes[i].blueMask;
4593 ddsfd.dwWidth = modes[i].viewportWidth;
4594 ddsfd.dwHeight = modes[i].viewportHeight;
4595 ddsfd.lPitch = modes[i].imageWidth;
4597 /* Send mode to the application */
4598 if (!modescb(&ddsfd,context)) return DD_OK;
4600 } else {
4601 #endif
4602 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4603 ddsfd.dwBackBufferCount = 1;
4604 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4605 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4606 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4607 /* FIXME: those masks would have to be set in depth > 8 */
4608 if (depths[i]==8) {
4609 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4610 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4611 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4612 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4613 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4614 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4615 } else {
4616 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4618 /* FIXME: We should query those from X itself */
4619 switch (depths[i]) {
4620 case 16:
4621 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4622 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4623 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4624 break;
4625 case 24:
4626 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4627 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4628 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4629 break;
4630 case 32:
4631 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4632 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4633 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4634 break;
4638 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4639 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4640 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4641 if (!modescb(&ddsfd,context)) return DD_OK;
4643 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4644 ddsfd.dwWidth = modes[j].w;
4645 ddsfd.dwHeight = modes[j].h;
4646 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4647 if (!modescb(&ddsfd,context)) return DD_OK;
4650 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4651 /* modeX is not standard VGA */
4653 ddsfd.dwHeight = 200;
4654 ddsfd.dwWidth = 320;
4655 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4656 if (!modescb(&ddsfd,context)) return DD_OK;
4659 #ifdef HAVE_LIBXXF86DGA2
4661 #endif
4662 return DD_OK;
4664 #endif /* defined(HAVE_LIBXXF86DGA) */
4666 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4667 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4669 ICOM_THIS(IDirectDraw2Impl,iface);
4670 XVisualInfo *vi;
4671 XPixmapFormatValues *pf;
4672 XVisualInfo vt;
4673 int xbpp, nvisuals, npixmap, i, emu;
4674 int has_mode[] = { 0, 0, 0, 0 };
4675 int has_depth[] = { 8, 15, 16, 24 };
4676 DDSURFACEDESC ddsfd;
4677 static struct {
4678 int w,h;
4679 } modes[] = { /* some of the usual modes */
4680 {512,384},
4681 {640,400},
4682 {640,480},
4683 {800,600},
4684 {1024,768},
4685 {1280,1024}
4687 DWORD maxWidth, maxHeight;
4689 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4690 ddsfd.dwSize = sizeof(ddsfd);
4691 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_PITCH;
4692 if (dwFlags & DDEDM_REFRESHRATES) {
4693 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4694 ddsfd.u.dwRefreshRate = 60;
4696 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4697 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4699 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4700 pf = XListPixmapFormats(display, &npixmap);
4702 i = 0;
4703 emu = 0;
4704 while ((i < npixmap) || (emu != 4)) {
4705 int mode_index = 0;
4706 int send_mode = 0;
4707 int j;
4709 if (i < npixmap) {
4710 for (j = 0; j < 4; j++) {
4711 if (has_depth[j] == pf[i].depth) {
4712 mode_index = j;
4713 break;
4716 if (j == 4) {
4717 i++;
4718 continue;
4722 if (has_mode[mode_index] == 0) {
4723 if (mode_index == 0) {
4724 send_mode = 1;
4726 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4727 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4728 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4729 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4730 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4731 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4732 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4733 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4734 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4736 xbpp = 1;
4738 has_mode[mode_index] = 1;
4739 } else {
4740 /* All the 'true color' depths (15, 16 and 24)
4741 First, find the corresponding visual to extract the bit masks */
4742 for (j = 0; j < nvisuals; j++) {
4743 if (vi[j].depth == pf[i].depth) {
4744 ddsfd.ddsCaps.dwCaps = 0;
4745 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4746 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4747 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4748 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4749 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4750 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4751 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4752 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4754 xbpp = pf[i].bits_per_pixel/8;
4756 send_mode = 1;
4757 has_mode[mode_index] = 1;
4758 break;
4761 if (j == nvisuals)
4762 ERR("Did not find visual corresponding the the pixmap format !\n");
4765 i++;
4766 } else {
4767 /* Now to emulated modes */
4768 if (has_mode[emu] == 0) {
4769 int c;
4770 int l;
4771 int depth = has_depth[emu];
4773 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4774 if (ModeEmulations[c].dest.depth == depth) {
4775 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4776 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4777 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4778 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4779 int j;
4780 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4781 if ((vi[j].depth == pf[l].depth) &&
4782 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4783 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4784 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4785 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4786 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4787 if (depth == 8) {
4788 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4789 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4790 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4791 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4792 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4793 } else {
4794 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4795 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4796 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4797 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4798 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4800 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4801 send_mode = 1;
4804 if (send_mode == 0)
4805 ERR("No visual corresponding to pixmap format !\n");
4813 emu++;
4816 if (send_mode) {
4817 int mode;
4819 if (TRACE_ON(ddraw)) {
4820 TRACE("Enumerating with pixel format : \n");
4821 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4822 DPRINTF("\n");
4825 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4826 /* Do not enumerate modes we cannot handle anyway */
4827 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4828 break;
4830 ddsfd.dwWidth = modes[mode].w;
4831 ddsfd.dwHeight= modes[mode].h;
4832 ddsfd.lPitch = ddsfd.dwWidth * xbpp;
4834 /* Now, send the mode description to the application */
4835 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4836 if (!modescb(&ddsfd, context))
4837 goto exit_enum;
4840 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4841 /* modeX is not standard VGA */
4842 ddsfd.dwWidth = 320;
4843 ddsfd.dwHeight = 200;
4844 ddsfd.lPitch = 320 * xbpp;
4845 if (!modescb(&ddsfd, context))
4846 goto exit_enum;
4850 exit_enum:
4851 TSXFree(vi);
4852 TSXFree(pf);
4854 return DD_OK;
4857 #ifdef HAVE_LIBXXF86DGA
4858 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4859 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4861 ICOM_THIS(IDirectDraw2Impl,iface);
4862 TRACE("(%p)->(%p)\n",This,lpddsfd);
4863 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4864 lpddsfd->dwHeight = This->d.height;
4865 lpddsfd->dwWidth = This->d.width;
4866 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4867 lpddsfd->dwBackBufferCount = 1;
4868 lpddsfd->u.dwRefreshRate = 60;
4869 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4870 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4871 if (TRACE_ON(ddraw)) {
4872 _dump_surface_desc(lpddsfd);
4874 return DD_OK;
4876 #endif /* defined(HAVE_LIBXXF86DGA) */
4878 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4879 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4881 ICOM_THIS(IDirectDraw2Impl,iface);
4882 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4883 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4884 lpddsfd->dwHeight = This->d.height;
4885 lpddsfd->dwWidth = This->d.width;
4886 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4887 lpddsfd->dwBackBufferCount = 1;
4888 lpddsfd->u.dwRefreshRate = 60;
4889 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4890 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4891 if (TRACE_ON(ddraw)) {
4892 _dump_surface_desc(lpddsfd);
4894 return DD_OK;
4897 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4898 ICOM_THIS(IDirectDraw2Impl,iface);
4899 TRACE("(%p)->()\n",This);
4900 return DD_OK;
4903 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4904 LPDIRECTDRAW2 iface,LPDWORD freq
4906 ICOM_THIS(IDirectDraw2Impl,iface);
4907 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4908 *freq = 60*100; /* 60 Hz */
4909 return DD_OK;
4912 /* what can we directly decompress? */
4913 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4914 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4916 ICOM_THIS(IDirectDraw2Impl,iface);
4917 FIXME("(%p,%p,%p), stub\n",This,x,y);
4918 return DD_OK;
4921 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4922 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4924 ICOM_THIS(IDirectDraw2Impl,iface);
4925 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4926 return DD_OK;
4929 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4930 LPDIRECTDRAW2 iface )
4932 ICOM_THIS(IDirectDraw2Impl,iface);
4933 FIXME("(%p)->()\n", This );
4935 return DD_OK;
4938 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4939 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4940 ICOM_THIS(IDirectDraw2Impl,iface);
4941 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4943 return DD_OK;
4946 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4947 LPDWORD lpdwScanLine) {
4948 ICOM_THIS(IDirectDraw2Impl,iface);
4949 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4951 if (lpdwScanLine)
4952 *lpdwScanLine = 0;
4953 return DD_OK;
4956 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4957 GUID *lpGUID) {
4958 ICOM_THIS(IDirectDraw2Impl,iface);
4959 FIXME("(%p)->(%p)\n", This, lpGUID);
4961 return DD_OK;
4964 #ifdef HAVE_LIBXXF86DGA
4966 /* Note: Hack so we can reuse the old functions without compiler warnings */
4967 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4968 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4969 #else
4970 # define XCAST(fun) (void *)
4971 #endif
4973 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4975 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4976 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4977 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4978 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4979 XCAST(Compact)IDirectDraw2Impl_Compact,
4980 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4981 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4982 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4983 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4984 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4985 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4986 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4987 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4988 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4989 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4990 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4991 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4992 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4993 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4994 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4995 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4996 #ifdef HAVE_LIBXXF86DGA2
4997 XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
4998 #else
4999 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5000 #endif
5001 DGA_IDirectDrawImpl_SetDisplayMode,
5002 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5005 #undef XCAST
5007 #endif /* defined(HAVE_LIBXXF86DGA) */
5009 /* Note: Hack so we can reuse the old functions without compiler warnings */
5010 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5011 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
5012 #else
5013 # define XCAST(fun) (void *)
5014 #endif
5016 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
5018 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5019 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5020 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5021 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5022 XCAST(Compact)IDirectDraw2Impl_Compact,
5023 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5024 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5025 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5026 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5027 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5028 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5029 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5030 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5031 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5032 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5033 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5034 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5035 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5036 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5037 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5038 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5039 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5040 Xlib_IDirectDrawImpl_SetDisplayMode,
5041 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5044 #undef XCAST
5046 /*****************************************************************************
5047 * IDirectDraw2
5051 #ifdef HAVE_LIBXXF86DGA
5052 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
5053 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
5055 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5056 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5058 #endif /* defined(HAVE_LIBXXF86DGA) */
5060 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
5061 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
5063 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5064 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5067 #ifdef HAVE_LIBXXF86DGA
5068 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
5069 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5071 ICOM_THIS(IDirectDraw2Impl,iface);
5072 TRACE("(%p)->(%p,%p,%p)\n",
5073 This,ddscaps,total,free
5075 if (total) *total = This->e.dga.fb_memsize * 1024;
5076 if (free) *free = This->e.dga.fb_memsize * 1024;
5077 return DD_OK;
5079 #endif /* defined(HAVE_LIBXXF86DGA) */
5081 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
5082 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5084 ICOM_THIS(IDirectDraw2Impl,iface);
5085 TRACE("(%p)->(%p,%p,%p)\n",
5086 This,ddscaps,total,free
5088 if (total) *total = 2048 * 1024;
5089 if (free) *free = 2048 * 1024;
5090 return DD_OK;
5093 #ifdef HAVE_LIBXXF86DGA
5094 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
5096 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5097 DGA_IDirectDraw2Impl_QueryInterface,
5098 IDirectDraw2Impl_AddRef,
5099 DGA_IDirectDraw2Impl_Release,
5100 IDirectDraw2Impl_Compact,
5101 IDirectDraw2Impl_CreateClipper,
5102 DGA_IDirectDraw2Impl_CreatePalette,
5103 DGA_IDirectDraw2Impl_CreateSurface,
5104 IDirectDraw2Impl_DuplicateSurface,
5105 DGA_IDirectDraw2Impl_EnumDisplayModes,
5106 IDirectDraw2Impl_EnumSurfaces,
5107 IDirectDraw2Impl_FlipToGDISurface,
5108 DGA_IDirectDraw2Impl_GetCaps,
5109 DGA_IDirectDraw2Impl_GetDisplayMode,
5110 IDirectDraw2Impl_GetFourCCCodes,
5111 IDirectDraw2Impl_GetGDISurface,
5112 IDirectDraw2Impl_GetMonitorFrequency,
5113 IDirectDraw2Impl_GetScanLine,
5114 IDirectDraw2Impl_GetVerticalBlankStatus,
5115 IDirectDraw2Impl_Initialize,
5116 DGA_IDirectDraw2Impl_RestoreDisplayMode,
5117 IDirectDraw2Impl_SetCooperativeLevel,
5118 DGA_IDirectDraw2Impl_SetDisplayMode,
5119 IDirectDraw2Impl_WaitForVerticalBlank,
5120 DGA_IDirectDraw2Impl_GetAvailableVidMem
5122 #endif /* defined(HAVE_LIBXXF86DGA) */
5124 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
5126 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5127 Xlib_IDirectDraw2Impl_QueryInterface,
5128 IDirectDraw2Impl_AddRef,
5129 Xlib_IDirectDraw2Impl_Release,
5130 IDirectDraw2Impl_Compact,
5131 IDirectDraw2Impl_CreateClipper,
5132 Xlib_IDirectDraw2Impl_CreatePalette,
5133 Xlib_IDirectDraw2Impl_CreateSurface,
5134 IDirectDraw2Impl_DuplicateSurface,
5135 Xlib_IDirectDraw2Impl_EnumDisplayModes,
5136 IDirectDraw2Impl_EnumSurfaces,
5137 IDirectDraw2Impl_FlipToGDISurface,
5138 Xlib_IDirectDraw2Impl_GetCaps,
5139 Xlib_IDirectDraw2Impl_GetDisplayMode,
5140 IDirectDraw2Impl_GetFourCCCodes,
5141 IDirectDraw2Impl_GetGDISurface,
5142 IDirectDraw2Impl_GetMonitorFrequency,
5143 IDirectDraw2Impl_GetScanLine,
5144 IDirectDraw2Impl_GetVerticalBlankStatus,
5145 IDirectDraw2Impl_Initialize,
5146 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5147 IDirectDraw2Impl_SetCooperativeLevel,
5148 Xlib_IDirectDraw2Impl_SetDisplayMode,
5149 IDirectDraw2Impl_WaitForVerticalBlank,
5150 Xlib_IDirectDraw2Impl_GetAvailableVidMem
5153 /*****************************************************************************
5154 * IDirectDraw4
5158 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
5159 HDC hdc,
5160 LPDIRECTDRAWSURFACE *lpDDS) {
5161 ICOM_THIS(IDirectDraw4Impl,iface);
5162 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
5164 return DD_OK;
5167 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
5168 ICOM_THIS(IDirectDraw4Impl,iface);
5169 FIXME("(%p)->()\n", This);
5171 return DD_OK;
5174 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
5175 ICOM_THIS(IDirectDraw4Impl,iface);
5176 FIXME("(%p)->()\n", This);
5178 return DD_OK;
5181 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5182 LPDDDEVICEIDENTIFIER lpdddi,
5183 DWORD dwFlags) {
5184 ICOM_THIS(IDirectDraw4Impl,iface);
5185 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5187 return DD_OK;
5190 #ifdef HAVE_LIBXXF86DGA
5192 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5193 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5194 #else
5195 # define XCAST(fun) (void*)
5196 #endif
5198 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5200 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5201 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5202 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5203 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5204 XCAST(Compact)IDirectDraw2Impl_Compact,
5205 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5206 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5207 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5208 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5209 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5210 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5211 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5212 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5213 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5214 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5215 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5216 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5217 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5218 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5219 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5220 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5221 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5222 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5223 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5224 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5225 IDirectDraw4Impl_GetSurfaceFromDC,
5226 IDirectDraw4Impl_RestoreAllSurfaces,
5227 IDirectDraw4Impl_TestCooperativeLevel,
5228 IDirectDraw4Impl_GetDeviceIdentifier
5231 #undef XCAST
5233 #endif /* defined(HAVE_LIBXXF86DGA) */
5235 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5236 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5237 #else
5238 # define XCAST(fun) (void*)
5239 #endif
5241 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5243 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5244 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5245 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5246 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5247 XCAST(Compact)IDirectDraw2Impl_Compact,
5248 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5249 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5250 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5251 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5252 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5253 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5254 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5255 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5256 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5257 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5258 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5259 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5260 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5261 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5262 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5263 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5264 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5265 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5266 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5267 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5268 IDirectDraw4Impl_GetSurfaceFromDC,
5269 IDirectDraw4Impl_RestoreAllSurfaces,
5270 IDirectDraw4Impl_TestCooperativeLevel,
5271 IDirectDraw4Impl_GetDeviceIdentifier
5274 #undef XCAST
5276 /******************************************************************************
5277 * DirectDrawCreate
5280 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5282 LRESULT ret;
5283 IDirectDrawImpl* ddraw = NULL;
5284 DWORD lastError;
5286 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5288 SetLastError( ERROR_SUCCESS );
5289 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
5290 if( (!ddraw) &&
5291 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
5294 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5297 if( ddraw )
5299 /* Perform any special direct draw functions */
5300 if (msg==WM_PAINT)
5301 ddraw->d.paintable = 1;
5303 /* Now let the application deal with the rest of this */
5304 if( ddraw->d.mainWindow )
5307 /* Don't think that we actually need to call this but...
5308 might as well be on the safe side of things... */
5310 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5311 it should be the procedures of our fake window that gets called
5312 instead of those of the window provided by the application.
5313 And with this patch, mouse clicks work with Monkey Island III
5314 - Lionel */
5315 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5317 if( !ret )
5319 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5320 /* We didn't handle the message - give it to the application */
5321 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5323 ret = CallWindowProcA(tmpWnd->winproc,
5324 ddraw->d.mainWindow, msg, wParam, lParam );
5326 WIN_ReleaseWndPtr(tmpWnd);
5330 } else {
5331 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5335 else
5337 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5340 return ret;
5343 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5344 #ifdef HAVE_LIBXXF86DGA
5345 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5346 int memsize,banksize,major,minor,flags;
5347 char *addr;
5348 int depth;
5349 int dga_version;
5350 int width, height;
5352 /* Get DGA availability / version */
5353 dga_version = DDRAW_DGA_Available();
5355 if (dga_version == 0) {
5356 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5357 return DDERR_GENERIC;
5360 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5361 (*ilplpDD)->ref = 1;
5362 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5363 #ifdef HAVE_LIBXXF86DGA2
5364 if (dga_version == 1) {
5365 (*ilplpDD)->e.dga.version = 1;
5366 #endif /* defined(HAVE_LIBXXF86DGA2) */
5367 TSXF86DGAQueryVersion(display,&major,&minor);
5368 TRACE("XF86DGA is version %d.%d\n",major,minor);
5369 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5370 if (!(flags & XF86DGADirectPresent))
5371 MESSAGE("direct video is NOT PRESENT.\n");
5372 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5373 (*ilplpDD)->e.dga.fb_width = width;
5374 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5375 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5376 (*ilplpDD)->e.dga.fb_height = height;
5377 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5378 addr,width,banksize,memsize
5380 TRACE("viewport height: %d\n",height);
5381 /* Get the screen dimensions as seen by Wine.
5382 In that case, it may be better to ignore the -desktop mode and return the
5383 real screen size => print a warning */
5384 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5385 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5386 if (((*ilplpDD)->d.height != height) ||
5387 ((*ilplpDD)->d.width != width))
5388 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5389 (*ilplpDD)->e.dga.fb_addr = addr;
5390 (*ilplpDD)->e.dga.fb_memsize = memsize;
5391 (*ilplpDD)->e.dga.vpmask = 0;
5393 /* just assume the default depth is the DGA depth too */
5394 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5395 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
5396 #ifdef RESTORE_SIGNALS
5397 SIGNAL_Init();
5398 #endif
5399 #ifdef HAVE_LIBXXF86DGA2
5400 } else {
5401 XDGAMode *modes;
5402 int i, num_modes;
5403 int mode_to_use = 0;
5405 (*ilplpDD)->e.dga.version = 2;
5407 TSXDGAQueryVersion(display,&major,&minor);
5408 TRACE("XDGA is version %d.%d\n",major,minor);
5410 TRACE("Opening the frame buffer.\n");
5411 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5412 ERR("Error opening the frame buffer !!!\n");
5414 return DDERR_GENERIC;
5417 /* List all available modes */
5418 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5419 (*ilplpDD)->e.dga.modes = modes;
5420 (*ilplpDD)->e.dga.num_modes = num_modes;
5421 if (TRACE_ON(ddraw)) {
5422 TRACE("Available modes :\n");
5423 for (i = 0; i < num_modes; i++) {
5424 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5425 modes[i].num,
5426 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5427 modes[i].viewportWidth, modes[i].viewportHeight,
5428 modes[i].depth);
5429 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5430 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5431 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5432 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5433 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5434 DPRINTF("\n");
5436 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5437 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5438 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5439 mode_to_use = modes[i].num;
5443 if (mode_to_use == 0) {
5444 ERR("Could not find mode !\n");
5445 mode_to_use = 1;
5446 } else {
5447 DPRINTF("Using mode number %d\n", mode_to_use);
5450 /* Initialize the frame buffer */
5451 _DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
5452 /* Set the input handling for relative mouse movements */
5453 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5455 #endif /* defined(HAVE_LIBXXF86DGA2) */
5456 return DD_OK;
5457 #else /* defined(HAVE_LIBXXF86DGA) */
5458 return DDERR_INVALIDDIRECTDRAWGUID;
5459 #endif /* defined(HAVE_LIBXXF86DGA) */
5462 static BOOL
5463 DDRAW_XSHM_Available(void)
5465 #ifdef HAVE_LIBXXSHM
5466 if (TSXShmQueryExtension(display))
5468 int major, minor;
5469 Bool shpix;
5471 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5472 (Options.noXSHM != 1))
5473 return 1;
5474 else
5475 return 0;
5477 else
5478 return 0;
5479 #else
5480 return 0;
5481 #endif
5484 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5485 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5486 int depth;
5488 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5489 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5490 (*ilplpDD)->ref = 1;
5491 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5493 /* At DirectDraw creation, the depth is the default depth */
5494 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5495 _common_depth_to_pixelformat(depth,
5496 &((*ilplpDD)->d.directdraw_pixelformat),
5497 &((*ilplpDD)->d.screen_pixelformat),
5498 &((*ilplpDD)->d.pixmap_depth));
5499 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5500 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5502 #ifdef HAVE_LIBXXSHM
5503 /* Test if XShm is available. */
5504 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5505 (*ilplpDD)->e.xlib.xshm_compl = 0;
5506 TRACE("Using XShm extension.\n");
5508 #endif
5510 return DD_OK;
5513 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5514 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5515 WNDCLASSA wc;
5516 /* WND* pParentWindow; */
5517 HRESULT ret;
5519 if (!HIWORD(lpGUID)) lpGUID = NULL;
5521 TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID),ilplpDD,pUnkOuter);
5523 if ( ( !lpGUID ) ||
5524 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5525 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5526 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5527 /* if they didn't request a particular interface, use the best
5528 * supported one */
5529 if (DDRAW_DGA_Available())
5530 lpGUID = &DGA_DirectDraw_GUID;
5531 else
5532 lpGUID = &XLIB_DirectDraw_GUID;
5535 wc.style = CS_GLOBALCLASS;
5536 wc.lpfnWndProc = Xlib_DDWndProc;
5537 wc.cbClsExtra = 0;
5538 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
5539 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
5541 /* We can be a child of the desktop since we're really important */
5543 This code is not useful since hInstance is forced to 0 afterward
5544 pParentWindow = WIN_GetDesktop();
5545 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5547 wc.hInstance = 0;
5550 wc.hIcon = 0;
5551 wc.hCursor = (HCURSOR)IDC_ARROWA;
5552 wc.hbrBackground= NULL_BRUSH;
5553 wc.lpszMenuName = 0;
5554 wc.lpszClassName= "WINE_DirectDraw";
5555 RegisterClassA(&wc);
5557 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5558 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5560 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5561 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5563 else {
5564 goto err;
5568 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5569 return ret;
5571 err:
5572 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",
5573 debugstr_guid(lpGUID),lplpDD,pUnkOuter);
5574 return DDERR_INVALIDDIRECTDRAWGUID;
5577 /*******************************************************************************
5578 * DirectDraw ClassFactory
5580 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5583 typedef struct
5585 /* IUnknown fields */
5586 ICOM_VFIELD(IClassFactory);
5587 DWORD ref;
5588 } IClassFactoryImpl;
5590 static HRESULT WINAPI
5591 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5592 ICOM_THIS(IClassFactoryImpl,iface);
5594 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
5595 return E_NOINTERFACE;
5598 static ULONG WINAPI
5599 DDCF_AddRef(LPCLASSFACTORY iface) {
5600 ICOM_THIS(IClassFactoryImpl,iface);
5601 return ++(This->ref);
5604 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5605 ICOM_THIS(IClassFactoryImpl,iface);
5606 /* static class, won't be freed */
5607 return --(This->ref);
5610 static HRESULT WINAPI DDCF_CreateInstance(
5611 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5613 ICOM_THIS(IClassFactoryImpl,iface);
5615 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
5616 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5617 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5618 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5619 /* FIXME: reuse already created DirectDraw if present? */
5620 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5622 return CLASS_E_CLASSNOTAVAILABLE;
5625 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5626 ICOM_THIS(IClassFactoryImpl,iface);
5627 FIXME("(%p)->(%d),stub!\n",This,dolock);
5628 return S_OK;
5631 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5633 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5634 DDCF_QueryInterface,
5635 DDCF_AddRef,
5636 DDCF_Release,
5637 DDCF_CreateInstance,
5638 DDCF_LockServer
5640 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5642 /*******************************************************************************
5643 * DllGetClassObject [DDRAW.13]
5644 * Retrieves class object from a DLL object
5646 * NOTES
5647 * Docs say returns STDAPI
5649 * PARAMS
5650 * rclsid [I] CLSID for the class object
5651 * riid [I] Reference to identifier of interface for class object
5652 * ppv [O] Address of variable to receive interface pointer for riid
5654 * RETURNS
5655 * Success: S_OK
5656 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5657 * E_UNEXPECTED
5659 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5661 TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5662 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5663 *ppv = (LPVOID)&DDRAW_CF;
5664 IClassFactory_AddRef((IClassFactory*)*ppv);
5665 return S_OK;
5667 FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5668 return CLASS_E_CLASSNOTAVAILABLE;
5672 /*******************************************************************************
5673 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5675 * RETURNS
5676 * Success: S_OK
5677 * Failure: S_FALSE
5679 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5681 FIXME("(void): stub\n");
5682 return S_FALSE;
5685 #else /* !defined(X_DISPLAY_MISSING) */
5687 #include "windef.h"
5688 #include "wtypes.h"
5690 #define DD_OK 0
5692 typedef void *LPUNKNOWN;
5693 typedef void *LPDIRECTDRAW;
5694 typedef void *LPDIRECTDRAWCLIPPER;
5695 typedef void *LPDDENUMCALLBACKA;
5696 typedef void *LPDDENUMCALLBACKEXA;
5697 typedef void *LPDDENUMCALLBACKEXW;
5698 typedef void *LPDDENUMCALLBACKW;
5700 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5702 return DD_OK;
5705 HRESULT WINAPI DirectDrawCreate(
5706 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5708 return DD_OK;
5711 HRESULT WINAPI DirectDrawCreateClipper(
5712 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5714 return DD_OK;
5717 HRESULT WINAPI DirectDrawEnumerateA(
5718 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5720 return DD_OK;
5723 HRESULT WINAPI DirectDrawEnumerateExA(
5724 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5726 return DD_OK;
5729 HRESULT WINAPI DirectDrawEnumerateExW(
5730 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5732 return DD_OK;
5735 HRESULT WINAPI DirectDrawEnumerateW(
5736 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5738 return DD_OK;
5741 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5743 return CLASS_E_CLASSNOTAVAILABLE;
5746 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5748 return DD_OK;
5751 #endif /* !defined(X_DISPLAY_MISSING) */