Release 980927
[wine.git] / graphics / ddraw.c
blob7670832f71848f43a3f915b3f9da58b55eb01fa4
1 /* DirectDraw using DGA or Xlib
3 * Copyright 1997,1998 Marcus Meissner
4 */
5 /* When DirectVideo mode is enabled you can no longer use 'normal' X
6 * applications nor can you switch to a virtual console. Also, enabling
7 * only works, if you have switched to the screen where the application
8 * is running.
9 * Some ways to debug this stuff are:
10 * - A terminal connected to the serial port. Can be bought used for cheap.
11 * (This is the method I am using.)
12 * - Another machine connected over some kind of network.
14 * FIXME: The Xshm implementation has been temporarily removed. It will be
15 * later reintegrated into the Xlib implementation.
17 * FIXME: The Xlib implementation hangs the windowmanager and all other
18 * running X clients, even though I am polling X events and answering
19 * them. But you can switch to another console (ctrl-alt-fx) and
20 * "killall wine" processes. Any help on this one appreciated. -Marcus
21 * NOTE: The hanging only seems to happen with -managed. I have
22 * implemented support for the -desktop option. This seems
23 * to not have the hanging problems. - Peter Hunnisett
26 #include "config.h"
27 #include <unistd.h>
28 #include <assert.h>
29 #include "ts_xlib.h"
30 #include <sys/signal.h>
32 #include "windows.h"
33 #include "winerror.h"
34 #include "interfaces.h"
35 #include "gdi.h"
36 #include "heap.h"
37 #include "ldt.h"
38 #include "dc.h"
39 #include "win.h"
40 #include "miscemu.h"
41 #include "ddraw.h"
42 #include "d3d.h"
43 #include "debug.h"
44 #include "compobj.h"
45 #include "spy.h"
46 #include "message.h"
48 #ifdef HAVE_LIBXXF86DGA
49 #include "ts_xf86dga.h"
50 #endif
52 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
53 #undef DIABLO_HACK
55 /* restore signal handlers overwritten by XF86DGA
56 * this is a define, for it will only work in emulator mode
58 #undef RESTORE_SIGNALS
60 /* Where do these GUIDs come from? mkuuid.
61 * They exist solely to distinguish between the targets Wine support,
62 * and should be different than any other GUIDs in existence.
64 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
65 0xe2dcb020,
66 0xdc60,
67 0x11d1,
68 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
71 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
72 0x1574a740,
73 0xdc61,
74 0x11d1,
75 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
78 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
79 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
80 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
81 static struct IDirectDrawClipper_VTable ddclipvt;
82 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
83 static struct IDirect3D_VTable d3dvt;
84 static struct IDirect3D2_VTable d3d2vt;
86 void Xlib_MessagePump(HWND32 hwnd) {
87 MSG32 msg32;
89 while (EVENT_WaitNetEvent(FALSE,FALSE)) {
90 while (PeekMessage32A(&msg32,0,0,0,0)) {
91 GetMessage32A(&msg32,0,0,0);
92 TranslateMessage32(&msg32);
93 DispatchMessage32A(&msg32);
98 BOOL32
99 DDRAW_DGA_Available()
101 #ifdef HAVE_LIBXXF86DGA
102 int evbase, evret;
103 return (getuid() == 0)&&TSXF86DGAQueryExtension(display,&evbase,&evret);
104 #else /* defined(HAVE_LIBXXF86DGA) */
105 return 0;
106 #endif /* defined(HAVE_LIBXXF86DGA) */
109 HRESULT WINAPI
110 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
111 if (DDRAW_DGA_Available()) {
112 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
114 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
115 ddenumproc(NULL,"WINE","display",data);
116 return 0;
119 /* What is this doing here? */
120 HRESULT WINAPI
121 DSoundHelp(DWORD x,DWORD y,DWORD z) {
122 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
123 return 0;
127 /******************************************************************************
128 * internal helper functions
130 static void _dump_DDBLTFX(DWORD flagmask) {
131 int i;
132 const struct {
133 DWORD mask;
134 char *name;
135 } flags[] = {
136 #define FE(x) { x, #x},
137 FE(DDBLTFX_ARITHSTRETCHY)
138 FE(DDBLTFX_MIRRORLEFTRIGHT)
139 FE(DDBLTFX_MIRRORUPDOWN)
140 FE(DDBLTFX_NOTEARING)
141 FE(DDBLTFX_ROTATE180)
142 FE(DDBLTFX_ROTATE270)
143 FE(DDBLTFX_ROTATE90)
144 FE(DDBLTFX_ZBUFFERRANGE)
145 FE(DDBLTFX_ZBUFFERBASEDEST)
147 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
148 if (flags[i].mask & flagmask) {
149 DUMP("%s ",flags[i].name);
152 DUMP("\n");
156 static void _dump_DDBLTFAST(DWORD flagmask) {
157 int i;
158 const struct {
159 DWORD mask;
160 char *name;
161 } flags[] = {
162 #define FE(x) { x, #x},
163 FE(DDBLTFAST_NOCOLORKEY)
164 FE(DDBLTFAST_SRCCOLORKEY)
165 FE(DDBLTFAST_DESTCOLORKEY)
166 FE(DDBLTFAST_WAIT)
168 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
169 if (flags[i].mask & flagmask)
170 DUMP("%s ",flags[i].name);
171 DUMP("\n");
174 static void _dump_DDBLT(DWORD flagmask) {
175 int i;
176 const struct {
177 DWORD mask;
178 char *name;
179 } flags[] = {
180 #define FE(x) { x, #x},
181 FE(DDBLT_ALPHADEST)
182 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
183 FE(DDBLT_ALPHADESTNEG)
184 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
185 FE(DDBLT_ALPHAEDGEBLEND)
186 FE(DDBLT_ALPHASRC)
187 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
188 FE(DDBLT_ALPHASRCNEG)
189 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
190 FE(DDBLT_ASYNC)
191 FE(DDBLT_COLORFILL)
192 FE(DDBLT_DDFX)
193 FE(DDBLT_DDROPS)
194 FE(DDBLT_KEYDEST)
195 FE(DDBLT_KEYDESTOVERRIDE)
196 FE(DDBLT_KEYSRC)
197 FE(DDBLT_KEYSRCOVERRIDE)
198 FE(DDBLT_ROP)
199 FE(DDBLT_ROTATIONANGLE)
200 FE(DDBLT_ZBUFFER)
201 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
202 FE(DDBLT_ZBUFFERDESTOVERRIDE)
203 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
204 FE(DDBLT_ZBUFFERSRCOVERRIDE)
205 FE(DDBLT_WAIT)
206 FE(DDBLT_DEPTHFILL)
208 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
209 if (flags[i].mask & flagmask)
210 DUMP("%s ",flags[i].name);
213 static void _dump_DDSCAPS(DWORD flagmask) {
214 int i;
215 const struct {
216 DWORD mask;
217 char *name;
218 } flags[] = {
219 #define FE(x) { x, #x},
220 FE(DDSCAPS_RESERVED1)
221 FE(DDSCAPS_ALPHA)
222 FE(DDSCAPS_BACKBUFFER)
223 FE(DDSCAPS_COMPLEX)
224 FE(DDSCAPS_FLIP)
225 FE(DDSCAPS_FRONTBUFFER)
226 FE(DDSCAPS_OFFSCREENPLAIN)
227 FE(DDSCAPS_OVERLAY)
228 FE(DDSCAPS_PALETTE)
229 FE(DDSCAPS_PRIMARYSURFACE)
230 FE(DDSCAPS_PRIMARYSURFACELEFT)
231 FE(DDSCAPS_SYSTEMMEMORY)
232 FE(DDSCAPS_TEXTURE)
233 FE(DDSCAPS_3DDEVICE)
234 FE(DDSCAPS_VIDEOMEMORY)
235 FE(DDSCAPS_VISIBLE)
236 FE(DDSCAPS_WRITEONLY)
237 FE(DDSCAPS_ZBUFFER)
238 FE(DDSCAPS_OWNDC)
239 FE(DDSCAPS_LIVEVIDEO)
240 FE(DDSCAPS_HWCODEC)
241 FE(DDSCAPS_MODEX)
242 FE(DDSCAPS_MIPMAP)
243 FE(DDSCAPS_RESERVED2)
244 FE(DDSCAPS_ALLOCONLOAD)
245 FE(DDSCAPS_VIDEOPORT)
246 FE(DDSCAPS_LOCALVIDMEM)
247 FE(DDSCAPS_NONLOCALVIDMEM)
248 FE(DDSCAPS_STANDARDVGAMODE)
249 FE(DDSCAPS_OPTIMIZED)
251 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
252 if (flags[i].mask & flagmask)
253 DUMP("%s ",flags[i].name);
254 DUMP("\n");
257 static void _dump_DDSD(DWORD flagmask) {
258 int i;
259 const struct {
260 DWORD mask;
261 char *name;
262 } flags[] = {
263 FE(DDSD_CAPS)
264 FE(DDSD_HEIGHT)
265 FE(DDSD_WIDTH)
266 FE(DDSD_PITCH)
267 FE(DDSD_BACKBUFFERCOUNT)
268 FE(DDSD_ZBUFFERBITDEPTH)
269 FE(DDSD_ALPHABITDEPTH)
270 FE(DDSD_PIXELFORMAT)
271 FE(DDSD_CKDESTOVERLAY)
272 FE(DDSD_CKDESTBLT)
273 FE(DDSD_CKSRCOVERLAY)
274 FE(DDSD_CKSRCBLT)
275 FE(DDSD_MIPMAPCOUNT)
276 FE(DDSD_REFRESHRATE)
277 FE(DDSD_LINEARSIZE)
278 FE(DDSD_LPSURFACE)
280 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
281 if (flags[i].mask & flagmask)
282 DUMP("%s ",flags[i].name);
283 DUMP("\n");
286 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
287 static XVisualInfo *vi;
288 XVisualInfo vt;
289 int nitems;
291 if (!vi)
292 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
294 pf->dwFourCC = 0;
295 if (ddraw->d.depth==8) {
296 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
297 pf->x.dwRGBBitCount = 8;
298 pf->y.dwRBitMask = 0;
299 pf->z.dwGBitMask = 0;
300 pf->xx.dwBBitMask = 0;
301 pf->xy.dwRGBAlphaBitMask= 0;
302 return 0;
304 if (ddraw->d.depth==16) {
305 pf->dwFlags = DDPF_RGB;
306 pf->x.dwRGBBitCount = 16;
307 pf->y.dwRBitMask = vi[0].red_mask;
308 pf->z.dwGBitMask = vi[0].green_mask;
309 pf->xx.dwBBitMask = vi[0].blue_mask;
310 pf->xy.dwRGBAlphaBitMask= 0;
311 return 0;
313 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
314 return DDERR_GENERIC;
317 /******************************************************************************
318 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
320 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
321 * DDS and DDS2 use those functions. (Function calls did not change (except
322 * using different DirectDrawSurfaceX version), just added flags and functions)
324 static HRESULT WINAPI IDirectDrawSurface3_Lock(
325 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
327 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
328 this,lprect,lpddsd,flags,(DWORD)hnd);
329 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
330 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
331 this,lprect,lpddsd,flags,(DWORD)hnd);
333 if (lprect) {
334 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
335 lprect->top,lprect->left,lprect->bottom,lprect->right
337 lpddsd->y.lpSurface = this->s.surface +
338 (lprect->top*this->s.lpitch) +
339 (lprect->left*(this->s.ddraw->d.depth/8));
340 } else {
341 assert(this->s.surface);
342 lpddsd->y.lpSurface = this->s.surface;
344 lpddsd->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_LPSURFACE;
345 lpddsd->dwWidth = this->s.width;
346 lpddsd->dwHeight = this->s.height;
347 lpddsd->lPitch = this->s.lpitch;
348 _getpixelformat(this->s.ddraw,&(lpddsd->ddpfPixelFormat));
349 return 0;
352 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
353 LPDIRECTDRAWSURFACE3 this,LPVOID surface
355 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
356 return 0;
359 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
360 LPDIRECTDRAWSURFACE3 this,LPVOID surface
362 Xlib_MessagePump(this->s.ddraw->e.xlib.window);
364 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
366 if (!this->s.ddraw->e.xlib.paintable)
368 return DD_OK;
371 TSXPutImage( display,
372 this->s.ddraw->e.xlib.drawable,
373 DefaultGCOfScreen(screen),
374 this->t.xlib.image,
375 0, 0, 0, 0,
376 this->t.xlib.image->width,
377 this->t.xlib.image->height
379 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
381 return DD_OK;
384 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
385 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
387 #ifdef HAVE_LIBXXF86DGA
388 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
389 if (!flipto) {
390 if (this->s.backbuffer)
391 flipto = this->s.backbuffer;
392 else
393 flipto = this;
395 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
397 if (flipto->s.palette && flipto->s.palette->cm) {
398 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
400 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
402 if (flipto!=this) {
403 int tmp;
404 LPVOID ptmp;
406 tmp = this->t.dga.fb_height;
407 this->t.dga.fb_height = flipto->t.dga.fb_height;
408 flipto->t.dga.fb_height = tmp;
410 ptmp = this->s.surface;
411 this->s.surface = flipto->s.surface;
412 flipto->s.surface = ptmp;
414 return 0;
415 #else /* defined(HAVE_LIBXXF86DGA) */
416 return E_UNEXPECTED;
417 #endif /* defined(HAVE_LIBXXF86DGA) */
420 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
421 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
423 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
424 Xlib_MessagePump(this->s.ddraw->e.xlib.window);
425 if (!this->s.ddraw->e.xlib.paintable)
426 return 0;
428 if (!flipto) {
429 if (this->s.backbuffer)
430 flipto = this->s.backbuffer;
431 else
432 flipto = this;
435 TSXPutImage(display,
436 this->s.ddraw->e.xlib.drawable,
437 DefaultGCOfScreen(screen),
438 flipto->t.xlib.image,
439 0, 0, 0, 0,
440 flipto->t.xlib.image->width,
441 flipto->t.xlib.image->height);
442 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
443 if (flipto!=this) {
444 XImage *tmp;
445 LPVOID *surf;
446 tmp = this->t.xlib.image;
447 this->t.xlib.image = flipto->t.xlib.image;
448 flipto->t.xlib.image = tmp;
449 surf = this->s.surface;
450 this->s.surface = flipto->s.surface;
451 flipto->s.surface = surf;
453 return 0;
456 /* The IDirectDrawSurface3::SetPalette method attaches the specified
457 * DirectDrawPalette object to a surface. The surface uses this palette for all
458 * subsequent operations. The palette change takes place immediately.
460 static HRESULT WINAPI IDirectDrawSurface3_SetPalette(
461 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
463 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
465 /* According to spec, we are only supposed to
466 * AddRef if this is not the same palette.
468 if( this->s.palette != pal )
470 if( pal != NULL )
472 pal->lpvtbl->fnAddRef( pal );
474 if( this->s.palette != NULL )
476 this->s.palette->lpvtbl->fnRelease( this->s.palette );
478 this->s.palette = pal;
480 /* I think that we need to attach it to all backbuffers...*/
481 if( this->s.backbuffer )
483 if( this->s.backbuffer->s.palette )
485 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
486 this->s.backbuffer->s.palette );
488 this->s.backbuffer->s.palette = pal;
489 if( pal )
491 pal->lpvtbl->fnAddRef( pal );
495 /* Perform the refresh */
496 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
499 return 0;
502 static HRESULT WINAPI IDirectDrawSurface3_Blt(
503 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
505 RECT32 xdst,xsrc;
506 int i,j;
508 if (rdst) {
509 memcpy(&xdst,rdst,sizeof(xdst));
510 } else {
511 xdst.top = 0;
512 xdst.bottom = this->s.height;
513 xdst.left = 0;
514 xdst.right = this->s.width;
517 if (rsrc) {
518 memcpy(&xsrc,rsrc,sizeof(xsrc));
519 } else if (src) {
520 xsrc.top = 0;
521 xsrc.bottom = src->s.height;
522 xsrc.left = 0;
523 xsrc.right = src->s.width;
526 if (dwFlags & DDBLT_COLORFILL) {
527 int bpp = this->s.ddraw->d.depth/8;
528 LPBYTE xline,xpixel;
530 xline = (LPBYTE)this->s.surface+xdst.top*this->s.lpitch;
531 for (i=xdst.top;i<xdst.bottom;i++) {
532 xpixel = xline+bpp*xdst.left;
534 for (j=xdst.left;j<xdst.right;j++) {
535 /* FIXME: this only works on little endian
536 * architectures, where DWORD starts with low
537 * byte first!
539 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
540 xpixel += bpp;
542 xline += this->s.lpitch;
544 dwFlags &= ~(DDBLT_COLORFILL);
546 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
547 if ( (xsrc.top ==0) && (xsrc.bottom ==this->s.height) &&
548 (xsrc.left==0) && (xsrc.right ==this->s.width) &&
549 (xdst.top ==0) && (xdst.bottom ==this->s.height) &&
550 (xdst.left==0) && (xdst.right ==this->s.width) &&
551 !dwFlags
553 memcpy(this->s.surface,src->s.surface,this->s.height*this->s.lpitch);
554 return 0;
556 if (dwFlags) {
557 FIXME(ddraw,"(%p)->(%p,%p,%p,%08lx,%p),stub!\n",
558 this,rdst,src,rsrc,dwFlags,lpbltfx
560 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
561 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
562 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
564 if (dwFlags & DDBLT_DDFX) {
565 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
567 return 0;
570 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
571 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
573 int i,bpp;
574 if (TRACE_ON(ddraw)) {
575 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx),stub!\n",
576 this,dstx,dsty,src,rsrc,trans
578 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
579 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
581 bpp = this->s.ddraw->d.depth/8;
582 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
583 memcpy( this->s.surface+((i+dsty)*this->s.width*bpp)+dstx*bpp,
584 src->s.surface +(rsrc->top+i)*src->s.width*bpp+rsrc->left*bpp,
585 (rsrc->right-rsrc->left)*bpp
588 return 0;
591 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
592 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
594 TRACE(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
595 this,ddbltbatch,x,y
597 return 0;
600 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
601 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
603 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
604 caps->dwCaps = DDCAPS_PALETTE; /* probably more */
605 return 0;
608 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
609 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
610 ) {
611 if (TRACE_ON(ddraw)) {
612 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
613 this,ddsd);
614 fprintf(stderr," flags: ");
615 _dump_DDSD(ddsd->dwFlags);
616 fprintf(stderr,"\n");
619 ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
620 ddsd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
621 ddsd->dwBackBufferCount = 1;
622 ddsd->dwHeight = this->s.height;
623 ddsd->dwWidth = this->s.width;
624 ddsd->lPitch = this->s.lpitch;
625 if (this->s.backbuffer)
626 ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
627 _getpixelformat(this->s.ddraw,&(ddsd->ddpfPixelFormat));
629 return 0;
632 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
633 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
635 return ++(this->ref);
638 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
639 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
641 #ifdef HAVE_LIBXXF86DGA
642 if (!--(this->ref)) {
643 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
644 /* clear out of surface list */
645 if (this->t.dga.fb_height == -1) {
646 HeapFree(GetProcessHeap(),0,this->s.surface);
647 } else {
648 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
650 HeapFree(GetProcessHeap(),0,this);
651 return 0;
653 #endif /* defined(HAVE_LIBXXF86DGA) */
654 return this->ref;
657 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
658 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
660 if (!--(this->ref)) {
661 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
662 HeapFree(GetProcessHeap(),0,this->s.surface);
664 if( this->s.backbuffer )
666 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
669 this->t.xlib.image->data = NULL;
670 TSXDestroyImage(this->t.xlib.image);
671 this->t.xlib.image = 0;
673 this->s.palette->lpvtbl->fnRelease(this->s.palette);
675 HeapFree(GetProcessHeap(),0,this);
676 return 0;
678 return this->ref;
681 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
682 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
684 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
685 this, lpddsd, lpdsf);
687 if (TRACE_ON(ddraw)) {
688 TRACE(ddraw," caps ");
689 _dump_DDSCAPS(lpddsd->dwCaps);
692 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
693 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
694 return E_FAIL;
697 /* FIXME: should handle more than one backbuffer */
698 *lpdsf = this->s.backbuffer;
700 if( this->s.backbuffer )
702 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
705 return 0;
708 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
709 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
711 return DDERR_ALREADYINITIALIZED;
714 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
715 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
717 return _getpixelformat(this->s.ddraw,pf);
720 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
721 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
722 return 0;
725 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
726 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
728 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
729 return 0;
732 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
733 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
735 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
736 return 0;
739 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
740 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
742 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
743 this->s.backbuffer = surf;
744 return 0;
747 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
748 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
749 *lphdc = BeginPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps);
750 return 0;
753 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
754 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
755 EndPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps);
756 return 0;
760 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
761 char xrefiid[50];
763 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
764 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
766 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
767 * the same interface. And IUnknown does that too of course.
769 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
770 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
771 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
772 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
774 *obj = this;
775 this->lpvtbl->fnAddRef(this);
776 return 0;
778 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
779 return OLE_E_ENUM_NOMORE;
782 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
783 FIXME(ddraw,"(%p)->(), stub!\n",this);
784 return 0; /* hmm */
787 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
788 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
789 return 0;
792 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
793 FIXME(ddraw,"(%p)->(),stub!\n",this);
794 return 0;
797 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
798 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
800 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
802 if( dwFlags & DDCKEY_SRCBLT )
804 dwFlags &= ~DDCKEY_SRCBLT;
807 if( dwFlags )
809 TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
812 return DD_OK;
815 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
816 IDirectDrawSurface3_QueryInterface,
817 IDirectDrawSurface3_AddRef,
818 DGA_IDirectDrawSurface3_Release,
819 IDirectDrawSurface3_AddAttachedSurface,
820 (void*)5,
821 IDirectDrawSurface3_Blt,
822 IDirectDrawSurface3_BltBatch,
823 IDirectDrawSurface3_BltFast,
824 (void*)9,
825 IDirectDrawSurface3_EnumAttachedSurfaces,
826 (void*)11,
827 DGA_IDirectDrawSurface3_Flip,
828 IDirectDrawSurface3_GetAttachedSurface,
829 IDirectDrawSurface3_GetBltStatus,
830 IDirectDrawSurface3_GetCaps,
831 (void*)16,
832 (void*)17,
833 IDirectDrawSurface3_GetDC,
834 (void*)19,
835 IDirectDrawSurface3_GetOverlayPosition,
836 (void*)21,
837 IDirectDrawSurface3_GetPixelFormat,
838 IDirectDrawSurface3_GetSurfaceDesc,
839 IDirectDrawSurface3_Initialize,
840 IDirectDrawSurface3_IsLost,
841 IDirectDrawSurface3_Lock,
842 IDirectDrawSurface3_ReleaseDC,
843 IDirectDrawSurface3_Restore,
844 IDirectDrawSurface3_SetClipper,
845 IDirectDrawSurface3_SetColorKey,
846 (void*)31,
847 IDirectDrawSurface3_SetPalette,
848 DGA_IDirectDrawSurface3_Unlock,
849 (void*)34,
850 (void*)35,
851 (void*)36,
852 (void*)37,
853 (void*)38,
854 (void*)39,
855 (void*)40,
858 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
859 IDirectDrawSurface3_QueryInterface,
860 IDirectDrawSurface3_AddRef,
861 Xlib_IDirectDrawSurface3_Release,
862 IDirectDrawSurface3_AddAttachedSurface,
863 (void*)5,
864 IDirectDrawSurface3_Blt,
865 IDirectDrawSurface3_BltBatch,
866 IDirectDrawSurface3_BltFast,
867 (void*)9,
868 IDirectDrawSurface3_EnumAttachedSurfaces,
869 (void*)11,
870 Xlib_IDirectDrawSurface3_Flip,
871 IDirectDrawSurface3_GetAttachedSurface,
872 IDirectDrawSurface3_GetBltStatus,
873 IDirectDrawSurface3_GetCaps,
874 (void*)16,
875 (void*)17,
876 IDirectDrawSurface3_GetDC,
877 (void*)19,
878 IDirectDrawSurface3_GetOverlayPosition,
879 (void*)21,
880 IDirectDrawSurface3_GetPixelFormat,
881 IDirectDrawSurface3_GetSurfaceDesc,
882 IDirectDrawSurface3_Initialize,
883 IDirectDrawSurface3_IsLost,
884 IDirectDrawSurface3_Lock,
885 IDirectDrawSurface3_ReleaseDC,
886 IDirectDrawSurface3_Restore,
887 IDirectDrawSurface3_SetClipper,
888 IDirectDrawSurface3_SetColorKey,
889 (void*)31,
890 IDirectDrawSurface3_SetPalette,
891 Xlib_IDirectDrawSurface3_Unlock,
892 (void*)34,
893 (void*)35,
894 (void*)36,
895 (void*)37,
896 (void*)38,
897 (void*)39,
898 (void*)40,
901 /******************************************************************************
902 * IDirectDrawClipper
904 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
905 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
907 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
908 return 0;
911 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
912 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
914 this->ref--;
915 if (this->ref)
916 return this->ref;
917 HeapFree(GetProcessHeap(),0,this);
918 return 0;
921 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
922 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
924 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
925 if (hmm) *hmm=0;
926 return 0;
929 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
930 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
932 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
933 return 0;
936 static struct IDirectDrawClipper_VTable ddclipvt = {
937 (void*)1,
938 (void*)2,
939 IDirectDrawClipper_Release,
940 IDirectDrawClipper_GetClipList,
941 (void*)5,
942 (void*)6,
943 (void*)7,
944 IDirectDrawClipper_SetClipList,
945 IDirectDrawClipper_SetHwnd
948 /******************************************************************************
949 * IDirectDrawPalette
951 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
952 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
954 XColor xc;
955 int i;
957 if (!this->cm) /* should not happen */ {
958 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
959 return DDERR_GENERIC;
961 for (i=0;i<count;i++) {
962 #if 0
964 xc.pixel = i+start;
965 TSXQueryColor(display,this->cm,&xc);
966 palent[i].peRed = xc.red>>8;
967 palent[i].peGreen = xc.green>>8;
968 palent[i].peBlue = xc.blue>>8;
969 #endif
971 palent[i].peRed = this->palents[start+i].peRed;
972 palent[i].peBlue = this->palents[start+i].peBlue;
973 palent[i].peGreen = this->palents[start+i].peGreen;
974 palent[i].peFlags = this->palents[start+i].peFlags;
977 return 0;
980 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
981 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
983 XColor xc;
984 int i;
986 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
987 this,x,start,count,palent
989 if (!this->cm) /* should not happen */ {
990 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
991 return DDERR_GENERIC;
993 if (!this->ddraw->e.xlib.paintable)
994 return 0;
995 for (i=0;i<count;i++) {
996 xc.red = palent[i].peRed<<8;
997 xc.blue = palent[i].peBlue<<8;
998 xc.green = palent[i].peGreen<<8;
999 xc.flags = DoRed|DoBlue|DoGreen;
1000 xc.pixel = start+i;
1002 TSXStoreColor(display,this->cm,&xc);
1004 this->palents[start+i].peRed = palent[i].peRed;
1005 this->palents[start+i].peBlue = palent[i].peBlue;
1006 this->palents[start+i].peGreen = palent[i].peGreen;
1007 this->palents[start+i].peFlags = palent[i].peFlags;
1009 return 0;
1012 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1013 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1015 #ifdef HAVE_LIBXXF86DGA
1016 XColor xc;
1017 Colormap cm;
1018 int i;
1020 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1021 this,x,start,count,palent
1023 if (!this->cm) /* should not happen */ {
1024 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1025 return DDERR_GENERIC;
1027 /* FIXME: free colorcells instead of freeing whole map */
1028 cm = this->cm;
1029 this->cm = TSXCopyColormapAndFree(display,this->cm);
1030 TSXFreeColormap(display,cm);
1032 for (i=0;i<count;i++) {
1033 xc.red = palent[i].peRed<<8;
1034 xc.blue = palent[i].peBlue<<8;
1035 xc.green = palent[i].peGreen<<8;
1036 xc.flags = DoRed|DoBlue|DoGreen;
1037 xc.pixel = i+start;
1039 TSXStoreColor(display,this->cm,&xc);
1041 this->palents[start+i].peRed = palent[i].peRed;
1042 this->palents[start+i].peBlue = palent[i].peBlue;
1043 this->palents[start+i].peGreen = palent[i].peGreen;
1044 this->palents[start+i].peFlags = palent[i].peFlags;
1046 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1047 return 0;
1048 #else /* defined(HAVE_LIBXXF86DGA) */
1049 return E_UNEXPECTED;
1050 #endif /* defined(HAVE_LIBXXF86DGA) */
1053 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1054 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1055 if (!--(this->ref)) {
1056 if (this->cm) {
1057 TSXFreeColormap(display,this->cm);
1058 this->cm = 0;
1060 HeapFree(GetProcessHeap(),0,this);
1061 return 0;
1063 return this->ref;
1066 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1068 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1069 return ++(this->ref);
1072 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1073 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1075 return DDERR_ALREADYINITIALIZED;
1078 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1079 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1081 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1082 return DD_OK;
1085 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1086 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1088 char xrefiid[50];
1090 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1091 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1093 return S_OK;
1096 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1097 IDirectDrawPalette_QueryInterface,
1098 IDirectDrawPalette_AddRef,
1099 IDirectDrawPalette_Release,
1100 IDirectDrawPalette_GetCaps,
1101 IDirectDrawPalette_GetEntries,
1102 IDirectDrawPalette_Initialize,
1103 DGA_IDirectDrawPalette_SetEntries
1106 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1107 IDirectDrawPalette_QueryInterface,
1108 IDirectDrawPalette_AddRef,
1109 IDirectDrawPalette_Release,
1110 IDirectDrawPalette_GetCaps,
1111 IDirectDrawPalette_GetEntries,
1112 IDirectDrawPalette_Initialize,
1113 Xlib_IDirectDrawPalette_SetEntries
1116 static HRESULT WINAPI IDirect3D_QueryInterface(
1117 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1119 /* FIXME: Not sure if this is correct */
1120 char xrefiid[50];
1122 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1123 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1124 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1125 *obj = this;
1126 this->lpvtbl->fnAddRef(this);
1127 return 0;
1129 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1130 LPDIRECT3D d3d;
1132 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1133 d3d->ref = 1;
1134 d3d->ddraw = (LPDIRECTDRAW)this;
1135 this->lpvtbl->fnAddRef(this);
1136 d3d->lpvtbl = &d3dvt;
1137 *obj = d3d;
1138 return 0;
1140 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1141 LPDIRECT3D2 d3d;
1143 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1144 d3d->ref = 1;
1145 d3d->ddraw = (LPDIRECTDRAW)this;
1146 this->lpvtbl->fnAddRef(this);
1147 d3d->lpvtbl = &d3d2vt;
1148 *obj = d3d;
1149 return 0;
1151 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1152 return OLE_E_ENUM_NOMORE;
1155 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1156 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1158 return ++(this->ref);
1161 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1163 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1165 if (!--(this->ref)) {
1166 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1167 HeapFree(GetProcessHeap(),0,this);
1168 return 0;
1170 return this->ref;
1173 static HRESULT WINAPI IDirect3D_Initialize(
1174 LPDIRECT3D this, REFIID refiid )
1176 /* FIXME: Not sure if this is correct */
1177 char xrefiid[50];
1179 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1180 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1182 return DDERR_ALREADYINITIALIZED;
1185 /*******************************************************************************
1186 * IDirect3D
1188 static struct IDirect3D_VTable d3dvt = {
1189 (void*)IDirect3D_QueryInterface,
1190 (void*)IDirect3D_AddRef,
1191 (void*)IDirect3D_Release,
1192 IDirect3D_Initialize,
1193 (void*)5,
1194 (void*)6,
1195 (void*)7,
1196 (void*)8,
1197 (void*)9,
1200 /*******************************************************************************
1201 * IDirect3D2
1203 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1204 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1206 if (!--(this->ref)) {
1207 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1208 HeapFree(GetProcessHeap(),0,this);
1209 return 0;
1211 return this->ref;
1214 static HRESULT WINAPI IDirect3D2_EnumDevices(
1215 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1217 D3DDEVICEDESC d1,d2;
1219 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1220 d1.dwSize = sizeof(d1);
1221 d1.dwFlags = 0;
1223 d2.dwSize = sizeof(d2);
1224 d2.dwFlags = 0;
1225 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1226 return 0;
1229 static struct IDirect3D2_VTable d3d2vt = {
1230 (void*)1,
1231 (void*)2,
1232 IDirect3D2_Release,
1233 IDirect3D2_EnumDevices,
1234 (void*)5,
1235 (void*)6,
1236 (void*)7,
1237 (void*)8,
1238 (void*)9,
1241 /*******************************************************************************
1242 * IDirectDraw
1245 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1246 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1248 static INT32 ddrawXlibThisOffset = 0;
1250 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1251 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1253 #ifdef HAVE_LIBXXF86DGA
1254 int i;
1256 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1257 if (TRACE_ON(ddraw)) {
1258 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1259 _dump_DDSD(lpddsd->dwFlags);
1260 fprintf(stderr,"caps ");
1261 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1262 fprintf(stderr,"]\n");
1265 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1266 this->lpvtbl->fnAddRef(this);
1267 (*lpdsf)->ref = 1;
1268 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1269 if ( (lpddsd->dwFlags & DDSD_CAPS) &&
1270 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1272 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1273 lpddsd->dwWidth = this->e.dga.fb_width;
1274 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1275 lpddsd->dwHeight = this->e.dga.fb_height;
1276 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1277 (*lpdsf)->t.dga.fb_height = -1;
1278 (*lpdsf)->s.lpitch = lpddsd->dwWidth*this->d.depth/8;
1279 TRACE(ddraw,"using system memory for a primary surface\n");
1280 } else {
1281 for (i=0;i<32;i++)
1282 if (!(this->e.dga.vpmask & (1<<i)))
1283 break;
1284 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1285 /* if i == 32 or maximum ... return error */
1286 this->e.dga.vpmask|=(1<<i);
1287 (*lpdsf)->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1288 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1289 (*lpdsf)->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1292 lpddsd->lPitch = (*lpdsf)->s.lpitch;
1294 (*lpdsf)->s.width = this->d.width;
1295 (*lpdsf)->s.height = this->d.height;
1296 (*lpdsf)->s.ddraw = this;
1297 (*lpdsf)->s.backbuffer = NULL;
1298 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1299 LPDIRECTDRAWSURFACE3 back;
1301 if (lpddsd->dwBackBufferCount>1)
1302 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1304 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1305 this->lpvtbl->fnAddRef(this);
1306 back->ref = 1;
1307 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1308 for (i=0;i<32;i++)
1309 if (!(this->e.dga.vpmask & (1<<i)))
1310 break;
1311 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1312 /* if i == 32 or maximum ... return error */
1313 this->e.dga.vpmask|=(1<<i);
1314 back->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1315 back->t.dga.fb_height = i*this->e.dga.fb_height;
1317 back->s.width = this->d.width;
1318 back->s.height = this->d.height;
1319 back->s.ddraw = this;
1320 back->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1321 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1322 * one! */
1324 return 0;
1325 #else /* defined(HAVE_LIBXXF86DGA) */
1326 return E_UNEXPECTED;
1327 #endif /* defined(HAVE_LIBXXF86DGA) */
1330 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1331 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1333 XImage *img;
1335 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1336 this,lpddsd,lpdsf,lpunk);
1338 if (TRACE_ON(ddraw)) {
1339 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1340 _dump_DDSD(lpddsd->dwFlags);
1341 fprintf(stderr,"caps ");
1342 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1343 fprintf(stderr,"]\n");
1346 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1348 this->lpvtbl->fnAddRef(this);
1349 (*lpdsf)->s.ddraw = this;
1350 (*lpdsf)->ref = 1;
1351 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1353 if ( (lpddsd->dwFlags & DDSD_CAPS) &&
1354 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1356 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1357 lpddsd->dwWidth = this->e.dga.fb_width;
1358 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1359 lpddsd->dwHeight = this->e.dga.fb_height;
1360 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1361 TRACE(ddraw,"using system memory for a primary surface\n");
1362 } else {
1363 TRACE(ddraw,"using standard XImage for a primary surface\n");
1364 /* FIXME: !8 bit images */
1365 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1366 lpddsd->dwWidth = this->d.width;
1367 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1368 lpddsd->dwHeight = this->d.height;
1369 (*lpdsf)->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpddsd->dwHeight*lpddsd->dwWidth);
1370 (*lpdsf)->s.width = lpddsd->dwWidth;
1371 (*lpdsf)->s.height = lpddsd->dwHeight;
1375 (*lpdsf)->t.xlib.image = img =
1376 TSXCreateImage( display,
1377 DefaultVisualOfScreen(screen),
1378 /*FIXME: depth*/8,
1379 ZPixmap,
1381 (*lpdsf)->s.surface,
1382 (*lpdsf)->s.width,
1383 (*lpdsf)->s.height,
1385 (*lpdsf)->s.width*1
1386 /* FIXME: !8 bit images */
1388 /* END FIXME: Xlib */
1390 (*lpdsf)->s.lpitch = img->bytes_per_line;
1391 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1392 LPDIRECTDRAWSURFACE3 back;
1394 if (lpddsd->dwBackBufferCount>1)
1395 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1397 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1399 this->lpvtbl->fnAddRef(this);
1400 back->s.ddraw = this;
1402 back->ref = 1;
1403 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
1404 /* FIXME: !8 bit images */
1405 back->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1406 img->width*img->height
1408 back->t.xlib.image = TSXCreateImage(
1409 display,
1410 DefaultVisualOfScreen(screen),
1411 /*FIXME: depth*/8,
1412 ZPixmap,
1414 back->s.surface,
1415 this->d.width,
1416 this->d.height,
1418 this->d.width*1
1419 /* FIXME: !8 bit images */
1421 back->s.width = this->d.width;
1422 back->s.height = this->d.height;
1423 back->s.lpitch = back->t.xlib.image->bytes_per_line;
1424 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1425 * one! */
1427 return 0;
1430 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
1431 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1433 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1434 *dst = src; /* FIXME */
1435 return 0;
1438 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1439 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
1441 int i;
1442 const struct {
1443 int mask;
1444 char *name;
1445 } flagmap[] = {
1446 FE(DDSCL_FULLSCREEN)
1447 FE(DDSCL_ALLOWREBOOT)
1448 FE(DDSCL_NOWINDOWCHANGES)
1449 FE(DDSCL_NORMAL)
1450 FE(DDSCL_ALLOWMODEX)
1451 FE(DDSCL_EXCLUSIVE)
1452 FE(DDSCL_SETFOCUSWINDOW)
1453 FE(DDSCL_SETDEVICEWINDOW)
1454 FE(DDSCL_CREATEDEVICEWINDOW)
1457 TRACE(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
1458 if(TRACE_ON(ddraw)){
1459 dbg_decl_str(ddraw, 512);
1460 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1461 if (flagmap[i].mask & cooplevel)
1462 dsprintf(ddraw, "%s ", flagmap[i].name);
1463 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1465 this->d.mainWindow = hwnd;
1466 return 0;
1470 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
1471 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1473 #ifdef HAVE_LIBXXF86DGA
1474 int i,*depths,depcount;
1476 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
1478 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1479 for (i=0;i<depcount;i++)
1480 if (depths[i]==depth)
1481 break;
1482 TSXFree(depths);
1483 if (i==depcount) {/* not found */
1484 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1485 return DDERR_UNSUPPORTEDMODE;
1487 if (this->d.width < width) {
1488 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
1489 return DDERR_UNSUPPORTEDMODE;
1491 this->d.width = width;
1492 this->d.height = height;
1493 /* adjust fb_height, so we don't overlap */
1494 if (this->e.dga.fb_height < height)
1495 this->e.dga.fb_height = height;
1496 this->d.depth = depth;
1498 /* FIXME: this function OVERWRITES several signal handlers.
1499 * can we save them? and restore them later? In a way that
1500 * it works for the library too?
1502 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
1503 #ifdef DIABLO_HACK
1504 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
1505 #endif
1507 #ifdef RESTORE_SIGNALS
1508 SIGNAL_InitEmulator();
1509 #endif
1510 return 0;
1511 #else /* defined(HAVE_LIBXXF86DGA) */
1512 return E_UNEXPECTED;
1513 #endif /* defined(HAVE_LIBXXF86DGA) */
1516 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
1517 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1519 int i,*depths,depcount;
1520 char buf[200];
1522 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
1523 this, width, height, depth);
1525 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1526 for (i=0;i<depcount;i++)
1527 if (depths[i]==depth)
1528 break;
1529 TSXFree(depths);
1530 if (i==depcount) {/* not found */
1531 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
1532 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
1533 return DDERR_UNSUPPORTEDMODE;
1535 if (this->d.width < width) {
1536 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld",width,height,depth,width,this->d.width);
1537 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
1538 return DDERR_UNSUPPORTEDMODE;
1540 this->e.xlib.window = CreateWindowEx32A(
1542 "WINE_DirectDraw",
1543 "WINE_DirectDraw",
1544 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1545 0,0,
1546 width,
1547 height,
1551 NULL
1554 /* Store this with the window. We'll use it for the window procedure */
1555 SetWindowLong32A(this->e.xlib.window,ddrawXlibThisOffset,(LONG)this);
1557 this->e.xlib.paintable = 1;
1559 ShowWindow32(this->e.xlib.window,TRUE);
1560 UpdateWindow32(this->e.xlib.window);
1562 assert(this->e.xlib.window);
1564 this->e.xlib.drawable = WIN_FindWndPtr(this->e.xlib.window)->window;
1566 /* We don't have a context for this window. Host off the desktop */
1567 if( !this->e.xlib.drawable )
1569 this->e.xlib.drawable = WIN_GetDesktop()->window;
1572 this->d.width = width;
1573 this->d.height = height;
1574 /* adjust fb_height, so we don't overlap */
1575 if (this->e.dga.fb_height < height)
1576 this->e.dga.fb_height = height;
1577 this->d.depth = depth;
1578 return 0;
1581 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
1582 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1584 #ifdef HAVE_LIBXXF86DGA
1585 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1586 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
1587 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1588 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1589 if (caps2) {
1590 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
1591 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1592 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1594 return 0;
1595 #else /* defined(HAVE_LIBXXF86DGA) */
1596 return E_UNEXPECTED;
1597 #endif /* defined(HAVE_LIBXXF86DGA) */
1600 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
1601 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1603 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1604 /* FIXME: Xlib */
1605 caps1->dwVidMemTotal = 2048*1024;
1606 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1607 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1608 if (caps2) {
1609 caps2->dwVidMemTotal = 2048*1024;
1610 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1611 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1613 /* END FIXME: Xlib */
1614 return 0;
1617 static HRESULT WINAPI IDirectDraw2_CreateClipper(
1618 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
1620 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
1621 this,x,lpddclip,lpunk
1623 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1624 (*lpddclip)->ref = 1;
1625 (*lpddclip)->lpvtbl = &ddclipvt;
1626 return 0;
1629 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
1630 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1632 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1633 if (*lpddpal == NULL) return E_OUTOFMEMORY;
1634 (*lpddpal)->ref = 1;
1635 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1636 (*lpddpal)->installed = 0;
1637 if (this->d.depth<=8) {
1638 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
1639 } else {
1640 /* we don't want palettes in hicolor or truecolor */
1641 (*lpddpal)->cm = 0;
1643 return 0;
1646 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
1647 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1649 HRESULT res;
1650 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1651 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
1652 if (res != 0) return res;
1653 (*lpddpal)->lpvtbl = &dga_ddpalvt;
1654 return 0;
1657 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
1658 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1660 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1661 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1662 if (*lpddpal == NULL) return E_OUTOFMEMORY;
1663 (*lpddpal)->ref = 1;
1664 (*lpddpal)->installed = 0;
1666 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1667 this->lpvtbl->fnAddRef(this);
1669 if (this->d.depth<=8) {
1670 (*lpddpal)->cm = TSXCreateColormap(display,this->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
1671 /* later installed ...
1672 * TSXInstallColormap(display,(*lpddpal)->cm);
1673 * TSXSetWindowColormap(display,this->e.xlib.drawable,(*lpddpal)->cm);
1676 else
1678 /* we don't want palettes in hicolor or truecolor */
1679 (*lpddpal)->cm = 0;
1682 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
1683 return 0;
1686 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1687 #ifdef HAVE_LIBXXF86DGA
1688 TRACE(ddraw, "(%p)->()\n",this);
1689 Sleep(1000);
1690 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
1691 #ifdef RESTORE_SIGNALS
1692 SIGNAL_InitEmulator();
1693 #endif
1694 return 0;
1695 #else /* defined(HAVE_LIBXXF86DGA) */
1696 return E_UNEXPECTED;
1697 #endif
1700 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1701 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
1702 Sleep(1000);
1703 return 0;
1706 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
1707 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
1709 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
1710 return 0;
1713 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
1714 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1716 return ++(this->ref);
1719 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
1720 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1722 #ifdef HAVE_LIBXXF86DGA
1723 if (!--(this->ref)) {
1724 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
1725 #ifdef RESTORE_SIGNALS
1726 SIGNAL_InitEmulator();
1727 #endif
1728 HeapFree(GetProcessHeap(),0,this);
1729 return 0;
1731 #endif /* defined(HAVE_LIBXXF86DGA) */
1732 return this->ref;
1735 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
1736 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1738 if (!--(this->ref)) {
1739 HeapFree(GetProcessHeap(),0,this);
1740 return 0;
1742 /* FIXME: destroy window ... */
1743 return this->ref;
1746 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
1747 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
1749 char xrefiid[50];
1751 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1752 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1753 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1754 *obj = this;
1755 this->lpvtbl->fnAddRef(this);
1756 return 0;
1758 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1759 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
1760 this->lpvtbl->fnAddRef(this);
1761 *obj = this;
1762 return 0;
1764 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1765 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
1766 this->lpvtbl->fnAddRef(this);
1767 *obj = this;
1768 return 0;
1770 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1771 LPDIRECT3D d3d;
1773 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1774 d3d->ref = 1;
1775 d3d->ddraw = (LPDIRECTDRAW)this;
1776 this->lpvtbl->fnAddRef(this);
1777 d3d->lpvtbl = &d3dvt;
1778 *obj = d3d;
1779 return 0;
1781 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1782 LPDIRECT3D2 d3d;
1784 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1785 d3d->ref = 1;
1786 d3d->ddraw = (LPDIRECTDRAW)this;
1787 this->lpvtbl->fnAddRef(this);
1788 d3d->lpvtbl = &d3d2vt;
1789 *obj = d3d;
1790 return 0;
1792 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
1793 return OLE_E_ENUM_NOMORE;
1796 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
1797 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
1799 char xrefiid[50];
1801 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1802 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1803 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1804 *obj = this;
1805 this->lpvtbl->fnAddRef(this);
1806 return 0;
1808 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1809 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
1810 this->lpvtbl->fnAddRef(this);
1811 *obj = this;
1812 return 0;
1814 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1815 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
1816 this->lpvtbl->fnAddRef(this);
1817 *obj = this;
1818 return 0;
1820 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1821 LPDIRECT3D d3d;
1823 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1824 d3d->ref = 1;
1825 d3d->ddraw = (LPDIRECTDRAW)this;
1826 this->lpvtbl->fnAddRef(this);
1827 d3d->lpvtbl = &d3dvt;
1828 *obj = d3d;
1829 return 0;
1831 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1832 LPDIRECT3D2 d3d;
1834 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1835 d3d->ref = 1;
1836 d3d->ddraw = (LPDIRECTDRAW)this;
1837 this->lpvtbl->fnAddRef(this);
1838 d3d->lpvtbl = &d3d2vt;
1839 *obj = d3d;
1840 return 0;
1842 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
1843 return OLE_E_ENUM_NOMORE;
1846 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
1847 LPDIRECTDRAW2 this,BOOL32 *status
1849 TRACE(ddraw,"(%p)->(%p)\n",this,status);
1850 *status = TRUE;
1851 return 0;
1854 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
1855 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
1857 DDSURFACEDESC ddsfd;
1859 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
1861 _getpixelformat(this,&(ddsfd.ddpfPixelFormat));
1862 ddsfd.dwSize = sizeof(ddsfd);
1863 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1864 if (dwFlags & DDEDM_REFRESHRATES) {
1865 ddsfd.dwFlags |= DDSD_REFRESHRATE;
1866 ddsfd.x.dwRefreshRate = 60;
1869 ddsfd.dwWidth = 640;
1870 ddsfd.dwHeight = 480;
1871 ddsfd.dwBackBufferCount = 1;
1872 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
1874 if (!modescb(&ddsfd,context)) return 0;
1876 ddsfd.dwWidth = 800;
1877 ddsfd.dwHeight = 600;
1878 if (!modescb(&ddsfd,context)) return 0;
1880 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
1881 /* modeX is not standard VGA */
1883 ddsfd.dwHeight = 200;
1884 ddsfd.dwWidth = 320;
1885 if (!modescb(&ddsfd,context)) return 0;
1887 return DD_OK;
1890 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
1891 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
1893 #ifdef HAVE_LIBXXF86DGA
1894 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
1895 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1896 lpddsfd->dwHeight = screenHeight;
1897 lpddsfd->dwWidth = screenWidth;
1898 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
1899 lpddsfd->dwBackBufferCount = 1;
1900 lpddsfd->x.dwRefreshRate = 60;
1901 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
1902 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
1903 return DD_OK;
1904 #else /* defined(HAVE_LIBXXF86DGA) */
1905 return E_UNEXPECTED;
1906 #endif /* defined(HAVE_LIBXXF86DGA) */
1909 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
1910 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
1912 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
1913 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1914 lpddsfd->dwHeight = screenHeight;
1915 lpddsfd->dwWidth = screenWidth;
1916 /* POOLE FIXME: Xlib */
1917 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
1918 /* END FIXME: Xlib */
1919 lpddsfd->dwBackBufferCount = 1;
1920 lpddsfd->x.dwRefreshRate = 60;
1921 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
1922 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
1923 return DD_OK;
1926 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
1927 TRACE(ddraw,"(%p)->()\n",this);
1928 return DD_OK;
1931 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
1932 LPDIRECTDRAW2 this,LPDWORD freq
1934 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
1935 *freq = 60*100; /* 60 Hz */
1936 return 0;
1939 /* what can we directly decompress? */
1940 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
1941 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
1943 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
1944 return 0;
1947 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
1948 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
1950 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
1951 return 0;
1954 static HRESULT WINAPI IDirectDraw2_Compact(
1955 LPDIRECTDRAW2 this )
1957 FIXME(ddraw,"(%p)->()\n", this );
1959 return DD_OK;
1963 /* Note: Hack so we can reuse the old functions without compiler warnings */
1964 #ifdef __GNUC__
1965 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
1966 #else
1967 # define XCAST(fun) (void*)
1968 #endif
1970 static struct IDirectDraw_VTable dga_ddvt = {
1971 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
1972 XCAST(AddRef)IDirectDraw2_AddRef,
1973 XCAST(Release)DGA_IDirectDraw2_Release,
1974 XCAST(Compact)IDirectDraw2_Compact,
1975 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
1976 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
1977 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
1978 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
1979 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
1980 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
1981 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
1982 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
1983 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
1984 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
1985 XCAST(GetGDISurface)15,
1986 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
1987 XCAST(GetScanLine)17,
1988 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
1989 XCAST(Initialize)19,
1990 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
1991 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
1992 DGA_IDirectDraw_SetDisplayMode,
1993 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
1996 static struct IDirectDraw_VTable xlib_ddvt = {
1997 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
1998 XCAST(AddRef)IDirectDraw2_AddRef,
1999 XCAST(Release)Xlib_IDirectDraw2_Release,
2000 XCAST(Compact)IDirectDraw2_Compact,
2001 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2002 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2003 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2004 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2005 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2006 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2007 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2008 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2009 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2010 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2011 XCAST(GetGDISurface)15,
2012 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2013 XCAST(GetScanLine)17,
2014 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2015 XCAST(Initialize)19,
2016 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2017 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2018 Xlib_IDirectDraw_SetDisplayMode,
2019 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2022 /*****************************************************************************
2023 * IDirectDraw2
2028 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2029 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2031 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2034 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2035 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2037 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2040 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2041 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2043 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2044 this,ddscaps,total,free
2046 if (total) *total = this->e.dga.fb_memsize * 1024;
2047 if (free) *free = this->e.dga.fb_memsize * 1024;
2048 return 0;
2051 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2052 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2054 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2055 this,ddscaps,total,free
2057 if (total) *total = 2048 * 1024;
2058 if (free) *free = 2048 * 1024;
2059 return 0;
2062 static IDirectDraw2_VTable dga_dd2vt = {
2063 DGA_IDirectDraw2_QueryInterface,
2064 IDirectDraw2_AddRef,
2065 DGA_IDirectDraw2_Release,
2066 IDirectDraw2_Compact,
2067 IDirectDraw2_CreateClipper,
2068 DGA_IDirectDraw2_CreatePalette,
2069 DGA_IDirectDraw2_CreateSurface,
2070 (void*)8,
2071 IDirectDraw2_EnumDisplayModes,
2072 IDirectDraw2_EnumSurfaces,
2073 IDirectDraw2_FlipToGDISurface,
2074 DGA_IDirectDraw2_GetCaps,
2075 DGA_IDirectDraw2_GetDisplayMode,
2076 IDirectDraw2_GetFourCCCodes,
2077 (void*)15,
2078 IDirectDraw2_GetMonitorFrequency,
2079 (void*)17,
2080 IDirectDraw2_GetVerticalBlankStatus,
2081 (void*)19,
2082 DGA_IDirectDraw2_RestoreDisplayMode,
2083 IDirectDraw2_SetCooperativeLevel,
2084 DGA_IDirectDraw2_SetDisplayMode,
2085 IDirectDraw2_WaitForVerticalBlank,
2086 DGA_IDirectDraw2_GetAvailableVidMem
2089 static struct IDirectDraw2_VTable xlib_dd2vt = {
2090 Xlib_IDirectDraw2_QueryInterface,
2091 IDirectDraw2_AddRef,
2092 Xlib_IDirectDraw2_Release,
2093 IDirectDraw2_Compact,
2094 IDirectDraw2_CreateClipper,
2095 Xlib_IDirectDraw2_CreatePalette,
2096 Xlib_IDirectDraw2_CreateSurface,
2097 (void*)8,
2098 IDirectDraw2_EnumDisplayModes,
2099 IDirectDraw2_EnumSurfaces,
2100 IDirectDraw2_FlipToGDISurface,
2101 Xlib_IDirectDraw2_GetCaps,
2102 Xlib_IDirectDraw2_GetDisplayMode,
2103 IDirectDraw2_GetFourCCCodes,
2104 (void*)15,
2105 IDirectDraw2_GetMonitorFrequency,
2106 (void*)17,
2107 IDirectDraw2_GetVerticalBlankStatus,
2108 (void*)19,
2109 Xlib_IDirectDraw2_RestoreDisplayMode,
2110 IDirectDraw2_SetCooperativeLevel,
2111 Xlib_IDirectDraw2_SetDisplayMode,
2112 IDirectDraw2_WaitForVerticalBlank,
2113 Xlib_IDirectDraw2_GetAvailableVidMem
2116 /******************************************************************************
2117 * DirectDrawCreate
2120 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2121 #ifdef HAVE_LIBXXF86DGA
2122 int memsize,banksize,width,major,minor,flags,height;
2123 char *addr;
2125 if (getuid() != 0) {
2126 MSG("Must be root to use XF86DGA!\n");
2127 MessageBox32A(0,"Using the XF86DGA extension requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2128 return E_UNEXPECTED;
2130 if (!DDRAW_DGA_Available()) {
2131 TRACE(ddraw,"No XF86DGA detected.\n");
2132 return DDERR_GENERIC;
2134 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2135 (*lplpDD)->lpvtbl = &dga_ddvt;
2136 (*lplpDD)->ref = 1;
2137 TSXF86DGAQueryVersion(display,&major,&minor);
2138 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2139 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2140 if (!(flags & XF86DGADirectPresent))
2141 MSG("direct video is NOT PRESENT.\n");
2142 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2143 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2144 addr,width,banksize,memsize
2146 (*lplpDD)->e.dga.fb_width = width;
2147 (*lplpDD)->d.width = width;
2148 (*lplpDD)->e.dga.fb_addr = addr;
2149 (*lplpDD)->e.dga.fb_memsize = memsize;
2150 (*lplpDD)->e.dga.fb_banksize = banksize;
2152 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2153 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2154 (*lplpDD)->e.dga.fb_height = screenHeight;
2155 #ifdef DIABLO_HACK
2156 (*lplpDD)->e.dga.vpmask = 1;
2157 #else
2158 (*lplpDD)->e.dga.vpmask = 0;
2159 #endif
2161 /* just assume the default depth is the DGA depth too */
2162 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2163 #ifdef RESTORE_SIGNALS
2164 SIGNAL_InitEmulator();
2165 #endif
2166 return 0;
2167 #else /* defined(HAVE_LIBXXF86DGA) */
2168 return DDERR_INVALIDDIRECTDRAWGUID;
2169 #endif /* defined(HAVE_LIBXXF86DGA) */
2172 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2174 LRESULT ret;
2175 LPDIRECTDRAW ddraw = NULL;
2176 DWORD lastError;
2178 /*FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2180 SetLastError( ERROR_SUCCESS );
2181 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2182 if( (!ddraw) &&
2183 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2186 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2189 if( ddraw )
2191 /* Perform any special direct draw functions */
2192 if (msg==WM_PAINT)
2194 ddraw->e.xlib.paintable = 1;
2197 /* Now let the application deal with the rest of this */
2198 if( ddraw->d.mainWindow )
2201 /* Don't think that we actually need to call this but...
2202 might as well be on the safe side of things... */
2203 ret = DefWindowProc32A( hwnd, msg, wParam, lParam );
2205 if( !ret )
2207 /* We didn't handle the message - give it to the application */
2208 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2209 ddraw->d.mainWindow, msg, wParam, lParam );
2213 else
2215 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2219 else
2221 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2224 return ret;
2227 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2228 WNDCLASS32A wc;
2229 int have_xshm = 0;
2230 WND* pParentWindow;
2232 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2233 (*lplpDD)->lpvtbl = &xlib_ddvt;
2234 (*lplpDD)->ref = 1;
2235 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
2236 (*lplpDD)->e.xlib.use_xshm = have_xshm;
2237 wc.style = CS_GLOBALCLASS;
2238 wc.lpfnWndProc = Xlib_DDWndProc;
2239 wc.cbClsExtra = 0;
2240 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
2241 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
2243 /* We can be a child of the desktop since we're really important */
2244 pParentWindow = WIN_GetDesktop();
2245 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
2246 wc.hInstance = 0;
2248 wc.hIcon = 0;
2249 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
2250 wc.hbrBackground= NULL_BRUSH;
2251 wc.lpszMenuName = 0;
2252 wc.lpszClassName= "WINE_DirectDraw";
2254 (*lplpDD)->e.xlib.winclass = RegisterClass32A(&wc);
2256 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2257 (*lplpDD)->d.height = screenHeight;
2258 (*lplpDD)->d.width = screenWidth;
2259 return 0;
2262 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
2263 char xclsid[50];
2265 if (HIWORD(lpGUID))
2266 WINE_StringFromCLSID(lpGUID,xclsid);
2267 else {
2268 sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID);
2269 lpGUID = NULL;
2272 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
2274 if (!lpGUID) {
2275 /* if they didn't request a particular interface, use the best
2276 * supported one */
2277 if (DDRAW_DGA_Available())
2278 lpGUID = &DGA_DirectDraw_GUID;
2279 else
2280 lpGUID = &XLIB_DirectDraw_GUID;
2283 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
2284 return DGA_DirectDrawCreate(lplpDD, pUnkOuter);
2285 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
2286 return Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
2288 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
2289 return DDERR_INVALIDDIRECTDRAWGUID;