EnumDisplayModes must pass lPitch.
[wine.git] / graphics / ddraw.c
blobc47df9085c28f6a758ef2d7bc0f8147c0a082d67
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 xbpp, 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|DDSD_PITCH;
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) || (emu != 4)) {
4704 int mode_index = 0;
4705 int send_mode = 0;
4706 int j;
4708 if (i < npixmap) {
4709 for (j = 0; j < 4; j++) {
4710 if (has_depth[j] == pf[i].depth) {
4711 mode_index = j;
4712 break;
4715 if (j == 4) {
4716 i++;
4717 continue;
4721 if (has_mode[mode_index] == 0) {
4722 if (mode_index == 0) {
4723 send_mode = 1;
4725 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4726 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4727 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4728 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4729 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4730 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4731 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4732 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4733 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4735 xbpp = 1;
4737 has_mode[mode_index] = 1;
4738 } else {
4739 /* All the 'true color' depths (15, 16 and 24)
4740 First, find the corresponding visual to extract the bit masks */
4741 for (j = 0; j < nvisuals; j++) {
4742 if (vi[j].depth == pf[i].depth) {
4743 ddsfd.ddsCaps.dwCaps = 0;
4744 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4745 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4746 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4747 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4748 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4749 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4750 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4751 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4753 xbpp = pf[i].bits_per_pixel/8;
4755 send_mode = 1;
4756 has_mode[mode_index] = 1;
4757 break;
4760 if (j == nvisuals)
4761 ERR("Did not find visual corresponding the the pixmap format !\n");
4764 i++;
4765 } else {
4766 /* Now to emulated modes */
4767 if (has_mode[emu] == 0) {
4768 int c;
4769 int l;
4770 int depth = has_depth[emu];
4772 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4773 if (ModeEmulations[c].dest.depth == depth) {
4774 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4775 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4776 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4777 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4778 int j;
4779 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4780 if ((vi[j].depth == pf[l].depth) &&
4781 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4782 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4783 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4784 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4785 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4786 if (depth == 8) {
4787 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4788 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4789 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4790 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4791 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4792 } else {
4793 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4794 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4795 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4796 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4797 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4799 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4800 send_mode = 1;
4803 if (send_mode == 0)
4804 ERR("No visual corresponding to pixmap format !\n");
4812 emu++;
4815 if (send_mode) {
4816 int mode;
4818 if (TRACE_ON(ddraw)) {
4819 TRACE("Enumerating with pixel format : \n");
4820 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4821 DPRINTF("\n");
4824 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4825 /* Do not enumerate modes we cannot handle anyway */
4826 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4827 break;
4829 ddsfd.dwWidth = modes[mode].w;
4830 ddsfd.dwHeight= modes[mode].h;
4831 ddsfd.lPitch = ddsfd.dwWidth * xbpp;
4833 /* Now, send the mode description to the application */
4834 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4835 if (!modescb(&ddsfd, context))
4836 goto exit_enum;
4839 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4840 /* modeX is not standard VGA */
4841 ddsfd.dwWidth = 320;
4842 ddsfd.dwHeight = 200;
4843 ddsfd.lPitch = 320 * xbpp;
4844 if (!modescb(&ddsfd, context))
4845 goto exit_enum;
4849 exit_enum:
4850 TSXFree(vi);
4851 TSXFree(pf);
4853 return DD_OK;
4856 #ifdef HAVE_LIBXXF86DGA
4857 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4858 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4860 ICOM_THIS(IDirectDraw2Impl,iface);
4861 TRACE("(%p)->(%p)\n",This,lpddsfd);
4862 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4863 lpddsfd->dwHeight = This->d.height;
4864 lpddsfd->dwWidth = This->d.width;
4865 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4866 lpddsfd->dwBackBufferCount = 1;
4867 lpddsfd->u.dwRefreshRate = 60;
4868 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4869 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4870 if (TRACE_ON(ddraw)) {
4871 _dump_surface_desc(lpddsfd);
4873 return DD_OK;
4875 #endif /* defined(HAVE_LIBXXF86DGA) */
4877 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4878 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4880 ICOM_THIS(IDirectDraw2Impl,iface);
4881 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4882 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4883 lpddsfd->dwHeight = This->d.height;
4884 lpddsfd->dwWidth = This->d.width;
4885 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4886 lpddsfd->dwBackBufferCount = 1;
4887 lpddsfd->u.dwRefreshRate = 60;
4888 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4889 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4890 if (TRACE_ON(ddraw)) {
4891 _dump_surface_desc(lpddsfd);
4893 return DD_OK;
4896 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4897 ICOM_THIS(IDirectDraw2Impl,iface);
4898 TRACE("(%p)->()\n",This);
4899 return DD_OK;
4902 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4903 LPDIRECTDRAW2 iface,LPDWORD freq
4905 ICOM_THIS(IDirectDraw2Impl,iface);
4906 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4907 *freq = 60*100; /* 60 Hz */
4908 return DD_OK;
4911 /* what can we directly decompress? */
4912 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4913 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4915 ICOM_THIS(IDirectDraw2Impl,iface);
4916 FIXME("(%p,%p,%p), stub\n",This,x,y);
4917 return DD_OK;
4920 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4921 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4923 ICOM_THIS(IDirectDraw2Impl,iface);
4924 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4925 return DD_OK;
4928 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4929 LPDIRECTDRAW2 iface )
4931 ICOM_THIS(IDirectDraw2Impl,iface);
4932 FIXME("(%p)->()\n", This );
4934 return DD_OK;
4937 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4938 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4939 ICOM_THIS(IDirectDraw2Impl,iface);
4940 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4942 return DD_OK;
4945 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4946 LPDWORD lpdwScanLine) {
4947 ICOM_THIS(IDirectDraw2Impl,iface);
4948 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4950 if (lpdwScanLine)
4951 *lpdwScanLine = 0;
4952 return DD_OK;
4955 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4956 GUID *lpGUID) {
4957 ICOM_THIS(IDirectDraw2Impl,iface);
4958 FIXME("(%p)->(%p)\n", This, lpGUID);
4960 return DD_OK;
4963 #ifdef HAVE_LIBXXF86DGA
4965 /* Note: Hack so we can reuse the old functions without compiler warnings */
4966 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4967 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4968 #else
4969 # define XCAST(fun) (void *)
4970 #endif
4972 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4974 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4975 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4976 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4977 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4978 XCAST(Compact)IDirectDraw2Impl_Compact,
4979 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4980 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4981 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4982 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4983 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4984 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4985 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4986 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4987 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4988 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4989 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4990 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4991 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4992 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4993 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4994 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4995 #ifdef HAVE_LIBXXF86DGA2
4996 XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
4997 #else
4998 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4999 #endif
5000 DGA_IDirectDrawImpl_SetDisplayMode,
5001 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5004 #undef XCAST
5006 #endif /* defined(HAVE_LIBXXF86DGA) */
5008 /* Note: Hack so we can reuse the old functions without compiler warnings */
5009 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5010 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
5011 #else
5012 # define XCAST(fun) (void *)
5013 #endif
5015 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
5017 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5018 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5019 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5020 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5021 XCAST(Compact)IDirectDraw2Impl_Compact,
5022 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5023 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5024 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5025 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5026 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5027 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5028 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5029 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5030 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5031 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5032 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5033 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5034 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5035 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5036 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5037 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5038 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5039 Xlib_IDirectDrawImpl_SetDisplayMode,
5040 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5043 #undef XCAST
5045 /*****************************************************************************
5046 * IDirectDraw2
5050 #ifdef HAVE_LIBXXF86DGA
5051 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
5052 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
5054 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5055 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5057 #endif /* defined(HAVE_LIBXXF86DGA) */
5059 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
5060 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
5062 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5063 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5066 #ifdef HAVE_LIBXXF86DGA
5067 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
5068 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5070 ICOM_THIS(IDirectDraw2Impl,iface);
5071 TRACE("(%p)->(%p,%p,%p)\n",
5072 This,ddscaps,total,free
5074 if (total) *total = This->e.dga.fb_memsize * 1024;
5075 if (free) *free = This->e.dga.fb_memsize * 1024;
5076 return DD_OK;
5078 #endif /* defined(HAVE_LIBXXF86DGA) */
5080 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
5081 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5083 ICOM_THIS(IDirectDraw2Impl,iface);
5084 TRACE("(%p)->(%p,%p,%p)\n",
5085 This,ddscaps,total,free
5087 if (total) *total = 2048 * 1024;
5088 if (free) *free = 2048 * 1024;
5089 return DD_OK;
5092 #ifdef HAVE_LIBXXF86DGA
5093 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
5095 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5096 DGA_IDirectDraw2Impl_QueryInterface,
5097 IDirectDraw2Impl_AddRef,
5098 DGA_IDirectDraw2Impl_Release,
5099 IDirectDraw2Impl_Compact,
5100 IDirectDraw2Impl_CreateClipper,
5101 DGA_IDirectDraw2Impl_CreatePalette,
5102 DGA_IDirectDraw2Impl_CreateSurface,
5103 IDirectDraw2Impl_DuplicateSurface,
5104 DGA_IDirectDraw2Impl_EnumDisplayModes,
5105 IDirectDraw2Impl_EnumSurfaces,
5106 IDirectDraw2Impl_FlipToGDISurface,
5107 DGA_IDirectDraw2Impl_GetCaps,
5108 DGA_IDirectDraw2Impl_GetDisplayMode,
5109 IDirectDraw2Impl_GetFourCCCodes,
5110 IDirectDraw2Impl_GetGDISurface,
5111 IDirectDraw2Impl_GetMonitorFrequency,
5112 IDirectDraw2Impl_GetScanLine,
5113 IDirectDraw2Impl_GetVerticalBlankStatus,
5114 IDirectDraw2Impl_Initialize,
5115 DGA_IDirectDraw2Impl_RestoreDisplayMode,
5116 IDirectDraw2Impl_SetCooperativeLevel,
5117 DGA_IDirectDraw2Impl_SetDisplayMode,
5118 IDirectDraw2Impl_WaitForVerticalBlank,
5119 DGA_IDirectDraw2Impl_GetAvailableVidMem
5121 #endif /* defined(HAVE_LIBXXF86DGA) */
5123 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
5125 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5126 Xlib_IDirectDraw2Impl_QueryInterface,
5127 IDirectDraw2Impl_AddRef,
5128 Xlib_IDirectDraw2Impl_Release,
5129 IDirectDraw2Impl_Compact,
5130 IDirectDraw2Impl_CreateClipper,
5131 Xlib_IDirectDraw2Impl_CreatePalette,
5132 Xlib_IDirectDraw2Impl_CreateSurface,
5133 IDirectDraw2Impl_DuplicateSurface,
5134 Xlib_IDirectDraw2Impl_EnumDisplayModes,
5135 IDirectDraw2Impl_EnumSurfaces,
5136 IDirectDraw2Impl_FlipToGDISurface,
5137 Xlib_IDirectDraw2Impl_GetCaps,
5138 Xlib_IDirectDraw2Impl_GetDisplayMode,
5139 IDirectDraw2Impl_GetFourCCCodes,
5140 IDirectDraw2Impl_GetGDISurface,
5141 IDirectDraw2Impl_GetMonitorFrequency,
5142 IDirectDraw2Impl_GetScanLine,
5143 IDirectDraw2Impl_GetVerticalBlankStatus,
5144 IDirectDraw2Impl_Initialize,
5145 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5146 IDirectDraw2Impl_SetCooperativeLevel,
5147 Xlib_IDirectDraw2Impl_SetDisplayMode,
5148 IDirectDraw2Impl_WaitForVerticalBlank,
5149 Xlib_IDirectDraw2Impl_GetAvailableVidMem
5152 /*****************************************************************************
5153 * IDirectDraw4
5157 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
5158 HDC hdc,
5159 LPDIRECTDRAWSURFACE *lpDDS) {
5160 ICOM_THIS(IDirectDraw4Impl,iface);
5161 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
5163 return DD_OK;
5166 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
5167 ICOM_THIS(IDirectDraw4Impl,iface);
5168 FIXME("(%p)->()\n", This);
5170 return DD_OK;
5173 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
5174 ICOM_THIS(IDirectDraw4Impl,iface);
5175 FIXME("(%p)->()\n", This);
5177 return DD_OK;
5180 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5181 LPDDDEVICEIDENTIFIER lpdddi,
5182 DWORD dwFlags) {
5183 ICOM_THIS(IDirectDraw4Impl,iface);
5184 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5186 return DD_OK;
5189 #ifdef HAVE_LIBXXF86DGA
5191 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5192 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5193 #else
5194 # define XCAST(fun) (void*)
5195 #endif
5197 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5199 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5200 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5201 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5202 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5203 XCAST(Compact)IDirectDraw2Impl_Compact,
5204 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5205 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5206 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5207 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5208 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5209 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5210 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5211 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5212 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5213 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5214 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5215 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5216 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5217 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5218 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5219 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5220 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5221 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5222 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5223 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5224 IDirectDraw4Impl_GetSurfaceFromDC,
5225 IDirectDraw4Impl_RestoreAllSurfaces,
5226 IDirectDraw4Impl_TestCooperativeLevel,
5227 IDirectDraw4Impl_GetDeviceIdentifier
5230 #undef XCAST
5232 #endif /* defined(HAVE_LIBXXF86DGA) */
5234 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5235 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5236 #else
5237 # define XCAST(fun) (void*)
5238 #endif
5240 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5242 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5243 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5244 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5245 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5246 XCAST(Compact)IDirectDraw2Impl_Compact,
5247 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5248 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5249 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5250 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5251 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5252 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5253 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5254 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5255 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5256 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5257 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5258 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5259 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5260 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5261 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5262 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5263 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5264 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5265 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5266 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5267 IDirectDraw4Impl_GetSurfaceFromDC,
5268 IDirectDraw4Impl_RestoreAllSurfaces,
5269 IDirectDraw4Impl_TestCooperativeLevel,
5270 IDirectDraw4Impl_GetDeviceIdentifier
5273 #undef XCAST
5275 /******************************************************************************
5276 * DirectDrawCreate
5279 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5281 LRESULT ret;
5282 IDirectDrawImpl* ddraw = NULL;
5283 DWORD lastError;
5285 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5287 SetLastError( ERROR_SUCCESS );
5288 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
5289 if( (!ddraw) &&
5290 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
5293 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5296 if( ddraw )
5298 /* Perform any special direct draw functions */
5299 if (msg==WM_PAINT)
5300 ddraw->d.paintable = 1;
5302 /* Now let the application deal with the rest of this */
5303 if( ddraw->d.mainWindow )
5306 /* Don't think that we actually need to call this but...
5307 might as well be on the safe side of things... */
5309 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5310 it should be the procedures of our fake window that gets called
5311 instead of those of the window provided by the application.
5312 And with this patch, mouse clicks work with Monkey Island III
5313 - Lionel */
5314 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5316 if( !ret )
5318 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5319 /* We didn't handle the message - give it to the application */
5320 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5322 ret = CallWindowProcA(tmpWnd->winproc,
5323 ddraw->d.mainWindow, msg, wParam, lParam );
5325 WIN_ReleaseWndPtr(tmpWnd);
5329 } else {
5330 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5334 else
5336 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5339 return ret;
5342 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5343 #ifdef HAVE_LIBXXF86DGA
5344 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5345 int memsize,banksize,major,minor,flags;
5346 char *addr;
5347 int depth;
5348 int dga_version;
5349 int width, height;
5351 /* Get DGA availability / version */
5352 dga_version = DDRAW_DGA_Available();
5354 if (dga_version == 0) {
5355 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5356 return DDERR_GENERIC;
5359 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5360 (*ilplpDD)->ref = 1;
5361 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5362 #ifdef HAVE_LIBXXF86DGA2
5363 if (dga_version == 1) {
5364 (*ilplpDD)->e.dga.version = 1;
5365 #endif /* defined(HAVE_LIBXXF86DGA2) */
5366 TSXF86DGAQueryVersion(display,&major,&minor);
5367 TRACE("XF86DGA is version %d.%d\n",major,minor);
5368 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5369 if (!(flags & XF86DGADirectPresent))
5370 MESSAGE("direct video is NOT PRESENT.\n");
5371 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5372 (*ilplpDD)->e.dga.fb_width = width;
5373 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5374 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5375 (*ilplpDD)->e.dga.fb_height = height;
5376 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5377 addr,width,banksize,memsize
5379 TRACE("viewport height: %d\n",height);
5380 /* Get the screen dimensions as seen by Wine.
5381 In that case, it may be better to ignore the -desktop mode and return the
5382 real screen size => print a warning */
5383 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5384 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5385 if (((*ilplpDD)->d.height != height) ||
5386 ((*ilplpDD)->d.width != width))
5387 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5388 (*ilplpDD)->e.dga.fb_addr = addr;
5389 (*ilplpDD)->e.dga.fb_memsize = memsize;
5390 (*ilplpDD)->e.dga.vpmask = 0;
5392 /* just assume the default depth is the DGA depth too */
5393 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5394 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
5395 #ifdef RESTORE_SIGNALS
5396 SIGNAL_Init();
5397 #endif
5398 #ifdef HAVE_LIBXXF86DGA2
5399 } else {
5400 XDGAMode *modes;
5401 int i, num_modes;
5402 int mode_to_use = 0;
5404 (*ilplpDD)->e.dga.version = 2;
5406 TSXDGAQueryVersion(display,&major,&minor);
5407 TRACE("XDGA is version %d.%d\n",major,minor);
5409 TRACE("Opening the frame buffer.\n");
5410 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5411 ERR("Error opening the frame buffer !!!\n");
5413 return DDERR_GENERIC;
5416 /* List all available modes */
5417 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5418 (*ilplpDD)->e.dga.modes = modes;
5419 (*ilplpDD)->e.dga.num_modes = num_modes;
5420 if (TRACE_ON(ddraw)) {
5421 TRACE("Available modes :\n");
5422 for (i = 0; i < num_modes; i++) {
5423 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5424 modes[i].num,
5425 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5426 modes[i].viewportWidth, modes[i].viewportHeight,
5427 modes[i].depth);
5428 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5429 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5430 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5431 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5432 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5433 DPRINTF("\n");
5435 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5436 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5437 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5438 mode_to_use = modes[i].num;
5442 if (mode_to_use == 0) {
5443 ERR("Could not find mode !\n");
5444 mode_to_use = 1;
5445 } else {
5446 DPRINTF("Using mode number %d\n", mode_to_use);
5449 /* Initialize the frame buffer */
5450 _DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
5451 /* Set the input handling for relative mouse movements */
5452 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5454 #endif /* defined(HAVE_LIBXXF86DGA2) */
5455 return DD_OK;
5456 #else /* defined(HAVE_LIBXXF86DGA) */
5457 return DDERR_INVALIDDIRECTDRAWGUID;
5458 #endif /* defined(HAVE_LIBXXF86DGA) */
5461 static BOOL
5462 DDRAW_XSHM_Available(void)
5464 #ifdef HAVE_LIBXXSHM
5465 if (TSXShmQueryExtension(display))
5467 int major, minor;
5468 Bool shpix;
5470 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5471 (Options.noXSHM != 1))
5472 return 1;
5473 else
5474 return 0;
5476 else
5477 return 0;
5478 #else
5479 return 0;
5480 #endif
5483 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5484 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5485 int depth;
5487 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5488 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5489 (*ilplpDD)->ref = 1;
5490 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5492 /* At DirectDraw creation, the depth is the default depth */
5493 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5494 _common_depth_to_pixelformat(depth,
5495 &((*ilplpDD)->d.directdraw_pixelformat),
5496 &((*ilplpDD)->d.screen_pixelformat),
5497 &((*ilplpDD)->d.pixmap_depth));
5498 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5499 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5501 #ifdef HAVE_LIBXXSHM
5502 /* Test if XShm is available. */
5503 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5504 (*ilplpDD)->e.xlib.xshm_compl = 0;
5505 TRACE("Using XShm extension.\n");
5507 #endif
5509 return DD_OK;
5512 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5513 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5514 char xclsid[50];
5515 WNDCLASSA wc;
5516 /* WND* pParentWindow; */
5517 HRESULT ret;
5519 if (HIWORD(lpGUID))
5520 WINE_StringFromCLSID(lpGUID,xclsid);
5521 else {
5522 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
5523 lpGUID = NULL;
5526 TRACE("(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
5528 if ( ( !lpGUID ) ||
5529 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5530 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5531 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5532 /* if they didn't request a particular interface, use the best
5533 * supported one */
5534 if (DDRAW_DGA_Available())
5535 lpGUID = &DGA_DirectDraw_GUID;
5536 else
5537 lpGUID = &XLIB_DirectDraw_GUID;
5540 wc.style = CS_GLOBALCLASS;
5541 wc.lpfnWndProc = Xlib_DDWndProc;
5542 wc.cbClsExtra = 0;
5543 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
5544 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
5546 /* We can be a child of the desktop since we're really important */
5548 This code is not useful since hInstance is forced to 0 afterward
5549 pParentWindow = WIN_GetDesktop();
5550 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5552 wc.hInstance = 0;
5555 wc.hIcon = 0;
5556 wc.hCursor = (HCURSOR)IDC_ARROWA;
5557 wc.hbrBackground= NULL_BRUSH;
5558 wc.lpszMenuName = 0;
5559 wc.lpszClassName= "WINE_DirectDraw";
5560 RegisterClassA(&wc);
5562 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5563 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5565 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5566 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5568 else {
5569 goto err;
5573 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5574 return ret;
5576 err:
5577 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
5578 return DDERR_INVALIDDIRECTDRAWGUID;
5581 /*******************************************************************************
5582 * DirectDraw ClassFactory
5584 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5587 typedef struct
5589 /* IUnknown fields */
5590 ICOM_VFIELD(IClassFactory);
5591 DWORD ref;
5592 } IClassFactoryImpl;
5594 static HRESULT WINAPI
5595 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5596 ICOM_THIS(IClassFactoryImpl,iface);
5597 char buf[80];
5599 if (HIWORD(riid))
5600 WINE_StringFromCLSID(riid,buf);
5601 else
5602 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5603 FIXME("(%p)->(%s,%p),stub!\n",This,buf,ppobj);
5604 return E_NOINTERFACE;
5607 static ULONG WINAPI
5608 DDCF_AddRef(LPCLASSFACTORY iface) {
5609 ICOM_THIS(IClassFactoryImpl,iface);
5610 return ++(This->ref);
5613 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5614 ICOM_THIS(IClassFactoryImpl,iface);
5615 /* static class, won't be freed */
5616 return --(This->ref);
5619 static HRESULT WINAPI DDCF_CreateInstance(
5620 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5622 ICOM_THIS(IClassFactoryImpl,iface);
5623 char buf[80];
5625 WINE_StringFromCLSID(riid,buf);
5626 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
5627 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5628 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5629 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5630 /* FIXME: reuse already created DirectDraw if present? */
5631 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5633 return CLASS_E_CLASSNOTAVAILABLE;
5636 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5637 ICOM_THIS(IClassFactoryImpl,iface);
5638 FIXME("(%p)->(%d),stub!\n",This,dolock);
5639 return S_OK;
5642 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5644 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5645 DDCF_QueryInterface,
5646 DDCF_AddRef,
5647 DDCF_Release,
5648 DDCF_CreateInstance,
5649 DDCF_LockServer
5651 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5653 /*******************************************************************************
5654 * DllGetClassObject [DDRAW.13]
5655 * Retrieves class object from a DLL object
5657 * NOTES
5658 * Docs say returns STDAPI
5660 * PARAMS
5661 * rclsid [I] CLSID for the class object
5662 * riid [I] Reference to identifier of interface for class object
5663 * ppv [O] Address of variable to receive interface pointer for riid
5665 * RETURNS
5666 * Success: S_OK
5667 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5668 * E_UNEXPECTED
5670 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5672 char buf[80],xbuf[80];
5674 if (HIWORD(rclsid))
5675 WINE_StringFromCLSID(rclsid,xbuf);
5676 else
5677 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
5678 if (HIWORD(riid))
5679 WINE_StringFromCLSID(riid,buf);
5680 else
5681 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5682 WINE_StringFromCLSID(riid,xbuf);
5683 TRACE("(%p,%p,%p)\n", xbuf, buf, ppv);
5684 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5685 *ppv = (LPVOID)&DDRAW_CF;
5686 IClassFactory_AddRef((IClassFactory*)*ppv);
5687 return S_OK;
5689 FIXME("(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
5690 return CLASS_E_CLASSNOTAVAILABLE;
5694 /*******************************************************************************
5695 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5697 * RETURNS
5698 * Success: S_OK
5699 * Failure: S_FALSE
5701 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5703 FIXME("(void): stub\n");
5704 return S_FALSE;
5707 #else /* !defined(X_DISPLAY_MISSING) */
5709 #include "windef.h"
5710 #include "wtypes.h"
5712 #define DD_OK 0
5714 typedef void *LPUNKNOWN;
5715 typedef void *LPDIRECTDRAW;
5716 typedef void *LPDIRECTDRAWCLIPPER;
5717 typedef void *LPDDENUMCALLBACKA;
5718 typedef void *LPDDENUMCALLBACKEXA;
5719 typedef void *LPDDENUMCALLBACKEXW;
5720 typedef void *LPDDENUMCALLBACKW;
5722 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5724 return DD_OK;
5727 HRESULT WINAPI DirectDrawCreate(
5728 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5730 return DD_OK;
5733 HRESULT WINAPI DirectDrawCreateClipper(
5734 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5736 return DD_OK;
5739 HRESULT WINAPI DirectDrawEnumerateA(
5740 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5742 return DD_OK;
5745 HRESULT WINAPI DirectDrawEnumerateExA(
5746 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5748 return DD_OK;
5751 HRESULT WINAPI DirectDrawEnumerateExW(
5752 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5754 return DD_OK;
5757 HRESULT WINAPI DirectDrawEnumerateW(
5758 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5760 return DD_OK;
5763 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5765 return CLASS_E_CLASSNOTAVAILABLE;
5768 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5770 return DD_OK;
5773 #endif /* !defined(X_DISPLAY_MISSING) */