Small fixes.
[wine/multimedia.git] / graphics / ddraw.c
blobaa2beba4f863cb5274c129c4385832783e888dc7
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.
16 #include "config.h"
17 #include <unistd.h>
18 #include <assert.h>
19 #include "ts_xlib.h"
20 #include <sys/signal.h>
22 #include "windows.h"
23 #include "winerror.h"
24 #include "interfaces.h"
25 #include "gdi.h"
26 #include "heap.h"
27 #include "ldt.h"
28 #include "dc.h"
29 #include "win.h"
30 #include "miscemu.h"
31 #include "ddraw.h"
32 #include "d3d.h"
33 #include "debug.h"
34 #include "compobj.h"
35 #include "spy.h"
36 #include "message.h"
38 #ifdef HAVE_LIBXXF86DGA
39 #include "ts_xf86dga.h"
40 #endif
42 #ifdef HAVE_LIBXXSHM
43 #include <sys/types.h>
44 #include <sys/ipc.h>
45 #include <sys/shm.h>
46 #include "ts_xshm.h"
47 #endif
49 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
50 #undef DIABLO_HACK
52 /* restore signal handlers overwritten by XF86DGA
53 * this is a define, for it will only work in emulator mode
55 #undef RESTORE_SIGNALS
57 /* Where do these GUIDs come from? mkuuid.
58 * They exist solely to distinguish between the targets Wine support,
59 * and should be different than any other GUIDs in existence.
61 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
62 0xe2dcb020,
63 0xdc60,
64 0x11d1,
65 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
68 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
69 0x1574a740,
70 0xdc61,
71 0x11d1,
72 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
75 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
76 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
77 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
78 static struct IDirectDrawClipper_VTable ddclipvt;
79 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
80 static struct IDirect3D_VTable d3dvt;
81 static struct IDirect3D2_VTable d3d2vt;
83 BOOL32
84 DDRAW_DGA_Available()
86 #ifdef HAVE_LIBXXF86DGA
87 int evbase, evret;
88 return (getuid() == 0)&&TSXF86DGAQueryExtension(display,&evbase,&evret);
89 #else /* defined(HAVE_LIBXXF86DGA) */
90 return 0;
91 #endif /* defined(HAVE_LIBXXF86DGA) */
94 HRESULT WINAPI
95 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
96 if (DDRAW_DGA_Available()) {
97 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
99 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
100 ddenumproc(NULL,"WINE","display",data);
101 return 0;
104 /* What is this doing here? */
105 HRESULT WINAPI
106 DSoundHelp(DWORD x,DWORD y,DWORD z) {
107 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
108 return 0;
112 /******************************************************************************
113 * internal helper functions
115 static void _dump_DDBLTFX(DWORD flagmask) {
116 int i;
117 const struct {
118 DWORD mask;
119 char *name;
120 } flags[] = {
121 #define FE(x) { x, #x},
122 FE(DDBLTFX_ARITHSTRETCHY)
123 FE(DDBLTFX_MIRRORLEFTRIGHT)
124 FE(DDBLTFX_MIRRORUPDOWN)
125 FE(DDBLTFX_NOTEARING)
126 FE(DDBLTFX_ROTATE180)
127 FE(DDBLTFX_ROTATE270)
128 FE(DDBLTFX_ROTATE90)
129 FE(DDBLTFX_ZBUFFERRANGE)
130 FE(DDBLTFX_ZBUFFERBASEDEST)
132 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
133 if (flags[i].mask & flagmask) {
134 DUMP("%s ",flags[i].name);
137 DUMP("\n");
141 static void _dump_DDBLTFAST(DWORD flagmask) {
142 int i;
143 const struct {
144 DWORD mask;
145 char *name;
146 } flags[] = {
147 #define FE(x) { x, #x},
148 FE(DDBLTFAST_NOCOLORKEY)
149 FE(DDBLTFAST_SRCCOLORKEY)
150 FE(DDBLTFAST_DESTCOLORKEY)
151 FE(DDBLTFAST_WAIT)
153 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
154 if (flags[i].mask & flagmask)
155 DUMP("%s ",flags[i].name);
156 DUMP("\n");
159 static void _dump_DDBLT(DWORD flagmask) {
160 int i;
161 const struct {
162 DWORD mask;
163 char *name;
164 } flags[] = {
165 #define FE(x) { x, #x},
166 FE(DDBLT_ALPHADEST)
167 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
168 FE(DDBLT_ALPHADESTNEG)
169 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
170 FE(DDBLT_ALPHAEDGEBLEND)
171 FE(DDBLT_ALPHASRC)
172 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
173 FE(DDBLT_ALPHASRCNEG)
174 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
175 FE(DDBLT_ASYNC)
176 FE(DDBLT_COLORFILL)
177 FE(DDBLT_DDFX)
178 FE(DDBLT_DDROPS)
179 FE(DDBLT_KEYDEST)
180 FE(DDBLT_KEYDESTOVERRIDE)
181 FE(DDBLT_KEYSRC)
182 FE(DDBLT_KEYSRCOVERRIDE)
183 FE(DDBLT_ROP)
184 FE(DDBLT_ROTATIONANGLE)
185 FE(DDBLT_ZBUFFER)
186 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
187 FE(DDBLT_ZBUFFERDESTOVERRIDE)
188 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
189 FE(DDBLT_ZBUFFERSRCOVERRIDE)
190 FE(DDBLT_WAIT)
191 FE(DDBLT_DEPTHFILL)
193 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
194 if (flags[i].mask & flagmask)
195 DUMP("%s ",flags[i].name);
198 static void _dump_DDSCAPS(DWORD flagmask) {
199 int i;
200 const struct {
201 DWORD mask;
202 char *name;
203 } flags[] = {
204 #define FE(x) { x, #x},
205 FE(DDSCAPS_RESERVED1)
206 FE(DDSCAPS_ALPHA)
207 FE(DDSCAPS_BACKBUFFER)
208 FE(DDSCAPS_COMPLEX)
209 FE(DDSCAPS_FLIP)
210 FE(DDSCAPS_FRONTBUFFER)
211 FE(DDSCAPS_OFFSCREENPLAIN)
212 FE(DDSCAPS_OVERLAY)
213 FE(DDSCAPS_PALETTE)
214 FE(DDSCAPS_PRIMARYSURFACE)
215 FE(DDSCAPS_PRIMARYSURFACELEFT)
216 FE(DDSCAPS_SYSTEMMEMORY)
217 FE(DDSCAPS_TEXTURE)
218 FE(DDSCAPS_3DDEVICE)
219 FE(DDSCAPS_VIDEOMEMORY)
220 FE(DDSCAPS_VISIBLE)
221 FE(DDSCAPS_WRITEONLY)
222 FE(DDSCAPS_ZBUFFER)
223 FE(DDSCAPS_OWNDC)
224 FE(DDSCAPS_LIVEVIDEO)
225 FE(DDSCAPS_HWCODEC)
226 FE(DDSCAPS_MODEX)
227 FE(DDSCAPS_MIPMAP)
228 FE(DDSCAPS_RESERVED2)
229 FE(DDSCAPS_ALLOCONLOAD)
230 FE(DDSCAPS_VIDEOPORT)
231 FE(DDSCAPS_LOCALVIDMEM)
232 FE(DDSCAPS_NONLOCALVIDMEM)
233 FE(DDSCAPS_STANDARDVGAMODE)
234 FE(DDSCAPS_OPTIMIZED)
236 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
237 if (flags[i].mask & flagmask)
238 DUMP("%s ",flags[i].name);
239 DUMP("\n");
242 static void _dump_DDSD(DWORD flagmask) {
243 int i;
244 const struct {
245 DWORD mask;
246 char *name;
247 } flags[] = {
248 FE(DDSD_CAPS)
249 FE(DDSD_HEIGHT)
250 FE(DDSD_WIDTH)
251 FE(DDSD_PITCH)
252 FE(DDSD_BACKBUFFERCOUNT)
253 FE(DDSD_ZBUFFERBITDEPTH)
254 FE(DDSD_ALPHABITDEPTH)
255 FE(DDSD_PIXELFORMAT)
256 FE(DDSD_CKDESTOVERLAY)
257 FE(DDSD_CKDESTBLT)
258 FE(DDSD_CKSRCOVERLAY)
259 FE(DDSD_CKSRCBLT)
260 FE(DDSD_MIPMAPCOUNT)
261 FE(DDSD_REFRESHRATE)
262 FE(DDSD_LINEARSIZE)
263 FE(DDSD_LPSURFACE)
265 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
266 if (flags[i].mask & flagmask)
267 DUMP("%s ",flags[i].name);
268 DUMP("\n");
271 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
272 static XVisualInfo *vi;
273 XVisualInfo vt;
274 int nitems;
276 if (!vi)
277 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
279 pf->dwFourCC = 0;
280 if (ddraw->d.depth==8) {
281 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
282 pf->x.dwRGBBitCount = 8;
283 pf->y.dwRBitMask = 0;
284 pf->z.dwGBitMask = 0;
285 pf->xx.dwBBitMask = 0;
286 pf->xy.dwRGBAlphaBitMask= 0;
287 return 0;
289 if (ddraw->d.depth==16) {
290 pf->dwFlags = DDPF_RGB;
291 pf->x.dwRGBBitCount = 16;
292 pf->y.dwRBitMask = vi[0].red_mask;
293 pf->z.dwGBitMask = vi[0].green_mask;
294 pf->xx.dwBBitMask = vi[0].blue_mask;
295 pf->xy.dwRGBAlphaBitMask= 0;
296 return 0;
298 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
299 return DDERR_GENERIC;
302 /******************************************************************************
303 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
305 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
306 * DDS and DDS2 use those functions. (Function calls did not change (except
307 * using different DirectDrawSurfaceX version), just added flags and functions)
309 static HRESULT WINAPI IDirectDrawSurface3_Lock(
310 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
312 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
313 this,lprect,lpddsd,flags,(DWORD)hnd);
314 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
315 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
316 this,lprect,lpddsd,flags,(DWORD)hnd);
318 if (lprect) {
319 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
320 lprect->top,lprect->left,lprect->bottom,lprect->right
322 lpddsd->y.lpSurface = this->s.surface +
323 (lprect->top*this->s.lpitch) +
324 (lprect->left*(this->s.ddraw->d.depth/8));
325 } else {
326 assert(this->s.surface);
327 lpddsd->y.lpSurface = this->s.surface;
329 lpddsd->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_LPSURFACE;
330 lpddsd->dwWidth = this->s.width;
331 lpddsd->dwHeight = this->s.height;
332 lpddsd->lPitch = this->s.lpitch;
333 _getpixelformat(this->s.ddraw,&(lpddsd->ddpfPixelFormat));
334 return 0;
337 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
338 LPDIRECTDRAWSURFACE3 this,LPVOID surface
340 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
341 return 0;
344 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
345 LPDIRECTDRAWSURFACE3 this,LPVOID surface)
347 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
349 if (!this->s.ddraw->e.xlib.paintable)
350 return DD_OK;
352 /* Only redraw the screen when unlocking the buffer that is on screen */
353 if ((this->t.xlib.image != NULL) && (this->t.xlib.on_screen))
354 #ifdef HAVE_LIBXXSHM
355 if (this->s.ddraw->e.xlib.xshm_active)
356 TSXShmPutImage(display,
357 this->s.ddraw->e.xlib.drawable,
358 DefaultGCOfScreen(screen),
359 this->t.xlib.image,
360 0, 0, 0, 0,
361 this->t.xlib.image->width,
362 this->t.xlib.image->height,
363 False);
364 else
365 #endif
366 TSXPutImage( display,
367 this->s.ddraw->e.xlib.drawable,
368 DefaultGCOfScreen(screen),
369 this->t.xlib.image,
370 0, 0, 0, 0,
371 this->t.xlib.image->width,
372 this->t.xlib.image->height);
374 if (this->s.palette && this->s.palette->cm)
375 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
377 return DD_OK;
380 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
381 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
383 #ifdef HAVE_LIBXXF86DGA
384 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
385 if (!flipto) {
386 if (this->s.backbuffer)
387 flipto = this->s.backbuffer;
388 else
389 flipto = this;
391 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
393 if (flipto->s.palette && flipto->s.palette->cm) {
394 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
396 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
398 if (flipto!=this) {
399 int tmp;
400 LPVOID ptmp;
402 tmp = this->t.dga.fb_height;
403 this->t.dga.fb_height = flipto->t.dga.fb_height;
404 flipto->t.dga.fb_height = tmp;
406 ptmp = this->s.surface;
407 this->s.surface = flipto->s.surface;
408 flipto->s.surface = ptmp;
410 return 0;
411 #else /* defined(HAVE_LIBXXF86DGA) */
412 return E_UNEXPECTED;
413 #endif /* defined(HAVE_LIBXXF86DGA) */
416 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
417 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
419 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
420 if (!this->s.ddraw->e.xlib.paintable)
421 return 0;
423 if (!flipto) {
424 if (this->s.backbuffer)
425 flipto = this->s.backbuffer;
426 else
427 flipto = this;
430 #ifdef HAVE_LIBXXSHM
431 if (this->s.ddraw->e.xlib.xshm_active)
432 TSXShmPutImage(display,
433 this->s.ddraw->e.xlib.drawable,
434 DefaultGCOfScreen(screen),
435 flipto->t.xlib.image,
436 0, 0, 0, 0,
437 flipto->t.xlib.image->width,
438 flipto->t.xlib.image->height,
439 False);
440 else
441 #endif
442 TSXPutImage(display,
443 this->s.ddraw->e.xlib.drawable,
444 DefaultGCOfScreen(screen),
445 flipto->t.xlib.image,
446 0, 0, 0, 0,
447 flipto->t.xlib.image->width,
448 flipto->t.xlib.image->height);
450 if (flipto->s.palette && flipto->s.palette->cm) {
451 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,flipto->s.palette->cm);
453 if (flipto!=this) {
454 XImage *tmp;
455 LPVOID *surf;
456 tmp = this->t.xlib.image;
457 this->t.xlib.image = flipto->t.xlib.image;
458 flipto->t.xlib.image = tmp;
459 surf = this->s.surface;
460 this->s.surface = flipto->s.surface;
461 flipto->s.surface = surf;
464 return 0;
468 /* The IDirectDrawSurface3::SetPalette method attaches the specified
469 * DirectDrawPalette object to a surface. The surface uses this palette for all
470 * subsequent operations. The palette change takes place immediately.
472 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
473 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
475 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
476 /* According to spec, we are only supposed to
477 * AddRef if this is not the same palette.
479 if( this->s.palette != pal )
481 if( pal != NULL )
482 pal->lpvtbl->fnAddRef( pal );
483 if( this->s.palette != NULL )
484 this->s.palette->lpvtbl->fnRelease( this->s.palette );
485 this->s.palette = pal;
487 /* I think that we need to attach it to all backbuffers...*/
488 if( this->s.backbuffer ) {
489 if( this->s.backbuffer->s.palette )
490 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
491 this->s.backbuffer->s.palette );
492 this->s.backbuffer->s.palette = pal;
493 if( pal )
494 pal->lpvtbl->fnAddRef( pal );
497 /* Perform the refresh */
498 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
501 return 0;
504 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
505 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
507 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
508 #ifdef HAVE_LIBXXF86DGA
509 /* According to spec, we are only supposed to
510 * AddRef if this is not the same palette.
512 if( this->s.palette != pal )
514 if( pal != NULL )
515 pal->lpvtbl->fnAddRef( pal );
516 if( this->s.palette != NULL )
517 this->s.palette->lpvtbl->fnRelease( this->s.palette );
518 this->s.palette = pal;
520 /* I think that we need to attach it to all backbuffers...*/
521 if( this->s.backbuffer ) {
522 if( this->s.backbuffer->s.palette )
523 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
524 this->s.backbuffer->s.palette = pal;
525 if( pal ) pal->lpvtbl->fnAddRef( pal );
527 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
529 return 0;
530 #else /* defined(HAVE_LIBXXF86DGA) */
531 return E_UNEXPECTED;
532 #endif /* defined(HAVE_LIBXXF86DGA) */
537 static HRESULT WINAPI IDirectDrawSurface3_Blt(
538 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
540 RECT32 xdst,xsrc;
541 int i,j;
543 if (TRACE_ON(ddraw)) {
544 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
545 this,rdst,src,rsrc,dwFlags,lpbltfx);
546 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
547 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
548 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
549 if (dwFlags & DDBLT_DDFX) {
550 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
554 if (rdst) {
555 memcpy(&xdst,rdst,sizeof(xdst));
556 } else {
557 xdst.top = 0;
558 xdst.bottom = this->s.height;
559 xdst.left = 0;
560 xdst.right = this->s.width;
563 if (rsrc) {
564 memcpy(&xsrc,rsrc,sizeof(xsrc));
565 } else if (src) {
566 xsrc.top = 0;
567 xsrc.bottom = src->s.height;
568 xsrc.left = 0;
569 xsrc.right = src->s.width;
572 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
574 if (dwFlags & DDBLT_COLORFILL) {
575 int bpp = this->s.ddraw->d.depth/8;
576 LPBYTE xline,xpixel;
578 xline = (LPBYTE)this->s.surface+xdst.top*this->s.lpitch;
579 for (i=xdst.top;i<xdst.bottom;i++) {
580 xpixel = xline+bpp*xdst.left;
582 for (j=xdst.left;j<xdst.right;j++) {
583 /* FIXME: this only works on little endian
584 * architectures, where DWORD starts with low
585 * byte first!
587 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
588 xpixel += bpp;
590 xline += this->s.lpitch;
592 dwFlags &= ~(DDBLT_COLORFILL);
593 } else { /* Once we have done colorfill, we do not do anything else... */
594 if ( (xsrc.top ==0) && (xsrc.bottom ==this->s.height) &&
595 (xsrc.left==0) && (xsrc.right ==this->s.width) &&
596 (xdst.top ==0) && (xdst.bottom ==this->s.height) &&
597 (xdst.left==0) && (xdst.right ==this->s.width) &&
598 !dwFlags
600 memcpy(this->s.surface,src->s.surface,this->s.height*this->s.lpitch);
601 return 0;
602 } else {
603 /* Non full screen Blit. In this case, we need to copy line per line.
604 WARNING : if the program behaves badly (ie sizes of structures are different
605 or buffer not big enough) this may crash Wine... */
606 int bpp = this->s.ddraw->d.depth / 8;
607 int height = xsrc.bottom - xsrc.top;
608 int width = (xsrc.right - xsrc.left) * bpp;
609 int h;
611 for (h = 0; h < height; h++) {
612 memcpy(this->s.surface + ((h + xdst.top) * this->s.lpitch) + xdst.left * bpp,
613 src->s.surface + ((h + xsrc.top) * src->s.lpitch) + xsrc.left * bpp,
614 width);
619 if (dwFlags) {
620 TRACE(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
623 return 0;
626 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Blt(
627 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
629 HRESULT ret;
631 /* First, call the "common" blit function */
632 ret = IDirectDrawSurface3_Blt(this, rdst, src, rsrc, dwFlags, lpbltfx);
634 /* Then put the result on screen if blited on main screen buffer */
635 if (!this->s.ddraw->e.xlib.paintable)
636 return ret;
638 if ((this->t.xlib.image != NULL) && (this->t.xlib.on_screen))
639 #ifdef HAVE_LIBXXSHM
640 if (this->s.ddraw->e.xlib.xshm_active)
641 TSXShmPutImage(display,
642 this->s.ddraw->e.xlib.drawable,
643 DefaultGCOfScreen(screen),
644 this->t.xlib.image,
645 0, 0, 0, 0,
646 this->t.xlib.image->width,
647 this->t.xlib.image->height,
648 False);
649 else
650 #endif
651 TSXPutImage(display,
652 this->s.ddraw->e.xlib.drawable,
653 DefaultGCOfScreen(screen),
654 this->t.xlib.image,
655 0, 0, 0, 0,
656 this->t.xlib.image->width,
657 this->t.xlib.image->height);
658 if (this->s.palette && this->s.palette->cm)
659 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
661 return ret;
664 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
665 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
667 int i,bpp;
668 if (TRACE_ON(ddraw)) {
669 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx),stub!\n",
670 this,dstx,dsty,src,rsrc,trans
672 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
673 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
675 bpp = this->s.ddraw->d.depth/8;
676 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
677 memcpy( this->s.surface+((i+dsty)*this->s.width*bpp)+dstx*bpp,
678 src->s.surface +(rsrc->top+i)*src->s.width*bpp+rsrc->left*bpp,
679 (rsrc->right-rsrc->left)*bpp
682 return 0;
685 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
686 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
688 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
689 this,ddbltbatch,x,y
691 return 0;
694 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
695 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
697 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
698 caps->dwCaps = DDCAPS_PALETTE; /* probably more */
699 return 0;
702 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
703 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
704 ) {
705 if (TRACE_ON(ddraw)) {
706 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
707 this,ddsd);
708 fprintf(stderr," flags: ");
709 _dump_DDSD(ddsd->dwFlags);
710 fprintf(stderr,"\n");
713 ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
714 ddsd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
715 ddsd->dwBackBufferCount = 1;
716 ddsd->dwHeight = this->s.height;
717 ddsd->dwWidth = this->s.width;
718 ddsd->lPitch = this->s.lpitch;
719 if (this->s.backbuffer)
720 ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
721 _getpixelformat(this->s.ddraw,&(ddsd->ddpfPixelFormat));
723 return 0;
726 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
727 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
729 return ++(this->ref);
732 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
733 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
735 #ifdef HAVE_LIBXXF86DGA
736 if (!--(this->ref)) {
737 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
738 /* clear out of surface list */
739 if (this->t.dga.fb_height == -1) {
740 HeapFree(GetProcessHeap(),0,this->s.surface);
741 } else {
742 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
744 HeapFree(GetProcessHeap(),0,this);
745 return 0;
747 #endif /* defined(HAVE_LIBXXF86DGA) */
748 return this->ref;
751 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
752 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
754 if (!--(this->ref)) {
755 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
757 if( this->s.backbuffer ) {
758 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
761 if (this->t.xlib.image != NULL) {
762 this->t.xlib.image->data = NULL;
764 #ifdef HAVE_LIBXXSHM
765 if (this->s.ddraw->e.xlib.xshm_active) {
766 TSXShmDetach(display, &(this->t.xlib.shminfo));
767 TSXDestroyImage(this->t.xlib.image);
768 shmdt(this->t.xlib.shminfo.shmaddr);
769 } else {
770 #endif
771 HeapFree(GetProcessHeap(),0,this->s.surface);
772 TSXDestroyImage(this->t.xlib.image);
773 #ifdef HAVE_LIBXXSHM
775 #endif
777 this->t.xlib.image = 0;
778 } else {
779 HeapFree(GetProcessHeap(),0,this->s.surface);
782 if (this->s.palette)
783 this->s.palette->lpvtbl->fnRelease(this->s.palette);
785 HeapFree(GetProcessHeap(),0,this);
786 return 0;
789 return this->ref;
792 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
793 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
795 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
796 this, lpddsd, lpdsf);
798 if (TRACE_ON(ddraw)) {
799 TRACE(ddraw," caps ");
800 _dump_DDSCAPS(lpddsd->dwCaps);
803 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
804 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
805 return E_FAIL;
808 /* FIXME: should handle more than one backbuffer */
809 *lpdsf = this->s.backbuffer;
811 if( this->s.backbuffer )
813 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
816 return 0;
819 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
820 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
822 return DDERR_ALREADYINITIALIZED;
825 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
826 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
828 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
829 return _getpixelformat(this->s.ddraw,pf);
832 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
833 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
834 return 0;
837 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
838 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
840 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
841 return 0;
844 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
845 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
847 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
848 return 0;
851 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
852 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
854 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
855 this->s.backbuffer = surf;
856 return 0;
859 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
860 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
861 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
862 return 0;
865 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
866 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
867 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
868 return 0;
872 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
873 char xrefiid[50];
875 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
876 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
878 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
879 * the same interface. And IUnknown does that too of course.
881 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
882 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
883 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
884 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
886 *obj = this;
887 this->lpvtbl->fnAddRef(this);
888 return 0;
890 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
891 return OLE_E_ENUM_NOMORE;
894 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
895 TRACE(ddraw,"(%p)->(), stub!\n",this);
896 return 0; /* hmm */
899 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
900 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
901 return 0;
904 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
905 FIXME(ddraw,"(%p)->(),stub!\n",this);
906 return 0;
909 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
910 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
912 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
914 if( dwFlags & DDCKEY_SRCBLT )
915 dwFlags &= ~DDCKEY_SRCBLT;
916 if( dwFlags )
917 TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
918 return DD_OK;
921 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
922 LPDIRECTDRAWSURFACE3 this,
923 LPRECT32 lpRect )
925 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
927 return DD_OK;
930 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
931 LPDIRECTDRAWSURFACE3 this,
932 DWORD dwFlags,
933 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
935 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
937 return DD_OK;
940 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
941 LPDIRECTDRAWSURFACE3 this,
942 DWORD dwFlags,
943 LPVOID lpContext,
944 LPDDENUMSURFACESCALLBACK lpfnCallback )
946 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
947 lpContext, lpfnCallback );
949 return DD_OK;
952 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
953 LPDIRECTDRAWSURFACE3 this,
954 LPDIRECTDRAWCLIPPER* lplpDDClipper )
956 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
958 return DD_OK;
961 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
962 LPDIRECTDRAWSURFACE3 this,
963 DWORD dwFlags,
964 LPDDCOLORKEY lpDDColorKey )
966 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDColorKey);
968 return DD_OK;
971 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
972 LPDIRECTDRAWSURFACE3 this,
973 DWORD dwFlags )
975 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
977 return DD_OK;
980 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
981 LPDIRECTDRAWSURFACE3 this,
982 LPDIRECTDRAWPALETTE* lplpDDPalette )
984 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
986 return DD_OK;
989 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
990 LPDIRECTDRAWSURFACE3 this,
991 LONG lX,
992 LONG lY)
994 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
996 return DD_OK;
999 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
1000 LPDIRECTDRAWSURFACE3 this,
1001 LPRECT32 lpSrcRect,
1002 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
1003 LPRECT32 lpDestRect,
1004 DWORD dwFlags,
1005 LPDDOVERLAYFX lpDDOverlayFx )
1007 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1008 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1010 return DD_OK;
1013 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
1014 LPDIRECTDRAWSURFACE3 this,
1015 DWORD dwFlags )
1017 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1019 return DD_OK;
1022 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
1023 LPDIRECTDRAWSURFACE3 this,
1024 DWORD dwFlags,
1025 LPDIRECTDRAWSURFACE3 lpDDSReference )
1027 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1029 return DD_OK;
1032 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
1033 LPDIRECTDRAWSURFACE3 this,
1034 LPVOID* lplpDD )
1036 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1038 return DD_OK;
1041 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
1042 LPDIRECTDRAWSURFACE3 this,
1043 DWORD dwFlags )
1045 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1047 return DD_OK;
1050 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
1051 LPDIRECTDRAWSURFACE3 this,
1052 DWORD dwFlags )
1054 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1056 return DD_OK;
1059 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1060 LPDIRECTDRAWSURFACE3 this,
1061 LPDDSURFACEDESC lpDDSD,
1062 DWORD dwFlags )
1064 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1066 return DD_OK;
1069 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1070 IDirectDrawSurface3_QueryInterface,
1071 IDirectDrawSurface3_AddRef,
1072 DGA_IDirectDrawSurface3_Release,
1073 IDirectDrawSurface3_AddAttachedSurface,
1074 IDirectDrawSurface3_AddOverlayDirtyRect,
1075 IDirectDrawSurface3_Blt,
1076 IDirectDrawSurface3_BltBatch,
1077 IDirectDrawSurface3_BltFast,
1078 IDirectDrawSurface3_DeleteAttachedSurface,
1079 IDirectDrawSurface3_EnumAttachedSurfaces,
1080 IDirectDrawSurface3_EnumOverlayZOrders,
1081 DGA_IDirectDrawSurface3_Flip,
1082 IDirectDrawSurface3_GetAttachedSurface,
1083 IDirectDrawSurface3_GetBltStatus,
1084 IDirectDrawSurface3_GetCaps,
1085 IDirectDrawSurface3_GetClipper,
1086 IDirectDrawSurface3_GetColorKey,
1087 IDirectDrawSurface3_GetDC,
1088 IDirectDrawSurface3_GetFlipStatus,
1089 IDirectDrawSurface3_GetOverlayPosition,
1090 IDirectDrawSurface3_GetPalette,
1091 IDirectDrawSurface3_GetPixelFormat,
1092 IDirectDrawSurface3_GetSurfaceDesc,
1093 IDirectDrawSurface3_Initialize,
1094 IDirectDrawSurface3_IsLost,
1095 IDirectDrawSurface3_Lock,
1096 IDirectDrawSurface3_ReleaseDC,
1097 IDirectDrawSurface3_Restore,
1098 IDirectDrawSurface3_SetClipper,
1099 IDirectDrawSurface3_SetColorKey,
1100 IDirectDrawSurface3_SetOverlayPosition,
1101 DGA_IDirectDrawSurface3_SetPalette,
1102 DGA_IDirectDrawSurface3_Unlock,
1103 IDirectDrawSurface3_UpdateOverlay,
1104 IDirectDrawSurface3_UpdateOverlayDisplay,
1105 IDirectDrawSurface3_UpdateOverlayZOrder,
1106 IDirectDrawSurface3_GetDDInterface,
1107 IDirectDrawSurface3_PageLock,
1108 IDirectDrawSurface3_PageUnlock,
1109 IDirectDrawSurface3_SetSurfaceDesc,
1112 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1113 IDirectDrawSurface3_QueryInterface,
1114 IDirectDrawSurface3_AddRef,
1115 Xlib_IDirectDrawSurface3_Release,
1116 IDirectDrawSurface3_AddAttachedSurface,
1117 IDirectDrawSurface3_AddOverlayDirtyRect,
1118 Xlib_IDirectDrawSurface3_Blt,
1119 IDirectDrawSurface3_BltBatch,
1120 IDirectDrawSurface3_BltFast,
1121 IDirectDrawSurface3_DeleteAttachedSurface,
1122 IDirectDrawSurface3_EnumAttachedSurfaces,
1123 IDirectDrawSurface3_EnumOverlayZOrders,
1124 Xlib_IDirectDrawSurface3_Flip,
1125 IDirectDrawSurface3_GetAttachedSurface,
1126 IDirectDrawSurface3_GetBltStatus,
1127 IDirectDrawSurface3_GetCaps,
1128 IDirectDrawSurface3_GetClipper,
1129 IDirectDrawSurface3_GetColorKey,
1130 IDirectDrawSurface3_GetDC,
1131 IDirectDrawSurface3_GetFlipStatus,
1132 IDirectDrawSurface3_GetOverlayPosition,
1133 IDirectDrawSurface3_GetPalette,
1134 IDirectDrawSurface3_GetPixelFormat,
1135 IDirectDrawSurface3_GetSurfaceDesc,
1136 IDirectDrawSurface3_Initialize,
1137 IDirectDrawSurface3_IsLost,
1138 IDirectDrawSurface3_Lock,
1139 IDirectDrawSurface3_ReleaseDC,
1140 IDirectDrawSurface3_Restore,
1141 IDirectDrawSurface3_SetClipper,
1142 IDirectDrawSurface3_SetColorKey,
1143 IDirectDrawSurface3_SetOverlayPosition,
1144 Xlib_IDirectDrawSurface3_SetPalette,
1145 Xlib_IDirectDrawSurface3_Unlock,
1146 IDirectDrawSurface3_UpdateOverlay,
1147 IDirectDrawSurface3_UpdateOverlayDisplay,
1148 IDirectDrawSurface3_UpdateOverlayZOrder,
1149 IDirectDrawSurface3_GetDDInterface,
1150 IDirectDrawSurface3_PageLock,
1151 IDirectDrawSurface3_PageUnlock,
1152 IDirectDrawSurface3_SetSurfaceDesc,
1156 /******************************************************************************
1157 * IDirectDrawClipper
1159 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1160 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1162 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1163 return 0;
1166 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1167 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1169 this->ref--;
1170 if (this->ref)
1171 return this->ref;
1172 HeapFree(GetProcessHeap(),0,this);
1173 return 0;
1176 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1177 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1179 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1180 if (hmm) *hmm=0;
1181 return 0;
1184 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1185 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1187 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1188 return 0;
1191 static struct IDirectDrawClipper_VTable ddclipvt = {
1192 (void*)1,
1193 (void*)2,
1194 IDirectDrawClipper_Release,
1195 IDirectDrawClipper_GetClipList,
1196 (void*)5,
1197 (void*)6,
1198 (void*)7,
1199 IDirectDrawClipper_SetClipList,
1200 IDirectDrawClipper_SetHwnd
1203 /******************************************************************************
1204 * IDirectDrawPalette
1206 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1207 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1209 int i;
1211 if (!this->cm) /* should not happen */ {
1212 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1213 return DDERR_GENERIC;
1215 for (i=0;i<count;i++) {
1216 palent[i].peRed = this->palents[start+i].peRed;
1217 palent[i].peBlue = this->palents[start+i].peBlue;
1218 palent[i].peGreen = this->palents[start+i].peGreen;
1219 palent[i].peFlags = this->palents[start+i].peFlags;
1222 return 0;
1225 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1226 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1228 XColor xc;
1229 int i;
1231 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1232 this,x,start,count,palent
1234 if (!this->cm) /* should not happen */ {
1235 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1236 return DDERR_GENERIC;
1238 if (!this->ddraw->e.xlib.paintable)
1239 return 0;
1240 for (i=0;i<count;i++) {
1241 xc.red = palent[i].peRed<<8;
1242 xc.blue = palent[i].peBlue<<8;
1243 xc.green = palent[i].peGreen<<8;
1244 xc.flags = DoRed|DoBlue|DoGreen;
1245 xc.pixel = start+i;
1247 TSXStoreColor(display,this->cm,&xc);
1249 this->palents[start+i].peRed = palent[i].peRed;
1250 this->palents[start+i].peBlue = palent[i].peBlue;
1251 this->palents[start+i].peGreen = palent[i].peGreen;
1252 this->palents[start+i].peFlags = palent[i].peFlags;
1254 return 0;
1257 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1258 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1260 #ifdef HAVE_LIBXXF86DGA
1261 XColor xc;
1262 Colormap cm;
1263 int i;
1265 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1266 this,x,start,count,palent
1268 if (!this->cm) /* should not happen */ {
1269 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1270 return DDERR_GENERIC;
1272 /* FIXME: free colorcells instead of freeing whole map */
1273 cm = this->cm;
1274 this->cm = TSXCopyColormapAndFree(display,this->cm);
1275 TSXFreeColormap(display,cm);
1277 for (i=0;i<count;i++) {
1278 xc.red = palent[i].peRed<<8;
1279 xc.blue = palent[i].peBlue<<8;
1280 xc.green = palent[i].peGreen<<8;
1281 xc.flags = DoRed|DoBlue|DoGreen;
1282 xc.pixel = i+start;
1284 TSXStoreColor(display,this->cm,&xc);
1286 this->palents[start+i].peRed = palent[i].peRed;
1287 this->palents[start+i].peBlue = palent[i].peBlue;
1288 this->palents[start+i].peGreen = palent[i].peGreen;
1289 this->palents[start+i].peFlags = palent[i].peFlags;
1291 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1292 return 0;
1293 #else /* defined(HAVE_LIBXXF86DGA) */
1294 return E_UNEXPECTED;
1295 #endif /* defined(HAVE_LIBXXF86DGA) */
1298 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1299 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1300 if (!--(this->ref)) {
1301 if (this->cm) {
1302 TSXFreeColormap(display,this->cm);
1303 this->cm = 0;
1305 HeapFree(GetProcessHeap(),0,this);
1306 return 0;
1308 return this->ref;
1311 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1313 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1314 return ++(this->ref);
1317 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1318 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1320 return DDERR_ALREADYINITIALIZED;
1323 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1324 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1326 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1327 return DD_OK;
1330 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1331 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1333 char xrefiid[50];
1335 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1336 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1338 return S_OK;
1341 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1342 IDirectDrawPalette_QueryInterface,
1343 IDirectDrawPalette_AddRef,
1344 IDirectDrawPalette_Release,
1345 IDirectDrawPalette_GetCaps,
1346 IDirectDrawPalette_GetEntries,
1347 IDirectDrawPalette_Initialize,
1348 DGA_IDirectDrawPalette_SetEntries
1351 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1352 IDirectDrawPalette_QueryInterface,
1353 IDirectDrawPalette_AddRef,
1354 IDirectDrawPalette_Release,
1355 IDirectDrawPalette_GetCaps,
1356 IDirectDrawPalette_GetEntries,
1357 IDirectDrawPalette_Initialize,
1358 Xlib_IDirectDrawPalette_SetEntries
1361 static HRESULT WINAPI IDirect3D_QueryInterface(
1362 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1364 /* FIXME: Not sure if this is correct */
1365 char xrefiid[50];
1367 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1368 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1369 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1370 *obj = this;
1371 this->lpvtbl->fnAddRef(this);
1372 return 0;
1374 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1375 LPDIRECT3D d3d;
1377 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1378 d3d->ref = 1;
1379 d3d->ddraw = (LPDIRECTDRAW)this;
1380 this->lpvtbl->fnAddRef(this);
1381 d3d->lpvtbl = &d3dvt;
1382 *obj = d3d;
1383 return 0;
1385 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1386 LPDIRECT3D2 d3d;
1388 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1389 d3d->ref = 1;
1390 d3d->ddraw = (LPDIRECTDRAW)this;
1391 this->lpvtbl->fnAddRef(this);
1392 d3d->lpvtbl = &d3d2vt;
1393 *obj = d3d;
1394 return 0;
1396 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1397 return OLE_E_ENUM_NOMORE;
1400 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1401 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1403 return ++(this->ref);
1406 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1408 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1410 if (!--(this->ref)) {
1411 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1412 HeapFree(GetProcessHeap(),0,this);
1413 return 0;
1415 return this->ref;
1418 static HRESULT WINAPI IDirect3D_Initialize(
1419 LPDIRECT3D this, REFIID refiid )
1421 /* FIXME: Not sure if this is correct */
1422 char xrefiid[50];
1424 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1425 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1427 return DDERR_ALREADYINITIALIZED;
1430 /*******************************************************************************
1431 * IDirect3D
1433 static struct IDirect3D_VTable d3dvt = {
1434 (void*)IDirect3D_QueryInterface,
1435 (void*)IDirect3D_AddRef,
1436 (void*)IDirect3D_Release,
1437 IDirect3D_Initialize,
1438 (void*)5,
1439 (void*)6,
1440 (void*)7,
1441 (void*)8,
1442 (void*)9,
1445 /*******************************************************************************
1446 * IDirect3D2
1448 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1449 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1451 if (!--(this->ref)) {
1452 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1453 HeapFree(GetProcessHeap(),0,this);
1454 return 0;
1456 return this->ref;
1459 static HRESULT WINAPI IDirect3D2_EnumDevices(
1460 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1462 D3DDEVICEDESC d1,d2;
1464 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1465 #if 0
1466 d1.dwSize = sizeof(d1);
1467 d1.dwFlags = 0;
1469 d2.dwSize = sizeof(d2);
1470 d2.dwFlags = 0;
1471 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1472 #endif
1473 return 0;
1476 static struct IDirect3D2_VTable d3d2vt = {
1477 (void*)1,
1478 (void*)2,
1479 IDirect3D2_Release,
1480 IDirect3D2_EnumDevices,
1481 (void*)5,
1482 (void*)6,
1483 (void*)7,
1484 (void*)8,
1485 (void*)9,
1488 /*******************************************************************************
1489 * IDirectDraw
1492 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1493 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1495 static INT32 ddrawXlibThisOffset = 0;
1497 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1498 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1500 #ifdef HAVE_LIBXXF86DGA
1501 int i;
1503 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1504 if (TRACE_ON(ddraw)) {
1505 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1506 _dump_DDSD(lpddsd->dwFlags);
1507 fprintf(stderr,"caps ");
1508 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1509 fprintf(stderr,"]\n");
1512 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1513 this->lpvtbl->fnAddRef(this);
1514 (*lpdsf)->ref = 1;
1515 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1516 if ( (lpddsd->dwFlags & DDSD_CAPS) &&
1517 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1519 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1520 lpddsd->dwWidth = this->e.dga.fb_width;
1521 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1522 lpddsd->dwHeight = this->e.dga.fb_height;
1523 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1524 (*lpdsf)->t.dga.fb_height = -1;
1525 (*lpdsf)->s.lpitch = lpddsd->dwWidth*this->d.depth/8;
1526 TRACE(ddraw,"using system memory for a primary surface\n");
1527 } else {
1528 for (i=0;i<32;i++)
1529 if (!(this->e.dga.vpmask & (1<<i)))
1530 break;
1531 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1532 /* if i == 32 or maximum ... return error */
1533 this->e.dga.vpmask|=(1<<i);
1534 (*lpdsf)->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1535 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1536 (*lpdsf)->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1539 lpddsd->lPitch = (*lpdsf)->s.lpitch;
1541 (*lpdsf)->s.width = this->d.width;
1542 (*lpdsf)->s.height = this->d.height;
1543 (*lpdsf)->s.ddraw = this;
1544 (*lpdsf)->s.backbuffer = NULL;
1545 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1546 LPDIRECTDRAWSURFACE3 back;
1548 if (lpddsd->dwBackBufferCount>1)
1549 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1551 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1552 this->lpvtbl->fnAddRef(this);
1553 back->ref = 1;
1554 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1555 for (i=0;i<32;i++)
1556 if (!(this->e.dga.vpmask & (1<<i)))
1557 break;
1558 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1559 /* if i == 32 or maximum ... return error */
1560 this->e.dga.vpmask|=(1<<i);
1561 back->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1562 back->t.dga.fb_height = i*this->e.dga.fb_height;
1564 back->s.width = this->d.width;
1565 back->s.height = this->d.height;
1566 back->s.ddraw = this;
1567 back->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1568 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1569 * one! */
1571 return 0;
1572 #else /* defined(HAVE_LIBXXF86DGA) */
1573 return E_UNEXPECTED;
1574 #endif /* defined(HAVE_LIBXXF86DGA) */
1577 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
1578 XImage *img;
1580 #ifdef HAVE_LIBXXSHM
1581 if (this->e.xlib.xshm_active) {
1582 img = TSXShmCreateImage(display,
1583 DefaultVisualOfScreen(screen),
1584 this->d.depth,
1585 ZPixmap,
1586 NULL,
1587 &(lpdsf->t.xlib.shminfo),
1588 lpdsf->s.width,
1589 lpdsf->s.height);
1591 if (img == NULL)
1592 return NULL;
1594 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
1595 if (lpdsf->t.xlib.shminfo.shmid < 0) {
1596 TSXDestroyImage(img);
1597 return NULL;
1600 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
1602 if (img->data == (char *) -1) {
1603 TSXDestroyImage(img);
1604 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1605 return NULL;
1607 lpdsf->t.xlib.shminfo.readOnly = False;
1609 TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
1610 TSXSync(display, False);
1612 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1614 lpdsf->s.surface = img->data;
1615 } else {
1616 #endif
1617 /* Allocate surface memory */
1618 lpdsf->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpdsf->s.width * lpdsf->s.height *this->d.depth/8);
1620 /* In this case, create an XImage */
1621 img =
1622 TSXCreateImage(display,
1623 DefaultVisualOfScreen(screen),
1624 this->d.depth,
1625 ZPixmap,
1627 lpdsf->s.surface,
1628 lpdsf->s.width,
1629 lpdsf->s.height,
1631 lpdsf->s.width * (this->d.depth / 8)
1634 #ifdef HAVE_LIBXXSHM
1636 #endif
1637 lpdsf->s.lpitch = img->bytes_per_line;
1639 return img;
1642 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1643 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1645 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1646 this,lpddsd,lpdsf,lpunk);
1648 if (TRACE_ON(ddraw)) {
1649 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1650 _dump_DDSD(lpddsd->dwFlags);
1651 fprintf(stderr,"caps ");
1652 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1653 fprintf(stderr,"]\n");
1656 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1658 this->lpvtbl->fnAddRef(this);
1659 (*lpdsf)->s.ddraw = this;
1660 (*lpdsf)->ref = 1;
1661 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1663 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1664 lpddsd->dwWidth = this->d.width;
1665 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1666 lpddsd->dwHeight = this->d.height;
1668 (*lpdsf)->s.width = lpddsd->dwWidth;
1669 (*lpdsf)->s.height = lpddsd->dwHeight;
1671 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1672 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)) {
1674 /* Allocate surface memory */
1675 (*lpdsf)->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1677 /* No XImage for a offscreen buffer */
1678 (*lpdsf)->t.xlib.image = NULL;
1679 (*lpdsf)->t.xlib.on_screen = FALSE;
1680 (*lpdsf)->s.lpitch = lpddsd->dwWidth * (this->d.depth / 8);
1682 TRACE(ddraw,"using system memory for a primary surface (%p)\n", *lpdsf);
1683 } else {
1684 XImage *img;
1686 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
1688 /* Create the XImage */
1689 img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
1690 if (img == NULL)
1691 return DDERR_OUTOFMEMORY;
1693 (*lpdsf)->t.xlib.image = img;
1694 (*lpdsf)->t.xlib.on_screen = TRUE;
1696 /* Check for backbuffers */
1697 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1698 LPDIRECTDRAWSURFACE3 back;
1699 XImage *img;
1701 if (lpddsd->dwBackBufferCount>1)
1702 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1704 (*lpdsf)->s.backbuffer = back =
1705 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1707 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
1709 this->lpvtbl->fnAddRef(this);
1710 back->s.ddraw = this;
1712 back->ref = 1;
1713 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
1715 back->s.width = lpddsd->dwWidth;
1716 back->s.height = lpddsd->dwHeight;
1718 /* Create the XImage */
1719 img = create_ximage(this, back);
1720 if (img == NULL)
1721 return DDERR_OUTOFMEMORY;
1722 back->t.xlib.image = img;
1724 back->t.xlib.on_screen = FALSE;
1725 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1726 * one! */
1730 return 0;
1733 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
1734 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1736 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1737 *dst = src; /* FIXME */
1738 return 0;
1741 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1742 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
1744 int i;
1745 const struct {
1746 int mask;
1747 char *name;
1748 } flagmap[] = {
1749 FE(DDSCL_FULLSCREEN)
1750 FE(DDSCL_ALLOWREBOOT)
1751 FE(DDSCL_NOWINDOWCHANGES)
1752 FE(DDSCL_NORMAL)
1753 FE(DDSCL_ALLOWMODEX)
1754 FE(DDSCL_EXCLUSIVE)
1755 FE(DDSCL_SETFOCUSWINDOW)
1756 FE(DDSCL_SETDEVICEWINDOW)
1757 FE(DDSCL_CREATEDEVICEWINDOW)
1760 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
1761 if(TRACE_ON(ddraw)){
1762 dbg_decl_str(ddraw, 512);
1763 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1764 if (flagmap[i].mask & cooplevel)
1765 dsprintf(ddraw, "%s ", flagmap[i].name);
1766 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1768 this->d.mainWindow = hwnd;
1769 return 0;
1773 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
1774 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1776 #ifdef HAVE_LIBXXF86DGA
1777 int i,*depths,depcount;
1778 HWND32 window;
1780 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
1782 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1783 for (i=0;i<depcount;i++)
1784 if (depths[i]==depth)
1785 break;
1786 TSXFree(depths);
1787 if (i==depcount) {/* not found */
1788 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1789 return DDERR_UNSUPPORTEDMODE;
1791 if (this->d.width < width) {
1792 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
1793 return DDERR_UNSUPPORTEDMODE;
1795 this->d.width = width;
1796 this->d.height = height;
1797 /* adjust fb_height, so we don't overlap */
1798 if (this->e.dga.fb_height < height)
1799 this->e.dga.fb_height = height;
1800 this->d.depth = depth;
1802 /* First, create a window for this mode. Apparently, some games
1803 (such as Monkey Island III) do not do this properly for themselves. */
1804 window = CreateWindowEx32A(
1806 "WINE_DirectDraw",
1807 "WINE_DirectDraw",
1808 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1809 0,0,
1810 width,
1811 height,
1815 NULL
1817 SetWindowLong32A(window,ddrawXlibThisOffset,(LONG)this);
1818 ShowWindow32(window,TRUE);
1819 UpdateWindow32(window);
1820 assert(window);
1822 /* FIXME: this function OVERWRITES several signal handlers.
1823 * can we save them? and restore them later? In a way that
1824 * it works for the library too?
1826 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
1827 #ifdef DIABLO_HACK
1828 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
1829 #endif
1831 #ifdef RESTORE_SIGNALS
1832 SIGNAL_InitEmulator();
1833 #endif
1834 return 0;
1835 #else /* defined(HAVE_LIBXXF86DGA) */
1836 return E_UNEXPECTED;
1837 #endif /* defined(HAVE_LIBXXF86DGA) */
1840 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
1841 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1843 int i,*depths,depcount;
1844 char buf[200];
1846 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
1847 this, width, height, depth);
1849 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1850 for (i=0;i<depcount;i++)
1851 if (depths[i]==depth)
1852 break;
1853 TSXFree(depths);
1854 if (i==depcount) {/* not found */
1855 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
1856 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
1857 return DDERR_UNSUPPORTEDMODE;
1860 if (this->d.window)
1861 DestroyWindow32(this->d.window);
1862 this->d.window = CreateWindowEx32A(
1864 "WINE_DirectDraw",
1865 "WINE_DirectDraw",
1866 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1867 0,0,
1868 width,
1869 height,
1873 NULL
1876 /* Store this with the window. We'll use it for the window procedure */
1877 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
1879 this->e.xlib.paintable = 1;
1881 ShowWindow32(this->d.window,TRUE);
1882 UpdateWindow32(this->d.window);
1884 assert(this->d.window);
1886 this->e.xlib.drawable = WIN_FindWndPtr(this->d.window)->window;
1888 /* We don't have a context for this window. Host off the desktop */
1889 if( !this->e.xlib.drawable )
1891 this->e.xlib.drawable = WIN_GetDesktop()->window;
1894 this->d.width = width;
1895 this->d.height = height;
1896 this->d.depth = depth;
1897 return 0;
1900 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
1901 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1903 #ifdef HAVE_LIBXXF86DGA
1904 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1905 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
1906 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1907 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1908 if (caps2) {
1909 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
1910 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1911 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1913 return 0;
1914 #else /* defined(HAVE_LIBXXF86DGA) */
1915 return E_UNEXPECTED;
1916 #endif /* defined(HAVE_LIBXXF86DGA) */
1919 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
1920 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1922 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1923 /* FIXME: Xlib */
1924 caps1->dwVidMemTotal = 2048*1024;
1925 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1926 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1927 if (caps2) {
1928 caps2->dwVidMemTotal = 2048*1024;
1929 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1930 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1932 /* END FIXME: Xlib */
1933 return 0;
1936 static HRESULT WINAPI IDirectDraw2_CreateClipper(
1937 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
1939 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
1940 this,x,lpddclip,lpunk
1942 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1943 (*lpddclip)->ref = 1;
1944 (*lpddclip)->lpvtbl = &ddclipvt;
1945 return 0;
1948 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
1949 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1951 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1952 if (*lpddpal == NULL) return E_OUTOFMEMORY;
1953 (*lpddpal)->ref = 1;
1954 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1955 (*lpddpal)->installed = 0;
1956 if (this->d.depth<=8) {
1957 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
1958 } else {
1959 /* we don't want palettes in hicolor or truecolor */
1960 (*lpddpal)->cm = 0;
1962 return 0;
1965 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
1966 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1968 HRESULT res;
1969 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1970 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
1971 if (res != 0) return res;
1972 (*lpddpal)->lpvtbl = &dga_ddpalvt;
1973 return 0;
1976 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
1977 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1979 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1980 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1981 if (*lpddpal == NULL) return E_OUTOFMEMORY;
1982 (*lpddpal)->ref = 1;
1983 (*lpddpal)->installed = 0;
1985 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1986 this->lpvtbl->fnAddRef(this);
1988 if (this->d.depth<=8) {
1989 (*lpddpal)->cm = TSXCreateColormap(display,this->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
1990 /* FIXME: this is not correct, when using -managed */
1991 TSXInstallColormap(display,(*lpddpal)->cm);
1993 else
1995 /* we don't want palettes in hicolor or truecolor */
1996 (*lpddpal)->cm = 0;
1999 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2000 return 0;
2003 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2004 #ifdef HAVE_LIBXXF86DGA
2005 TRACE(ddraw, "(%p)->()\n",this);
2006 Sleep(1000);
2007 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2008 #ifdef RESTORE_SIGNALS
2009 SIGNAL_InitEmulator();
2010 #endif
2011 return 0;
2012 #else /* defined(HAVE_LIBXXF86DGA) */
2013 return E_UNEXPECTED;
2014 #endif
2017 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2018 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
2019 Sleep(1000);
2020 return 0;
2023 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
2024 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
2026 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
2027 return 0;
2030 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
2031 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2033 return ++(this->ref);
2036 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2037 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2039 #ifdef HAVE_LIBXXF86DGA
2040 if (!--(this->ref)) {
2041 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2042 #ifdef RESTORE_SIGNALS
2043 SIGNAL_InitEmulator();
2044 #endif
2045 HeapFree(GetProcessHeap(),0,this);
2046 return 0;
2048 #endif /* defined(HAVE_LIBXXF86DGA) */
2049 return this->ref;
2052 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2053 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2055 if (!--(this->ref)) {
2056 HeapFree(GetProcessHeap(),0,this);
2057 return 0;
2059 /* FIXME: destroy window ... */
2060 return this->ref;
2063 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
2064 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2066 char xrefiid[50];
2068 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2069 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2070 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2071 *obj = this;
2072 this->lpvtbl->fnAddRef(this);
2073 return 0;
2075 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2076 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
2077 this->lpvtbl->fnAddRef(this);
2078 *obj = this;
2079 return 0;
2081 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2082 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
2083 this->lpvtbl->fnAddRef(this);
2084 *obj = this;
2085 return 0;
2087 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2088 LPDIRECT3D d3d;
2090 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2091 d3d->ref = 1;
2092 d3d->ddraw = (LPDIRECTDRAW)this;
2093 this->lpvtbl->fnAddRef(this);
2094 d3d->lpvtbl = &d3dvt;
2095 *obj = d3d;
2096 return 0;
2098 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2099 LPDIRECT3D2 d3d;
2101 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2102 d3d->ref = 1;
2103 d3d->ddraw = (LPDIRECTDRAW)this;
2104 this->lpvtbl->fnAddRef(this);
2105 d3d->lpvtbl = &d3d2vt;
2106 *obj = d3d;
2107 return 0;
2109 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2110 return OLE_E_ENUM_NOMORE;
2113 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
2114 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2116 char xrefiid[50];
2118 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2119 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2120 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2121 *obj = this;
2122 this->lpvtbl->fnAddRef(this);
2123 return 0;
2125 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2126 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2127 this->lpvtbl->fnAddRef(this);
2128 *obj = this;
2129 return 0;
2131 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2132 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2133 this->lpvtbl->fnAddRef(this);
2134 *obj = this;
2135 return 0;
2137 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2138 LPDIRECT3D d3d;
2140 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2141 d3d->ref = 1;
2142 d3d->ddraw = (LPDIRECTDRAW)this;
2143 this->lpvtbl->fnAddRef(this);
2144 d3d->lpvtbl = &d3dvt;
2145 *obj = d3d;
2146 return 0;
2148 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2149 LPDIRECT3D2 d3d;
2151 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2152 d3d->ref = 1;
2153 d3d->ddraw = (LPDIRECTDRAW)this;
2154 this->lpvtbl->fnAddRef(this);
2155 d3d->lpvtbl = &d3d2vt;
2156 *obj = d3d;
2157 return 0;
2159 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2160 return OLE_E_ENUM_NOMORE;
2163 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2164 LPDIRECTDRAW2 this,BOOL32 *status
2166 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2167 *status = TRUE;
2168 return 0;
2171 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2172 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2174 DDSURFACEDESC ddsfd;
2175 static struct {
2176 int w,h;
2177 } modes[5] = { /* some of the usual modes */
2178 {512,384},
2179 {640,400},
2180 {640,480},
2181 {800,600},
2182 {1024,768},
2184 static int depths[4] = {8,16,24,32};
2185 int i,j;
2187 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2188 ddsfd.dwSize = sizeof(ddsfd);
2189 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2190 if (dwFlags & DDEDM_REFRESHRATES) {
2191 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2192 ddsfd.x.dwRefreshRate = 60;
2195 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2196 ddsfd.dwBackBufferCount = 1;
2197 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2198 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2199 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2200 /* FIXME: those masks would have to be set in depth > 8 */
2201 if (depths[i]==8) {
2202 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2203 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2204 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2205 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2206 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2207 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2208 } else {
2209 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2211 /* FIXME: We should query those from X itself */
2212 switch (depths[i]) {
2213 case 16:
2214 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2215 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2216 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2217 break;
2218 case 24:
2219 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2220 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2221 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2222 break;
2223 case 32:
2224 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2225 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2226 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2227 break;
2231 ddsfd.dwWidth = screenWidth;
2232 ddsfd.dwHeight = screenHeight;
2233 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2234 if (!modescb(&ddsfd,context)) return 0;
2236 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2237 ddsfd.dwWidth = modes[j].w;
2238 ddsfd.dwHeight = modes[j].h;
2239 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2240 if (!modescb(&ddsfd,context)) return 0;
2243 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2244 /* modeX is not standard VGA */
2246 ddsfd.dwHeight = 200;
2247 ddsfd.dwWidth = 320;
2248 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2249 if (!modescb(&ddsfd,context)) return 0;
2252 return DD_OK;
2255 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2256 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2258 #ifdef HAVE_LIBXXF86DGA
2259 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2260 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2261 lpddsfd->dwHeight = screenHeight;
2262 lpddsfd->dwWidth = screenWidth;
2263 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2264 lpddsfd->dwBackBufferCount = 1;
2265 lpddsfd->x.dwRefreshRate = 60;
2266 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2267 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2268 return DD_OK;
2269 #else /* defined(HAVE_LIBXXF86DGA) */
2270 return E_UNEXPECTED;
2271 #endif /* defined(HAVE_LIBXXF86DGA) */
2274 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2275 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2277 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2278 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2279 lpddsfd->dwHeight = screenHeight;
2280 lpddsfd->dwWidth = screenWidth;
2281 /* POOLE FIXME: Xlib */
2282 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2283 /* END FIXME: Xlib */
2284 lpddsfd->dwBackBufferCount = 1;
2285 lpddsfd->x.dwRefreshRate = 60;
2286 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2287 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2288 return DD_OK;
2291 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2292 TRACE(ddraw,"(%p)->()\n",this);
2293 return DD_OK;
2296 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2297 LPDIRECTDRAW2 this,LPDWORD freq
2299 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2300 *freq = 60*100; /* 60 Hz */
2301 return 0;
2304 /* what can we directly decompress? */
2305 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2306 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2308 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2309 return 0;
2312 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2313 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2315 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2316 return 0;
2319 static HRESULT WINAPI IDirectDraw2_Compact(
2320 LPDIRECTDRAW2 this )
2322 FIXME(ddraw,"(%p)->()\n", this );
2324 return DD_OK;
2328 /* Note: Hack so we can reuse the old functions without compiler warnings */
2329 #ifdef __GNUC__
2330 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2331 #else
2332 # define XCAST(fun) (void*)
2333 #endif
2335 static struct IDirectDraw_VTable dga_ddvt = {
2336 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2337 XCAST(AddRef)IDirectDraw2_AddRef,
2338 XCAST(Release)DGA_IDirectDraw2_Release,
2339 XCAST(Compact)IDirectDraw2_Compact,
2340 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2341 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2342 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2343 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2344 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2345 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2346 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2347 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2348 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2349 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2350 XCAST(GetGDISurface)15,
2351 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2352 XCAST(GetScanLine)17,
2353 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2354 XCAST(Initialize)19,
2355 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2356 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2357 DGA_IDirectDraw_SetDisplayMode,
2358 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2361 static struct IDirectDraw_VTable xlib_ddvt = {
2362 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2363 XCAST(AddRef)IDirectDraw2_AddRef,
2364 XCAST(Release)Xlib_IDirectDraw2_Release,
2365 XCAST(Compact)IDirectDraw2_Compact,
2366 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2367 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2368 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2369 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2370 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2371 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2372 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2373 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2374 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2375 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2376 XCAST(GetGDISurface)15,
2377 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2378 XCAST(GetScanLine)17,
2379 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2380 XCAST(Initialize)19,
2381 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2382 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2383 Xlib_IDirectDraw_SetDisplayMode,
2384 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2387 /*****************************************************************************
2388 * IDirectDraw2
2393 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2394 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2396 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2399 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2400 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2402 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2405 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2406 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2408 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2409 this,ddscaps,total,free
2411 if (total) *total = this->e.dga.fb_memsize * 1024;
2412 if (free) *free = this->e.dga.fb_memsize * 1024;
2413 return 0;
2416 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2417 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2419 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2420 this,ddscaps,total,free
2422 if (total) *total = 2048 * 1024;
2423 if (free) *free = 2048 * 1024;
2424 return 0;
2427 static IDirectDraw2_VTable dga_dd2vt = {
2428 DGA_IDirectDraw2_QueryInterface,
2429 IDirectDraw2_AddRef,
2430 DGA_IDirectDraw2_Release,
2431 IDirectDraw2_Compact,
2432 IDirectDraw2_CreateClipper,
2433 DGA_IDirectDraw2_CreatePalette,
2434 DGA_IDirectDraw2_CreateSurface,
2435 (void*)8,
2436 IDirectDraw2_EnumDisplayModes,
2437 IDirectDraw2_EnumSurfaces,
2438 IDirectDraw2_FlipToGDISurface,
2439 DGA_IDirectDraw2_GetCaps,
2440 DGA_IDirectDraw2_GetDisplayMode,
2441 IDirectDraw2_GetFourCCCodes,
2442 (void*)15,
2443 IDirectDraw2_GetMonitorFrequency,
2444 (void*)17,
2445 IDirectDraw2_GetVerticalBlankStatus,
2446 (void*)19,
2447 DGA_IDirectDraw2_RestoreDisplayMode,
2448 IDirectDraw2_SetCooperativeLevel,
2449 DGA_IDirectDraw2_SetDisplayMode,
2450 IDirectDraw2_WaitForVerticalBlank,
2451 DGA_IDirectDraw2_GetAvailableVidMem
2454 static struct IDirectDraw2_VTable xlib_dd2vt = {
2455 Xlib_IDirectDraw2_QueryInterface,
2456 IDirectDraw2_AddRef,
2457 Xlib_IDirectDraw2_Release,
2458 IDirectDraw2_Compact,
2459 IDirectDraw2_CreateClipper,
2460 Xlib_IDirectDraw2_CreatePalette,
2461 Xlib_IDirectDraw2_CreateSurface,
2462 (void*)8,
2463 IDirectDraw2_EnumDisplayModes,
2464 IDirectDraw2_EnumSurfaces,
2465 IDirectDraw2_FlipToGDISurface,
2466 Xlib_IDirectDraw2_GetCaps,
2467 Xlib_IDirectDraw2_GetDisplayMode,
2468 IDirectDraw2_GetFourCCCodes,
2469 (void*)15,
2470 IDirectDraw2_GetMonitorFrequency,
2471 (void*)17,
2472 IDirectDraw2_GetVerticalBlankStatus,
2473 (void*)19,
2474 Xlib_IDirectDraw2_RestoreDisplayMode,
2475 IDirectDraw2_SetCooperativeLevel,
2476 Xlib_IDirectDraw2_SetDisplayMode,
2477 IDirectDraw2_WaitForVerticalBlank,
2478 Xlib_IDirectDraw2_GetAvailableVidMem
2481 /******************************************************************************
2482 * DirectDrawCreate
2485 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2487 LRESULT ret;
2488 LPDIRECTDRAW ddraw = NULL;
2489 DWORD lastError;
2491 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2493 SetLastError( ERROR_SUCCESS );
2494 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2495 if( (!ddraw) &&
2496 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2499 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2502 if( ddraw )
2504 /* Perform any special direct draw functions */
2505 if (msg==WM_PAINT)
2506 ddraw->e.xlib.paintable = 1;
2508 /* Now let the application deal with the rest of this */
2509 if( ddraw->d.mainWindow )
2512 /* Don't think that we actually need to call this but...
2513 might as well be on the safe side of things... */
2515 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
2516 it should be the procedures of our fake window that gets called
2517 instead of those of the window provided by the application.
2518 And with this patch, mouse clicks work with Monkey Island III
2519 - Lionel */
2520 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2522 if( !ret )
2524 /* We didn't handle the message - give it to the application */
2525 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
2526 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2527 ddraw->d.mainWindow, msg, wParam, lParam );
2532 else
2534 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
2538 else
2540 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2543 return ret;
2546 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2547 #ifdef HAVE_LIBXXF86DGA
2548 int memsize,banksize,width,major,minor,flags,height;
2549 char *addr;
2551 if (getuid() != 0) {
2552 MSG("Must be root to use XF86DGA!\n");
2553 MessageBox32A(0,"Using the XF86DGA extension requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2554 return E_UNEXPECTED;
2556 if (!DDRAW_DGA_Available()) {
2557 TRACE(ddraw,"No XF86DGA detected.\n");
2558 return DDERR_GENERIC;
2560 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2561 (*lplpDD)->lpvtbl = &dga_ddvt;
2562 (*lplpDD)->ref = 1;
2563 TSXF86DGAQueryVersion(display,&major,&minor);
2564 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2565 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2566 if (!(flags & XF86DGADirectPresent))
2567 MSG("direct video is NOT PRESENT.\n");
2568 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2569 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2570 addr,width,banksize,memsize
2572 (*lplpDD)->e.dga.fb_width = width;
2573 (*lplpDD)->d.width = width;
2574 (*lplpDD)->e.dga.fb_addr = addr;
2575 (*lplpDD)->e.dga.fb_memsize = memsize;
2576 (*lplpDD)->e.dga.fb_banksize = banksize;
2578 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2579 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2580 (*lplpDD)->e.dga.fb_height = screenHeight;
2581 #ifdef DIABLO_HACK
2582 (*lplpDD)->e.dga.vpmask = 1;
2583 #else
2584 (*lplpDD)->e.dga.vpmask = 0;
2585 #endif
2587 /* just assume the default depth is the DGA depth too */
2588 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2589 #ifdef RESTORE_SIGNALS
2590 SIGNAL_InitEmulator();
2591 #endif
2593 return 0;
2594 #else /* defined(HAVE_LIBXXF86DGA) */
2595 return DDERR_INVALIDDIRECTDRAWGUID;
2596 #endif /* defined(HAVE_LIBXXF86DGA) */
2599 BOOL32
2600 DDRAW_XSHM_Available()
2602 #ifdef HAVE_LIBXXSHM
2603 if (TSXShmQueryExtension(display))
2605 int major, minor;
2606 Bool shpix;
2608 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
2609 return 1;
2610 else
2611 return 0;
2613 else
2614 return 0;
2615 #else
2616 return 0;
2617 #endif
2620 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2622 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2623 (*lplpDD)->lpvtbl = &xlib_ddvt;
2624 (*lplpDD)->ref = 1;
2625 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
2627 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2628 (*lplpDD)->d.height = screenHeight;
2629 (*lplpDD)->d.width = screenWidth;
2631 #ifdef HAVE_LIBXXSHM
2632 /* Test if XShm is available.
2633 As XShm is not ready yet for 'prime-time', it is disabled for now */
2634 if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
2635 TRACE(ddraw, "Using XShm extesion.\n");
2636 #endif
2638 return 0;
2641 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
2642 char xclsid[50];
2643 WNDCLASS32A wc;
2644 WND* pParentWindow;
2645 HRESULT ret;
2647 if (HIWORD(lpGUID))
2648 WINE_StringFromCLSID(lpGUID,xclsid);
2649 else {
2650 sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID);
2651 lpGUID = NULL;
2654 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
2656 if (!lpGUID) {
2657 /* if they didn't request a particular interface, use the best
2658 * supported one */
2659 if (DDRAW_DGA_Available())
2660 lpGUID = &DGA_DirectDraw_GUID;
2661 else
2662 lpGUID = &XLIB_DirectDraw_GUID;
2665 wc.style = CS_GLOBALCLASS;
2666 wc.lpfnWndProc = Xlib_DDWndProc;
2667 wc.cbClsExtra = 0;
2668 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
2669 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
2671 /* We can be a child of the desktop since we're really important */
2672 pParentWindow = WIN_GetDesktop();
2673 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
2674 wc.hInstance = 0;
2676 wc.hIcon = 0;
2677 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
2678 wc.hbrBackground= NULL_BRUSH;
2679 wc.lpszMenuName = 0;
2680 wc.lpszClassName= "WINE_DirectDraw";
2681 RegisterClass32A(&wc);
2683 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
2684 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
2685 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
2686 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
2687 else
2688 goto err;
2690 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
2691 return ret;
2693 err:
2694 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
2695 return DDERR_INVALIDDIRECTDRAWGUID;