Use $(AS) instead of $(CC) to compile .s files.
[wine/multimedia.git] / graphics / ddraw.c
blob3677f4bb684966df9bcb3d4d1a753fa4ad191b79
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.
18 #include "config.h"
19 #include <unistd.h>
20 #include <assert.h>
21 #include "ts_xlib.h"
22 #include <sys/signal.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"
40 #ifdef HAVE_LIBXXF86DGA
41 #include "ts_xf86dga.h"
42 #endif
44 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
45 #undef DIABLO_HACK
47 /* restore signal handlers overwritten by XF86DGA
48 * this is a define, for it will only work in emulator mode
50 #undef RESTORE_SIGNALS
52 /* Where do these GUIDs come from? mkuuid.
53 * They exist solely to distinguish between the targets Wine support,
54 * and should be different than any other GUIDs in existence.
56 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
57 0xe2dcb020,
58 0xdc60,
59 0x11d1,
60 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
63 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
64 0x1574a740,
65 0xdc61,
66 0x11d1,
67 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
70 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
71 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
72 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
73 static struct IDirectDrawClipper_VTable ddclipvt;
74 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
75 static struct IDirect3D_VTable d3dvt;
76 static struct IDirect3D2_VTable d3d2vt;
78 void Xlib_MessagePump(HWND32 hwnd) {
79 MSG32 msg32;
81 while (EVENT_WaitNetEvent(FALSE,FALSE)) {
82 while (PeekMessage32A(&msg32,0,0,0,0)) {
83 GetMessage32A(&msg32,0,0,0);
84 TranslateMessage32(&msg32);
85 DispatchMessage32A(&msg32);
90 BOOL32
91 DDRAW_DGA_Available()
93 #ifdef HAVE_LIBXXF86DGA
94 int evbase, evret;
95 return (getuid() == 0)&&TSXF86DGAQueryExtension(display,&evbase,&evret);
96 #else /* defined(HAVE_LIBXXF86DGA) */
97 return 0;
98 #endif /* defined(HAVE_LIBXXF86DGA) */
101 HRESULT WINAPI
102 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
103 if (DDRAW_DGA_Available()) {
104 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
106 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
107 ddenumproc(NULL,"WINE","display",data);
108 return 0;
111 /* What is this doing here? */
112 HRESULT WINAPI
113 DSoundHelp(DWORD x,DWORD y,DWORD z) {
114 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
115 return 0;
119 /******************************************************************************
120 * internal helper functions
122 static void _dump_DDBLTFX(DWORD flagmask) {
123 int i;
124 const struct {
125 DWORD mask;
126 char *name;
127 } flags[] = {
128 #define FE(x) { x, #x},
129 FE(DDBLTFX_ARITHSTRETCHY)
130 FE(DDBLTFX_MIRRORLEFTRIGHT)
131 FE(DDBLTFX_MIRRORUPDOWN)
132 FE(DDBLTFX_NOTEARING)
133 FE(DDBLTFX_ROTATE180)
134 FE(DDBLTFX_ROTATE270)
135 FE(DDBLTFX_ROTATE90)
136 FE(DDBLTFX_ZBUFFERRANGE)
137 FE(DDBLTFX_ZBUFFERBASEDEST)
139 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
140 if (flags[i].mask & flagmask) {
141 DUMP("%s ",flags[i].name);
144 DUMP("\n");
148 static void _dump_DDBLTFAST(DWORD flagmask) {
149 int i;
150 const struct {
151 DWORD mask;
152 char *name;
153 } flags[] = {
154 #define FE(x) { x, #x},
155 FE(DDBLTFAST_NOCOLORKEY)
156 FE(DDBLTFAST_SRCCOLORKEY)
157 FE(DDBLTFAST_DESTCOLORKEY)
158 FE(DDBLTFAST_WAIT)
160 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
161 if (flags[i].mask & flagmask)
162 DUMP("%s ",flags[i].name);
163 DUMP("\n");
166 static void _dump_DDBLT(DWORD flagmask) {
167 int i;
168 const struct {
169 DWORD mask;
170 char *name;
171 } flags[] = {
172 #define FE(x) { x, #x},
173 FE(DDBLT_ALPHADEST)
174 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
175 FE(DDBLT_ALPHADESTNEG)
176 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
177 FE(DDBLT_ALPHAEDGEBLEND)
178 FE(DDBLT_ALPHASRC)
179 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
180 FE(DDBLT_ALPHASRCNEG)
181 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
182 FE(DDBLT_ASYNC)
183 FE(DDBLT_COLORFILL)
184 FE(DDBLT_DDFX)
185 FE(DDBLT_DDROPS)
186 FE(DDBLT_KEYDEST)
187 FE(DDBLT_KEYDESTOVERRIDE)
188 FE(DDBLT_KEYSRC)
189 FE(DDBLT_KEYSRCOVERRIDE)
190 FE(DDBLT_ROP)
191 FE(DDBLT_ROTATIONANGLE)
192 FE(DDBLT_ZBUFFER)
193 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
194 FE(DDBLT_ZBUFFERDESTOVERRIDE)
195 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
196 FE(DDBLT_ZBUFFERSRCOVERRIDE)
197 FE(DDBLT_WAIT)
198 FE(DDBLT_DEPTHFILL)
200 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
201 if (flags[i].mask & flagmask)
202 DUMP("%s ",flags[i].name);
205 static void _dump_DDSCAPS(DWORD flagmask) {
206 int i;
207 const struct {
208 DWORD mask;
209 char *name;
210 } flags[] = {
211 #define FE(x) { x, #x},
212 FE(DDSCAPS_RESERVED1)
213 FE(DDSCAPS_ALPHA)
214 FE(DDSCAPS_BACKBUFFER)
215 FE(DDSCAPS_COMPLEX)
216 FE(DDSCAPS_FLIP)
217 FE(DDSCAPS_FRONTBUFFER)
218 FE(DDSCAPS_OFFSCREENPLAIN)
219 FE(DDSCAPS_OVERLAY)
220 FE(DDSCAPS_PALETTE)
221 FE(DDSCAPS_PRIMARYSURFACE)
222 FE(DDSCAPS_PRIMARYSURFACELEFT)
223 FE(DDSCAPS_SYSTEMMEMORY)
224 FE(DDSCAPS_TEXTURE)
225 FE(DDSCAPS_3DDEVICE)
226 FE(DDSCAPS_VIDEOMEMORY)
227 FE(DDSCAPS_VISIBLE)
228 FE(DDSCAPS_WRITEONLY)
229 FE(DDSCAPS_ZBUFFER)
230 FE(DDSCAPS_OWNDC)
231 FE(DDSCAPS_LIVEVIDEO)
232 FE(DDSCAPS_HWCODEC)
233 FE(DDSCAPS_MODEX)
234 FE(DDSCAPS_MIPMAP)
235 FE(DDSCAPS_RESERVED2)
236 FE(DDSCAPS_ALLOCONLOAD)
237 FE(DDSCAPS_VIDEOPORT)
238 FE(DDSCAPS_LOCALVIDMEM)
239 FE(DDSCAPS_NONLOCALVIDMEM)
240 FE(DDSCAPS_STANDARDVGAMODE)
241 FE(DDSCAPS_OPTIMIZED)
243 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
244 if (flags[i].mask & flagmask)
245 DUMP("%s ",flags[i].name);
246 DUMP("\n");
249 static void _dump_DDSD(DWORD flagmask) {
250 int i;
251 const struct {
252 DWORD mask;
253 char *name;
254 } flags[] = {
255 FE(DDSD_CAPS)
256 FE(DDSD_HEIGHT)
257 FE(DDSD_WIDTH)
258 FE(DDSD_PITCH)
259 FE(DDSD_BACKBUFFERCOUNT)
260 FE(DDSD_ZBUFFERBITDEPTH)
261 FE(DDSD_ALPHABITDEPTH)
262 FE(DDSD_PIXELFORMAT)
263 FE(DDSD_CKDESTOVERLAY)
264 FE(DDSD_CKDESTBLT)
265 FE(DDSD_CKSRCOVERLAY)
266 FE(DDSD_CKSRCBLT)
267 FE(DDSD_MIPMAPCOUNT)
268 FE(DDSD_REFRESHRATE)
269 FE(DDSD_LINEARSIZE)
270 FE(DDSD_LPSURFACE)
272 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
273 if (flags[i].mask & flagmask)
274 DUMP("%s ",flags[i].name);
275 DUMP("\n");
278 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
279 static XVisualInfo *vi;
280 XVisualInfo vt;
281 int nitems;
283 if (!vi)
284 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
286 pf->dwFourCC = 0;
287 if (ddraw->d.depth==8) {
288 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
289 pf->x.dwRGBBitCount = 8;
290 pf->y.dwRBitMask = 0;
291 pf->z.dwGBitMask = 0;
292 pf->xx.dwBBitMask = 0;
293 pf->xy.dwRGBAlphaBitMask= 0;
294 return 0;
296 if (ddraw->d.depth==16) {
297 pf->dwFlags = DDPF_RGB;
298 pf->x.dwRGBBitCount = 16;
299 pf->y.dwRBitMask = vi[0].red_mask;
300 pf->z.dwGBitMask = vi[0].green_mask;
301 pf->xx.dwBBitMask = vi[0].blue_mask;
302 pf->xy.dwRGBAlphaBitMask= 0;
303 return 0;
305 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
306 return DDERR_GENERIC;
309 /******************************************************************************
310 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
312 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
313 * DDS and DDS2 use those functions. (Function calls did not change (except
314 * using different DirectDrawSurfaceX version), just added flags and functions)
316 static HRESULT WINAPI IDirectDrawSurface3_Lock(
317 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
319 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
320 this,lprect,lpddsd,flags,(DWORD)hnd);
321 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
322 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
323 this,lprect,lpddsd,flags,(DWORD)hnd);
325 if (lprect) {
326 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
327 lprect->top,lprect->left,lprect->bottom,lprect->right
329 lpddsd->y.lpSurface = this->s.surface +
330 (lprect->top*this->s.lpitch) +
331 (lprect->left*(this->s.ddraw->d.depth/8));
332 } else {
333 assert(this->s.surface);
334 lpddsd->y.lpSurface = this->s.surface;
336 lpddsd->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_LPSURFACE;
337 lpddsd->dwWidth = this->s.width;
338 lpddsd->dwHeight = this->s.height;
339 lpddsd->lPitch = this->s.lpitch;
340 _getpixelformat(this->s.ddraw,&(lpddsd->ddpfPixelFormat));
341 return 0;
344 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
345 LPDIRECTDRAWSURFACE3 this,LPVOID surface
347 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
348 return 0;
351 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
352 LPDIRECTDRAWSURFACE3 this,LPVOID surface
354 Xlib_MessagePump(this->s.ddraw->e.xlib.window);
356 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
358 if (!this->s.ddraw->e.xlib.paintable)
360 return DD_OK;
363 TSXPutImage( display,
364 this->s.ddraw->e.xlib.drawable,
365 DefaultGCOfScreen(screen),
366 this->t.xlib.image,
367 0, 0, 0, 0,
368 this->t.xlib.image->width,
369 this->t.xlib.image->height
371 if (this->s.palette && this->s.palette->cm)
372 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
374 return DD_OK;
377 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
378 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
380 #ifdef HAVE_LIBXXF86DGA
381 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
382 if (!flipto) {
383 if (this->s.backbuffer)
384 flipto = this->s.backbuffer;
385 else
386 flipto = this;
388 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
390 if (flipto->s.palette && flipto->s.palette->cm) {
391 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
393 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
395 if (flipto!=this) {
396 int tmp;
397 LPVOID ptmp;
399 tmp = this->t.dga.fb_height;
400 this->t.dga.fb_height = flipto->t.dga.fb_height;
401 flipto->t.dga.fb_height = tmp;
403 ptmp = this->s.surface;
404 this->s.surface = flipto->s.surface;
405 flipto->s.surface = ptmp;
407 return 0;
408 #else /* defined(HAVE_LIBXXF86DGA) */
409 return E_UNEXPECTED;
410 #endif /* defined(HAVE_LIBXXF86DGA) */
413 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
414 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
416 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
417 Xlib_MessagePump(this->s.ddraw->e.xlib.window);
418 if (!this->s.ddraw->e.xlib.paintable)
419 return 0;
421 if (!flipto) {
422 if (this->s.backbuffer)
423 flipto = this->s.backbuffer;
424 else
425 flipto = this;
428 TSXPutImage(display,
429 this->s.ddraw->e.xlib.drawable,
430 DefaultGCOfScreen(screen),
431 flipto->t.xlib.image,
432 0, 0, 0, 0,
433 flipto->t.xlib.image->width,
434 flipto->t.xlib.image->height);
435 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
436 if (flipto!=this) {
437 XImage *tmp;
438 LPVOID *surf;
439 tmp = this->t.xlib.image;
440 this->t.xlib.image = flipto->t.xlib.image;
441 flipto->t.xlib.image = tmp;
442 surf = this->s.surface;
443 this->s.surface = flipto->s.surface;
444 flipto->s.surface = surf;
446 return 0;
449 /* The IDirectDrawSurface3::SetPalette method attaches the specified
450 * DirectDrawPalette object to a surface. The surface uses this palette for all
451 * subsequent operations. The palette change takes place immediately.
453 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
454 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
456 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
458 /* According to spec, we are only supposed to
459 * AddRef if this is not the same palette.
461 if( this->s.palette != pal )
463 if( pal != NULL )
464 pal->lpvtbl->fnAddRef( pal );
465 if( this->s.palette != NULL )
466 this->s.palette->lpvtbl->fnRelease( this->s.palette );
467 this->s.palette = pal;
469 /* I think that we need to attach it to all backbuffers...*/
470 if( this->s.backbuffer ) {
471 if( this->s.backbuffer->s.palette )
472 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
473 this->s.backbuffer->s.palette );
474 this->s.backbuffer->s.palette = pal;
475 if( pal )
476 pal->lpvtbl->fnAddRef( pal );
479 /* Perform the refresh */
480 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
483 return 0;
486 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
487 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
489 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
491 /* According to spec, we are only supposed to
492 * AddRef if this is not the same palette.
494 if( this->s.palette != pal )
496 if( pal != NULL )
497 pal->lpvtbl->fnAddRef( pal );
498 if( this->s.palette != NULL )
499 this->s.palette->lpvtbl->fnRelease( this->s.palette );
500 this->s.palette = pal;
502 /* I think that we need to attach it to all backbuffers...*/
503 if( this->s.backbuffer ) {
504 if( this->s.backbuffer->s.palette )
505 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
506 this->s.backbuffer->s.palette = pal;
507 if( pal ) pal->lpvtbl->fnAddRef( pal );
509 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
511 return 0;
514 static HRESULT WINAPI IDirectDrawSurface3_Blt(
515 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
517 RECT32 xdst,xsrc;
518 int i,j;
520 if (rdst) {
521 memcpy(&xdst,rdst,sizeof(xdst));
522 } else {
523 xdst.top = 0;
524 xdst.bottom = this->s.height;
525 xdst.left = 0;
526 xdst.right = this->s.width;
529 if (rsrc) {
530 memcpy(&xsrc,rsrc,sizeof(xsrc));
531 } else if (src) {
532 xsrc.top = 0;
533 xsrc.bottom = src->s.height;
534 xsrc.left = 0;
535 xsrc.right = src->s.width;
538 if (dwFlags & DDBLT_COLORFILL) {
539 int bpp = this->s.ddraw->d.depth/8;
540 LPBYTE xline,xpixel;
542 xline = (LPBYTE)this->s.surface+xdst.top*this->s.lpitch;
543 for (i=xdst.top;i<xdst.bottom;i++) {
544 xpixel = xline+bpp*xdst.left;
546 for (j=xdst.left;j<xdst.right;j++) {
547 /* FIXME: this only works on little endian
548 * architectures, where DWORD starts with low
549 * byte first!
551 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
552 xpixel += bpp;
554 xline += this->s.lpitch;
556 dwFlags &= ~(DDBLT_COLORFILL);
558 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
559 if ( (xsrc.top ==0) && (xsrc.bottom ==this->s.height) &&
560 (xsrc.left==0) && (xsrc.right ==this->s.width) &&
561 (xdst.top ==0) && (xdst.bottom ==this->s.height) &&
562 (xdst.left==0) && (xdst.right ==this->s.width) &&
563 !dwFlags
565 memcpy(this->s.surface,src->s.surface,this->s.height*this->s.lpitch);
566 return 0;
568 if (dwFlags) {
569 FIXME(ddraw,"(%p)->(%p,%p,%p,%08lx,%p),stub!\n",
570 this,rdst,src,rsrc,dwFlags,lpbltfx
572 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
573 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
574 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
576 if (dwFlags & DDBLT_DDFX) {
577 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
579 return 0;
582 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
583 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
585 int i,bpp;
586 if (TRACE_ON(ddraw)) {
587 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx),stub!\n",
588 this,dstx,dsty,src,rsrc,trans
590 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
591 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
593 bpp = this->s.ddraw->d.depth/8;
594 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
595 memcpy( this->s.surface+((i+dsty)*this->s.width*bpp)+dstx*bpp,
596 src->s.surface +(rsrc->top+i)*src->s.width*bpp+rsrc->left*bpp,
597 (rsrc->right-rsrc->left)*bpp
600 return 0;
603 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
604 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
606 TRACE(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
607 this,ddbltbatch,x,y
609 return 0;
612 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
613 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
615 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
616 caps->dwCaps = DDCAPS_PALETTE; /* probably more */
617 return 0;
620 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
621 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
622 ) {
623 if (TRACE_ON(ddraw)) {
624 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
625 this,ddsd);
626 fprintf(stderr," flags: ");
627 _dump_DDSD(ddsd->dwFlags);
628 fprintf(stderr,"\n");
631 ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
632 ddsd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
633 ddsd->dwBackBufferCount = 1;
634 ddsd->dwHeight = this->s.height;
635 ddsd->dwWidth = this->s.width;
636 ddsd->lPitch = this->s.lpitch;
637 if (this->s.backbuffer)
638 ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
639 _getpixelformat(this->s.ddraw,&(ddsd->ddpfPixelFormat));
641 return 0;
644 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
645 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
647 return ++(this->ref);
650 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
651 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
653 #ifdef HAVE_LIBXXF86DGA
654 if (!--(this->ref)) {
655 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
656 /* clear out of surface list */
657 if (this->t.dga.fb_height == -1) {
658 HeapFree(GetProcessHeap(),0,this->s.surface);
659 } else {
660 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
662 HeapFree(GetProcessHeap(),0,this);
663 return 0;
665 #endif /* defined(HAVE_LIBXXF86DGA) */
666 return this->ref;
669 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
670 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
672 if (!--(this->ref)) {
673 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
674 HeapFree(GetProcessHeap(),0,this->s.surface);
676 if( this->s.backbuffer )
678 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
681 this->t.xlib.image->data = NULL;
682 TSXDestroyImage(this->t.xlib.image);
683 this->t.xlib.image = 0;
685 if (this->s.palette)
686 this->s.palette->lpvtbl->fnRelease(this->s.palette);
689 HeapFree(GetProcessHeap(),0,this);
690 return 0;
692 return this->ref;
695 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
696 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
698 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
699 this, lpddsd, lpdsf);
701 if (TRACE_ON(ddraw)) {
702 TRACE(ddraw," caps ");
703 _dump_DDSCAPS(lpddsd->dwCaps);
706 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
707 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
708 return E_FAIL;
711 /* FIXME: should handle more than one backbuffer */
712 *lpdsf = this->s.backbuffer;
714 if( this->s.backbuffer )
716 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
719 return 0;
722 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
723 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
725 return DDERR_ALREADYINITIALIZED;
728 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
729 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
731 return _getpixelformat(this->s.ddraw,pf);
734 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
735 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
736 return 0;
739 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
740 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
742 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
743 return 0;
746 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
747 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
749 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
750 return 0;
753 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
754 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
756 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
757 this->s.backbuffer = surf;
758 return 0;
761 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
762 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
763 *lphdc = BeginPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps);
764 return 0;
767 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
768 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
769 EndPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps);
770 return 0;
774 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
775 char xrefiid[50];
777 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
778 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
780 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
781 * the same interface. And IUnknown does that too of course.
783 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
784 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
785 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
786 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
788 *obj = this;
789 this->lpvtbl->fnAddRef(this);
790 return 0;
792 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
793 return OLE_E_ENUM_NOMORE;
796 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
797 TRACE(ddraw,"(%p)->(), stub!\n",this);
798 return 0; /* hmm */
801 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
802 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
803 return 0;
806 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
807 FIXME(ddraw,"(%p)->(),stub!\n",this);
808 return 0;
811 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
812 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
814 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
816 if( dwFlags & DDCKEY_SRCBLT )
818 dwFlags &= ~DDCKEY_SRCBLT;
821 if( dwFlags )
823 TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
826 return DD_OK;
829 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
830 IDirectDrawSurface3_QueryInterface,
831 IDirectDrawSurface3_AddRef,
832 DGA_IDirectDrawSurface3_Release,
833 IDirectDrawSurface3_AddAttachedSurface,
834 (void*)5,
835 IDirectDrawSurface3_Blt,
836 IDirectDrawSurface3_BltBatch,
837 IDirectDrawSurface3_BltFast,
838 (void*)9,
839 IDirectDrawSurface3_EnumAttachedSurfaces,
840 (void*)11,
841 DGA_IDirectDrawSurface3_Flip,
842 IDirectDrawSurface3_GetAttachedSurface,
843 IDirectDrawSurface3_GetBltStatus,
844 IDirectDrawSurface3_GetCaps,
845 (void*)16,
846 (void*)17,
847 IDirectDrawSurface3_GetDC,
848 (void*)19,
849 IDirectDrawSurface3_GetOverlayPosition,
850 (void*)21,
851 IDirectDrawSurface3_GetPixelFormat,
852 IDirectDrawSurface3_GetSurfaceDesc,
853 IDirectDrawSurface3_Initialize,
854 IDirectDrawSurface3_IsLost,
855 IDirectDrawSurface3_Lock,
856 IDirectDrawSurface3_ReleaseDC,
857 IDirectDrawSurface3_Restore,
858 IDirectDrawSurface3_SetClipper,
859 IDirectDrawSurface3_SetColorKey,
860 (void*)31,
861 DGA_IDirectDrawSurface3_SetPalette,
862 DGA_IDirectDrawSurface3_Unlock,
863 (void*)34,
864 (void*)35,
865 (void*)36,
866 (void*)37,
867 (void*)38,
868 (void*)39,
869 (void*)40,
872 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
873 IDirectDrawSurface3_QueryInterface,
874 IDirectDrawSurface3_AddRef,
875 Xlib_IDirectDrawSurface3_Release,
876 IDirectDrawSurface3_AddAttachedSurface,
877 (void*)5,
878 IDirectDrawSurface3_Blt,
879 IDirectDrawSurface3_BltBatch,
880 IDirectDrawSurface3_BltFast,
881 (void*)9,
882 IDirectDrawSurface3_EnumAttachedSurfaces,
883 (void*)11,
884 Xlib_IDirectDrawSurface3_Flip,
885 IDirectDrawSurface3_GetAttachedSurface,
886 IDirectDrawSurface3_GetBltStatus,
887 IDirectDrawSurface3_GetCaps,
888 (void*)16,
889 (void*)17,
890 IDirectDrawSurface3_GetDC,
891 (void*)19,
892 IDirectDrawSurface3_GetOverlayPosition,
893 (void*)21,
894 IDirectDrawSurface3_GetPixelFormat,
895 IDirectDrawSurface3_GetSurfaceDesc,
896 IDirectDrawSurface3_Initialize,
897 IDirectDrawSurface3_IsLost,
898 IDirectDrawSurface3_Lock,
899 IDirectDrawSurface3_ReleaseDC,
900 IDirectDrawSurface3_Restore,
901 IDirectDrawSurface3_SetClipper,
902 IDirectDrawSurface3_SetColorKey,
903 (void*)31,
904 Xlib_IDirectDrawSurface3_SetPalette,
905 Xlib_IDirectDrawSurface3_Unlock,
906 (void*)34,
907 (void*)35,
908 (void*)36,
909 (void*)37,
910 (void*)38,
911 (void*)39,
912 (void*)40,
915 /******************************************************************************
916 * IDirectDrawClipper
918 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
919 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
921 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
922 return 0;
925 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
926 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
928 this->ref--;
929 if (this->ref)
930 return this->ref;
931 HeapFree(GetProcessHeap(),0,this);
932 return 0;
935 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
936 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
938 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
939 if (hmm) *hmm=0;
940 return 0;
943 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
944 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
946 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
947 return 0;
950 static struct IDirectDrawClipper_VTable ddclipvt = {
951 (void*)1,
952 (void*)2,
953 IDirectDrawClipper_Release,
954 IDirectDrawClipper_GetClipList,
955 (void*)5,
956 (void*)6,
957 (void*)7,
958 IDirectDrawClipper_SetClipList,
959 IDirectDrawClipper_SetHwnd
962 /******************************************************************************
963 * IDirectDrawPalette
965 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
966 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
968 XColor xc;
969 int i;
971 if (!this->cm) /* should not happen */ {
972 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
973 return DDERR_GENERIC;
975 for (i=0;i<count;i++) {
976 #if 0
978 xc.pixel = i+start;
979 TSXQueryColor(display,this->cm,&xc);
980 palent[i].peRed = xc.red>>8;
981 palent[i].peGreen = xc.green>>8;
982 palent[i].peBlue = xc.blue>>8;
983 #endif
985 palent[i].peRed = this->palents[start+i].peRed;
986 palent[i].peBlue = this->palents[start+i].peBlue;
987 palent[i].peGreen = this->palents[start+i].peGreen;
988 palent[i].peFlags = this->palents[start+i].peFlags;
991 return 0;
994 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
995 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
997 XColor xc;
998 int i;
1000 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1001 this,x,start,count,palent
1003 if (!this->cm) /* should not happen */ {
1004 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1005 return DDERR_GENERIC;
1007 if (!this->ddraw->e.xlib.paintable)
1008 return 0;
1009 for (i=0;i<count;i++) {
1010 xc.red = palent[i].peRed<<8;
1011 xc.blue = palent[i].peBlue<<8;
1012 xc.green = palent[i].peGreen<<8;
1013 xc.flags = DoRed|DoBlue|DoGreen;
1014 xc.pixel = start+i;
1016 TSXStoreColor(display,this->cm,&xc);
1018 this->palents[start+i].peRed = palent[i].peRed;
1019 this->palents[start+i].peBlue = palent[i].peBlue;
1020 this->palents[start+i].peGreen = palent[i].peGreen;
1021 this->palents[start+i].peFlags = palent[i].peFlags;
1023 return 0;
1026 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1027 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1029 #ifdef HAVE_LIBXXF86DGA
1030 XColor xc;
1031 Colormap cm;
1032 int i;
1034 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1035 this,x,start,count,palent
1037 if (!this->cm) /* should not happen */ {
1038 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1039 return DDERR_GENERIC;
1041 /* FIXME: free colorcells instead of freeing whole map */
1042 cm = this->cm;
1043 this->cm = TSXCopyColormapAndFree(display,this->cm);
1044 TSXFreeColormap(display,cm);
1046 for (i=0;i<count;i++) {
1047 xc.red = palent[i].peRed<<8;
1048 xc.blue = palent[i].peBlue<<8;
1049 xc.green = palent[i].peGreen<<8;
1050 xc.flags = DoRed|DoBlue|DoGreen;
1051 xc.pixel = i+start;
1053 TSXStoreColor(display,this->cm,&xc);
1055 this->palents[start+i].peRed = palent[i].peRed;
1056 this->palents[start+i].peBlue = palent[i].peBlue;
1057 this->palents[start+i].peGreen = palent[i].peGreen;
1058 this->palents[start+i].peFlags = palent[i].peFlags;
1060 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1061 return 0;
1062 #else /* defined(HAVE_LIBXXF86DGA) */
1063 return E_UNEXPECTED;
1064 #endif /* defined(HAVE_LIBXXF86DGA) */
1067 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1068 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1069 if (!--(this->ref)) {
1070 if (this->cm) {
1071 TSXFreeColormap(display,this->cm);
1072 this->cm = 0;
1074 HeapFree(GetProcessHeap(),0,this);
1075 return 0;
1077 return this->ref;
1080 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1082 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1083 return ++(this->ref);
1086 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1087 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1089 return DDERR_ALREADYINITIALIZED;
1092 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1093 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1095 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1096 return DD_OK;
1099 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1100 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1102 char xrefiid[50];
1104 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1105 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1107 return S_OK;
1110 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1111 IDirectDrawPalette_QueryInterface,
1112 IDirectDrawPalette_AddRef,
1113 IDirectDrawPalette_Release,
1114 IDirectDrawPalette_GetCaps,
1115 IDirectDrawPalette_GetEntries,
1116 IDirectDrawPalette_Initialize,
1117 DGA_IDirectDrawPalette_SetEntries
1120 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1121 IDirectDrawPalette_QueryInterface,
1122 IDirectDrawPalette_AddRef,
1123 IDirectDrawPalette_Release,
1124 IDirectDrawPalette_GetCaps,
1125 IDirectDrawPalette_GetEntries,
1126 IDirectDrawPalette_Initialize,
1127 Xlib_IDirectDrawPalette_SetEntries
1130 static HRESULT WINAPI IDirect3D_QueryInterface(
1131 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1133 /* FIXME: Not sure if this is correct */
1134 char xrefiid[50];
1136 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1137 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1138 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1139 *obj = this;
1140 this->lpvtbl->fnAddRef(this);
1141 return 0;
1143 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1144 LPDIRECT3D d3d;
1146 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1147 d3d->ref = 1;
1148 d3d->ddraw = (LPDIRECTDRAW)this;
1149 this->lpvtbl->fnAddRef(this);
1150 d3d->lpvtbl = &d3dvt;
1151 *obj = d3d;
1152 return 0;
1154 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1155 LPDIRECT3D2 d3d;
1157 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1158 d3d->ref = 1;
1159 d3d->ddraw = (LPDIRECTDRAW)this;
1160 this->lpvtbl->fnAddRef(this);
1161 d3d->lpvtbl = &d3d2vt;
1162 *obj = d3d;
1163 return 0;
1165 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1166 return OLE_E_ENUM_NOMORE;
1169 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1170 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1172 return ++(this->ref);
1175 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1177 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1179 if (!--(this->ref)) {
1180 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1181 HeapFree(GetProcessHeap(),0,this);
1182 return 0;
1184 return this->ref;
1187 static HRESULT WINAPI IDirect3D_Initialize(
1188 LPDIRECT3D this, REFIID refiid )
1190 /* FIXME: Not sure if this is correct */
1191 char xrefiid[50];
1193 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1194 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1196 return DDERR_ALREADYINITIALIZED;
1199 /*******************************************************************************
1200 * IDirect3D
1202 static struct IDirect3D_VTable d3dvt = {
1203 (void*)IDirect3D_QueryInterface,
1204 (void*)IDirect3D_AddRef,
1205 (void*)IDirect3D_Release,
1206 IDirect3D_Initialize,
1207 (void*)5,
1208 (void*)6,
1209 (void*)7,
1210 (void*)8,
1211 (void*)9,
1214 /*******************************************************************************
1215 * IDirect3D2
1217 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1218 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1220 if (!--(this->ref)) {
1221 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1222 HeapFree(GetProcessHeap(),0,this);
1223 return 0;
1225 return this->ref;
1228 static HRESULT WINAPI IDirect3D2_EnumDevices(
1229 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1231 D3DDEVICEDESC d1,d2;
1233 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1234 d1.dwSize = sizeof(d1);
1235 d1.dwFlags = 0;
1237 d2.dwSize = sizeof(d2);
1238 d2.dwFlags = 0;
1239 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1240 return 0;
1243 static struct IDirect3D2_VTable d3d2vt = {
1244 (void*)1,
1245 (void*)2,
1246 IDirect3D2_Release,
1247 IDirect3D2_EnumDevices,
1248 (void*)5,
1249 (void*)6,
1250 (void*)7,
1251 (void*)8,
1252 (void*)9,
1255 /*******************************************************************************
1256 * IDirectDraw
1259 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1260 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1262 static INT32 ddrawXlibThisOffset = 0;
1264 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1265 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1267 #ifdef HAVE_LIBXXF86DGA
1268 int i;
1270 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1271 if (TRACE_ON(ddraw)) {
1272 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1273 _dump_DDSD(lpddsd->dwFlags);
1274 fprintf(stderr,"caps ");
1275 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1276 fprintf(stderr,"]\n");
1279 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1280 this->lpvtbl->fnAddRef(this);
1281 (*lpdsf)->ref = 1;
1282 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1283 if ( (lpddsd->dwFlags & DDSD_CAPS) &&
1284 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1286 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1287 lpddsd->dwWidth = this->e.dga.fb_width;
1288 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1289 lpddsd->dwHeight = this->e.dga.fb_height;
1290 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1291 (*lpdsf)->t.dga.fb_height = -1;
1292 (*lpdsf)->s.lpitch = lpddsd->dwWidth*this->d.depth/8;
1293 TRACE(ddraw,"using system memory for a primary surface\n");
1294 } else {
1295 for (i=0;i<32;i++)
1296 if (!(this->e.dga.vpmask & (1<<i)))
1297 break;
1298 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1299 /* if i == 32 or maximum ... return error */
1300 this->e.dga.vpmask|=(1<<i);
1301 (*lpdsf)->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1302 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1303 (*lpdsf)->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1306 lpddsd->lPitch = (*lpdsf)->s.lpitch;
1308 (*lpdsf)->s.width = this->d.width;
1309 (*lpdsf)->s.height = this->d.height;
1310 (*lpdsf)->s.ddraw = this;
1311 (*lpdsf)->s.backbuffer = NULL;
1312 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1313 LPDIRECTDRAWSURFACE3 back;
1315 if (lpddsd->dwBackBufferCount>1)
1316 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1318 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1319 this->lpvtbl->fnAddRef(this);
1320 back->ref = 1;
1321 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1322 for (i=0;i<32;i++)
1323 if (!(this->e.dga.vpmask & (1<<i)))
1324 break;
1325 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1326 /* if i == 32 or maximum ... return error */
1327 this->e.dga.vpmask|=(1<<i);
1328 back->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1329 back->t.dga.fb_height = i*this->e.dga.fb_height;
1331 back->s.width = this->d.width;
1332 back->s.height = this->d.height;
1333 back->s.ddraw = this;
1334 back->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1335 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1336 * one! */
1338 return 0;
1339 #else /* defined(HAVE_LIBXXF86DGA) */
1340 return E_UNEXPECTED;
1341 #endif /* defined(HAVE_LIBXXF86DGA) */
1344 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1345 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1347 XImage *img;
1349 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1350 this,lpddsd,lpdsf,lpunk);
1352 if (TRACE_ON(ddraw)) {
1353 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1354 _dump_DDSD(lpddsd->dwFlags);
1355 fprintf(stderr,"caps ");
1356 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1357 fprintf(stderr,"]\n");
1360 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1362 this->lpvtbl->fnAddRef(this);
1363 (*lpdsf)->s.ddraw = this;
1364 (*lpdsf)->ref = 1;
1365 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1367 if ( (lpddsd->dwFlags & DDSD_CAPS) &&
1368 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1370 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1371 lpddsd->dwWidth = this->e.dga.fb_width;
1372 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1373 lpddsd->dwHeight = this->e.dga.fb_height;
1374 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1375 TRACE(ddraw,"using system memory for a primary surface\n");
1376 } else {
1377 TRACE(ddraw,"using standard XImage for a primary surface\n");
1378 /* FIXME: !8 bit images */
1379 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1380 lpddsd->dwWidth = this->d.width;
1381 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1382 lpddsd->dwHeight = this->d.height;
1384 (*lpdsf)->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpddsd->dwHeight*lpddsd->dwWidth*this->d.depth/8);
1385 (*lpdsf)->s.width = lpddsd->dwWidth;
1386 (*lpdsf)->s.height = lpddsd->dwHeight;
1389 (*lpdsf)->t.xlib.image = img =
1390 TSXCreateImage( display,
1391 DefaultVisualOfScreen(screen),
1392 /*FIXME: depth*/8,
1393 ZPixmap,
1395 (*lpdsf)->s.surface,
1396 (*lpdsf)->s.width,
1397 (*lpdsf)->s.height,
1399 (*lpdsf)->s.width*1
1400 /* FIXME: !8 bit images */
1402 /* END FIXME: Xlib */
1404 (*lpdsf)->s.lpitch = img->bytes_per_line;
1405 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1406 LPDIRECTDRAWSURFACE3 back;
1408 if (lpddsd->dwBackBufferCount>1)
1409 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1411 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1413 this->lpvtbl->fnAddRef(this);
1414 back->s.ddraw = this;
1416 back->ref = 1;
1417 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
1418 /* FIXME: !8 bit images */
1419 back->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1420 img->width*img->height
1422 back->t.xlib.image = TSXCreateImage(
1423 display,
1424 DefaultVisualOfScreen(screen),
1425 /*FIXME: depth*/8,
1426 ZPixmap,
1428 back->s.surface,
1429 this->d.width,
1430 this->d.height,
1432 this->d.width*1
1433 /* FIXME: !8 bit images */
1435 back->s.width = this->d.width;
1436 back->s.height = this->d.height;
1437 back->s.lpitch = back->t.xlib.image->bytes_per_line;
1438 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1439 * one! */
1441 return 0;
1444 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
1445 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1447 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1448 *dst = src; /* FIXME */
1449 return 0;
1452 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1453 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
1455 int i;
1456 const struct {
1457 int mask;
1458 char *name;
1459 } flagmap[] = {
1460 FE(DDSCL_FULLSCREEN)
1461 FE(DDSCL_ALLOWREBOOT)
1462 FE(DDSCL_NOWINDOWCHANGES)
1463 FE(DDSCL_NORMAL)
1464 FE(DDSCL_ALLOWMODEX)
1465 FE(DDSCL_EXCLUSIVE)
1466 FE(DDSCL_SETFOCUSWINDOW)
1467 FE(DDSCL_SETDEVICEWINDOW)
1468 FE(DDSCL_CREATEDEVICEWINDOW)
1471 TRACE(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
1472 if(TRACE_ON(ddraw)){
1473 dbg_decl_str(ddraw, 512);
1474 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1475 if (flagmap[i].mask & cooplevel)
1476 dsprintf(ddraw, "%s ", flagmap[i].name);
1477 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1479 this->d.mainWindow = hwnd;
1480 return 0;
1484 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
1485 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1487 #ifdef HAVE_LIBXXF86DGA
1488 int i,*depths,depcount;
1490 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
1492 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1493 for (i=0;i<depcount;i++)
1494 if (depths[i]==depth)
1495 break;
1496 TSXFree(depths);
1497 if (i==depcount) {/* not found */
1498 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1499 return DDERR_UNSUPPORTEDMODE;
1501 if (this->d.width < width) {
1502 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
1503 return DDERR_UNSUPPORTEDMODE;
1505 this->d.width = width;
1506 this->d.height = height;
1507 /* adjust fb_height, so we don't overlap */
1508 if (this->e.dga.fb_height < height)
1509 this->e.dga.fb_height = height;
1510 this->d.depth = depth;
1512 /* FIXME: this function OVERWRITES several signal handlers.
1513 * can we save them? and restore them later? In a way that
1514 * it works for the library too?
1516 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
1517 #ifdef DIABLO_HACK
1518 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
1519 #endif
1521 #ifdef RESTORE_SIGNALS
1522 SIGNAL_InitEmulator();
1523 #endif
1524 return 0;
1525 #else /* defined(HAVE_LIBXXF86DGA) */
1526 return E_UNEXPECTED;
1527 #endif /* defined(HAVE_LIBXXF86DGA) */
1530 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
1531 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1533 int i,*depths,depcount;
1534 char buf[200];
1536 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
1537 this, width, height, depth);
1539 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1540 for (i=0;i<depcount;i++)
1541 if (depths[i]==depth)
1542 break;
1543 TSXFree(depths);
1544 if (i==depcount) {/* not found */
1545 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
1546 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
1547 return DDERR_UNSUPPORTEDMODE;
1550 if (this->d.width < width) {
1551 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld",width,height,depth,width,this->d.width);
1552 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
1553 return DDERR_UNSUPPORTEDMODE;
1556 this->e.xlib.window = CreateWindowEx32A(
1558 "WINE_DirectDraw",
1559 "WINE_DirectDraw",
1560 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1561 0,0,
1562 width,
1563 height,
1567 NULL
1570 /* Store this with the window. We'll use it for the window procedure */
1571 SetWindowLong32A(this->e.xlib.window,ddrawXlibThisOffset,(LONG)this);
1573 this->e.xlib.paintable = 1;
1575 ShowWindow32(this->e.xlib.window,TRUE);
1576 UpdateWindow32(this->e.xlib.window);
1578 assert(this->e.xlib.window);
1580 this->e.xlib.drawable = WIN_FindWndPtr(this->e.xlib.window)->window;
1582 /* We don't have a context for this window. Host off the desktop */
1583 if( !this->e.xlib.drawable )
1585 this->e.xlib.drawable = WIN_GetDesktop()->window;
1588 this->d.width = width;
1589 this->d.height = height;
1591 /* adjust fb_height, so we don't overlap */
1593 if (this->e.dga.fb_height < height)
1594 this->e.dga.fb_height = height;*/
1595 this->d.depth = depth;
1596 return 0;
1599 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
1600 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1602 #ifdef HAVE_LIBXXF86DGA
1603 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1604 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
1605 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1606 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1607 if (caps2) {
1608 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
1609 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1610 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1612 return 0;
1613 #else /* defined(HAVE_LIBXXF86DGA) */
1614 return E_UNEXPECTED;
1615 #endif /* defined(HAVE_LIBXXF86DGA) */
1618 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
1619 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1621 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1622 /* FIXME: Xlib */
1623 caps1->dwVidMemTotal = 2048*1024;
1624 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1625 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1626 if (caps2) {
1627 caps2->dwVidMemTotal = 2048*1024;
1628 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1629 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1631 /* END FIXME: Xlib */
1632 return 0;
1635 static HRESULT WINAPI IDirectDraw2_CreateClipper(
1636 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
1638 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
1639 this,x,lpddclip,lpunk
1641 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1642 (*lpddclip)->ref = 1;
1643 (*lpddclip)->lpvtbl = &ddclipvt;
1644 return 0;
1647 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
1648 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1650 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1651 if (*lpddpal == NULL) return E_OUTOFMEMORY;
1652 (*lpddpal)->ref = 1;
1653 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1654 (*lpddpal)->installed = 0;
1655 if (this->d.depth<=8) {
1656 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
1657 } else {
1658 /* we don't want palettes in hicolor or truecolor */
1659 (*lpddpal)->cm = 0;
1661 return 0;
1664 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
1665 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1667 HRESULT res;
1668 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1669 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
1670 if (res != 0) return res;
1671 (*lpddpal)->lpvtbl = &dga_ddpalvt;
1672 return 0;
1675 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
1676 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1678 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1679 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1680 if (*lpddpal == NULL) return E_OUTOFMEMORY;
1681 (*lpddpal)->ref = 1;
1682 (*lpddpal)->installed = 0;
1684 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1685 this->lpvtbl->fnAddRef(this);
1687 if (this->d.depth<=8) {
1688 (*lpddpal)->cm = TSXCreateColormap(display,this->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
1689 /* later installed ...
1690 * TSXInstallColormap(display,(*lpddpal)->cm);
1691 * TSXSetWindowColormap(display,this->e.xlib.drawable,(*lpddpal)->cm);
1693 TSXInstallColormap(display,(*lpddpal)->cm);
1695 else
1697 /* we don't want palettes in hicolor or truecolor */
1698 (*lpddpal)->cm = 0;
1701 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
1702 return 0;
1705 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1706 #ifdef HAVE_LIBXXF86DGA
1707 TRACE(ddraw, "(%p)->()\n",this);
1708 Sleep(1000);
1709 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
1710 #ifdef RESTORE_SIGNALS
1711 SIGNAL_InitEmulator();
1712 #endif
1713 return 0;
1714 #else /* defined(HAVE_LIBXXF86DGA) */
1715 return E_UNEXPECTED;
1716 #endif
1719 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1720 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
1721 Sleep(1000);
1722 return 0;
1725 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
1726 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
1728 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
1729 return 0;
1732 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
1733 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1735 return ++(this->ref);
1738 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
1739 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1741 #ifdef HAVE_LIBXXF86DGA
1742 if (!--(this->ref)) {
1743 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
1744 #ifdef RESTORE_SIGNALS
1745 SIGNAL_InitEmulator();
1746 #endif
1747 HeapFree(GetProcessHeap(),0,this);
1748 return 0;
1750 #endif /* defined(HAVE_LIBXXF86DGA) */
1751 return this->ref;
1754 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
1755 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1757 if (!--(this->ref)) {
1758 HeapFree(GetProcessHeap(),0,this);
1759 return 0;
1761 /* FIXME: destroy window ... */
1762 return this->ref;
1765 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
1766 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
1768 char xrefiid[50];
1770 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1771 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1772 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1773 *obj = this;
1774 this->lpvtbl->fnAddRef(this);
1775 return 0;
1777 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1778 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
1779 this->lpvtbl->fnAddRef(this);
1780 *obj = this;
1781 return 0;
1783 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1784 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
1785 this->lpvtbl->fnAddRef(this);
1786 *obj = this;
1787 return 0;
1789 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1790 LPDIRECT3D d3d;
1792 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1793 d3d->ref = 1;
1794 d3d->ddraw = (LPDIRECTDRAW)this;
1795 this->lpvtbl->fnAddRef(this);
1796 d3d->lpvtbl = &d3dvt;
1797 *obj = d3d;
1798 return 0;
1800 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1801 LPDIRECT3D2 d3d;
1803 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1804 d3d->ref = 1;
1805 d3d->ddraw = (LPDIRECTDRAW)this;
1806 this->lpvtbl->fnAddRef(this);
1807 d3d->lpvtbl = &d3d2vt;
1808 *obj = d3d;
1809 return 0;
1811 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
1812 return OLE_E_ENUM_NOMORE;
1815 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
1816 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
1818 char xrefiid[50];
1820 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1821 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1822 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1823 *obj = this;
1824 this->lpvtbl->fnAddRef(this);
1825 return 0;
1827 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1828 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
1829 this->lpvtbl->fnAddRef(this);
1830 *obj = this;
1831 return 0;
1833 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1834 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
1835 this->lpvtbl->fnAddRef(this);
1836 *obj = this;
1837 return 0;
1839 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1840 LPDIRECT3D d3d;
1842 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1843 d3d->ref = 1;
1844 d3d->ddraw = (LPDIRECTDRAW)this;
1845 this->lpvtbl->fnAddRef(this);
1846 d3d->lpvtbl = &d3dvt;
1847 *obj = d3d;
1848 return 0;
1850 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1851 LPDIRECT3D2 d3d;
1853 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1854 d3d->ref = 1;
1855 d3d->ddraw = (LPDIRECTDRAW)this;
1856 this->lpvtbl->fnAddRef(this);
1857 d3d->lpvtbl = &d3d2vt;
1858 *obj = d3d;
1859 return 0;
1861 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
1862 return OLE_E_ENUM_NOMORE;
1865 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
1866 LPDIRECTDRAW2 this,BOOL32 *status
1868 TRACE(ddraw,"(%p)->(%p)\n",this,status);
1869 *status = TRUE;
1870 return 0;
1873 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
1874 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
1876 DDSURFACEDESC ddsfd;
1878 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
1880 _getpixelformat(this,&(ddsfd.ddpfPixelFormat));
1881 ddsfd.dwSize = sizeof(ddsfd);
1882 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1883 if (dwFlags & DDEDM_REFRESHRATES) {
1884 ddsfd.dwFlags |= DDSD_REFRESHRATE;
1885 ddsfd.x.dwRefreshRate = 60;
1888 ddsfd.dwWidth = 640;
1889 ddsfd.dwHeight = 480;
1890 ddsfd.dwBackBufferCount = 1;
1891 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
1893 if (!modescb(&ddsfd,context)) return 0;
1895 ddsfd.dwWidth = 800;
1896 ddsfd.dwHeight = 600;
1897 if (!modescb(&ddsfd,context)) return 0;
1899 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
1900 /* modeX is not standard VGA */
1902 ddsfd.dwHeight = 200;
1903 ddsfd.dwWidth = 320;
1904 if (!modescb(&ddsfd,context)) return 0;
1906 return DD_OK;
1909 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
1910 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
1912 #ifdef HAVE_LIBXXF86DGA
1913 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
1914 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1915 lpddsfd->dwHeight = screenHeight;
1916 lpddsfd->dwWidth = screenWidth;
1917 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
1918 lpddsfd->dwBackBufferCount = 1;
1919 lpddsfd->x.dwRefreshRate = 60;
1920 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
1921 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
1922 return DD_OK;
1923 #else /* defined(HAVE_LIBXXF86DGA) */
1924 return E_UNEXPECTED;
1925 #endif /* defined(HAVE_LIBXXF86DGA) */
1928 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
1929 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
1931 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
1932 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1933 lpddsfd->dwHeight = screenHeight;
1934 lpddsfd->dwWidth = screenWidth;
1935 /* POOLE FIXME: Xlib */
1936 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
1937 /* END FIXME: Xlib */
1938 lpddsfd->dwBackBufferCount = 1;
1939 lpddsfd->x.dwRefreshRate = 60;
1940 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
1941 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
1942 return DD_OK;
1945 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
1946 TRACE(ddraw,"(%p)->()\n",this);
1947 return DD_OK;
1950 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
1951 LPDIRECTDRAW2 this,LPDWORD freq
1953 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
1954 *freq = 60*100; /* 60 Hz */
1955 return 0;
1958 /* what can we directly decompress? */
1959 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
1960 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
1962 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
1963 return 0;
1966 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
1967 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
1969 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
1970 return 0;
1973 static HRESULT WINAPI IDirectDraw2_Compact(
1974 LPDIRECTDRAW2 this )
1976 FIXME(ddraw,"(%p)->()\n", this );
1978 return DD_OK;
1982 /* Note: Hack so we can reuse the old functions without compiler warnings */
1983 #ifdef __GNUC__
1984 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
1985 #else
1986 # define XCAST(fun) (void*)
1987 #endif
1989 static struct IDirectDraw_VTable dga_ddvt = {
1990 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
1991 XCAST(AddRef)IDirectDraw2_AddRef,
1992 XCAST(Release)DGA_IDirectDraw2_Release,
1993 XCAST(Compact)IDirectDraw2_Compact,
1994 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
1995 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
1996 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
1997 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
1998 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
1999 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2000 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2001 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2002 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2003 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2004 XCAST(GetGDISurface)15,
2005 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2006 XCAST(GetScanLine)17,
2007 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2008 XCAST(Initialize)19,
2009 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2010 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2011 DGA_IDirectDraw_SetDisplayMode,
2012 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2015 static struct IDirectDraw_VTable xlib_ddvt = {
2016 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2017 XCAST(AddRef)IDirectDraw2_AddRef,
2018 XCAST(Release)Xlib_IDirectDraw2_Release,
2019 XCAST(Compact)IDirectDraw2_Compact,
2020 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2021 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2022 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2023 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2024 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2025 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2026 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2027 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2028 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2029 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2030 XCAST(GetGDISurface)15,
2031 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2032 XCAST(GetScanLine)17,
2033 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2034 XCAST(Initialize)19,
2035 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2036 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2037 Xlib_IDirectDraw_SetDisplayMode,
2038 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2041 /*****************************************************************************
2042 * IDirectDraw2
2047 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2048 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2050 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2053 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2054 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2056 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2059 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2060 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2062 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2063 this,ddscaps,total,free
2065 if (total) *total = this->e.dga.fb_memsize * 1024;
2066 if (free) *free = this->e.dga.fb_memsize * 1024;
2067 return 0;
2070 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2071 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2073 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2074 this,ddscaps,total,free
2076 if (total) *total = 2048 * 1024;
2077 if (free) *free = 2048 * 1024;
2078 return 0;
2081 static IDirectDraw2_VTable dga_dd2vt = {
2082 DGA_IDirectDraw2_QueryInterface,
2083 IDirectDraw2_AddRef,
2084 DGA_IDirectDraw2_Release,
2085 IDirectDraw2_Compact,
2086 IDirectDraw2_CreateClipper,
2087 DGA_IDirectDraw2_CreatePalette,
2088 DGA_IDirectDraw2_CreateSurface,
2089 (void*)8,
2090 IDirectDraw2_EnumDisplayModes,
2091 IDirectDraw2_EnumSurfaces,
2092 IDirectDraw2_FlipToGDISurface,
2093 DGA_IDirectDraw2_GetCaps,
2094 DGA_IDirectDraw2_GetDisplayMode,
2095 IDirectDraw2_GetFourCCCodes,
2096 (void*)15,
2097 IDirectDraw2_GetMonitorFrequency,
2098 (void*)17,
2099 IDirectDraw2_GetVerticalBlankStatus,
2100 (void*)19,
2101 DGA_IDirectDraw2_RestoreDisplayMode,
2102 IDirectDraw2_SetCooperativeLevel,
2103 DGA_IDirectDraw2_SetDisplayMode,
2104 IDirectDraw2_WaitForVerticalBlank,
2105 DGA_IDirectDraw2_GetAvailableVidMem
2108 static struct IDirectDraw2_VTable xlib_dd2vt = {
2109 Xlib_IDirectDraw2_QueryInterface,
2110 IDirectDraw2_AddRef,
2111 Xlib_IDirectDraw2_Release,
2112 IDirectDraw2_Compact,
2113 IDirectDraw2_CreateClipper,
2114 Xlib_IDirectDraw2_CreatePalette,
2115 Xlib_IDirectDraw2_CreateSurface,
2116 (void*)8,
2117 IDirectDraw2_EnumDisplayModes,
2118 IDirectDraw2_EnumSurfaces,
2119 IDirectDraw2_FlipToGDISurface,
2120 Xlib_IDirectDraw2_GetCaps,
2121 Xlib_IDirectDraw2_GetDisplayMode,
2122 IDirectDraw2_GetFourCCCodes,
2123 (void*)15,
2124 IDirectDraw2_GetMonitorFrequency,
2125 (void*)17,
2126 IDirectDraw2_GetVerticalBlankStatus,
2127 (void*)19,
2128 Xlib_IDirectDraw2_RestoreDisplayMode,
2129 IDirectDraw2_SetCooperativeLevel,
2130 Xlib_IDirectDraw2_SetDisplayMode,
2131 IDirectDraw2_WaitForVerticalBlank,
2132 Xlib_IDirectDraw2_GetAvailableVidMem
2135 /******************************************************************************
2136 * DirectDrawCreate
2139 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2140 #ifdef HAVE_LIBXXF86DGA
2141 int memsize,banksize,width,major,minor,flags,height;
2142 char *addr;
2144 if (getuid() != 0) {
2145 MSG("Must be root to use XF86DGA!\n");
2146 MessageBox32A(0,"Using the XF86DGA extension requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2147 return E_UNEXPECTED;
2149 if (!DDRAW_DGA_Available()) {
2150 TRACE(ddraw,"No XF86DGA detected.\n");
2151 return DDERR_GENERIC;
2153 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2154 (*lplpDD)->lpvtbl = &dga_ddvt;
2155 (*lplpDD)->ref = 1;
2156 TSXF86DGAQueryVersion(display,&major,&minor);
2157 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2158 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2159 if (!(flags & XF86DGADirectPresent))
2160 MSG("direct video is NOT PRESENT.\n");
2161 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2162 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2163 addr,width,banksize,memsize
2165 (*lplpDD)->e.dga.fb_width = width;
2166 (*lplpDD)->d.width = width;
2167 (*lplpDD)->e.dga.fb_addr = addr;
2168 (*lplpDD)->e.dga.fb_memsize = memsize;
2169 (*lplpDD)->e.dga.fb_banksize = banksize;
2171 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2172 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2173 (*lplpDD)->e.dga.fb_height = screenHeight;
2174 #ifdef DIABLO_HACK
2175 (*lplpDD)->e.dga.vpmask = 1;
2176 #else
2177 (*lplpDD)->e.dga.vpmask = 0;
2178 #endif
2180 /* just assume the default depth is the DGA depth too */
2181 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2182 #ifdef RESTORE_SIGNALS
2183 SIGNAL_InitEmulator();
2184 #endif
2185 return 0;
2186 #else /* defined(HAVE_LIBXXF86DGA) */
2187 return DDERR_INVALIDDIRECTDRAWGUID;
2188 #endif /* defined(HAVE_LIBXXF86DGA) */
2191 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2193 LRESULT ret;
2194 LPDIRECTDRAW ddraw = NULL;
2195 DWORD lastError;
2197 /*FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2199 SetLastError( ERROR_SUCCESS );
2200 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2201 if( (!ddraw) &&
2202 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2205 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2208 if( ddraw )
2210 /* Perform any special direct draw functions */
2211 if (msg==WM_PAINT)
2213 ddraw->e.xlib.paintable = 1;
2216 /* Now let the application deal with the rest of this */
2217 if( ddraw->d.mainWindow )
2220 /* Don't think that we actually need to call this but...
2221 might as well be on the safe side of things... */
2222 ret = DefWindowProc32A( hwnd, msg, wParam, lParam );
2224 if( !ret )
2226 /* We didn't handle the message - give it to the application */
2227 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow))
2228 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2229 ddraw->d.mainWindow, msg, wParam, lParam );
2233 else
2235 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2239 else
2241 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2244 return ret;
2247 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2248 WNDCLASS32A wc;
2249 int have_xshm = 0;
2250 WND* pParentWindow;
2252 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2253 (*lplpDD)->lpvtbl = &xlib_ddvt;
2254 (*lplpDD)->ref = 1;
2255 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
2256 (*lplpDD)->e.xlib.use_xshm = have_xshm;
2257 wc.style = CS_GLOBALCLASS;
2258 wc.lpfnWndProc = Xlib_DDWndProc;
2259 wc.cbClsExtra = 0;
2260 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
2261 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
2263 /* We can be a child of the desktop since we're really important */
2264 pParentWindow = WIN_GetDesktop();
2265 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
2266 wc.hInstance = 0;
2268 wc.hIcon = 0;
2269 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
2270 wc.hbrBackground= NULL_BRUSH;
2271 wc.lpszMenuName = 0;
2272 wc.lpszClassName= "WINE_DirectDraw";
2274 (*lplpDD)->e.xlib.winclass = RegisterClass32A(&wc);
2276 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2277 (*lplpDD)->d.height = screenHeight;
2278 (*lplpDD)->d.width = screenWidth;
2279 return 0;
2282 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
2283 char xclsid[50];
2285 if (HIWORD(lpGUID))
2286 WINE_StringFromCLSID(lpGUID,xclsid);
2287 else {
2288 sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID);
2289 lpGUID = NULL;
2292 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
2294 if (!lpGUID) {
2295 /* if they didn't request a particular interface, use the best
2296 * supported one */
2297 if (DDRAW_DGA_Available())
2298 lpGUID = &DGA_DirectDraw_GUID;
2299 else
2300 lpGUID = &XLIB_DirectDraw_GUID;
2303 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
2304 return DGA_DirectDrawCreate(lplpDD, pUnkOuter);
2305 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
2306 return Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
2308 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
2309 return DDERR_INVALIDDIRECTDRAWGUID;