Cosmetics.
[wine.git] / graphics / ddraw.c
blob0b710b0495a86e4d5c88712bcd1ebe23d0c6a36a
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 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"
19 #ifndef X_DISPLAY_MISSING
21 #include "ts_xlib.h"
22 #include "ts_xutil.h"
24 #ifdef HAVE_LIBXXSHM
25 #include <sys/types.h>
26 #include <sys/ipc.h>
27 #include <sys/shm.h>
28 #include "ts_xshm.h"
29 #endif /* defined(HAVE_LIBXXSHM) */
31 #ifdef HAVE_LIBXXF86DGA
32 #include "ts_xf86dga.h"
33 #endif /* defined(HAVE_LIBXXF86DGA) */
35 #ifdef HAVE_LIBXXF86VM
36 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
37 this is a crude hack to get around it */
38 #define XMD_H
39 typedef int INT32;
40 #include "ts_xf86vmode.h"
41 #endif /* defined(HAVE_LIBXXF86VM) */
43 #include "x11drv.h"
45 #include <unistd.h>
46 #include <assert.h>
47 #include <sys/signal.h>
48 #include <fcntl.h>
49 #include <string.h>
50 #include <stdlib.h>
52 #include "winerror.h"
53 #include "gdi.h"
54 #include "heap.h"
55 #include "dc.h"
56 #include "win.h"
57 #include "miscemu.h"
58 #include "ddraw.h"
59 #include "d3d.h"
60 #include "debug.h"
61 #include "spy.h"
62 #include "message.h"
63 #include "options.h"
64 #include "monitor.h"
66 /* This for all the enumeration and creation of D3D-related objects */
67 #include "d3d_private.h"
69 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
70 #undef DIABLO_HACK
72 /* Restore signal handlers overwritten by XF86DGA
74 #define RESTORE_SIGNALS
76 /* Where do these GUIDs come from? mkuuid.
77 * They exist solely to distinguish between the targets Wine support,
78 * and should be different than any other GUIDs in existence.
80 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
81 0xe2dcb020,
82 0xdc60,
83 0x11d1,
84 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
87 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
88 0x1574a740,
89 0xdc61,
90 0x11d1,
91 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
94 static struct IDirectDrawSurface4_VTable dga_dds4vt, xlib_dds4vt;
95 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
96 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
97 static struct IDirectDraw4_VTable dga_dd4vt, xlib_dd4vt;
98 static struct IDirectDrawClipper_VTable ddclipvt;
99 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
100 static struct IDirect3D_VTable d3dvt;
101 static struct IDirect3D2_VTable d3d2vt;
103 #ifdef HAVE_LIBXXF86VM
104 static XF86VidModeModeInfo *orig_mode = NULL;
105 #endif
107 #ifdef HAVE_LIBXXSHM
108 static int XShmErrorFlag = 0;
109 #endif
111 BOOL
112 DDRAW_DGA_Available(void)
114 #ifdef HAVE_LIBXXF86DGA
115 int evbase, evret, fd;
117 if (Options.noDGA)
118 return 0;
120 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
121 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
122 /* others. --stephenc */
123 if ((fd = open("/dev/mem", O_RDWR)) != -1)
124 close(fd);
126 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
127 #else /* defined(HAVE_LIBXXF86DGA) */
128 return 0;
129 #endif /* defined(HAVE_LIBXXF86DGA) */
132 /**********************************************************************/
134 typedef struct {
135 LPVOID lpCallback;
136 LPVOID lpContext;
137 } DirectDrawEnumerateProcData;
139 /***********************************************************************
140 * DirectDrawEnumerateExA (DDRAW.*)
142 HRESULT WINAPI DirectDrawEnumerateExA(
143 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
145 TRACE(ddraw, "(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
147 if (TRACE_ON(ddraw)) {
148 DUMP(" Flags : ");
149 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
150 DUMP("DDENUM_ATTACHEDSECONDARYDEVICES ");
151 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
152 DUMP("DDENUM_DETACHEDSECONDARYDEVICES ");
153 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
154 DUMP("DDENUM_NONDISPLAYDEVICES ");
155 DUMP("\n");
158 if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
159 /* For the moment, Wine does not support any 3D only accelerators */
160 return DD_OK;
163 if (DDRAW_DGA_Available()) {
164 TRACE(ddraw, "Enumerating DGA interface\n");
165 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
166 return DD_OK;
169 TRACE(ddraw, "Enumerating Xlib interface\n");
170 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
171 return DD_OK;
173 TRACE(ddraw, "Enumerating Default interface\n");
174 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
175 return DD_OK;
177 return DD_OK;
180 /***********************************************************************
181 * DirectDrawEnumerateExW (DDRAW.*)
184 static BOOL CALLBACK DirectDrawEnumerateExProcW(
185 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
186 LPVOID lpContext, HMONITOR hm)
188 DirectDrawEnumerateProcData *pEPD =
189 (DirectDrawEnumerateProcData *) lpContext;
190 LPWSTR lpDriverDescriptionW =
191 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
192 LPWSTR lpDriverNameW =
193 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
195 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
196 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
198 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
199 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
201 return bResult;
204 /**********************************************************************/
206 HRESULT WINAPI DirectDrawEnumerateExW(
207 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
209 DirectDrawEnumerateProcData epd;
210 epd.lpCallback = lpCallback;
211 epd.lpContext = lpContext;
213 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
214 (LPVOID) &epd, 0);
217 /***********************************************************************
218 * DirectDrawEnumerateA (DDRAW.*)
221 static BOOL CALLBACK DirectDrawEnumerateProcA(
222 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
223 LPVOID lpContext, HMONITOR hm)
225 DirectDrawEnumerateProcData *pEPD =
226 (DirectDrawEnumerateProcData *) lpContext;
228 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
229 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
232 /**********************************************************************/
234 HRESULT WINAPI DirectDrawEnumerateA(
235 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
237 DirectDrawEnumerateProcData epd;
238 epd.lpCallback = lpCallback;
239 epd.lpContext = lpContext;
241 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
242 (LPVOID) &epd, 0);
245 /***********************************************************************
246 * DirectDrawEnumerateW (DDRAW.*)
249 static BOOL WINAPI DirectDrawEnumerateProcW(
250 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
251 LPVOID lpContext, HMONITOR hm)
253 DirectDrawEnumerateProcData *pEPD =
254 (DirectDrawEnumerateProcData *) lpContext;
256 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
257 lpGUID, lpDriverDescription, lpDriverName,
258 pEPD->lpContext);
261 /**********************************************************************/
263 HRESULT WINAPI DirectDrawEnumerateW(
264 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
266 DirectDrawEnumerateProcData epd;
267 epd.lpCallback = lpCallback;
268 epd.lpContext = lpContext;
270 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
271 (LPVOID) &epd, 0);
274 /***********************************************************************
275 * DSoundHelp (DDRAW.?)
278 /* What is this doing here? */
279 HRESULT WINAPI
280 DSoundHelp(DWORD x,DWORD y,DWORD z) {
281 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
282 return 0;
285 /******************************************************************************
286 * internal helper functions
288 static void _dump_DDBLTFX(DWORD flagmask) {
289 int i;
290 const struct {
291 DWORD mask;
292 char *name;
293 } flags[] = {
294 #define FE(x) { x, #x},
295 FE(DDBLTFX_ARITHSTRETCHY)
296 FE(DDBLTFX_MIRRORLEFTRIGHT)
297 FE(DDBLTFX_MIRRORUPDOWN)
298 FE(DDBLTFX_NOTEARING)
299 FE(DDBLTFX_ROTATE180)
300 FE(DDBLTFX_ROTATE270)
301 FE(DDBLTFX_ROTATE90)
302 FE(DDBLTFX_ZBUFFERRANGE)
303 FE(DDBLTFX_ZBUFFERBASEDEST)
305 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
306 if (flags[i].mask & flagmask) {
307 DUMP("%s ",flags[i].name);
310 DUMP("\n");
314 static void _dump_DDBLTFAST(DWORD flagmask) {
315 int i;
316 const struct {
317 DWORD mask;
318 char *name;
319 } flags[] = {
320 #define FE(x) { x, #x},
321 FE(DDBLTFAST_NOCOLORKEY)
322 FE(DDBLTFAST_SRCCOLORKEY)
323 FE(DDBLTFAST_DESTCOLORKEY)
324 FE(DDBLTFAST_WAIT)
326 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
327 if (flags[i].mask & flagmask)
328 DUMP("%s ",flags[i].name);
329 DUMP("\n");
332 static void _dump_DDBLT(DWORD flagmask) {
333 int i;
334 const struct {
335 DWORD mask;
336 char *name;
337 } flags[] = {
338 #define FE(x) { x, #x},
339 FE(DDBLT_ALPHADEST)
340 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
341 FE(DDBLT_ALPHADESTNEG)
342 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
343 FE(DDBLT_ALPHAEDGEBLEND)
344 FE(DDBLT_ALPHASRC)
345 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
346 FE(DDBLT_ALPHASRCNEG)
347 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
348 FE(DDBLT_ASYNC)
349 FE(DDBLT_COLORFILL)
350 FE(DDBLT_DDFX)
351 FE(DDBLT_DDROPS)
352 FE(DDBLT_KEYDEST)
353 FE(DDBLT_KEYDESTOVERRIDE)
354 FE(DDBLT_KEYSRC)
355 FE(DDBLT_KEYSRCOVERRIDE)
356 FE(DDBLT_ROP)
357 FE(DDBLT_ROTATIONANGLE)
358 FE(DDBLT_ZBUFFER)
359 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
360 FE(DDBLT_ZBUFFERDESTOVERRIDE)
361 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
362 FE(DDBLT_ZBUFFERSRCOVERRIDE)
363 FE(DDBLT_WAIT)
364 FE(DDBLT_DEPTHFILL)
366 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
367 if (flags[i].mask & flagmask)
368 DUMP("%s ",flags[i].name);
369 DUMP("\n");
372 static void _dump_DDSCAPS(DWORD flagmask) {
373 int i;
374 const struct {
375 DWORD mask;
376 char *name;
377 } flags[] = {
378 #define FE(x) { x, #x},
379 FE(DDSCAPS_RESERVED1)
380 FE(DDSCAPS_ALPHA)
381 FE(DDSCAPS_BACKBUFFER)
382 FE(DDSCAPS_COMPLEX)
383 FE(DDSCAPS_FLIP)
384 FE(DDSCAPS_FRONTBUFFER)
385 FE(DDSCAPS_OFFSCREENPLAIN)
386 FE(DDSCAPS_OVERLAY)
387 FE(DDSCAPS_PALETTE)
388 FE(DDSCAPS_PRIMARYSURFACE)
389 FE(DDSCAPS_PRIMARYSURFACELEFT)
390 FE(DDSCAPS_SYSTEMMEMORY)
391 FE(DDSCAPS_TEXTURE)
392 FE(DDSCAPS_3DDEVICE)
393 FE(DDSCAPS_VIDEOMEMORY)
394 FE(DDSCAPS_VISIBLE)
395 FE(DDSCAPS_WRITEONLY)
396 FE(DDSCAPS_ZBUFFER)
397 FE(DDSCAPS_OWNDC)
398 FE(DDSCAPS_LIVEVIDEO)
399 FE(DDSCAPS_HWCODEC)
400 FE(DDSCAPS_MODEX)
401 FE(DDSCAPS_MIPMAP)
402 FE(DDSCAPS_RESERVED2)
403 FE(DDSCAPS_ALLOCONLOAD)
404 FE(DDSCAPS_VIDEOPORT)
405 FE(DDSCAPS_LOCALVIDMEM)
406 FE(DDSCAPS_NONLOCALVIDMEM)
407 FE(DDSCAPS_STANDARDVGAMODE)
408 FE(DDSCAPS_OPTIMIZED)
410 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
411 if (flags[i].mask & flagmask)
412 DUMP("%s ",flags[i].name);
413 DUMP("\n");
416 static void _dump_DDSD(DWORD flagmask) {
417 int i;
418 const struct {
419 DWORD mask;
420 char *name;
421 } flags[] = {
422 FE(DDSD_CAPS)
423 FE(DDSD_HEIGHT)
424 FE(DDSD_WIDTH)
425 FE(DDSD_PITCH)
426 FE(DDSD_BACKBUFFERCOUNT)
427 FE(DDSD_ZBUFFERBITDEPTH)
428 FE(DDSD_ALPHABITDEPTH)
429 FE(DDSD_PIXELFORMAT)
430 FE(DDSD_CKDESTOVERLAY)
431 FE(DDSD_CKDESTBLT)
432 FE(DDSD_CKSRCOVERLAY)
433 FE(DDSD_CKSRCBLT)
434 FE(DDSD_MIPMAPCOUNT)
435 FE(DDSD_REFRESHRATE)
436 FE(DDSD_LINEARSIZE)
437 FE(DDSD_LPSURFACE)
439 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
440 if (flags[i].mask & flagmask)
441 DUMP("%s ",flags[i].name);
442 DUMP("\n");
445 static void _dump_DDCOLORKEY(DWORD flagmask) {
446 int i;
447 const struct {
448 DWORD mask;
449 char *name;
450 } flags[] = {
451 #define FE(x) { x, #x},
452 FE(DDPF_ALPHAPIXELS)
453 FE(DDPF_ALPHA)
454 FE(DDPF_FOURCC)
455 FE(DDPF_PALETTEINDEXED4)
456 FE(DDPF_PALETTEINDEXEDTO8)
457 FE(DDPF_PALETTEINDEXED8)
458 FE(DDPF_RGB)
459 FE(DDPF_COMPRESSED)
460 FE(DDPF_RGBTOYUV)
461 FE(DDPF_YUV)
462 FE(DDPF_ZBUFFER)
463 FE(DDPF_PALETTEINDEXED1)
464 FE(DDPF_PALETTEINDEXED2)
465 FE(DDPF_ZPIXELS)
467 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
468 if (flags[i].mask & flagmask)
469 DUMP("%s ",flags[i].name);
470 DUMP("\n");
473 static void _dump_paletteformat(DWORD dwFlags) {
474 int i;
475 const struct {
476 DWORD mask;
477 char *name;
478 } flags[] = {
479 #define FE(x) { x, #x},
480 FE(DDPCAPS_4BIT)
481 FE(DDPCAPS_8BITENTRIES)
482 FE(DDPCAPS_8BIT)
483 FE(DDPCAPS_INITIALIZE)
484 FE(DDPCAPS_PRIMARYSURFACE)
485 FE(DDPCAPS_PRIMARYSURFACELEFT)
486 FE(DDPCAPS_ALLOW256)
487 FE(DDPCAPS_VSYNC)
488 FE(DDPCAPS_1BIT)
489 FE(DDPCAPS_2BIT)
490 FE(DDPCAPS_ALPHA)
492 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
493 if (flags[i].mask & dwFlags)
494 DUMP("%s ",flags[i].name);
495 DUMP("\n");
498 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
499 DUMP("Size : %ld\n", pf->dwSize);
500 if (pf->dwFlags)
501 _dump_DDCOLORKEY(pf->dwFlags);
502 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
503 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
504 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
505 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
508 /******************************************************************************
509 * IDirectDrawSurface methods
511 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
512 * DDS and DDS2 use those functions. (Function calls did not change (except
513 * using different DirectDrawSurfaceX version), just added flags and functions)
515 static HRESULT WINAPI IDirectDrawSurface4_Lock(
516 LPDIRECTDRAWSURFACE4 this,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
518 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
519 this,lprect,lpddsd,flags,(DWORD)hnd);
520 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
521 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
522 this,lprect,lpddsd,flags,(DWORD)hnd);
524 /* First, copy the Surface description */
525 *lpddsd = this->s.surface_desc;
526 TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
527 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
529 /* If asked only for a part, change the surface pointer */
530 if (lprect) {
531 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
532 lprect->top,lprect->left,lprect->bottom,lprect->right
534 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
535 (lprect->top*this->s.surface_desc.lPitch) +
536 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
537 } else {
538 assert(this->s.surface_desc.y.lpSurface);
540 return DD_OK;
543 static HRESULT WINAPI DGA_IDirectDrawSurface4_Unlock(
544 LPDIRECTDRAWSURFACE4 this,LPVOID surface
546 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
547 return DD_OK;
550 static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4 this) {
551 if (this->s.ddraw->d.pixel_convert != NULL)
552 this->s.ddraw->d.pixel_convert(this->s.surface_desc.y.lpSurface,
553 this->t.xlib.image->data,
554 this->s.surface_desc.dwWidth,
555 this->s.surface_desc.dwHeight,
556 this->s.surface_desc.lPitch,
557 this->s.palette);
559 #ifdef HAVE_LIBXXSHM
560 if (this->s.ddraw->e.xlib.xshm_active)
561 TSXShmPutImage(display,
562 this->s.ddraw->d.drawable,
563 DefaultGCOfScreen(X11DRV_GetXScreen()),
564 this->t.xlib.image,
565 0, 0, 0, 0,
566 this->t.xlib.image->width,
567 this->t.xlib.image->height,
568 False);
569 else
570 #endif
571 TSXPutImage( display,
572 this->s.ddraw->d.drawable,
573 DefaultGCOfScreen(X11DRV_GetXScreen()),
574 this->t.xlib.image,
575 0, 0, 0, 0,
576 this->t.xlib.image->width,
577 this->t.xlib.image->height);
580 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Unlock(
581 LPDIRECTDRAWSURFACE4 this,LPVOID surface)
583 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
585 if (!this->s.ddraw->d.paintable)
586 return DD_OK;
588 /* Only redraw the screen when unlocking the buffer that is on screen */
589 if ((this->t.xlib.image != NULL) &&
590 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
591 Xlib_copy_surface_on_screen(this);
593 if (this->s.palette && this->s.palette->cm)
594 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
597 return DD_OK;
600 static HRESULT WINAPI DGA_IDirectDrawSurface4_Flip(
601 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
603 #ifdef HAVE_LIBXXF86DGA
604 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
605 if (!flipto) {
606 if (this->s.backbuffer)
607 flipto = this->s.backbuffer;
608 else
609 flipto = this;
611 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
613 if (flipto->s.palette && flipto->s.palette->cm) {
614 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
616 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
618 if (flipto!=this) {
619 int tmp;
620 LPVOID ptmp;
622 tmp = this->t.dga.fb_height;
623 this->t.dga.fb_height = flipto->t.dga.fb_height;
624 flipto->t.dga.fb_height = tmp;
626 ptmp = this->s.surface_desc.y.lpSurface;
627 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
628 flipto->s.surface_desc.y.lpSurface = ptmp;
630 return DD_OK;
631 #else /* defined(HAVE_LIBXXF86DGA) */
632 return E_UNEXPECTED;
633 #endif /* defined(HAVE_LIBXXF86DGA) */
636 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Flip(
637 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
639 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
640 if (!this->s.ddraw->d.paintable)
641 return DD_OK;
643 if (!flipto) {
644 if (this->s.backbuffer)
645 flipto = this->s.backbuffer;
646 else
647 flipto = this;
650 Xlib_copy_surface_on_screen(this);
652 if (flipto->s.palette && flipto->s.palette->cm) {
653 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,flipto->s.palette->cm);
655 if (flipto!=this) {
656 XImage *tmp;
657 LPVOID *surf;
658 tmp = this->t.xlib.image;
659 this->t.xlib.image = flipto->t.xlib.image;
660 flipto->t.xlib.image = tmp;
661 surf = this->s.surface_desc.y.lpSurface;
662 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
663 flipto->s.surface_desc.y.lpSurface = surf;
665 return DD_OK;
669 /* The IDirectDrawSurface4::SetPalette method attaches the specified
670 * DirectDrawPalette object to a surface. The surface uses this palette for all
671 * subsequent operations. The palette change takes place immediately.
673 static HRESULT WINAPI Xlib_IDirectDrawSurface4_SetPalette(
674 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
676 int i;
677 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
679 if (pal == NULL) {
680 if( this->s.palette != NULL )
681 this->s.palette->lpvtbl->fnRelease( this->s.palette );
682 this->s.palette = pal;
684 return DD_OK;
687 if( !(pal->cm) && (this->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
689 pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,
690 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
692 if (!Options.managed)
693 TSXInstallColormap(display,pal->cm);
695 for (i=0;i<256;i++) {
696 XColor xc;
698 xc.red = pal->palents[i].peRed<<8;
699 xc.blue = pal->palents[i].peBlue<<8;
700 xc.green = pal->palents[i].peGreen<<8;
701 xc.flags = DoRed|DoBlue|DoGreen;
702 xc.pixel = i;
703 TSXStoreColor(display,pal->cm,&xc);
705 TSXInstallColormap(display,pal->cm);
708 /* According to spec, we are only supposed to
709 * AddRef if this is not the same palette.
711 if( this->s.palette != pal )
713 if( pal != NULL )
714 pal->lpvtbl->fnAddRef( pal );
715 if( this->s.palette != NULL )
716 this->s.palette->lpvtbl->fnRelease( this->s.palette );
717 this->s.palette = pal;
719 /* I think that we need to attach it to all backbuffers...*/
720 if( this->s.backbuffer ) {
721 if( this->s.backbuffer->s.palette )
722 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
723 this->s.backbuffer->s.palette );
724 this->s.backbuffer->s.palette = pal;
725 if( pal )
726 pal->lpvtbl->fnAddRef( pal );
728 /* Perform the refresh */
729 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
731 return DD_OK;
734 static HRESULT WINAPI DGA_IDirectDrawSurface4_SetPalette(
735 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
737 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
738 #ifdef HAVE_LIBXXF86DGA
739 /* According to spec, we are only supposed to
740 * AddRef if this is not the same palette.
742 if( this->s.palette != pal )
744 if( pal != NULL )
745 pal->lpvtbl->fnAddRef( pal );
746 if( this->s.palette != NULL )
747 this->s.palette->lpvtbl->fnRelease( this->s.palette );
748 this->s.palette = pal;
750 /* I think that we need to attach it to all backbuffers...*/
751 if( this->s.backbuffer ) {
752 if( this->s.backbuffer->s.palette )
753 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
754 this->s.backbuffer->s.palette = pal;
755 if( pal ) pal->lpvtbl->fnAddRef( pal );
757 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
759 return DD_OK;
760 #else /* defined(HAVE_LIBXXF86DGA) */
761 return E_UNEXPECTED;
762 #endif /* defined(HAVE_LIBXXF86DGA) */
767 static HRESULT WINAPI IDirectDrawSurface4_Blt(
768 LPDIRECTDRAWSURFACE4 this,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
770 RECT xdst,xsrc;
771 DDSURFACEDESC ddesc,sdesc;
772 int i,j;
774 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
775 this,rdst,src,rsrc,dwFlags,lpbltfx);
777 if (src != NULL)
778 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
779 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
781 if (TRACE_ON(ddraw)) {
782 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
783 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
784 TRACE(ddraw,"\tflags: "); _dump_DDBLT(dwFlags);
785 if (dwFlags & DDBLT_DDFX) {
786 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
790 if (rdst) {
791 memcpy(&xdst,rdst,sizeof(xdst));
792 } else {
793 xdst.top = 0;
794 xdst.bottom = ddesc.dwHeight;
795 xdst.left = 0;
796 xdst.right = ddesc.dwWidth;
799 if (rsrc) {
800 memcpy(&xsrc,rsrc,sizeof(xsrc));
801 } else {
802 if (src) {
803 xsrc.top = 0;
804 xsrc.bottom = sdesc.dwHeight;
805 xsrc.left = 0;
806 xsrc.right = sdesc.dwWidth;
807 } else {
808 memset(&xsrc,0,sizeof(xsrc));
812 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
814 /* First, all the 'source-less' blits */
815 if (dwFlags & DDBLT_COLORFILL) {
816 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
817 LPBYTE xline,xpixel;
819 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
820 for (i=xdst.top;i<xdst.bottom;i++) {
821 xpixel = xline+bpp*xdst.left;
823 for (j=xdst.left;j<xdst.right;j++) {
824 /* FIXME: this only works on little endian
825 * architectures, where DWORD starts with low
826 * byte first!
828 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
829 xpixel += bpp;
831 xline += ddesc.lPitch;
833 dwFlags &= ~(DDBLT_COLORFILL);
836 if (dwFlags & DDBLT_DEPTHFILL) {
837 #ifdef HAVE_MESAGL
838 GLboolean ztest;
840 /* Clears the screen */
841 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
842 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
843 glGetBooleanv(GL_DEPTH_TEST, &ztest);
844 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
845 glClear(GL_DEPTH_BUFFER_BIT);
846 glDepthMask(ztest);
848 dwFlags &= ~(DDBLT_DEPTHFILL);
849 #endif HAVE_MESAGL
852 if (!src) {
853 if (dwFlags) {
854 TRACE(ddraw,"\t(src=NULL):Unsupported flags: "); _dump_DDBLT(dwFlags);
856 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
857 return DD_OK;
860 /* Now the 'with source' blits */
862 /* Standard 'full-surface' blit without special effects */
863 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
864 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
865 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
866 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
867 !dwFlags
869 memcpy(ddesc.y.lpSurface,
870 sdesc.y.lpSurface,
871 ddesc.dwHeight * ddesc.lPitch);
872 } else {
873 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
874 int srcheight = xsrc.bottom - xsrc.top;
875 int srcwidth = xsrc.right - xsrc.left;
876 int dstheight = xdst.bottom - xdst.top;
877 int dstwidth = xdst.right - xdst.left;
878 int width = (xsrc.right - xsrc.left) * bpp;
879 int h;
881 /* Sanity check for rectangle sizes */
882 if ((srcheight != dstheight) || (srcwidth != dstwidth)) {
883 int x, y;
885 /* I think we should do a Blit with 'stretching' here....
886 Tomb Raider II uses this to display the background during the menu selection
887 when the screen resolution is != than 640x480 */
888 TRACE(ddraw, "Blt with stretching\n");
890 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
891 if (bpp == 1) {
892 /* In this case, we cannot do any anti-aliasing */
893 if(dwFlags & DDBLT_KEYSRC) {
894 for (y = xdst.top; y < xdst.bottom; y++) {
895 for (x = xdst.left; x < xdst.right; x++) {
896 double sx, sy;
897 unsigned char tmp;
898 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
899 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
901 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
902 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
904 tmp = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
906 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
907 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
908 dbuf[(y * ddesc.lPitch) + x] = tmp;
911 } else {
912 for (y = xdst.top; y < xdst.bottom; y++) {
913 for (x = xdst.left; x < xdst.right; x++) {
914 double sx, sy;
915 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
916 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
918 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
919 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
921 dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
925 } else {
926 FIXME(ddraw, "Not done yet for depth != 8\n");
928 } else {
929 /* Same size => fast blit */
930 if (dwFlags & DDBLT_KEYSRC) {
931 switch (bpp) {
932 case 1: {
933 unsigned char tmp,*psrc,*pdst;
934 int h,i;
936 for (h = 0; h < srcheight; h++) {
937 psrc=sdesc.y.lpSurface +
938 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
939 pdst=ddesc.y.lpSurface +
940 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
941 for(i=0;i<srcwidth;i++) {
942 tmp=*(psrc + i);
943 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
944 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
945 *(pdst + i)=tmp;
948 dwFlags&=~(DDBLT_KEYSRC);
949 } break;
951 case 2: {
952 unsigned short tmp,*psrc,*pdst;
953 int h,i;
955 for (h = 0; h < srcheight; h++) {
956 psrc=sdesc.y.lpSurface +
957 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
958 pdst=ddesc.y.lpSurface +
959 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
960 for(i=0;i<srcwidth;i++) {
961 tmp=*(psrc + i);
962 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
963 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
964 *(pdst + i)=tmp;
967 dwFlags&=~(DDBLT_KEYSRC);
968 } break;
970 default:
971 FIXME(ddraw, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
973 } else {
974 /* Non-stretching Blt without color keying */
975 for (h = 0; h < srcheight; h++) {
976 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
977 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
978 width);
984 if (dwFlags && FIXME_ON(ddraw)) {
985 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
988 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
989 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
991 return DD_OK;
994 static HRESULT WINAPI IDirectDrawSurface4_BltFast(
995 LPDIRECTDRAWSURFACE4 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
997 int i,bpp,w,h;
998 DDSURFACEDESC ddesc,sdesc;
1000 if (1 || TRACE_ON(ddraw)) {
1001 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1002 this,dstx,dsty,src,rsrc,trans
1004 FIXME(ddraw," trans:");
1005 if (FIXME_ON(ddraw))
1006 _dump_DDBLTFAST(trans);
1007 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1009 /* We need to lock the surfaces, or we won't get refreshes when done. */
1010 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1011 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1012 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
1013 h=rsrc->bottom-rsrc->top;
1014 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1015 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1016 if (h<0) h=0;
1017 w=rsrc->right-rsrc->left;
1018 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1019 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1020 if (w<0) w=0;
1022 for (i=0;i<h;i++) {
1023 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
1024 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
1025 w*bpp
1028 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
1029 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
1030 return DD_OK;
1033 static HRESULT WINAPI IDirectDrawSurface4_BltBatch(
1034 LPDIRECTDRAWSURFACE4 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1036 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1037 this,ddbltbatch,x,y
1039 return DD_OK;
1042 static HRESULT WINAPI IDirectDrawSurface4_GetCaps(
1043 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS caps
1045 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
1046 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1047 return DD_OK;
1050 static HRESULT WINAPI IDirectDrawSurface4_GetSurfaceDesc(
1051 LPDIRECTDRAWSURFACE4 this,LPDDSURFACEDESC ddsd
1052 ) {
1053 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
1054 this,ddsd);
1056 /* Simply copy the surface description stored in the object */
1057 *ddsd = this->s.surface_desc;
1059 if (TRACE_ON(ddraw)) {
1060 DUMP(" flags: ");
1061 _dump_DDSD(ddsd->dwFlags);
1062 if (ddsd->dwFlags & DDSD_CAPS) {
1063 DUMP(" caps: ");
1064 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
1066 if (ddsd->dwFlags & DDSD_PIXELFORMAT) {
1067 DUMP(" pixel format : \n");
1068 _dump_pixelformat(&(ddsd->ddpfPixelFormat));
1072 return DD_OK;
1075 static ULONG WINAPI IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4 this) {
1076 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1078 return ++(this->ref);
1081 static ULONG WINAPI DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1082 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1084 #ifdef HAVE_LIBXXF86DGA
1085 if (!--(this->ref)) {
1086 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1087 /* clear out of surface list */
1088 if (this->t.dga.fb_height == -1) {
1089 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1090 } else {
1091 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
1094 /* Free the backbuffer */
1095 if (this->s.backbuffer)
1096 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1098 HeapFree(GetProcessHeap(),0,this);
1099 return 0;
1101 #endif /* defined(HAVE_LIBXXF86DGA) */
1102 return this->ref;
1105 static ULONG WINAPI Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1106 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1108 if (!--(this->ref)) {
1109 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1111 if( this->s.backbuffer )
1112 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1114 if (this->t.xlib.image != NULL) {
1115 if (this->s.ddraw->d.pixel_convert != NULL) {
1116 /* In pixel conversion mode, there are two buffers to release... */
1117 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1119 #ifdef HAVE_LIBXXSHM
1120 if (this->s.ddraw->e.xlib.xshm_active) {
1121 TSXShmDetach(display, &(this->t.xlib.shminfo));
1122 TSXDestroyImage(this->t.xlib.image);
1123 shmdt(this->t.xlib.shminfo.shmaddr);
1124 } else {
1125 #endif
1126 HeapFree(GetProcessHeap(),0,this->t.xlib.image->data);
1127 this->t.xlib.image->data = NULL;
1128 TSXDestroyImage(this->t.xlib.image);
1129 #ifdef HAVE_LIBXXSHM
1131 #endif
1133 } else {
1134 this->t.xlib.image->data = NULL;
1136 #ifdef HAVE_LIBXXSHM
1137 if (this->s.ddraw->e.xlib.xshm_active) {
1138 TSXShmDetach(display, &(this->t.xlib.shminfo));
1139 TSXDestroyImage(this->t.xlib.image);
1140 shmdt(this->t.xlib.shminfo.shmaddr);
1141 } else {
1142 #endif
1143 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1144 TSXDestroyImage(this->t.xlib.image);
1145 #ifdef HAVE_LIBXXSHM
1147 #endif
1150 this->t.xlib.image = 0;
1151 } else {
1152 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1155 if (this->s.palette)
1156 this->s.palette->lpvtbl->fnRelease(this->s.palette);
1158 HeapFree(GetProcessHeap(),0,this);
1159 return 0;
1162 return this->ref;
1165 static HRESULT WINAPI IDirectDrawSurface4_GetAttachedSurface(
1166 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1168 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1169 this, lpddsd, lpdsf);
1171 if (TRACE_ON(ddraw)) {
1172 TRACE(ddraw," caps ");
1173 _dump_DDSCAPS(lpddsd->dwCaps);
1176 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1177 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1178 return E_FAIL;
1181 /* FIXME: should handle more than one backbuffer */
1182 *lpdsf = this->s.backbuffer;
1184 if( this->s.backbuffer )
1185 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
1187 return DD_OK;
1190 static HRESULT WINAPI IDirectDrawSurface4_Initialize(
1191 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1193 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
1195 return DDERR_ALREADYINITIALIZED;
1198 static HRESULT WINAPI IDirectDrawSurface4_GetPixelFormat(
1199 LPDIRECTDRAWSURFACE4 this,LPDDPIXELFORMAT pf
1201 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
1203 *pf = this->s.surface_desc.ddpfPixelFormat;
1205 return DD_OK;
1208 static HRESULT WINAPI IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4 this,DWORD dwFlags) {
1209 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
1210 return DD_OK;
1213 static HRESULT WINAPI IDirectDrawSurface4_GetOverlayPosition(
1214 LPDIRECTDRAWSURFACE4 this,LPLONG x1,LPLONG x2
1216 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
1217 return DD_OK;
1220 static HRESULT WINAPI IDirectDrawSurface4_SetClipper(
1221 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWCLIPPER clipper
1223 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
1224 return DD_OK;
1227 static HRESULT WINAPI IDirectDrawSurface4_AddAttachedSurface(
1228 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 surf
1230 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
1232 this->lpvtbl->fnAddRef(this);
1234 /* This hack will be enough for the moment */
1235 if (this->s.backbuffer == NULL)
1236 this->s.backbuffer = surf;
1237 return DD_OK;
1240 static HRESULT WINAPI IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4 this,HDC* lphdc) {
1241 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
1242 *lphdc = BeginPaint(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1243 return DD_OK;
1246 static HRESULT WINAPI IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4 this,HDC hdc) {
1247 DDSURFACEDESC desc;
1248 DWORD x, y;
1250 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
1251 EndPaint(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1253 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1254 I fill it with 'dummy' values to have something on the screen */
1255 this->lpvtbl->fnLock(this,NULL,&desc,0,0);
1256 for (y = 0; y < desc.dwHeight; y++) {
1257 for (x = 0; x < desc.dwWidth; x++) {
1258 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) this + x + y;
1261 this->lpvtbl->fnUnlock(this,NULL);
1263 return DD_OK;
1267 static HRESULT WINAPI IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4 this,REFIID refiid,LPVOID *obj) {
1268 char xrefiid[50];
1270 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1271 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1273 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1274 * the same interface. And IUnknown does that too of course.
1276 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1277 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1278 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1279 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1280 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1282 *obj = this;
1283 this->lpvtbl->fnAddRef(this);
1285 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1287 return S_OK;
1289 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1291 /* Texture interface */
1292 *obj = d3dtexture2_create(this);
1293 this->lpvtbl->fnAddRef(this);
1295 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1297 return S_OK;
1299 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1301 /* Texture interface */
1302 *obj = d3dtexture_create(this);
1303 this->lpvtbl->fnAddRef(this);
1305 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1307 return S_OK;
1309 else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj))
1311 /* It is the OpenGL Direct3D Device */
1312 this->lpvtbl->fnAddRef(this);
1314 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1316 return S_OK;
1319 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1320 return OLE_E_ENUM_NOMORE;
1323 static HRESULT WINAPI IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4 this) {
1324 TRACE(ddraw,"(%p)->(), stub!\n",this);
1325 return DD_OK; /* hmm */
1328 static HRESULT WINAPI IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1329 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
1330 return DD_OK;
1333 static HRESULT WINAPI IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4 this) {
1334 FIXME(ddraw,"(%p)->(),stub!\n",this);
1335 return DD_OK;
1338 static HRESULT WINAPI IDirectDrawSurface4_SetColorKey(
1339 LPDIRECTDRAWSURFACE4 this, DWORD dwFlags, LPDDCOLORKEY ckey )
1341 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);
1343 if( dwFlags & DDCKEY_SRCBLT )
1345 dwFlags &= ~DDCKEY_SRCBLT;
1346 this->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1347 memcpy( &(this->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1350 if( dwFlags & DDCKEY_DESTBLT )
1352 dwFlags &= ~DDCKEY_DESTBLT;
1353 this->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1354 memcpy( &(this->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1357 if( dwFlags & DDCKEY_SRCOVERLAY )
1359 dwFlags &= ~DDCKEY_SRCOVERLAY;
1360 this->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1361 memcpy( &(this->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1364 if( dwFlags & DDCKEY_DESTOVERLAY )
1366 dwFlags &= ~DDCKEY_DESTOVERLAY;
1367 this->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1368 memcpy( &(this->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1371 if( dwFlags )
1373 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1376 return DD_OK;
1380 static HRESULT WINAPI IDirectDrawSurface4_AddOverlayDirtyRect(
1381 LPDIRECTDRAWSURFACE4 this,
1382 LPRECT lpRect )
1384 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
1386 return DD_OK;
1389 static HRESULT WINAPI IDirectDrawSurface4_DeleteAttachedSurface(
1390 LPDIRECTDRAWSURFACE4 this,
1391 DWORD dwFlags,
1392 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1394 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1396 return DD_OK;
1399 static HRESULT WINAPI IDirectDrawSurface4_EnumOverlayZOrders(
1400 LPDIRECTDRAWSURFACE4 this,
1401 DWORD dwFlags,
1402 LPVOID lpContext,
1403 LPDDENUMSURFACESCALLBACK lpfnCallback )
1405 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1406 lpContext, lpfnCallback );
1408 return DD_OK;
1411 static HRESULT WINAPI IDirectDrawSurface4_GetClipper(
1412 LPDIRECTDRAWSURFACE4 this,
1413 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1415 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1417 return DD_OK;
1420 static HRESULT WINAPI IDirectDrawSurface4_GetColorKey(
1421 LPDIRECTDRAWSURFACE4 this,
1422 DWORD dwFlags,
1423 LPDDCOLORKEY lpDDColorKey )
1425 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);
1427 if( dwFlags & DDCKEY_SRCBLT ) {
1428 dwFlags &= ~DDCKEY_SRCBLT;
1429 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1432 if( dwFlags & DDCKEY_DESTBLT )
1434 dwFlags &= ~DDCKEY_DESTBLT;
1435 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1438 if( dwFlags & DDCKEY_SRCOVERLAY )
1440 dwFlags &= ~DDCKEY_SRCOVERLAY;
1441 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1444 if( dwFlags & DDCKEY_DESTOVERLAY )
1446 dwFlags &= ~DDCKEY_DESTOVERLAY;
1447 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1450 if( dwFlags )
1452 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1455 return DD_OK;
1458 static HRESULT WINAPI IDirectDrawSurface4_GetFlipStatus(
1459 LPDIRECTDRAWSURFACE4 this,
1460 DWORD dwFlags )
1462 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1464 return DD_OK;
1467 static HRESULT WINAPI IDirectDrawSurface4_GetPalette(
1468 LPDIRECTDRAWSURFACE4 this,
1469 LPDIRECTDRAWPALETTE* lplpDDPalette )
1471 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1473 return DD_OK;
1476 static HRESULT WINAPI IDirectDrawSurface4_SetOverlayPosition(
1477 LPDIRECTDRAWSURFACE4 this,
1478 LONG lX,
1479 LONG lY)
1481 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1483 return DD_OK;
1486 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlay(
1487 LPDIRECTDRAWSURFACE4 this,
1488 LPRECT lpSrcRect,
1489 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1490 LPRECT lpDestRect,
1491 DWORD dwFlags,
1492 LPDDOVERLAYFX lpDDOverlayFx )
1494 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1495 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1497 return DD_OK;
1500 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayDisplay(
1501 LPDIRECTDRAWSURFACE4 this,
1502 DWORD dwFlags )
1504 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1506 return DD_OK;
1509 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayZOrder(
1510 LPDIRECTDRAWSURFACE4 this,
1511 DWORD dwFlags,
1512 LPDIRECTDRAWSURFACE4 lpDDSReference )
1514 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1516 return DD_OK;
1519 static HRESULT WINAPI IDirectDrawSurface4_GetDDInterface(
1520 LPDIRECTDRAWSURFACE4 this,
1521 LPVOID* lplpDD )
1523 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1525 /* Not sure about that... */
1526 *lplpDD = (void *) this->s.ddraw;
1528 return DD_OK;
1531 static HRESULT WINAPI IDirectDrawSurface4_PageLock(
1532 LPDIRECTDRAWSURFACE4 this,
1533 DWORD dwFlags )
1535 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1537 return DD_OK;
1540 static HRESULT WINAPI IDirectDrawSurface4_PageUnlock(
1541 LPDIRECTDRAWSURFACE4 this,
1542 DWORD dwFlags )
1544 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1546 return DD_OK;
1549 static HRESULT WINAPI IDirectDrawSurface4_SetSurfaceDesc(
1550 LPDIRECTDRAWSURFACE4 this,
1551 LPDDSURFACEDESC lpDDSD,
1552 DWORD dwFlags )
1554 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1556 return DD_OK;
1559 static HRESULT WINAPI IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4 this,
1560 REFGUID guidTag,
1561 LPVOID lpData,
1562 DWORD cbSize,
1563 DWORD dwFlags) {
1564 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag, lpData, cbSize, dwFlags);
1566 return DD_OK;
1569 static HRESULT WINAPI IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4 this,
1570 REFGUID guidTag,
1571 LPVOID lpBuffer,
1572 LPDWORD lpcbBufferSize) {
1573 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", this, guidTag, lpBuffer, lpcbBufferSize);
1575 return DD_OK;
1578 static HRESULT WINAPI IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4 this,
1579 REFGUID guidTag) {
1580 FIXME(ddraw, "(%p)->(%p)\n", this, guidTag);
1582 return DD_OK;
1585 static HRESULT WINAPI IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4 this,
1586 LPDWORD lpValue) {
1587 FIXME(ddraw, "(%p)->(%p)\n", this, lpValue);
1589 return DD_OK;
1592 static HRESULT WINAPI IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 this) {
1593 FIXME(ddraw, "(%p)\n", this);
1595 return DD_OK;
1598 static struct IDirectDrawSurface4_VTable dga_dds4vt = {
1599 IDirectDrawSurface4_QueryInterface,
1600 IDirectDrawSurface4_AddRef,
1601 DGA_IDirectDrawSurface4_Release,
1602 IDirectDrawSurface4_AddAttachedSurface,
1603 IDirectDrawSurface4_AddOverlayDirtyRect,
1604 IDirectDrawSurface4_Blt,
1605 IDirectDrawSurface4_BltBatch,
1606 IDirectDrawSurface4_BltFast,
1607 IDirectDrawSurface4_DeleteAttachedSurface,
1608 IDirectDrawSurface4_EnumAttachedSurfaces,
1609 IDirectDrawSurface4_EnumOverlayZOrders,
1610 DGA_IDirectDrawSurface4_Flip,
1611 IDirectDrawSurface4_GetAttachedSurface,
1612 IDirectDrawSurface4_GetBltStatus,
1613 IDirectDrawSurface4_GetCaps,
1614 IDirectDrawSurface4_GetClipper,
1615 IDirectDrawSurface4_GetColorKey,
1616 IDirectDrawSurface4_GetDC,
1617 IDirectDrawSurface4_GetFlipStatus,
1618 IDirectDrawSurface4_GetOverlayPosition,
1619 IDirectDrawSurface4_GetPalette,
1620 IDirectDrawSurface4_GetPixelFormat,
1621 IDirectDrawSurface4_GetSurfaceDesc,
1622 IDirectDrawSurface4_Initialize,
1623 IDirectDrawSurface4_IsLost,
1624 IDirectDrawSurface4_Lock,
1625 IDirectDrawSurface4_ReleaseDC,
1626 IDirectDrawSurface4_Restore,
1627 IDirectDrawSurface4_SetClipper,
1628 IDirectDrawSurface4_SetColorKey,
1629 IDirectDrawSurface4_SetOverlayPosition,
1630 DGA_IDirectDrawSurface4_SetPalette,
1631 DGA_IDirectDrawSurface4_Unlock,
1632 IDirectDrawSurface4_UpdateOverlay,
1633 IDirectDrawSurface4_UpdateOverlayDisplay,
1634 IDirectDrawSurface4_UpdateOverlayZOrder,
1635 IDirectDrawSurface4_GetDDInterface,
1636 IDirectDrawSurface4_PageLock,
1637 IDirectDrawSurface4_PageUnlock,
1638 IDirectDrawSurface4_SetSurfaceDesc,
1639 IDirectDrawSurface4_SetPrivateData,
1640 IDirectDrawSurface4_GetPrivateData,
1641 IDirectDrawSurface4_FreePrivateData,
1642 IDirectDrawSurface4_GetUniquenessValue,
1643 IDirectDrawSurface4_ChangeUniquenessValue
1646 static struct IDirectDrawSurface4_VTable xlib_dds4vt = {
1647 IDirectDrawSurface4_QueryInterface,
1648 IDirectDrawSurface4_AddRef,
1649 Xlib_IDirectDrawSurface4_Release,
1650 IDirectDrawSurface4_AddAttachedSurface,
1651 IDirectDrawSurface4_AddOverlayDirtyRect,
1652 IDirectDrawSurface4_Blt,
1653 IDirectDrawSurface4_BltBatch,
1654 IDirectDrawSurface4_BltFast,
1655 IDirectDrawSurface4_DeleteAttachedSurface,
1656 IDirectDrawSurface4_EnumAttachedSurfaces,
1657 IDirectDrawSurface4_EnumOverlayZOrders,
1658 Xlib_IDirectDrawSurface4_Flip,
1659 IDirectDrawSurface4_GetAttachedSurface,
1660 IDirectDrawSurface4_GetBltStatus,
1661 IDirectDrawSurface4_GetCaps,
1662 IDirectDrawSurface4_GetClipper,
1663 IDirectDrawSurface4_GetColorKey,
1664 IDirectDrawSurface4_GetDC,
1665 IDirectDrawSurface4_GetFlipStatus,
1666 IDirectDrawSurface4_GetOverlayPosition,
1667 IDirectDrawSurface4_GetPalette,
1668 IDirectDrawSurface4_GetPixelFormat,
1669 IDirectDrawSurface4_GetSurfaceDesc,
1670 IDirectDrawSurface4_Initialize,
1671 IDirectDrawSurface4_IsLost,
1672 IDirectDrawSurface4_Lock,
1673 IDirectDrawSurface4_ReleaseDC,
1674 IDirectDrawSurface4_Restore,
1675 IDirectDrawSurface4_SetClipper,
1676 IDirectDrawSurface4_SetColorKey,
1677 IDirectDrawSurface4_SetOverlayPosition,
1678 Xlib_IDirectDrawSurface4_SetPalette,
1679 Xlib_IDirectDrawSurface4_Unlock,
1680 IDirectDrawSurface4_UpdateOverlay,
1681 IDirectDrawSurface4_UpdateOverlayDisplay,
1682 IDirectDrawSurface4_UpdateOverlayZOrder,
1683 IDirectDrawSurface4_GetDDInterface,
1684 IDirectDrawSurface4_PageLock,
1685 IDirectDrawSurface4_PageUnlock,
1686 IDirectDrawSurface4_SetSurfaceDesc,
1687 IDirectDrawSurface4_SetPrivateData,
1688 IDirectDrawSurface4_GetPrivateData,
1689 IDirectDrawSurface4_FreePrivateData,
1690 IDirectDrawSurface4_GetUniquenessValue,
1691 IDirectDrawSurface4_ChangeUniquenessValue
1694 /******************************************************************************
1695 * DirectDrawCreateClipper (DDRAW.7)
1697 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1698 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1699 LPUNKNOWN pUnkOuter)
1701 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1703 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1704 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1705 (*lplpDDClipper)->ref = 1;
1707 return DD_OK;
1710 /******************************************************************************
1711 * IDirectDrawClipper
1713 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1714 LPDIRECTDRAWCLIPPER this,DWORD x,HWND hwnd
1716 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1717 return DD_OK;
1720 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1721 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1723 this->ref--;
1724 if (this->ref)
1725 return this->ref;
1726 HeapFree(GetProcessHeap(),0,this);
1727 return 0;
1730 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1731 LPDIRECTDRAWCLIPPER this,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
1733 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1734 if (hmm) *hmm=0;
1735 return DD_OK;
1738 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1739 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1741 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1742 return DD_OK;
1745 static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
1746 LPDIRECTDRAWCLIPPER this,
1747 REFIID riid,
1748 LPVOID* ppvObj )
1750 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
1751 return OLE_E_ENUM_NOMORE;
1754 static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
1756 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1757 return ++(this->ref);
1760 static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
1761 LPDIRECTDRAWCLIPPER this,
1762 HWND* HWndPtr )
1764 FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
1765 return DD_OK;
1768 static HRESULT WINAPI IDirectDrawClipper_Initialize(
1769 LPDIRECTDRAWCLIPPER this,
1770 LPDIRECTDRAW lpDD,
1771 DWORD dwFlags )
1773 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
1774 return DD_OK;
1777 static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
1778 LPDIRECTDRAWCLIPPER this,
1779 BOOL* lpbChanged )
1781 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
1782 return DD_OK;
1785 static struct IDirectDrawClipper_VTable ddclipvt = {
1786 IDirectDrawClipper_QueryInterface,
1787 IDirectDrawClipper_AddRef,
1788 IDirectDrawClipper_Release,
1789 IDirectDrawClipper_GetClipList,
1790 IDirectDrawClipper_GetHWnd,
1791 IDirectDrawClipper_Initialize,
1792 IDirectDrawClipper_IsClipListChanged,
1793 IDirectDrawClipper_SetClipList,
1794 IDirectDrawClipper_SetHwnd
1798 /******************************************************************************
1799 * IDirectDrawPalette
1801 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1802 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1804 int i;
1806 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1807 this,x,start,count,palent);
1809 if (!this->cm) /* should not happen */ {
1810 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1811 return DDERR_GENERIC;
1813 for (i=0;i<count;i++) {
1814 palent[i].peRed = this->palents[start+i].peRed;
1815 palent[i].peBlue = this->palents[start+i].peBlue;
1816 palent[i].peGreen = this->palents[start+i].peGreen;
1817 palent[i].peFlags = this->palents[start+i].peFlags;
1820 return DD_OK;
1823 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1824 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1826 XColor xc;
1827 int i;
1829 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1830 this,x,start,count,palent
1832 for (i=0;i<count;i++) {
1833 xc.red = palent[i].peRed<<8;
1834 xc.blue = palent[i].peBlue<<8;
1835 xc.green = palent[i].peGreen<<8;
1836 xc.flags = DoRed|DoBlue|DoGreen;
1837 xc.pixel = start+i;
1839 if (this->cm)
1840 TSXStoreColor(display,this->cm,&xc);
1842 this->palents[start+i].peRed = palent[i].peRed;
1843 this->palents[start+i].peBlue = palent[i].peBlue;
1844 this->palents[start+i].peGreen = palent[i].peGreen;
1845 this->palents[start+i].peFlags = palent[i].peFlags;
1848 /* Now, if we are in 'depth conversion mode', update the screen palette */
1849 if (this->ddraw->d.palette_convert != NULL)
1850 this->ddraw->d.palette_convert(palent, this->screen_palents, start, count);
1852 return DD_OK;
1855 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1856 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1858 #ifdef HAVE_LIBXXF86DGA
1859 XColor xc;
1860 Colormap cm;
1861 int i;
1863 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1864 this,x,start,count,palent
1866 if (!this->cm) /* should not happen */ {
1867 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1868 return DDERR_GENERIC;
1870 /* FIXME: free colorcells instead of freeing whole map */
1871 cm = this->cm;
1872 this->cm = TSXCopyColormapAndFree(display,this->cm);
1873 TSXFreeColormap(display,cm);
1875 for (i=0;i<count;i++) {
1876 xc.red = palent[i].peRed<<8;
1877 xc.blue = palent[i].peBlue<<8;
1878 xc.green = palent[i].peGreen<<8;
1879 xc.flags = DoRed|DoBlue|DoGreen;
1880 xc.pixel = i+start;
1882 TSXStoreColor(display,this->cm,&xc);
1884 this->palents[start+i].peRed = palent[i].peRed;
1885 this->palents[start+i].peBlue = palent[i].peBlue;
1886 this->palents[start+i].peGreen = palent[i].peGreen;
1887 this->palents[start+i].peFlags = palent[i].peFlags;
1889 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1890 return DD_OK;
1891 #else /* defined(HAVE_LIBXXF86DGA) */
1892 return E_UNEXPECTED;
1893 #endif /* defined(HAVE_LIBXXF86DGA) */
1896 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1897 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1898 if (!--(this->ref)) {
1899 if (this->cm) {
1900 TSXFreeColormap(display,this->cm);
1901 this->cm = 0;
1903 HeapFree(GetProcessHeap(),0,this);
1904 return 0;
1906 return this->ref;
1909 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1911 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1912 return ++(this->ref);
1915 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1916 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1918 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1920 return DDERR_ALREADYINITIALIZED;
1923 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1924 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1926 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1927 return DD_OK;
1930 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1931 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1933 char xrefiid[50];
1935 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1936 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1938 return S_OK;
1941 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1942 IDirectDrawPalette_QueryInterface,
1943 IDirectDrawPalette_AddRef,
1944 IDirectDrawPalette_Release,
1945 IDirectDrawPalette_GetCaps,
1946 IDirectDrawPalette_GetEntries,
1947 IDirectDrawPalette_Initialize,
1948 DGA_IDirectDrawPalette_SetEntries
1951 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1952 IDirectDrawPalette_QueryInterface,
1953 IDirectDrawPalette_AddRef,
1954 IDirectDrawPalette_Release,
1955 IDirectDrawPalette_GetCaps,
1956 IDirectDrawPalette_GetEntries,
1957 IDirectDrawPalette_Initialize,
1958 Xlib_IDirectDrawPalette_SetEntries
1961 /*******************************************************************************
1962 * IDirect3D
1964 static HRESULT WINAPI IDirect3D_QueryInterface(
1965 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1967 /* FIXME: Not sure if this is correct */
1968 char xrefiid[50];
1970 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1971 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1972 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1973 *obj = this;
1974 this->lpvtbl->fnAddRef(this);
1976 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
1978 return S_OK;
1980 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1981 LPDIRECT3D d3d;
1983 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1984 d3d->ref = 1;
1985 d3d->ddraw = (LPDIRECTDRAW)this;
1986 this->lpvtbl->fnAddRef(this);
1987 d3d->lpvtbl = &d3dvt;
1988 *obj = d3d;
1990 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
1992 return S_OK;
1994 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
1995 LPDIRECT3D2 d3d;
1997 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1998 d3d->ref = 1;
1999 d3d->ddraw = (LPDIRECTDRAW)this;
2000 this->lpvtbl->fnAddRef(this);
2001 d3d->lpvtbl = &d3d2vt;
2002 *obj = d3d;
2004 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2006 return S_OK;
2008 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
2009 return OLE_E_ENUM_NOMORE;
2012 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
2013 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2015 return ++(this->ref);
2018 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
2020 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2022 if (!--(this->ref)) {
2023 this->ddraw->lpvtbl->fnRelease(this->ddraw);
2024 HeapFree(GetProcessHeap(),0,this);
2025 return 0;
2027 return this->ref;
2030 static HRESULT WINAPI IDirect3D_Initialize(
2031 LPDIRECT3D this, REFIID refiid )
2033 /* FIXME: Not sure if this is correct */
2034 char xrefiid[50];
2036 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2037 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
2039 return DDERR_ALREADYINITIALIZED;
2042 static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this,
2043 LPD3DENUMDEVICESCALLBACK cb,
2044 LPVOID context) {
2045 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
2047 /* Call functions defined in d3ddevices.c */
2048 if (!d3d_OpenGL_dx3(cb, context))
2049 return DD_OK;
2051 return DD_OK;
2054 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,
2055 LPDIRECT3DLIGHT *lplight,
2056 IUnknown *lpunk)
2058 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
2060 /* Call the creation function that is located in d3dlight.c */
2061 *lplight = d3dlight_create_dx3(this);
2063 return DD_OK;
2066 static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this,
2067 LPDIRECT3DMATERIAL *lpmaterial,
2068 IUnknown *lpunk)
2070 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2072 /* Call the creation function that is located in d3dviewport.c */
2073 *lpmaterial = d3dmaterial_create(this);
2075 return DD_OK;
2078 static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this,
2079 LPDIRECT3DVIEWPORT *lpviewport,
2080 IUnknown *lpunk)
2082 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2084 /* Call the creation function that is located in d3dviewport.c */
2085 *lpviewport = d3dviewport_create(this);
2087 return DD_OK;
2090 static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this,
2091 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2092 LPD3DFINDDEVICERESULT lpfinddevrst)
2094 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2096 return DD_OK;
2099 static struct IDirect3D_VTable d3dvt = {
2100 IDirect3D_QueryInterface,
2101 IDirect3D_AddRef,
2102 IDirect3D_Release,
2103 IDirect3D_Initialize,
2104 IDirect3D_EnumDevices,
2105 IDirect3D_CreateLight,
2106 IDirect3D_CreateMaterial,
2107 IDirect3D_CreateViewport,
2108 IDirect3D_FindDevice
2111 /*******************************************************************************
2112 * IDirect3D2
2114 static HRESULT WINAPI IDirect3D2_QueryInterface(
2115 LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) {
2116 /* For the moment, we use the same function as in IDirect3D */
2117 TRACE(ddraw, "Calling IDirect3D enumerating function.\n");
2119 return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj);
2122 static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) {
2123 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2125 return ++(this->ref);
2128 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
2129 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2131 if (!--(this->ref)) {
2132 this->ddraw->lpvtbl->fnRelease(this->ddraw);
2133 HeapFree(GetProcessHeap(),0,this);
2134 return 0;
2136 return this->ref;
2139 static HRESULT WINAPI IDirect3D2_EnumDevices(
2140 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2142 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
2144 /* Call functions defined in d3ddevices.c */
2145 if (!d3d_OpenGL(cb, context))
2146 return DD_OK;
2148 return DD_OK;
2151 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,
2152 LPDIRECT3DLIGHT *lplight,
2153 IUnknown *lpunk)
2155 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
2157 /* Call the creation function that is located in d3dlight.c */
2158 *lplight = d3dlight_create(this);
2160 return DD_OK;
2163 static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this,
2164 LPDIRECT3DMATERIAL2 *lpmaterial,
2165 IUnknown *lpunk)
2167 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2169 /* Call the creation function that is located in d3dviewport.c */
2170 *lpmaterial = d3dmaterial2_create(this);
2172 return DD_OK;
2175 static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this,
2176 LPDIRECT3DVIEWPORT2 *lpviewport,
2177 IUnknown *lpunk)
2179 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2181 /* Call the creation function that is located in d3dviewport.c */
2182 *lpviewport = d3dviewport2_create(this);
2184 return DD_OK;
2187 static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this,
2188 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2189 LPD3DFINDDEVICERESULT lpfinddevrst)
2191 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2193 return DD_OK;
2196 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,
2197 REFCLSID rguid,
2198 LPDIRECTDRAWSURFACE surface,
2199 LPDIRECT3DDEVICE2 *device)
2201 char xbuf[50];
2203 WINE_StringFromCLSID(rguid,xbuf);
2204 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device);
2206 if (is_OpenGL(rguid, surface, device, this)) {
2207 this->lpvtbl->fnAddRef(this);
2208 return DD_OK;
2211 return DDERR_INVALIDPARAMS;
2214 static struct IDirect3D2_VTable d3d2vt = {
2215 IDirect3D2_QueryInterface,
2216 IDirect3D2_AddRef,
2217 IDirect3D2_Release,
2218 IDirect3D2_EnumDevices,
2219 IDirect3D2_CreateLight,
2220 IDirect3D2_CreateMaterial,
2221 IDirect3D2_CreateViewport,
2222 IDirect3D2_FindDevice,
2223 IDirect3D2_CreateDevice
2226 /*******************************************************************************
2227 * IDirectDraw
2230 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2231 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2233 static INT ddrawXlibThisOffset = 0;
2235 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
2236 LPDDSURFACEDESC lpddsd,
2237 LPDIRECTDRAWSURFACE lpdsf)
2239 int bpp;
2241 /* The surface was already allocated when entering in this function */
2242 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2244 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2245 /* This is a Z Buffer */
2246 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2247 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2248 } else {
2249 /* This is a standard image */
2250 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2251 /* No pixel format => use DirectDraw's format */
2252 lpddsd->ddpfPixelFormat = this->d.directdraw_pixelformat;
2253 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2254 } else {
2255 /* To check what the program wants */
2256 if (TRACE_ON(ddraw)) {
2257 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2261 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2262 bpp = 1;
2263 } else {
2264 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2268 /* Copy the surface description */
2269 lpdsf->s.surface_desc = *lpddsd;
2271 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2272 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2273 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2275 return DD_OK;
2278 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
2279 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2281 #ifdef HAVE_LIBXXF86DGA
2282 int i;
2284 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
2285 if (TRACE_ON(ddraw)) {
2286 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2287 _dump_DDSD(lpddsd->dwFlags);
2288 DUMP(" caps ");
2289 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2292 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2293 this->lpvtbl->fnAddRef(this);
2295 (*lpdsf)->ref = 1;
2296 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds4vt;
2297 (*lpdsf)->s.ddraw = this;
2298 (*lpdsf)->s.palette = NULL;
2299 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2301 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2302 lpddsd->dwWidth = this->d.width;
2303 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2304 lpddsd->dwHeight = this->d.height;
2306 /* Check if this a 'primary surface' or not */
2307 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2308 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2310 /* This is THE primary surface => there is DGA-specific code */
2311 /* First, store the surface description */
2312 (*lpdsf)->s.surface_desc = *lpddsd;
2314 /* Find a viewport */
2315 for (i=0;i<32;i++)
2316 if (!(this->e.dga.vpmask & (1<<i)))
2317 break;
2318 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2319 /* if i == 32 or maximum ... return error */
2320 this->e.dga.vpmask|=(1<<i);
2321 (*lpdsf)->s.surface_desc.y.lpSurface =
2322 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2323 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
2324 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
2325 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
2327 /* Add flags if there were not present */
2328 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2329 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2330 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2331 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d.width,this->d.height,lpddsd->lPitch);
2332 /* We put our surface always in video memory */
2333 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2334 (*lpdsf)->s.surface_desc.ddpfPixelFormat = this->d.directdraw_pixelformat;
2335 (*lpdsf)->s.backbuffer = NULL;
2337 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2338 LPDIRECTDRAWSURFACE4 back;
2340 if (lpddsd->dwBackBufferCount>1)
2341 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2343 (*lpdsf)->s.backbuffer = back =
2344 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2345 this->lpvtbl->fnAddRef(this);
2346 back->ref = 1;
2347 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&dga_dds4vt;
2348 for (i=0;i<32;i++)
2349 if (!(this->e.dga.vpmask & (1<<i)))
2350 break;
2351 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2352 /* if i == 32 or maximum ... return error */
2353 this->e.dga.vpmask|=(1<<i);
2354 back->t.dga.fb_height = i*this->e.dga.fb_height;
2356 /* Copy the surface description from the front buffer */
2357 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2358 /* Change the parameters that are not the same */
2359 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
2360 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2361 back->s.ddraw = this;
2362 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2363 * one! */
2365 /* Add relevant info to front and back buffers */
2366 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2367 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2368 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2369 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2370 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2372 } else {
2373 /* There is no DGA-specific code here...
2374 Go to the common surface creation function */
2375 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2378 return DD_OK;
2379 #else /* defined(HAVE_LIBXXF86DGA) */
2380 return E_UNEXPECTED;
2381 #endif /* defined(HAVE_LIBXXF86DGA) */
2384 #ifdef HAVE_LIBXXSHM
2385 /* Error handlers for Image creation */
2386 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2387 XShmErrorFlag = 1;
2388 return 0;
2391 static XImage *create_xshmimage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2392 XImage *img;
2393 int (*WineXHandler)(Display *, XErrorEvent *);
2395 img = TSXShmCreateImage(display,
2396 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2397 this->d.pixmap_depth,
2398 ZPixmap,
2399 NULL,
2400 &(lpdsf->t.xlib.shminfo),
2401 lpdsf->s.surface_desc.dwWidth,
2402 lpdsf->s.surface_desc.dwHeight);
2404 if (img == NULL) {
2405 MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2406 this->e.xlib.xshm_active = 0;
2407 return NULL;
2410 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2411 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2412 MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2413 this->e.xlib.xshm_active = 0;
2414 TSXDestroyImage(img);
2415 return NULL;
2418 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2420 if (img->data == (char *) -1) {
2421 MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2422 this->e.xlib.xshm_active = 0;
2423 TSXDestroyImage(img);
2424 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2425 return NULL;
2427 lpdsf->t.xlib.shminfo.readOnly = False;
2429 /* This is where things start to get trickier....
2430 First, we flush the current X connections to be sure to catch all non-XShm related
2431 errors */
2432 TSXSync(display, False);
2433 /* Then we enter in the non-thread safe part of the tests */
2434 EnterCriticalSection( &X11DRV_CritSection );
2436 /* Reset the error flag, sets our new error handler and try to attach the surface */
2437 XShmErrorFlag = 0;
2438 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2439 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2440 XSync(display, False);
2442 /* Check the error flag */
2443 if (XShmErrorFlag) {
2444 /* An error occured */
2445 XFlush(display);
2446 XShmErrorFlag = 0;
2447 XDestroyImage(img);
2448 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2449 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2450 XSetErrorHandler(WineXHandler);
2452 MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
2453 this->e.xlib.xshm_active = 0;
2455 /* Leave the critical section */
2456 LeaveCriticalSection( &X11DRV_CritSection );
2458 return NULL;
2461 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2462 but it may be a bit overkill.... */
2463 XSetErrorHandler(WineXHandler);
2464 LeaveCriticalSection( &X11DRV_CritSection );
2466 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2468 if (this->d.pixel_convert != NULL) {
2469 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2470 lpdsf->s.surface_desc.dwWidth *
2471 lpdsf->s.surface_desc.dwHeight *
2472 (this->d.directdraw_pixelformat.x.dwRGBBitCount));
2473 } else {
2474 lpdsf->s.surface_desc.y.lpSurface = img->data;
2477 return img;
2479 #endif /* HAVE_LIBXXSHM */
2481 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2482 XImage *img = NULL;
2483 void *img_data;
2485 #ifdef HAVE_LIBXXSHM
2486 if (this->e.xlib.xshm_active) {
2487 img = create_xshmimage(this, lpdsf);
2490 if (img == NULL) {
2491 #endif
2492 /* Allocate surface memory */
2493 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2494 lpdsf->s.surface_desc.dwWidth *
2495 lpdsf->s.surface_desc.dwHeight *
2496 (this->d.directdraw_pixelformat.x.dwRGBBitCount / 8));
2498 if (this->d.pixel_convert != NULL) {
2499 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2500 lpdsf->s.surface_desc.dwWidth *
2501 lpdsf->s.surface_desc.dwHeight *
2502 (this->d.screen_pixelformat.x.dwRGBBitCount / 8));
2503 } else {
2504 img_data = lpdsf->s.surface_desc.y.lpSurface;
2507 /* In this case, create an XImage */
2508 img =
2509 TSXCreateImage(display,
2510 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2511 this->d.pixmap_depth,
2512 ZPixmap,
2514 img_data,
2515 lpdsf->s.surface_desc.dwWidth,
2516 lpdsf->s.surface_desc.dwHeight,
2518 lpdsf->s.surface_desc.dwWidth * (this->d.screen_pixelformat.x.dwRGBBitCount / 8)
2521 #ifdef HAVE_LIBXXSHM
2523 #endif
2524 if (this->d.pixel_convert != NULL) {
2525 lpdsf->s.surface_desc.lPitch = (this->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
2526 } else {
2527 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2530 return img;
2533 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
2534 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2536 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2537 this,lpddsd,lpdsf,lpunk);
2539 if (TRACE_ON(ddraw)) {
2540 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2541 _dump_DDSD(lpddsd->dwFlags);
2542 DUMP(" caps ");
2543 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2546 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2548 this->lpvtbl->fnAddRef(this);
2549 (*lpdsf)->s.ddraw = this;
2550 (*lpdsf)->ref = 1;
2551 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds4vt;
2552 (*lpdsf)->s.palette = NULL;
2553 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2555 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2556 lpddsd->dwWidth = this->d.width;
2557 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2558 lpddsd->dwHeight = this->d.height;
2560 /* Check if this a 'primary surface' or not */
2561 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2562 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2563 XImage *img;
2565 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
2567 /* First, store the surface description */
2568 (*lpdsf)->s.surface_desc = *lpddsd;
2570 /* Create the XImage */
2571 img = create_ximage(this, (LPDIRECTDRAWSURFACE4) *lpdsf);
2572 if (img == NULL)
2573 return DDERR_OUTOFMEMORY;
2574 (*lpdsf)->t.xlib.image = img;
2576 /* Add flags if there were not present */
2577 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2578 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2579 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2580 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2581 (*lpdsf)->s.surface_desc.ddpfPixelFormat = this->d.directdraw_pixelformat;
2582 (*lpdsf)->s.backbuffer = NULL;
2584 /* Check for backbuffers */
2585 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2586 LPDIRECTDRAWSURFACE4 back;
2587 XImage *img;
2589 if (lpddsd->dwBackBufferCount>1)
2590 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2592 (*lpdsf)->s.backbuffer = back =
2593 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2595 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2597 this->lpvtbl->fnAddRef(this);
2598 back->s.ddraw = this;
2600 back->ref = 1;
2601 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&xlib_dds4vt;
2602 /* Copy the surface description from the front buffer */
2603 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2605 /* Create the XImage */
2606 img = create_ximage(this, back);
2607 if (img == NULL)
2608 return DDERR_OUTOFMEMORY;
2609 back->t.xlib.image = img;
2611 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2612 * one! */
2614 /* Add relevant info to front and back buffers */
2615 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2616 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2617 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2618 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2619 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2621 } else {
2622 /* There is no Xlib-specific code here...
2623 Go to the common surface creation function */
2624 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2627 return DD_OK;
2630 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
2631 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2633 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
2634 *dst = src; /* FIXME */
2635 return DD_OK;
2639 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2640 * even when the approbiate bitmasks are not specified.
2642 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
2643 LPDIRECTDRAW2 this,HWND hwnd,DWORD cooplevel
2645 int i;
2646 const struct {
2647 int mask;
2648 char *name;
2649 } flagmap[] = {
2650 FE(DDSCL_FULLSCREEN)
2651 FE(DDSCL_ALLOWREBOOT)
2652 FE(DDSCL_NOWINDOWCHANGES)
2653 FE(DDSCL_NORMAL)
2654 FE(DDSCL_ALLOWMODEX)
2655 FE(DDSCL_EXCLUSIVE)
2656 FE(DDSCL_SETFOCUSWINDOW)
2657 FE(DDSCL_SETDEVICEWINDOW)
2658 FE(DDSCL_CREATEDEVICEWINDOW)
2661 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
2662 if(TRACE_ON(ddraw)){
2663 dbg_decl_str(ddraw, 512);
2664 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2665 if (flagmap[i].mask & cooplevel)
2666 dsprintf(ddraw, "%s ", flagmap[i].name);
2667 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2669 this->d.mainWindow = hwnd;
2671 /* This will be overwritten in the case of Full Screen mode.
2672 Windowed games could work with that :-) */
2673 if (hwnd)
2675 WND *tmpWnd = WIN_FindWndPtr(hwnd);
2676 this->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
2677 WIN_ReleaseWndPtr(tmpWnd);
2680 return DD_OK;
2683 /* Small helper to either use the cooperative window or create a new
2684 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2686 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
2687 RECT rect;
2689 /* Do not destroy the application supplied cooperative window */
2690 if (this->d.window && this->d.window != this->d.mainWindow) {
2691 DestroyWindow(this->d.window);
2692 this->d.window = 0;
2694 /* Sanity check cooperative window before assigning it to drawing. */
2695 if ( IsWindow(this->d.mainWindow) &&
2696 IsWindowVisible(this->d.mainWindow)
2698 GetWindowRect(this->d.mainWindow,&rect);
2699 if (((rect.right-rect.left) >= this->d.width) &&
2700 ((rect.bottom-rect.top) >= this->d.height)
2702 this->d.window = this->d.mainWindow;
2704 /* ... failed, create new one. */
2705 if (!this->d.window) {
2706 this->d.window = CreateWindowExA(
2708 "WINE_DirectDraw",
2709 "WINE_DirectDraw",
2710 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2711 0,0,
2712 this->d.width,
2713 this->d.height,
2717 NULL
2719 /*Store THIS with the window. We'll use it in the window procedure*/
2720 SetWindowLongA(this->d.window,ddrawXlibThisOffset,(LONG)this);
2721 ShowWindow(this->d.window,TRUE);
2722 UpdateWindow(this->d.window);
2724 SetFocus(this->d.window);
2727 static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
2728 XVisualInfo *vi;
2729 XPixmapFormatValues *pf;
2730 XVisualInfo vt;
2731 int nvisuals, npixmap, i;
2732 int match = 0;
2734 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
2735 pf = XListPixmapFormats(display, &npixmap);
2737 for (i = 0; i < npixmap; i++) {
2738 if (pf[i].bits_per_pixel == depth) {
2739 int j;
2741 for (j = 0; j < nvisuals; j++) {
2742 if (vi[j].depth == pf[i].depth) {
2743 pixelformat->dwSize = sizeof(*pixelformat);
2744 if (depth == 8) {
2745 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
2746 pixelformat->y.dwRBitMask = 0;
2747 pixelformat->z.dwGBitMask = 0;
2748 pixelformat->xx.dwBBitMask = 0;
2749 } else {
2750 pixelformat->dwFlags = DDPF_RGB;
2751 pixelformat->y.dwRBitMask = vi[j].red_mask;
2752 pixelformat->z.dwGBitMask = vi[j].green_mask;
2753 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
2755 pixelformat->dwFourCC = 0;
2756 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
2757 pixelformat->xy.dwRGBAlphaBitMask= 0;
2759 *screen_pixelformat = *pixelformat;
2761 if (pix_depth != NULL)
2762 *pix_depth = vi[j].depth;
2764 match = 1;
2766 break;
2770 if (j == nvisuals)
2771 ERR(ddraw, "No visual corresponding to pixmap format !\n");
2775 if ((match == 0) && (depth == 8)) {
2776 pixelformat->dwSize = sizeof(*pixelformat);
2777 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
2778 pixelformat->dwFourCC = 0;
2779 pixelformat->x.dwRGBBitCount = 8;
2780 pixelformat->y.dwRBitMask = 0;
2781 pixelformat->z.dwGBitMask = 0;
2782 pixelformat->xx.dwBBitMask = 0;
2783 pixelformat->xy.dwRGBAlphaBitMask= 0;
2785 /* In that case, find a visual to emulate the 8 bpp format */
2786 for (i = 0; i < npixmap; i++) {
2787 if (pf[i].bits_per_pixel >= depth) {
2788 int j;
2790 for (j = 0; j < nvisuals; j++) {
2791 if (vi[j].depth == pf[i].depth) {
2792 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
2793 screen_pixelformat->dwFlags = DDPF_RGB;
2794 screen_pixelformat->dwFourCC = 0;
2795 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
2796 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
2797 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
2798 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
2799 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
2801 if (pix_depth != NULL)
2802 *pix_depth = vi[j].depth;
2804 match = 2;
2806 break;
2810 if (j == nvisuals)
2811 ERR(ddraw, "No visual corresponding to pixmap format !\n");
2816 TSXFree(vi);
2817 TSXFree(pf);
2819 return match;
2822 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
2823 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2825 #ifdef HAVE_LIBXXF86DGA
2826 int i,mode_count;
2828 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2830 /* We hope getting the asked for depth */
2831 if (_common_depth_to_pixelformat(depth, &(this->d.directdraw_pixelformat), &(this->d.screen_pixelformat), NULL) != 1) {
2832 /* I.e. no visual found or emulated */
2833 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2834 return DDERR_UNSUPPORTEDMODE;
2837 if (this->d.width < width) {
2838 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2839 return DDERR_UNSUPPORTEDMODE;
2841 this->d.width = width;
2842 this->d.height = height;
2844 /* adjust fb_height, so we don't overlap */
2845 if (this->e.dga.fb_height < height)
2846 this->e.dga.fb_height = height;
2847 _common_IDirectDraw_SetDisplayMode(this);
2849 #ifdef HAVE_LIBXXF86VM
2851 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2852 XF86VidModeModeLine mod_tmp;
2853 /* int dotclock_tmp; */
2855 /* save original video mode and set fullscreen if available*/
2856 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2857 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2858 orig_mode->hdisplay = mod_tmp.hdisplay;
2859 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2860 orig_mode->hsyncend = mod_tmp.hsyncend;
2861 orig_mode->htotal = mod_tmp.htotal;
2862 orig_mode->vdisplay = mod_tmp.vdisplay;
2863 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2864 orig_mode->vsyncend = mod_tmp.vsyncend;
2865 orig_mode->vtotal = mod_tmp.vtotal;
2866 orig_mode->flags = mod_tmp.flags;
2867 orig_mode->private = mod_tmp.private;
2869 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2870 for (i=0;i<mode_count;i++)
2872 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2874 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2875 *vidmode = *(all_modes[i]);
2876 break;
2877 } else
2878 TSXFree(all_modes[i]->private);
2880 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
2881 TSXFree(all_modes);
2883 if (!vidmode)
2884 WARN(ddraw, "Fullscreen mode not available!\n");
2886 if (vidmode)
2888 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
2889 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2890 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
2891 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2892 #endif
2895 #endif
2897 /* FIXME: this function OVERWRITES several signal handlers.
2898 * can we save them? and restore them later? In a way that
2899 * it works for the library too?
2901 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2902 #ifdef DIABLO_HACK
2903 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2904 #else
2905 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2906 #endif
2908 #ifdef RESTORE_SIGNALS
2909 SIGNAL_InitHandlers();
2910 #endif
2911 return DD_OK;
2912 #else /* defined(HAVE_LIBXXF86DGA) */
2913 return E_UNEXPECTED;
2914 #endif /* defined(HAVE_LIBXXF86DGA) */
2917 /* *************************************
2918 16 / 15 bpp to palettized 8 bpp
2919 ************************************* */
2920 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, LPDIRECTDRAWPALETTE palette) {
2921 unsigned char *c_src = (unsigned char *) src;
2922 unsigned short *c_dst = (unsigned short *) dst;
2923 int x, y;
2925 if (palette != NULL) {
2926 unsigned short *pal = (unsigned short *) palette->screen_palents;
2928 for (y = 0; y < height; y++) {
2929 for (x = 0; x < width; x++) {
2930 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
2933 } else {
2934 WARN(ddraw, "No palette set...\n");
2935 memset(dst, 0, width * height * 2);
2938 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
2939 int i;
2940 unsigned short *pal = (unsigned short *) screen_palette;
2942 for (i = 0; i < count; i++)
2943 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
2944 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
2945 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
2947 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
2948 int i;
2949 unsigned short *pal = (unsigned short *) screen_palette;
2951 for (i = 0; i < count; i++)
2952 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
2953 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
2954 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
2957 /* *************************************
2958 24 / 32 bpp to palettized 8 bpp
2959 ************************************* */
2960 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, LPDIRECTDRAWPALETTE palette) {
2961 unsigned char *c_src = (unsigned char *) src;
2962 unsigned int *c_dst = (unsigned int *) dst;
2963 int x, y;
2965 if (palette != NULL) {
2966 unsigned int *pal = (unsigned int *) palette->screen_palents;
2968 for (y = 0; y < height; y++) {
2969 for (x = 0; x < width; x++) {
2970 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
2973 } else {
2974 WARN(ddraw, "No palette set...\n");
2975 memset(dst, 0, width * height * 4);
2978 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
2979 int i;
2980 unsigned int *pal = (unsigned int *) screen_palette;
2982 for (i = 0; i < count; i++)
2983 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
2984 (((unsigned int) palent[i].peGreen) << 8) |
2985 ((unsigned int) palent[i].peBlue));
2988 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2989 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2991 char buf[200];
2992 WND *tmpWnd;
2994 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2995 this, width, height, depth);
2997 switch (_common_depth_to_pixelformat(depth,
2998 &(this->d.directdraw_pixelformat),
2999 &(this->d.screen_pixelformat),
3000 &(this->d.pixmap_depth))) {
3001 case 0:
3002 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3003 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3004 return DDERR_UNSUPPORTEDMODE;
3006 case 1:
3007 /* No convertion */
3008 this->d.pixel_convert = NULL;
3009 this->d.palette_convert = NULL;
3010 break;
3012 case 2: {
3013 int found = 0;
3015 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3017 /* Set the depth convertion routines */
3018 switch (this->d.screen_pixelformat.x.dwRGBBitCount) {
3019 case 16:
3020 if ((this->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
3021 (this->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
3022 (this->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3023 /* 16 bpp */
3024 found = 1;
3026 this->d.pixel_convert = pixel_convert_16_to_8;
3027 this->d.palette_convert = palette_convert_16_to_8;
3028 } else if ((this->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
3029 (this->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
3030 (this->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3031 /* 15 bpp */
3032 found = 1;
3034 this->d.pixel_convert = pixel_convert_16_to_8;
3035 this->d.palette_convert = palette_convert_15_to_8;
3037 break;
3039 case 24:
3040 /* Not handled yet :/ */
3041 found = 0;
3042 break;
3044 case 32:
3045 if ((this->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) &&
3046 (this->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) &&
3047 (this->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
3048 /* 24 bpp */
3049 found = 1;
3051 this->d.pixel_convert = pixel_convert_32_to_8;
3052 this->d.palette_convert = palette_convert_24_to_8;
3054 break;
3057 if (!found) {
3058 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3059 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3060 return DDERR_UNSUPPORTEDMODE;
3062 } break;
3065 this->d.width = width;
3066 this->d.height = height;
3068 _common_IDirectDraw_SetDisplayMode(this);
3070 tmpWnd = WIN_FindWndPtr(this->d.window);
3071 this->d.paintable = 1;
3072 this->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3073 /* We don't have a context for this window. Host off the desktop */
3075 if( !this->d.drawable )
3077 this->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3078 WIN_ReleaseDesktop();
3080 WIN_ReleaseWndPtr(tmpWnd);
3081 return DD_OK;
3084 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
3085 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
3087 #ifdef HAVE_LIBXXF86DGA
3088 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
3089 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
3090 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3091 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3092 if (caps2) {
3093 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
3094 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3095 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3097 return DD_OK;
3098 #else /* defined(HAVE_LIBXXF86DGA) */
3099 return E_UNEXPECTED;
3100 #endif /* defined(HAVE_LIBXXF86DGA) */
3103 static void fill_caps(LPDDCAPS caps) {
3104 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3105 Need to be fixed, though.. */
3106 if (caps == NULL)
3107 return;
3109 caps->dwSize = sizeof(*caps);
3110 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3111 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
3112 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3113 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3114 caps->dwFXCaps = 0;
3115 caps->dwFXAlphaCaps = 0;
3116 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3117 caps->dwSVCaps = 0;
3118 caps->dwZBufferBitDepths = DDBD_16;
3119 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3120 to put textures in video memory.
3121 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3122 for example) ? */
3123 caps->dwVidMemTotal = 8192 * 1024;
3124 caps->dwVidMemFree = 8192 * 1024;
3125 /* These are all the supported capabilities of the surfaces */
3126 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3127 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3128 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3129 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3130 #ifdef HAVE_MESAGL
3131 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3132 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3133 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3134 #endif
3137 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
3138 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
3140 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
3142 /* Put the same caps for the two capabilities */
3143 fill_caps(caps1);
3144 fill_caps(caps2);
3146 return DD_OK;
3149 static HRESULT WINAPI IDirectDraw2_CreateClipper(
3150 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3152 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3153 this,x,lpddclip,lpunk
3155 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
3156 (*lpddclip)->ref = 1;
3157 (*lpddclip)->lpvtbl = &ddclipvt;
3158 return DD_OK;
3161 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
3162 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk,int *psize
3164 int size = 0;
3166 if (TRACE_ON(ddraw))
3167 _dump_paletteformat(dwFlags);
3169 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
3170 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3171 (*lpddpal)->ref = 1;
3172 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
3173 (*lpddpal)->installed = 0;
3175 if (dwFlags & DDPCAPS_1BIT)
3176 size = 2;
3177 else if (dwFlags & DDPCAPS_2BIT)
3178 size = 4;
3179 else if (dwFlags & DDPCAPS_4BIT)
3180 size = 16;
3181 else if (dwFlags & DDPCAPS_8BIT)
3182 size = 256;
3183 else
3184 ERR(ddraw, "unhandled palette format\n");
3185 *psize = size;
3187 if (palent)
3189 /* Now, if we are in 'depth conversion mode', create the screen palette */
3190 if (this->d.palette_convert != NULL)
3191 this->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3193 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3194 } else if (this->d.palette_convert != NULL) {
3195 /* In that case, put all 0xFF */
3196 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3199 return DD_OK;
3202 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
3203 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3205 HRESULT res;
3206 int xsize = 0,i;
3208 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
3209 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
3210 if (res != 0) return res;
3211 (*lpddpal)->lpvtbl = &dga_ddpalvt;
3212 if (this->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3213 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3214 } else {
3215 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3216 (*lpddpal)->cm = 0;
3218 if (((*lpddpal)->cm)&&xsize) {
3219 for (i=0;i<xsize;i++) {
3220 XColor xc;
3222 xc.red = (*lpddpal)->palents[i].peRed<<8;
3223 xc.blue = (*lpddpal)->palents[i].peBlue<<8;
3224 xc.green = (*lpddpal)->palents[i].peGreen<<8;
3225 xc.flags = DoRed|DoBlue|DoGreen;
3226 xc.pixel = i;
3227 TSXStoreColor(display,(*lpddpal)->cm,&xc);
3230 return DD_OK;
3233 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
3234 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3236 int xsize;
3237 HRESULT res;
3239 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
3240 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
3241 if (res != 0) return res;
3242 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
3243 return DD_OK;
3246 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3247 #ifdef HAVE_LIBXXF86DGA
3248 TRACE(ddraw, "(%p)->()\n",this);
3249 Sleep(1000);
3250 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3251 #ifdef RESTORE_SIGNALS
3252 SIGNAL_InitHandlers();
3253 #endif
3254 return DD_OK;
3255 #else /* defined(HAVE_LIBXXF86DGA) */
3256 return E_UNEXPECTED;
3257 #endif
3260 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3261 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
3262 Sleep(1000);
3263 return DD_OK;
3266 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
3267 LPDIRECTDRAW2 this,DWORD x,HANDLE h
3269 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
3270 return DD_OK;
3273 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
3274 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
3276 return ++(this->ref);
3279 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3280 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3282 #ifdef HAVE_LIBXXF86DGA
3283 if (!--(this->ref)) {
3284 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3285 if (this->d.window && (this->d.mainWindow != this->d.window))
3286 DestroyWindow(this->d.window);
3287 #ifdef HAVE_LIBXXF86VM
3288 if (orig_mode) {
3289 TSXF86VidModeSwitchToMode(
3290 display,
3291 DefaultScreen(display),
3292 orig_mode);
3293 if (orig_mode->privsize)
3294 TSXFree(orig_mode->private);
3295 free(orig_mode);
3296 orig_mode = NULL;
3298 #endif
3300 #ifdef RESTORE_SIGNALS
3301 SIGNAL_InitHandlers();
3302 #endif
3303 HeapFree(GetProcessHeap(),0,this);
3304 return 0;
3306 #endif /* defined(HAVE_LIBXXF86DGA) */
3307 return this->ref;
3310 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3311 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3313 if (!--(this->ref)) {
3314 if (this->d.window && (this->d.mainWindow != this->d.window))
3315 DestroyWindow(this->d.window);
3316 HeapFree(GetProcessHeap(),0,this);
3317 return 0;
3319 /* FIXME: destroy window ... */
3320 return this->ref;
3323 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
3324 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3326 char xrefiid[50];
3328 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3329 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3330 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3331 *obj = this;
3332 this->lpvtbl->fnAddRef(this);
3334 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3336 return S_OK;
3338 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3339 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
3340 this->lpvtbl->fnAddRef(this);
3341 *obj = this;
3343 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3345 return S_OK;
3347 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3348 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
3349 this->lpvtbl->fnAddRef(this);
3350 *obj = this;
3352 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3354 return S_OK;
3356 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3357 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd4vt;
3358 this->lpvtbl->fnAddRef(this);
3359 *obj = this;
3361 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3363 return S_OK;
3365 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3366 LPDIRECT3D d3d;
3368 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3369 d3d->ref = 1;
3370 d3d->ddraw = (LPDIRECTDRAW)this;
3371 this->lpvtbl->fnAddRef(this);
3372 d3d->lpvtbl = &d3dvt;
3373 *obj = d3d;
3375 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3377 return S_OK;
3379 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3380 LPDIRECT3D2 d3d;
3382 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3383 d3d->ref = 1;
3384 d3d->ddraw = (LPDIRECTDRAW)this;
3385 this->lpvtbl->fnAddRef(this);
3386 d3d->lpvtbl = &d3d2vt;
3387 *obj = d3d;
3389 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3391 return S_OK;
3393 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3394 return OLE_E_ENUM_NOMORE;
3397 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
3398 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3400 char xrefiid[50];
3402 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3403 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3404 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3405 *obj = this;
3406 this->lpvtbl->fnAddRef(this);
3408 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3410 return S_OK;
3412 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3413 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
3414 this->lpvtbl->fnAddRef(this);
3415 *obj = this;
3417 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3419 return S_OK;
3421 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3422 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
3423 this->lpvtbl->fnAddRef(this);
3424 *obj = this;
3426 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3428 return S_OK;
3430 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3431 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd4vt;
3432 this->lpvtbl->fnAddRef(this);
3433 *obj = this;
3435 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3437 return S_OK;
3439 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3440 LPDIRECT3D d3d;
3442 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3443 d3d->ref = 1;
3444 d3d->ddraw = (LPDIRECTDRAW)this;
3445 this->lpvtbl->fnAddRef(this);
3446 d3d->lpvtbl = &d3dvt;
3447 *obj = d3d;
3449 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3451 return S_OK;
3453 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3454 LPDIRECT3D2 d3d;
3456 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3457 d3d->ref = 1;
3458 d3d->ddraw = (LPDIRECTDRAW)this;
3459 this->lpvtbl->fnAddRef(this);
3460 d3d->lpvtbl = &d3d2vt;
3461 *obj = d3d;
3463 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3465 return S_OK;
3467 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3468 return OLE_E_ENUM_NOMORE;
3471 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
3472 LPDIRECTDRAW2 this,BOOL *status
3474 TRACE(ddraw,"(%p)->(%p)\n",this,status);
3475 *status = TRUE;
3476 return DD_OK;
3479 static HRESULT WINAPI DGA_IDirectDraw2_EnumDisplayModes(
3480 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3482 DDSURFACEDESC ddsfd;
3483 static struct {
3484 int w,h;
3485 } modes[5] = { /* some of the usual modes */
3486 {512,384},
3487 {640,400},
3488 {640,480},
3489 {800,600},
3490 {1024,768},
3492 static int depths[4] = {8,16,24,32};
3493 int i,j;
3495 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
3496 ddsfd.dwSize = sizeof(ddsfd);
3497 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3498 if (dwFlags & DDEDM_REFRESHRATES) {
3499 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3500 ddsfd.x.dwRefreshRate = 60;
3503 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3504 ddsfd.dwBackBufferCount = 1;
3505 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3506 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3507 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3508 /* FIXME: those masks would have to be set in depth > 8 */
3509 if (depths[i]==8) {
3510 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3511 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3512 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3513 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3514 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3515 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3516 } else {
3517 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3519 /* FIXME: We should query those from X itself */
3520 switch (depths[i]) {
3521 case 16:
3522 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3523 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3524 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3525 break;
3526 case 24:
3527 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3528 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3529 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3530 break;
3531 case 32:
3532 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3533 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3534 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3535 break;
3539 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3540 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3541 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3542 if (!modescb(&ddsfd,context)) return DD_OK;
3544 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3545 ddsfd.dwWidth = modes[j].w;
3546 ddsfd.dwHeight = modes[j].h;
3547 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3548 if (!modescb(&ddsfd,context)) return DD_OK;
3551 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3552 /* modeX is not standard VGA */
3554 ddsfd.dwHeight = 200;
3555 ddsfd.dwWidth = 320;
3556 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3557 if (!modescb(&ddsfd,context)) return DD_OK;
3560 return DD_OK;
3563 static HRESULT WINAPI Xlib_IDirectDraw2_EnumDisplayModes(
3564 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3566 XVisualInfo *vi;
3567 XPixmapFormatValues *pf;
3568 XVisualInfo vt;
3569 int nvisuals, npixmap, i;
3570 int send_mode;
3571 int has_8bpp = 0;
3572 DDSURFACEDESC ddsfd;
3573 static struct {
3574 int w,h;
3575 } modes[] = { /* some of the usual modes */
3576 {512,384},
3577 {640,400},
3578 {640,480},
3579 {800,600},
3580 {1024,768},
3581 {1280,1024}
3583 DWORD maxWidth, maxHeight;
3585 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
3586 ddsfd.dwSize = sizeof(ddsfd);
3587 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
3588 if (dwFlags & DDEDM_REFRESHRATES) {
3589 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3590 ddsfd.x.dwRefreshRate = 60;
3592 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3593 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3595 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3596 pf = XListPixmapFormats(display, &npixmap);
3598 i = 0;
3599 send_mode = 0;
3600 while (i < npixmap) {
3601 if ((has_8bpp == 0) && (pf[i].depth == 8)) {
3602 /* Special case of a 8bpp depth */
3603 has_8bpp = 1;
3604 send_mode = 1;
3606 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
3607 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3608 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
3609 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3610 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
3611 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3612 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3613 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3614 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3615 } else if (pf[i].depth > 8) {
3616 int j;
3618 /* All the 'true color' depths (15, 16 and 24)
3619 First, find the corresponding visual to extract the bit masks */
3620 for (j = 0; j < nvisuals; j++) {
3621 if (vi[j].depth == pf[i].depth) {
3622 ddsfd.ddsCaps.dwCaps = 0;
3623 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3624 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3625 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3626 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
3627 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
3628 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
3629 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
3630 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3632 send_mode = 1;
3633 break;
3637 if (j == nvisuals)
3638 ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
3639 } else {
3640 send_mode = 0;
3643 if (send_mode) {
3644 int mode;
3646 if (TRACE_ON(ddraw)) {
3647 TRACE(ddraw, "Enumerating with pixel format : \n");
3648 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
3651 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
3652 /* Do not enumerate modes we cannot handle anyway */
3653 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
3654 break;
3656 ddsfd.dwWidth = modes[mode].w;
3657 ddsfd.dwHeight = modes[mode].h;
3659 /* Now, send the mode description to the application */
3660 TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
3661 if (!modescb(&ddsfd, context))
3662 goto exit_enum;
3665 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3666 /* modeX is not standard VGA */
3667 ddsfd.dwWidth = 320;
3668 ddsfd.dwHeight = 200;
3669 if (!modescb(&ddsfd, context))
3670 goto exit_enum;
3674 /* Hack to always enumerate a 8bpp depth */
3675 i++;
3676 if ((i == npixmap) && (has_8bpp == 0)) {
3677 i--;
3678 pf[i].depth = 8;
3682 exit_enum:
3683 TSXFree(vi);
3684 TSXFree(pf);
3686 return DD_OK;
3689 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
3690 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3692 #ifdef HAVE_LIBXXF86DGA
3693 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
3694 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3695 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3696 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3697 lpddsfd->lPitch = this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3698 lpddsfd->dwBackBufferCount = 1;
3699 lpddsfd->x.dwRefreshRate = 60;
3700 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3701 lpddsfd->ddpfPixelFormat = this->d.directdraw_pixelformat;
3702 return DD_OK;
3703 #else /* defined(HAVE_LIBXXF86DGA) */
3704 return E_UNEXPECTED;
3705 #endif /* defined(HAVE_LIBXXF86DGA) */
3708 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
3709 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3711 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
3712 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3713 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3714 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3715 lpddsfd->lPitch = lpddsfd->dwWidth * this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3716 lpddsfd->dwBackBufferCount = 1;
3717 lpddsfd->x.dwRefreshRate = 60;
3718 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3719 lpddsfd->ddpfPixelFormat = this->d.directdraw_pixelformat;
3720 return DD_OK;
3723 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
3724 TRACE(ddraw,"(%p)->()\n",this);
3725 return DD_OK;
3728 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
3729 LPDIRECTDRAW2 this,LPDWORD freq
3731 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
3732 *freq = 60*100; /* 60 Hz */
3733 return DD_OK;
3736 /* what can we directly decompress? */
3737 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
3738 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
3740 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
3741 return DD_OK;
3744 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
3745 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
3747 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
3748 return DD_OK;
3751 static HRESULT WINAPI IDirectDraw2_Compact(
3752 LPDIRECTDRAW2 this )
3754 FIXME(ddraw,"(%p)->()\n", this );
3756 return DD_OK;
3759 static HRESULT WINAPI IDirectDraw2_GetGDISurface(LPDIRECTDRAW2 this,
3760 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
3761 FIXME(ddraw,"(%p)->(%p)\n", this, lplpGDIDDSSurface);
3763 return DD_OK;
3766 static HRESULT WINAPI IDirectDraw2_GetScanLine(LPDIRECTDRAW2 this,
3767 LPDWORD lpdwScanLine) {
3768 FIXME(ddraw,"(%p)->(%p)\n", this, lpdwScanLine);
3770 return DD_OK;
3773 static HRESULT WINAPI IDirectDraw2_Initialize(LPDIRECTDRAW2 this,
3774 GUID *lpGUID) {
3775 FIXME(ddraw,"(%p)->(%p)\n", this, lpGUID);
3777 return DD_OK;
3780 /* Note: Hack so we can reuse the old functions without compiler warnings */
3781 #ifdef __GNUC__
3782 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
3783 #else
3784 # define XCAST(fun) (void*)
3785 #endif
3787 static struct IDirectDraw_VTable dga_ddvt = {
3788 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3789 XCAST(AddRef)IDirectDraw2_AddRef,
3790 XCAST(Release)DGA_IDirectDraw2_Release,
3791 XCAST(Compact)IDirectDraw2_Compact,
3792 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3793 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3794 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3795 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3796 XCAST(EnumDisplayModes)DGA_IDirectDraw2_EnumDisplayModes,
3797 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3798 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3799 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3800 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3801 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3802 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3803 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3804 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3805 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3806 XCAST(Initialize)IDirectDraw2_Initialize,
3807 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3808 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3809 DGA_IDirectDraw_SetDisplayMode,
3810 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3813 static struct IDirectDraw_VTable xlib_ddvt = {
3814 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3815 XCAST(AddRef)IDirectDraw2_AddRef,
3816 XCAST(Release)Xlib_IDirectDraw2_Release,
3817 XCAST(Compact)IDirectDraw2_Compact,
3818 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3819 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3820 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3821 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3822 XCAST(EnumDisplayModes)Xlib_IDirectDraw2_EnumDisplayModes,
3823 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3824 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3825 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3826 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3827 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3828 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3829 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3830 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3831 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3832 XCAST(Initialize)IDirectDraw2_Initialize,
3833 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3834 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3835 Xlib_IDirectDraw_SetDisplayMode,
3836 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3839 #undef XCAST
3841 /*****************************************************************************
3842 * IDirectDraw2
3847 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
3848 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3850 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3853 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
3854 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3856 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3859 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
3860 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3862 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3863 this,ddscaps,total,free
3865 if (total) *total = this->e.dga.fb_memsize * 1024;
3866 if (free) *free = this->e.dga.fb_memsize * 1024;
3867 return DD_OK;
3870 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
3871 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3873 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3874 this,ddscaps,total,free
3876 if (total) *total = 2048 * 1024;
3877 if (free) *free = 2048 * 1024;
3878 return DD_OK;
3881 static IDirectDraw2_VTable dga_dd2vt = {
3882 DGA_IDirectDraw2_QueryInterface,
3883 IDirectDraw2_AddRef,
3884 DGA_IDirectDraw2_Release,
3885 IDirectDraw2_Compact,
3886 IDirectDraw2_CreateClipper,
3887 DGA_IDirectDraw2_CreatePalette,
3888 DGA_IDirectDraw2_CreateSurface,
3889 IDirectDraw2_DuplicateSurface,
3890 DGA_IDirectDraw2_EnumDisplayModes,
3891 IDirectDraw2_EnumSurfaces,
3892 IDirectDraw2_FlipToGDISurface,
3893 DGA_IDirectDraw2_GetCaps,
3894 DGA_IDirectDraw2_GetDisplayMode,
3895 IDirectDraw2_GetFourCCCodes,
3896 IDirectDraw2_GetGDISurface,
3897 IDirectDraw2_GetMonitorFrequency,
3898 IDirectDraw2_GetScanLine,
3899 IDirectDraw2_GetVerticalBlankStatus,
3900 IDirectDraw2_Initialize,
3901 DGA_IDirectDraw2_RestoreDisplayMode,
3902 IDirectDraw2_SetCooperativeLevel,
3903 DGA_IDirectDraw2_SetDisplayMode,
3904 IDirectDraw2_WaitForVerticalBlank,
3905 DGA_IDirectDraw2_GetAvailableVidMem
3908 static struct IDirectDraw2_VTable xlib_dd2vt = {
3909 Xlib_IDirectDraw2_QueryInterface,
3910 IDirectDraw2_AddRef,
3911 Xlib_IDirectDraw2_Release,
3912 IDirectDraw2_Compact,
3913 IDirectDraw2_CreateClipper,
3914 Xlib_IDirectDraw2_CreatePalette,
3915 Xlib_IDirectDraw2_CreateSurface,
3916 IDirectDraw2_DuplicateSurface,
3917 Xlib_IDirectDraw2_EnumDisplayModes,
3918 IDirectDraw2_EnumSurfaces,
3919 IDirectDraw2_FlipToGDISurface,
3920 Xlib_IDirectDraw2_GetCaps,
3921 Xlib_IDirectDraw2_GetDisplayMode,
3922 IDirectDraw2_GetFourCCCodes,
3923 IDirectDraw2_GetGDISurface,
3924 IDirectDraw2_GetMonitorFrequency,
3925 IDirectDraw2_GetScanLine,
3926 IDirectDraw2_GetVerticalBlankStatus,
3927 IDirectDraw2_Initialize,
3928 Xlib_IDirectDraw2_RestoreDisplayMode,
3929 IDirectDraw2_SetCooperativeLevel,
3930 Xlib_IDirectDraw2_SetDisplayMode,
3931 IDirectDraw2_WaitForVerticalBlank,
3932 Xlib_IDirectDraw2_GetAvailableVidMem
3935 /*****************************************************************************
3936 * IDirectDraw4
3940 static HRESULT WINAPI IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4 this,
3941 HDC hdc,
3942 LPDIRECTDRAWSURFACE *lpDDS) {
3943 FIXME(ddraw, "(%p)->(%08ld,%p)\n", this, (DWORD) hdc, lpDDS);
3945 return DD_OK;
3948 static HRESULT WINAPI IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4 this) {
3949 FIXME(ddraw, "(%p)->()\n", this);
3951 return DD_OK;
3954 static HRESULT WINAPI IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4 this) {
3955 FIXME(ddraw, "(%p)->()\n", this);
3957 return DD_OK;
3960 static HRESULT WINAPI IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4 this,
3961 LPDDDEVICEIDENTIFIER lpdddi,
3962 DWORD dwFlags) {
3963 FIXME(ddraw, "(%p)->(%p,%08lx)\n", this, lpdddi, dwFlags);
3965 return DD_OK;
3968 #ifdef __GNUC__
3969 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
3970 #else
3971 # define XCAST(fun) (void*)
3972 #endif
3975 static struct IDirectDraw4_VTable dga_dd4vt = {
3976 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3977 XCAST(AddRef)IDirectDraw2_AddRef,
3978 XCAST(Release)DGA_IDirectDraw2_Release,
3979 XCAST(Compact)IDirectDraw2_Compact,
3980 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3981 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3982 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3983 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3984 XCAST(EnumDisplayModes)DGA_IDirectDraw2_EnumDisplayModes,
3985 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3986 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3987 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3988 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3989 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3990 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3991 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3992 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3993 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3994 XCAST(Initialize)IDirectDraw2_Initialize,
3995 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3996 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3997 XCAST(SetDisplayMode)DGA_IDirectDraw_SetDisplayMode,
3998 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3999 XCAST(GetAvailableVidMem)DGA_IDirectDraw2_GetAvailableVidMem,
4000 IDirectDraw4_GetSurfaceFromDC,
4001 IDirectDraw4_RestoreAllSurfaces,
4002 IDirectDraw4_TestCooperativeLevel,
4003 IDirectDraw4_GetDeviceIdentifier
4006 static struct IDirectDraw4_VTable xlib_dd4vt = {
4007 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
4008 XCAST(AddRef)IDirectDraw2_AddRef,
4009 XCAST(Release)Xlib_IDirectDraw2_Release,
4010 XCAST(Compact)IDirectDraw2_Compact,
4011 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
4012 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
4013 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
4014 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
4015 XCAST(EnumDisplayModes)Xlib_IDirectDraw2_EnumDisplayModes,
4016 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
4017 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
4018 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
4019 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
4020 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
4021 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
4022 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
4023 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
4024 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
4025 XCAST(Initialize)IDirectDraw2_Initialize,
4026 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
4027 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
4028 XCAST(SetDisplayMode)Xlib_IDirectDraw_SetDisplayMode,
4029 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
4030 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2_GetAvailableVidMem,
4031 IDirectDraw4_GetSurfaceFromDC,
4032 IDirectDraw4_RestoreAllSurfaces,
4033 IDirectDraw4_TestCooperativeLevel,
4034 IDirectDraw4_GetDeviceIdentifier
4037 #undef XCAST
4039 /******************************************************************************
4040 * DirectDrawCreate
4043 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4045 LRESULT ret;
4046 LPDIRECTDRAW ddraw = NULL;
4047 DWORD lastError;
4049 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4051 SetLastError( ERROR_SUCCESS );
4052 ddraw = (LPDIRECTDRAW)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4053 if( (!ddraw) &&
4054 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4057 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4060 if( ddraw )
4062 /* Perform any special direct draw functions */
4063 if (msg==WM_PAINT)
4064 ddraw->d.paintable = 1;
4066 /* Now let the application deal with the rest of this */
4067 if( ddraw->d.mainWindow )
4070 /* Don't think that we actually need to call this but...
4071 might as well be on the safe side of things... */
4073 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4074 it should be the procedures of our fake window that gets called
4075 instead of those of the window provided by the application.
4076 And with this patch, mouse clicks work with Monkey Island III
4077 - Lionel */
4078 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4080 if( !ret )
4082 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4083 /* We didn't handle the message - give it to the application */
4084 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4086 ret = CallWindowProcA(tmpWnd->winproc,
4087 ddraw->d.mainWindow, msg, wParam, lParam );
4089 WIN_ReleaseWndPtr(tmpWnd);
4093 } else {
4094 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4098 else
4100 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4103 return ret;
4106 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4107 #ifdef HAVE_LIBXXF86DGA
4108 int memsize,banksize,width,major,minor,flags,height;
4109 char *addr;
4110 int fd;
4111 int depth;
4113 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4114 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4115 close(fd);
4117 if (fd == -1) {
4118 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4119 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4120 return E_UNEXPECTED;
4122 if (!DDRAW_DGA_Available()) {
4123 TRACE(ddraw,"No XF86DGA detected.\n");
4124 return DDERR_GENERIC;
4126 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
4127 (*lplpDD)->lpvtbl = &dga_ddvt;
4128 (*lplpDD)->ref = 1;
4129 TSXF86DGAQueryVersion(display,&major,&minor);
4130 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4131 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4132 if (!(flags & XF86DGADirectPresent))
4133 MSG("direct video is NOT PRESENT.\n");
4134 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4135 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4136 addr,width,banksize,memsize
4138 (*lplpDD)->e.dga.fb_width = width;
4139 (*lplpDD)->d.width = width;
4140 (*lplpDD)->e.dga.fb_addr = addr;
4141 (*lplpDD)->e.dga.fb_memsize = memsize;
4142 (*lplpDD)->e.dga.fb_banksize = banksize;
4144 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4145 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4146 (*lplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4147 #ifdef DIABLO_HACK
4148 (*lplpDD)->e.dga.vpmask = 1;
4149 #else
4150 (*lplpDD)->e.dga.vpmask = 0;
4151 #endif
4153 /* just assume the default depth is the DGA depth too */
4154 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4155 _common_depth_to_pixelformat(depth, &((*lplpDD)->d.directdraw_pixelformat), &((*lplpDD)->d.screen_pixelformat), NULL);
4156 #ifdef RESTORE_SIGNALS
4157 SIGNAL_InitHandlers();
4158 #endif
4160 return DD_OK;
4161 #else /* defined(HAVE_LIBXXF86DGA) */
4162 return DDERR_INVALIDDIRECTDRAWGUID;
4163 #endif /* defined(HAVE_LIBXXF86DGA) */
4166 BOOL
4167 DDRAW_XSHM_Available(void)
4169 #ifdef HAVE_LIBXXSHM
4170 if (TSXShmQueryExtension(display))
4172 int major, minor;
4173 Bool shpix;
4175 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4176 return 1;
4177 else
4178 return 0;
4180 else
4181 return 0;
4182 #else
4183 return 0;
4184 #endif
4187 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4188 int depth;
4190 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
4191 (*lplpDD)->lpvtbl = &xlib_ddvt;
4192 (*lplpDD)->ref = 1;
4193 (*lplpDD)->d.drawable = 0; /* in SetDisplayMode */
4195 /* At DirectDraw creation, the depth is the default depth */
4196 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4197 _common_depth_to_pixelformat(depth, &((*lplpDD)->d.directdraw_pixelformat), &((*lplpDD)->d.screen_pixelformat), NULL);
4198 (*lplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4199 (*lplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4201 #ifdef HAVE_LIBXXSHM
4202 /* Test if XShm is available. */
4203 if (((*lplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4204 TRACE(ddraw, "Using XShm extension.\n");
4205 #endif
4207 return DD_OK;
4210 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4211 char xclsid[50];
4212 WNDCLASSA wc;
4213 /* WND* pParentWindow; */
4214 HRESULT ret;
4216 if (HIWORD(lpGUID))
4217 WINE_StringFromCLSID(lpGUID,xclsid);
4218 else {
4219 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4220 lpGUID = NULL;
4223 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
4225 if (!lpGUID) {
4226 /* if they didn't request a particular interface, use the best
4227 * supported one */
4228 if (DDRAW_DGA_Available())
4229 lpGUID = &DGA_DirectDraw_GUID;
4230 else
4231 lpGUID = &XLIB_DirectDraw_GUID;
4234 wc.style = CS_GLOBALCLASS;
4235 wc.lpfnWndProc = Xlib_DDWndProc;
4236 wc.cbClsExtra = 0;
4237 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
4238 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
4240 /* We can be a child of the desktop since we're really important */
4242 This code is not useful since hInstance is forced to 0 afterward
4243 pParentWindow = WIN_GetDesktop();
4244 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
4246 wc.hInstance = 0;
4249 wc.hIcon = 0;
4250 wc.hCursor = (HCURSOR)IDC_ARROWA;
4251 wc.hbrBackground= NULL_BRUSH;
4252 wc.lpszMenuName = 0;
4253 wc.lpszClassName= "WINE_DirectDraw";
4254 RegisterClassA(&wc);
4256 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4257 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4258 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4259 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4260 else
4261 goto err;
4264 (*lplpDD)->d.winclass = RegisterClassA(&wc);
4265 return ret;
4267 err:
4268 ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4269 return DDERR_INVALIDDIRECTDRAWGUID;
4273 #else /* !defined(X_DISPLAY_MISSING) */
4275 #include "windef.h"
4277 #define DD_OK 0
4279 typedef void *LPGUID;
4280 typedef void *LPUNKNOWN;
4281 typedef void *LPDIRECTDRAW;
4282 typedef void *LPDIRECTDRAWCLIPPER;
4283 typedef void *LPDDENUMCALLBACKA;
4284 typedef void *LPDDENUMCALLBACKEXA;
4285 typedef void *LPDDENUMCALLBACKEXW;
4286 typedef void *LPDDENUMCALLBACKW;
4288 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
4290 return DD_OK;
4293 HRESULT WINAPI DirectDrawCreate(
4294 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
4296 return DD_OK;
4299 HRESULT WINAPI DirectDrawCreateClipper(
4300 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
4302 return DD_OK;
4305 HRESULT WINAPI DirectDrawEnumerateA(
4306 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
4308 return DD_OK;
4311 HRESULT WINAPI DirectDrawEnumerateExA(
4312 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
4314 return DD_OK;
4317 HRESULT WINAPI DirectDrawEnumerateExW(
4318 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
4320 return DD_OK;
4323 HRESULT WINAPI DirectDrawEnumerateW(
4324 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
4326 return DD_OK;
4329 #endif /* !defined(X_DISPLAY_MISSING) */