Updated, added chapter on configuration and architecture.
[wine.git] / graphics / ddraw.c
blob63ec0893baba9652ad3e1995340fd543dee8b335
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);
740 return DD_OK;
743 #ifdef HAVE_LIBXXF86DGA
744 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
745 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
747 ICOM_THIS(IDirectDrawSurface4Impl,iface);
748 TRACE("(%p)->Unlock(%p)\n",This,surface);
749 return DD_OK;
751 #endif /* defined(HAVE_LIBXXF86DGA) */
753 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
754 if (This->s.ddraw->d.pixel_convert != NULL)
755 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
756 This->t.xlib.image->data,
757 This->s.surface_desc.dwWidth,
758 This->s.surface_desc.dwHeight,
759 This->s.surface_desc.lPitch,
760 This->s.palette);
762 #ifdef HAVE_LIBXXSHM
763 if (This->s.ddraw->e.xlib.xshm_active) {
764 int compl = This->s.ddraw->e.xlib.xshm_compl;
765 if (compl)
766 X11DRV_EVENT_WaitShmCompletion( compl );
767 This->s.ddraw->e.xlib.xshm_compl = X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
768 TSXShmPutImage(display,
769 This->s.ddraw->d.drawable,
770 DefaultGCOfScreen(X11DRV_GetXScreen()),
771 This->t.xlib.image,
772 0, 0, 0, 0,
773 This->t.xlib.image->width,
774 This->t.xlib.image->height,
775 True);
777 else
778 #endif
779 TSXPutImage( display,
780 This->s.ddraw->d.drawable,
781 DefaultGCOfScreen(X11DRV_GetXScreen()),
782 This->t.xlib.image,
783 0, 0, 0, 0,
784 This->t.xlib.image->width,
785 This->t.xlib.image->height);
788 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
789 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
791 ICOM_THIS(IDirectDrawSurface4Impl,iface);
792 TRACE("(%p)->Unlock(%p)\n",This,surface);
794 if (!This->s.ddraw->d.paintable)
795 return DD_OK;
797 /* Only redraw the screen when unlocking the buffer that is on screen */
798 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
799 Xlib_copy_surface_on_screen(This);
801 if (This->s.palette && This->s.palette->cm)
802 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
804 return DD_OK;
807 static IDirectDrawSurface4Impl* _common_find_flipto(
808 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
810 int i,j,flipable=0;
811 struct _surface_chain *chain = This->s.chain;
813 /* if there was no override flipto, look for current backbuffer */
814 if (!flipto) {
815 /* walk the flip chain looking for backbuffer */
816 for (i=0;i<chain->nrofsurfaces;i++) {
817 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
818 flipable++;
819 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
820 flipto = chain->surfaces[i];
822 /* sanity checks ... */
823 if (!flipto) {
824 if (flipable>1) {
825 for (i=0;i<chain->nrofsurfaces;i++)
826 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
827 break;
828 if (i==chain->nrofsurfaces) {
829 /* we do not have a frontbuffer either */
830 for (i=0;i<chain->nrofsurfaces;i++)
831 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
832 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
833 break;
835 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
836 int k = j % chain->nrofsurfaces;
837 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
838 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
839 flipto = chain->surfaces[k];
840 break;
845 if (!flipto)
846 flipto = This;
848 TRACE("flipping to %p\n",flipto);
850 return flipto;
853 #ifdef HAVE_LIBXXF86DGA
854 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
855 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
857 ICOM_THIS(IDirectDrawSurface4Impl,iface);
858 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
859 DWORD xheight;
860 LPBYTE surf;
862 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
863 iflipto = _common_find_flipto(This,iflipto);
865 /* and flip! */
866 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
867 if (iflipto->s.palette && iflipto->s.palette->cm)
868 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
869 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
872 /* We need to switch the lowlevel surfaces, for DGA this is: */
874 /* The height within the framebuffer */
875 xheight = This->t.dga.fb_height;
876 This->t.dga.fb_height = iflipto->t.dga.fb_height;
877 iflipto->t.dga.fb_height = xheight;
879 /* And the assciated surface pointer */
880 surf = This->s.surface_desc.u1.lpSurface;
881 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
882 iflipto->s.surface_desc.u1.lpSurface = surf;
884 return DD_OK;
886 #endif /* defined(HAVE_LIBXXF86DGA) */
888 #ifdef HAVE_LIBXXF86DGA2
889 static HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
890 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
892 ICOM_THIS(IDirectDrawSurface4Impl,iface);
893 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
894 DWORD xheight;
895 LPBYTE surf;
897 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
898 iflipto = _common_find_flipto(This,iflipto);
900 /* and flip! */
901 TSXDGASetViewport(display,DefaultScreen(display),0,iflipto->t.dga.fb_height, XDGAFlipRetrace);
902 TSXDGASync(display,DefaultScreen(display));
903 TSXFlush(display);
904 if (iflipto->s.palette && iflipto->s.palette->cm)
905 TSXDGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
906 /* We need to switch the lowlevel surfaces, for DGA this is: */
908 /* The height within the framebuffer */
909 xheight = This->t.dga.fb_height;
910 This->t.dga.fb_height = iflipto->t.dga.fb_height;
911 iflipto->t.dga.fb_height = xheight;
913 /* And the assciated surface pointer */
914 surf = This->s.surface_desc.u1.lpSurface;
915 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
916 iflipto->s.surface_desc.u1.lpSurface = surf;
918 return DD_OK;
920 #endif /* defined(HAVE_LIBXXF86DGA2) */
922 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
923 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
925 ICOM_THIS(IDirectDrawSurface4Impl,iface);
926 XImage *image;
927 LPBYTE surf;
928 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
930 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
931 iflipto = _common_find_flipto(This,iflipto);
933 #if defined(HAVE_MESAGL) && 0 /* does not work */
934 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
935 TRACE(" - OpenGL flip\n");
936 ENTER_GL();
937 glXSwapBuffers(display, This->s.ddraw->d.drawable);
938 LEAVE_GL();
940 return DD_OK;
942 #endif /* defined(HAVE_MESAGL) */
944 if (!This->s.ddraw->d.paintable)
945 return DD_OK;
947 /* We need to switch the lowlevel surfaces, for xlib this is: */
948 /* The surface pointer */
949 surf = This->s.surface_desc.u1.lpSurface;
950 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
951 iflipto->s.surface_desc.u1.lpSurface = surf;
952 /* the associated ximage */
953 image = This->t.xlib.image;
954 This->t.xlib.image = iflipto->t.xlib.image;
955 iflipto->t.xlib.image = image;
957 Xlib_copy_surface_on_screen(This);
959 if (iflipto->s.palette && iflipto->s.palette->cm)
960 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
961 return DD_OK;
964 /* The IDirectDrawSurface4::SetPalette method attaches the specified
965 * DirectDrawPalette object to a surface. The surface uses this palette for all
966 * subsequent operations. The palette change takes place immediately.
968 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
969 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
971 ICOM_THIS(IDirectDrawSurface4Impl,iface);
972 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
973 int i;
974 TRACE("(%p)->(%p)\n",This,ipal);
976 if (ipal == NULL) {
977 if( This->s.palette != NULL )
978 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
979 This->s.palette = ipal;
981 return DD_OK;
984 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8))
986 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
987 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
989 if (!Options.managed)
990 TSXInstallColormap(display,ipal->cm);
992 for (i=0;i<256;i++) {
993 XColor xc;
995 xc.red = ipal->palents[i].peRed<<8;
996 xc.blue = ipal->palents[i].peBlue<<8;
997 xc.green = ipal->palents[i].peGreen<<8;
998 xc.flags = DoRed|DoBlue|DoGreen;
999 xc.pixel = i;
1000 TSXStoreColor(display,ipal->cm,&xc);
1002 TSXInstallColormap(display,ipal->cm);
1005 /* According to spec, we are only supposed to
1006 * AddRef if this is not the same palette.
1008 if( This->s.palette != ipal )
1010 if( ipal != NULL )
1011 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1012 if( This->s.palette != NULL )
1013 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1014 This->s.palette = ipal;
1015 /* Perform the refresh */
1016 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
1018 return DD_OK;
1021 #ifdef HAVE_LIBXXF86DGA
1022 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
1023 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1025 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1026 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1027 TRACE("(%p)->(%p)\n",This,ipal);
1029 /* According to spec, we are only supposed to
1030 * AddRef if this is not the same palette.
1032 if( This->s.palette != ipal )
1034 if( ipal != NULL )
1035 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1036 if( This->s.palette != NULL )
1037 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1038 This->s.palette = ipal;
1039 #ifdef HAVE_LIBXXF86DGA2
1040 if (This->s.ddraw->e.dga.version == 2)
1041 TSXDGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1042 else
1043 #endif /* defined(HAVE_LIBXXF86DGA2) */
1044 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1046 return DD_OK;
1048 #endif /* defined(HAVE_LIBXXF86DGA) */
1050 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
1052 int x, y;
1053 LPBYTE first;
1055 /* Do first row */
1057 #define COLORFILL_ROW(type) { \
1058 type *d = (type *) buf; \
1059 for (x = 0; x < width; x++) \
1060 d[x] = (type) color; \
1061 break; \
1064 switch(bpp) {
1065 case 1: COLORFILL_ROW(BYTE)
1066 case 2: COLORFILL_ROW(WORD)
1067 case 4: COLORFILL_ROW(DWORD)
1068 default:
1069 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
1070 return DDERR_UNSUPPORTED;
1073 #undef COLORFILL_ROW
1075 /* Now copy first row */
1076 first = buf;
1077 for (y = 1; y < height; y++) {
1078 buf += lPitch;
1079 memcpy(buf, first, width * bpp);
1082 return DD_OK;
1085 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
1086 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
1088 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1089 RECT xdst,xsrc;
1090 DDSURFACEDESC ddesc,sdesc;
1091 HRESULT ret = DD_OK;
1092 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
1093 int x, y;
1094 LPBYTE dbuf, sbuf;
1096 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
1098 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
1099 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1101 if (TRACE_ON(ddraw)) {
1102 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1103 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1104 TRACE("\tflags: ");
1105 _dump_DDBLT(dwFlags);
1106 if (dwFlags & DDBLT_DDFX) {
1107 TRACE("\tblitfx: ");
1108 _dump_DDBLTFX(lpbltfx->dwDDFX);
1112 if (rdst) {
1113 if ((rdst->top < 0) ||
1114 (rdst->left < 0) ||
1115 (rdst->bottom < 0) ||
1116 (rdst->right < 0)) {
1117 ERR(" Negative values in LPRECT !!!\n");
1118 goto release;
1120 memcpy(&xdst,rdst,sizeof(xdst));
1121 } else {
1122 xdst.top = 0;
1123 xdst.bottom = ddesc.dwHeight;
1124 xdst.left = 0;
1125 xdst.right = ddesc.dwWidth;
1128 if (rsrc) {
1129 if ((rsrc->top < 0) ||
1130 (rsrc->left < 0) ||
1131 (rsrc->bottom < 0) ||
1132 (rsrc->right < 0)) {
1133 ERR(" Negative values in LPRECT !!!\n");
1134 goto release;
1136 memcpy(&xsrc,rsrc,sizeof(xsrc));
1137 } else {
1138 if (src) {
1139 xsrc.top = 0;
1140 xsrc.bottom = sdesc.dwHeight;
1141 xsrc.left = 0;
1142 xsrc.right = sdesc.dwWidth;
1143 } else {
1144 memset(&xsrc,0,sizeof(xsrc));
1148 bpp = GET_BPP(ddesc);
1149 srcheight = xsrc.bottom - xsrc.top;
1150 srcwidth = xsrc.right - xsrc.left;
1151 dstheight = xdst.bottom - xdst.top;
1152 dstwidth = xdst.right - xdst.left;
1153 width = (xdst.right - xdst.left) * bpp;
1154 dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1156 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1158 /* First, all the 'source-less' blits */
1159 if (dwFlags & DDBLT_COLORFILL) {
1160 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1161 ddesc.lPitch, lpbltfx->u4.dwFillColor);
1162 dwFlags &= ~DDBLT_COLORFILL;
1165 if (dwFlags & DDBLT_DEPTHFILL) {
1166 #ifdef HAVE_MESAGL
1167 GLboolean ztest;
1169 /* Clears the screen */
1170 TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
1171 glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1172 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1173 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1174 glClear(GL_DEPTH_BUFFER_BIT);
1175 glDepthMask(ztest);
1177 dwFlags &= ~(DDBLT_DEPTHFILL);
1178 #endif /* defined(HAVE_MESAGL) */
1181 if (dwFlags & DDBLT_ROP) {
1182 /* Catch some degenerate cases here */
1183 switch(lpbltfx->dwROP) {
1184 case BLACKNESS:
1185 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1186 break;
1187 case 0xAA0029: /* No-op */
1188 break;
1189 case WHITENESS:
1190 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1191 break;
1192 default:
1193 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
1194 goto error;
1196 dwFlags &= ~DDBLT_ROP;
1199 if (dwFlags & DDBLT_DDROPS) {
1200 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
1203 /* Now the 'with source' blits */
1204 if (src) {
1205 LPBYTE sbase;
1206 int sx, xinc, sy, yinc;
1208 sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1209 xinc = (srcwidth << 16) / dstwidth;
1210 yinc = (srcheight << 16) / dstheight;
1212 if (!dwFlags) {
1214 /* No effects, we can cheat here */
1215 if (dstwidth == srcwidth) {
1216 if (dstheight == srcheight) {
1217 /* No stretching in either direction. This needs to be as fast as possible */
1218 sbuf = sbase;
1219 for (y = 0; y < dstheight; y++) {
1220 memcpy(dbuf, sbuf, width);
1221 sbuf += sdesc.lPitch;
1222 dbuf += ddesc.lPitch;
1224 } else {
1225 /* Stretching in Y direction only */
1226 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1227 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1228 memcpy(dbuf, sbuf, width);
1229 dbuf += ddesc.lPitch;
1232 } else {
1233 /* Stretching in X direction */
1234 int last_sy = -1;
1235 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1236 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1238 if ((sy >> 16) == (last_sy >> 16)) {
1239 /* Same as last row - copy already stretched row */
1240 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1241 } else {
1243 #define STRETCH_ROW(type) { \
1244 type *s = (type *) sbuf, *d = (type *) dbuf; \
1245 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1246 d[x] = s[sx >> 16]; \
1247 break; }
1249 switch(bpp) {
1250 case 1: STRETCH_ROW(BYTE)
1251 case 2: STRETCH_ROW(WORD)
1252 case 4: STRETCH_ROW(DWORD)
1253 default:
1254 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1255 ret = DDERR_UNSUPPORTED;
1256 goto error;
1259 #undef STRETCH_ROW
1262 last_sy = sy;
1263 dbuf += ddesc.lPitch;
1266 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1267 DWORD keylow, keyhigh;
1269 if (dwFlags & DDBLT_KEYSRC) {
1270 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1271 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1272 } else {
1273 /* I'm not sure if this is correct */
1274 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1275 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1276 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1280 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1281 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1283 #define COPYROW_COLORKEY(type) { \
1284 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1285 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1286 tmp = s[sx >> 16]; \
1287 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1289 break; }
1291 switch (bpp) {
1292 case 1: COPYROW_COLORKEY(BYTE)
1293 case 2: COPYROW_COLORKEY(WORD)
1294 case 4: COPYROW_COLORKEY(DWORD)
1295 default:
1296 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1297 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1298 ret = DDERR_UNSUPPORTED;
1299 goto error;
1301 dbuf += ddesc.lPitch;
1304 #undef COPYROW_COLORKEY
1306 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1311 error:
1313 if (dwFlags && FIXME_ON(ddraw)) {
1314 FIXME("\tUnsupported flags: ");
1315 _dump_DDBLT(dwFlags);
1317 release:
1319 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1320 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1322 return DD_OK;
1325 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1326 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1328 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1329 int bpp, w, h, x, y;
1330 DDSURFACEDESC ddesc,sdesc;
1331 HRESULT ret = DD_OK;
1332 LPBYTE sbuf, dbuf;
1333 RECT rsrc2;
1336 if (TRACE_ON(ddraw)) {
1337 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1338 This,dstx,dsty,src,rsrc,trans
1340 FIXME(" trans:");
1341 if (FIXME_ON(ddraw))
1342 _dump_DDBLTFAST(trans);
1343 if (rsrc)
1344 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1345 else
1346 FIXME(" srcrect: NULL\n");
1349 /* We need to lock the surfaces, or we won't get refreshes when done. */
1350 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1351 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1353 if (!rsrc) {
1354 WARN("rsrc is NULL!\n");
1355 rsrc = &rsrc2;
1356 rsrc->left = rsrc->top = 0;
1357 rsrc->right = sdesc.dwWidth;
1358 rsrc->bottom = sdesc.dwHeight;
1361 bpp = GET_BPP(This->s.surface_desc);
1362 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1363 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1366 h=rsrc->bottom-rsrc->top;
1367 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1368 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1369 if (h<0) h=0;
1371 w=rsrc->right-rsrc->left;
1372 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1373 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1374 if (w<0) w=0;
1376 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1377 DWORD keylow, keyhigh;
1378 if (trans & DDBLTFAST_SRCCOLORKEY) {
1379 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1380 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1381 } else {
1382 /* I'm not sure if this is correct */
1383 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1384 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1385 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1388 #define COPYBOX_COLORKEY(type) { \
1389 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1390 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1391 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1392 for (y = 0; y < h; y++) { \
1393 for (x = 0; x < w; x++) { \
1394 tmp = s[x]; \
1395 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1397 (LPBYTE)s += sdesc.lPitch; \
1398 (LPBYTE)d += ddesc.lPitch; \
1400 break; \
1403 switch (bpp) {
1404 case 1: COPYBOX_COLORKEY(BYTE)
1405 case 2: COPYBOX_COLORKEY(WORD)
1406 case 4: COPYBOX_COLORKEY(DWORD)
1407 default:
1408 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1409 ret = DDERR_UNSUPPORTED;
1410 goto error;
1413 #undef COPYBOX_COLORKEY
1415 } else {
1416 int width = w * bpp;
1418 for (y = 0; y < h; y++) {
1419 memcpy(dbuf, sbuf, width);
1420 sbuf += sdesc.lPitch;
1421 dbuf += ddesc.lPitch;
1425 error:
1427 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1428 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1429 return ret;
1432 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1433 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1435 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1436 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1437 This,ddbltbatch,x,y
1439 return DD_OK;
1442 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1443 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1445 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1446 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1447 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1448 return DD_OK;
1451 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1452 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1453 ) {
1454 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1455 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1457 /* Simply copy the surface description stored in the object */
1458 *ddsd = This->s.surface_desc;
1460 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1462 return DD_OK;
1465 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1466 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1467 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1468 return ++(This->ref);
1471 #ifdef HAVE_LIBXXF86DGA
1472 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1473 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1475 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1477 if (--(This->ref))
1478 return This->ref;
1480 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1481 /* clear out of surface list */
1482 if (This->t.dga.fb_height == -1)
1483 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1484 else
1485 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1487 /* Free the DIBSection (if any) */
1488 if (This->s.hdc != 0) {
1489 SelectObject(This->s.hdc, This->s.holdbitmap);
1490 DeleteDC(This->s.hdc);
1491 DeleteObject(This->s.DIBsection);
1494 /* Free the clipper if attached to this surface */
1495 if( This->s.lpClipper )
1496 IDirectDrawClipper_Release(This->s.lpClipper);
1498 HeapFree(GetProcessHeap(),0,This);
1499 return S_OK;
1501 #endif /* defined(HAVE_LIBXXF86DGA) */
1503 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1504 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1506 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1508 if (--(This->ref))
1509 return This->ref;
1511 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1513 if (This->t.xlib.image != NULL) {
1514 if (This->s.ddraw->d.pixel_convert != NULL) {
1515 /* In pixel conversion mode, there are 2 buffers to release. */
1516 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1518 #ifdef HAVE_LIBXXSHM
1519 if (This->s.ddraw->e.xlib.xshm_active) {
1520 TSXShmDetach(display, &(This->t.xlib.shminfo));
1521 TSXDestroyImage(This->t.xlib.image);
1522 shmdt(This->t.xlib.shminfo.shmaddr);
1523 } else {
1524 #endif
1525 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1526 This->t.xlib.image->data = NULL;
1527 TSXDestroyImage(This->t.xlib.image);
1528 #ifdef HAVE_LIBXXSHM
1530 #endif
1531 } else {
1532 This->t.xlib.image->data = NULL;
1534 #ifdef HAVE_LIBXXSHM
1535 if (This->s.ddraw->e.xlib.xshm_active) {
1536 TSXShmDetach(display, &(This->t.xlib.shminfo));
1537 TSXDestroyImage(This->t.xlib.image);
1538 shmdt(This->t.xlib.shminfo.shmaddr);
1539 } else {
1540 #endif
1541 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1542 TSXDestroyImage(This->t.xlib.image);
1543 #ifdef HAVE_LIBXXSHM
1545 #endif
1547 This->t.xlib.image = 0;
1548 } else {
1549 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1552 if (This->s.palette)
1553 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1555 /* Free the DIBSection (if any) */
1556 if (This->s.hdc != 0) {
1557 SelectObject(This->s.hdc, This->s.holdbitmap);
1558 DeleteDC(This->s.hdc);
1559 DeleteObject(This->s.DIBsection);
1562 /* Free the clipper if present */
1563 if( This->s.lpClipper )
1564 IDirectDrawClipper_Release(This->s.lpClipper);
1566 HeapFree(GetProcessHeap(),0,This);
1567 return S_OK;
1570 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1571 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1573 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1574 int i,found = 0,xstart;
1575 struct _surface_chain *chain;
1577 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1578 if (TRACE_ON(ddraw)) {
1579 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1580 DPRINTF("\n");
1582 chain = This->s.chain;
1583 if (!chain)
1584 return DDERR_NOTFOUND;
1586 for (i=0;i<chain->nrofsurfaces;i++)
1587 if (chain->surfaces[i] == This)
1588 break;
1590 xstart = i;
1591 for (i=0;i<chain->nrofsurfaces;i++) {
1592 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1593 #if 0
1594 if (found) /* may not find the same caps twice, (doc) */
1595 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1596 #endif
1597 found = (i+1)+xstart;
1600 if (!found)
1601 return DDERR_NOTFOUND;
1602 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1603 /* FIXME: AddRef? */
1604 TRACE("found %p\n",*lpdsf);
1605 return DD_OK;
1608 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1609 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1611 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1612 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1614 return DDERR_ALREADYINITIALIZED;
1617 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1618 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1620 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1621 TRACE("(%p)->(%p)\n",This,pf);
1623 *pf = This->s.surface_desc.ddpfPixelFormat;
1624 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1625 return DD_OK;
1628 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1629 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1630 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1631 return DD_OK;
1634 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1635 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1637 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1638 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1639 return DD_OK;
1642 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1643 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
1645 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1646 TRACE("(%p)->(%p)!\n",This,lpClipper);
1648 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
1649 This->s.lpClipper = lpClipper;
1650 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
1651 return DD_OK;
1654 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1655 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1657 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1658 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1659 int i;
1660 struct _surface_chain *chain;
1662 FIXME("(%p)->(%p)\n",This,surf);
1663 chain = This->s.chain;
1665 /* IDirectDrawSurface4_AddRef(surf); */
1667 if (chain) {
1668 for (i=0;i<chain->nrofsurfaces;i++)
1669 if (chain->surfaces[i] == isurf)
1670 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1671 } else {
1672 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1673 chain->nrofsurfaces = 1;
1674 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1675 chain->surfaces[0] = This;
1676 This->s.chain = chain;
1679 if (chain->surfaces)
1680 chain->surfaces = HeapReAlloc(
1681 GetProcessHeap(),
1683 chain->surfaces,
1684 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1686 else
1687 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1688 isurf->s.chain = chain;
1689 chain->surfaces[chain->nrofsurfaces++] = isurf;
1690 return DD_OK;
1693 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1694 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1695 DDSURFACEDESC desc;
1696 BITMAPINFO *b_info;
1697 UINT usage;
1699 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1701 /* Creates a DIB Section of the same size / format as the surface */
1702 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1704 if (This->s.hdc == 0) {
1705 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1706 case 16:
1707 case 32:
1708 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1709 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1710 break;
1711 #endif
1713 case 24:
1714 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1715 break;
1717 default:
1718 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1719 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1720 break;
1723 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1724 b_info->bmiHeader.biWidth = desc.dwWidth;
1725 b_info->bmiHeader.biHeight = desc.dwHeight;
1726 b_info->bmiHeader.biPlanes = 1;
1727 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1728 #if 0
1729 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1730 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1731 #endif
1732 b_info->bmiHeader.biCompression = BI_RGB;
1733 #if 0
1734 else
1735 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1736 #endif
1737 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1738 b_info->bmiHeader.biXPelsPerMeter = 0;
1739 b_info->bmiHeader.biYPelsPerMeter = 0;
1740 b_info->bmiHeader.biClrUsed = 0;
1741 b_info->bmiHeader.biClrImportant = 0;
1743 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1744 case 16:
1745 case 32:
1746 #if 0
1748 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1750 usage = 0;
1751 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1752 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1753 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1755 break;
1756 #endif
1757 case 24:
1758 /* Nothing to do */
1759 usage = DIB_RGB_COLORS;
1760 break;
1762 default: {
1763 int i;
1765 /* Fill the palette */
1766 usage = DIB_RGB_COLORS;
1768 if (This->s.palette == NULL) {
1769 ERR("Bad palette !!!\n");
1770 } else {
1771 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1772 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1774 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1775 rgb[i].rgbBlue = pent[i].peBlue;
1776 rgb[i].rgbRed = pent[i].peRed;
1777 rgb[i].rgbGreen = pent[i].peGreen;
1781 break;
1783 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1784 b_info,
1785 usage,
1786 &(This->s.bitmap_data),
1790 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1791 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1793 /* b_info is not useful anymore */
1794 HeapFree(GetProcessHeap(), 0, b_info);
1796 /* Create the DC */
1797 This->s.hdc = CreateCompatibleDC(0);
1798 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1801 /* Copy our surface in the DIB section */
1802 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1803 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1804 else
1805 /* TODO */
1806 FIXME("This case has to be done :/\n");
1808 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1809 *lphdc = This->s.hdc;
1811 return DD_OK;
1814 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1815 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1817 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1818 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1819 /* Copy the DIB section to our surface */
1820 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1821 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1822 } else {
1823 /* TODO */
1824 FIXME("This case has to be done :/\n");
1826 /* Unlock the surface */
1827 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1828 return DD_OK;
1831 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1832 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1833 char xrefiid[50];
1835 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1836 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
1838 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1839 * the same interface. And IUnknown does that too of course.
1841 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1842 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1843 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1844 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1845 IsEqualGUID( &IID_IUnknown, refiid )
1847 *obj = This;
1848 IDirectDrawSurface4_AddRef(iface);
1850 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1851 return S_OK;
1853 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1855 /* Texture interface */
1856 *obj = d3dtexture2_create(This);
1857 IDirectDrawSurface4_AddRef(iface);
1858 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1859 return S_OK;
1861 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1863 /* Texture interface */
1864 *obj = d3dtexture_create(This);
1865 IDirectDrawSurface4_AddRef(iface);
1867 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1869 return S_OK;
1871 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1872 /* It is the OpenGL Direct3D Device */
1873 IDirectDrawSurface4_AddRef(iface);
1874 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1875 return S_OK;
1878 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
1879 return OLE_E_ENUM_NOMORE;
1882 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1883 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1884 TRACE("(%p)->(), stub!\n",This);
1885 return DD_OK; /* hmm */
1888 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1889 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1890 int i;
1891 struct _surface_chain *chain = This->s.chain;
1893 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1894 for (i=0;i<chain->nrofsurfaces;i++) {
1895 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1896 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1897 return DD_OK; /* FIXME: return value correct? */
1899 return DD_OK;
1902 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1903 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1904 FIXME("(%p)->(),stub!\n",This);
1905 return DD_OK;
1908 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1909 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1911 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1912 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1913 if (TRACE_ON(ddraw)) {
1914 _dump_colorkeyflag(dwFlags);
1915 DPRINTF(" : ");
1916 _dump_DDCOLORKEY((void *) ckey);
1917 DPRINTF("\n");
1920 /* If this surface was loaded as a texture, call also the texture
1921 SetColorKey callback */
1922 if (This->s.texture) {
1923 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1926 if( dwFlags & DDCKEY_SRCBLT )
1928 dwFlags &= ~DDCKEY_SRCBLT;
1929 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1930 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1933 if( dwFlags & DDCKEY_DESTBLT )
1935 dwFlags &= ~DDCKEY_DESTBLT;
1936 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1937 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1940 if( dwFlags & DDCKEY_SRCOVERLAY )
1942 dwFlags &= ~DDCKEY_SRCOVERLAY;
1943 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1944 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1947 if( dwFlags & DDCKEY_DESTOVERLAY )
1949 dwFlags &= ~DDCKEY_DESTOVERLAY;
1950 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1951 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1954 if( dwFlags )
1956 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1959 return DD_OK;
1963 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1964 LPDIRECTDRAWSURFACE4 iface,
1965 LPRECT lpRect )
1967 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1968 FIXME("(%p)->(%p),stub!\n",This,lpRect);
1970 return DD_OK;
1973 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1974 LPDIRECTDRAWSURFACE4 iface,
1975 DWORD dwFlags,
1976 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1978 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1979 int i;
1980 struct _surface_chain *chain;
1982 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
1983 chain = This->s.chain;
1984 for (i=0;i<chain->nrofsurfaces;i++) {
1985 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
1986 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
1988 chain->surfaces[i]->s.chain = NULL;
1989 memcpy( chain->surfaces+i,
1990 chain->surfaces+(i+1),
1991 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
1993 chain->surfaces = HeapReAlloc(
1994 GetProcessHeap(),
1996 chain->surfaces,
1997 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
1999 chain->nrofsurfaces--;
2000 return DD_OK;
2003 return DD_OK;
2006 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
2007 LPDIRECTDRAWSURFACE4 iface,
2008 DWORD dwFlags,
2009 LPVOID lpContext,
2010 LPDDENUMSURFACESCALLBACK lpfnCallback )
2012 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2013 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
2014 lpContext, lpfnCallback );
2016 return DD_OK;
2019 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
2020 LPDIRECTDRAWSURFACE4 iface,
2021 LPDIRECTDRAWCLIPPER* lplpDDClipper )
2023 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2024 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
2026 return DD_OK;
2029 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
2030 LPDIRECTDRAWSURFACE4 iface,
2031 DWORD dwFlags,
2032 LPDDCOLORKEY lpDDColorKey )
2034 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2035 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
2037 if( dwFlags & DDCKEY_SRCBLT ) {
2038 dwFlags &= ~DDCKEY_SRCBLT;
2039 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
2042 if( dwFlags & DDCKEY_DESTBLT )
2044 dwFlags &= ~DDCKEY_DESTBLT;
2045 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
2048 if( dwFlags & DDCKEY_SRCOVERLAY )
2050 dwFlags &= ~DDCKEY_SRCOVERLAY;
2051 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
2054 if( dwFlags & DDCKEY_DESTOVERLAY )
2056 dwFlags &= ~DDCKEY_DESTOVERLAY;
2057 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
2060 if( dwFlags )
2062 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2065 return DD_OK;
2068 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
2069 LPDIRECTDRAWSURFACE4 iface,
2070 DWORD dwFlags )
2072 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2073 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2075 return DD_OK;
2078 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
2079 LPDIRECTDRAWSURFACE4 iface,
2080 LPDIRECTDRAWPALETTE* lplpDDPalette )
2082 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2083 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
2085 if (This->s.palette != NULL) {
2086 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
2088 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
2089 return DD_OK;
2090 } else {
2091 return DDERR_NOPALETTEATTACHED;
2095 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
2096 LPDIRECTDRAWSURFACE4 iface,
2097 LONG lX,
2098 LONG lY)
2100 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2101 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
2103 return DD_OK;
2106 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
2107 LPDIRECTDRAWSURFACE4 iface,
2108 LPRECT lpSrcRect,
2109 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
2110 LPRECT lpDestRect,
2111 DWORD dwFlags,
2112 LPDDOVERLAYFX lpDDOverlayFx )
2114 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2115 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
2116 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
2118 return DD_OK;
2121 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
2122 LPDIRECTDRAWSURFACE4 iface,
2123 DWORD dwFlags )
2125 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2126 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2128 return DD_OK;
2131 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2132 LPDIRECTDRAWSURFACE4 iface,
2133 DWORD dwFlags,
2134 LPDIRECTDRAWSURFACE4 lpDDSReference )
2136 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2137 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2139 return DD_OK;
2142 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2143 LPDIRECTDRAWSURFACE4 iface,
2144 LPVOID* lplpDD )
2146 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2147 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2149 /* Not sure about that... */
2150 *lplpDD = (void *) This->s.ddraw;
2152 return DD_OK;
2155 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2156 LPDIRECTDRAWSURFACE4 iface,
2157 DWORD dwFlags )
2159 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2160 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2162 return DD_OK;
2165 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2166 LPDIRECTDRAWSURFACE4 iface,
2167 DWORD dwFlags )
2169 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2170 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2172 return DD_OK;
2175 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2176 LPDIRECTDRAWSURFACE4 iface,
2177 LPDDSURFACEDESC lpDDSD,
2178 DWORD dwFlags )
2180 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2181 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2183 return DD_OK;
2186 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2187 REFGUID guidTag,
2188 LPVOID lpData,
2189 DWORD cbSize,
2190 DWORD dwFlags) {
2191 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2192 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2194 return DD_OK;
2197 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2198 REFGUID guidTag,
2199 LPVOID lpBuffer,
2200 LPDWORD lpcbBufferSize) {
2201 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2202 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2204 return DD_OK;
2207 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2208 REFGUID guidTag) {
2209 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2210 FIXME("(%p)->(%p)\n", This, guidTag);
2212 return DD_OK;
2215 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2216 LPDWORD lpValue) {
2217 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2218 FIXME("(%p)->(%p)\n", This, lpValue);
2220 return DD_OK;
2223 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2224 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2225 FIXME("(%p)\n", This);
2227 return DD_OK;
2230 #ifdef HAVE_LIBXXF86DGA
2231 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2233 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2234 IDirectDrawSurface4Impl_QueryInterface,
2235 IDirectDrawSurface4Impl_AddRef,
2236 DGA_IDirectDrawSurface4Impl_Release,
2237 IDirectDrawSurface4Impl_AddAttachedSurface,
2238 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2239 IDirectDrawSurface4Impl_Blt,
2240 IDirectDrawSurface4Impl_BltBatch,
2241 IDirectDrawSurface4Impl_BltFast,
2242 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2243 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2244 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2245 DGA_IDirectDrawSurface4Impl_Flip,
2246 IDirectDrawSurface4Impl_GetAttachedSurface,
2247 IDirectDrawSurface4Impl_GetBltStatus,
2248 IDirectDrawSurface4Impl_GetCaps,
2249 IDirectDrawSurface4Impl_GetClipper,
2250 IDirectDrawSurface4Impl_GetColorKey,
2251 IDirectDrawSurface4Impl_GetDC,
2252 IDirectDrawSurface4Impl_GetFlipStatus,
2253 IDirectDrawSurface4Impl_GetOverlayPosition,
2254 IDirectDrawSurface4Impl_GetPalette,
2255 IDirectDrawSurface4Impl_GetPixelFormat,
2256 IDirectDrawSurface4Impl_GetSurfaceDesc,
2257 IDirectDrawSurface4Impl_Initialize,
2258 IDirectDrawSurface4Impl_IsLost,
2259 IDirectDrawSurface4Impl_Lock,
2260 IDirectDrawSurface4Impl_ReleaseDC,
2261 IDirectDrawSurface4Impl_Restore,
2262 IDirectDrawSurface4Impl_SetClipper,
2263 IDirectDrawSurface4Impl_SetColorKey,
2264 IDirectDrawSurface4Impl_SetOverlayPosition,
2265 DGA_IDirectDrawSurface4Impl_SetPalette,
2266 DGA_IDirectDrawSurface4Impl_Unlock,
2267 IDirectDrawSurface4Impl_UpdateOverlay,
2268 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2269 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2270 IDirectDrawSurface4Impl_GetDDInterface,
2271 IDirectDrawSurface4Impl_PageLock,
2272 IDirectDrawSurface4Impl_PageUnlock,
2273 IDirectDrawSurface4Impl_SetSurfaceDesc,
2274 IDirectDrawSurface4Impl_SetPrivateData,
2275 IDirectDrawSurface4Impl_GetPrivateData,
2276 IDirectDrawSurface4Impl_FreePrivateData,
2277 IDirectDrawSurface4Impl_GetUniquenessValue,
2278 IDirectDrawSurface4Impl_ChangeUniquenessValue
2280 #endif /* defined(HAVE_LIBXXF86DGA) */
2282 #ifdef HAVE_LIBXXF86DGA2
2283 static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
2285 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2286 IDirectDrawSurface4Impl_QueryInterface,
2287 IDirectDrawSurface4Impl_AddRef,
2288 DGA_IDirectDrawSurface4Impl_Release,
2289 IDirectDrawSurface4Impl_AddAttachedSurface,
2290 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2291 IDirectDrawSurface4Impl_Blt,
2292 IDirectDrawSurface4Impl_BltBatch,
2293 IDirectDrawSurface4Impl_BltFast,
2294 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2295 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2296 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2297 DGA2_IDirectDrawSurface4Impl_Flip,
2298 IDirectDrawSurface4Impl_GetAttachedSurface,
2299 IDirectDrawSurface4Impl_GetBltStatus,
2300 IDirectDrawSurface4Impl_GetCaps,
2301 IDirectDrawSurface4Impl_GetClipper,
2302 IDirectDrawSurface4Impl_GetColorKey,
2303 IDirectDrawSurface4Impl_GetDC,
2304 IDirectDrawSurface4Impl_GetFlipStatus,
2305 IDirectDrawSurface4Impl_GetOverlayPosition,
2306 IDirectDrawSurface4Impl_GetPalette,
2307 IDirectDrawSurface4Impl_GetPixelFormat,
2308 IDirectDrawSurface4Impl_GetSurfaceDesc,
2309 IDirectDrawSurface4Impl_Initialize,
2310 IDirectDrawSurface4Impl_IsLost,
2311 IDirectDrawSurface4Impl_Lock,
2312 IDirectDrawSurface4Impl_ReleaseDC,
2313 IDirectDrawSurface4Impl_Restore,
2314 IDirectDrawSurface4Impl_SetClipper,
2315 IDirectDrawSurface4Impl_SetColorKey,
2316 IDirectDrawSurface4Impl_SetOverlayPosition,
2317 DGA_IDirectDrawSurface4Impl_SetPalette,
2318 DGA_IDirectDrawSurface4Impl_Unlock,
2319 IDirectDrawSurface4Impl_UpdateOverlay,
2320 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2321 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2322 IDirectDrawSurface4Impl_GetDDInterface,
2323 IDirectDrawSurface4Impl_PageLock,
2324 IDirectDrawSurface4Impl_PageUnlock,
2325 IDirectDrawSurface4Impl_SetSurfaceDesc,
2326 IDirectDrawSurface4Impl_SetPrivateData,
2327 IDirectDrawSurface4Impl_GetPrivateData,
2328 IDirectDrawSurface4Impl_FreePrivateData,
2329 IDirectDrawSurface4Impl_GetUniquenessValue,
2330 IDirectDrawSurface4Impl_ChangeUniquenessValue
2332 #endif /* defined(HAVE_LIBXXF86DGA2) */
2334 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2336 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2337 IDirectDrawSurface4Impl_QueryInterface,
2338 IDirectDrawSurface4Impl_AddRef,
2339 Xlib_IDirectDrawSurface4Impl_Release,
2340 IDirectDrawSurface4Impl_AddAttachedSurface,
2341 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2342 IDirectDrawSurface4Impl_Blt,
2343 IDirectDrawSurface4Impl_BltBatch,
2344 IDirectDrawSurface4Impl_BltFast,
2345 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2346 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2347 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2348 Xlib_IDirectDrawSurface4Impl_Flip,
2349 IDirectDrawSurface4Impl_GetAttachedSurface,
2350 IDirectDrawSurface4Impl_GetBltStatus,
2351 IDirectDrawSurface4Impl_GetCaps,
2352 IDirectDrawSurface4Impl_GetClipper,
2353 IDirectDrawSurface4Impl_GetColorKey,
2354 IDirectDrawSurface4Impl_GetDC,
2355 IDirectDrawSurface4Impl_GetFlipStatus,
2356 IDirectDrawSurface4Impl_GetOverlayPosition,
2357 IDirectDrawSurface4Impl_GetPalette,
2358 IDirectDrawSurface4Impl_GetPixelFormat,
2359 IDirectDrawSurface4Impl_GetSurfaceDesc,
2360 IDirectDrawSurface4Impl_Initialize,
2361 IDirectDrawSurface4Impl_IsLost,
2362 IDirectDrawSurface4Impl_Lock,
2363 IDirectDrawSurface4Impl_ReleaseDC,
2364 IDirectDrawSurface4Impl_Restore,
2365 IDirectDrawSurface4Impl_SetClipper,
2366 IDirectDrawSurface4Impl_SetColorKey,
2367 IDirectDrawSurface4Impl_SetOverlayPosition,
2368 Xlib_IDirectDrawSurface4Impl_SetPalette,
2369 Xlib_IDirectDrawSurface4Impl_Unlock,
2370 IDirectDrawSurface4Impl_UpdateOverlay,
2371 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2372 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2373 IDirectDrawSurface4Impl_GetDDInterface,
2374 IDirectDrawSurface4Impl_PageLock,
2375 IDirectDrawSurface4Impl_PageUnlock,
2376 IDirectDrawSurface4Impl_SetSurfaceDesc,
2377 IDirectDrawSurface4Impl_SetPrivateData,
2378 IDirectDrawSurface4Impl_GetPrivateData,
2379 IDirectDrawSurface4Impl_FreePrivateData,
2380 IDirectDrawSurface4Impl_GetUniquenessValue,
2381 IDirectDrawSurface4Impl_ChangeUniquenessValue
2384 /******************************************************************************
2385 * DirectDrawCreateClipper (DDRAW.7)
2387 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2388 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2389 LPUNKNOWN pUnkOuter)
2391 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2392 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2394 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2395 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2396 (*ilplpDDClipper)->ref = 1;
2398 (*ilplpDDClipper)->hWnd = 0;
2400 return DD_OK;
2403 /******************************************************************************
2404 * IDirectDrawClipper
2406 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2407 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
2409 ICOM_THIS(IDirectDrawClipperImpl,iface);
2411 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
2412 if( dwFlags ) {
2413 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
2414 return DDERR_INVALIDPARAMS;
2417 This->hWnd = hWnd;
2418 return DD_OK;
2421 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2422 ICOM_THIS(IDirectDrawClipperImpl,iface);
2423 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2425 This->ref--;
2426 if (This->ref)
2427 return This->ref;
2428 HeapFree(GetProcessHeap(),0,This);
2429 return S_OK;
2432 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2433 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2435 ICOM_THIS(IDirectDrawClipperImpl,iface);
2436 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2437 if (hmm) *hmm=0;
2438 return DD_OK;
2441 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2442 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2444 ICOM_THIS(IDirectDrawClipperImpl,iface);
2445 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2446 return DD_OK;
2449 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2450 LPDIRECTDRAWCLIPPER iface,
2451 REFIID riid,
2452 LPVOID* ppvObj )
2454 ICOM_THIS(IDirectDrawClipperImpl,iface);
2455 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2456 return OLE_E_ENUM_NOMORE;
2459 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2461 ICOM_THIS(IDirectDrawClipperImpl,iface);
2462 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2463 return ++(This->ref);
2466 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2467 LPDIRECTDRAWCLIPPER iface,
2468 HWND* hWndPtr )
2470 ICOM_THIS(IDirectDrawClipperImpl,iface);
2471 FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
2473 *hWndPtr = This->hWnd;
2475 return DD_OK;
2478 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2479 LPDIRECTDRAWCLIPPER iface,
2480 LPDIRECTDRAW lpDD,
2481 DWORD dwFlags )
2483 ICOM_THIS(IDirectDrawClipperImpl,iface);
2484 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2485 return DD_OK;
2488 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2489 LPDIRECTDRAWCLIPPER iface,
2490 BOOL* lpbChanged )
2492 ICOM_THIS(IDirectDrawClipperImpl,iface);
2493 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2494 return DD_OK;
2497 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2499 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2500 IDirectDrawClipperImpl_QueryInterface,
2501 IDirectDrawClipperImpl_AddRef,
2502 IDirectDrawClipperImpl_Release,
2503 IDirectDrawClipperImpl_GetClipList,
2504 IDirectDrawClipperImpl_GetHWnd,
2505 IDirectDrawClipperImpl_Initialize,
2506 IDirectDrawClipperImpl_IsClipListChanged,
2507 IDirectDrawClipperImpl_SetClipList,
2508 IDirectDrawClipperImpl_SetHwnd
2512 /******************************************************************************
2513 * IDirectDrawPalette
2515 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2516 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2518 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2519 int i;
2521 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2522 This,x,start,count,palent);
2524 /* No palette created and not in depth-convertion mode -> BUG ! */
2525 if ((This->cm == None) &&
2526 (This->ddraw->d.palette_convert == NULL))
2528 FIXME("app tried to read colormap for non-palettized mode\n");
2529 return DDERR_GENERIC;
2531 for (i=0;i<count;i++) {
2532 palent[i].peRed = This->palents[start+i].peRed;
2533 palent[i].peBlue = This->palents[start+i].peBlue;
2534 palent[i].peGreen = This->palents[start+i].peGreen;
2535 palent[i].peFlags = This->palents[start+i].peFlags;
2538 return DD_OK;
2541 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2542 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2544 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2545 XColor xc;
2546 int i;
2548 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2549 This,x,start,count,palent
2551 for (i=0;i<count;i++) {
2552 xc.red = palent[i].peRed<<8;
2553 xc.blue = palent[i].peBlue<<8;
2554 xc.green = palent[i].peGreen<<8;
2555 xc.flags = DoRed|DoBlue|DoGreen;
2556 xc.pixel = start+i;
2558 if (This->cm)
2559 TSXStoreColor(display,This->cm,&xc);
2561 This->palents[start+i].peRed = palent[i].peRed;
2562 This->palents[start+i].peBlue = palent[i].peBlue;
2563 This->palents[start+i].peGreen = palent[i].peGreen;
2564 This->palents[start+i].peFlags = palent[i].peFlags;
2567 /* Now, if we are in 'depth conversion mode', update the screen palette */
2568 /* FIXME: we need to update the image or we won't get palette fading. */
2569 if (This->ddraw->d.palette_convert != NULL)
2570 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2572 return DD_OK;
2575 #ifdef HAVE_LIBXXF86DGA
2576 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2577 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2579 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2580 XColor xc;
2581 Colormap cm;
2582 int i;
2584 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2585 This,x,start,count,palent
2587 if (!This->cm) /* should not happen */ {
2588 FIXME("app tried to set colormap in non-palettized mode\n");
2589 return DDERR_GENERIC;
2591 /* FIXME: free colorcells instead of freeing whole map */
2592 cm = This->cm;
2593 This->cm = TSXCopyColormapAndFree(display,This->cm);
2594 TSXFreeColormap(display,cm);
2596 for (i=0;i<count;i++) {
2597 xc.red = palent[i].peRed<<8;
2598 xc.blue = palent[i].peBlue<<8;
2599 xc.green = palent[i].peGreen<<8;
2600 xc.flags = DoRed|DoBlue|DoGreen;
2601 xc.pixel = i+start;
2603 TSXStoreColor(display,This->cm,&xc);
2605 This->palents[start+i].peRed = palent[i].peRed;
2606 This->palents[start+i].peBlue = palent[i].peBlue;
2607 This->palents[start+i].peGreen = palent[i].peGreen;
2608 This->palents[start+i].peFlags = palent[i].peFlags;
2610 #ifdef HAVE_LIBXXF86DGA2
2611 if (This->ddraw->e.dga.version == 2)
2612 TSXDGAInstallColormap(display,DefaultScreen(display),This->cm);
2613 else
2614 #endif /* defined(HAVE_LIBXXF86DGA2) */
2615 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2616 return DD_OK;
2618 #endif /* defined(HAVE_LIBXXF86DGA) */
2620 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2621 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2622 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2623 if (!--(This->ref)) {
2624 if (This->cm) {
2625 TSXFreeColormap(display,This->cm);
2626 This->cm = 0;
2628 HeapFree(GetProcessHeap(),0,This);
2629 return S_OK;
2631 return This->ref;
2634 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2635 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2637 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2638 return ++(This->ref);
2641 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2642 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2644 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2645 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2647 return DDERR_ALREADYINITIALIZED;
2650 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2651 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2653 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2654 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2655 return DD_OK;
2658 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2659 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2661 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2662 char xrefiid[50];
2664 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2665 FIXME("(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2667 return S_OK;
2670 #ifdef HAVE_LIBXXF86DGA
2671 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2673 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2674 IDirectDrawPaletteImpl_QueryInterface,
2675 IDirectDrawPaletteImpl_AddRef,
2676 IDirectDrawPaletteImpl_Release,
2677 IDirectDrawPaletteImpl_GetCaps,
2678 IDirectDrawPaletteImpl_GetEntries,
2679 IDirectDrawPaletteImpl_Initialize,
2680 DGA_IDirectDrawPaletteImpl_SetEntries
2682 #endif /* defined(HAVE_LIBXXF86DGA) */
2684 static ICOM_VTABLE(IDirectDrawPalette) xlib_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 Xlib_IDirectDrawPaletteImpl_SetEntries
2696 /*******************************************************************************
2697 * IDirect3D
2699 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2700 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2702 ICOM_THIS(IDirect3DImpl,iface);
2703 /* FIXME: Not sure if this is correct */
2704 char xrefiid[50];
2706 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2707 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2708 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2709 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2710 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2711 *obj = This->ddraw;
2712 IDirect3D_AddRef(iface);
2714 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2716 return S_OK;
2718 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2719 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2720 *obj = This;
2721 IDirect3D_AddRef(iface);
2723 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2725 return S_OK;
2727 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2728 IDirect3D2Impl* d3d;
2730 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2731 d3d->ref = 1;
2732 d3d->ddraw = This->ddraw;
2733 IDirect3D_AddRef(iface);
2734 ICOM_VTBL(d3d) = &d3d2vt;
2735 *obj = d3d;
2737 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2739 return S_OK;
2741 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2742 return OLE_E_ENUM_NOMORE;
2745 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2746 ICOM_THIS(IDirect3DImpl,iface);
2747 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2749 return ++(This->ref);
2752 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2754 ICOM_THIS(IDirect3DImpl,iface);
2755 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2757 if (!--(This->ref)) {
2758 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2759 HeapFree(GetProcessHeap(),0,This);
2760 return S_OK;
2762 return This->ref;
2765 static HRESULT WINAPI IDirect3DImpl_Initialize(
2766 LPDIRECT3D iface, REFIID refiid )
2768 ICOM_THIS(IDirect3DImpl,iface);
2769 /* FIXME: Not sure if this is correct */
2770 char xrefiid[50];
2772 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2773 FIXME("(%p)->(%s):stub.\n",This,xrefiid);
2775 return DDERR_ALREADYINITIALIZED;
2778 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2779 LPD3DENUMDEVICESCALLBACK cb,
2780 LPVOID context) {
2781 ICOM_THIS(IDirect3DImpl,iface);
2782 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2784 /* Call functions defined in d3ddevices.c */
2785 if (!d3d_OpenGL_dx3(cb, context))
2786 return DD_OK;
2788 return DD_OK;
2791 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2792 LPDIRECT3DLIGHT *lplight,
2793 IUnknown *lpunk)
2795 ICOM_THIS(IDirect3DImpl,iface);
2796 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2798 /* Call the creation function that is located in d3dlight.c */
2799 *lplight = d3dlight_create_dx3(This);
2801 return DD_OK;
2804 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2805 LPDIRECT3DMATERIAL *lpmaterial,
2806 IUnknown *lpunk)
2808 ICOM_THIS(IDirect3DImpl,iface);
2809 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2811 /* Call the creation function that is located in d3dviewport.c */
2812 *lpmaterial = d3dmaterial_create(This);
2814 return DD_OK;
2817 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2818 LPDIRECT3DVIEWPORT *lpviewport,
2819 IUnknown *lpunk)
2821 ICOM_THIS(IDirect3DImpl,iface);
2822 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2824 /* Call the creation function that is located in d3dviewport.c */
2825 *lpviewport = d3dviewport_create(This);
2827 return DD_OK;
2830 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2831 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2832 LPD3DFINDDEVICERESULT lpfinddevrst)
2834 ICOM_THIS(IDirect3DImpl,iface);
2835 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2837 return DD_OK;
2840 static ICOM_VTABLE(IDirect3D) d3dvt =
2842 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2843 IDirect3DImpl_QueryInterface,
2844 IDirect3DImpl_AddRef,
2845 IDirect3DImpl_Release,
2846 IDirect3DImpl_Initialize,
2847 IDirect3DImpl_EnumDevices,
2848 IDirect3DImpl_CreateLight,
2849 IDirect3DImpl_CreateMaterial,
2850 IDirect3DImpl_CreateViewport,
2851 IDirect3DImpl_FindDevice
2854 /*******************************************************************************
2855 * IDirect3D2
2857 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2858 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2859 ICOM_THIS(IDirect3D2Impl,iface);
2861 /* FIXME: Not sure if this is correct */
2862 char xrefiid[50];
2864 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2865 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2866 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2867 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2868 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2869 *obj = This->ddraw;
2870 IDirect3D2_AddRef(iface);
2872 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2874 return S_OK;
2876 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2877 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2878 *obj = This;
2879 IDirect3D2_AddRef(iface);
2881 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2883 return S_OK;
2885 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2886 IDirect3DImpl* d3d;
2888 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2889 d3d->ref = 1;
2890 d3d->ddraw = This->ddraw;
2891 IDirect3D2_AddRef(iface);
2892 ICOM_VTBL(d3d) = &d3dvt;
2893 *obj = d3d;
2895 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2897 return S_OK;
2899 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2900 return OLE_E_ENUM_NOMORE;
2903 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2904 ICOM_THIS(IDirect3D2Impl,iface);
2905 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2907 return ++(This->ref);
2910 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2911 ICOM_THIS(IDirect3D2Impl,iface);
2912 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2914 if (!--(This->ref)) {
2915 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2916 HeapFree(GetProcessHeap(),0,This);
2917 return S_OK;
2919 return This->ref;
2922 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2923 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2925 ICOM_THIS(IDirect3D2Impl,iface);
2926 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2928 /* Call functions defined in d3ddevices.c */
2929 if (!d3d_OpenGL(cb, context))
2930 return DD_OK;
2932 return DD_OK;
2935 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2936 LPDIRECT3DLIGHT *lplight,
2937 IUnknown *lpunk)
2939 ICOM_THIS(IDirect3D2Impl,iface);
2940 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2942 /* Call the creation function that is located in d3dlight.c */
2943 *lplight = d3dlight_create(This);
2945 return DD_OK;
2948 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2949 LPDIRECT3DMATERIAL2 *lpmaterial,
2950 IUnknown *lpunk)
2952 ICOM_THIS(IDirect3D2Impl,iface);
2953 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2955 /* Call the creation function that is located in d3dviewport.c */
2956 *lpmaterial = d3dmaterial2_create(This);
2958 return DD_OK;
2961 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2962 LPDIRECT3DVIEWPORT2 *lpviewport,
2963 IUnknown *lpunk)
2965 ICOM_THIS(IDirect3D2Impl,iface);
2966 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2968 /* Call the creation function that is located in d3dviewport.c */
2969 *lpviewport = d3dviewport2_create(This);
2971 return DD_OK;
2974 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2975 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2976 LPD3DFINDDEVICERESULT lpfinddevrst)
2978 ICOM_THIS(IDirect3D2Impl,iface);
2979 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2981 return DD_OK;
2984 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2985 REFCLSID rguid,
2986 LPDIRECTDRAWSURFACE surface,
2987 LPDIRECT3DDEVICE2 *device)
2989 ICOM_THIS(IDirect3D2Impl,iface);
2990 char xbuf[50];
2992 WINE_StringFromCLSID(rguid,xbuf);
2993 FIXME("(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2995 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2996 IDirect3D2_AddRef(iface);
2997 return DD_OK;
3000 return DDERR_INVALIDPARAMS;
3003 static ICOM_VTABLE(IDirect3D2) d3d2vt =
3005 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3006 IDirect3D2Impl_QueryInterface,
3007 IDirect3D2Impl_AddRef,
3008 IDirect3D2Impl_Release,
3009 IDirect3D2Impl_EnumDevices,
3010 IDirect3D2Impl_CreateLight,
3011 IDirect3D2Impl_CreateMaterial,
3012 IDirect3D2Impl_CreateViewport,
3013 IDirect3D2Impl_FindDevice,
3014 IDirect3D2Impl_CreateDevice
3017 /*******************************************************************************
3018 * IDirectDraw
3021 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
3022 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
3024 static INT ddrawXlibThisOffset = 0;
3026 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
3027 IDirectDrawSurfaceImpl* lpdsf)
3029 int bpp;
3031 /* The surface was already allocated when entering in this function */
3032 TRACE("using system memory for a surface (%p) \n", lpdsf);
3034 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
3035 /* This is a Z Buffer */
3036 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
3037 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
3038 } else {
3039 /* This is a standard image */
3040 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
3041 /* No pixel format => use DirectDraw's format */
3042 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3043 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
3045 bpp = GET_BPP(lpdsf->s.surface_desc);
3048 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
3049 /* The surface was preallocated : seems that we have nothing to do :-) */
3050 ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
3053 assert(bpp);
3054 FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf->s.surface_desc.dwWidth,lpdsf->s.surface_desc.dwHeight,bpp);
3056 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
3057 lpdsf->s.surface_desc.u1.lpSurface =
3058 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
3059 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
3061 return DD_OK;
3064 #ifdef HAVE_LIBXXF86DGA
3065 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
3066 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3068 ICOM_THIS(IDirectDraw2Impl,iface);
3069 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3070 int i, fbheight = This->e.dga.fb_height;
3072 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
3073 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3075 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3076 GetProcessHeap(),
3077 HEAP_ZERO_MEMORY,
3078 sizeof(IDirectDrawSurfaceImpl)
3080 IDirectDraw2_AddRef(iface);
3082 (*ilpdsf)->ref = 1;
3083 #ifdef HAVE_LIBXXF86DGA2
3084 if (This->e.dga.version == 2)
3085 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
3086 else
3087 #endif /* defined(HAVE_LIBXXF86DGA2) */
3088 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
3089 (*ilpdsf)->s.ddraw = This;
3090 (*ilpdsf)->s.palette = NULL;
3091 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
3092 (*ilpdsf)->s.lpClipper = NULL;
3094 /* Copy the surface description */
3095 (*ilpdsf)->s.surface_desc = *lpddsd;
3097 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3098 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3099 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3100 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3102 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3104 /* Check if this a 'primary surface' or not */
3105 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3106 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3107 /* This is THE primary surface => there is DGA-specific code */
3109 /* First, store the surface description */
3110 (*ilpdsf)->s.surface_desc = *lpddsd;
3112 /* Find a viewport */
3113 for (i=0;i<32;i++)
3114 if (!(This->e.dga.vpmask & (1<<i)))
3115 break;
3116 TRACE("using viewport %d for a primary surface\n",i);
3117 /* if i == 32 or maximum ... return error */
3118 This->e.dga.vpmask|=(1<<i);
3119 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
3120 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
3122 (*ilpdsf)->s.surface_desc.u1.lpSurface =
3123 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3125 (*ilpdsf)->t.dga.fb_height = i*fbheight;
3127 /* Add flags if there were not present */
3128 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3129 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3130 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3131 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
3132 /* We put our surface always in video memory */
3133 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3134 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3135 (*ilpdsf)->s.chain = NULL;
3137 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3138 IDirectDrawSurface4Impl* back;
3139 int bbc;
3141 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
3142 int i;
3144 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3145 GetProcessHeap(),
3146 HEAP_ZERO_MEMORY,
3147 sizeof(IDirectDrawSurface4Impl)
3149 IDirectDraw2_AddRef(iface);
3150 back->ref = 1;
3151 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
3152 for (i=0;i<32;i++)
3153 if (!(This->e.dga.vpmask & (1<<i)))
3154 break;
3155 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
3156 /* if i == 32 or maximum ... return error */
3157 This->e.dga.vpmask|=(1<<i);
3158 back->t.dga.fb_height = i*fbheight;
3159 /* Copy the surface description from the front buffer */
3160 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3161 /* Change the parameters that are not the same */
3162 back->s.surface_desc.u1.lpSurface =
3163 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3165 back->s.ddraw = This;
3166 /* Add relevant info to front and back buffers */
3167 /* FIXME: backbuffer/frontbuffer handling broken here, but
3168 * will be fixed up in _Flip().
3170 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3171 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
3172 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3173 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3174 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3177 } else {
3178 /* There is no DGA-specific code here...
3179 Go to the common surface creation function */
3180 return common_off_screen_CreateSurface(This, *ilpdsf);
3182 return DD_OK;
3184 #endif /* defined(HAVE_LIBXXF86DGA) */
3186 #ifdef HAVE_LIBXXSHM
3187 /* Error handlers for Image creation */
3188 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
3189 XShmErrorFlag = 1;
3190 return 0;
3193 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3194 XImage *img;
3195 int (*WineXHandler)(Display *, XErrorEvent *);
3197 img = TSXShmCreateImage(display,
3198 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3199 This->d.pixmap_depth,
3200 ZPixmap,
3201 NULL,
3202 &(lpdsf->t.xlib.shminfo),
3203 lpdsf->s.surface_desc.dwWidth,
3204 lpdsf->s.surface_desc.dwHeight
3207 if (img == NULL) {
3208 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3209 This->e.xlib.xshm_active = 0;
3210 return NULL;
3213 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3214 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3215 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3216 This->e.xlib.xshm_active = 0;
3217 TSXDestroyImage(img);
3218 return NULL;
3221 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3223 if (img->data == (char *) -1) {
3224 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3225 This->e.xlib.xshm_active = 0;
3226 TSXDestroyImage(img);
3227 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3228 return NULL;
3230 lpdsf->t.xlib.shminfo.readOnly = False;
3232 /* This is where things start to get trickier....
3233 * First, we flush the current X connections to be sure to catch all
3234 * non-XShm related errors
3236 TSXSync(display, False);
3237 /* Then we enter in the non-thread safe part of the tests */
3238 EnterCriticalSection( &X11DRV_CritSection );
3240 /* Reset the error flag, sets our new error handler and try to attach
3241 * the surface
3243 XShmErrorFlag = 0;
3244 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3245 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3246 XSync(display, False);
3248 /* Check the error flag */
3249 if (XShmErrorFlag) {
3250 /* An error occured */
3251 XFlush(display);
3252 XShmErrorFlag = 0;
3253 XDestroyImage(img);
3254 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3255 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3256 XSetErrorHandler(WineXHandler);
3258 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3259 This->e.xlib.xshm_active = 0;
3261 /* Leave the critical section */
3262 LeaveCriticalSection( &X11DRV_CritSection );
3263 return NULL;
3265 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3266 * this works, but it may be a bit overkill....
3268 XSetErrorHandler(WineXHandler);
3269 LeaveCriticalSection( &X11DRV_CritSection );
3271 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3273 if (This->d.pixel_convert != NULL) {
3274 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3275 GetProcessHeap(),
3276 HEAP_ZERO_MEMORY,
3277 lpdsf->s.surface_desc.dwWidth *
3278 lpdsf->s.surface_desc.dwHeight *
3279 PFGET_BPP(This->d.directdraw_pixelformat)
3281 } else {
3282 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3284 return img;
3286 #endif /* HAVE_LIBXXSHM */
3288 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3289 XImage *img = NULL;
3290 void *img_data;
3292 #ifdef HAVE_LIBXXSHM
3293 if (This->e.xlib.xshm_active)
3294 img = create_xshmimage(This, lpdsf);
3296 if (img == NULL) {
3297 #endif
3298 /* Allocate surface memory */
3299 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3300 GetProcessHeap(),HEAP_ZERO_MEMORY,
3301 lpdsf->s.surface_desc.dwWidth *
3302 lpdsf->s.surface_desc.dwHeight *
3303 PFGET_BPP(This->d.directdraw_pixelformat)
3306 if (This->d.pixel_convert != NULL) {
3307 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3308 lpdsf->s.surface_desc.dwWidth *
3309 lpdsf->s.surface_desc.dwHeight *
3310 PFGET_BPP(This->d.screen_pixelformat)
3312 } else {
3313 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3316 /* In this case, create an XImage */
3317 img = TSXCreateImage(display,
3318 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3319 This->d.pixmap_depth,
3320 ZPixmap,
3322 img_data,
3323 lpdsf->s.surface_desc.dwWidth,
3324 lpdsf->s.surface_desc.dwHeight,
3326 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3328 #ifdef HAVE_LIBXXSHM
3330 #endif
3331 if (This->d.pixel_convert != NULL)
3332 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3333 else
3334 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3335 return img;
3338 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3339 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3341 ICOM_THIS(IDirectDraw2Impl,iface);
3342 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3344 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3346 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3348 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3349 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3352 IDirectDraw2_AddRef(iface);
3354 (*ilpdsf)->s.ddraw = This;
3355 (*ilpdsf)->ref = 1;
3356 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3357 (*ilpdsf)->s.palette = NULL;
3358 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3359 (*ilpdsf)->s.lpClipper = NULL;
3361 /* Copy the surface description */
3362 (*ilpdsf)->s.surface_desc = *lpddsd;
3364 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3365 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3366 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3367 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3368 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3370 /* Check if this a 'primary surface' or not */
3371 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3372 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3373 XImage *img;
3375 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3376 /* Create the XImage */
3377 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3378 if (img == NULL)
3379 return DDERR_OUTOFMEMORY;
3380 (*ilpdsf)->t.xlib.image = img;
3382 /* Add flags if there were not present */
3383 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3384 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3385 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3386 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3387 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3389 /* Check for backbuffers */
3390 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3391 IDirectDrawSurface4Impl* back;
3392 XImage *img;
3393 int i;
3395 for (i=lpddsd->dwBackBufferCount;i--;) {
3396 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3397 GetProcessHeap(),HEAP_ZERO_MEMORY,
3398 sizeof(IDirectDrawSurface4Impl)
3401 TRACE("allocated back-buffer (%p)\n", back);
3403 IDirectDraw2_AddRef(iface);
3404 back->s.ddraw = This;
3406 back->ref = 1;
3407 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3408 /* Copy the surface description from the front buffer */
3409 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3411 /* Create the XImage */
3412 img = create_ximage(This, back);
3413 if (img == NULL)
3414 return DDERR_OUTOFMEMORY;
3415 back->t.xlib.image = img;
3417 /* Add relevant info to front and back buffers */
3418 /* FIXME: backbuffer/frontbuffer handling broken here, but
3419 * will be fixed up in _Flip().
3421 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3422 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3423 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3424 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3425 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3428 } else {
3429 /* There is no Xlib-specific code here...
3430 Go to the common surface creation function */
3431 return common_off_screen_CreateSurface(This, *ilpdsf);
3433 return DD_OK;
3436 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3437 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3439 ICOM_THIS(IDirectDraw2Impl,iface);
3440 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3441 *dst = src; /* FIXME */
3442 return DD_OK;
3446 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3447 * even when the approbiate bitmasks are not specified.
3449 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3450 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3452 ICOM_THIS(IDirectDraw2Impl,iface);
3453 int i;
3454 const struct {
3455 int mask;
3456 char *name;
3457 } flags[] = {
3458 #define FE(x) { x, #x},
3459 FE(DDSCL_FULLSCREEN)
3460 FE(DDSCL_ALLOWREBOOT)
3461 FE(DDSCL_NOWINDOWCHANGES)
3462 FE(DDSCL_NORMAL)
3463 FE(DDSCL_ALLOWMODEX)
3464 FE(DDSCL_EXCLUSIVE)
3465 FE(DDSCL_SETFOCUSWINDOW)
3466 FE(DDSCL_SETDEVICEWINDOW)
3467 FE(DDSCL_CREATEDEVICEWINDOW)
3468 #undef FE
3471 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3472 if (TRACE_ON(ddraw)) {
3473 DPRINTF(" - ");
3474 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
3475 if (flags[i].mask & cooplevel) {
3476 DPRINTF("%s ",flags[i].name);
3479 DPRINTF("\n");
3481 This->d.mainWindow = hwnd;
3483 /* This will be overwritten in the case of Full Screen mode.
3484 Windowed games could work with that :-) */
3485 if (hwnd)
3487 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3488 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3489 WIN_ReleaseWndPtr(tmpWnd);
3491 if( !This->d.drawable ) {
3492 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3493 WIN_ReleaseDesktop();
3495 TRACE("Setting drawable to %ld\n", This->d.drawable);
3498 return DD_OK;
3501 /* Small helper to either use the cooperative window or create a new
3502 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3504 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3505 RECT rect;
3507 /* Do not destroy the application supplied cooperative window */
3508 if (This->d.window && This->d.window != This->d.mainWindow) {
3509 DestroyWindow(This->d.window);
3510 This->d.window = 0;
3512 /* Sanity check cooperative window before assigning it to drawing. */
3513 if ( IsWindow(This->d.mainWindow) &&
3514 IsWindowVisible(This->d.mainWindow)
3516 /* if it does not fit, resize the cooperative window.
3517 * and hope the app likes it
3519 GetWindowRect(This->d.mainWindow,&rect);
3520 if ((((rect.right-rect.left) >= This->d.width) &&
3521 ((rect.bottom-rect.top) >= This->d.height))
3523 This->d.window = This->d.mainWindow;
3524 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3528 /* ... failed, create new one. */
3529 if (!This->d.window) {
3530 This->d.window = CreateWindowExA(
3532 "WINE_DirectDraw",
3533 "WINE_DirectDraw",
3534 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3535 0,0,
3536 This->d.width,
3537 This->d.height,
3541 NULL
3543 /*Store THIS with the window. We'll use it in the window procedure*/
3544 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3545 ShowWindow(This->d.window,TRUE);
3546 UpdateWindow(This->d.window);
3548 SetFocus(This->d.window);
3551 static int _common_depth_to_pixelformat(DWORD depth,
3552 DDPIXELFORMAT *pixelformat,
3553 DDPIXELFORMAT *screen_pixelformat,
3554 int *pix_depth) {
3555 XVisualInfo *vi;
3556 XPixmapFormatValues *pf;
3557 XVisualInfo vt;
3558 int nvisuals, npixmap, i;
3559 int match = 0;
3560 int index = -2;
3562 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3563 pf = XListPixmapFormats(display, &npixmap);
3565 for (i = 0; i < npixmap; i++) {
3566 if (pf[i].depth == depth) {
3567 int j;
3569 for (j = 0; j < nvisuals; j++) {
3570 if (vi[j].depth == pf[i].depth) {
3571 pixelformat->dwSize = sizeof(*pixelformat);
3572 if (depth == 8) {
3573 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3574 pixelformat->u1.dwRBitMask = 0;
3575 pixelformat->u2.dwGBitMask = 0;
3576 pixelformat->u3.dwBBitMask = 0;
3577 } else {
3578 pixelformat->dwFlags = DDPF_RGB;
3579 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3580 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3581 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3583 pixelformat->dwFourCC = 0;
3584 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3585 pixelformat->u4.dwRGBAlphaBitMask= 0;
3587 *screen_pixelformat = *pixelformat;
3589 if (pix_depth != NULL)
3590 *pix_depth = vi[j].depth;
3592 match = 1;
3593 index = -1;
3595 goto clean_up_and_exit;
3599 ERR("No visual corresponding to pixmap format !\n");
3603 if (match == 0) {
3604 /* We try now to find an emulated mode */
3605 int c;
3607 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3608 if (ModeEmulations[c].dest.depth == depth) {
3609 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3610 for (i = 0; i < npixmap; i++) {
3611 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3612 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3613 int j;
3615 for (j = 0; j < nvisuals; j++) {
3616 if (vi[j].depth == pf[i].depth) {
3617 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3618 screen_pixelformat->dwFlags = DDPF_RGB;
3619 screen_pixelformat->dwFourCC = 0;
3620 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3621 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3622 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3623 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3624 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3626 pixelformat->dwSize = sizeof(*pixelformat);
3627 pixelformat->dwFourCC = 0;
3628 if (depth == 8) {
3629 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3630 pixelformat->u.dwRGBBitCount = 8;
3631 pixelformat->u1.dwRBitMask = 0;
3632 pixelformat->u2.dwGBitMask = 0;
3633 pixelformat->u3.dwBBitMask = 0;
3634 } else {
3635 pixelformat->dwFlags = DDPF_RGB;
3636 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3637 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3638 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3639 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3641 pixelformat->u4.dwRGBAlphaBitMask= 0;
3643 if (pix_depth != NULL)
3644 *pix_depth = vi[j].depth;
3646 match = 2;
3647 index = c;
3649 goto clean_up_and_exit;
3652 ERR("No visual corresponding to pixmap format !\n");
3660 clean_up_and_exit:
3661 TSXFree(vi);
3662 TSXFree(pf);
3664 return index;
3667 #ifdef HAVE_LIBXXF86DGA
3668 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3669 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3671 ICOM_THIS(IDirectDrawImpl,iface);
3672 int i,mode_count;
3674 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3676 #ifdef HAVE_LIBXXF86DGA2
3677 if (This->e.dga.version == 2)
3678 /* For the moment, we suppose we have the correct display settings when in DGA 2.0 mode */
3679 return DD_OK;
3680 #endif /* defined(HAVE_LIBXXF86DGA2) */
3682 /* We hope getting the asked for depth */
3683 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3684 /* I.e. no visual found or emulated */
3685 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3686 return DDERR_UNSUPPORTEDMODE;
3689 if (This->d.width < width) {
3690 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3691 return DDERR_UNSUPPORTEDMODE;
3693 This->d.width = width;
3694 This->d.height = height;
3696 /* adjust fb_height, so we don't overlap */
3697 if (This->e.dga.fb_height < height)
3698 This->e.dga.fb_height = height;
3699 _common_IDirectDrawImpl_SetDisplayMode(This);
3701 #ifdef HAVE_LIBXXF86VM
3702 #ifdef HAVE_LIBXXF86DGA2
3703 if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3704 #endif /* defined(HAVE_LIBXXF86DGA2) */
3706 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3707 XF86VidModeModeLine mod_tmp;
3708 /* int dotclock_tmp; */
3710 /* save original video mode and set fullscreen if available*/
3711 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3712 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3713 orig_mode->hdisplay = mod_tmp.hdisplay;
3714 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3715 orig_mode->hsyncend = mod_tmp.hsyncend;
3716 orig_mode->htotal = mod_tmp.htotal;
3717 orig_mode->vdisplay = mod_tmp.vdisplay;
3718 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3719 orig_mode->vsyncend = mod_tmp.vsyncend;
3720 orig_mode->vtotal = mod_tmp.vtotal;
3721 orig_mode->flags = mod_tmp.flags;
3722 orig_mode->private = mod_tmp.private;
3724 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3725 for (i=0;i<mode_count;i++)
3727 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3729 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3730 *vidmode = *(all_modes[i]);
3731 break;
3732 } else
3733 TSXFree(all_modes[i]->private);
3735 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3736 TSXFree(all_modes);
3738 if (!vidmode)
3739 WARN("Fullscreen mode not available!\n");
3741 if (vidmode)
3743 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3744 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3745 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3746 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3747 #endif
3750 #endif
3752 /* FIXME: this function OVERWRITES several signal handlers.
3753 * can we save them? and restore them later? In a way that
3754 * it works for the library too?
3756 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3757 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3759 #ifdef RESTORE_SIGNALS
3760 SIGNAL_Init();
3761 #endif
3762 return DD_OK;
3764 #endif /* defined(HAVE_LIBXXF86DGA) */
3766 /* *************************************
3767 16 / 15 bpp to palettized 8 bpp
3768 ************************************* */
3769 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3770 unsigned char *c_src = (unsigned char *) src;
3771 unsigned short *c_dst = (unsigned short *) dst;
3772 int y;
3774 if (palette != NULL) {
3775 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3777 for (y = height; y--; ) {
3778 #if defined(__i386__) && defined(__GNUC__)
3779 /* gcc generates slightly inefficient code for the the copy / lookup,
3780 * it generates one excess memory access (to pal) per pixel. Since
3781 * we know that pal is not modified by the memory write we can
3782 * put it into a register and reduce the number of memory accesses
3783 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3784 * (This is not guaranteed to be the fastest method.)
3786 __asm__ __volatile__(
3787 "xor %%eax,%%eax\n"
3788 "1:\n"
3789 " lodsb\n"
3790 " movw (%%edx,%%eax,2),%%ax\n"
3791 " stosw\n"
3792 " xor %%eax,%%eax\n"
3793 " loop 1b\n"
3794 : "=S" (c_src), "=D" (c_dst)
3795 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3796 : "eax", "cc", "memory"
3798 c_src+=(pitch-width);
3799 #else
3800 unsigned char * srclineend = c_src+width;
3801 while (c_src < srclineend)
3802 *c_dst++ = pal[*c_src++];
3803 c_src+=(pitch-width);
3804 #endif
3806 } else {
3807 WARN("No palette set...\n");
3808 memset(dst, 0, width * height * 2);
3811 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3812 int i;
3813 unsigned short *pal = (unsigned short *) screen_palette;
3815 for (i = 0; i < count; i++)
3816 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3817 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3818 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3820 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3821 int i;
3822 unsigned short *pal = (unsigned short *) screen_palette;
3824 for (i = 0; i < count; i++)
3825 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3826 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3827 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3830 /* *************************************
3831 24 to palettized 8 bpp
3832 ************************************* */
3833 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3834 unsigned char *c_src = (unsigned char *) src;
3835 unsigned char *c_dst = (unsigned char *) dst;
3836 int y;
3838 if (palette != NULL) {
3839 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3841 for (y = height; y--; ) {
3842 unsigned char * srclineend = c_src+width;
3843 while (c_src < srclineend ) {
3844 register long pixel = pal[*c_src++];
3845 *c_dst++ = pixel;
3846 *c_dst++ = pixel>>8;
3847 *c_dst++ = pixel>>16;
3849 c_src+=(pitch-width);
3851 } else {
3852 WARN("No palette set...\n");
3853 memset(dst, 0, width * height * 4);
3856 /* *************************************
3857 32 bpp to palettized 8 bpp
3858 ************************************* */
3859 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3860 unsigned char *c_src = (unsigned char *) src;
3861 unsigned int *c_dst = (unsigned int *) dst;
3862 int y;
3864 if (palette != NULL) {
3865 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3867 for (y = height; y--; ) {
3868 #if defined(__i386__) && defined(__GNUC__)
3869 /* See comment in pixel_convert_16_to_8 */
3870 __asm__ __volatile__(
3871 "xor %%eax,%%eax\n"
3872 "1:\n"
3873 " lodsb\n"
3874 " movl (%%edx,%%eax,4),%%eax\n"
3875 " stosl\n"
3876 " xor %%eax,%%eax\n"
3877 " loop 1b\n"
3878 : "=S" (c_src), "=D" (c_dst)
3879 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3880 : "eax", "cc", "memory"
3882 c_src+=(pitch-width);
3883 #else
3884 unsigned char * srclineend = c_src+width;
3885 while (c_src < srclineend )
3886 *c_dst++ = pal[*c_src++];
3887 c_src+=(pitch-width);
3888 #endif
3890 } else {
3891 WARN("No palette set...\n");
3892 memset(dst, 0, width * height * 4);
3896 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3897 int i;
3898 unsigned int *pal = (unsigned int *) screen_palette;
3900 for (i = 0; i < count; i++)
3901 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3902 (((unsigned int) palent[i].peGreen) << 8) |
3903 ((unsigned int) palent[i].peBlue));
3906 /* *************************************
3907 32 bpp to 16 bpp
3908 ************************************* */
3909 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3910 unsigned short *c_src = (unsigned short *) src;
3911 unsigned int *c_dst = (unsigned int *) dst;
3912 int y;
3914 for (y = height; y--; ) {
3915 unsigned short * srclineend = c_src+width;
3916 while (c_src < srclineend ) {
3917 *c_dst++ = (((*c_src & 0xF800) << 8) |
3918 ((*c_src & 0x07E0) << 5) |
3919 ((*c_src & 0x001F) << 3));
3920 c_src++;
3922 c_src+=((pitch/2)-width);
3927 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3928 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3930 ICOM_THIS(IDirectDrawImpl,iface);
3931 char buf[200];
3932 WND *tmpWnd;
3933 int c;
3935 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3936 This, width, height, depth);
3938 switch ((c = _common_depth_to_pixelformat(depth,
3939 &(This->d.directdraw_pixelformat),
3940 &(This->d.screen_pixelformat),
3941 &(This->d.pixmap_depth)))) {
3942 case -2:
3943 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3944 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3945 return DDERR_UNSUPPORTEDMODE;
3947 case -1:
3948 /* No convertion */
3949 This->d.pixel_convert = NULL;
3950 This->d.palette_convert = NULL;
3951 break;
3953 default:
3954 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3956 /* Set the depth convertion routines */
3957 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
3958 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
3961 This->d.width = width;
3962 This->d.height = height;
3964 _common_IDirectDrawImpl_SetDisplayMode(This);
3966 tmpWnd = WIN_FindWndPtr(This->d.window);
3967 This->d.paintable = 1;
3968 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3969 WIN_ReleaseWndPtr(tmpWnd);
3971 /* We don't have a context for this window. Host off the desktop */
3972 if( !This->d.drawable )
3974 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3975 WIN_ReleaseDesktop();
3977 TRACE("Setting drawable to %ld\n", This->d.drawable);
3979 return DD_OK;
3982 #ifdef HAVE_LIBXXF86DGA
3983 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3984 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3986 ICOM_THIS(IDirectDraw2Impl,iface);
3987 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3988 if (!caps1 && !caps2)
3989 return DDERR_INVALIDPARAMS;
3990 if (caps1) {
3991 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3992 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3993 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3995 if (caps2) {
3996 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3997 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3998 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4000 return DD_OK;
4002 #endif /* defined(HAVE_LIBXXF86DGA) */
4004 static void fill_caps(LPDDCAPS caps) {
4005 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4006 Need to be fixed, though.. */
4007 if (caps == NULL)
4008 return;
4010 caps->dwSize = sizeof(*caps);
4011 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
4012 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
4013 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
4014 caps->dwFXCaps = 0;
4015 caps->dwFXAlphaCaps = 0;
4016 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
4017 caps->dwSVCaps = 0;
4018 caps->dwZBufferBitDepths = DDBD_16;
4019 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4020 to put textures in video memory.
4021 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4022 for example) ? */
4023 caps->dwVidMemTotal = 8192 * 1024;
4024 caps->dwVidMemFree = 8192 * 1024;
4025 /* These are all the supported capabilities of the surfaces */
4026 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
4027 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
4028 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
4029 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
4030 #ifdef HAVE_MESAGL
4031 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
4032 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
4033 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
4034 #endif
4037 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
4038 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4040 ICOM_THIS(IDirectDraw2Impl,iface);
4041 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4043 /* Put the same caps for the two capabilities */
4044 fill_caps(caps1);
4045 fill_caps(caps2);
4047 return DD_OK;
4050 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
4051 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
4053 ICOM_THIS(IDirectDraw2Impl,iface);
4054 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
4055 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4056 This,x,ilpddclip,lpunk
4058 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
4059 (*ilpddclip)->ref = 1;
4060 ICOM_VTBL(*ilpddclip) = &ddclipvt;
4061 return DD_OK;
4064 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
4065 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
4067 int size = 0;
4069 if (TRACE_ON(ddraw))
4070 _dump_paletteformat(dwFlags);
4072 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
4073 if (*lpddpal == NULL) return E_OUTOFMEMORY;
4074 (*lpddpal)->ref = 1;
4075 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
4076 (*lpddpal)->installed = 0;
4078 if (dwFlags & DDPCAPS_1BIT)
4079 size = 2;
4080 else if (dwFlags & DDPCAPS_2BIT)
4081 size = 4;
4082 else if (dwFlags & DDPCAPS_4BIT)
4083 size = 16;
4084 else if (dwFlags & DDPCAPS_8BIT)
4085 size = 256;
4086 else
4087 ERR("unhandled palette format\n");
4088 *psize = size;
4090 if (palent)
4092 /* Now, if we are in 'depth conversion mode', create the screen palette */
4093 if (This->d.palette_convert != NULL)
4094 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
4096 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
4097 } else if (This->d.palette_convert != NULL) {
4098 /* In that case, put all 0xFF */
4099 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
4102 return DD_OK;
4105 #ifdef HAVE_LIBXXF86DGA
4106 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
4107 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4109 ICOM_THIS(IDirectDraw2Impl,iface);
4110 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4111 HRESULT res;
4112 int xsize = 0,i;
4114 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4115 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4116 if (res != 0) return res;
4117 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
4118 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
4119 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
4120 } else {
4121 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4122 (*ilpddpal)->cm = 0;
4124 if (((*ilpddpal)->cm)&&xsize) {
4125 for (i=0;i<xsize;i++) {
4126 XColor xc;
4128 xc.red = (*ilpddpal)->palents[i].peRed<<8;
4129 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
4130 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
4131 xc.flags = DoRed|DoBlue|DoGreen;
4132 xc.pixel = i;
4133 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
4136 return DD_OK;
4138 #endif /* defined(HAVE_LIBXXF86DGA) */
4140 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
4141 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4143 ICOM_THIS(IDirectDraw2Impl,iface);
4144 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4145 int xsize;
4146 HRESULT res;
4148 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4149 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4150 if (res != 0) return res;
4151 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
4152 return DD_OK;
4155 #ifdef HAVE_LIBXXF86DGA
4156 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4157 ICOM_THIS(IDirectDraw2Impl,iface);
4158 TRACE("(%p)->()\n",This);
4159 Sleep(1000);
4160 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4161 #ifdef RESTORE_SIGNALS
4162 SIGNAL_Init();
4163 #endif
4164 return DD_OK;
4166 #endif /* defined(HAVE_LIBXXF86DGA) */
4168 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4169 ICOM_THIS(IDirectDraw2Impl,iface);
4170 TRACE("(%p)->RestoreDisplayMode()\n", This);
4171 Sleep(1000);
4172 return DD_OK;
4175 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
4176 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
4178 ICOM_THIS(IDirectDraw2Impl,iface);
4179 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
4180 return DD_OK;
4183 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
4184 ICOM_THIS(IDirectDraw2Impl,iface);
4185 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
4187 return ++(This->ref);
4190 #ifdef HAVE_LIBXXF86DGA
4191 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4192 ICOM_THIS(IDirectDraw2Impl,iface);
4193 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4195 if (!--(This->ref)) {
4196 #ifdef HAVE_LIBXXF86DGA2
4197 if (This->e.dga.version == 2) {
4198 TRACE("Closing access to the FrameBuffer\n");
4199 TSXDGACloseFramebuffer(display, DefaultScreen(display));
4201 /* Set the input handling back to absolute */
4202 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
4204 /* Ungrab mouse and keyboard */
4205 TSXUngrabPointer(display, CurrentTime);
4206 TSXUngrabKeyboard(display, CurrentTime);
4207 } else
4208 #endif /* defined(HAVE_LIBXXF86DGA2) */
4209 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4210 if (This->d.window && (This->d.mainWindow != This->d.window))
4211 DestroyWindow(This->d.window);
4212 #ifdef HAVE_LIBXXF86VM
4213 if (orig_mode) {
4214 TSXF86VidModeSwitchToMode(
4215 display,
4216 DefaultScreen(display),
4217 orig_mode);
4218 if (orig_mode->privsize)
4219 TSXFree(orig_mode->private);
4220 free(orig_mode);
4221 orig_mode = NULL;
4223 #endif
4225 #ifdef RESTORE_SIGNALS
4226 SIGNAL_Init();
4227 #endif
4228 HeapFree(GetProcessHeap(),0,This);
4229 return S_OK;
4231 return This->ref;
4233 #endif /* defined(HAVE_LIBXXF86DGA) */
4235 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4236 ICOM_THIS(IDirectDraw2Impl,iface);
4237 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4239 if (!--(This->ref)) {
4240 if (This->d.window && (This->d.mainWindow != This->d.window))
4241 DestroyWindow(This->d.window);
4242 HeapFree(GetProcessHeap(),0,This);
4243 return S_OK;
4245 /* FIXME: destroy window ... */
4246 return This->ref;
4249 #ifdef HAVE_LIBXXF86DGA
4250 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4251 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4253 ICOM_THIS(IDirectDraw2Impl,iface);
4254 char xrefiid[50];
4256 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4257 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4258 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4259 *obj = This;
4260 IDirectDraw2_AddRef(iface);
4262 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4264 return S_OK;
4266 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4267 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4268 IDirectDraw2_AddRef(iface);
4269 *obj = This;
4271 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4273 return S_OK;
4275 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4276 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4277 IDirectDraw2_AddRef(iface);
4278 *obj = This;
4280 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4282 return S_OK;
4284 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4285 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4286 IDirectDraw2_AddRef(iface);
4287 *obj = This;
4289 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4291 return S_OK;
4293 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4294 IDirect3DImpl* d3d;
4296 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4297 d3d->ref = 1;
4298 d3d->ddraw = (IDirectDrawImpl*)This;
4299 IDirectDraw2_AddRef(iface);
4300 ICOM_VTBL(d3d) = &d3dvt;
4301 *obj = d3d;
4303 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4305 return S_OK;
4307 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4308 IDirect3D2Impl* d3d;
4310 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4311 d3d->ref = 1;
4312 d3d->ddraw = (IDirectDrawImpl*)This;
4313 IDirectDraw2_AddRef(iface);
4314 ICOM_VTBL(d3d) = &d3d2vt;
4315 *obj = d3d;
4317 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4319 return S_OK;
4321 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4322 return OLE_E_ENUM_NOMORE;
4324 #endif /* defined(HAVE_LIBXXF86DGA) */
4326 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4327 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4329 ICOM_THIS(IDirectDraw2Impl,iface);
4330 char xrefiid[50];
4332 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4333 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4334 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4335 *obj = This;
4336 IDirectDraw2_AddRef(iface);
4338 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4340 return S_OK;
4342 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4343 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4344 IDirectDraw2_AddRef(iface);
4345 *obj = This;
4347 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4349 return S_OK;
4351 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4352 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4353 IDirectDraw2_AddRef(iface);
4354 *obj = This;
4356 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4358 return S_OK;
4360 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4361 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4362 IDirectDraw2_AddRef(iface);
4363 *obj = This;
4365 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4367 return S_OK;
4369 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4370 IDirect3DImpl* d3d;
4372 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4373 d3d->ref = 1;
4374 d3d->ddraw = (IDirectDrawImpl*)This;
4375 IDirectDraw2_AddRef(iface);
4376 ICOM_VTBL(d3d) = &d3dvt;
4377 *obj = d3d;
4379 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4381 return S_OK;
4383 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4384 IDirect3D2Impl* d3d;
4386 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4387 d3d->ref = 1;
4388 d3d->ddraw = (IDirectDrawImpl*)This;
4389 IDirectDraw2_AddRef(iface);
4390 ICOM_VTBL(d3d) = &d3d2vt;
4391 *obj = d3d;
4393 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4395 return S_OK;
4397 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4398 return OLE_E_ENUM_NOMORE;
4401 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4402 LPDIRECTDRAW2 iface,BOOL *status
4404 ICOM_THIS(IDirectDraw2Impl,iface);
4405 TRACE("(%p)->(%p)\n",This,status);
4406 *status = TRUE;
4407 return DD_OK;
4410 #ifdef HAVE_LIBXXF86DGA
4411 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4412 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4414 ICOM_THIS(IDirectDraw2Impl,iface);
4415 DDSURFACEDESC ddsfd;
4416 static struct {
4417 int w,h;
4418 } modes[5] = { /* some of the usual modes */
4419 {512,384},
4420 {640,400},
4421 {640,480},
4422 {800,600},
4423 {1024,768},
4425 static int depths[4] = {8,16,24,32};
4426 int i,j;
4428 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4429 ddsfd.dwSize = sizeof(ddsfd);
4430 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4431 if (dwFlags & DDEDM_REFRESHRATES) {
4432 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4433 ddsfd.u.dwRefreshRate = 60;
4436 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4437 ddsfd.dwBackBufferCount = 1;
4438 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4439 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4440 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4441 /* FIXME: those masks would have to be set in depth > 8 */
4442 if (depths[i]==8) {
4443 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4444 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4445 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4446 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4447 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4448 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4449 } else {
4450 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4452 /* FIXME: We should query those from X itself */
4453 switch (depths[i]) {
4454 case 16:
4455 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4456 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4457 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4458 break;
4459 case 24:
4460 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4461 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4462 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4463 break;
4464 case 32:
4465 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4466 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4467 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4468 break;
4472 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4473 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4474 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4475 if (!modescb(&ddsfd,context)) return DD_OK;
4477 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4478 ddsfd.dwWidth = modes[j].w;
4479 ddsfd.dwHeight = modes[j].h;
4480 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4481 if (!modescb(&ddsfd,context)) return DD_OK;
4484 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4485 /* modeX is not standard VGA */
4487 ddsfd.dwHeight = 200;
4488 ddsfd.dwWidth = 320;
4489 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4490 if (!modescb(&ddsfd,context)) return DD_OK;
4493 return DD_OK;
4495 #endif /* defined(HAVE_LIBXXF86DGA) */
4497 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4498 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4500 ICOM_THIS(IDirectDraw2Impl,iface);
4501 XVisualInfo *vi;
4502 XPixmapFormatValues *pf;
4503 XVisualInfo vt;
4504 int nvisuals, npixmap, i, emu;
4505 int has_mode[] = { 0, 0, 0, 0 };
4506 int has_depth[] = { 8, 15, 16, 24 };
4507 DDSURFACEDESC ddsfd;
4508 static struct {
4509 int w,h;
4510 } modes[] = { /* some of the usual modes */
4511 {512,384},
4512 {640,400},
4513 {640,480},
4514 {800,600},
4515 {1024,768},
4516 {1280,1024}
4518 DWORD maxWidth, maxHeight;
4520 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4521 ddsfd.dwSize = sizeof(ddsfd);
4522 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
4523 if (dwFlags & DDEDM_REFRESHRATES) {
4524 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4525 ddsfd.u.dwRefreshRate = 60;
4527 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4528 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4530 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4531 pf = XListPixmapFormats(display, &npixmap);
4533 i = 0;
4534 emu = 0;
4535 while ((i < npixmap) ||
4536 (emu != 4)) {
4537 int mode_index = 0;
4538 int send_mode = 0;
4539 int j;
4541 if (i < npixmap) {
4542 for (j = 0; j < 4; j++) {
4543 if (has_depth[j] == pf[i].depth) {
4544 mode_index = j;
4545 break;
4548 if (j == 4) {
4549 i++;
4550 continue;
4554 if (has_mode[mode_index] == 0) {
4555 if (mode_index == 0) {
4556 send_mode = 1;
4558 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4559 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4560 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4561 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4562 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4563 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4564 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4565 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4566 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4568 has_mode[mode_index] = 1;
4569 } else {
4570 /* All the 'true color' depths (15, 16 and 24)
4571 First, find the corresponding visual to extract the bit masks */
4572 for (j = 0; j < nvisuals; j++) {
4573 if (vi[j].depth == pf[i].depth) {
4574 ddsfd.ddsCaps.dwCaps = 0;
4575 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4576 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4577 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4578 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4579 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4580 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4581 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4582 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4584 send_mode = 1;
4585 has_mode[mode_index] = 1;
4586 break;
4590 if (j == nvisuals)
4591 ERR("Did not find visual corresponding the the pixmap format !\n");
4595 i++;
4596 } else {
4597 /* Now to emulated modes */
4598 if (has_mode[emu] == 0) {
4599 int c;
4600 int l;
4601 int depth = has_depth[emu];
4603 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4604 if (ModeEmulations[c].dest.depth == depth) {
4605 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4606 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4607 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4608 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4609 int j;
4610 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4611 if ((vi[j].depth == pf[l].depth) &&
4612 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4613 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4614 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4615 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4616 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4617 if (depth == 8) {
4618 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4619 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4620 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4621 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4622 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4623 } else {
4624 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4625 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4626 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4627 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4628 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4630 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4631 send_mode = 1;
4634 if (send_mode == 0)
4635 ERR("No visual corresponding to pixmap format !\n");
4643 emu++;
4646 if (send_mode) {
4647 int mode;
4649 if (TRACE_ON(ddraw)) {
4650 TRACE("Enumerating with pixel format : \n");
4651 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4652 DPRINTF("\n");
4655 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4656 /* Do not enumerate modes we cannot handle anyway */
4657 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4658 break;
4660 ddsfd.dwWidth = modes[mode].w;
4661 ddsfd.dwHeight = modes[mode].h;
4663 /* Now, send the mode description to the application */
4664 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4665 if (!modescb(&ddsfd, context))
4666 goto exit_enum;
4669 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4670 /* modeX is not standard VGA */
4671 ddsfd.dwWidth = 320;
4672 ddsfd.dwHeight = 200;
4673 if (!modescb(&ddsfd, context))
4674 goto exit_enum;
4679 exit_enum:
4680 TSXFree(vi);
4681 TSXFree(pf);
4683 return DD_OK;
4686 #ifdef HAVE_LIBXXF86DGA
4687 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4688 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4690 ICOM_THIS(IDirectDraw2Impl,iface);
4691 TRACE("(%p)->(%p)\n",This,lpddsfd);
4692 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4693 lpddsfd->dwHeight = This->d.height;
4694 lpddsfd->dwWidth = This->d.width;
4695 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4696 lpddsfd->dwBackBufferCount = 1;
4697 lpddsfd->u.dwRefreshRate = 60;
4698 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4699 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4700 if (TRACE_ON(ddraw)) {
4701 _dump_surface_desc(lpddsfd);
4703 return DD_OK;
4705 #endif /* defined(HAVE_LIBXXF86DGA) */
4707 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4708 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4710 ICOM_THIS(IDirectDraw2Impl,iface);
4711 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4712 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4713 lpddsfd->dwHeight = This->d.height;
4714 lpddsfd->dwWidth = This->d.width;
4715 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4716 lpddsfd->dwBackBufferCount = 1;
4717 lpddsfd->u.dwRefreshRate = 60;
4718 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4719 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4720 if (TRACE_ON(ddraw)) {
4721 _dump_surface_desc(lpddsfd);
4723 return DD_OK;
4726 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4727 ICOM_THIS(IDirectDraw2Impl,iface);
4728 TRACE("(%p)->()\n",This);
4729 return DD_OK;
4732 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4733 LPDIRECTDRAW2 iface,LPDWORD freq
4735 ICOM_THIS(IDirectDraw2Impl,iface);
4736 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4737 *freq = 60*100; /* 60 Hz */
4738 return DD_OK;
4741 /* what can we directly decompress? */
4742 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4743 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4745 ICOM_THIS(IDirectDraw2Impl,iface);
4746 FIXME("(%p,%p,%p), stub\n",This,x,y);
4747 return DD_OK;
4750 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4751 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4753 ICOM_THIS(IDirectDraw2Impl,iface);
4754 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4755 return DD_OK;
4758 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4759 LPDIRECTDRAW2 iface )
4761 ICOM_THIS(IDirectDraw2Impl,iface);
4762 FIXME("(%p)->()\n", This );
4764 return DD_OK;
4767 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4768 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4769 ICOM_THIS(IDirectDraw2Impl,iface);
4770 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4772 return DD_OK;
4775 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4776 LPDWORD lpdwScanLine) {
4777 ICOM_THIS(IDirectDraw2Impl,iface);
4778 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4780 if (lpdwScanLine)
4781 *lpdwScanLine = 0;
4782 return DD_OK;
4785 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4786 GUID *lpGUID) {
4787 ICOM_THIS(IDirectDraw2Impl,iface);
4788 FIXME("(%p)->(%p)\n", This, lpGUID);
4790 return DD_OK;
4793 #ifdef HAVE_LIBXXF86DGA
4795 /* Note: Hack so we can reuse the old functions without compiler warnings */
4796 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4797 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4798 #else
4799 # define XCAST(fun) (void *)
4800 #endif
4802 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4804 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4805 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4806 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4807 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4808 XCAST(Compact)IDirectDraw2Impl_Compact,
4809 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4810 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4811 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4812 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4813 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4814 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4815 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4816 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4817 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4818 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4819 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4820 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4821 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4822 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4823 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4824 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4825 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4826 DGA_IDirectDrawImpl_SetDisplayMode,
4827 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4830 #undef XCAST
4832 #endif /* defined(HAVE_LIBXXF86DGA) */
4834 /* Note: Hack so we can reuse the old functions without compiler warnings */
4835 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4836 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
4837 #else
4838 # define XCAST(fun) (void *)
4839 #endif
4841 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
4843 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4844 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4845 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4846 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4847 XCAST(Compact)IDirectDraw2Impl_Compact,
4848 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4849 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4850 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4851 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4852 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4853 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4854 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4855 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4856 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4857 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4858 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4859 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4860 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4861 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4862 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4863 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4864 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4865 Xlib_IDirectDrawImpl_SetDisplayMode,
4866 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4869 #undef XCAST
4871 /*****************************************************************************
4872 * IDirectDraw2
4876 #ifdef HAVE_LIBXXF86DGA
4877 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4878 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
4880 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
4881 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4883 #endif /* defined(HAVE_LIBXXF86DGA) */
4885 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4886 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
4888 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
4889 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4892 #ifdef HAVE_LIBXXF86DGA
4893 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4894 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4896 ICOM_THIS(IDirectDraw2Impl,iface);
4897 TRACE("(%p)->(%p,%p,%p)\n",
4898 This,ddscaps,total,free
4900 if (total) *total = This->e.dga.fb_memsize * 1024;
4901 if (free) *free = This->e.dga.fb_memsize * 1024;
4902 return DD_OK;
4904 #endif /* defined(HAVE_LIBXXF86DGA) */
4906 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4907 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4909 ICOM_THIS(IDirectDraw2Impl,iface);
4910 TRACE("(%p)->(%p,%p,%p)\n",
4911 This,ddscaps,total,free
4913 if (total) *total = 2048 * 1024;
4914 if (free) *free = 2048 * 1024;
4915 return DD_OK;
4918 #ifdef HAVE_LIBXXF86DGA
4919 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
4921 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4922 DGA_IDirectDraw2Impl_QueryInterface,
4923 IDirectDraw2Impl_AddRef,
4924 DGA_IDirectDraw2Impl_Release,
4925 IDirectDraw2Impl_Compact,
4926 IDirectDraw2Impl_CreateClipper,
4927 DGA_IDirectDraw2Impl_CreatePalette,
4928 DGA_IDirectDraw2Impl_CreateSurface,
4929 IDirectDraw2Impl_DuplicateSurface,
4930 DGA_IDirectDraw2Impl_EnumDisplayModes,
4931 IDirectDraw2Impl_EnumSurfaces,
4932 IDirectDraw2Impl_FlipToGDISurface,
4933 DGA_IDirectDraw2Impl_GetCaps,
4934 DGA_IDirectDraw2Impl_GetDisplayMode,
4935 IDirectDraw2Impl_GetFourCCCodes,
4936 IDirectDraw2Impl_GetGDISurface,
4937 IDirectDraw2Impl_GetMonitorFrequency,
4938 IDirectDraw2Impl_GetScanLine,
4939 IDirectDraw2Impl_GetVerticalBlankStatus,
4940 IDirectDraw2Impl_Initialize,
4941 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4942 IDirectDraw2Impl_SetCooperativeLevel,
4943 DGA_IDirectDraw2Impl_SetDisplayMode,
4944 IDirectDraw2Impl_WaitForVerticalBlank,
4945 DGA_IDirectDraw2Impl_GetAvailableVidMem
4947 #endif /* defined(HAVE_LIBXXF86DGA) */
4949 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
4951 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4952 Xlib_IDirectDraw2Impl_QueryInterface,
4953 IDirectDraw2Impl_AddRef,
4954 Xlib_IDirectDraw2Impl_Release,
4955 IDirectDraw2Impl_Compact,
4956 IDirectDraw2Impl_CreateClipper,
4957 Xlib_IDirectDraw2Impl_CreatePalette,
4958 Xlib_IDirectDraw2Impl_CreateSurface,
4959 IDirectDraw2Impl_DuplicateSurface,
4960 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4961 IDirectDraw2Impl_EnumSurfaces,
4962 IDirectDraw2Impl_FlipToGDISurface,
4963 Xlib_IDirectDraw2Impl_GetCaps,
4964 Xlib_IDirectDraw2Impl_GetDisplayMode,
4965 IDirectDraw2Impl_GetFourCCCodes,
4966 IDirectDraw2Impl_GetGDISurface,
4967 IDirectDraw2Impl_GetMonitorFrequency,
4968 IDirectDraw2Impl_GetScanLine,
4969 IDirectDraw2Impl_GetVerticalBlankStatus,
4970 IDirectDraw2Impl_Initialize,
4971 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4972 IDirectDraw2Impl_SetCooperativeLevel,
4973 Xlib_IDirectDraw2Impl_SetDisplayMode,
4974 IDirectDraw2Impl_WaitForVerticalBlank,
4975 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4978 /*****************************************************************************
4979 * IDirectDraw4
4983 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4984 HDC hdc,
4985 LPDIRECTDRAWSURFACE *lpDDS) {
4986 ICOM_THIS(IDirectDraw4Impl,iface);
4987 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4989 return DD_OK;
4992 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4993 ICOM_THIS(IDirectDraw4Impl,iface);
4994 FIXME("(%p)->()\n", This);
4996 return DD_OK;
4999 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
5000 ICOM_THIS(IDirectDraw4Impl,iface);
5001 FIXME("(%p)->()\n", This);
5003 return DD_OK;
5006 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5007 LPDDDEVICEIDENTIFIER lpdddi,
5008 DWORD dwFlags) {
5009 ICOM_THIS(IDirectDraw4Impl,iface);
5010 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5012 return DD_OK;
5015 #ifdef HAVE_LIBXXF86DGA
5017 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5018 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5019 #else
5020 # define XCAST(fun) (void*)
5021 #endif
5023 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5025 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5026 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5027 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5028 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5029 XCAST(Compact)IDirectDraw2Impl_Compact,
5030 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5031 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5032 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5033 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5034 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5035 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5036 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5037 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5038 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5039 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5040 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5041 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5042 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5043 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5044 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5045 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5046 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5047 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5048 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5049 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5050 IDirectDraw4Impl_GetSurfaceFromDC,
5051 IDirectDraw4Impl_RestoreAllSurfaces,
5052 IDirectDraw4Impl_TestCooperativeLevel,
5053 IDirectDraw4Impl_GetDeviceIdentifier
5056 #undef XCAST
5058 #endif /* defined(HAVE_LIBXXF86DGA) */
5060 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5061 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5062 #else
5063 # define XCAST(fun) (void*)
5064 #endif
5066 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5068 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5069 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5070 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5071 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5072 XCAST(Compact)IDirectDraw2Impl_Compact,
5073 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5074 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5075 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5076 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5077 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5078 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5079 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5080 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5081 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5082 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5083 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5084 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5085 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5086 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5087 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5088 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5089 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5090 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5091 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5092 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5093 IDirectDraw4Impl_GetSurfaceFromDC,
5094 IDirectDraw4Impl_RestoreAllSurfaces,
5095 IDirectDraw4Impl_TestCooperativeLevel,
5096 IDirectDraw4Impl_GetDeviceIdentifier
5099 #undef XCAST
5101 /******************************************************************************
5102 * DirectDrawCreate
5105 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5107 LRESULT ret;
5108 IDirectDrawImpl* ddraw = NULL;
5109 DWORD lastError;
5111 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5113 SetLastError( ERROR_SUCCESS );
5114 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
5115 if( (!ddraw) &&
5116 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
5119 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5122 if( ddraw )
5124 /* Perform any special direct draw functions */
5125 if (msg==WM_PAINT)
5126 ddraw->d.paintable = 1;
5128 /* Now let the application deal with the rest of this */
5129 if( ddraw->d.mainWindow )
5132 /* Don't think that we actually need to call this but...
5133 might as well be on the safe side of things... */
5135 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5136 it should be the procedures of our fake window that gets called
5137 instead of those of the window provided by the application.
5138 And with this patch, mouse clicks work with Monkey Island III
5139 - Lionel */
5140 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5142 if( !ret )
5144 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5145 /* We didn't handle the message - give it to the application */
5146 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5148 ret = CallWindowProcA(tmpWnd->winproc,
5149 ddraw->d.mainWindow, msg, wParam, lParam );
5151 WIN_ReleaseWndPtr(tmpWnd);
5155 } else {
5156 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5160 else
5162 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5165 return ret;
5168 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5169 #ifdef HAVE_LIBXXF86DGA
5170 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5171 int memsize,banksize,major,minor,flags;
5172 char *addr;
5173 int depth;
5174 int dga_version;
5175 int width, height;
5177 /* Get DGA availability / version */
5178 dga_version = DDRAW_DGA_Available();
5180 if (dga_version == 0) {
5181 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5182 return DDERR_GENERIC;
5185 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5186 (*ilplpDD)->ref = 1;
5187 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5188 #ifdef HAVE_LIBXXF86DGA2
5189 if (dga_version == 1) {
5190 (*ilplpDD)->e.dga.version = 1;
5191 #endif /* defined(HAVE_LIBXXF86DGA2) */
5192 TSXF86DGAQueryVersion(display,&major,&minor);
5193 TRACE("XF86DGA is version %d.%d\n",major,minor);
5194 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5195 if (!(flags & XF86DGADirectPresent))
5196 MESSAGE("direct video is NOT PRESENT.\n");
5197 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5198 (*ilplpDD)->e.dga.fb_width = width;
5199 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5200 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5201 (*ilplpDD)->e.dga.fb_height = height;
5202 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5203 addr,width,banksize,memsize
5205 TRACE("viewport height: %d\n",height);
5206 /* Get the screen dimensions as seen by Wine.
5207 In that case, it may be better to ignore the -desktop mode and return the
5208 real screen size => print a warning */
5209 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5210 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5211 if (((*ilplpDD)->d.height != height) ||
5212 ((*ilplpDD)->d.width != width))
5213 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5214 (*ilplpDD)->e.dga.fb_addr = addr;
5215 (*ilplpDD)->e.dga.fb_memsize = memsize;
5216 (*ilplpDD)->e.dga.vpmask = 0;
5218 /* just assume the default depth is the DGA depth too */
5219 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5220 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
5221 #ifdef RESTORE_SIGNALS
5222 SIGNAL_Init();
5223 #endif
5224 #ifdef HAVE_LIBXXF86DGA2
5225 } else {
5226 DDPIXELFORMAT *pf = &((*ilplpDD)->d.directdraw_pixelformat);
5227 XDGAMode *modes;
5228 int i, num_modes;
5229 int mode_to_use = 0;
5231 (*ilplpDD)->e.dga.version = 2;
5234 TSXGrabPointer(display, DefaultRootWindow(display), True,
5235 PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
5236 GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
5238 TSXGrabKeyboard(display, DefaultRootWindow(display), True, GrabModeAsync,
5239 GrabModeAsync, CurrentTime);
5242 TSXDGAQueryVersion(display,&major,&minor);
5243 TRACE("XDGA is version %d.%d\n",major,minor);
5245 TRACE("Opening the frame buffer.\n");
5246 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5247 ERR("Error opening the frame buffer !!!\n");
5249 TSXUngrabPointer(display, CurrentTime);
5250 TSXUngrabKeyboard(display, CurrentTime);
5252 return DDERR_GENERIC;
5255 /* Set the input handling for relative mouse movements */
5256 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5258 /* List all available modes */
5259 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5260 if (TRACE_ON(ddraw)) {
5261 TRACE("Available modes :\n");
5262 for (i = 0; i < num_modes; i++) {
5263 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5264 modes[i].num,
5265 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5266 modes[i].viewportWidth, modes[i].viewportHeight,
5267 modes[i].depth);
5268 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5269 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5270 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5271 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5272 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5273 DPRINTF("\n");
5275 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5276 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5277 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5278 mode_to_use = modes[i].num;
5282 if (mode_to_use == 0) {
5283 ERR("Could not find mode !\n");
5284 mode_to_use = 1;
5285 } else {
5286 DPRINTF("Using mode number %d\n", mode_to_use);
5289 /* Now, get the device / mode description */
5290 (*ilplpDD)->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode_to_use);
5292 (*ilplpDD)->e.dga.fb_width = (*ilplpDD)->e.dga.dev->mode.imageWidth;
5293 TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
5294 (*ilplpDD)->e.dga.fb_height = (*ilplpDD)->e.dga.dev->mode.viewportHeight;
5295 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
5296 (*ilplpDD)->e.dga.dev->data,
5297 (*ilplpDD)->e.dga.dev->mode.imageWidth,
5298 ((*ilplpDD)->e.dga.dev->mode.imageWidth *
5299 (*ilplpDD)->e.dga.dev->mode.imageHeight *
5300 ((*ilplpDD)->e.dga.dev->mode.bitsPerPixel / 8))
5302 TRACE("viewport height: %d\n", (*ilplpDD)->e.dga.dev->mode.viewportHeight);
5303 /* Get the screen dimensions as seen by Wine.
5304 In that case, it may be better to ignore the -desktop mode and return the
5305 real screen size => print a warning */
5306 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5307 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5308 (*ilplpDD)->e.dga.fb_addr = (*ilplpDD)->e.dga.dev->data;
5309 (*ilplpDD)->e.dga.fb_memsize = ((*ilplpDD)->e.dga.dev->mode.imageWidth *
5310 (*ilplpDD)->e.dga.dev->mode.imageHeight *
5311 ((*ilplpDD)->e.dga.dev->mode.bitsPerPixel / 8));
5312 (*ilplpDD)->e.dga.vpmask = 0;
5314 /* Fill the screen pixelformat */
5315 if ((*ilplpDD)->e.dga.dev->mode.depth == 8) {
5316 pf->dwFlags = DDPF_PALETTEINDEXED8;
5317 pf->u1.dwRBitMask = 0;
5318 pf->u2.dwGBitMask = 0;
5319 pf->u3.dwBBitMask = 0;
5320 } else {
5321 pf->dwFlags = DDPF_RGB;
5322 pf->u1.dwRBitMask = (*ilplpDD)->e.dga.dev->mode.redMask;
5323 pf->u2.dwGBitMask = (*ilplpDD)->e.dga.dev->mode.greenMask;
5324 pf->u3.dwBBitMask = (*ilplpDD)->e.dga.dev->mode.blueMask;
5326 pf->dwFourCC = 0;
5327 pf->u.dwRGBBitCount = (*ilplpDD)->e.dga.dev->mode.bitsPerPixel;
5328 pf->u4.dwRGBAlphaBitMask= 0;
5330 (*ilplpDD)->d.screen_pixelformat = *pf;
5332 #endif /* defined(HAVE_LIBXXF86DGA2) */
5333 return DD_OK;
5334 #else /* defined(HAVE_LIBXXF86DGA) */
5335 return DDERR_INVALIDDIRECTDRAWGUID;
5336 #endif /* defined(HAVE_LIBXXF86DGA) */
5339 static BOOL
5340 DDRAW_XSHM_Available(void)
5342 #ifdef HAVE_LIBXXSHM
5343 if (TSXShmQueryExtension(display))
5345 int major, minor;
5346 Bool shpix;
5348 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5349 (Options.noXSHM != 1))
5350 return 1;
5351 else
5352 return 0;
5354 else
5355 return 0;
5356 #else
5357 return 0;
5358 #endif
5361 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5362 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5363 int depth;
5365 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5366 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5367 (*ilplpDD)->ref = 1;
5368 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5370 /* At DirectDraw creation, the depth is the default depth */
5371 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5372 _common_depth_to_pixelformat(depth,
5373 &((*ilplpDD)->d.directdraw_pixelformat),
5374 &((*ilplpDD)->d.screen_pixelformat),
5375 &((*ilplpDD)->d.pixmap_depth));
5376 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5377 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5379 #ifdef HAVE_LIBXXSHM
5380 /* Test if XShm is available. */
5381 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5382 (*ilplpDD)->e.xlib.xshm_compl = 0;
5383 TRACE("Using XShm extension.\n");
5385 #endif
5387 return DD_OK;
5390 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5391 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5392 char xclsid[50];
5393 WNDCLASSA wc;
5394 /* WND* pParentWindow; */
5395 HRESULT ret;
5397 if (HIWORD(lpGUID))
5398 WINE_StringFromCLSID(lpGUID,xclsid);
5399 else {
5400 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
5401 lpGUID = NULL;
5404 TRACE("(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
5406 if ( ( !lpGUID ) ||
5407 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5408 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5409 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5410 /* if they didn't request a particular interface, use the best
5411 * supported one */
5412 if (DDRAW_DGA_Available())
5413 lpGUID = &DGA_DirectDraw_GUID;
5414 else
5415 lpGUID = &XLIB_DirectDraw_GUID;
5418 wc.style = CS_GLOBALCLASS;
5419 wc.lpfnWndProc = Xlib_DDWndProc;
5420 wc.cbClsExtra = 0;
5421 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
5422 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
5424 /* We can be a child of the desktop since we're really important */
5426 This code is not useful since hInstance is forced to 0 afterward
5427 pParentWindow = WIN_GetDesktop();
5428 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5430 wc.hInstance = 0;
5433 wc.hIcon = 0;
5434 wc.hCursor = (HCURSOR)IDC_ARROWA;
5435 wc.hbrBackground= NULL_BRUSH;
5436 wc.lpszMenuName = 0;
5437 wc.lpszClassName= "WINE_DirectDraw";
5438 RegisterClassA(&wc);
5440 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5441 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5443 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5444 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5446 else {
5447 goto err;
5451 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5452 return ret;
5454 err:
5455 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
5456 return DDERR_INVALIDDIRECTDRAWGUID;
5459 /*******************************************************************************
5460 * DirectDraw ClassFactory
5462 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5465 typedef struct
5467 /* IUnknown fields */
5468 ICOM_VFIELD(IClassFactory);
5469 DWORD ref;
5470 } IClassFactoryImpl;
5472 static HRESULT WINAPI
5473 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5474 ICOM_THIS(IClassFactoryImpl,iface);
5475 char buf[80];
5477 if (HIWORD(riid))
5478 WINE_StringFromCLSID(riid,buf);
5479 else
5480 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5481 FIXME("(%p)->(%s,%p),stub!\n",This,buf,ppobj);
5482 return E_NOINTERFACE;
5485 static ULONG WINAPI
5486 DDCF_AddRef(LPCLASSFACTORY iface) {
5487 ICOM_THIS(IClassFactoryImpl,iface);
5488 return ++(This->ref);
5491 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5492 ICOM_THIS(IClassFactoryImpl,iface);
5493 /* static class, won't be freed */
5494 return --(This->ref);
5497 static HRESULT WINAPI DDCF_CreateInstance(
5498 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5500 ICOM_THIS(IClassFactoryImpl,iface);
5501 char buf[80];
5503 WINE_StringFromCLSID(riid,buf);
5504 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
5505 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5506 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5507 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5508 /* FIXME: reuse already created DirectDraw if present? */
5509 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5511 return CLASS_E_CLASSNOTAVAILABLE;
5514 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5515 ICOM_THIS(IClassFactoryImpl,iface);
5516 FIXME("(%p)->(%d),stub!\n",This,dolock);
5517 return S_OK;
5520 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5522 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5523 DDCF_QueryInterface,
5524 DDCF_AddRef,
5525 DDCF_Release,
5526 DDCF_CreateInstance,
5527 DDCF_LockServer
5529 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5531 /*******************************************************************************
5532 * DllGetClassObject [DDRAW.13]
5533 * Retrieves class object from a DLL object
5535 * NOTES
5536 * Docs say returns STDAPI
5538 * PARAMS
5539 * rclsid [I] CLSID for the class object
5540 * riid [I] Reference to identifier of interface for class object
5541 * ppv [O] Address of variable to receive interface pointer for riid
5543 * RETURNS
5544 * Success: S_OK
5545 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5546 * E_UNEXPECTED
5548 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5550 char buf[80],xbuf[80];
5552 if (HIWORD(rclsid))
5553 WINE_StringFromCLSID(rclsid,xbuf);
5554 else
5555 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
5556 if (HIWORD(riid))
5557 WINE_StringFromCLSID(riid,buf);
5558 else
5559 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5560 WINE_StringFromCLSID(riid,xbuf);
5561 TRACE("(%p,%p,%p)\n", xbuf, buf, ppv);
5562 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5563 *ppv = (LPVOID)&DDRAW_CF;
5564 IClassFactory_AddRef((IClassFactory*)*ppv);
5565 return S_OK;
5567 FIXME("(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
5568 return CLASS_E_CLASSNOTAVAILABLE;
5572 /*******************************************************************************
5573 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5575 * RETURNS
5576 * Success: S_OK
5577 * Failure: S_FALSE
5579 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5581 FIXME("(void): stub\n");
5582 return S_FALSE;
5585 #else /* !defined(X_DISPLAY_MISSING) */
5587 #include "windef.h"
5588 #include "wtypes.h"
5590 #define DD_OK 0
5592 typedef void *LPUNKNOWN;
5593 typedef void *LPDIRECTDRAW;
5594 typedef void *LPDIRECTDRAWCLIPPER;
5595 typedef void *LPDDENUMCALLBACKA;
5596 typedef void *LPDDENUMCALLBACKEXA;
5597 typedef void *LPDDENUMCALLBACKEXW;
5598 typedef void *LPDDENUMCALLBACKW;
5600 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5602 return DD_OK;
5605 HRESULT WINAPI DirectDrawCreate(
5606 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5608 return DD_OK;
5611 HRESULT WINAPI DirectDrawCreateClipper(
5612 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5614 return DD_OK;
5617 HRESULT WINAPI DirectDrawEnumerateA(
5618 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5620 return DD_OK;
5623 HRESULT WINAPI DirectDrawEnumerateExA(
5624 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5626 return DD_OK;
5629 HRESULT WINAPI DirectDrawEnumerateExW(
5630 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5632 return DD_OK;
5635 HRESULT WINAPI DirectDrawEnumerateW(
5636 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5638 return DD_OK;
5641 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5643 return CLASS_E_CLASSNOTAVAILABLE;
5646 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5648 return DD_OK;
5651 #endif /* !defined(X_DISPLAY_MISSING) */