Stubs for EnumServiceStatus32, small changes.
[wine/multimedia.git] / graphics / ddraw.c
blob3a9d787184f50413ff340f4211de8a6f5ccaf8dc
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 */
5 /* XF86DGA:
6 * When DirectVideo mode is enabled you can no longer use 'normal' X
7 * applications nor can you switch to a virtual console. Also, enabling
8 * only works, if you have switched to the screen where the application
9 * is running.
10 * Some ways to debug this stuff are:
11 * - A terminal connected to the serial port. Can be bought used for cheap.
12 * (This is the method I am using.)
13 * - Another machine connected over some kind of network.
16 #include "config.h"
17 #include <unistd.h>
18 #include <assert.h>
19 #include "ts_xlib.h"
20 #include <sys/signal.h>
21 #include <fcntl.h>
22 #include <string.h>
24 #include "windows.h"
25 #include "winerror.h"
26 #include "interfaces.h"
27 #include "gdi.h"
28 #include "heap.h"
29 #include "ldt.h"
30 #include "dc.h"
31 #include "win.h"
32 #include "miscemu.h"
33 #include "ddraw.h"
34 #include "d3d.h"
35 #include "debug.h"
36 #include "compobj.h"
37 #include "spy.h"
38 #include "message.h"
39 #include "x11drv.h"
40 #include "options.h"
42 #ifdef HAVE_LIBXXF86DGA
43 #include "ts_xf86dga.h"
44 #endif
46 #ifdef HAVE_LIBXXSHM
47 #include <sys/types.h>
48 #include <sys/ipc.h>
49 #include <sys/shm.h>
50 #include "ts_xshm.h"
51 #endif
53 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
54 #undef DIABLO_HACK
56 /* Restore signal handlers overwritten by XF86DGA
57 * this is a define, for it will only work in emulator mode
59 #undef RESTORE_SIGNALS
61 /* Where do these GUIDs come from? mkuuid.
62 * They exist solely to distinguish between the targets Wine support,
63 * and should be different than any other GUIDs in existence.
65 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
66 0xe2dcb020,
67 0xdc60,
68 0x11d1,
69 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
72 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
73 0x1574a740,
74 0xdc61,
75 0x11d1,
76 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
79 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
80 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
81 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
82 static struct IDirectDrawClipper_VTable ddclipvt;
83 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
84 static struct IDirect3D_VTable d3dvt;
85 static struct IDirect3D2_VTable d3d2vt;
87 BOOL32
88 DDRAW_DGA_Available()
90 #ifdef HAVE_LIBXXF86DGA
91 int evbase, evret, fd;
93 if (Options.noDGA)
94 return 0;
96 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
97 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
98 /* others. --stephenc */
99 if ((fd = open("/dev/mem", O_RDWR)) != -1)
100 close(fd);
102 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
103 #else /* defined(HAVE_LIBXXF86DGA) */
104 return 0;
105 #endif /* defined(HAVE_LIBXXF86DGA) */
108 HRESULT WINAPI
109 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
110 if (DDRAW_DGA_Available()) {
111 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
113 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
114 ddenumproc(NULL,"WINE","display",data);
115 return 0;
118 /* What is this doing here? */
119 HRESULT WINAPI
120 DSoundHelp(DWORD x,DWORD y,DWORD z) {
121 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
122 return 0;
126 /******************************************************************************
127 * internal helper functions
129 static void _dump_DDBLTFX(DWORD flagmask) {
130 int i;
131 const struct {
132 DWORD mask;
133 char *name;
134 } flags[] = {
135 #define FE(x) { x, #x},
136 FE(DDBLTFX_ARITHSTRETCHY)
137 FE(DDBLTFX_MIRRORLEFTRIGHT)
138 FE(DDBLTFX_MIRRORUPDOWN)
139 FE(DDBLTFX_NOTEARING)
140 FE(DDBLTFX_ROTATE180)
141 FE(DDBLTFX_ROTATE270)
142 FE(DDBLTFX_ROTATE90)
143 FE(DDBLTFX_ZBUFFERRANGE)
144 FE(DDBLTFX_ZBUFFERBASEDEST)
146 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
147 if (flags[i].mask & flagmask) {
148 DUMP("%s ",flags[i].name);
151 DUMP("\n");
155 static void _dump_DDBLTFAST(DWORD flagmask) {
156 int i;
157 const struct {
158 DWORD mask;
159 char *name;
160 } flags[] = {
161 #define FE(x) { x, #x},
162 FE(DDBLTFAST_NOCOLORKEY)
163 FE(DDBLTFAST_SRCCOLORKEY)
164 FE(DDBLTFAST_DESTCOLORKEY)
165 FE(DDBLTFAST_WAIT)
167 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
168 if (flags[i].mask & flagmask)
169 DUMP("%s ",flags[i].name);
170 DUMP("\n");
173 static void _dump_DDBLT(DWORD flagmask) {
174 int i;
175 const struct {
176 DWORD mask;
177 char *name;
178 } flags[] = {
179 #define FE(x) { x, #x},
180 FE(DDBLT_ALPHADEST)
181 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
182 FE(DDBLT_ALPHADESTNEG)
183 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
184 FE(DDBLT_ALPHAEDGEBLEND)
185 FE(DDBLT_ALPHASRC)
186 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
187 FE(DDBLT_ALPHASRCNEG)
188 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
189 FE(DDBLT_ASYNC)
190 FE(DDBLT_COLORFILL)
191 FE(DDBLT_DDFX)
192 FE(DDBLT_DDROPS)
193 FE(DDBLT_KEYDEST)
194 FE(DDBLT_KEYDESTOVERRIDE)
195 FE(DDBLT_KEYSRC)
196 FE(DDBLT_KEYSRCOVERRIDE)
197 FE(DDBLT_ROP)
198 FE(DDBLT_ROTATIONANGLE)
199 FE(DDBLT_ZBUFFER)
200 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
201 FE(DDBLT_ZBUFFERDESTOVERRIDE)
202 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
203 FE(DDBLT_ZBUFFERSRCOVERRIDE)
204 FE(DDBLT_WAIT)
205 FE(DDBLT_DEPTHFILL)
207 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
208 if (flags[i].mask & flagmask)
209 DUMP("%s ",flags[i].name);
212 static void _dump_DDSCAPS(DWORD flagmask) {
213 int i;
214 const struct {
215 DWORD mask;
216 char *name;
217 } flags[] = {
218 #define FE(x) { x, #x},
219 FE(DDSCAPS_RESERVED1)
220 FE(DDSCAPS_ALPHA)
221 FE(DDSCAPS_BACKBUFFER)
222 FE(DDSCAPS_COMPLEX)
223 FE(DDSCAPS_FLIP)
224 FE(DDSCAPS_FRONTBUFFER)
225 FE(DDSCAPS_OFFSCREENPLAIN)
226 FE(DDSCAPS_OVERLAY)
227 FE(DDSCAPS_PALETTE)
228 FE(DDSCAPS_PRIMARYSURFACE)
229 FE(DDSCAPS_PRIMARYSURFACELEFT)
230 FE(DDSCAPS_SYSTEMMEMORY)
231 FE(DDSCAPS_TEXTURE)
232 FE(DDSCAPS_3DDEVICE)
233 FE(DDSCAPS_VIDEOMEMORY)
234 FE(DDSCAPS_VISIBLE)
235 FE(DDSCAPS_WRITEONLY)
236 FE(DDSCAPS_ZBUFFER)
237 FE(DDSCAPS_OWNDC)
238 FE(DDSCAPS_LIVEVIDEO)
239 FE(DDSCAPS_HWCODEC)
240 FE(DDSCAPS_MODEX)
241 FE(DDSCAPS_MIPMAP)
242 FE(DDSCAPS_RESERVED2)
243 FE(DDSCAPS_ALLOCONLOAD)
244 FE(DDSCAPS_VIDEOPORT)
245 FE(DDSCAPS_LOCALVIDMEM)
246 FE(DDSCAPS_NONLOCALVIDMEM)
247 FE(DDSCAPS_STANDARDVGAMODE)
248 FE(DDSCAPS_OPTIMIZED)
250 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
251 if (flags[i].mask & flagmask)
252 DUMP("%s ",flags[i].name);
253 DUMP("\n");
256 static void _dump_DDSD(DWORD flagmask) {
257 int i;
258 const struct {
259 DWORD mask;
260 char *name;
261 } flags[] = {
262 FE(DDSD_CAPS)
263 FE(DDSD_HEIGHT)
264 FE(DDSD_WIDTH)
265 FE(DDSD_PITCH)
266 FE(DDSD_BACKBUFFERCOUNT)
267 FE(DDSD_ZBUFFERBITDEPTH)
268 FE(DDSD_ALPHABITDEPTH)
269 FE(DDSD_PIXELFORMAT)
270 FE(DDSD_CKDESTOVERLAY)
271 FE(DDSD_CKDESTBLT)
272 FE(DDSD_CKSRCOVERLAY)
273 FE(DDSD_CKSRCBLT)
274 FE(DDSD_MIPMAPCOUNT)
275 FE(DDSD_REFRESHRATE)
276 FE(DDSD_LINEARSIZE)
277 FE(DDSD_LPSURFACE)
279 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
280 if (flags[i].mask & flagmask)
281 DUMP("%s ",flags[i].name);
282 DUMP("\n");
285 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
286 static XVisualInfo *vi;
287 XVisualInfo vt;
288 int nitems;
290 if (!vi)
291 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
293 pf->dwFourCC = 0;
294 if (ddraw->d.depth==8) {
295 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
296 pf->x.dwRGBBitCount = 8;
297 pf->y.dwRBitMask = 0;
298 pf->z.dwGBitMask = 0;
299 pf->xx.dwBBitMask = 0;
300 pf->xy.dwRGBAlphaBitMask= 0;
301 return 0;
303 if (ddraw->d.depth==16) {
304 pf->dwFlags = DDPF_RGB;
305 pf->x.dwRGBBitCount = 16;
306 pf->y.dwRBitMask = vi[0].red_mask;
307 pf->z.dwGBitMask = vi[0].green_mask;
308 pf->xx.dwBBitMask = vi[0].blue_mask;
309 pf->xy.dwRGBAlphaBitMask= 0;
310 return 0;
312 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
313 return DDERR_GENERIC;
316 /******************************************************************************
317 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
319 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
320 * DDS and DDS2 use those functions. (Function calls did not change (except
321 * using different DirectDrawSurfaceX version), just added flags and functions)
323 static HRESULT WINAPI IDirectDrawSurface3_Lock(
324 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
326 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
327 this,lprect,lpddsd,flags,(DWORD)hnd);
328 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
329 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
330 this,lprect,lpddsd,flags,(DWORD)hnd);
332 if (lprect) {
333 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
334 lprect->top,lprect->left,lprect->bottom,lprect->right
336 lpddsd->y.lpSurface = this->s.surface +
337 (lprect->top*this->s.lpitch) +
338 (lprect->left*(this->s.ddraw->d.depth/8));
339 } else {
340 assert(this->s.surface);
341 lpddsd->y.lpSurface = this->s.surface;
343 lpddsd->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_LPSURFACE;
344 lpddsd->dwWidth = this->s.width;
345 lpddsd->dwHeight = this->s.height;
346 lpddsd->lPitch = this->s.lpitch;
347 _getpixelformat(this->s.ddraw,&(lpddsd->ddpfPixelFormat));
348 return 0;
351 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
352 LPDIRECTDRAWSURFACE3 this,LPVOID surface
354 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
355 return 0;
358 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
359 LPDIRECTDRAWSURFACE3 this,LPVOID surface)
361 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
363 if (!this->s.ddraw->e.xlib.paintable)
364 return DD_OK;
366 /* Only redraw the screen when unlocking the buffer that is on screen */
367 if ((this->t.xlib.image != NULL) && (this->t.xlib.on_screen)) {
368 #ifdef HAVE_LIBXXSHM
369 if (this->s.ddraw->e.xlib.xshm_active)
370 TSXShmPutImage(display,
371 this->s.ddraw->e.xlib.drawable,
372 DefaultGCOfScreen(screen),
373 this->t.xlib.image,
374 0, 0, 0, 0,
375 this->t.xlib.image->width,
376 this->t.xlib.image->height,
377 False);
378 else
379 #endif
380 TSXPutImage( display,
381 this->s.ddraw->e.xlib.drawable,
382 DefaultGCOfScreen(screen),
383 this->t.xlib.image,
384 0, 0, 0, 0,
385 this->t.xlib.image->width,
386 this->t.xlib.image->height);
389 if (this->s.palette && this->s.palette->cm)
390 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
392 return DD_OK;
395 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
396 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
398 #ifdef HAVE_LIBXXF86DGA
399 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
400 if (!flipto) {
401 if (this->s.backbuffer)
402 flipto = this->s.backbuffer;
403 else
404 flipto = this;
406 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
408 if (flipto->s.palette && flipto->s.palette->cm) {
409 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
411 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
413 if (flipto!=this) {
414 int tmp;
415 LPVOID ptmp;
417 tmp = this->t.dga.fb_height;
418 this->t.dga.fb_height = flipto->t.dga.fb_height;
419 flipto->t.dga.fb_height = tmp;
421 ptmp = this->s.surface;
422 this->s.surface = flipto->s.surface;
423 flipto->s.surface = ptmp;
425 return 0;
426 #else /* defined(HAVE_LIBXXF86DGA) */
427 return E_UNEXPECTED;
428 #endif /* defined(HAVE_LIBXXF86DGA) */
431 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
432 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
434 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
435 if (!this->s.ddraw->e.xlib.paintable)
436 return 0;
438 if (!flipto) {
439 if (this->s.backbuffer)
440 flipto = this->s.backbuffer;
441 else
442 flipto = this;
445 #ifdef HAVE_LIBXXSHM
446 if (this->s.ddraw->e.xlib.xshm_active) {
447 TSXShmPutImage(display,
448 this->s.ddraw->e.xlib.drawable,
449 DefaultGCOfScreen(screen),
450 flipto->t.xlib.image,
451 0, 0, 0, 0,
452 flipto->t.xlib.image->width,
453 flipto->t.xlib.image->height,
454 False);
455 } else
456 #endif
457 TSXPutImage(display,
458 this->s.ddraw->e.xlib.drawable,
459 DefaultGCOfScreen(screen),
460 flipto->t.xlib.image,
461 0, 0, 0, 0,
462 flipto->t.xlib.image->width,
463 flipto->t.xlib.image->height);
465 if (flipto->s.palette && flipto->s.palette->cm) {
466 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,flipto->s.palette->cm);
468 if (flipto!=this) {
469 XImage *tmp;
470 LPVOID *surf;
471 tmp = this->t.xlib.image;
472 this->t.xlib.image = flipto->t.xlib.image;
473 flipto->t.xlib.image = tmp;
474 surf = this->s.surface;
475 this->s.surface = flipto->s.surface;
476 flipto->s.surface = surf;
478 return 0;
482 /* The IDirectDrawSurface3::SetPalette method attaches the specified
483 * DirectDrawPalette object to a surface. The surface uses this palette for all
484 * subsequent operations. The palette change takes place immediately.
486 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
487 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
489 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
490 /* According to spec, we are only supposed to
491 * AddRef if this is not the same palette.
493 if( this->s.palette != pal )
495 if( pal != NULL )
496 pal->lpvtbl->fnAddRef( pal );
497 if( this->s.palette != NULL )
498 this->s.palette->lpvtbl->fnRelease( this->s.palette );
499 this->s.palette = pal;
501 /* I think that we need to attach it to all backbuffers...*/
502 if( this->s.backbuffer ) {
503 if( this->s.backbuffer->s.palette )
504 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
505 this->s.backbuffer->s.palette );
506 this->s.backbuffer->s.palette = pal;
507 if( pal )
508 pal->lpvtbl->fnAddRef( pal );
511 /* Perform the refresh */
512 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
515 return 0;
518 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
519 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
521 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
522 #ifdef HAVE_LIBXXF86DGA
523 /* According to spec, we are only supposed to
524 * AddRef if this is not the same palette.
526 if( this->s.palette != pal )
528 if( pal != NULL )
529 pal->lpvtbl->fnAddRef( pal );
530 if( this->s.palette != NULL )
531 this->s.palette->lpvtbl->fnRelease( this->s.palette );
532 this->s.palette = pal;
534 /* I think that we need to attach it to all backbuffers...*/
535 if( this->s.backbuffer ) {
536 if( this->s.backbuffer->s.palette )
537 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
538 this->s.backbuffer->s.palette = pal;
539 if( pal ) pal->lpvtbl->fnAddRef( pal );
541 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
543 return 0;
544 #else /* defined(HAVE_LIBXXF86DGA) */
545 return E_UNEXPECTED;
546 #endif /* defined(HAVE_LIBXXF86DGA) */
551 static HRESULT WINAPI IDirectDrawSurface3_Blt(
552 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
554 RECT32 xdst,xsrc;
555 int i,j;
557 if (TRACE_ON(ddraw)) {
558 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
559 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");
563 if (dwFlags & DDBLT_DDFX) {
564 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
568 if (rdst) {
569 memcpy(&xdst,rdst,sizeof(xdst));
570 } else {
571 xdst.top = 0;
572 xdst.bottom = this->s.height;
573 xdst.left = 0;
574 xdst.right = this->s.width;
577 if (rsrc) {
578 memcpy(&xsrc,rsrc,sizeof(xsrc));
579 } else {
580 if (src) {
581 xsrc.top = 0;
582 xsrc.bottom = src->s.height;
583 xsrc.left = 0;
584 xsrc.right = src->s.width;
585 } else {
586 memset(&xsrc,0,sizeof(xsrc));
590 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
592 if (dwFlags & DDBLT_COLORFILL) {
593 int bpp = this->s.ddraw->d.depth/8;
594 LPBYTE xline,xpixel;
596 xline = (LPBYTE)this->s.surface+xdst.top*this->s.lpitch;
597 for (i=xdst.top;i<xdst.bottom;i++) {
598 xpixel = xline+bpp*xdst.left;
600 for (j=xdst.left;j<xdst.right;j++) {
601 /* FIXME: this only works on little endian
602 * architectures, where DWORD starts with low
603 * byte first!
605 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
606 xpixel += bpp;
608 xline += this->s.lpitch;
610 dwFlags &= ~(DDBLT_COLORFILL);
613 if (!src) {
614 if (dwFlags) {
615 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
617 return 0;
620 if ( (xsrc.top ==0) && (xsrc.bottom ==this->s.height) &&
621 (xsrc.left==0) && (xsrc.right ==this->s.width) &&
622 (xdst.top ==0) && (xdst.bottom ==this->s.height) &&
623 (xdst.left==0) && (xdst.right ==this->s.width) &&
624 !dwFlags
626 memcpy(this->s.surface,src->s.surface,this->s.height*this->s.lpitch);
627 } else {
628 int bpp = this->s.ddraw->d.depth / 8;
629 int height = xsrc.bottom - xsrc.top;
630 int width = (xsrc.right - xsrc.left) * bpp;
631 int h;
633 for (h = 0; h < height; h++) {
634 memcpy(this->s.surface + ((h + xdst.top) * this->s.lpitch) + xdst.left * bpp,
635 src->s.surface + ((h + xsrc.top) * src->s.lpitch) + xsrc.left * bpp,
636 width);
640 if (dwFlags && FIXME_ON(ddraw)) {
641 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
643 return 0;
646 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Blt(
647 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
649 HRESULT ret;
651 /* First, call the "common" blit function */
652 ret = IDirectDrawSurface3_Blt(this, rdst, src, rsrc, dwFlags, lpbltfx);
654 /* Then put the result on screen if blited on main screen buffer */
655 if (!this->s.ddraw->e.xlib.paintable)
656 return ret;
658 if ((this->t.xlib.image != NULL) && (this->t.xlib.on_screen)) {
659 #ifdef HAVE_LIBXXSHM
660 if (this->s.ddraw->e.xlib.xshm_active)
661 TSXShmPutImage(display,
662 this->s.ddraw->e.xlib.drawable,
663 DefaultGCOfScreen(screen),
664 this->t.xlib.image,
665 0, 0, 0, 0,
666 this->t.xlib.image->width,
667 this->t.xlib.image->height,
668 False);
669 else
670 #endif
671 TSXPutImage(display,
672 this->s.ddraw->e.xlib.drawable,
673 DefaultGCOfScreen(screen),
674 this->t.xlib.image,
675 0, 0, 0, 0,
676 this->t.xlib.image->width,
677 this->t.xlib.image->height);
679 if (this->s.palette && this->s.palette->cm)
680 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
682 return ret;
685 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
686 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
688 int i,bpp;
689 DDSURFACEDESC ddesc,sdesc;
691 if (TRACE_ON(ddraw)) {
692 TRACE(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
693 this,dstx,dsty,src,rsrc,trans
695 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
696 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
698 /* We need to lock the surfaces, or we won't get refreshes when done */
699 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
700 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
701 bpp = this->s.ddraw->d.depth/8;
702 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
703 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
704 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
705 (rsrc->right-rsrc->left)*bpp
708 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
709 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
710 return 0;
713 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
714 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
716 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
717 this,ddbltbatch,x,y
719 return 0;
722 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
723 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
725 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
726 caps->dwCaps = DDCAPS_PALETTE; /* probably more */
727 return 0;
730 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
731 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
732 ) {
733 if (TRACE_ON(ddraw)) {
734 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
735 this,ddsd);
736 fprintf(stderr," flags: ");
737 _dump_DDSD(ddsd->dwFlags);
738 fprintf(stderr,"\n");
741 ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
742 ddsd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
743 ddsd->dwBackBufferCount = 1;
744 ddsd->dwHeight = this->s.height;
745 ddsd->dwWidth = this->s.width;
746 ddsd->lPitch = this->s.lpitch;
747 if (this->s.backbuffer)
748 ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
749 _getpixelformat(this->s.ddraw,&(ddsd->ddpfPixelFormat));
751 return 0;
754 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
755 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
757 return ++(this->ref);
760 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
761 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
763 #ifdef HAVE_LIBXXF86DGA
764 if (!--(this->ref)) {
765 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
766 /* clear out of surface list */
767 if (this->t.dga.fb_height == -1) {
768 HeapFree(GetProcessHeap(),0,this->s.surface);
769 } else {
770 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
772 HeapFree(GetProcessHeap(),0,this);
773 return 0;
775 #endif /* defined(HAVE_LIBXXF86DGA) */
776 return this->ref;
779 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
780 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
782 if (!--(this->ref)) {
783 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
785 if( this->s.backbuffer )
786 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
788 if (this->t.xlib.image != NULL) {
789 this->t.xlib.image->data = NULL;
791 #ifdef HAVE_LIBXXSHM
792 if (this->s.ddraw->e.xlib.xshm_active) {
793 TSXShmDetach(display, &(this->t.xlib.shminfo));
794 TSXDestroyImage(this->t.xlib.image);
795 shmdt(this->t.xlib.shminfo.shmaddr);
796 } else {
797 #endif
798 HeapFree(GetProcessHeap(),0,this->s.surface);
799 TSXDestroyImage(this->t.xlib.image);
800 #ifdef HAVE_LIBXXSHM
802 #endif
804 this->t.xlib.image = 0;
805 } else {
806 HeapFree(GetProcessHeap(),0,this->s.surface);
809 if (this->s.palette)
810 this->s.palette->lpvtbl->fnRelease(this->s.palette);
812 HeapFree(GetProcessHeap(),0,this);
813 return 0;
816 return this->ref;
819 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
820 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
822 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
823 this, lpddsd, lpdsf);
825 if (TRACE_ON(ddraw)) {
826 TRACE(ddraw," caps ");
827 _dump_DDSCAPS(lpddsd->dwCaps);
830 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
831 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
832 return E_FAIL;
835 /* FIXME: should handle more than one backbuffer */
836 *lpdsf = this->s.backbuffer;
838 if( this->s.backbuffer )
839 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
841 return 0;
844 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
845 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
847 return DDERR_ALREADYINITIALIZED;
850 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
851 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
853 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
854 return _getpixelformat(this->s.ddraw,pf);
857 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
858 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
859 return 0;
862 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
863 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
865 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
866 return 0;
869 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
870 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
872 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
873 return 0;
876 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
877 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
879 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
880 this->s.backbuffer = surf;
881 return 0;
884 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
885 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
886 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
887 return 0;
890 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
891 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
892 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
893 return 0;
897 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
898 char xrefiid[50];
900 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
901 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
903 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
904 * the same interface. And IUnknown does that too of course.
906 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
907 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
908 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
909 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
911 *obj = this;
912 this->lpvtbl->fnAddRef(this);
913 return 0;
915 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
916 return OLE_E_ENUM_NOMORE;
919 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
920 TRACE(ddraw,"(%p)->(), stub!\n",this);
921 return 0; /* hmm */
924 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
925 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
926 return 0;
929 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
930 FIXME(ddraw,"(%p)->(),stub!\n",this);
931 return 0;
934 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
935 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
937 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
939 if( dwFlags & DDCKEY_SRCBLT )
940 dwFlags &= ~DDCKEY_SRCBLT;
941 if( dwFlags )
942 TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
943 return DD_OK;
946 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
947 LPDIRECTDRAWSURFACE3 this,
948 LPRECT32 lpRect )
950 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
952 return DD_OK;
955 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
956 LPDIRECTDRAWSURFACE3 this,
957 DWORD dwFlags,
958 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
960 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
962 return DD_OK;
965 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
966 LPDIRECTDRAWSURFACE3 this,
967 DWORD dwFlags,
968 LPVOID lpContext,
969 LPDDENUMSURFACESCALLBACK lpfnCallback )
971 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
972 lpContext, lpfnCallback );
974 return DD_OK;
977 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
978 LPDIRECTDRAWSURFACE3 this,
979 LPDIRECTDRAWCLIPPER* lplpDDClipper )
981 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
983 return DD_OK;
986 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
987 LPDIRECTDRAWSURFACE3 this,
988 DWORD dwFlags,
989 LPDDCOLORKEY lpDDColorKey )
991 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDColorKey);
993 return DD_OK;
996 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
997 LPDIRECTDRAWSURFACE3 this,
998 DWORD dwFlags )
1000 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1002 return DD_OK;
1005 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
1006 LPDIRECTDRAWSURFACE3 this,
1007 LPDIRECTDRAWPALETTE* lplpDDPalette )
1009 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1011 return DD_OK;
1014 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
1015 LPDIRECTDRAWSURFACE3 this,
1016 LONG lX,
1017 LONG lY)
1019 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1021 return DD_OK;
1024 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
1025 LPDIRECTDRAWSURFACE3 this,
1026 LPRECT32 lpSrcRect,
1027 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
1028 LPRECT32 lpDestRect,
1029 DWORD dwFlags,
1030 LPDDOVERLAYFX lpDDOverlayFx )
1032 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1033 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1035 return DD_OK;
1038 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
1039 LPDIRECTDRAWSURFACE3 this,
1040 DWORD dwFlags )
1042 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1044 return DD_OK;
1047 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
1048 LPDIRECTDRAWSURFACE3 this,
1049 DWORD dwFlags,
1050 LPDIRECTDRAWSURFACE3 lpDDSReference )
1052 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1054 return DD_OK;
1057 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
1058 LPDIRECTDRAWSURFACE3 this,
1059 LPVOID* lplpDD )
1061 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1063 return DD_OK;
1066 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
1067 LPDIRECTDRAWSURFACE3 this,
1068 DWORD dwFlags )
1070 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1072 return DD_OK;
1075 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
1076 LPDIRECTDRAWSURFACE3 this,
1077 DWORD dwFlags )
1079 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1081 return DD_OK;
1084 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1085 LPDIRECTDRAWSURFACE3 this,
1086 LPDDSURFACEDESC lpDDSD,
1087 DWORD dwFlags )
1089 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1091 return DD_OK;
1094 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1095 IDirectDrawSurface3_QueryInterface,
1096 IDirectDrawSurface3_AddRef,
1097 DGA_IDirectDrawSurface3_Release,
1098 IDirectDrawSurface3_AddAttachedSurface,
1099 IDirectDrawSurface3_AddOverlayDirtyRect,
1100 IDirectDrawSurface3_Blt,
1101 IDirectDrawSurface3_BltBatch,
1102 IDirectDrawSurface3_BltFast,
1103 IDirectDrawSurface3_DeleteAttachedSurface,
1104 IDirectDrawSurface3_EnumAttachedSurfaces,
1105 IDirectDrawSurface3_EnumOverlayZOrders,
1106 DGA_IDirectDrawSurface3_Flip,
1107 IDirectDrawSurface3_GetAttachedSurface,
1108 IDirectDrawSurface3_GetBltStatus,
1109 IDirectDrawSurface3_GetCaps,
1110 IDirectDrawSurface3_GetClipper,
1111 IDirectDrawSurface3_GetColorKey,
1112 IDirectDrawSurface3_GetDC,
1113 IDirectDrawSurface3_GetFlipStatus,
1114 IDirectDrawSurface3_GetOverlayPosition,
1115 IDirectDrawSurface3_GetPalette,
1116 IDirectDrawSurface3_GetPixelFormat,
1117 IDirectDrawSurface3_GetSurfaceDesc,
1118 IDirectDrawSurface3_Initialize,
1119 IDirectDrawSurface3_IsLost,
1120 IDirectDrawSurface3_Lock,
1121 IDirectDrawSurface3_ReleaseDC,
1122 IDirectDrawSurface3_Restore,
1123 IDirectDrawSurface3_SetClipper,
1124 IDirectDrawSurface3_SetColorKey,
1125 IDirectDrawSurface3_SetOverlayPosition,
1126 DGA_IDirectDrawSurface3_SetPalette,
1127 DGA_IDirectDrawSurface3_Unlock,
1128 IDirectDrawSurface3_UpdateOverlay,
1129 IDirectDrawSurface3_UpdateOverlayDisplay,
1130 IDirectDrawSurface3_UpdateOverlayZOrder,
1131 IDirectDrawSurface3_GetDDInterface,
1132 IDirectDrawSurface3_PageLock,
1133 IDirectDrawSurface3_PageUnlock,
1134 IDirectDrawSurface3_SetSurfaceDesc,
1137 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1138 IDirectDrawSurface3_QueryInterface,
1139 IDirectDrawSurface3_AddRef,
1140 Xlib_IDirectDrawSurface3_Release,
1141 IDirectDrawSurface3_AddAttachedSurface,
1142 IDirectDrawSurface3_AddOverlayDirtyRect,
1143 Xlib_IDirectDrawSurface3_Blt,
1144 IDirectDrawSurface3_BltBatch,
1145 IDirectDrawSurface3_BltFast,
1146 IDirectDrawSurface3_DeleteAttachedSurface,
1147 IDirectDrawSurface3_EnumAttachedSurfaces,
1148 IDirectDrawSurface3_EnumOverlayZOrders,
1149 Xlib_IDirectDrawSurface3_Flip,
1150 IDirectDrawSurface3_GetAttachedSurface,
1151 IDirectDrawSurface3_GetBltStatus,
1152 IDirectDrawSurface3_GetCaps,
1153 IDirectDrawSurface3_GetClipper,
1154 IDirectDrawSurface3_GetColorKey,
1155 IDirectDrawSurface3_GetDC,
1156 IDirectDrawSurface3_GetFlipStatus,
1157 IDirectDrawSurface3_GetOverlayPosition,
1158 IDirectDrawSurface3_GetPalette,
1159 IDirectDrawSurface3_GetPixelFormat,
1160 IDirectDrawSurface3_GetSurfaceDesc,
1161 IDirectDrawSurface3_Initialize,
1162 IDirectDrawSurface3_IsLost,
1163 IDirectDrawSurface3_Lock,
1164 IDirectDrawSurface3_ReleaseDC,
1165 IDirectDrawSurface3_Restore,
1166 IDirectDrawSurface3_SetClipper,
1167 IDirectDrawSurface3_SetColorKey,
1168 IDirectDrawSurface3_SetOverlayPosition,
1169 Xlib_IDirectDrawSurface3_SetPalette,
1170 Xlib_IDirectDrawSurface3_Unlock,
1171 IDirectDrawSurface3_UpdateOverlay,
1172 IDirectDrawSurface3_UpdateOverlayDisplay,
1173 IDirectDrawSurface3_UpdateOverlayZOrder,
1174 IDirectDrawSurface3_GetDDInterface,
1175 IDirectDrawSurface3_PageLock,
1176 IDirectDrawSurface3_PageUnlock,
1177 IDirectDrawSurface3_SetSurfaceDesc,
1181 /******************************************************************************
1182 * IDirectDrawClipper
1184 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1185 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1187 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1188 return 0;
1191 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1192 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1194 this->ref--;
1195 if (this->ref)
1196 return this->ref;
1197 HeapFree(GetProcessHeap(),0,this);
1198 return 0;
1201 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1202 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1204 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1205 if (hmm) *hmm=0;
1206 return 0;
1209 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1210 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1212 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1213 return 0;
1216 static struct IDirectDrawClipper_VTable ddclipvt = {
1217 (void*)1,
1218 (void*)2,
1219 IDirectDrawClipper_Release,
1220 IDirectDrawClipper_GetClipList,
1221 (void*)5,
1222 (void*)6,
1223 (void*)7,
1224 IDirectDrawClipper_SetClipList,
1225 IDirectDrawClipper_SetHwnd
1228 /******************************************************************************
1229 * IDirectDrawPalette
1231 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1232 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1234 int i;
1236 if (!this->cm) /* should not happen */ {
1237 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1238 return DDERR_GENERIC;
1240 for (i=0;i<count;i++) {
1241 palent[i].peRed = this->palents[start+i].peRed;
1242 palent[i].peBlue = this->palents[start+i].peBlue;
1243 palent[i].peGreen = this->palents[start+i].peGreen;
1244 palent[i].peFlags = this->palents[start+i].peFlags;
1247 return 0;
1250 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1251 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1253 XColor xc;
1254 int i;
1256 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1257 this,x,start,count,palent
1259 if (!this->cm) /* should not happen */ {
1260 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1261 return DDERR_GENERIC;
1263 if (!this->ddraw->e.xlib.paintable)
1264 return 0;
1265 for (i=0;i<count;i++) {
1266 xc.red = palent[i].peRed<<8;
1267 xc.blue = palent[i].peBlue<<8;
1268 xc.green = palent[i].peGreen<<8;
1269 xc.flags = DoRed|DoBlue|DoGreen;
1270 xc.pixel = start+i;
1272 TSXStoreColor(display,this->cm,&xc);
1274 this->palents[start+i].peRed = palent[i].peRed;
1275 this->palents[start+i].peBlue = palent[i].peBlue;
1276 this->palents[start+i].peGreen = palent[i].peGreen;
1277 this->palents[start+i].peFlags = palent[i].peFlags;
1279 return 0;
1282 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1283 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1285 #ifdef HAVE_LIBXXF86DGA
1286 XColor xc;
1287 Colormap cm;
1288 int i;
1290 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1291 this,x,start,count,palent
1293 if (!this->cm) /* should not happen */ {
1294 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1295 return DDERR_GENERIC;
1297 /* FIXME: free colorcells instead of freeing whole map */
1298 cm = this->cm;
1299 this->cm = TSXCopyColormapAndFree(display,this->cm);
1300 TSXFreeColormap(display,cm);
1302 for (i=0;i<count;i++) {
1303 xc.red = palent[i].peRed<<8;
1304 xc.blue = palent[i].peBlue<<8;
1305 xc.green = palent[i].peGreen<<8;
1306 xc.flags = DoRed|DoBlue|DoGreen;
1307 xc.pixel = i+start;
1309 TSXStoreColor(display,this->cm,&xc);
1311 this->palents[start+i].peRed = palent[i].peRed;
1312 this->palents[start+i].peBlue = palent[i].peBlue;
1313 this->palents[start+i].peGreen = palent[i].peGreen;
1314 this->palents[start+i].peFlags = palent[i].peFlags;
1316 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1317 return 0;
1318 #else /* defined(HAVE_LIBXXF86DGA) */
1319 return E_UNEXPECTED;
1320 #endif /* defined(HAVE_LIBXXF86DGA) */
1323 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1324 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1325 if (!--(this->ref)) {
1326 if (this->cm) {
1327 TSXFreeColormap(display,this->cm);
1328 this->cm = 0;
1330 HeapFree(GetProcessHeap(),0,this);
1331 return 0;
1333 return this->ref;
1336 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1338 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1339 return ++(this->ref);
1342 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1343 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1345 return DDERR_ALREADYINITIALIZED;
1348 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1349 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1351 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1352 return DD_OK;
1355 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1356 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1358 char xrefiid[50];
1360 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1361 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1363 return S_OK;
1366 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1367 IDirectDrawPalette_QueryInterface,
1368 IDirectDrawPalette_AddRef,
1369 IDirectDrawPalette_Release,
1370 IDirectDrawPalette_GetCaps,
1371 IDirectDrawPalette_GetEntries,
1372 IDirectDrawPalette_Initialize,
1373 DGA_IDirectDrawPalette_SetEntries
1376 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1377 IDirectDrawPalette_QueryInterface,
1378 IDirectDrawPalette_AddRef,
1379 IDirectDrawPalette_Release,
1380 IDirectDrawPalette_GetCaps,
1381 IDirectDrawPalette_GetEntries,
1382 IDirectDrawPalette_Initialize,
1383 Xlib_IDirectDrawPalette_SetEntries
1386 static HRESULT WINAPI IDirect3D_QueryInterface(
1387 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1389 /* FIXME: Not sure if this is correct */
1390 char xrefiid[50];
1392 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1393 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1394 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1395 *obj = this;
1396 this->lpvtbl->fnAddRef(this);
1397 return 0;
1399 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1400 LPDIRECT3D d3d;
1402 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1403 d3d->ref = 1;
1404 d3d->ddraw = (LPDIRECTDRAW)this;
1405 this->lpvtbl->fnAddRef(this);
1406 d3d->lpvtbl = &d3dvt;
1407 *obj = d3d;
1408 return 0;
1410 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1411 LPDIRECT3D2 d3d;
1413 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1414 d3d->ref = 1;
1415 d3d->ddraw = (LPDIRECTDRAW)this;
1416 this->lpvtbl->fnAddRef(this);
1417 d3d->lpvtbl = &d3d2vt;
1418 *obj = d3d;
1419 return 0;
1421 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1422 return OLE_E_ENUM_NOMORE;
1425 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1426 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1428 return ++(this->ref);
1431 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1433 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1435 if (!--(this->ref)) {
1436 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1437 HeapFree(GetProcessHeap(),0,this);
1438 return 0;
1440 return this->ref;
1443 static HRESULT WINAPI IDirect3D_Initialize(
1444 LPDIRECT3D this, REFIID refiid )
1446 /* FIXME: Not sure if this is correct */
1447 char xrefiid[50];
1449 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1450 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1452 return DDERR_ALREADYINITIALIZED;
1455 /*******************************************************************************
1456 * IDirect3D
1458 static struct IDirect3D_VTable d3dvt = {
1459 (void*)IDirect3D_QueryInterface,
1460 (void*)IDirect3D_AddRef,
1461 (void*)IDirect3D_Release,
1462 IDirect3D_Initialize,
1463 (void*)5,
1464 (void*)6,
1465 (void*)7,
1466 (void*)8,
1467 (void*)9,
1470 /*******************************************************************************
1471 * IDirect3D2
1473 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1474 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1476 if (!--(this->ref)) {
1477 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1478 HeapFree(GetProcessHeap(),0,this);
1479 return 0;
1481 return this->ref;
1484 static HRESULT WINAPI IDirect3D2_EnumDevices(
1485 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1487 D3DDEVICEDESC d1,d2;
1489 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1490 #if 0
1491 d1.dwSize = sizeof(d1);
1492 d1.dwFlags = 0;
1494 d2.dwSize = sizeof(d2);
1495 d2.dwFlags = 0;
1496 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1497 #endif
1498 return 0;
1501 static struct IDirect3D2_VTable d3d2vt = {
1502 (void*)1,
1503 (void*)2,
1504 IDirect3D2_Release,
1505 IDirect3D2_EnumDevices,
1506 (void*)5,
1507 (void*)6,
1508 (void*)7,
1509 (void*)8,
1510 (void*)9,
1513 /*******************************************************************************
1514 * IDirectDraw
1517 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1518 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1520 static INT32 ddrawXlibThisOffset = 0;
1522 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1523 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1525 #ifdef HAVE_LIBXXF86DGA
1526 int i;
1528 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1529 if (TRACE_ON(ddraw)) {
1530 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1531 _dump_DDSD(lpddsd->dwFlags);
1532 fprintf(stderr,"caps ");
1533 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1534 fprintf(stderr,"]\n");
1537 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1538 this->lpvtbl->fnAddRef(this);
1539 (*lpdsf)->ref = 1;
1540 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1541 if ( (lpddsd->dwFlags & DDSD_CAPS) &&
1542 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1544 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1545 lpddsd->dwWidth = this->e.dga.fb_width;
1546 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1547 lpddsd->dwHeight = this->e.dga.fb_height;
1548 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1549 (*lpdsf)->t.dga.fb_height = -1;
1550 (*lpdsf)->s.lpitch = lpddsd->dwWidth*this->d.depth/8;
1551 TRACE(ddraw,"using system memory for a primary surface\n");
1552 } else {
1553 for (i=0;i<32;i++)
1554 if (!(this->e.dga.vpmask & (1<<i)))
1555 break;
1556 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1557 /* if i == 32 or maximum ... return error */
1558 this->e.dga.vpmask|=(1<<i);
1559 (*lpdsf)->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1560 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1561 (*lpdsf)->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1564 lpddsd->lPitch = (*lpdsf)->s.lpitch;
1566 (*lpdsf)->s.width = this->d.width;
1567 (*lpdsf)->s.height = this->d.height;
1568 (*lpdsf)->s.ddraw = this;
1569 (*lpdsf)->s.backbuffer = NULL;
1570 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1571 LPDIRECTDRAWSURFACE3 back;
1573 if (lpddsd->dwBackBufferCount>1)
1574 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1576 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1577 this->lpvtbl->fnAddRef(this);
1578 back->ref = 1;
1579 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1580 for (i=0;i<32;i++)
1581 if (!(this->e.dga.vpmask & (1<<i)))
1582 break;
1583 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1584 /* if i == 32 or maximum ... return error */
1585 this->e.dga.vpmask|=(1<<i);
1586 back->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1587 back->t.dga.fb_height = i*this->e.dga.fb_height;
1589 back->s.width = this->d.width;
1590 back->s.height = this->d.height;
1591 back->s.ddraw = this;
1592 back->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1593 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1594 * one! */
1596 return 0;
1597 #else /* defined(HAVE_LIBXXF86DGA) */
1598 return E_UNEXPECTED;
1599 #endif /* defined(HAVE_LIBXXF86DGA) */
1602 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
1603 XImage *img;
1605 #ifdef HAVE_LIBXXSHM
1606 if (this->e.xlib.xshm_active) {
1607 img = TSXShmCreateImage(display,
1608 DefaultVisualOfScreen(screen),
1609 this->d.depth,
1610 ZPixmap,
1611 NULL,
1612 &(lpdsf->t.xlib.shminfo),
1613 lpdsf->s.width,
1614 lpdsf->s.height);
1616 if (img == NULL)
1617 return NULL;
1619 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
1620 if (lpdsf->t.xlib.shminfo.shmid < 0) {
1621 TSXDestroyImage(img);
1622 return NULL;
1625 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
1627 if (img->data == (char *) -1) {
1628 TSXDestroyImage(img);
1629 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1630 return NULL;
1632 lpdsf->t.xlib.shminfo.readOnly = False;
1634 TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
1635 TSXSync(display, False);
1637 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1639 lpdsf->s.surface = img->data;
1640 } else {
1641 #endif
1642 /* Allocate surface memory */
1643 lpdsf->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpdsf->s.width * lpdsf->s.height *this->d.depth/8);
1645 /* In this case, create an XImage */
1646 img =
1647 TSXCreateImage(display,
1648 DefaultVisualOfScreen(screen),
1649 this->d.depth,
1650 ZPixmap,
1652 lpdsf->s.surface,
1653 lpdsf->s.width,
1654 lpdsf->s.height,
1656 lpdsf->s.width * (this->d.depth / 8)
1659 #ifdef HAVE_LIBXXSHM
1661 #endif
1662 lpdsf->s.lpitch = img->bytes_per_line;
1664 return img;
1667 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1668 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1670 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1671 this,lpddsd,lpdsf,lpunk);
1673 if (TRACE_ON(ddraw)) {
1674 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1675 _dump_DDSD(lpddsd->dwFlags);
1676 fprintf(stderr,"caps ");
1677 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1678 fprintf(stderr,"]\n");
1681 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1683 this->lpvtbl->fnAddRef(this);
1684 (*lpdsf)->s.ddraw = this;
1685 (*lpdsf)->ref = 1;
1686 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1688 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1689 lpddsd->dwWidth = this->d.width;
1690 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1691 lpddsd->dwHeight = this->d.height;
1693 (*lpdsf)->s.width = lpddsd->dwWidth;
1694 (*lpdsf)->s.height = lpddsd->dwHeight;
1696 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1697 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)) {
1699 /* Allocate surface memory */
1700 (*lpdsf)->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1702 /* No XImage for a offscreen buffer */
1703 (*lpdsf)->t.xlib.image = NULL;
1704 (*lpdsf)->t.xlib.on_screen = FALSE;
1705 (*lpdsf)->s.lpitch = lpddsd->dwWidth * (this->d.depth / 8);
1707 TRACE(ddraw,"using system memory for a primary surface (%p)\n", *lpdsf);
1708 } else {
1709 XImage *img;
1711 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
1713 /* Create the XImage */
1714 img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
1715 if (img == NULL)
1716 return DDERR_OUTOFMEMORY;
1718 (*lpdsf)->t.xlib.image = img;
1719 (*lpdsf)->t.xlib.on_screen = TRUE;
1721 /* Check for backbuffers */
1722 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1723 LPDIRECTDRAWSURFACE3 back;
1724 XImage *img;
1726 if (lpddsd->dwBackBufferCount>1)
1727 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1729 (*lpdsf)->s.backbuffer = back =
1730 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1732 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
1734 this->lpvtbl->fnAddRef(this);
1735 back->s.ddraw = this;
1737 back->ref = 1;
1738 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
1740 back->s.width = lpddsd->dwWidth;
1741 back->s.height = lpddsd->dwHeight;
1743 /* Create the XImage */
1744 img = create_ximage(this, back);
1745 if (img == NULL)
1746 return DDERR_OUTOFMEMORY;
1747 back->t.xlib.image = img;
1749 back->t.xlib.on_screen = FALSE;
1750 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1751 * one! */
1755 return 0;
1758 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
1759 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1761 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1762 *dst = src; /* FIXME */
1763 return 0;
1767 * The Xlib Implementation tries to use the passed hwnd as drawing window,
1768 * even when the approbiate bitmasks are not specified.
1770 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1771 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
1773 int i;
1774 const struct {
1775 int mask;
1776 char *name;
1777 } flagmap[] = {
1778 FE(DDSCL_FULLSCREEN)
1779 FE(DDSCL_ALLOWREBOOT)
1780 FE(DDSCL_NOWINDOWCHANGES)
1781 FE(DDSCL_NORMAL)
1782 FE(DDSCL_ALLOWMODEX)
1783 FE(DDSCL_EXCLUSIVE)
1784 FE(DDSCL_SETFOCUSWINDOW)
1785 FE(DDSCL_SETDEVICEWINDOW)
1786 FE(DDSCL_CREATEDEVICEWINDOW)
1789 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
1790 if(TRACE_ON(ddraw)){
1791 dbg_decl_str(ddraw, 512);
1792 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1793 if (flagmap[i].mask & cooplevel)
1794 dsprintf(ddraw, "%s ", flagmap[i].name);
1795 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1797 this->d.mainWindow = hwnd;
1798 return 0;
1801 /* Small helper to either use the cooperative window or create a new
1802 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
1804 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
1805 RECT32 rect;
1807 /* Do not destroy the application supplied cooperative window */
1808 if (this->d.window && this->d.window != this->d.mainWindow) {
1809 DestroyWindow32(this->d.window);
1810 this->d.window = 0;
1812 /* Sanity check cooperative window before assigning it to drawing. */
1813 if ( IsWindow32(this->d.mainWindow) &&
1814 IsWindowVisible32(this->d.mainWindow)
1816 GetWindowRect32(this->d.mainWindow,&rect);
1817 if (((rect.right-rect.left) >= this->d.width) &&
1818 ((rect.bottom-rect.top) >= this->d.height)
1820 this->d.window = this->d.mainWindow;
1822 /* ... failed, create new one. */
1823 if (!this->d.window) {
1824 this->d.window = CreateWindowEx32A(
1826 "WINE_DirectDraw",
1827 "WINE_DirectDraw",
1828 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1829 0,0,
1830 this->d.width,
1831 this->d.height,
1835 NULL
1837 /*Store THIS with the window. We'll use it in the window procedure*/
1838 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
1839 ShowWindow32(this->d.window,TRUE);
1840 UpdateWindow32(this->d.window);
1844 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
1845 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1847 #ifdef HAVE_LIBXXF86DGA
1848 int i,*depths,depcount;
1850 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
1852 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1853 for (i=0;i<depcount;i++)
1854 if (depths[i]==depth)
1855 break;
1856 TSXFree(depths);
1857 if (i==depcount) {/* not found */
1858 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1859 return DDERR_UNSUPPORTEDMODE;
1861 if (this->d.width < width) {
1862 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
1863 return DDERR_UNSUPPORTEDMODE;
1865 this->d.width = width;
1866 this->d.height = height;
1867 this->d.depth = depth;
1869 /* adjust fb_height, so we don't overlap */
1870 if (this->e.dga.fb_height < height)
1871 this->e.dga.fb_height = height;
1872 _common_IDirectDraw_SetDisplayMode(this);
1874 /* FIXME: this function OVERWRITES several signal handlers.
1875 * can we save them? and restore them later? In a way that
1876 * it works for the library too?
1878 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
1879 #ifdef DIABLO_HACK
1880 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
1881 #endif
1883 #ifdef RESTORE_SIGNALS
1884 SIGNAL_InitEmulator();
1885 #endif
1886 return 0;
1887 #else /* defined(HAVE_LIBXXF86DGA) */
1888 return E_UNEXPECTED;
1889 #endif /* defined(HAVE_LIBXXF86DGA) */
1892 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
1893 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1895 int i,*depths,depcount;
1896 char buf[200];
1898 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
1899 this, width, height, depth);
1901 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1902 for (i=0;i<depcount;i++)
1903 if (depths[i]==depth)
1904 break;
1905 TSXFree(depths);
1906 if (i==depcount) {/* not found */
1907 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
1908 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
1909 return DDERR_UNSUPPORTEDMODE;
1911 this->d.width = width;
1912 this->d.height = height;
1913 this->d.depth = depth;
1915 _common_IDirectDraw_SetDisplayMode(this);
1917 this->e.xlib.paintable = 1;
1918 this->e.xlib.drawable = WIN_FindWndPtr(this->d.window)->window;
1919 /* We don't have a context for this window. Host off the desktop */
1920 if( !this->e.xlib.drawable )
1921 this->e.xlib.drawable = WIN_GetDesktop()->window;
1922 return 0;
1925 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
1926 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1928 #ifdef HAVE_LIBXXF86DGA
1929 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1930 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
1931 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1932 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1933 if (caps2) {
1934 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
1935 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1936 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1938 return 0;
1939 #else /* defined(HAVE_LIBXXF86DGA) */
1940 return E_UNEXPECTED;
1941 #endif /* defined(HAVE_LIBXXF86DGA) */
1944 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
1945 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1947 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1948 /* FIXME: Xlib */
1949 caps1->dwVidMemTotal = 2048*1024;
1950 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
1951 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1952 if (caps2) {
1953 caps2->dwVidMemTotal = 2048*1024;
1954 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
1955 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1957 /* END FIXME: Xlib */
1958 return 0;
1961 static HRESULT WINAPI IDirectDraw2_CreateClipper(
1962 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
1964 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
1965 this,x,lpddclip,lpunk
1967 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1968 (*lpddclip)->ref = 1;
1969 (*lpddclip)->lpvtbl = &ddclipvt;
1970 return 0;
1973 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
1974 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1976 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1977 if (*lpddpal == NULL) return E_OUTOFMEMORY;
1978 (*lpddpal)->ref = 1;
1979 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1980 (*lpddpal)->installed = 0;
1981 if (this->d.depth<=8) {
1982 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
1983 } else {
1984 /* we don't want palettes in hicolor or truecolor */
1985 (*lpddpal)->cm = 0;
1987 return 0;
1990 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
1991 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1993 HRESULT res;
1994 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1995 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
1996 if (res != 0) return res;
1997 (*lpddpal)->lpvtbl = &dga_ddpalvt;
1998 return 0;
2001 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2002 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2004 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2005 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2006 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2007 (*lpddpal)->ref = 1;
2008 (*lpddpal)->installed = 0;
2010 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2011 this->lpvtbl->fnAddRef(this);
2013 if (this->d.depth<=8) {
2014 (*lpddpal)->cm = TSXCreateColormap(display,this->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
2015 /* FIXME: this is not correct, when using -managed */
2016 TSXInstallColormap(display,(*lpddpal)->cm);
2018 else
2020 /* we don't want palettes in hicolor or truecolor */
2021 (*lpddpal)->cm = 0;
2024 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2025 return 0;
2028 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2029 #ifdef HAVE_LIBXXF86DGA
2030 TRACE(ddraw, "(%p)->()\n",this);
2031 Sleep(1000);
2032 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2033 #ifdef RESTORE_SIGNALS
2034 SIGNAL_InitEmulator();
2035 #endif
2036 return 0;
2037 #else /* defined(HAVE_LIBXXF86DGA) */
2038 return E_UNEXPECTED;
2039 #endif
2042 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2043 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
2044 Sleep(1000);
2045 return 0;
2048 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
2049 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
2051 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
2052 return 0;
2055 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
2056 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2058 return ++(this->ref);
2061 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2062 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2064 #ifdef HAVE_LIBXXF86DGA
2065 if (!--(this->ref)) {
2066 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2067 #ifdef RESTORE_SIGNALS
2068 SIGNAL_InitEmulator();
2069 #endif
2070 HeapFree(GetProcessHeap(),0,this);
2071 return 0;
2073 #endif /* defined(HAVE_LIBXXF86DGA) */
2074 return this->ref;
2077 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2078 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2080 if (!--(this->ref)) {
2081 HeapFree(GetProcessHeap(),0,this);
2082 return 0;
2084 /* FIXME: destroy window ... */
2085 return this->ref;
2088 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
2089 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2091 char xrefiid[50];
2093 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2094 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2095 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2096 *obj = this;
2097 this->lpvtbl->fnAddRef(this);
2098 return 0;
2100 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2101 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
2102 this->lpvtbl->fnAddRef(this);
2103 *obj = this;
2104 return 0;
2106 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2107 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
2108 this->lpvtbl->fnAddRef(this);
2109 *obj = this;
2110 return 0;
2112 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2113 LPDIRECT3D d3d;
2115 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2116 d3d->ref = 1;
2117 d3d->ddraw = (LPDIRECTDRAW)this;
2118 this->lpvtbl->fnAddRef(this);
2119 d3d->lpvtbl = &d3dvt;
2120 *obj = d3d;
2121 return 0;
2123 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2124 LPDIRECT3D2 d3d;
2126 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2127 d3d->ref = 1;
2128 d3d->ddraw = (LPDIRECTDRAW)this;
2129 this->lpvtbl->fnAddRef(this);
2130 d3d->lpvtbl = &d3d2vt;
2131 *obj = d3d;
2132 return 0;
2134 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2135 return OLE_E_ENUM_NOMORE;
2138 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
2139 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2141 char xrefiid[50];
2143 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2144 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2145 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2146 *obj = this;
2147 this->lpvtbl->fnAddRef(this);
2148 return 0;
2150 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2151 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2152 this->lpvtbl->fnAddRef(this);
2153 *obj = this;
2154 return 0;
2156 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2157 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2158 this->lpvtbl->fnAddRef(this);
2159 *obj = this;
2160 return 0;
2162 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2163 LPDIRECT3D d3d;
2165 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2166 d3d->ref = 1;
2167 d3d->ddraw = (LPDIRECTDRAW)this;
2168 this->lpvtbl->fnAddRef(this);
2169 d3d->lpvtbl = &d3dvt;
2170 *obj = d3d;
2171 return 0;
2173 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2174 LPDIRECT3D2 d3d;
2176 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2177 d3d->ref = 1;
2178 d3d->ddraw = (LPDIRECTDRAW)this;
2179 this->lpvtbl->fnAddRef(this);
2180 d3d->lpvtbl = &d3d2vt;
2181 *obj = d3d;
2182 return 0;
2184 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2185 return OLE_E_ENUM_NOMORE;
2188 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2189 LPDIRECTDRAW2 this,BOOL32 *status
2191 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2192 *status = TRUE;
2193 return 0;
2196 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2197 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2199 DDSURFACEDESC ddsfd;
2200 static struct {
2201 int w,h;
2202 } modes[5] = { /* some of the usual modes */
2203 {512,384},
2204 {640,400},
2205 {640,480},
2206 {800,600},
2207 {1024,768},
2209 static int depths[4] = {8,16,24,32};
2210 int i,j;
2212 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2213 ddsfd.dwSize = sizeof(ddsfd);
2214 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2215 if (dwFlags & DDEDM_REFRESHRATES) {
2216 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2217 ddsfd.x.dwRefreshRate = 60;
2220 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2221 ddsfd.dwBackBufferCount = 1;
2222 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2223 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2224 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2225 /* FIXME: those masks would have to be set in depth > 8 */
2226 if (depths[i]==8) {
2227 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2228 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2229 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2230 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2231 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2232 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2233 } else {
2234 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2236 /* FIXME: We should query those from X itself */
2237 switch (depths[i]) {
2238 case 16:
2239 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2240 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2241 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2242 break;
2243 case 24:
2244 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2245 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2246 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2247 break;
2248 case 32:
2249 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2250 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2251 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2252 break;
2256 ddsfd.dwWidth = screenWidth;
2257 ddsfd.dwHeight = screenHeight;
2258 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2259 if (!modescb(&ddsfd,context)) return 0;
2261 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2262 ddsfd.dwWidth = modes[j].w;
2263 ddsfd.dwHeight = modes[j].h;
2264 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2265 if (!modescb(&ddsfd,context)) return 0;
2268 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2269 /* modeX is not standard VGA */
2271 ddsfd.dwHeight = 200;
2272 ddsfd.dwWidth = 320;
2273 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2274 if (!modescb(&ddsfd,context)) return 0;
2277 return DD_OK;
2280 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2281 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2283 #ifdef HAVE_LIBXXF86DGA
2284 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2285 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2286 lpddsfd->dwHeight = screenHeight;
2287 lpddsfd->dwWidth = screenWidth;
2288 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2289 lpddsfd->dwBackBufferCount = 1;
2290 lpddsfd->x.dwRefreshRate = 60;
2291 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2292 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2293 return DD_OK;
2294 #else /* defined(HAVE_LIBXXF86DGA) */
2295 return E_UNEXPECTED;
2296 #endif /* defined(HAVE_LIBXXF86DGA) */
2299 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2300 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2302 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2303 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2304 lpddsfd->dwHeight = screenHeight;
2305 lpddsfd->dwWidth = screenWidth;
2306 /* POOLE FIXME: Xlib */
2307 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2308 /* END FIXME: Xlib */
2309 lpddsfd->dwBackBufferCount = 1;
2310 lpddsfd->x.dwRefreshRate = 60;
2311 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2312 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2313 return DD_OK;
2316 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2317 TRACE(ddraw,"(%p)->()\n",this);
2318 return DD_OK;
2321 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2322 LPDIRECTDRAW2 this,LPDWORD freq
2324 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2325 *freq = 60*100; /* 60 Hz */
2326 return 0;
2329 /* what can we directly decompress? */
2330 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2331 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2333 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2334 return 0;
2337 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2338 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2340 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2341 return 0;
2344 static HRESULT WINAPI IDirectDraw2_Compact(
2345 LPDIRECTDRAW2 this )
2347 FIXME(ddraw,"(%p)->()\n", this );
2349 return DD_OK;
2353 /* Note: Hack so we can reuse the old functions without compiler warnings */
2354 #ifdef __GNUC__
2355 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2356 #else
2357 # define XCAST(fun) (void*)
2358 #endif
2360 static struct IDirectDraw_VTable dga_ddvt = {
2361 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2362 XCAST(AddRef)IDirectDraw2_AddRef,
2363 XCAST(Release)DGA_IDirectDraw2_Release,
2364 XCAST(Compact)IDirectDraw2_Compact,
2365 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2366 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2367 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2368 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2369 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2370 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2371 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2372 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2373 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2374 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2375 XCAST(GetGDISurface)15,
2376 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2377 XCAST(GetScanLine)17,
2378 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2379 XCAST(Initialize)19,
2380 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2381 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2382 DGA_IDirectDraw_SetDisplayMode,
2383 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2386 static struct IDirectDraw_VTable xlib_ddvt = {
2387 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2388 XCAST(AddRef)IDirectDraw2_AddRef,
2389 XCAST(Release)Xlib_IDirectDraw2_Release,
2390 XCAST(Compact)IDirectDraw2_Compact,
2391 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2392 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2393 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2394 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2395 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2396 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2397 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2398 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2399 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2400 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2401 XCAST(GetGDISurface)15,
2402 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2403 XCAST(GetScanLine)17,
2404 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2405 XCAST(Initialize)19,
2406 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2407 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2408 Xlib_IDirectDraw_SetDisplayMode,
2409 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2412 /*****************************************************************************
2413 * IDirectDraw2
2418 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2419 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2421 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2424 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2425 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2427 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2430 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2431 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2433 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2434 this,ddscaps,total,free
2436 if (total) *total = this->e.dga.fb_memsize * 1024;
2437 if (free) *free = this->e.dga.fb_memsize * 1024;
2438 return 0;
2441 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2442 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2444 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2445 this,ddscaps,total,free
2447 if (total) *total = 2048 * 1024;
2448 if (free) *free = 2048 * 1024;
2449 return 0;
2452 static IDirectDraw2_VTable dga_dd2vt = {
2453 DGA_IDirectDraw2_QueryInterface,
2454 IDirectDraw2_AddRef,
2455 DGA_IDirectDraw2_Release,
2456 IDirectDraw2_Compact,
2457 IDirectDraw2_CreateClipper,
2458 DGA_IDirectDraw2_CreatePalette,
2459 DGA_IDirectDraw2_CreateSurface,
2460 (void*)8,
2461 IDirectDraw2_EnumDisplayModes,
2462 IDirectDraw2_EnumSurfaces,
2463 IDirectDraw2_FlipToGDISurface,
2464 DGA_IDirectDraw2_GetCaps,
2465 DGA_IDirectDraw2_GetDisplayMode,
2466 IDirectDraw2_GetFourCCCodes,
2467 (void*)15,
2468 IDirectDraw2_GetMonitorFrequency,
2469 (void*)17,
2470 IDirectDraw2_GetVerticalBlankStatus,
2471 (void*)19,
2472 DGA_IDirectDraw2_RestoreDisplayMode,
2473 IDirectDraw2_SetCooperativeLevel,
2474 DGA_IDirectDraw2_SetDisplayMode,
2475 IDirectDraw2_WaitForVerticalBlank,
2476 DGA_IDirectDraw2_GetAvailableVidMem
2479 static struct IDirectDraw2_VTable xlib_dd2vt = {
2480 Xlib_IDirectDraw2_QueryInterface,
2481 IDirectDraw2_AddRef,
2482 Xlib_IDirectDraw2_Release,
2483 IDirectDraw2_Compact,
2484 IDirectDraw2_CreateClipper,
2485 Xlib_IDirectDraw2_CreatePalette,
2486 Xlib_IDirectDraw2_CreateSurface,
2487 (void*)8,
2488 IDirectDraw2_EnumDisplayModes,
2489 IDirectDraw2_EnumSurfaces,
2490 IDirectDraw2_FlipToGDISurface,
2491 Xlib_IDirectDraw2_GetCaps,
2492 Xlib_IDirectDraw2_GetDisplayMode,
2493 IDirectDraw2_GetFourCCCodes,
2494 (void*)15,
2495 IDirectDraw2_GetMonitorFrequency,
2496 (void*)17,
2497 IDirectDraw2_GetVerticalBlankStatus,
2498 (void*)19,
2499 Xlib_IDirectDraw2_RestoreDisplayMode,
2500 IDirectDraw2_SetCooperativeLevel,
2501 Xlib_IDirectDraw2_SetDisplayMode,
2502 IDirectDraw2_WaitForVerticalBlank,
2503 Xlib_IDirectDraw2_GetAvailableVidMem
2506 /******************************************************************************
2507 * DirectDrawCreate
2510 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2512 LRESULT ret;
2513 LPDIRECTDRAW ddraw = NULL;
2514 DWORD lastError;
2516 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2518 SetLastError( ERROR_SUCCESS );
2519 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2520 if( (!ddraw) &&
2521 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2524 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2527 if( ddraw )
2529 /* Perform any special direct draw functions */
2530 if (msg==WM_PAINT)
2531 ddraw->e.xlib.paintable = 1;
2533 /* Now let the application deal with the rest of this */
2534 if( ddraw->d.mainWindow )
2537 /* Don't think that we actually need to call this but...
2538 might as well be on the safe side of things... */
2540 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
2541 it should be the procedures of our fake window that gets called
2542 instead of those of the window provided by the application.
2543 And with this patch, mouse clicks work with Monkey Island III
2544 - Lionel */
2545 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2547 if( !ret )
2549 /* We didn't handle the message - give it to the application */
2550 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
2551 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2552 ddraw->d.mainWindow, msg, wParam, lParam );
2556 } else {
2557 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
2560 } else {
2561 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2564 return ret;
2567 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2568 #ifdef HAVE_LIBXXF86DGA
2569 int memsize,banksize,width,major,minor,flags,height;
2570 char *addr;
2571 int fd;
2573 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
2574 if ((fd = open("/dev/mem", O_RDWR)) != -1)
2575 close(fd);
2577 if (fd == -1) {
2578 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
2579 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2580 return E_UNEXPECTED;
2582 if (!DDRAW_DGA_Available()) {
2583 TRACE(ddraw,"No XF86DGA detected.\n");
2584 return DDERR_GENERIC;
2586 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2587 (*lplpDD)->lpvtbl = &dga_ddvt;
2588 (*lplpDD)->ref = 1;
2589 TSXF86DGAQueryVersion(display,&major,&minor);
2590 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2591 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2592 if (!(flags & XF86DGADirectPresent))
2593 MSG("direct video is NOT PRESENT.\n");
2594 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2595 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2596 addr,width,banksize,memsize
2598 (*lplpDD)->e.dga.fb_width = width;
2599 (*lplpDD)->d.width = width;
2600 (*lplpDD)->e.dga.fb_addr = addr;
2601 (*lplpDD)->e.dga.fb_memsize = memsize;
2602 (*lplpDD)->e.dga.fb_banksize = banksize;
2604 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2605 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2606 (*lplpDD)->e.dga.fb_height = screenHeight;
2607 #ifdef DIABLO_HACK
2608 (*lplpDD)->e.dga.vpmask = 1;
2609 #else
2610 (*lplpDD)->e.dga.vpmask = 0;
2611 #endif
2613 /* just assume the default depth is the DGA depth too */
2614 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2615 #ifdef RESTORE_SIGNALS
2616 SIGNAL_InitEmulator();
2617 #endif
2619 return 0;
2620 #else /* defined(HAVE_LIBXXF86DGA) */
2621 return DDERR_INVALIDDIRECTDRAWGUID;
2622 #endif /* defined(HAVE_LIBXXF86DGA) */
2625 BOOL32
2626 DDRAW_XSHM_Available()
2628 #ifdef HAVE_LIBXXSHM
2629 if (TSXShmQueryExtension(display))
2631 int major, minor;
2632 Bool shpix;
2634 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
2635 return 1;
2636 else
2637 return 0;
2639 else
2640 return 0;
2641 #else
2642 return 0;
2643 #endif
2646 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2648 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2649 (*lplpDD)->lpvtbl = &xlib_ddvt;
2650 (*lplpDD)->ref = 1;
2651 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
2653 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2654 (*lplpDD)->d.height = screenHeight;
2655 (*lplpDD)->d.width = screenWidth;
2657 #ifdef HAVE_LIBXXSHM
2658 /* Test if XShm is available.
2659 As XShm is not ready yet for 'prime-time', it is disabled for now */
2660 if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
2661 TRACE(ddraw, "Using XShm extesion.\n");
2662 #endif
2664 return 0;
2667 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
2668 char xclsid[50];
2669 WNDCLASS32A wc;
2670 WND* pParentWindow;
2671 HRESULT ret;
2673 if (HIWORD(lpGUID))
2674 WINE_StringFromCLSID(lpGUID,xclsid);
2675 else {
2676 sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID);
2677 lpGUID = NULL;
2680 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
2682 if (!lpGUID) {
2683 /* if they didn't request a particular interface, use the best
2684 * supported one */
2685 if (DDRAW_DGA_Available())
2686 lpGUID = &DGA_DirectDraw_GUID;
2687 else
2688 lpGUID = &XLIB_DirectDraw_GUID;
2691 wc.style = CS_GLOBALCLASS;
2692 wc.lpfnWndProc = Xlib_DDWndProc;
2693 wc.cbClsExtra = 0;
2694 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
2695 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
2697 /* We can be a child of the desktop since we're really important */
2698 pParentWindow = WIN_GetDesktop();
2699 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
2700 wc.hInstance = 0;
2702 wc.hIcon = 0;
2703 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
2704 wc.hbrBackground= NULL_BRUSH;
2705 wc.lpszMenuName = 0;
2706 wc.lpszClassName= "WINE_DirectDraw";
2707 RegisterClass32A(&wc);
2709 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
2710 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
2711 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
2712 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
2713 else
2714 goto err;
2716 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
2717 return ret;
2719 err:
2720 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
2721 return DDERR_INVALIDDIRECTDRAWGUID;