- added definition of DirectDrawCreateClipper.
[wine/multimedia.git] / graphics / ddraw.c
blob1969b44471e3ff35d0962013fa0d0f0399322063
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 */
5 /* XF86DGA:
6 * When DirectVideo mode is enabled you can no longer use 'normal' X
7 * applications nor can you switch to a virtual console. Also, enabling
8 * only works, if you have switched to the screen where the application
9 * is running.
10 * Some ways to debug this stuff are:
11 * - A terminal connected to the serial port. Can be bought used for cheap.
12 * (This is the method I am using.)
13 * - Another machine connected over some kind of network.
16 #include "config.h"
17 #include <unistd.h>
18 #include <assert.h>
19 #include "ts_xlib.h"
20 #include <sys/signal.h>
21 #include <fcntl.h>
22 #include <string.h>
24 #include "windows.h"
25 #include "winerror.h"
26 #include "interfaces.h"
27 #include "gdi.h"
28 #include "heap.h"
29 #include "ldt.h"
30 #include "dc.h"
31 #include "win.h"
32 #include "miscemu.h"
33 #include "ddraw.h"
34 #include "d3d.h"
35 #include "debug.h"
36 #include "compobj.h"
37 #include "spy.h"
38 #include "message.h"
39 #include "x11drv.h"
40 #include "options.h"
42 #ifdef HAVE_LIBXXF86DGA
43 #include "ts_xf86dga.h"
44 #endif
46 #ifdef HAVE_LIBXXSHM
47 #include <sys/types.h>
48 #include <sys/ipc.h>
49 #include <sys/shm.h>
50 #include "ts_xshm.h"
51 #endif
53 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
54 #undef DIABLO_HACK
56 /* Restore signal handlers overwritten by XF86DGA
57 * this is a define, for it will only work in emulator mode
59 #undef RESTORE_SIGNALS
61 /* Where do these GUIDs come from? mkuuid.
62 * They exist solely to distinguish between the targets Wine support,
63 * and should be different than any other GUIDs in existence.
65 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
66 0xe2dcb020,
67 0xdc60,
68 0x11d1,
69 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
72 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
73 0x1574a740,
74 0xdc61,
75 0x11d1,
76 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
79 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
80 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
81 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
82 static struct IDirectDrawClipper_VTable ddclipvt;
83 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
84 static struct IDirect3D_VTable d3dvt;
85 static struct IDirect3D2_VTable d3d2vt;
87 BOOL32
88 DDRAW_DGA_Available()
90 #ifdef HAVE_LIBXXF86DGA
91 int evbase, evret, fd;
93 if (Options.noDGA)
94 return 0;
96 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
97 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
98 /* others. --stephenc */
99 if ((fd = open("/dev/mem", O_RDWR)) != -1)
100 close(fd);
102 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
103 #else /* defined(HAVE_LIBXXF86DGA) */
104 return 0;
105 #endif /* defined(HAVE_LIBXXF86DGA) */
108 HRESULT WINAPI
109 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
110 if (DDRAW_DGA_Available()) {
111 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
113 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
114 ddenumproc(NULL,"WINE","display",data);
115 return 0;
118 /* What is this doing here? */
119 HRESULT WINAPI
120 DSoundHelp(DWORD x,DWORD y,DWORD z) {
121 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
122 return 0;
126 /******************************************************************************
127 * internal helper functions
129 static void _dump_DDBLTFX(DWORD flagmask) {
130 int i;
131 const struct {
132 DWORD mask;
133 char *name;
134 } flags[] = {
135 #define FE(x) { x, #x},
136 FE(DDBLTFX_ARITHSTRETCHY)
137 FE(DDBLTFX_MIRRORLEFTRIGHT)
138 FE(DDBLTFX_MIRRORUPDOWN)
139 FE(DDBLTFX_NOTEARING)
140 FE(DDBLTFX_ROTATE180)
141 FE(DDBLTFX_ROTATE270)
142 FE(DDBLTFX_ROTATE90)
143 FE(DDBLTFX_ZBUFFERRANGE)
144 FE(DDBLTFX_ZBUFFERBASEDEST)
146 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
147 if (flags[i].mask & flagmask) {
148 DUMP("%s ",flags[i].name);
151 DUMP("\n");
155 static void _dump_DDBLTFAST(DWORD flagmask) {
156 int i;
157 const struct {
158 DWORD mask;
159 char *name;
160 } flags[] = {
161 #define FE(x) { x, #x},
162 FE(DDBLTFAST_NOCOLORKEY)
163 FE(DDBLTFAST_SRCCOLORKEY)
164 FE(DDBLTFAST_DESTCOLORKEY)
165 FE(DDBLTFAST_WAIT)
167 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
168 if (flags[i].mask & flagmask)
169 DUMP("%s ",flags[i].name);
170 DUMP("\n");
173 static void _dump_DDBLT(DWORD flagmask) {
174 int i;
175 const struct {
176 DWORD mask;
177 char *name;
178 } flags[] = {
179 #define FE(x) { x, #x},
180 FE(DDBLT_ALPHADEST)
181 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
182 FE(DDBLT_ALPHADESTNEG)
183 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
184 FE(DDBLT_ALPHAEDGEBLEND)
185 FE(DDBLT_ALPHASRC)
186 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
187 FE(DDBLT_ALPHASRCNEG)
188 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
189 FE(DDBLT_ASYNC)
190 FE(DDBLT_COLORFILL)
191 FE(DDBLT_DDFX)
192 FE(DDBLT_DDROPS)
193 FE(DDBLT_KEYDEST)
194 FE(DDBLT_KEYDESTOVERRIDE)
195 FE(DDBLT_KEYSRC)
196 FE(DDBLT_KEYSRCOVERRIDE)
197 FE(DDBLT_ROP)
198 FE(DDBLT_ROTATIONANGLE)
199 FE(DDBLT_ZBUFFER)
200 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
201 FE(DDBLT_ZBUFFERDESTOVERRIDE)
202 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
203 FE(DDBLT_ZBUFFERSRCOVERRIDE)
204 FE(DDBLT_WAIT)
205 FE(DDBLT_DEPTHFILL)
207 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
208 if (flags[i].mask & flagmask)
209 DUMP("%s ",flags[i].name);
212 static void _dump_DDSCAPS(DWORD flagmask) {
213 int i;
214 const struct {
215 DWORD mask;
216 char *name;
217 } flags[] = {
218 #define FE(x) { x, #x},
219 FE(DDSCAPS_RESERVED1)
220 FE(DDSCAPS_ALPHA)
221 FE(DDSCAPS_BACKBUFFER)
222 FE(DDSCAPS_COMPLEX)
223 FE(DDSCAPS_FLIP)
224 FE(DDSCAPS_FRONTBUFFER)
225 FE(DDSCAPS_OFFSCREENPLAIN)
226 FE(DDSCAPS_OVERLAY)
227 FE(DDSCAPS_PALETTE)
228 FE(DDSCAPS_PRIMARYSURFACE)
229 FE(DDSCAPS_PRIMARYSURFACELEFT)
230 FE(DDSCAPS_SYSTEMMEMORY)
231 FE(DDSCAPS_TEXTURE)
232 FE(DDSCAPS_3DDEVICE)
233 FE(DDSCAPS_VIDEOMEMORY)
234 FE(DDSCAPS_VISIBLE)
235 FE(DDSCAPS_WRITEONLY)
236 FE(DDSCAPS_ZBUFFER)
237 FE(DDSCAPS_OWNDC)
238 FE(DDSCAPS_LIVEVIDEO)
239 FE(DDSCAPS_HWCODEC)
240 FE(DDSCAPS_MODEX)
241 FE(DDSCAPS_MIPMAP)
242 FE(DDSCAPS_RESERVED2)
243 FE(DDSCAPS_ALLOCONLOAD)
244 FE(DDSCAPS_VIDEOPORT)
245 FE(DDSCAPS_LOCALVIDMEM)
246 FE(DDSCAPS_NONLOCALVIDMEM)
247 FE(DDSCAPS_STANDARDVGAMODE)
248 FE(DDSCAPS_OPTIMIZED)
250 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
251 if (flags[i].mask & flagmask)
252 DUMP("%s ",flags[i].name);
253 DUMP("\n");
256 static void _dump_DDSD(DWORD flagmask) {
257 int i;
258 const struct {
259 DWORD mask;
260 char *name;
261 } flags[] = {
262 FE(DDSD_CAPS)
263 FE(DDSD_HEIGHT)
264 FE(DDSD_WIDTH)
265 FE(DDSD_PITCH)
266 FE(DDSD_BACKBUFFERCOUNT)
267 FE(DDSD_ZBUFFERBITDEPTH)
268 FE(DDSD_ALPHABITDEPTH)
269 FE(DDSD_PIXELFORMAT)
270 FE(DDSD_CKDESTOVERLAY)
271 FE(DDSD_CKDESTBLT)
272 FE(DDSD_CKSRCOVERLAY)
273 FE(DDSD_CKSRCBLT)
274 FE(DDSD_MIPMAPCOUNT)
275 FE(DDSD_REFRESHRATE)
276 FE(DDSD_LINEARSIZE)
277 FE(DDSD_LPSURFACE)
279 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
280 if (flags[i].mask & flagmask)
281 DUMP("%s ",flags[i].name);
282 DUMP("\n");
285 static void _dump_DDCOLORKEY(DWORD flagmask) {
286 int i;
287 const struct {
288 DWORD mask;
289 char *name;
290 } flags[] = {
291 #define FE(x) { x, #x},
292 FE(DDPF_ALPHAPIXELS)
293 FE(DDPF_ALPHA)
294 FE(DDPF_FOURCC)
295 FE(DDPF_PALETTEINDEXED4)
296 FE(DDPF_PALETTEINDEXEDTO8)
297 FE(DDPF_PALETTEINDEXED8)
298 FE(DDPF_RGB)
299 FE(DDPF_COMPRESSED)
300 FE(DDPF_RGBTOYUV)
301 FE(DDPF_YUV)
302 FE(DDPF_ZBUFFER)
303 FE(DDPF_PALETTEINDEXED1)
304 FE(DDPF_PALETTEINDEXED2)
305 FE(DDPF_ZPIXELS)
307 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
308 if (flags[i].mask & flagmask)
309 DUMP("%s ",flags[i].name);
310 DUMP("\n");
313 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
314 _dump_DDCOLORKEY(pf->dwFlags);
315 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
316 DUMP("RBG bit cbout : %ld\n", pf->x.dwRGBBitCount);
317 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
318 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
321 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
322 static XVisualInfo *vi;
323 XVisualInfo vt;
324 int nitems;
326 if (!vi)
327 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
329 pf->dwFourCC = 0;
330 if (ddraw->d.depth==8) {
331 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
332 pf->x.dwRGBBitCount = 8;
333 pf->y.dwRBitMask = 0;
334 pf->z.dwGBitMask = 0;
335 pf->xx.dwBBitMask = 0;
336 pf->xy.dwRGBAlphaBitMask= 0;
337 return 0;
339 if (ddraw->d.depth==16) {
340 pf->dwFlags = DDPF_RGB;
341 pf->x.dwRGBBitCount = 16;
342 pf->y.dwRBitMask = vi[0].red_mask;
343 pf->z.dwGBitMask = vi[0].green_mask;
344 pf->xx.dwBBitMask = vi[0].blue_mask;
345 pf->xy.dwRGBAlphaBitMask= 0;
346 return 0;
348 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
349 return DDERR_GENERIC;
352 /******************************************************************************
353 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
355 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
356 * DDS and DDS2 use those functions. (Function calls did not change (except
357 * using different DirectDrawSurfaceX version), just added flags and functions)
359 static HRESULT WINAPI IDirectDrawSurface3_Lock(
360 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
362 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
363 this,lprect,lpddsd,flags,(DWORD)hnd);
364 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
365 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
366 this,lprect,lpddsd,flags,(DWORD)hnd);
368 /* First, copy the Surface description */
369 *lpddsd = this->s.surface_desc;
371 /* If asked only for a part, change the surface pointer */
372 if (lprect) {
373 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
374 lprect->top,lprect->left,lprect->bottom,lprect->right
376 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
377 (lprect->top*this->s.surface_desc.lPitch) +
378 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
379 } else {
380 assert(this->s.surface_desc.y.lpSurface);
382 return 0;
385 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
386 LPDIRECTDRAWSURFACE3 this,LPVOID surface
388 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
389 return 0;
392 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
393 LPDIRECTDRAWSURFACE3 this,LPVOID surface)
395 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
397 if (!this->s.ddraw->e.xlib.paintable)
398 return DD_OK;
400 /* Only redraw the screen when unlocking the buffer that is on screen */
401 if ((this->t.xlib.image != NULL) &&
402 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
403 #ifdef HAVE_LIBXXSHM
404 if (this->s.ddraw->e.xlib.xshm_active)
405 TSXShmPutImage(display,
406 this->s.ddraw->e.xlib.drawable,
407 DefaultGCOfScreen(screen),
408 this->t.xlib.image,
409 0, 0, 0, 0,
410 this->t.xlib.image->width,
411 this->t.xlib.image->height,
412 False);
413 else
414 #endif
415 TSXPutImage( display,
416 this->s.ddraw->e.xlib.drawable,
417 DefaultGCOfScreen(screen),
418 this->t.xlib.image,
419 0, 0, 0, 0,
420 this->t.xlib.image->width,
421 this->t.xlib.image->height);
423 if (this->s.palette && this->s.palette->cm)
424 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
427 return DD_OK;
430 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
431 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
433 #ifdef HAVE_LIBXXF86DGA
434 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
435 if (!flipto) {
436 if (this->s.backbuffer)
437 flipto = this->s.backbuffer;
438 else
439 flipto = this;
441 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
443 if (flipto->s.palette && flipto->s.palette->cm) {
444 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
446 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
448 if (flipto!=this) {
449 int tmp;
450 LPVOID ptmp;
452 tmp = this->t.dga.fb_height;
453 this->t.dga.fb_height = flipto->t.dga.fb_height;
454 flipto->t.dga.fb_height = tmp;
456 ptmp = this->s.surface_desc.y.lpSurface;
457 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
458 flipto->s.surface_desc.y.lpSurface = ptmp;
460 return 0;
461 #else /* defined(HAVE_LIBXXF86DGA) */
462 return E_UNEXPECTED;
463 #endif /* defined(HAVE_LIBXXF86DGA) */
466 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
467 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
469 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
470 if (!this->s.ddraw->e.xlib.paintable)
471 return 0;
473 if (!flipto) {
474 if (this->s.backbuffer)
475 flipto = this->s.backbuffer;
476 else
477 flipto = this;
480 #ifdef HAVE_LIBXXSHM
481 if (this->s.ddraw->e.xlib.xshm_active) {
482 TSXShmPutImage(display,
483 this->s.ddraw->e.xlib.drawable,
484 DefaultGCOfScreen(screen),
485 flipto->t.xlib.image,
486 0, 0, 0, 0,
487 flipto->t.xlib.image->width,
488 flipto->t.xlib.image->height,
489 False);
490 } else
491 #endif
492 TSXPutImage(display,
493 this->s.ddraw->e.xlib.drawable,
494 DefaultGCOfScreen(screen),
495 flipto->t.xlib.image,
496 0, 0, 0, 0,
497 flipto->t.xlib.image->width,
498 flipto->t.xlib.image->height);
500 if (flipto->s.palette && flipto->s.palette->cm) {
501 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,flipto->s.palette->cm);
503 if (flipto!=this) {
504 XImage *tmp;
505 LPVOID *surf;
506 tmp = this->t.xlib.image;
507 this->t.xlib.image = flipto->t.xlib.image;
508 flipto->t.xlib.image = tmp;
509 surf = this->s.surface_desc.y.lpSurface;
510 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
511 flipto->s.surface_desc.y.lpSurface = surf;
513 return 0;
517 /* The IDirectDrawSurface3::SetPalette method attaches the specified
518 * DirectDrawPalette object to a surface. The surface uses this palette for all
519 * subsequent operations. The palette change takes place immediately.
521 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
522 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
524 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
525 /* According to spec, we are only supposed to
526 * AddRef if this is not the same palette.
528 if( this->s.palette != pal )
530 if( pal != NULL )
531 pal->lpvtbl->fnAddRef( pal );
532 if( this->s.palette != NULL )
533 this->s.palette->lpvtbl->fnRelease( this->s.palette );
534 this->s.palette = pal;
536 /* I think that we need to attach it to all backbuffers...*/
537 if( this->s.backbuffer ) {
538 if( this->s.backbuffer->s.palette )
539 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
540 this->s.backbuffer->s.palette );
541 this->s.backbuffer->s.palette = pal;
542 if( pal )
543 pal->lpvtbl->fnAddRef( pal );
546 /* Perform the refresh */
547 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
550 return 0;
553 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
554 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
556 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
557 #ifdef HAVE_LIBXXF86DGA
558 /* According to spec, we are only supposed to
559 * AddRef if this is not the same palette.
561 if( this->s.palette != pal )
563 if( pal != NULL )
564 pal->lpvtbl->fnAddRef( pal );
565 if( this->s.palette != NULL )
566 this->s.palette->lpvtbl->fnRelease( this->s.palette );
567 this->s.palette = pal;
569 /* I think that we need to attach it to all backbuffers...*/
570 if( this->s.backbuffer ) {
571 if( this->s.backbuffer->s.palette )
572 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
573 this->s.backbuffer->s.palette = pal;
574 if( pal ) pal->lpvtbl->fnAddRef( pal );
576 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
578 return 0;
579 #else /* defined(HAVE_LIBXXF86DGA) */
580 return E_UNEXPECTED;
581 #endif /* defined(HAVE_LIBXXF86DGA) */
586 static HRESULT WINAPI IDirectDrawSurface3_Blt(
587 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
589 RECT32 xdst,xsrc;
590 DDSURFACEDESC ddesc,sdesc;
591 int i,j;
593 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
594 this,rdst,src,rsrc,dwFlags,lpbltfx);
596 if (src != NULL)
597 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
598 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
600 if (TRACE_ON(ddraw)) {
601 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
602 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
603 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
604 if (dwFlags & DDBLT_DDFX) {
605 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
609 if (rdst) {
610 memcpy(&xdst,rdst,sizeof(xdst));
611 } else {
612 xdst.top = 0;
613 xdst.bottom = ddesc.dwHeight;
614 xdst.left = 0;
615 xdst.right = ddesc.dwWidth;
618 if (rsrc) {
619 memcpy(&xsrc,rsrc,sizeof(xsrc));
620 } else {
621 if (src) {
622 xsrc.top = 0;
623 xsrc.bottom = sdesc.dwHeight;
624 xsrc.left = 0;
625 xsrc.right = sdesc.dwWidth;
626 } else {
627 memset(&xsrc,0,sizeof(xsrc));
631 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
633 if (dwFlags & DDBLT_COLORFILL) {
634 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
635 LPBYTE xline,xpixel;
637 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
638 for (i=xdst.top;i<xdst.bottom;i++) {
639 xpixel = xline+bpp*xdst.left;
641 for (j=xdst.left;j<xdst.right;j++) {
642 /* FIXME: this only works on little endian
643 * architectures, where DWORD starts with low
644 * byte first!
646 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
647 xpixel += bpp;
649 xline += ddesc.lPitch;
651 dwFlags &= ~(DDBLT_COLORFILL);
654 if (!src) {
655 if (dwFlags) {
656 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
658 return 0;
661 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
662 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
663 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
664 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
665 !dwFlags
667 memcpy(ddesc.y.lpSurface,
668 sdesc.y.lpSurface,
669 ddesc.dwHeight * ddesc.lPitch);
670 } else {
671 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
672 int height = xsrc.bottom - xsrc.top;
673 int width = (xsrc.right - xsrc.left) * bpp;
674 int h;
676 for (h = 0; h < height; h++) {
677 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
678 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
679 width);
683 if (dwFlags && FIXME_ON(ddraw)) {
684 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
687 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
688 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
690 return 0;
693 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
694 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
696 int i,bpp;
697 DDSURFACEDESC ddesc,sdesc;
699 if (TRACE_ON(ddraw)) {
700 TRACE(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
701 this,dstx,dsty,src,rsrc,trans
703 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
704 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
706 /* We need to lock the surfaces, or we won't get refreshes when done */
707 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
708 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
709 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
710 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
711 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
712 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
713 (rsrc->right-rsrc->left)*bpp
716 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
717 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
718 return 0;
721 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
722 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
724 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
725 this,ddbltbatch,x,y
727 return 0;
730 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
731 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
733 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
734 caps->dwCaps = DDCAPS_PALETTE; /* probably more */
735 return 0;
738 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
739 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
740 ) {
741 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
742 this,ddsd);
744 /* Simply copy the surface description stored in the object */
745 *ddsd = this->s.surface_desc;
747 if (TRACE_ON(ddraw)) {
748 fprintf(stderr," flags: ");
749 _dump_DDSD(ddsd->dwFlags);
750 if (ddsd->dwFlags & DDSD_CAPS) {
751 fprintf(stderr, " caps: ");
752 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
754 fprintf(stderr,"\n");
757 return 0;
760 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
761 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
763 return ++(this->ref);
766 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
767 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
769 #ifdef HAVE_LIBXXF86DGA
770 if (!--(this->ref)) {
771 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
772 /* clear out of surface list */
773 if (this->t.dga.fb_height == -1) {
774 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
775 } else {
776 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
778 HeapFree(GetProcessHeap(),0,this);
779 return 0;
781 #endif /* defined(HAVE_LIBXXF86DGA) */
782 return this->ref;
785 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
786 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
788 if (!--(this->ref)) {
789 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
791 if( this->s.backbuffer )
792 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
794 if (this->t.xlib.image != NULL) {
795 this->t.xlib.image->data = NULL;
797 #ifdef HAVE_LIBXXSHM
798 if (this->s.ddraw->e.xlib.xshm_active) {
799 TSXShmDetach(display, &(this->t.xlib.shminfo));
800 TSXDestroyImage(this->t.xlib.image);
801 shmdt(this->t.xlib.shminfo.shmaddr);
802 } else {
803 #endif
804 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
805 TSXDestroyImage(this->t.xlib.image);
806 #ifdef HAVE_LIBXXSHM
808 #endif
810 this->t.xlib.image = 0;
811 } else {
812 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
815 if (this->s.palette)
816 this->s.palette->lpvtbl->fnRelease(this->s.palette);
818 HeapFree(GetProcessHeap(),0,this);
819 return 0;
822 return this->ref;
825 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
826 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
828 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
829 this, lpddsd, lpdsf);
831 if (TRACE_ON(ddraw)) {
832 TRACE(ddraw," caps ");
833 _dump_DDSCAPS(lpddsd->dwCaps);
836 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
837 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
838 return E_FAIL;
841 /* FIXME: should handle more than one backbuffer */
842 *lpdsf = this->s.backbuffer;
844 if( this->s.backbuffer )
845 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
847 return 0;
850 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
851 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
853 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
855 return DDERR_ALREADYINITIALIZED;
858 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
859 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
861 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
863 *pf = this->s.surface_desc.ddpfPixelFormat;
865 return 0;
868 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
869 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
870 return 0;
873 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
874 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
876 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
877 return 0;
880 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
881 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
883 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
884 return 0;
887 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
888 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
890 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
892 /* This hack will be enough for the moment */
893 if (this->s.backbuffer == NULL)
894 this->s.backbuffer = surf;
895 return 0;
898 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
899 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
900 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
901 return 0;
904 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
905 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
906 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
907 return 0;
911 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
912 char xrefiid[50];
914 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
915 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
917 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
918 * the same interface. And IUnknown does that too of course.
920 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
921 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
922 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
923 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
925 *obj = this;
926 this->lpvtbl->fnAddRef(this);
927 return 0;
929 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
930 return OLE_E_ENUM_NOMORE;
933 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
934 TRACE(ddraw,"(%p)->(), stub!\n",this);
935 return 0; /* hmm */
938 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
939 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
940 return 0;
943 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
944 FIXME(ddraw,"(%p)->(),stub!\n",this);
945 return 0;
948 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
949 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
951 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
953 if( dwFlags & DDCKEY_SRCBLT )
954 dwFlags &= ~DDCKEY_SRCBLT;
955 if( dwFlags )
956 TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
957 return DD_OK;
960 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
961 LPDIRECTDRAWSURFACE3 this,
962 LPRECT32 lpRect )
964 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
966 return DD_OK;
969 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
970 LPDIRECTDRAWSURFACE3 this,
971 DWORD dwFlags,
972 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
974 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
976 return DD_OK;
979 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
980 LPDIRECTDRAWSURFACE3 this,
981 DWORD dwFlags,
982 LPVOID lpContext,
983 LPDDENUMSURFACESCALLBACK lpfnCallback )
985 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
986 lpContext, lpfnCallback );
988 return DD_OK;
991 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
992 LPDIRECTDRAWSURFACE3 this,
993 LPDIRECTDRAWCLIPPER* lplpDDClipper )
995 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
997 return DD_OK;
1000 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
1001 LPDIRECTDRAWSURFACE3 this,
1002 DWORD dwFlags,
1003 LPDDCOLORKEY lpDDColorKey )
1005 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDColorKey);
1007 return DD_OK;
1010 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
1011 LPDIRECTDRAWSURFACE3 this,
1012 DWORD dwFlags )
1014 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1016 return DD_OK;
1019 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
1020 LPDIRECTDRAWSURFACE3 this,
1021 LPDIRECTDRAWPALETTE* lplpDDPalette )
1023 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1025 return DD_OK;
1028 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
1029 LPDIRECTDRAWSURFACE3 this,
1030 LONG lX,
1031 LONG lY)
1033 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1035 return DD_OK;
1038 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
1039 LPDIRECTDRAWSURFACE3 this,
1040 LPRECT32 lpSrcRect,
1041 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
1042 LPRECT32 lpDestRect,
1043 DWORD dwFlags,
1044 LPDDOVERLAYFX lpDDOverlayFx )
1046 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1047 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1049 return DD_OK;
1052 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
1053 LPDIRECTDRAWSURFACE3 this,
1054 DWORD dwFlags )
1056 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1058 return DD_OK;
1061 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
1062 LPDIRECTDRAWSURFACE3 this,
1063 DWORD dwFlags,
1064 LPDIRECTDRAWSURFACE3 lpDDSReference )
1066 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1068 return DD_OK;
1071 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
1072 LPDIRECTDRAWSURFACE3 this,
1073 LPVOID* lplpDD )
1075 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1077 return DD_OK;
1080 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
1081 LPDIRECTDRAWSURFACE3 this,
1082 DWORD dwFlags )
1084 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1086 return DD_OK;
1089 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
1090 LPDIRECTDRAWSURFACE3 this,
1091 DWORD dwFlags )
1093 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1095 return DD_OK;
1098 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1099 LPDIRECTDRAWSURFACE3 this,
1100 LPDDSURFACEDESC lpDDSD,
1101 DWORD dwFlags )
1103 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1105 return DD_OK;
1108 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1109 IDirectDrawSurface3_QueryInterface,
1110 IDirectDrawSurface3_AddRef,
1111 DGA_IDirectDrawSurface3_Release,
1112 IDirectDrawSurface3_AddAttachedSurface,
1113 IDirectDrawSurface3_AddOverlayDirtyRect,
1114 IDirectDrawSurface3_Blt,
1115 IDirectDrawSurface3_BltBatch,
1116 IDirectDrawSurface3_BltFast,
1117 IDirectDrawSurface3_DeleteAttachedSurface,
1118 IDirectDrawSurface3_EnumAttachedSurfaces,
1119 IDirectDrawSurface3_EnumOverlayZOrders,
1120 DGA_IDirectDrawSurface3_Flip,
1121 IDirectDrawSurface3_GetAttachedSurface,
1122 IDirectDrawSurface3_GetBltStatus,
1123 IDirectDrawSurface3_GetCaps,
1124 IDirectDrawSurface3_GetClipper,
1125 IDirectDrawSurface3_GetColorKey,
1126 IDirectDrawSurface3_GetDC,
1127 IDirectDrawSurface3_GetFlipStatus,
1128 IDirectDrawSurface3_GetOverlayPosition,
1129 IDirectDrawSurface3_GetPalette,
1130 IDirectDrawSurface3_GetPixelFormat,
1131 IDirectDrawSurface3_GetSurfaceDesc,
1132 IDirectDrawSurface3_Initialize,
1133 IDirectDrawSurface3_IsLost,
1134 IDirectDrawSurface3_Lock,
1135 IDirectDrawSurface3_ReleaseDC,
1136 IDirectDrawSurface3_Restore,
1137 IDirectDrawSurface3_SetClipper,
1138 IDirectDrawSurface3_SetColorKey,
1139 IDirectDrawSurface3_SetOverlayPosition,
1140 DGA_IDirectDrawSurface3_SetPalette,
1141 DGA_IDirectDrawSurface3_Unlock,
1142 IDirectDrawSurface3_UpdateOverlay,
1143 IDirectDrawSurface3_UpdateOverlayDisplay,
1144 IDirectDrawSurface3_UpdateOverlayZOrder,
1145 IDirectDrawSurface3_GetDDInterface,
1146 IDirectDrawSurface3_PageLock,
1147 IDirectDrawSurface3_PageUnlock,
1148 IDirectDrawSurface3_SetSurfaceDesc,
1151 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1152 IDirectDrawSurface3_QueryInterface,
1153 IDirectDrawSurface3_AddRef,
1154 Xlib_IDirectDrawSurface3_Release,
1155 IDirectDrawSurface3_AddAttachedSurface,
1156 IDirectDrawSurface3_AddOverlayDirtyRect,
1157 IDirectDrawSurface3_Blt,
1158 IDirectDrawSurface3_BltBatch,
1159 IDirectDrawSurface3_BltFast,
1160 IDirectDrawSurface3_DeleteAttachedSurface,
1161 IDirectDrawSurface3_EnumAttachedSurfaces,
1162 IDirectDrawSurface3_EnumOverlayZOrders,
1163 Xlib_IDirectDrawSurface3_Flip,
1164 IDirectDrawSurface3_GetAttachedSurface,
1165 IDirectDrawSurface3_GetBltStatus,
1166 IDirectDrawSurface3_GetCaps,
1167 IDirectDrawSurface3_GetClipper,
1168 IDirectDrawSurface3_GetColorKey,
1169 IDirectDrawSurface3_GetDC,
1170 IDirectDrawSurface3_GetFlipStatus,
1171 IDirectDrawSurface3_GetOverlayPosition,
1172 IDirectDrawSurface3_GetPalette,
1173 IDirectDrawSurface3_GetPixelFormat,
1174 IDirectDrawSurface3_GetSurfaceDesc,
1175 IDirectDrawSurface3_Initialize,
1176 IDirectDrawSurface3_IsLost,
1177 IDirectDrawSurface3_Lock,
1178 IDirectDrawSurface3_ReleaseDC,
1179 IDirectDrawSurface3_Restore,
1180 IDirectDrawSurface3_SetClipper,
1181 IDirectDrawSurface3_SetColorKey,
1182 IDirectDrawSurface3_SetOverlayPosition,
1183 Xlib_IDirectDrawSurface3_SetPalette,
1184 Xlib_IDirectDrawSurface3_Unlock,
1185 IDirectDrawSurface3_UpdateOverlay,
1186 IDirectDrawSurface3_UpdateOverlayDisplay,
1187 IDirectDrawSurface3_UpdateOverlayZOrder,
1188 IDirectDrawSurface3_GetDDInterface,
1189 IDirectDrawSurface3_PageLock,
1190 IDirectDrawSurface3_PageUnlock,
1191 IDirectDrawSurface3_SetSurfaceDesc,
1194 /******************************************************************************
1195 * DirectDrawCreateClipper (DDRAW.7)
1197 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1198 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1199 LPUNKNOWN pUnkOuter)
1201 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1203 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1204 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1205 (*lplpDDClipper)->ref = 1;
1207 return 0;
1210 /******************************************************************************
1211 * IDirectDrawClipper
1213 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1214 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1216 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1217 return 0;
1220 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1221 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1223 this->ref--;
1224 if (this->ref)
1225 return this->ref;
1226 HeapFree(GetProcessHeap(),0,this);
1227 return 0;
1230 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1231 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1233 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1234 if (hmm) *hmm=0;
1235 return 0;
1238 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1239 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1241 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1242 return 0;
1245 static struct IDirectDrawClipper_VTable ddclipvt = {
1246 (void*)1,
1247 (void*)2,
1248 IDirectDrawClipper_Release,
1249 IDirectDrawClipper_GetClipList,
1250 (void*)5,
1251 (void*)6,
1252 (void*)7,
1253 IDirectDrawClipper_SetClipList,
1254 IDirectDrawClipper_SetHwnd
1257 /******************************************************************************
1258 * IDirectDrawPalette
1260 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1261 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1263 int i;
1265 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1266 this,x,start,count,palent);
1268 if (!this->cm) /* should not happen */ {
1269 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1270 return DDERR_GENERIC;
1272 for (i=0;i<count;i++) {
1273 palent[i].peRed = this->palents[start+i].peRed;
1274 palent[i].peBlue = this->palents[start+i].peBlue;
1275 palent[i].peGreen = this->palents[start+i].peGreen;
1276 palent[i].peFlags = this->palents[start+i].peFlags;
1279 return 0;
1282 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1283 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1285 XColor xc;
1286 int i;
1288 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1289 this,x,start,count,palent
1291 if (!this->cm) /* should not happen */ {
1292 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1293 return DDERR_GENERIC;
1295 if (!this->ddraw->e.xlib.paintable)
1296 return 0;
1297 for (i=0;i<count;i++) {
1298 xc.red = palent[i].peRed<<8;
1299 xc.blue = palent[i].peBlue<<8;
1300 xc.green = palent[i].peGreen<<8;
1301 xc.flags = DoRed|DoBlue|DoGreen;
1302 xc.pixel = start+i;
1304 TSXStoreColor(display,this->cm,&xc);
1306 this->palents[start+i].peRed = palent[i].peRed;
1307 this->palents[start+i].peBlue = palent[i].peBlue;
1308 this->palents[start+i].peGreen = palent[i].peGreen;
1309 this->palents[start+i].peFlags = palent[i].peFlags;
1311 return 0;
1314 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1315 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1317 #ifdef HAVE_LIBXXF86DGA
1318 XColor xc;
1319 Colormap cm;
1320 int i;
1322 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1323 this,x,start,count,palent
1325 if (!this->cm) /* should not happen */ {
1326 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1327 return DDERR_GENERIC;
1329 /* FIXME: free colorcells instead of freeing whole map */
1330 cm = this->cm;
1331 this->cm = TSXCopyColormapAndFree(display,this->cm);
1332 TSXFreeColormap(display,cm);
1334 for (i=0;i<count;i++) {
1335 xc.red = palent[i].peRed<<8;
1336 xc.blue = palent[i].peBlue<<8;
1337 xc.green = palent[i].peGreen<<8;
1338 xc.flags = DoRed|DoBlue|DoGreen;
1339 xc.pixel = i+start;
1341 TSXStoreColor(display,this->cm,&xc);
1343 this->palents[start+i].peRed = palent[i].peRed;
1344 this->palents[start+i].peBlue = palent[i].peBlue;
1345 this->palents[start+i].peGreen = palent[i].peGreen;
1346 this->palents[start+i].peFlags = palent[i].peFlags;
1348 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1349 return 0;
1350 #else /* defined(HAVE_LIBXXF86DGA) */
1351 return E_UNEXPECTED;
1352 #endif /* defined(HAVE_LIBXXF86DGA) */
1355 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1356 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1357 if (!--(this->ref)) {
1358 if (this->cm) {
1359 TSXFreeColormap(display,this->cm);
1360 this->cm = 0;
1362 HeapFree(GetProcessHeap(),0,this);
1363 return 0;
1365 return this->ref;
1368 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1370 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1371 return ++(this->ref);
1374 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1375 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1377 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1379 return DDERR_ALREADYINITIALIZED;
1382 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1383 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1385 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1386 return DD_OK;
1389 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1390 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1392 char xrefiid[50];
1394 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1395 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1397 return S_OK;
1400 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1401 IDirectDrawPalette_QueryInterface,
1402 IDirectDrawPalette_AddRef,
1403 IDirectDrawPalette_Release,
1404 IDirectDrawPalette_GetCaps,
1405 IDirectDrawPalette_GetEntries,
1406 IDirectDrawPalette_Initialize,
1407 DGA_IDirectDrawPalette_SetEntries
1410 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1411 IDirectDrawPalette_QueryInterface,
1412 IDirectDrawPalette_AddRef,
1413 IDirectDrawPalette_Release,
1414 IDirectDrawPalette_GetCaps,
1415 IDirectDrawPalette_GetEntries,
1416 IDirectDrawPalette_Initialize,
1417 Xlib_IDirectDrawPalette_SetEntries
1420 /*******************************************************************************
1421 * IDirect3D
1423 static HRESULT WINAPI IDirect3D_QueryInterface(
1424 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1426 /* FIXME: Not sure if this is correct */
1427 char xrefiid[50];
1429 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1430 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1431 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1432 *obj = this;
1433 this->lpvtbl->fnAddRef(this);
1434 return 0;
1436 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1437 LPDIRECT3D d3d;
1439 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1440 d3d->ref = 1;
1441 d3d->ddraw = (LPDIRECTDRAW)this;
1442 this->lpvtbl->fnAddRef(this);
1443 d3d->lpvtbl = &d3dvt;
1444 *obj = d3d;
1445 return 0;
1447 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1448 LPDIRECT3D2 d3d;
1450 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1451 d3d->ref = 1;
1452 d3d->ddraw = (LPDIRECTDRAW)this;
1453 this->lpvtbl->fnAddRef(this);
1454 d3d->lpvtbl = &d3d2vt;
1455 *obj = d3d;
1456 return 0;
1458 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1459 return OLE_E_ENUM_NOMORE;
1462 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1463 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1465 return ++(this->ref);
1468 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1470 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1472 if (!--(this->ref)) {
1473 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1474 HeapFree(GetProcessHeap(),0,this);
1475 return 0;
1477 return this->ref;
1480 static HRESULT WINAPI IDirect3D_Initialize(
1481 LPDIRECT3D this, REFIID refiid )
1483 /* FIXME: Not sure if this is correct */
1484 char xrefiid[50];
1486 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1487 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1489 return DDERR_ALREADYINITIALIZED;
1492 /*******************************************************************************
1493 * IDirect3D
1495 static struct IDirect3D_VTable d3dvt = {
1496 (void*)IDirect3D_QueryInterface,
1497 (void*)IDirect3D_AddRef,
1498 (void*)IDirect3D_Release,
1499 IDirect3D_Initialize,
1500 (void*)5,
1501 (void*)6,
1502 (void*)7,
1503 (void*)8,
1504 (void*)9,
1507 /*******************************************************************************
1508 * IDirect3D2
1510 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1511 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1513 if (!--(this->ref)) {
1514 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1515 HeapFree(GetProcessHeap(),0,this);
1516 return 0;
1518 return this->ref;
1521 static HRESULT WINAPI IDirect3D2_EnumDevices(
1522 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1524 D3DDEVICEDESC d1,d2;
1526 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1527 #if 0
1528 d1.dwSize = sizeof(d1);
1529 d1.dwFlags = 0;
1531 d2.dwSize = sizeof(d2);
1532 d2.dwFlags = 0;
1533 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1534 #endif
1535 return 0;
1538 static struct IDirect3D2_VTable d3d2vt = {
1539 (void*)1,
1540 (void*)2,
1541 IDirect3D2_Release,
1542 IDirect3D2_EnumDevices,
1543 (void*)5,
1544 (void*)6,
1545 (void*)7,
1546 (void*)8,
1547 (void*)9,
1550 /*******************************************************************************
1551 * IDirectDraw
1554 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1555 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1557 static INT32 ddrawXlibThisOffset = 0;
1559 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
1560 LPDDSURFACEDESC lpddsd,
1561 LPDIRECTDRAWSURFACE lpdsf)
1563 int bpp;
1565 /* The surface was already allocated when entering in this function */
1566 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
1567 /* No pixel format => use DirectDraw's format */
1568 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
1569 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
1570 } else {
1571 /* To check what the program wants */
1572 if (TRACE_ON(ddraw)) {
1573 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
1577 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
1579 /* Copy the surface description */
1580 lpdsf->s.surface_desc = *lpddsd;
1582 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1583 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
1584 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
1586 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
1588 return 0;
1591 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1592 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1594 #ifdef HAVE_LIBXXF86DGA
1595 int i;
1597 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1598 if (TRACE_ON(ddraw)) {
1599 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1600 _dump_DDSD(lpddsd->dwFlags);
1601 fprintf(stderr,"caps ");
1602 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1603 fprintf(stderr,"]\n");
1606 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1607 this->lpvtbl->fnAddRef(this);
1608 (*lpdsf)->ref = 1;
1609 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1610 (*lpdsf)->s.ddraw = this;
1611 (*lpdsf)->s.palette = NULL;
1612 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
1614 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1615 lpddsd->dwWidth = this->d.width;
1616 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1617 lpddsd->dwHeight = this->d.height;
1619 /* Check if this a 'primary surface' or not */
1620 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1621 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1623 /* This is THE primary surface => there is DGA-specific code */
1624 /* First, store the surface description */
1625 (*lpdsf)->s.surface_desc = *lpddsd;
1627 /* Find a viewport */
1628 for (i=0;i<32;i++)
1629 if (!(this->e.dga.vpmask & (1<<i)))
1630 break;
1631 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1632 /* if i == 32 or maximum ... return error */
1633 this->e.dga.vpmask|=(1<<i);
1634 (*lpdsf)->s.surface_desc.y.lpSurface =
1635 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1636 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1637 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
1638 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
1640 /* Add flags if there were not present */
1641 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1642 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1643 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1644 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1645 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1646 (*lpdsf)->s.backbuffer = NULL;
1648 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1649 LPDIRECTDRAWSURFACE3 back;
1651 if (lpddsd->dwBackBufferCount>1)
1652 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1654 (*lpdsf)->s.backbuffer = back =
1655 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1656 this->lpvtbl->fnAddRef(this);
1657 back->ref = 1;
1658 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1659 for (i=0;i<32;i++)
1660 if (!(this->e.dga.vpmask & (1<<i)))
1661 break;
1662 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1663 /* if i == 32 or maximum ... return error */
1664 this->e.dga.vpmask|=(1<<i);
1665 back->t.dga.fb_height = i*this->e.dga.fb_height;
1667 /* Copy the surface description from the front buffer */
1668 back->s.surface_desc = (*lpdsf)->s.surface_desc;
1669 /* Change the parameters that are not the same */
1670 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
1671 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1672 back->s.ddraw = this;
1673 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1674 * one! */
1676 /* Add relevant info to front and back buffers */
1677 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1678 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
1679 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1680 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
1682 } else {
1683 /* There is no DGA-specific code here...
1684 Go to the common surface creation function */
1685 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
1688 return 0;
1689 #else /* defined(HAVE_LIBXXF86DGA) */
1690 return E_UNEXPECTED;
1691 #endif /* defined(HAVE_LIBXXF86DGA) */
1694 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
1695 XImage *img;
1697 #ifdef HAVE_LIBXXSHM
1698 if (this->e.xlib.xshm_active) {
1699 img = TSXShmCreateImage(display,
1700 DefaultVisualOfScreen(screen),
1701 this->d.depth,
1702 ZPixmap,
1703 NULL,
1704 &(lpdsf->t.xlib.shminfo),
1705 lpdsf->s.surface_desc.dwWidth,
1706 lpdsf->s.surface_desc.dwHeight);
1708 if (img == NULL)
1709 return NULL;
1711 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
1712 if (lpdsf->t.xlib.shminfo.shmid < 0) {
1713 TSXDestroyImage(img);
1714 return NULL;
1717 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
1719 if (img->data == (char *) -1) {
1720 TSXDestroyImage(img);
1721 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1722 return NULL;
1724 lpdsf->t.xlib.shminfo.readOnly = False;
1726 TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
1727 TSXSync(display, False);
1729 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1731 lpdsf->s.surface_desc.y.lpSurface = img->data;
1732 } else {
1733 #endif
1734 /* Allocate surface memory */
1735 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1736 lpdsf->s.surface_desc.dwWidth *
1737 lpdsf->s.surface_desc.dwHeight *
1738 (this->d.depth / 8));
1740 /* In this case, create an XImage */
1741 img =
1742 TSXCreateImage(display,
1743 DefaultVisualOfScreen(screen),
1744 this->d.depth,
1745 ZPixmap,
1747 lpdsf->s.surface_desc.y.lpSurface,
1748 lpdsf->s.surface_desc.dwWidth,
1749 lpdsf->s.surface_desc.dwHeight,
1751 lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8)
1754 #ifdef HAVE_LIBXXSHM
1756 #endif
1757 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
1759 return img;
1762 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1763 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1765 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1766 this,lpddsd,lpdsf,lpunk);
1768 if (TRACE_ON(ddraw)) {
1769 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1770 _dump_DDSD(lpddsd->dwFlags);
1771 fprintf(stderr,"caps ");
1772 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1773 fprintf(stderr,"]\n");
1776 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1778 this->lpvtbl->fnAddRef(this);
1779 (*lpdsf)->s.ddraw = this;
1780 (*lpdsf)->ref = 1;
1781 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1782 (*lpdsf)->s.palette = NULL;
1783 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
1785 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1786 lpddsd->dwWidth = this->d.width;
1787 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1788 lpddsd->dwHeight = this->d.height;
1790 /* Check if this a 'primary surface' or not */
1791 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1792 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1793 XImage *img;
1795 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
1797 /* First, store the surface description */
1798 (*lpdsf)->s.surface_desc = *lpddsd;
1800 /* Create the XImage */
1801 img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
1802 if (img == NULL)
1803 return DDERR_OUTOFMEMORY;
1804 (*lpdsf)->t.xlib.image = img;
1806 /* Add flags if there were not present */
1807 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1808 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1809 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1810 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1811 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1812 (*lpdsf)->s.backbuffer = NULL;
1814 /* Check for backbuffers */
1815 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1816 LPDIRECTDRAWSURFACE3 back;
1817 XImage *img;
1819 if (lpddsd->dwBackBufferCount>1)
1820 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1822 (*lpdsf)->s.backbuffer = back =
1823 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1825 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
1827 this->lpvtbl->fnAddRef(this);
1828 back->s.ddraw = this;
1830 back->ref = 1;
1831 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
1832 /* Copy the surface description from the front buffer */
1833 back->s.surface_desc = (*lpdsf)->s.surface_desc;
1835 /* Create the XImage */
1836 img = create_ximage(this, back);
1837 if (img == NULL)
1838 return DDERR_OUTOFMEMORY;
1839 back->t.xlib.image = img;
1841 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1842 * one! */
1844 /* Add relevant info to front and back buffers */
1845 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1846 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
1847 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1848 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
1850 } else {
1851 /* There is no Xlib-specific code here...
1852 Go to the common surface creation function */
1853 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
1856 return 0;
1859 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
1860 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1862 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1863 *dst = src; /* FIXME */
1864 return 0;
1868 * The Xlib Implementation tries to use the passed hwnd as drawing window,
1869 * even when the approbiate bitmasks are not specified.
1871 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1872 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
1874 int i;
1875 const struct {
1876 int mask;
1877 char *name;
1878 } flagmap[] = {
1879 FE(DDSCL_FULLSCREEN)
1880 FE(DDSCL_ALLOWREBOOT)
1881 FE(DDSCL_NOWINDOWCHANGES)
1882 FE(DDSCL_NORMAL)
1883 FE(DDSCL_ALLOWMODEX)
1884 FE(DDSCL_EXCLUSIVE)
1885 FE(DDSCL_SETFOCUSWINDOW)
1886 FE(DDSCL_SETDEVICEWINDOW)
1887 FE(DDSCL_CREATEDEVICEWINDOW)
1890 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
1891 if(TRACE_ON(ddraw)){
1892 dbg_decl_str(ddraw, 512);
1893 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1894 if (flagmap[i].mask & cooplevel)
1895 dsprintf(ddraw, "%s ", flagmap[i].name);
1896 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1898 this->d.mainWindow = hwnd;
1899 return 0;
1902 /* Small helper to either use the cooperative window or create a new
1903 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
1905 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
1906 RECT32 rect;
1908 /* Do not destroy the application supplied cooperative window */
1909 if (this->d.window && this->d.window != this->d.mainWindow) {
1910 DestroyWindow32(this->d.window);
1911 this->d.window = 0;
1913 /* Sanity check cooperative window before assigning it to drawing. */
1914 if ( IsWindow32(this->d.mainWindow) &&
1915 IsWindowVisible32(this->d.mainWindow)
1917 GetWindowRect32(this->d.mainWindow,&rect);
1918 if (((rect.right-rect.left) >= this->d.width) &&
1919 ((rect.bottom-rect.top) >= this->d.height)
1921 this->d.window = this->d.mainWindow;
1923 /* ... failed, create new one. */
1924 if (!this->d.window) {
1925 this->d.window = CreateWindowEx32A(
1927 "WINE_DirectDraw",
1928 "WINE_DirectDraw",
1929 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1930 0,0,
1931 this->d.width,
1932 this->d.height,
1936 NULL
1938 /*Store THIS with the window. We'll use it in the window procedure*/
1939 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
1940 ShowWindow32(this->d.window,TRUE);
1941 UpdateWindow32(this->d.window);
1945 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
1946 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1948 #ifdef HAVE_LIBXXF86DGA
1949 int i,*depths,depcount;
1951 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
1953 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1954 for (i=0;i<depcount;i++)
1955 if (depths[i]==depth)
1956 break;
1957 TSXFree(depths);
1958 if (i==depcount) {/* not found */
1959 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1960 return DDERR_UNSUPPORTEDMODE;
1962 if (this->d.width < width) {
1963 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
1964 return DDERR_UNSUPPORTEDMODE;
1966 this->d.width = width;
1967 this->d.height = height;
1968 this->d.depth = depth;
1970 /* adjust fb_height, so we don't overlap */
1971 if (this->e.dga.fb_height < height)
1972 this->e.dga.fb_height = height;
1973 _common_IDirectDraw_SetDisplayMode(this);
1975 /* FIXME: this function OVERWRITES several signal handlers.
1976 * can we save them? and restore them later? In a way that
1977 * it works for the library too?
1979 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
1980 #ifdef DIABLO_HACK
1981 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
1982 #endif
1984 #ifdef RESTORE_SIGNALS
1985 SIGNAL_InitEmulator();
1986 #endif
1987 return 0;
1988 #else /* defined(HAVE_LIBXXF86DGA) */
1989 return E_UNEXPECTED;
1990 #endif /* defined(HAVE_LIBXXF86DGA) */
1993 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
1994 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1996 int i,*depths,depcount;
1997 char buf[200];
1999 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2000 this, width, height, depth);
2002 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2003 for (i=0;i<depcount;i++)
2004 if (depths[i]==depth)
2005 break;
2006 TSXFree(depths);
2007 if (i==depcount) {/* not found */
2008 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2009 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2010 return DDERR_UNSUPPORTEDMODE;
2012 this->d.width = width;
2013 this->d.height = height;
2014 this->d.depth = depth;
2016 _common_IDirectDraw_SetDisplayMode(this);
2018 this->e.xlib.paintable = 1;
2019 this->e.xlib.drawable = WIN_FindWndPtr(this->d.window)->window;
2020 /* We don't have a context for this window. Host off the desktop */
2021 if( !this->e.xlib.drawable )
2022 this->e.xlib.drawable = WIN_GetDesktop()->window;
2023 return 0;
2026 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2027 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2029 #ifdef HAVE_LIBXXF86DGA
2030 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2031 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2032 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2033 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2034 if (caps2) {
2035 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2036 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2037 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2039 return 0;
2040 #else /* defined(HAVE_LIBXXF86DGA) */
2041 return E_UNEXPECTED;
2042 #endif /* defined(HAVE_LIBXXF86DGA) */
2045 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2046 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2048 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2049 /* FIXME: Xlib */
2050 caps1->dwVidMemTotal = 2048*1024;
2051 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2052 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2053 if (caps2) {
2054 caps2->dwVidMemTotal = 2048*1024;
2055 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2056 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2058 /* END FIXME: Xlib */
2059 return 0;
2062 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2063 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2065 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2066 this,x,lpddclip,lpunk
2068 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2069 (*lpddclip)->ref = 1;
2070 (*lpddclip)->lpvtbl = &ddclipvt;
2071 return 0;
2074 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2075 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2077 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2078 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2079 (*lpddpal)->ref = 1;
2080 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2081 (*lpddpal)->installed = 0;
2082 if (this->d.depth<=8) {
2083 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
2084 } else {
2085 /* we don't want palettes in hicolor or truecolor */
2086 (*lpddpal)->cm = 0;
2088 return 0;
2091 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2092 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2094 HRESULT res;
2095 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2096 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
2097 if (res != 0) return res;
2098 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2099 return 0;
2102 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2103 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2105 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2106 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2107 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2108 (*lpddpal)->ref = 1;
2109 (*lpddpal)->installed = 0;
2111 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2112 this->lpvtbl->fnAddRef(this);
2114 if (this->d.depth<=8) {
2115 (*lpddpal)->cm = TSXCreateColormap(display,this->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
2116 /* FIXME: this is not correct, when using -managed */
2117 TSXInstallColormap(display,(*lpddpal)->cm);
2119 else
2121 /* we don't want palettes in hicolor or truecolor */
2122 (*lpddpal)->cm = 0;
2125 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2126 return 0;
2129 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2130 #ifdef HAVE_LIBXXF86DGA
2131 TRACE(ddraw, "(%p)->()\n",this);
2132 Sleep(1000);
2133 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2134 #ifdef RESTORE_SIGNALS
2135 SIGNAL_InitEmulator();
2136 #endif
2137 return 0;
2138 #else /* defined(HAVE_LIBXXF86DGA) */
2139 return E_UNEXPECTED;
2140 #endif
2143 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2144 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
2145 Sleep(1000);
2146 return 0;
2149 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
2150 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
2152 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
2153 return 0;
2156 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
2157 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2159 return ++(this->ref);
2162 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2163 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2165 #ifdef HAVE_LIBXXF86DGA
2166 if (!--(this->ref)) {
2167 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2168 #ifdef RESTORE_SIGNALS
2169 SIGNAL_InitEmulator();
2170 #endif
2171 HeapFree(GetProcessHeap(),0,this);
2172 return 0;
2174 #endif /* defined(HAVE_LIBXXF86DGA) */
2175 return this->ref;
2178 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2179 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2181 if (!--(this->ref)) {
2182 HeapFree(GetProcessHeap(),0,this);
2183 return 0;
2185 /* FIXME: destroy window ... */
2186 return this->ref;
2189 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
2190 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2192 char xrefiid[50];
2194 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2195 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2196 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2197 *obj = this;
2198 this->lpvtbl->fnAddRef(this);
2199 return 0;
2201 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2202 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
2203 this->lpvtbl->fnAddRef(this);
2204 *obj = this;
2205 return 0;
2207 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2208 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
2209 this->lpvtbl->fnAddRef(this);
2210 *obj = this;
2211 return 0;
2213 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2214 LPDIRECT3D d3d;
2216 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2217 d3d->ref = 1;
2218 d3d->ddraw = (LPDIRECTDRAW)this;
2219 this->lpvtbl->fnAddRef(this);
2220 d3d->lpvtbl = &d3dvt;
2221 *obj = d3d;
2222 return 0;
2224 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2225 LPDIRECT3D2 d3d;
2227 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2228 d3d->ref = 1;
2229 d3d->ddraw = (LPDIRECTDRAW)this;
2230 this->lpvtbl->fnAddRef(this);
2231 d3d->lpvtbl = &d3d2vt;
2232 *obj = d3d;
2233 return 0;
2235 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2236 return OLE_E_ENUM_NOMORE;
2239 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
2240 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2242 char xrefiid[50];
2244 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2245 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2246 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2247 *obj = this;
2248 this->lpvtbl->fnAddRef(this);
2249 return 0;
2251 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2252 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2253 this->lpvtbl->fnAddRef(this);
2254 *obj = this;
2255 return 0;
2257 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2258 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2259 this->lpvtbl->fnAddRef(this);
2260 *obj = this;
2261 return 0;
2263 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2264 LPDIRECT3D d3d;
2266 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2267 d3d->ref = 1;
2268 d3d->ddraw = (LPDIRECTDRAW)this;
2269 this->lpvtbl->fnAddRef(this);
2270 d3d->lpvtbl = &d3dvt;
2271 *obj = d3d;
2272 return 0;
2274 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2275 LPDIRECT3D2 d3d;
2277 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2278 d3d->ref = 1;
2279 d3d->ddraw = (LPDIRECTDRAW)this;
2280 this->lpvtbl->fnAddRef(this);
2281 d3d->lpvtbl = &d3d2vt;
2282 *obj = d3d;
2283 return 0;
2285 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2286 return OLE_E_ENUM_NOMORE;
2289 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2290 LPDIRECTDRAW2 this,BOOL32 *status
2292 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2293 *status = TRUE;
2294 return 0;
2297 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2298 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2300 DDSURFACEDESC ddsfd;
2301 static struct {
2302 int w,h;
2303 } modes[5] = { /* some of the usual modes */
2304 {512,384},
2305 {640,400},
2306 {640,480},
2307 {800,600},
2308 {1024,768},
2310 static int depths[4] = {8,16,24,32};
2311 int i,j;
2313 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2314 ddsfd.dwSize = sizeof(ddsfd);
2315 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2316 if (dwFlags & DDEDM_REFRESHRATES) {
2317 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2318 ddsfd.x.dwRefreshRate = 60;
2321 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2322 ddsfd.dwBackBufferCount = 1;
2323 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2324 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2325 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2326 /* FIXME: those masks would have to be set in depth > 8 */
2327 if (depths[i]==8) {
2328 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2329 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2330 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2331 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2332 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2333 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2334 } else {
2335 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2337 /* FIXME: We should query those from X itself */
2338 switch (depths[i]) {
2339 case 16:
2340 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2341 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2342 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2343 break;
2344 case 24:
2345 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2346 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2347 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2348 break;
2349 case 32:
2350 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2351 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2352 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2353 break;
2357 ddsfd.dwWidth = screenWidth;
2358 ddsfd.dwHeight = screenHeight;
2359 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2360 if (!modescb(&ddsfd,context)) return 0;
2362 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2363 ddsfd.dwWidth = modes[j].w;
2364 ddsfd.dwHeight = modes[j].h;
2365 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2366 if (!modescb(&ddsfd,context)) return 0;
2369 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2370 /* modeX is not standard VGA */
2372 ddsfd.dwHeight = 200;
2373 ddsfd.dwWidth = 320;
2374 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2375 if (!modescb(&ddsfd,context)) return 0;
2378 return DD_OK;
2381 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2382 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2384 #ifdef HAVE_LIBXXF86DGA
2385 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2386 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2387 lpddsfd->dwHeight = screenHeight;
2388 lpddsfd->dwWidth = screenWidth;
2389 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2390 lpddsfd->dwBackBufferCount = 1;
2391 lpddsfd->x.dwRefreshRate = 60;
2392 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2393 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2394 return DD_OK;
2395 #else /* defined(HAVE_LIBXXF86DGA) */
2396 return E_UNEXPECTED;
2397 #endif /* defined(HAVE_LIBXXF86DGA) */
2400 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2401 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2403 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2404 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2405 lpddsfd->dwHeight = screenHeight;
2406 lpddsfd->dwWidth = screenWidth;
2407 /* POOLE FIXME: Xlib */
2408 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2409 /* END FIXME: Xlib */
2410 lpddsfd->dwBackBufferCount = 1;
2411 lpddsfd->x.dwRefreshRate = 60;
2412 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2413 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2414 return DD_OK;
2417 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2418 TRACE(ddraw,"(%p)->()\n",this);
2419 return DD_OK;
2422 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2423 LPDIRECTDRAW2 this,LPDWORD freq
2425 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2426 *freq = 60*100; /* 60 Hz */
2427 return 0;
2430 /* what can we directly decompress? */
2431 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2432 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2434 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2435 return 0;
2438 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2439 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2441 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2442 return 0;
2445 static HRESULT WINAPI IDirectDraw2_Compact(
2446 LPDIRECTDRAW2 this )
2448 FIXME(ddraw,"(%p)->()\n", this );
2450 return DD_OK;
2454 /* Note: Hack so we can reuse the old functions without compiler warnings */
2455 #ifdef __GNUC__
2456 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2457 #else
2458 # define XCAST(fun) (void*)
2459 #endif
2461 static struct IDirectDraw_VTable dga_ddvt = {
2462 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2463 XCAST(AddRef)IDirectDraw2_AddRef,
2464 XCAST(Release)DGA_IDirectDraw2_Release,
2465 XCAST(Compact)IDirectDraw2_Compact,
2466 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2467 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2468 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2469 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2470 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2471 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2472 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2473 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2474 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2475 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2476 XCAST(GetGDISurface)15,
2477 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2478 XCAST(GetScanLine)17,
2479 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2480 XCAST(Initialize)19,
2481 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2482 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2483 DGA_IDirectDraw_SetDisplayMode,
2484 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2487 static struct IDirectDraw_VTable xlib_ddvt = {
2488 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2489 XCAST(AddRef)IDirectDraw2_AddRef,
2490 XCAST(Release)Xlib_IDirectDraw2_Release,
2491 XCAST(Compact)IDirectDraw2_Compact,
2492 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2493 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2494 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2495 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2496 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2497 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2498 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2499 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2500 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2501 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2502 XCAST(GetGDISurface)15,
2503 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2504 XCAST(GetScanLine)17,
2505 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2506 XCAST(Initialize)19,
2507 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2508 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2509 Xlib_IDirectDraw_SetDisplayMode,
2510 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2513 /*****************************************************************************
2514 * IDirectDraw2
2519 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2520 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2522 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2525 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2526 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2528 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2531 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2532 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2534 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2535 this,ddscaps,total,free
2537 if (total) *total = this->e.dga.fb_memsize * 1024;
2538 if (free) *free = this->e.dga.fb_memsize * 1024;
2539 return 0;
2542 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2543 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2545 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2546 this,ddscaps,total,free
2548 if (total) *total = 2048 * 1024;
2549 if (free) *free = 2048 * 1024;
2550 return 0;
2553 static IDirectDraw2_VTable dga_dd2vt = {
2554 DGA_IDirectDraw2_QueryInterface,
2555 IDirectDraw2_AddRef,
2556 DGA_IDirectDraw2_Release,
2557 IDirectDraw2_Compact,
2558 IDirectDraw2_CreateClipper,
2559 DGA_IDirectDraw2_CreatePalette,
2560 DGA_IDirectDraw2_CreateSurface,
2561 (void*)8,
2562 IDirectDraw2_EnumDisplayModes,
2563 IDirectDraw2_EnumSurfaces,
2564 IDirectDraw2_FlipToGDISurface,
2565 DGA_IDirectDraw2_GetCaps,
2566 DGA_IDirectDraw2_GetDisplayMode,
2567 IDirectDraw2_GetFourCCCodes,
2568 (void*)15,
2569 IDirectDraw2_GetMonitorFrequency,
2570 (void*)17,
2571 IDirectDraw2_GetVerticalBlankStatus,
2572 (void*)19,
2573 DGA_IDirectDraw2_RestoreDisplayMode,
2574 IDirectDraw2_SetCooperativeLevel,
2575 DGA_IDirectDraw2_SetDisplayMode,
2576 IDirectDraw2_WaitForVerticalBlank,
2577 DGA_IDirectDraw2_GetAvailableVidMem
2580 static struct IDirectDraw2_VTable xlib_dd2vt = {
2581 Xlib_IDirectDraw2_QueryInterface,
2582 IDirectDraw2_AddRef,
2583 Xlib_IDirectDraw2_Release,
2584 IDirectDraw2_Compact,
2585 IDirectDraw2_CreateClipper,
2586 Xlib_IDirectDraw2_CreatePalette,
2587 Xlib_IDirectDraw2_CreateSurface,
2588 (void*)8,
2589 IDirectDraw2_EnumDisplayModes,
2590 IDirectDraw2_EnumSurfaces,
2591 IDirectDraw2_FlipToGDISurface,
2592 Xlib_IDirectDraw2_GetCaps,
2593 Xlib_IDirectDraw2_GetDisplayMode,
2594 IDirectDraw2_GetFourCCCodes,
2595 (void*)15,
2596 IDirectDraw2_GetMonitorFrequency,
2597 (void*)17,
2598 IDirectDraw2_GetVerticalBlankStatus,
2599 (void*)19,
2600 Xlib_IDirectDraw2_RestoreDisplayMode,
2601 IDirectDraw2_SetCooperativeLevel,
2602 Xlib_IDirectDraw2_SetDisplayMode,
2603 IDirectDraw2_WaitForVerticalBlank,
2604 Xlib_IDirectDraw2_GetAvailableVidMem
2607 /******************************************************************************
2608 * DirectDrawCreate
2611 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2613 LRESULT ret;
2614 LPDIRECTDRAW ddraw = NULL;
2615 DWORD lastError;
2617 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2619 SetLastError( ERROR_SUCCESS );
2620 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2621 if( (!ddraw) &&
2622 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2625 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2628 if( ddraw )
2630 /* Perform any special direct draw functions */
2631 if (msg==WM_PAINT)
2632 ddraw->e.xlib.paintable = 1;
2634 /* Now let the application deal with the rest of this */
2635 if( ddraw->d.mainWindow )
2638 /* Don't think that we actually need to call this but...
2639 might as well be on the safe side of things... */
2641 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
2642 it should be the procedures of our fake window that gets called
2643 instead of those of the window provided by the application.
2644 And with this patch, mouse clicks work with Monkey Island III
2645 - Lionel */
2646 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2648 if( !ret )
2650 /* We didn't handle the message - give it to the application */
2651 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
2652 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2653 ddraw->d.mainWindow, msg, wParam, lParam );
2657 } else {
2658 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
2662 else
2664 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2667 return ret;
2670 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2671 #ifdef HAVE_LIBXXF86DGA
2672 int memsize,banksize,width,major,minor,flags,height;
2673 char *addr;
2674 int fd;
2676 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
2677 if ((fd = open("/dev/mem", O_RDWR)) != -1)
2678 close(fd);
2680 if (fd == -1) {
2681 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
2682 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2683 return E_UNEXPECTED;
2685 if (!DDRAW_DGA_Available()) {
2686 TRACE(ddraw,"No XF86DGA detected.\n");
2687 return DDERR_GENERIC;
2689 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2690 (*lplpDD)->lpvtbl = &dga_ddvt;
2691 (*lplpDD)->ref = 1;
2692 TSXF86DGAQueryVersion(display,&major,&minor);
2693 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2694 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2695 if (!(flags & XF86DGADirectPresent))
2696 MSG("direct video is NOT PRESENT.\n");
2697 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2698 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2699 addr,width,banksize,memsize
2701 (*lplpDD)->e.dga.fb_width = width;
2702 (*lplpDD)->d.width = width;
2703 (*lplpDD)->e.dga.fb_addr = addr;
2704 (*lplpDD)->e.dga.fb_memsize = memsize;
2705 (*lplpDD)->e.dga.fb_banksize = banksize;
2707 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2708 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2709 (*lplpDD)->e.dga.fb_height = screenHeight;
2710 #ifdef DIABLO_HACK
2711 (*lplpDD)->e.dga.vpmask = 1;
2712 #else
2713 (*lplpDD)->e.dga.vpmask = 0;
2714 #endif
2716 /* just assume the default depth is the DGA depth too */
2717 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2718 #ifdef RESTORE_SIGNALS
2719 SIGNAL_InitEmulator();
2720 #endif
2722 return 0;
2723 #else /* defined(HAVE_LIBXXF86DGA) */
2724 return DDERR_INVALIDDIRECTDRAWGUID;
2725 #endif /* defined(HAVE_LIBXXF86DGA) */
2728 BOOL32
2729 DDRAW_XSHM_Available()
2731 #ifdef HAVE_LIBXXSHM
2732 if (TSXShmQueryExtension(display))
2734 int major, minor;
2735 Bool shpix;
2737 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
2738 return 1;
2739 else
2740 return 0;
2742 else
2743 return 0;
2744 #else
2745 return 0;
2746 #endif
2749 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2751 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2752 (*lplpDD)->lpvtbl = &xlib_ddvt;
2753 (*lplpDD)->ref = 1;
2754 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
2756 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2757 (*lplpDD)->d.height = screenHeight;
2758 (*lplpDD)->d.width = screenWidth;
2760 #ifdef HAVE_LIBXXSHM
2761 /* Test if XShm is available.
2762 As XShm is not ready yet for 'prime-time', it is disabled for now */
2763 if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
2764 TRACE(ddraw, "Using XShm extesion.\n");
2765 #endif
2767 return 0;
2770 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
2771 char xclsid[50];
2772 WNDCLASS32A wc;
2773 WND* pParentWindow;
2774 HRESULT ret;
2776 if (HIWORD(lpGUID))
2777 WINE_StringFromCLSID(lpGUID,xclsid);
2778 else {
2779 sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID);
2780 lpGUID = NULL;
2783 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
2785 if (!lpGUID) {
2786 /* if they didn't request a particular interface, use the best
2787 * supported one */
2788 if (DDRAW_DGA_Available())
2789 lpGUID = &DGA_DirectDraw_GUID;
2790 else
2791 lpGUID = &XLIB_DirectDraw_GUID;
2794 wc.style = CS_GLOBALCLASS;
2795 wc.lpfnWndProc = Xlib_DDWndProc;
2796 wc.cbClsExtra = 0;
2797 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
2798 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
2800 /* We can be a child of the desktop since we're really important */
2801 pParentWindow = WIN_GetDesktop();
2802 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
2803 wc.hInstance = 0;
2805 wc.hIcon = 0;
2806 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
2807 wc.hbrBackground= NULL_BRUSH;
2808 wc.lpszMenuName = 0;
2809 wc.lpszClassName= "WINE_DirectDraw";
2810 RegisterClass32A(&wc);
2812 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
2813 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
2814 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
2815 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
2816 else
2817 goto err;
2819 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
2820 return ret;
2822 err:
2823 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
2824 return DDERR_INVALIDDIRECTDRAWGUID;