Added support for WODM_BREAKLOOP message.
[wine.git] / graphics / ddraw.c
blob799ea039d466042e8900aa3156cfe459424f84f5
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 #ifdef HAVE_LIBXXF86DGA2
3502 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel(
3503 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3505 ICOM_THIS(IDirectDraw2Impl,iface);
3506 HRESULT ret;
3507 int evbase, erbase;
3509 ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel);
3511 if (This->e.dga.version != 2) {
3512 return ret;
3513 } else {
3514 if (ret != DD_OK)
3515 return ret;
3517 TSXDGAQueryExtension(display, &evbase, &erbase);
3519 /* Now, start handling of DGA events giving the handle to the DDraw window
3520 as the window for which the event will be reported */
3521 TSXDGASelectInput(display, DefaultScreen(display),
3522 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3523 X11DRV_EVENT_SetDGAStatus(hwnd, evbase);
3525 return DD_OK;
3528 #endif
3530 /* Small helper to either use the cooperative window or create a new
3531 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3533 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3534 RECT rect;
3536 /* Do not destroy the application supplied cooperative window */
3537 if (This->d.window && This->d.window != This->d.mainWindow) {
3538 DestroyWindow(This->d.window);
3539 This->d.window = 0;
3541 /* Sanity check cooperative window before assigning it to drawing. */
3542 if ( IsWindow(This->d.mainWindow) &&
3543 IsWindowVisible(This->d.mainWindow)
3545 /* if it does not fit, resize the cooperative window.
3546 * and hope the app likes it
3548 GetWindowRect(This->d.mainWindow,&rect);
3549 if ((((rect.right-rect.left) >= This->d.width) &&
3550 ((rect.bottom-rect.top) >= This->d.height))
3552 This->d.window = This->d.mainWindow;
3553 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3557 /* ... failed, create new one. */
3558 if (!This->d.window) {
3559 This->d.window = CreateWindowExA(
3561 "WINE_DirectDraw",
3562 "WINE_DirectDraw",
3563 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3564 0,0,
3565 This->d.width,
3566 This->d.height,
3570 NULL
3572 /*Store THIS with the window. We'll use it in the window procedure*/
3573 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3574 ShowWindow(This->d.window,TRUE);
3575 UpdateWindow(This->d.window);
3577 SetFocus(This->d.window);
3580 static int _common_depth_to_pixelformat(DWORD depth,
3581 DDPIXELFORMAT *pixelformat,
3582 DDPIXELFORMAT *screen_pixelformat,
3583 int *pix_depth) {
3584 XVisualInfo *vi;
3585 XPixmapFormatValues *pf;
3586 XVisualInfo vt;
3587 int nvisuals, npixmap, i;
3588 int match = 0;
3589 int index = -2;
3591 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3592 pf = XListPixmapFormats(display, &npixmap);
3594 for (i = 0; i < npixmap; i++) {
3595 if (pf[i].depth == depth) {
3596 int j;
3598 for (j = 0; j < nvisuals; j++) {
3599 if (vi[j].depth == pf[i].depth) {
3600 pixelformat->dwSize = sizeof(*pixelformat);
3601 if (depth == 8) {
3602 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3603 pixelformat->u1.dwRBitMask = 0;
3604 pixelformat->u2.dwGBitMask = 0;
3605 pixelformat->u3.dwBBitMask = 0;
3606 } else {
3607 pixelformat->dwFlags = DDPF_RGB;
3608 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3609 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3610 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3612 pixelformat->dwFourCC = 0;
3613 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3614 pixelformat->u4.dwRGBAlphaBitMask= 0;
3616 *screen_pixelformat = *pixelformat;
3618 if (pix_depth != NULL)
3619 *pix_depth = vi[j].depth;
3621 match = 1;
3622 index = -1;
3624 goto clean_up_and_exit;
3628 ERR("No visual corresponding to pixmap format !\n");
3632 if (match == 0) {
3633 /* We try now to find an emulated mode */
3634 int c;
3636 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3637 if (ModeEmulations[c].dest.depth == depth) {
3638 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3639 for (i = 0; i < npixmap; i++) {
3640 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3641 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3642 int j;
3644 for (j = 0; j < nvisuals; j++) {
3645 if (vi[j].depth == pf[i].depth) {
3646 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3647 screen_pixelformat->dwFlags = DDPF_RGB;
3648 screen_pixelformat->dwFourCC = 0;
3649 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3650 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3651 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3652 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3653 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3655 pixelformat->dwSize = sizeof(*pixelformat);
3656 pixelformat->dwFourCC = 0;
3657 if (depth == 8) {
3658 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3659 pixelformat->u.dwRGBBitCount = 8;
3660 pixelformat->u1.dwRBitMask = 0;
3661 pixelformat->u2.dwGBitMask = 0;
3662 pixelformat->u3.dwBBitMask = 0;
3663 } else {
3664 pixelformat->dwFlags = DDPF_RGB;
3665 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3666 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3667 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3668 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3670 pixelformat->u4.dwRGBAlphaBitMask= 0;
3672 if (pix_depth != NULL)
3673 *pix_depth = vi[j].depth;
3675 match = 2;
3676 index = c;
3678 goto clean_up_and_exit;
3681 ERR("No visual corresponding to pixmap format !\n");
3689 clean_up_and_exit:
3690 TSXFree(vi);
3691 TSXFree(pf);
3693 return index;
3696 #ifdef HAVE_LIBXXF86DGA2
3697 static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl *This, int mode) {
3698 DDPIXELFORMAT *pf = &(This->d.directdraw_pixelformat);
3700 /* Now, get the device / mode description */
3701 This->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode);
3703 This->e.dga.fb_width = This->e.dga.dev->mode.imageWidth;
3704 TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
3705 This->e.dga.fb_height = This->e.dga.dev->mode.viewportHeight;
3706 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
3707 This->e.dga.dev->data,
3708 This->e.dga.dev->mode.imageWidth,
3709 (This->e.dga.dev->mode.imageWidth *
3710 This->e.dga.dev->mode.imageHeight *
3711 (This->e.dga.dev->mode.bitsPerPixel / 8))
3713 TRACE("viewport height: %d\n", This->e.dga.dev->mode.viewportHeight);
3714 /* Get the screen dimensions as seen by Wine.
3715 In that case, it may be better to ignore the -desktop mode and return the
3716 real screen size => print a warning */
3717 This->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3718 This->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3719 This->e.dga.fb_addr = This->e.dga.dev->data;
3720 This->e.dga.fb_memsize = (This->e.dga.dev->mode.imageWidth *
3721 This->e.dga.dev->mode.imageHeight *
3722 (This->e.dga.dev->mode.bitsPerPixel / 8));
3723 This->e.dga.vpmask = 0;
3725 /* Fill the screen pixelformat */
3726 pf->dwSize = sizeof(DDPIXELFORMAT);
3727 pf->dwFourCC = 0;
3728 pf->u.dwRGBBitCount = This->e.dga.dev->mode.bitsPerPixel;
3729 if (This->e.dga.dev->mode.depth == 8) {
3730 pf->dwFlags = DDPF_PALETTEINDEXED8;
3731 pf->u1.dwRBitMask = 0;
3732 pf->u2.dwGBitMask = 0;
3733 pf->u3.dwBBitMask = 0;
3734 } else {
3735 pf->dwFlags = DDPF_RGB;
3736 pf->u1.dwRBitMask = This->e.dga.dev->mode.redMask;
3737 pf->u2.dwGBitMask = This->e.dga.dev->mode.greenMask;
3738 pf->u3.dwBBitMask = This->e.dga.dev->mode.blueMask;
3740 pf->u4.dwRGBAlphaBitMask= 0;
3742 This->d.screen_pixelformat = *pf;
3744 #endif /* defined(HAVE_LIBXXF86DGA2) */
3746 #ifdef HAVE_LIBXXF86DGA
3747 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3748 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3750 ICOM_THIS(IDirectDrawImpl,iface);
3751 int i,mode_count;
3753 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3755 #ifdef HAVE_LIBXXF86DGA2
3756 if (This->e.dga.version == 2) {
3757 XDGAMode *modes = This->e.dga.modes;
3758 int mode_to_use = -1;
3760 /* Search in the list a display mode that corresponds to what is requested */
3761 for (i = 0; i < This->e.dga.num_modes; i++) {
3762 if ((height == modes[i].viewportHeight) &&
3763 (width == modes[i].viewportWidth) &&
3764 (depth == modes[i].depth)) {
3765 mode_to_use = modes[i].num;
3769 if (mode_to_use < 0) {
3770 ERR("Could not find matching mode !!!\n");
3771 return DDERR_UNSUPPORTEDMODE;
3772 } else {
3773 TRACE("Using mode number %d\n", mode_to_use);
3775 TSXDGACloseFramebuffer(display, DefaultScreen(display));
3777 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
3778 ERR("Error opening the frame buffer !!!\n");
3780 return DDERR_GENERIC;
3783 /* Initialize the frame buffer */
3784 _DGA_Initialize_FrameBuffer(This, mode_to_use);
3786 /* Re-get (if necessary) the DGA events */
3787 TSXDGASelectInput(display, DefaultScreen(display),
3788 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3791 return DD_OK;
3793 #endif /* defined(HAVE_LIBXXF86DGA2) */
3795 /* We hope getting the asked for depth */
3796 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3797 /* I.e. no visual found or emulated */
3798 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3799 return DDERR_UNSUPPORTEDMODE;
3802 if (This->d.width < width) {
3803 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3804 return DDERR_UNSUPPORTEDMODE;
3806 This->d.width = width;
3807 This->d.height = height;
3809 /* adjust fb_height, so we don't overlap */
3810 if (This->e.dga.fb_height < height)
3811 This->e.dga.fb_height = height;
3812 _common_IDirectDrawImpl_SetDisplayMode(This);
3814 #ifdef HAVE_LIBXXF86VM
3815 #ifdef HAVE_LIBXXF86DGA2
3816 if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3817 #endif /* defined(HAVE_LIBXXF86DGA2) */
3819 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3820 XF86VidModeModeLine mod_tmp;
3821 /* int dotclock_tmp; */
3823 /* save original video mode and set fullscreen if available*/
3824 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3825 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3826 orig_mode->hdisplay = mod_tmp.hdisplay;
3827 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3828 orig_mode->hsyncend = mod_tmp.hsyncend;
3829 orig_mode->htotal = mod_tmp.htotal;
3830 orig_mode->vdisplay = mod_tmp.vdisplay;
3831 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3832 orig_mode->vsyncend = mod_tmp.vsyncend;
3833 orig_mode->vtotal = mod_tmp.vtotal;
3834 orig_mode->flags = mod_tmp.flags;
3835 orig_mode->private = mod_tmp.private;
3837 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3838 for (i=0;i<mode_count;i++)
3840 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3842 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3843 *vidmode = *(all_modes[i]);
3844 break;
3845 } else
3846 TSXFree(all_modes[i]->private);
3848 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3849 TSXFree(all_modes);
3851 if (!vidmode)
3852 WARN("Fullscreen mode not available!\n");
3854 if (vidmode)
3856 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3857 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3858 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3859 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3860 #endif
3863 #endif
3865 /* FIXME: this function OVERWRITES several signal handlers.
3866 * can we save them? and restore them later? In a way that
3867 * it works for the library too?
3869 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3870 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3872 #ifdef RESTORE_SIGNALS
3873 SIGNAL_Init();
3874 #endif
3875 return DD_OK;
3877 #endif /* defined(HAVE_LIBXXF86DGA) */
3879 /* *************************************
3880 16 / 15 bpp to palettized 8 bpp
3881 ************************************* */
3882 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3883 unsigned char *c_src = (unsigned char *) src;
3884 unsigned short *c_dst = (unsigned short *) dst;
3885 int y;
3887 if (palette != NULL) {
3888 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3890 for (y = height; y--; ) {
3891 #if defined(__i386__) && defined(__GNUC__)
3892 /* gcc generates slightly inefficient code for the the copy / lookup,
3893 * it generates one excess memory access (to pal) per pixel. Since
3894 * we know that pal is not modified by the memory write we can
3895 * put it into a register and reduce the number of memory accesses
3896 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3897 * (This is not guaranteed to be the fastest method.)
3899 __asm__ __volatile__(
3900 "xor %%eax,%%eax\n"
3901 "1:\n"
3902 " lodsb\n"
3903 " movw (%%edx,%%eax,2),%%ax\n"
3904 " stosw\n"
3905 " xor %%eax,%%eax\n"
3906 " loop 1b\n"
3907 : "=S" (c_src), "=D" (c_dst)
3908 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3909 : "eax", "cc", "memory"
3911 c_src+=(pitch-width);
3912 #else
3913 unsigned char * srclineend = c_src+width;
3914 while (c_src < srclineend)
3915 *c_dst++ = pal[*c_src++];
3916 c_src+=(pitch-width);
3917 #endif
3919 } else {
3920 WARN("No palette set...\n");
3921 memset(dst, 0, width * height * 2);
3924 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3925 int i;
3926 unsigned short *pal = (unsigned short *) screen_palette;
3928 for (i = 0; i < count; i++)
3929 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3930 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3931 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3933 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3934 int i;
3935 unsigned short *pal = (unsigned short *) screen_palette;
3937 for (i = 0; i < count; i++)
3938 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3939 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3940 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3943 /* *************************************
3944 24 to palettized 8 bpp
3945 ************************************* */
3946 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3947 unsigned char *c_src = (unsigned char *) src;
3948 unsigned char *c_dst = (unsigned char *) dst;
3949 int y;
3951 if (palette != NULL) {
3952 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3954 for (y = height; y--; ) {
3955 unsigned char * srclineend = c_src+width;
3956 while (c_src < srclineend ) {
3957 register long pixel = pal[*c_src++];
3958 *c_dst++ = pixel;
3959 *c_dst++ = pixel>>8;
3960 *c_dst++ = pixel>>16;
3962 c_src+=(pitch-width);
3964 } else {
3965 WARN("No palette set...\n");
3966 memset(dst, 0, width * height * 4);
3969 /* *************************************
3970 32 bpp to palettized 8 bpp
3971 ************************************* */
3972 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3973 unsigned char *c_src = (unsigned char *) src;
3974 unsigned int *c_dst = (unsigned int *) dst;
3975 int y;
3977 if (palette != NULL) {
3978 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3980 for (y = height; y--; ) {
3981 #if defined(__i386__) && defined(__GNUC__)
3982 /* See comment in pixel_convert_16_to_8 */
3983 __asm__ __volatile__(
3984 "xor %%eax,%%eax\n"
3985 "1:\n"
3986 " lodsb\n"
3987 " movl (%%edx,%%eax,4),%%eax\n"
3988 " stosl\n"
3989 " xor %%eax,%%eax\n"
3990 " loop 1b\n"
3991 : "=S" (c_src), "=D" (c_dst)
3992 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3993 : "eax", "cc", "memory"
3995 c_src+=(pitch-width);
3996 #else
3997 unsigned char * srclineend = c_src+width;
3998 while (c_src < srclineend )
3999 *c_dst++ = pal[*c_src++];
4000 c_src+=(pitch-width);
4001 #endif
4003 } else {
4004 WARN("No palette set...\n");
4005 memset(dst, 0, width * height * 4);
4009 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
4010 int i;
4011 unsigned int *pal = (unsigned int *) screen_palette;
4013 for (i = 0; i < count; i++)
4014 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
4015 (((unsigned int) palent[i].peGreen) << 8) |
4016 ((unsigned int) palent[i].peBlue));
4019 /* *************************************
4020 32 bpp to 16 bpp
4021 ************************************* */
4022 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4023 unsigned short *c_src = (unsigned short *) src;
4024 unsigned int *c_dst = (unsigned int *) dst;
4025 int y;
4027 for (y = height; y--; ) {
4028 unsigned short * srclineend = c_src+width;
4029 while (c_src < srclineend ) {
4030 *c_dst++ = (((*c_src & 0xF800) << 8) |
4031 ((*c_src & 0x07E0) << 5) |
4032 ((*c_src & 0x001F) << 3));
4033 c_src++;
4035 c_src+=((pitch/2)-width);
4040 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
4041 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
4043 ICOM_THIS(IDirectDrawImpl,iface);
4044 char buf[200];
4045 WND *tmpWnd;
4046 int c;
4048 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
4049 This, width, height, depth);
4051 switch ((c = _common_depth_to_pixelformat(depth,
4052 &(This->d.directdraw_pixelformat),
4053 &(This->d.screen_pixelformat),
4054 &(This->d.pixmap_depth)))) {
4055 case -2:
4056 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
4057 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
4058 return DDERR_UNSUPPORTEDMODE;
4060 case -1:
4061 /* No convertion */
4062 This->d.pixel_convert = NULL;
4063 This->d.palette_convert = NULL;
4064 break;
4066 default:
4067 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
4069 /* Set the depth convertion routines */
4070 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
4071 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
4074 This->d.width = width;
4075 This->d.height = height;
4077 _common_IDirectDrawImpl_SetDisplayMode(This);
4079 tmpWnd = WIN_FindWndPtr(This->d.window);
4080 This->d.paintable = 1;
4081 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
4082 WIN_ReleaseWndPtr(tmpWnd);
4084 /* We don't have a context for this window. Host off the desktop */
4085 if( !This->d.drawable )
4087 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
4088 WIN_ReleaseDesktop();
4090 TRACE("Setting drawable to %ld\n", This->d.drawable);
4092 return DD_OK;
4095 #ifdef HAVE_LIBXXF86DGA
4096 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
4097 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4099 ICOM_THIS(IDirectDraw2Impl,iface);
4100 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4101 if (!caps1 && !caps2)
4102 return DDERR_INVALIDPARAMS;
4103 if (caps1) {
4104 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
4105 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4106 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4108 if (caps2) {
4109 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
4110 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4111 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4113 return DD_OK;
4115 #endif /* defined(HAVE_LIBXXF86DGA) */
4117 static void fill_caps(LPDDCAPS caps) {
4118 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4119 Need to be fixed, though.. */
4120 if (caps == NULL)
4121 return;
4123 caps->dwSize = sizeof(*caps);
4124 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
4125 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
4126 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
4127 caps->dwFXCaps = 0;
4128 caps->dwFXAlphaCaps = 0;
4129 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
4130 caps->dwSVCaps = 0;
4131 caps->dwZBufferBitDepths = DDBD_16;
4132 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4133 to put textures in video memory.
4134 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4135 for example) ? */
4136 caps->dwVidMemTotal = 8192 * 1024;
4137 caps->dwVidMemFree = 8192 * 1024;
4138 /* These are all the supported capabilities of the surfaces */
4139 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
4140 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
4141 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
4142 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
4143 #ifdef HAVE_MESAGL
4144 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
4145 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
4146 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
4147 #endif
4150 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
4151 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4153 ICOM_THIS(IDirectDraw2Impl,iface);
4154 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4156 /* Put the same caps for the two capabilities */
4157 fill_caps(caps1);
4158 fill_caps(caps2);
4160 return DD_OK;
4163 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
4164 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
4166 ICOM_THIS(IDirectDraw2Impl,iface);
4167 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
4168 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4169 This,x,ilpddclip,lpunk
4171 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
4172 (*ilpddclip)->ref = 1;
4173 ICOM_VTBL(*ilpddclip) = &ddclipvt;
4174 return DD_OK;
4177 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
4178 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
4180 int size = 0;
4182 if (TRACE_ON(ddraw))
4183 _dump_paletteformat(dwFlags);
4185 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
4186 if (*lpddpal == NULL) return E_OUTOFMEMORY;
4187 (*lpddpal)->ref = 1;
4188 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
4189 (*lpddpal)->installed = 0;
4191 if (dwFlags & DDPCAPS_1BIT)
4192 size = 2;
4193 else if (dwFlags & DDPCAPS_2BIT)
4194 size = 4;
4195 else if (dwFlags & DDPCAPS_4BIT)
4196 size = 16;
4197 else if (dwFlags & DDPCAPS_8BIT)
4198 size = 256;
4199 else
4200 ERR("unhandled palette format\n");
4201 *psize = size;
4203 if (palent)
4205 /* Now, if we are in 'depth conversion mode', create the screen palette */
4206 if (This->d.palette_convert != NULL)
4207 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
4209 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
4210 } else if (This->d.palette_convert != NULL) {
4211 /* In that case, put all 0xFF */
4212 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
4215 return DD_OK;
4218 #ifdef HAVE_LIBXXF86DGA
4219 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
4220 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4222 ICOM_THIS(IDirectDraw2Impl,iface);
4223 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4224 HRESULT res;
4225 int xsize = 0,i;
4227 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4228 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4229 if (res != 0) return res;
4230 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
4231 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
4232 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
4233 } else {
4234 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4235 (*ilpddpal)->cm = 0;
4237 if (((*ilpddpal)->cm)&&xsize) {
4238 for (i=0;i<xsize;i++) {
4239 XColor xc;
4241 xc.red = (*ilpddpal)->palents[i].peRed<<8;
4242 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
4243 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
4244 xc.flags = DoRed|DoBlue|DoGreen;
4245 xc.pixel = i;
4246 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
4249 return DD_OK;
4251 #endif /* defined(HAVE_LIBXXF86DGA) */
4253 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
4254 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4256 ICOM_THIS(IDirectDraw2Impl,iface);
4257 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4258 int xsize;
4259 HRESULT res;
4261 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4262 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4263 if (res != 0) return res;
4264 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
4265 return DD_OK;
4268 #ifdef HAVE_LIBXXF86DGA
4269 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4270 ICOM_THIS(IDirectDraw2Impl,iface);
4271 TRACE("(%p)->()\n",This);
4272 Sleep(1000);
4273 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4274 #ifdef RESTORE_SIGNALS
4275 SIGNAL_Init();
4276 #endif
4277 return DD_OK;
4279 #endif /* defined(HAVE_LIBXXF86DGA) */
4281 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4282 ICOM_THIS(IDirectDraw2Impl,iface);
4283 TRACE("(%p)->RestoreDisplayMode()\n", This);
4284 Sleep(1000);
4285 return DD_OK;
4288 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
4289 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
4291 ICOM_THIS(IDirectDraw2Impl,iface);
4292 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
4293 return DD_OK;
4296 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
4297 ICOM_THIS(IDirectDraw2Impl,iface);
4298 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
4300 return ++(This->ref);
4303 #ifdef HAVE_LIBXXF86DGA
4304 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4305 ICOM_THIS(IDirectDraw2Impl,iface);
4306 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4308 if (!--(This->ref)) {
4309 #ifdef HAVE_LIBXXF86DGA2
4310 if (This->e.dga.version == 2) {
4311 TRACE("Closing access to the FrameBuffer\n");
4312 TSXDGACloseFramebuffer(display, DefaultScreen(display));
4313 TRACE("Going back to normal X mode of operation\n");
4314 TSXDGASetMode(display, DefaultScreen(display), 0);
4316 /* Set the input handling back to absolute */
4317 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
4319 /* Remove the handling of DGA2 events */
4320 X11DRV_EVENT_SetDGAStatus(0, -1);
4322 /* Free the modes list */
4323 TSXFree(This->e.dga.modes);
4324 } else
4325 #endif /* defined(HAVE_LIBXXF86DGA2) */
4326 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4327 if (This->d.window && (This->d.mainWindow != This->d.window))
4328 DestroyWindow(This->d.window);
4329 #ifdef HAVE_LIBXXF86VM
4330 if (orig_mode) {
4331 TSXF86VidModeSwitchToMode(
4332 display,
4333 DefaultScreen(display),
4334 orig_mode);
4335 if (orig_mode->privsize)
4336 TSXFree(orig_mode->private);
4337 free(orig_mode);
4338 orig_mode = NULL;
4340 #endif
4342 #ifdef RESTORE_SIGNALS
4343 SIGNAL_Init();
4344 #endif
4345 HeapFree(GetProcessHeap(),0,This);
4346 return S_OK;
4348 return This->ref;
4350 #endif /* defined(HAVE_LIBXXF86DGA) */
4352 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4353 ICOM_THIS(IDirectDraw2Impl,iface);
4354 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4356 if (!--(This->ref)) {
4357 if (This->d.window && (This->d.mainWindow != This->d.window))
4358 DestroyWindow(This->d.window);
4359 HeapFree(GetProcessHeap(),0,This);
4360 return S_OK;
4362 /* FIXME: destroy window ... */
4363 return This->ref;
4366 #ifdef HAVE_LIBXXF86DGA
4367 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4368 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4370 ICOM_THIS(IDirectDraw2Impl,iface);
4371 char xrefiid[50];
4373 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4374 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4375 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4376 *obj = This;
4377 IDirectDraw2_AddRef(iface);
4379 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4381 return S_OK;
4383 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4384 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4385 IDirectDraw2_AddRef(iface);
4386 *obj = This;
4388 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4390 return S_OK;
4392 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4393 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4394 IDirectDraw2_AddRef(iface);
4395 *obj = This;
4397 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4399 return S_OK;
4401 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4402 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4403 IDirectDraw2_AddRef(iface);
4404 *obj = This;
4406 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4408 return S_OK;
4410 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4411 IDirect3DImpl* d3d;
4413 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4414 d3d->ref = 1;
4415 d3d->ddraw = (IDirectDrawImpl*)This;
4416 IDirectDraw2_AddRef(iface);
4417 ICOM_VTBL(d3d) = &d3dvt;
4418 *obj = d3d;
4420 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4422 return S_OK;
4424 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4425 IDirect3D2Impl* d3d;
4427 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4428 d3d->ref = 1;
4429 d3d->ddraw = (IDirectDrawImpl*)This;
4430 IDirectDraw2_AddRef(iface);
4431 ICOM_VTBL(d3d) = &d3d2vt;
4432 *obj = d3d;
4434 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4436 return S_OK;
4438 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4439 return OLE_E_ENUM_NOMORE;
4441 #endif /* defined(HAVE_LIBXXF86DGA) */
4443 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4444 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4446 ICOM_THIS(IDirectDraw2Impl,iface);
4447 char xrefiid[50];
4449 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4450 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4451 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4452 *obj = This;
4453 IDirectDraw2_AddRef(iface);
4455 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4457 return S_OK;
4459 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4460 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4461 IDirectDraw2_AddRef(iface);
4462 *obj = This;
4464 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4466 return S_OK;
4468 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4469 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4470 IDirectDraw2_AddRef(iface);
4471 *obj = This;
4473 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4475 return S_OK;
4477 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4478 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4479 IDirectDraw2_AddRef(iface);
4480 *obj = This;
4482 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4484 return S_OK;
4486 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4487 IDirect3DImpl* d3d;
4489 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4490 d3d->ref = 1;
4491 d3d->ddraw = (IDirectDrawImpl*)This;
4492 IDirectDraw2_AddRef(iface);
4493 ICOM_VTBL(d3d) = &d3dvt;
4494 *obj = d3d;
4496 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4498 return S_OK;
4500 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4501 IDirect3D2Impl* d3d;
4503 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4504 d3d->ref = 1;
4505 d3d->ddraw = (IDirectDrawImpl*)This;
4506 IDirectDraw2_AddRef(iface);
4507 ICOM_VTBL(d3d) = &d3d2vt;
4508 *obj = d3d;
4510 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4512 return S_OK;
4514 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4515 return OLE_E_ENUM_NOMORE;
4518 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4519 LPDIRECTDRAW2 iface,BOOL *status
4521 ICOM_THIS(IDirectDraw2Impl,iface);
4522 TRACE("(%p)->(%p)\n",This,status);
4523 *status = TRUE;
4524 return DD_OK;
4527 #ifdef HAVE_LIBXXF86DGA
4528 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4529 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4531 ICOM_THIS(IDirectDraw2Impl,iface);
4532 DDSURFACEDESC ddsfd;
4533 static struct {
4534 int w,h;
4535 } modes[5] = { /* some of the usual modes */
4536 {512,384},
4537 {640,400},
4538 {640,480},
4539 {800,600},
4540 {1024,768},
4542 static int depths[4] = {8,16,24,32};
4543 int i,j;
4545 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4546 ddsfd.dwSize = sizeof(ddsfd);
4547 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4548 if (dwFlags & DDEDM_REFRESHRATES) {
4549 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4550 ddsfd.u.dwRefreshRate = 60;
4552 ddsfd.ddsCaps.dwCaps = 0;
4553 ddsfd.dwBackBufferCount = 1;
4555 #ifdef HAVE_LIBXXF86DGA2
4556 if (This->e.dga.version == 2) {
4557 XDGAMode *modes = This->e.dga.modes;
4559 ddsfd.dwFlags |= DDSD_PITCH;
4560 for (i = 0; i < This->e.dga.num_modes; i++) {
4561 if (TRACE_ON(ddraw)) {
4562 DPRINTF(" Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
4563 modes[i].num,
4564 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
4565 modes[i].viewportWidth, modes[i].viewportHeight,
4566 modes[i].depth);
4567 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
4568 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
4569 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
4570 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
4571 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
4572 DPRINTF("\n");
4574 /* Fill the pixel format */
4575 ddsfd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
4576 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4577 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4578 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = modes[i].bitsPerPixel;
4579 if (modes[i].depth == 8) {
4580 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4581 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4582 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4583 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4584 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4585 } else {
4586 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4587 ddsfd.ddpfPixelFormat.u1.dwRBitMask = modes[i].redMask;
4588 ddsfd.ddpfPixelFormat.u2.dwGBitMask = modes[i].greenMask;
4589 ddsfd.ddpfPixelFormat.u3.dwBBitMask = modes[i].blueMask;
4592 ddsfd.dwWidth = modes[i].viewportWidth;
4593 ddsfd.dwHeight = modes[i].viewportHeight;
4594 ddsfd.lPitch = modes[i].imageWidth;
4596 /* Send mode to the application */
4597 if (!modescb(&ddsfd,context)) return DD_OK;
4599 } else {
4600 #endif
4601 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4602 ddsfd.dwBackBufferCount = 1;
4603 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4604 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4605 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4606 /* FIXME: those masks would have to be set in depth > 8 */
4607 if (depths[i]==8) {
4608 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4609 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4610 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4611 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4612 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4613 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4614 } else {
4615 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4617 /* FIXME: We should query those from X itself */
4618 switch (depths[i]) {
4619 case 16:
4620 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4621 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4622 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4623 break;
4624 case 24:
4625 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4626 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4627 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4628 break;
4629 case 32:
4630 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4631 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4632 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4633 break;
4637 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4638 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4639 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4640 if (!modescb(&ddsfd,context)) return DD_OK;
4642 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4643 ddsfd.dwWidth = modes[j].w;
4644 ddsfd.dwHeight = modes[j].h;
4645 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4646 if (!modescb(&ddsfd,context)) return DD_OK;
4649 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4650 /* modeX is not standard VGA */
4652 ddsfd.dwHeight = 200;
4653 ddsfd.dwWidth = 320;
4654 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4655 if (!modescb(&ddsfd,context)) return DD_OK;
4658 #ifdef HAVE_LIBXXF86DGA2
4660 #endif
4661 return DD_OK;
4663 #endif /* defined(HAVE_LIBXXF86DGA) */
4665 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4666 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4668 ICOM_THIS(IDirectDraw2Impl,iface);
4669 XVisualInfo *vi;
4670 XPixmapFormatValues *pf;
4671 XVisualInfo vt;
4672 int nvisuals, npixmap, i, emu;
4673 int has_mode[] = { 0, 0, 0, 0 };
4674 int has_depth[] = { 8, 15, 16, 24 };
4675 DDSURFACEDESC ddsfd;
4676 static struct {
4677 int w,h;
4678 } modes[] = { /* some of the usual modes */
4679 {512,384},
4680 {640,400},
4681 {640,480},
4682 {800,600},
4683 {1024,768},
4684 {1280,1024}
4686 DWORD maxWidth, maxHeight;
4688 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4689 ddsfd.dwSize = sizeof(ddsfd);
4690 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
4691 if (dwFlags & DDEDM_REFRESHRATES) {
4692 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4693 ddsfd.u.dwRefreshRate = 60;
4695 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4696 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4698 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4699 pf = XListPixmapFormats(display, &npixmap);
4701 i = 0;
4702 emu = 0;
4703 while ((i < npixmap) ||
4704 (emu != 4)) {
4705 int mode_index = 0;
4706 int send_mode = 0;
4707 int j;
4709 if (i < npixmap) {
4710 for (j = 0; j < 4; j++) {
4711 if (has_depth[j] == pf[i].depth) {
4712 mode_index = j;
4713 break;
4716 if (j == 4) {
4717 i++;
4718 continue;
4722 if (has_mode[mode_index] == 0) {
4723 if (mode_index == 0) {
4724 send_mode = 1;
4726 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4727 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4728 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4729 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4730 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4731 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4732 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4733 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4734 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4736 has_mode[mode_index] = 1;
4737 } else {
4738 /* All the 'true color' depths (15, 16 and 24)
4739 First, find the corresponding visual to extract the bit masks */
4740 for (j = 0; j < nvisuals; j++) {
4741 if (vi[j].depth == pf[i].depth) {
4742 ddsfd.ddsCaps.dwCaps = 0;
4743 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4744 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4745 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4746 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4747 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4748 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4749 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4750 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4752 send_mode = 1;
4753 has_mode[mode_index] = 1;
4754 break;
4758 if (j == nvisuals)
4759 ERR("Did not find visual corresponding the the pixmap format !\n");
4763 i++;
4764 } else {
4765 /* Now to emulated modes */
4766 if (has_mode[emu] == 0) {
4767 int c;
4768 int l;
4769 int depth = has_depth[emu];
4771 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4772 if (ModeEmulations[c].dest.depth == depth) {
4773 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4774 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4775 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4776 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4777 int j;
4778 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4779 if ((vi[j].depth == pf[l].depth) &&
4780 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4781 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4782 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4783 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4784 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4785 if (depth == 8) {
4786 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4787 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4788 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4789 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4790 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4791 } else {
4792 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4793 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4794 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4795 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4796 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4798 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4799 send_mode = 1;
4802 if (send_mode == 0)
4803 ERR("No visual corresponding to pixmap format !\n");
4811 emu++;
4814 if (send_mode) {
4815 int mode;
4817 if (TRACE_ON(ddraw)) {
4818 TRACE("Enumerating with pixel format : \n");
4819 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4820 DPRINTF("\n");
4823 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4824 /* Do not enumerate modes we cannot handle anyway */
4825 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4826 break;
4828 ddsfd.dwWidth = modes[mode].w;
4829 ddsfd.dwHeight = modes[mode].h;
4831 /* Now, send the mode description to the application */
4832 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4833 if (!modescb(&ddsfd, context))
4834 goto exit_enum;
4837 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4838 /* modeX is not standard VGA */
4839 ddsfd.dwWidth = 320;
4840 ddsfd.dwHeight = 200;
4841 if (!modescb(&ddsfd, context))
4842 goto exit_enum;
4847 exit_enum:
4848 TSXFree(vi);
4849 TSXFree(pf);
4851 return DD_OK;
4854 #ifdef HAVE_LIBXXF86DGA
4855 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4856 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4858 ICOM_THIS(IDirectDraw2Impl,iface);
4859 TRACE("(%p)->(%p)\n",This,lpddsfd);
4860 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4861 lpddsfd->dwHeight = This->d.height;
4862 lpddsfd->dwWidth = This->d.width;
4863 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4864 lpddsfd->dwBackBufferCount = 1;
4865 lpddsfd->u.dwRefreshRate = 60;
4866 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4867 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4868 if (TRACE_ON(ddraw)) {
4869 _dump_surface_desc(lpddsfd);
4871 return DD_OK;
4873 #endif /* defined(HAVE_LIBXXF86DGA) */
4875 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4876 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4878 ICOM_THIS(IDirectDraw2Impl,iface);
4879 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4880 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4881 lpddsfd->dwHeight = This->d.height;
4882 lpddsfd->dwWidth = This->d.width;
4883 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4884 lpddsfd->dwBackBufferCount = 1;
4885 lpddsfd->u.dwRefreshRate = 60;
4886 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4887 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4888 if (TRACE_ON(ddraw)) {
4889 _dump_surface_desc(lpddsfd);
4891 return DD_OK;
4894 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4895 ICOM_THIS(IDirectDraw2Impl,iface);
4896 TRACE("(%p)->()\n",This);
4897 return DD_OK;
4900 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4901 LPDIRECTDRAW2 iface,LPDWORD freq
4903 ICOM_THIS(IDirectDraw2Impl,iface);
4904 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4905 *freq = 60*100; /* 60 Hz */
4906 return DD_OK;
4909 /* what can we directly decompress? */
4910 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4911 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4913 ICOM_THIS(IDirectDraw2Impl,iface);
4914 FIXME("(%p,%p,%p), stub\n",This,x,y);
4915 return DD_OK;
4918 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4919 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4921 ICOM_THIS(IDirectDraw2Impl,iface);
4922 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4923 return DD_OK;
4926 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4927 LPDIRECTDRAW2 iface )
4929 ICOM_THIS(IDirectDraw2Impl,iface);
4930 FIXME("(%p)->()\n", This );
4932 return DD_OK;
4935 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4936 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4937 ICOM_THIS(IDirectDraw2Impl,iface);
4938 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4940 return DD_OK;
4943 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4944 LPDWORD lpdwScanLine) {
4945 ICOM_THIS(IDirectDraw2Impl,iface);
4946 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4948 if (lpdwScanLine)
4949 *lpdwScanLine = 0;
4950 return DD_OK;
4953 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4954 GUID *lpGUID) {
4955 ICOM_THIS(IDirectDraw2Impl,iface);
4956 FIXME("(%p)->(%p)\n", This, lpGUID);
4958 return DD_OK;
4961 #ifdef HAVE_LIBXXF86DGA
4963 /* Note: Hack so we can reuse the old functions without compiler warnings */
4964 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4965 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4966 #else
4967 # define XCAST(fun) (void *)
4968 #endif
4970 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4972 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4973 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4974 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4975 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4976 XCAST(Compact)IDirectDraw2Impl_Compact,
4977 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4978 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4979 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4980 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4981 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4982 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4983 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4984 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4985 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4986 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4987 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4988 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4989 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4990 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4991 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4992 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4993 #ifdef HAVE_LIBXXF86DGA2
4994 XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
4995 #else
4996 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4997 #endif
4998 DGA_IDirectDrawImpl_SetDisplayMode,
4999 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5002 #undef XCAST
5004 #endif /* defined(HAVE_LIBXXF86DGA) */
5006 /* Note: Hack so we can reuse the old functions without compiler warnings */
5007 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5008 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
5009 #else
5010 # define XCAST(fun) (void *)
5011 #endif
5013 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
5015 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5016 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5017 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5018 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5019 XCAST(Compact)IDirectDraw2Impl_Compact,
5020 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5021 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5022 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5023 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5024 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5025 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5026 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5027 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5028 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5029 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5030 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5031 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5032 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5033 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5034 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5035 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5036 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5037 Xlib_IDirectDrawImpl_SetDisplayMode,
5038 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5041 #undef XCAST
5043 /*****************************************************************************
5044 * IDirectDraw2
5048 #ifdef HAVE_LIBXXF86DGA
5049 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
5050 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
5052 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5053 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5055 #endif /* defined(HAVE_LIBXXF86DGA) */
5057 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
5058 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
5060 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5061 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5064 #ifdef HAVE_LIBXXF86DGA
5065 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
5066 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5068 ICOM_THIS(IDirectDraw2Impl,iface);
5069 TRACE("(%p)->(%p,%p,%p)\n",
5070 This,ddscaps,total,free
5072 if (total) *total = This->e.dga.fb_memsize * 1024;
5073 if (free) *free = This->e.dga.fb_memsize * 1024;
5074 return DD_OK;
5076 #endif /* defined(HAVE_LIBXXF86DGA) */
5078 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
5079 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5081 ICOM_THIS(IDirectDraw2Impl,iface);
5082 TRACE("(%p)->(%p,%p,%p)\n",
5083 This,ddscaps,total,free
5085 if (total) *total = 2048 * 1024;
5086 if (free) *free = 2048 * 1024;
5087 return DD_OK;
5090 #ifdef HAVE_LIBXXF86DGA
5091 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
5093 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5094 DGA_IDirectDraw2Impl_QueryInterface,
5095 IDirectDraw2Impl_AddRef,
5096 DGA_IDirectDraw2Impl_Release,
5097 IDirectDraw2Impl_Compact,
5098 IDirectDraw2Impl_CreateClipper,
5099 DGA_IDirectDraw2Impl_CreatePalette,
5100 DGA_IDirectDraw2Impl_CreateSurface,
5101 IDirectDraw2Impl_DuplicateSurface,
5102 DGA_IDirectDraw2Impl_EnumDisplayModes,
5103 IDirectDraw2Impl_EnumSurfaces,
5104 IDirectDraw2Impl_FlipToGDISurface,
5105 DGA_IDirectDraw2Impl_GetCaps,
5106 DGA_IDirectDraw2Impl_GetDisplayMode,
5107 IDirectDraw2Impl_GetFourCCCodes,
5108 IDirectDraw2Impl_GetGDISurface,
5109 IDirectDraw2Impl_GetMonitorFrequency,
5110 IDirectDraw2Impl_GetScanLine,
5111 IDirectDraw2Impl_GetVerticalBlankStatus,
5112 IDirectDraw2Impl_Initialize,
5113 DGA_IDirectDraw2Impl_RestoreDisplayMode,
5114 IDirectDraw2Impl_SetCooperativeLevel,
5115 DGA_IDirectDraw2Impl_SetDisplayMode,
5116 IDirectDraw2Impl_WaitForVerticalBlank,
5117 DGA_IDirectDraw2Impl_GetAvailableVidMem
5119 #endif /* defined(HAVE_LIBXXF86DGA) */
5121 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
5123 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5124 Xlib_IDirectDraw2Impl_QueryInterface,
5125 IDirectDraw2Impl_AddRef,
5126 Xlib_IDirectDraw2Impl_Release,
5127 IDirectDraw2Impl_Compact,
5128 IDirectDraw2Impl_CreateClipper,
5129 Xlib_IDirectDraw2Impl_CreatePalette,
5130 Xlib_IDirectDraw2Impl_CreateSurface,
5131 IDirectDraw2Impl_DuplicateSurface,
5132 Xlib_IDirectDraw2Impl_EnumDisplayModes,
5133 IDirectDraw2Impl_EnumSurfaces,
5134 IDirectDraw2Impl_FlipToGDISurface,
5135 Xlib_IDirectDraw2Impl_GetCaps,
5136 Xlib_IDirectDraw2Impl_GetDisplayMode,
5137 IDirectDraw2Impl_GetFourCCCodes,
5138 IDirectDraw2Impl_GetGDISurface,
5139 IDirectDraw2Impl_GetMonitorFrequency,
5140 IDirectDraw2Impl_GetScanLine,
5141 IDirectDraw2Impl_GetVerticalBlankStatus,
5142 IDirectDraw2Impl_Initialize,
5143 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5144 IDirectDraw2Impl_SetCooperativeLevel,
5145 Xlib_IDirectDraw2Impl_SetDisplayMode,
5146 IDirectDraw2Impl_WaitForVerticalBlank,
5147 Xlib_IDirectDraw2Impl_GetAvailableVidMem
5150 /*****************************************************************************
5151 * IDirectDraw4
5155 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
5156 HDC hdc,
5157 LPDIRECTDRAWSURFACE *lpDDS) {
5158 ICOM_THIS(IDirectDraw4Impl,iface);
5159 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
5161 return DD_OK;
5164 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
5165 ICOM_THIS(IDirectDraw4Impl,iface);
5166 FIXME("(%p)->()\n", This);
5168 return DD_OK;
5171 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
5172 ICOM_THIS(IDirectDraw4Impl,iface);
5173 FIXME("(%p)->()\n", This);
5175 return DD_OK;
5178 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5179 LPDDDEVICEIDENTIFIER lpdddi,
5180 DWORD dwFlags) {
5181 ICOM_THIS(IDirectDraw4Impl,iface);
5182 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5184 return DD_OK;
5187 #ifdef HAVE_LIBXXF86DGA
5189 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5190 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5191 #else
5192 # define XCAST(fun) (void*)
5193 #endif
5195 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5197 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5198 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5199 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5200 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5201 XCAST(Compact)IDirectDraw2Impl_Compact,
5202 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5203 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5204 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5205 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5206 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5207 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5208 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5209 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5210 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5211 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5212 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5213 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5214 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5215 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5216 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5217 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5218 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5219 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5220 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5221 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5222 IDirectDraw4Impl_GetSurfaceFromDC,
5223 IDirectDraw4Impl_RestoreAllSurfaces,
5224 IDirectDraw4Impl_TestCooperativeLevel,
5225 IDirectDraw4Impl_GetDeviceIdentifier
5228 #undef XCAST
5230 #endif /* defined(HAVE_LIBXXF86DGA) */
5232 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5233 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5234 #else
5235 # define XCAST(fun) (void*)
5236 #endif
5238 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5240 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5241 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5242 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5243 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5244 XCAST(Compact)IDirectDraw2Impl_Compact,
5245 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5246 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5247 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5248 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5249 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5250 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5251 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5252 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5253 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5254 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5255 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5256 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5257 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5258 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5259 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5260 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5261 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5262 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5263 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5264 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5265 IDirectDraw4Impl_GetSurfaceFromDC,
5266 IDirectDraw4Impl_RestoreAllSurfaces,
5267 IDirectDraw4Impl_TestCooperativeLevel,
5268 IDirectDraw4Impl_GetDeviceIdentifier
5271 #undef XCAST
5273 /******************************************************************************
5274 * DirectDrawCreate
5277 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5279 LRESULT ret;
5280 IDirectDrawImpl* ddraw = NULL;
5281 DWORD lastError;
5283 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5285 SetLastError( ERROR_SUCCESS );
5286 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
5287 if( (!ddraw) &&
5288 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
5291 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5294 if( ddraw )
5296 /* Perform any special direct draw functions */
5297 if (msg==WM_PAINT)
5298 ddraw->d.paintable = 1;
5300 /* Now let the application deal with the rest of this */
5301 if( ddraw->d.mainWindow )
5304 /* Don't think that we actually need to call this but...
5305 might as well be on the safe side of things... */
5307 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5308 it should be the procedures of our fake window that gets called
5309 instead of those of the window provided by the application.
5310 And with this patch, mouse clicks work with Monkey Island III
5311 - Lionel */
5312 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5314 if( !ret )
5316 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5317 /* We didn't handle the message - give it to the application */
5318 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5320 ret = CallWindowProcA(tmpWnd->winproc,
5321 ddraw->d.mainWindow, msg, wParam, lParam );
5323 WIN_ReleaseWndPtr(tmpWnd);
5327 } else {
5328 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5332 else
5334 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5337 return ret;
5340 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5341 #ifdef HAVE_LIBXXF86DGA
5342 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5343 int memsize,banksize,major,minor,flags;
5344 char *addr;
5345 int depth;
5346 int dga_version;
5347 int width, height;
5349 /* Get DGA availability / version */
5350 dga_version = DDRAW_DGA_Available();
5352 if (dga_version == 0) {
5353 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5354 return DDERR_GENERIC;
5357 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5358 (*ilplpDD)->ref = 1;
5359 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5360 #ifdef HAVE_LIBXXF86DGA2
5361 if (dga_version == 1) {
5362 (*ilplpDD)->e.dga.version = 1;
5363 #endif /* defined(HAVE_LIBXXF86DGA2) */
5364 TSXF86DGAQueryVersion(display,&major,&minor);
5365 TRACE("XF86DGA is version %d.%d\n",major,minor);
5366 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5367 if (!(flags & XF86DGADirectPresent))
5368 MESSAGE("direct video is NOT PRESENT.\n");
5369 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5370 (*ilplpDD)->e.dga.fb_width = width;
5371 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5372 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5373 (*ilplpDD)->e.dga.fb_height = height;
5374 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5375 addr,width,banksize,memsize
5377 TRACE("viewport height: %d\n",height);
5378 /* Get the screen dimensions as seen by Wine.
5379 In that case, it may be better to ignore the -desktop mode and return the
5380 real screen size => print a warning */
5381 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5382 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5383 if (((*ilplpDD)->d.height != height) ||
5384 ((*ilplpDD)->d.width != width))
5385 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5386 (*ilplpDD)->e.dga.fb_addr = addr;
5387 (*ilplpDD)->e.dga.fb_memsize = memsize;
5388 (*ilplpDD)->e.dga.vpmask = 0;
5390 /* just assume the default depth is the DGA depth too */
5391 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5392 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
5393 #ifdef RESTORE_SIGNALS
5394 SIGNAL_Init();
5395 #endif
5396 #ifdef HAVE_LIBXXF86DGA2
5397 } else {
5398 XDGAMode *modes;
5399 int i, num_modes;
5400 int mode_to_use = 0;
5402 (*ilplpDD)->e.dga.version = 2;
5404 TSXDGAQueryVersion(display,&major,&minor);
5405 TRACE("XDGA is version %d.%d\n",major,minor);
5407 TRACE("Opening the frame buffer.\n");
5408 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5409 ERR("Error opening the frame buffer !!!\n");
5411 return DDERR_GENERIC;
5414 /* List all available modes */
5415 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5416 (*ilplpDD)->e.dga.modes = modes;
5417 (*ilplpDD)->e.dga.num_modes = num_modes;
5418 if (TRACE_ON(ddraw)) {
5419 TRACE("Available modes :\n");
5420 for (i = 0; i < num_modes; i++) {
5421 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5422 modes[i].num,
5423 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5424 modes[i].viewportWidth, modes[i].viewportHeight,
5425 modes[i].depth);
5426 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5427 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5428 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5429 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5430 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5431 DPRINTF("\n");
5433 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5434 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5435 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5436 mode_to_use = modes[i].num;
5440 if (mode_to_use == 0) {
5441 ERR("Could not find mode !\n");
5442 mode_to_use = 1;
5443 } else {
5444 DPRINTF("Using mode number %d\n", mode_to_use);
5447 /* Initialize the frame buffer */
5448 _DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
5449 /* Set the input handling for relative mouse movements */
5450 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5452 #endif /* defined(HAVE_LIBXXF86DGA2) */
5453 return DD_OK;
5454 #else /* defined(HAVE_LIBXXF86DGA) */
5455 return DDERR_INVALIDDIRECTDRAWGUID;
5456 #endif /* defined(HAVE_LIBXXF86DGA) */
5459 static BOOL
5460 DDRAW_XSHM_Available(void)
5462 #ifdef HAVE_LIBXXSHM
5463 if (TSXShmQueryExtension(display))
5465 int major, minor;
5466 Bool shpix;
5468 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5469 (Options.noXSHM != 1))
5470 return 1;
5471 else
5472 return 0;
5474 else
5475 return 0;
5476 #else
5477 return 0;
5478 #endif
5481 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5482 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5483 int depth;
5485 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5486 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5487 (*ilplpDD)->ref = 1;
5488 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5490 /* At DirectDraw creation, the depth is the default depth */
5491 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5492 _common_depth_to_pixelformat(depth,
5493 &((*ilplpDD)->d.directdraw_pixelformat),
5494 &((*ilplpDD)->d.screen_pixelformat),
5495 &((*ilplpDD)->d.pixmap_depth));
5496 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5497 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5499 #ifdef HAVE_LIBXXSHM
5500 /* Test if XShm is available. */
5501 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5502 (*ilplpDD)->e.xlib.xshm_compl = 0;
5503 TRACE("Using XShm extension.\n");
5505 #endif
5507 return DD_OK;
5510 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5511 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5512 char xclsid[50];
5513 WNDCLASSA wc;
5514 /* WND* pParentWindow; */
5515 HRESULT ret;
5517 if (HIWORD(lpGUID))
5518 WINE_StringFromCLSID(lpGUID,xclsid);
5519 else {
5520 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
5521 lpGUID = NULL;
5524 TRACE("(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
5526 if ( ( !lpGUID ) ||
5527 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5528 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5529 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5530 /* if they didn't request a particular interface, use the best
5531 * supported one */
5532 if (DDRAW_DGA_Available())
5533 lpGUID = &DGA_DirectDraw_GUID;
5534 else
5535 lpGUID = &XLIB_DirectDraw_GUID;
5538 wc.style = CS_GLOBALCLASS;
5539 wc.lpfnWndProc = Xlib_DDWndProc;
5540 wc.cbClsExtra = 0;
5541 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
5542 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
5544 /* We can be a child of the desktop since we're really important */
5546 This code is not useful since hInstance is forced to 0 afterward
5547 pParentWindow = WIN_GetDesktop();
5548 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5550 wc.hInstance = 0;
5553 wc.hIcon = 0;
5554 wc.hCursor = (HCURSOR)IDC_ARROWA;
5555 wc.hbrBackground= NULL_BRUSH;
5556 wc.lpszMenuName = 0;
5557 wc.lpszClassName= "WINE_DirectDraw";
5558 RegisterClassA(&wc);
5560 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5561 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5563 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5564 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5566 else {
5567 goto err;
5571 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5572 return ret;
5574 err:
5575 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
5576 return DDERR_INVALIDDIRECTDRAWGUID;
5579 /*******************************************************************************
5580 * DirectDraw ClassFactory
5582 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5585 typedef struct
5587 /* IUnknown fields */
5588 ICOM_VFIELD(IClassFactory);
5589 DWORD ref;
5590 } IClassFactoryImpl;
5592 static HRESULT WINAPI
5593 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5594 ICOM_THIS(IClassFactoryImpl,iface);
5595 char buf[80];
5597 if (HIWORD(riid))
5598 WINE_StringFromCLSID(riid,buf);
5599 else
5600 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5601 FIXME("(%p)->(%s,%p),stub!\n",This,buf,ppobj);
5602 return E_NOINTERFACE;
5605 static ULONG WINAPI
5606 DDCF_AddRef(LPCLASSFACTORY iface) {
5607 ICOM_THIS(IClassFactoryImpl,iface);
5608 return ++(This->ref);
5611 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5612 ICOM_THIS(IClassFactoryImpl,iface);
5613 /* static class, won't be freed */
5614 return --(This->ref);
5617 static HRESULT WINAPI DDCF_CreateInstance(
5618 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5620 ICOM_THIS(IClassFactoryImpl,iface);
5621 char buf[80];
5623 WINE_StringFromCLSID(riid,buf);
5624 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
5625 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5626 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5627 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5628 /* FIXME: reuse already created DirectDraw if present? */
5629 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5631 return CLASS_E_CLASSNOTAVAILABLE;
5634 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5635 ICOM_THIS(IClassFactoryImpl,iface);
5636 FIXME("(%p)->(%d),stub!\n",This,dolock);
5637 return S_OK;
5640 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5642 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5643 DDCF_QueryInterface,
5644 DDCF_AddRef,
5645 DDCF_Release,
5646 DDCF_CreateInstance,
5647 DDCF_LockServer
5649 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5651 /*******************************************************************************
5652 * DllGetClassObject [DDRAW.13]
5653 * Retrieves class object from a DLL object
5655 * NOTES
5656 * Docs say returns STDAPI
5658 * PARAMS
5659 * rclsid [I] CLSID for the class object
5660 * riid [I] Reference to identifier of interface for class object
5661 * ppv [O] Address of variable to receive interface pointer for riid
5663 * RETURNS
5664 * Success: S_OK
5665 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5666 * E_UNEXPECTED
5668 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5670 char buf[80],xbuf[80];
5672 if (HIWORD(rclsid))
5673 WINE_StringFromCLSID(rclsid,xbuf);
5674 else
5675 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
5676 if (HIWORD(riid))
5677 WINE_StringFromCLSID(riid,buf);
5678 else
5679 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5680 WINE_StringFromCLSID(riid,xbuf);
5681 TRACE("(%p,%p,%p)\n", xbuf, buf, ppv);
5682 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5683 *ppv = (LPVOID)&DDRAW_CF;
5684 IClassFactory_AddRef((IClassFactory*)*ppv);
5685 return S_OK;
5687 FIXME("(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
5688 return CLASS_E_CLASSNOTAVAILABLE;
5692 /*******************************************************************************
5693 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5695 * RETURNS
5696 * Success: S_OK
5697 * Failure: S_FALSE
5699 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5701 FIXME("(void): stub\n");
5702 return S_FALSE;
5705 #else /* !defined(X_DISPLAY_MISSING) */
5707 #include "windef.h"
5708 #include "wtypes.h"
5710 #define DD_OK 0
5712 typedef void *LPUNKNOWN;
5713 typedef void *LPDIRECTDRAW;
5714 typedef void *LPDIRECTDRAWCLIPPER;
5715 typedef void *LPDDENUMCALLBACKA;
5716 typedef void *LPDDENUMCALLBACKEXA;
5717 typedef void *LPDDENUMCALLBACKEXW;
5718 typedef void *LPDDENUMCALLBACKW;
5720 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5722 return DD_OK;
5725 HRESULT WINAPI DirectDrawCreate(
5726 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5728 return DD_OK;
5731 HRESULT WINAPI DirectDrawCreateClipper(
5732 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5734 return DD_OK;
5737 HRESULT WINAPI DirectDrawEnumerateA(
5738 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5740 return DD_OK;
5743 HRESULT WINAPI DirectDrawEnumerateExA(
5744 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5746 return DD_OK;
5749 HRESULT WINAPI DirectDrawEnumerateExW(
5750 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5752 return DD_OK;
5755 HRESULT WINAPI DirectDrawEnumerateW(
5756 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5758 return DD_OK;
5761 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5763 return CLASS_E_CLASSNOTAVAILABLE;
5766 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5768 return DD_OK;
5771 #endif /* !defined(X_DISPLAY_MISSING) */