Handling for listviewstyles, view mode buttons in filedialogs
[wine/multimedia.git] / graphics / ddraw.c
blob4916df1bc498582f5003994e1420117d00f5f2c9
1 /* DirectDraw using DGA or Xlib
3 * Copyright 1997,1998 Marcus Meissner
4 */
5 /* When DirectVideo mode is enabled you can no longer use 'normal' X
6 * applications nor can you switch to a virtual console. Also, enabling
7 * only works, if you have switched to the screen where the application
8 * is running.
9 * Some ways to debug this stuff are:
10 * - A terminal connected to the serial port. Can be bought used for cheap.
11 * (This is the method I am using.)
12 * - Another machine connected over some kind of network.
14 * FIXME: The Xshm implementation has been temporarily removed. It will be
15 * later reintegrated into the Xlib implementation.
18 #include "config.h"
19 #include <unistd.h>
20 #include <assert.h>
21 #include "ts_xlib.h"
22 #include <sys/signal.h>
24 #include "windows.h"
25 #include "winerror.h"
26 #include "interfaces.h"
27 #include "gdi.h"
28 #include "heap.h"
29 #include "ldt.h"
30 #include "dc.h"
31 #include "win.h"
32 #include "miscemu.h"
33 #include "ddraw.h"
34 #include "d3d.h"
35 #include "debug.h"
36 #include "compobj.h"
37 #include "spy.h"
38 #include "message.h"
40 #ifdef HAVE_LIBXXF86DGA
41 #include "ts_xf86dga.h"
42 #endif
44 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
45 #undef DIABLO_HACK
47 /* restore signal handlers overwritten by XF86DGA
48 * this is a define, for it will only work in emulator mode
50 #undef RESTORE_SIGNALS
52 /* Where do these GUIDs come from? mkuuid.
53 * They exist solely to distinguish between the targets Wine support,
54 * and should be different than any other GUIDs in existence.
56 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
57 0xe2dcb020,
58 0xdc60,
59 0x11d1,
60 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
63 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
64 0x1574a740,
65 0xdc61,
66 0x11d1,
67 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
70 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
71 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
72 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
73 static struct IDirectDrawClipper_VTable ddclipvt;
74 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
75 static struct IDirect3D_VTable d3dvt;
76 static struct IDirect3D2_VTable d3d2vt;
78 BOOL32
79 DDRAW_DGA_Available()
81 #ifdef HAVE_LIBXXF86DGA
82 int evbase, evret;
83 return (getuid() == 0)&&TSXF86DGAQueryExtension(display,&evbase,&evret);
84 #else /* defined(HAVE_LIBXXF86DGA) */
85 return 0;
86 #endif /* defined(HAVE_LIBXXF86DGA) */
89 HRESULT WINAPI
90 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
91 if (DDRAW_DGA_Available()) {
92 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
94 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
95 ddenumproc(NULL,"WINE","display",data);
96 return 0;
99 /* What is this doing here? */
100 HRESULT WINAPI
101 DSoundHelp(DWORD x,DWORD y,DWORD z) {
102 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
103 return 0;
107 /******************************************************************************
108 * internal helper functions
110 static void _dump_DDBLTFX(DWORD flagmask) {
111 int i;
112 const struct {
113 DWORD mask;
114 char *name;
115 } flags[] = {
116 #define FE(x) { x, #x},
117 FE(DDBLTFX_ARITHSTRETCHY)
118 FE(DDBLTFX_MIRRORLEFTRIGHT)
119 FE(DDBLTFX_MIRRORUPDOWN)
120 FE(DDBLTFX_NOTEARING)
121 FE(DDBLTFX_ROTATE180)
122 FE(DDBLTFX_ROTATE270)
123 FE(DDBLTFX_ROTATE90)
124 FE(DDBLTFX_ZBUFFERRANGE)
125 FE(DDBLTFX_ZBUFFERBASEDEST)
127 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
128 if (flags[i].mask & flagmask) {
129 DUMP("%s ",flags[i].name);
132 DUMP("\n");
136 static void _dump_DDBLTFAST(DWORD flagmask) {
137 int i;
138 const struct {
139 DWORD mask;
140 char *name;
141 } flags[] = {
142 #define FE(x) { x, #x},
143 FE(DDBLTFAST_NOCOLORKEY)
144 FE(DDBLTFAST_SRCCOLORKEY)
145 FE(DDBLTFAST_DESTCOLORKEY)
146 FE(DDBLTFAST_WAIT)
148 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
149 if (flags[i].mask & flagmask)
150 DUMP("%s ",flags[i].name);
151 DUMP("\n");
154 static void _dump_DDBLT(DWORD flagmask) {
155 int i;
156 const struct {
157 DWORD mask;
158 char *name;
159 } flags[] = {
160 #define FE(x) { x, #x},
161 FE(DDBLT_ALPHADEST)
162 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
163 FE(DDBLT_ALPHADESTNEG)
164 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
165 FE(DDBLT_ALPHAEDGEBLEND)
166 FE(DDBLT_ALPHASRC)
167 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
168 FE(DDBLT_ALPHASRCNEG)
169 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
170 FE(DDBLT_ASYNC)
171 FE(DDBLT_COLORFILL)
172 FE(DDBLT_DDFX)
173 FE(DDBLT_DDROPS)
174 FE(DDBLT_KEYDEST)
175 FE(DDBLT_KEYDESTOVERRIDE)
176 FE(DDBLT_KEYSRC)
177 FE(DDBLT_KEYSRCOVERRIDE)
178 FE(DDBLT_ROP)
179 FE(DDBLT_ROTATIONANGLE)
180 FE(DDBLT_ZBUFFER)
181 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
182 FE(DDBLT_ZBUFFERDESTOVERRIDE)
183 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
184 FE(DDBLT_ZBUFFERSRCOVERRIDE)
185 FE(DDBLT_WAIT)
186 FE(DDBLT_DEPTHFILL)
188 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
189 if (flags[i].mask & flagmask)
190 DUMP("%s ",flags[i].name);
193 static void _dump_DDSCAPS(DWORD flagmask) {
194 int i;
195 const struct {
196 DWORD mask;
197 char *name;
198 } flags[] = {
199 #define FE(x) { x, #x},
200 FE(DDSCAPS_RESERVED1)
201 FE(DDSCAPS_ALPHA)
202 FE(DDSCAPS_BACKBUFFER)
203 FE(DDSCAPS_COMPLEX)
204 FE(DDSCAPS_FLIP)
205 FE(DDSCAPS_FRONTBUFFER)
206 FE(DDSCAPS_OFFSCREENPLAIN)
207 FE(DDSCAPS_OVERLAY)
208 FE(DDSCAPS_PALETTE)
209 FE(DDSCAPS_PRIMARYSURFACE)
210 FE(DDSCAPS_PRIMARYSURFACELEFT)
211 FE(DDSCAPS_SYSTEMMEMORY)
212 FE(DDSCAPS_TEXTURE)
213 FE(DDSCAPS_3DDEVICE)
214 FE(DDSCAPS_VIDEOMEMORY)
215 FE(DDSCAPS_VISIBLE)
216 FE(DDSCAPS_WRITEONLY)
217 FE(DDSCAPS_ZBUFFER)
218 FE(DDSCAPS_OWNDC)
219 FE(DDSCAPS_LIVEVIDEO)
220 FE(DDSCAPS_HWCODEC)
221 FE(DDSCAPS_MODEX)
222 FE(DDSCAPS_MIPMAP)
223 FE(DDSCAPS_RESERVED2)
224 FE(DDSCAPS_ALLOCONLOAD)
225 FE(DDSCAPS_VIDEOPORT)
226 FE(DDSCAPS_LOCALVIDMEM)
227 FE(DDSCAPS_NONLOCALVIDMEM)
228 FE(DDSCAPS_STANDARDVGAMODE)
229 FE(DDSCAPS_OPTIMIZED)
231 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
232 if (flags[i].mask & flagmask)
233 DUMP("%s ",flags[i].name);
234 DUMP("\n");
237 static void _dump_DDSD(DWORD flagmask) {
238 int i;
239 const struct {
240 DWORD mask;
241 char *name;
242 } flags[] = {
243 FE(DDSD_CAPS)
244 FE(DDSD_HEIGHT)
245 FE(DDSD_WIDTH)
246 FE(DDSD_PITCH)
247 FE(DDSD_BACKBUFFERCOUNT)
248 FE(DDSD_ZBUFFERBITDEPTH)
249 FE(DDSD_ALPHABITDEPTH)
250 FE(DDSD_PIXELFORMAT)
251 FE(DDSD_CKDESTOVERLAY)
252 FE(DDSD_CKDESTBLT)
253 FE(DDSD_CKSRCOVERLAY)
254 FE(DDSD_CKSRCBLT)
255 FE(DDSD_MIPMAPCOUNT)
256 FE(DDSD_REFRESHRATE)
257 FE(DDSD_LINEARSIZE)
258 FE(DDSD_LPSURFACE)
260 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
261 if (flags[i].mask & flagmask)
262 DUMP("%s ",flags[i].name);
263 DUMP("\n");
266 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
267 static XVisualInfo *vi;
268 XVisualInfo vt;
269 int nitems;
271 if (!vi)
272 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
274 pf->dwFourCC = 0;
275 if (ddraw->d.depth==8) {
276 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
277 pf->x.dwRGBBitCount = 8;
278 pf->y.dwRBitMask = 0;
279 pf->z.dwGBitMask = 0;
280 pf->xx.dwBBitMask = 0;
281 pf->xy.dwRGBAlphaBitMask= 0;
282 return 0;
284 if (ddraw->d.depth==16) {
285 pf->dwFlags = DDPF_RGB;
286 pf->x.dwRGBBitCount = 16;
287 pf->y.dwRBitMask = vi[0].red_mask;
288 pf->z.dwGBitMask = vi[0].green_mask;
289 pf->xx.dwBBitMask = vi[0].blue_mask;
290 pf->xy.dwRGBAlphaBitMask= 0;
291 return 0;
293 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
294 return DDERR_GENERIC;
297 /******************************************************************************
298 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
300 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
301 * DDS and DDS2 use those functions. (Function calls did not change (except
302 * using different DirectDrawSurfaceX version), just added flags and functions)
304 static HRESULT WINAPI IDirectDrawSurface3_Lock(
305 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
307 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
308 this,lprect,lpddsd,flags,(DWORD)hnd);
309 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
310 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
311 this,lprect,lpddsd,flags,(DWORD)hnd);
313 if (lprect) {
314 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
315 lprect->top,lprect->left,lprect->bottom,lprect->right
317 lpddsd->y.lpSurface = this->s.surface +
318 (lprect->top*this->s.lpitch) +
319 (lprect->left*(this->s.ddraw->d.depth/8));
320 } else {
321 assert(this->s.surface);
322 lpddsd->y.lpSurface = this->s.surface;
324 lpddsd->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_LPSURFACE;
325 lpddsd->dwWidth = this->s.width;
326 lpddsd->dwHeight = this->s.height;
327 lpddsd->lPitch = this->s.lpitch;
328 _getpixelformat(this->s.ddraw,&(lpddsd->ddpfPixelFormat));
329 return 0;
332 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
333 LPDIRECTDRAWSURFACE3 this,LPVOID surface
335 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
336 return 0;
339 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
340 LPDIRECTDRAWSURFACE3 this,LPVOID surface)
342 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
344 if (!this->s.ddraw->e.xlib.paintable)
345 return DD_OK;
347 /* Only redraw the screen when unlocking the buffer that is on screen */
348 if ((this->t.xlib.image != NULL) && (this->t.xlib.on_screen))
349 TSXPutImage( display,
350 this->s.ddraw->e.xlib.drawable,
351 DefaultGCOfScreen(screen),
352 this->t.xlib.image,
353 0, 0, 0, 0,
354 this->t.xlib.image->width,
355 this->t.xlib.image->height);
357 if (this->s.palette && this->s.palette->cm)
358 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
360 return DD_OK;
363 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
364 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
366 #ifdef HAVE_LIBXXF86DGA
367 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
368 if (!flipto) {
369 if (this->s.backbuffer)
370 flipto = this->s.backbuffer;
371 else
372 flipto = this;
374 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
376 if (flipto->s.palette && flipto->s.palette->cm) {
377 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
379 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
381 if (flipto!=this) {
382 int tmp;
383 LPVOID ptmp;
385 tmp = this->t.dga.fb_height;
386 this->t.dga.fb_height = flipto->t.dga.fb_height;
387 flipto->t.dga.fb_height = tmp;
389 ptmp = this->s.surface;
390 this->s.surface = flipto->s.surface;
391 flipto->s.surface = ptmp;
393 return 0;
394 #else /* defined(HAVE_LIBXXF86DGA) */
395 return E_UNEXPECTED;
396 #endif /* defined(HAVE_LIBXXF86DGA) */
399 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
400 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
402 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
403 if (!this->s.ddraw->e.xlib.paintable)
404 return 0;
406 if (!flipto) {
407 if (this->s.backbuffer)
408 flipto = this->s.backbuffer;
409 else
410 flipto = this;
413 TSXPutImage(display,
414 this->s.ddraw->e.xlib.drawable,
415 DefaultGCOfScreen(screen),
416 flipto->t.xlib.image,
417 0, 0, 0, 0,
418 flipto->t.xlib.image->width,
419 flipto->t.xlib.image->height);
420 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
421 if (flipto!=this) {
422 XImage *tmp;
423 LPVOID *surf;
424 tmp = this->t.xlib.image;
425 this->t.xlib.image = flipto->t.xlib.image;
426 flipto->t.xlib.image = tmp;
427 surf = this->s.surface;
428 this->s.surface = flipto->s.surface;
429 flipto->s.surface = surf;
431 flipto->t.xlib.on_screen = TRUE;
432 this->t.xlib.on_screen = FALSE;
434 return 0;
437 /* The IDirectDrawSurface3::SetPalette method attaches the specified
438 * DirectDrawPalette object to a surface. The surface uses this palette for all
439 * subsequent operations. The palette change takes place immediately.
441 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
442 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
444 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
445 /* According to spec, we are only supposed to
446 * AddRef if this is not the same palette.
448 if( this->s.palette != pal )
450 if( pal != NULL )
451 pal->lpvtbl->fnAddRef( pal );
452 if( this->s.palette != NULL )
453 this->s.palette->lpvtbl->fnRelease( this->s.palette );
454 this->s.palette = pal;
456 /* I think that we need to attach it to all backbuffers...*/
457 if( this->s.backbuffer ) {
458 if( this->s.backbuffer->s.palette )
459 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
460 this->s.backbuffer->s.palette );
461 this->s.backbuffer->s.palette = pal;
462 if( pal )
463 pal->lpvtbl->fnAddRef( pal );
466 /* Perform the refresh */
467 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
470 return 0;
473 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
474 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
476 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
477 #ifdef HAVE_LIBXXF86DGA
478 /* According to spec, we are only supposed to
479 * AddRef if this is not the same palette.
481 if( this->s.palette != pal )
483 if( pal != NULL )
484 pal->lpvtbl->fnAddRef( pal );
485 if( this->s.palette != NULL )
486 this->s.palette->lpvtbl->fnRelease( this->s.palette );
487 this->s.palette = pal;
489 /* I think that we need to attach it to all backbuffers...*/
490 if( this->s.backbuffer ) {
491 if( this->s.backbuffer->s.palette )
492 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
493 this->s.backbuffer->s.palette = pal;
494 if( pal ) pal->lpvtbl->fnAddRef( pal );
496 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
498 return 0;
499 #else /* defined(HAVE_LIBXXF86DGA) */
500 return E_UNEXPECTED;
501 #endif /* defined(HAVE_LIBXXF86DGA) */
506 static HRESULT WINAPI IDirectDrawSurface3_Blt(
507 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
509 RECT32 xdst,xsrc;
510 int i,j;
512 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
513 this,rdst,src,rsrc,dwFlags,lpbltfx);
514 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
515 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
516 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
517 if (dwFlags & DDBLT_DDFX) {
518 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
521 if (rdst) {
522 memcpy(&xdst,rdst,sizeof(xdst));
523 } else {
524 xdst.top = 0;
525 xdst.bottom = this->s.height;
526 xdst.left = 0;
527 xdst.right = this->s.width;
530 if (rsrc) {
531 memcpy(&xsrc,rsrc,sizeof(xsrc));
532 } else if (src) {
533 xsrc.top = 0;
534 xsrc.bottom = src->s.height;
535 xsrc.left = 0;
536 xsrc.right = src->s.width;
539 if (dwFlags & DDBLT_COLORFILL) {
540 int bpp = this->s.ddraw->d.depth/8;
541 LPBYTE xline,xpixel;
543 xline = (LPBYTE)this->s.surface+xdst.top*this->s.lpitch;
544 for (i=xdst.top;i<xdst.bottom;i++) {
545 xpixel = xline+bpp*xdst.left;
547 for (j=xdst.left;j<xdst.right;j++) {
548 /* FIXME: this only works on little endian
549 * architectures, where DWORD starts with low
550 * byte first!
552 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
553 xpixel += bpp;
555 xline += this->s.lpitch;
557 dwFlags &= ~(DDBLT_COLORFILL);
559 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
560 if ( (xsrc.top ==0) && (xsrc.bottom ==this->s.height) &&
561 (xsrc.left==0) && (xsrc.right ==this->s.width) &&
562 (xdst.top ==0) && (xdst.bottom ==this->s.height) &&
563 (xdst.left==0) && (xdst.right ==this->s.width) &&
564 !dwFlags
566 memcpy(this->s.surface,src->s.surface,this->s.height*this->s.lpitch);
567 return 0;
568 } else {
569 /* Non full screen Blit. In this case, we need to copy line per line.
570 WARNING : if the program behaves badly (ie sizes of structures are different
571 or buffer not big enough) this may crash Wine... */
572 int bpp = this->s.ddraw->d.depth / 8;
573 int height = xsrc.bottom - xsrc.top;
574 int width = (xsrc.right - xsrc.left) * bpp;
575 int h;
577 for (h = 0; h < height; h++) {
578 memcpy(this->s.surface + ((h + xdst.top) * this->s.lpitch) + xdst.left * bpp,
579 src->s.surface + ((h + xsrc.top) * src->s.lpitch) + xsrc.left * bpp,
580 width);
584 if (dwFlags) {
585 TRACE(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
588 return 0;
591 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Blt(
592 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
594 HRESULT ret;
596 /* First, call the "common" blit function */
597 ret = IDirectDrawSurface3_Blt(this, rdst, src, rsrc, dwFlags, lpbltfx);
599 /* Then put the result on screen if blited on main screen buffer */
600 if (!this->s.ddraw->e.xlib.paintable)
601 return ret;
603 if ((this->t.xlib.image != NULL) && (this->t.xlib.on_screen))
604 TSXPutImage(display,
605 this->s.ddraw->e.xlib.drawable,
606 DefaultGCOfScreen(screen),
607 this->t.xlib.image,
608 0, 0, 0, 0,
609 this->t.xlib.image->width,
610 this->t.xlib.image->height);
611 if (this->s.palette && this->s.palette->cm)
612 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
614 return ret;
617 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
618 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
620 int i,bpp;
621 if (TRACE_ON(ddraw)) {
622 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx),stub!\n",
623 this,dstx,dsty,src,rsrc,trans
625 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
626 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
628 bpp = this->s.ddraw->d.depth/8;
629 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
630 memcpy( this->s.surface+((i+dsty)*this->s.width*bpp)+dstx*bpp,
631 src->s.surface +(rsrc->top+i)*src->s.width*bpp+rsrc->left*bpp,
632 (rsrc->right-rsrc->left)*bpp
635 return 0;
638 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
639 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
641 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
642 this,ddbltbatch,x,y
644 return 0;
647 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
648 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
650 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
651 caps->dwCaps = DDCAPS_PALETTE; /* probably more */
652 return 0;
655 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
656 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
657 ) {
658 if (TRACE_ON(ddraw)) {
659 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
660 this,ddsd);
661 fprintf(stderr," flags: ");
662 _dump_DDSD(ddsd->dwFlags);
663 fprintf(stderr,"\n");
666 ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
667 ddsd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
668 ddsd->dwBackBufferCount = 1;
669 ddsd->dwHeight = this->s.height;
670 ddsd->dwWidth = this->s.width;
671 ddsd->lPitch = this->s.lpitch;
672 if (this->s.backbuffer)
673 ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
674 _getpixelformat(this->s.ddraw,&(ddsd->ddpfPixelFormat));
676 return 0;
679 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
680 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
682 return ++(this->ref);
685 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
686 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
688 #ifdef HAVE_LIBXXF86DGA
689 if (!--(this->ref)) {
690 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
691 /* clear out of surface list */
692 if (this->t.dga.fb_height == -1) {
693 HeapFree(GetProcessHeap(),0,this->s.surface);
694 } else {
695 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
697 HeapFree(GetProcessHeap(),0,this);
698 return 0;
700 #endif /* defined(HAVE_LIBXXF86DGA) */
701 return this->ref;
704 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
705 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
707 if (!--(this->ref)) {
708 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
709 HeapFree(GetProcessHeap(),0,this->s.surface);
711 if( this->s.backbuffer )
713 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
716 if (this->t.xlib.image != NULL) {
717 this->t.xlib.image->data = NULL;
718 TSXDestroyImage(this->t.xlib.image);
719 this->t.xlib.image = 0;
722 if (this->s.palette)
723 this->s.palette->lpvtbl->fnRelease(this->s.palette);
726 HeapFree(GetProcessHeap(),0,this);
727 return 0;
729 return this->ref;
732 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
733 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
735 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
736 this, lpddsd, lpdsf);
738 if (TRACE_ON(ddraw)) {
739 TRACE(ddraw," caps ");
740 _dump_DDSCAPS(lpddsd->dwCaps);
743 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
744 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
745 return E_FAIL;
748 /* FIXME: should handle more than one backbuffer */
749 *lpdsf = this->s.backbuffer;
751 if( this->s.backbuffer )
753 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
756 return 0;
759 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
760 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
762 return DDERR_ALREADYINITIALIZED;
765 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
766 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
768 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
769 return _getpixelformat(this->s.ddraw,pf);
772 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
773 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
774 return 0;
777 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
778 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
780 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
781 return 0;
784 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
785 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
787 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
788 return 0;
791 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
792 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
794 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
795 this->s.backbuffer = surf;
796 return 0;
799 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
800 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
801 *lphdc = BeginPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps);
802 return 0;
805 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
806 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
807 EndPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps);
808 return 0;
812 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
813 char xrefiid[50];
815 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
816 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
818 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
819 * the same interface. And IUnknown does that too of course.
821 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
822 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
823 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
824 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
826 *obj = this;
827 this->lpvtbl->fnAddRef(this);
828 return 0;
830 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
831 return OLE_E_ENUM_NOMORE;
834 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
835 TRACE(ddraw,"(%p)->(), stub!\n",this);
836 return 0; /* hmm */
839 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
840 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
841 return 0;
844 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
845 FIXME(ddraw,"(%p)->(),stub!\n",this);
846 return 0;
849 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
850 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
852 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
854 if( dwFlags & DDCKEY_SRCBLT )
855 dwFlags &= ~DDCKEY_SRCBLT;
856 if( dwFlags )
857 TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
858 return DD_OK;
861 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
862 LPDIRECTDRAWSURFACE3 this,
863 LPRECT32 lpRect )
865 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
867 return DD_OK;
870 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
871 LPDIRECTDRAWSURFACE3 this,
872 DWORD dwFlags,
873 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
875 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
877 return DD_OK;
880 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
881 LPDIRECTDRAWSURFACE3 this,
882 DWORD dwFlags,
883 LPVOID lpContext,
884 LPDDENUMSURFACESCALLBACK lpfnCallback )
886 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
887 lpContext, lpfnCallback );
889 return DD_OK;
892 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
893 LPDIRECTDRAWSURFACE3 this,
894 LPDIRECTDRAWCLIPPER* lplpDDClipper )
896 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
898 return DD_OK;
901 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
902 LPDIRECTDRAWSURFACE3 this,
903 DWORD dwFlags,
904 LPDDCOLORKEY lpDDColorKey )
906 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDColorKey);
908 return DD_OK;
911 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
912 LPDIRECTDRAWSURFACE3 this,
913 DWORD dwFlags )
915 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
917 return DD_OK;
920 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
921 LPDIRECTDRAWSURFACE3 this,
922 LPDIRECTDRAWPALETTE* lplpDDPalette )
924 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
926 return DD_OK;
929 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
930 LPDIRECTDRAWSURFACE3 this,
931 LONG lX,
932 LONG lY)
934 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
936 return DD_OK;
939 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
940 LPDIRECTDRAWSURFACE3 this,
941 LPRECT32 lpSrcRect,
942 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
943 LPRECT32 lpDestRect,
944 DWORD dwFlags,
945 LPDDOVERLAYFX lpDDOverlayFx )
947 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
948 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
950 return DD_OK;
953 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
954 LPDIRECTDRAWSURFACE3 this,
955 DWORD dwFlags )
957 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
959 return DD_OK;
962 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
963 LPDIRECTDRAWSURFACE3 this,
964 DWORD dwFlags,
965 LPDIRECTDRAWSURFACE3 lpDDSReference )
967 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
969 return DD_OK;
972 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
973 LPDIRECTDRAWSURFACE3 this,
974 LPVOID* lplpDD )
976 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
978 return DD_OK;
981 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
982 LPDIRECTDRAWSURFACE3 this,
983 DWORD dwFlags )
985 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
987 return DD_OK;
990 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
991 LPDIRECTDRAWSURFACE3 this,
992 DWORD dwFlags )
994 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
996 return DD_OK;
999 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1000 LPDIRECTDRAWSURFACE3 this,
1001 LPDDSURFACEDESC lpDDSD,
1002 DWORD dwFlags )
1004 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1006 return DD_OK;
1009 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1010 IDirectDrawSurface3_QueryInterface,
1011 IDirectDrawSurface3_AddRef,
1012 DGA_IDirectDrawSurface3_Release,
1013 IDirectDrawSurface3_AddAttachedSurface,
1014 IDirectDrawSurface3_AddOverlayDirtyRect,
1015 IDirectDrawSurface3_Blt,
1016 IDirectDrawSurface3_BltBatch,
1017 IDirectDrawSurface3_BltFast,
1018 IDirectDrawSurface3_DeleteAttachedSurface,
1019 IDirectDrawSurface3_EnumAttachedSurfaces,
1020 IDirectDrawSurface3_EnumOverlayZOrders,
1021 DGA_IDirectDrawSurface3_Flip,
1022 IDirectDrawSurface3_GetAttachedSurface,
1023 IDirectDrawSurface3_GetBltStatus,
1024 IDirectDrawSurface3_GetCaps,
1025 IDirectDrawSurface3_GetClipper,
1026 IDirectDrawSurface3_GetColorKey,
1027 IDirectDrawSurface3_GetDC,
1028 IDirectDrawSurface3_GetFlipStatus,
1029 IDirectDrawSurface3_GetOverlayPosition,
1030 IDirectDrawSurface3_GetPalette,
1031 IDirectDrawSurface3_GetPixelFormat,
1032 IDirectDrawSurface3_GetSurfaceDesc,
1033 IDirectDrawSurface3_Initialize,
1034 IDirectDrawSurface3_IsLost,
1035 IDirectDrawSurface3_Lock,
1036 IDirectDrawSurface3_ReleaseDC,
1037 IDirectDrawSurface3_Restore,
1038 IDirectDrawSurface3_SetClipper,
1039 IDirectDrawSurface3_SetColorKey,
1040 IDirectDrawSurface3_SetOverlayPosition,
1041 DGA_IDirectDrawSurface3_SetPalette,
1042 DGA_IDirectDrawSurface3_Unlock,
1043 IDirectDrawSurface3_UpdateOverlay,
1044 IDirectDrawSurface3_UpdateOverlayDisplay,
1045 IDirectDrawSurface3_UpdateOverlayZOrder,
1046 IDirectDrawSurface3_GetDDInterface,
1047 IDirectDrawSurface3_PageLock,
1048 IDirectDrawSurface3_PageUnlock,
1049 IDirectDrawSurface3_SetSurfaceDesc,
1052 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1053 IDirectDrawSurface3_QueryInterface,
1054 IDirectDrawSurface3_AddRef,
1055 Xlib_IDirectDrawSurface3_Release,
1056 IDirectDrawSurface3_AddAttachedSurface,
1057 IDirectDrawSurface3_AddOverlayDirtyRect,
1058 Xlib_IDirectDrawSurface3_Blt,
1059 IDirectDrawSurface3_BltBatch,
1060 IDirectDrawSurface3_BltFast,
1061 IDirectDrawSurface3_DeleteAttachedSurface,
1062 IDirectDrawSurface3_EnumAttachedSurfaces,
1063 IDirectDrawSurface3_EnumOverlayZOrders,
1064 Xlib_IDirectDrawSurface3_Flip,
1065 IDirectDrawSurface3_GetAttachedSurface,
1066 IDirectDrawSurface3_GetBltStatus,
1067 IDirectDrawSurface3_GetCaps,
1068 IDirectDrawSurface3_GetClipper,
1069 IDirectDrawSurface3_GetColorKey,
1070 IDirectDrawSurface3_GetDC,
1071 IDirectDrawSurface3_GetFlipStatus,
1072 IDirectDrawSurface3_GetOverlayPosition,
1073 IDirectDrawSurface3_GetPalette,
1074 IDirectDrawSurface3_GetPixelFormat,
1075 IDirectDrawSurface3_GetSurfaceDesc,
1076 IDirectDrawSurface3_Initialize,
1077 IDirectDrawSurface3_IsLost,
1078 IDirectDrawSurface3_Lock,
1079 IDirectDrawSurface3_ReleaseDC,
1080 IDirectDrawSurface3_Restore,
1081 IDirectDrawSurface3_SetClipper,
1082 IDirectDrawSurface3_SetColorKey,
1083 IDirectDrawSurface3_SetOverlayPosition,
1084 Xlib_IDirectDrawSurface3_SetPalette,
1085 Xlib_IDirectDrawSurface3_Unlock,
1086 IDirectDrawSurface3_UpdateOverlay,
1087 IDirectDrawSurface3_UpdateOverlayDisplay,
1088 IDirectDrawSurface3_UpdateOverlayZOrder,
1089 IDirectDrawSurface3_GetDDInterface,
1090 IDirectDrawSurface3_PageLock,
1091 IDirectDrawSurface3_PageUnlock,
1092 IDirectDrawSurface3_SetSurfaceDesc,
1095 /******************************************************************************
1096 * IDirectDrawClipper
1098 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1099 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1101 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1102 return 0;
1105 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1106 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1108 this->ref--;
1109 if (this->ref)
1110 return this->ref;
1111 HeapFree(GetProcessHeap(),0,this);
1112 return 0;
1115 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1116 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1118 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1119 if (hmm) *hmm=0;
1120 return 0;
1123 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1124 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1126 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1127 return 0;
1130 static struct IDirectDrawClipper_VTable ddclipvt = {
1131 (void*)1,
1132 (void*)2,
1133 IDirectDrawClipper_Release,
1134 IDirectDrawClipper_GetClipList,
1135 (void*)5,
1136 (void*)6,
1137 (void*)7,
1138 IDirectDrawClipper_SetClipList,
1139 IDirectDrawClipper_SetHwnd
1142 /******************************************************************************
1143 * IDirectDrawPalette
1145 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1146 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1148 int i;
1150 if (!this->cm) /* should not happen */ {
1151 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1152 return DDERR_GENERIC;
1154 for (i=0;i<count;i++) {
1155 palent[i].peRed = this->palents[start+i].peRed;
1156 palent[i].peBlue = this->palents[start+i].peBlue;
1157 palent[i].peGreen = this->palents[start+i].peGreen;
1158 palent[i].peFlags = this->palents[start+i].peFlags;
1161 return 0;
1164 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1165 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1167 XColor xc;
1168 int i;
1170 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1171 this,x,start,count,palent
1173 if (!this->cm) /* should not happen */ {
1174 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1175 return DDERR_GENERIC;
1177 if (!this->ddraw->e.xlib.paintable)
1178 return 0;
1179 for (i=0;i<count;i++) {
1180 xc.red = palent[i].peRed<<8;
1181 xc.blue = palent[i].peBlue<<8;
1182 xc.green = palent[i].peGreen<<8;
1183 xc.flags = DoRed|DoBlue|DoGreen;
1184 xc.pixel = start+i;
1186 TSXStoreColor(display,this->cm,&xc);
1188 this->palents[start+i].peRed = palent[i].peRed;
1189 this->palents[start+i].peBlue = palent[i].peBlue;
1190 this->palents[start+i].peGreen = palent[i].peGreen;
1191 this->palents[start+i].peFlags = palent[i].peFlags;
1193 return 0;
1196 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1197 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1199 #ifdef HAVE_LIBXXF86DGA
1200 XColor xc;
1201 Colormap cm;
1202 int i;
1204 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1205 this,x,start,count,palent
1207 if (!this->cm) /* should not happen */ {
1208 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1209 return DDERR_GENERIC;
1211 /* FIXME: free colorcells instead of freeing whole map */
1212 cm = this->cm;
1213 this->cm = TSXCopyColormapAndFree(display,this->cm);
1214 TSXFreeColormap(display,cm);
1216 for (i=0;i<count;i++) {
1217 xc.red = palent[i].peRed<<8;
1218 xc.blue = palent[i].peBlue<<8;
1219 xc.green = palent[i].peGreen<<8;
1220 xc.flags = DoRed|DoBlue|DoGreen;
1221 xc.pixel = i+start;
1223 TSXStoreColor(display,this->cm,&xc);
1225 this->palents[start+i].peRed = palent[i].peRed;
1226 this->palents[start+i].peBlue = palent[i].peBlue;
1227 this->palents[start+i].peGreen = palent[i].peGreen;
1228 this->palents[start+i].peFlags = palent[i].peFlags;
1230 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1231 return 0;
1232 #else /* defined(HAVE_LIBXXF86DGA) */
1233 return E_UNEXPECTED;
1234 #endif /* defined(HAVE_LIBXXF86DGA) */
1237 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1238 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1239 if (!--(this->ref)) {
1240 if (this->cm) {
1241 TSXFreeColormap(display,this->cm);
1242 this->cm = 0;
1244 HeapFree(GetProcessHeap(),0,this);
1245 return 0;
1247 return this->ref;
1250 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1252 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1253 return ++(this->ref);
1256 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1257 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1259 return DDERR_ALREADYINITIALIZED;
1262 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1263 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1265 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1266 return DD_OK;
1269 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1270 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1272 char xrefiid[50];
1274 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1275 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1277 return S_OK;
1280 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1281 IDirectDrawPalette_QueryInterface,
1282 IDirectDrawPalette_AddRef,
1283 IDirectDrawPalette_Release,
1284 IDirectDrawPalette_GetCaps,
1285 IDirectDrawPalette_GetEntries,
1286 IDirectDrawPalette_Initialize,
1287 DGA_IDirectDrawPalette_SetEntries
1290 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1291 IDirectDrawPalette_QueryInterface,
1292 IDirectDrawPalette_AddRef,
1293 IDirectDrawPalette_Release,
1294 IDirectDrawPalette_GetCaps,
1295 IDirectDrawPalette_GetEntries,
1296 IDirectDrawPalette_Initialize,
1297 Xlib_IDirectDrawPalette_SetEntries
1300 static HRESULT WINAPI IDirect3D_QueryInterface(
1301 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1303 /* FIXME: Not sure if this is correct */
1304 char xrefiid[50];
1306 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1307 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1308 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1309 *obj = this;
1310 this->lpvtbl->fnAddRef(this);
1311 return 0;
1313 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1314 LPDIRECT3D d3d;
1316 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1317 d3d->ref = 1;
1318 d3d->ddraw = (LPDIRECTDRAW)this;
1319 this->lpvtbl->fnAddRef(this);
1320 d3d->lpvtbl = &d3dvt;
1321 *obj = d3d;
1322 return 0;
1324 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1325 LPDIRECT3D2 d3d;
1327 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1328 d3d->ref = 1;
1329 d3d->ddraw = (LPDIRECTDRAW)this;
1330 this->lpvtbl->fnAddRef(this);
1331 d3d->lpvtbl = &d3d2vt;
1332 *obj = d3d;
1333 return 0;
1335 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1336 return OLE_E_ENUM_NOMORE;
1339 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1340 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1342 return ++(this->ref);
1345 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1347 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1349 if (!--(this->ref)) {
1350 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1351 HeapFree(GetProcessHeap(),0,this);
1352 return 0;
1354 return this->ref;
1357 static HRESULT WINAPI IDirect3D_Initialize(
1358 LPDIRECT3D this, REFIID refiid )
1360 /* FIXME: Not sure if this is correct */
1361 char xrefiid[50];
1363 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1364 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1366 return DDERR_ALREADYINITIALIZED;
1369 /*******************************************************************************
1370 * IDirect3D
1372 static struct IDirect3D_VTable d3dvt = {
1373 (void*)IDirect3D_QueryInterface,
1374 (void*)IDirect3D_AddRef,
1375 (void*)IDirect3D_Release,
1376 IDirect3D_Initialize,
1377 (void*)5,
1378 (void*)6,
1379 (void*)7,
1380 (void*)8,
1381 (void*)9,
1384 /*******************************************************************************
1385 * IDirect3D2
1387 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1388 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1390 if (!--(this->ref)) {
1391 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1392 HeapFree(GetProcessHeap(),0,this);
1393 return 0;
1395 return this->ref;
1398 static HRESULT WINAPI IDirect3D2_EnumDevices(
1399 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1401 D3DDEVICEDESC d1,d2;
1403 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1404 #if 0
1405 d1.dwSize = sizeof(d1);
1406 d1.dwFlags = 0;
1408 d2.dwSize = sizeof(d2);
1409 d2.dwFlags = 0;
1411 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1412 #endif
1413 return 0;
1416 static struct IDirect3D2_VTable d3d2vt = {
1417 (void*)1,
1418 (void*)2,
1419 IDirect3D2_Release,
1420 IDirect3D2_EnumDevices,
1421 (void*)5,
1422 (void*)6,
1423 (void*)7,
1424 (void*)8,
1425 (void*)9,
1428 /*******************************************************************************
1429 * IDirectDraw
1432 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1433 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1435 static INT32 ddrawXlibThisOffset = 0;
1437 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1438 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1440 #ifdef HAVE_LIBXXF86DGA
1441 int i;
1443 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1444 if (TRACE_ON(ddraw)) {
1445 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1446 _dump_DDSD(lpddsd->dwFlags);
1447 fprintf(stderr,"caps ");
1448 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1449 fprintf(stderr,"]\n");
1452 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1453 this->lpvtbl->fnAddRef(this);
1454 (*lpdsf)->ref = 1;
1455 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1456 if ( (lpddsd->dwFlags & DDSD_CAPS) &&
1457 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1459 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1460 lpddsd->dwWidth = this->e.dga.fb_width;
1461 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1462 lpddsd->dwHeight = this->e.dga.fb_height;
1463 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1464 (*lpdsf)->t.dga.fb_height = -1;
1465 (*lpdsf)->s.lpitch = lpddsd->dwWidth*this->d.depth/8;
1466 TRACE(ddraw,"using system memory for a primary surface\n");
1467 } else {
1468 for (i=0;i<32;i++)
1469 if (!(this->e.dga.vpmask & (1<<i)))
1470 break;
1471 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1472 /* if i == 32 or maximum ... return error */
1473 this->e.dga.vpmask|=(1<<i);
1474 (*lpdsf)->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1475 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1476 (*lpdsf)->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1479 lpddsd->lPitch = (*lpdsf)->s.lpitch;
1481 (*lpdsf)->s.width = this->d.width;
1482 (*lpdsf)->s.height = this->d.height;
1483 (*lpdsf)->s.ddraw = this;
1484 (*lpdsf)->s.backbuffer = NULL;
1485 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1486 LPDIRECTDRAWSURFACE3 back;
1488 if (lpddsd->dwBackBufferCount>1)
1489 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1491 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1492 this->lpvtbl->fnAddRef(this);
1493 back->ref = 1;
1494 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1495 for (i=0;i<32;i++)
1496 if (!(this->e.dga.vpmask & (1<<i)))
1497 break;
1498 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1499 /* if i == 32 or maximum ... return error */
1500 this->e.dga.vpmask|=(1<<i);
1501 back->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1502 back->t.dga.fb_height = i*this->e.dga.fb_height;
1504 back->s.width = this->d.width;
1505 back->s.height = this->d.height;
1506 back->s.ddraw = this;
1507 back->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1508 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1509 * one! */
1511 return 0;
1512 #else /* defined(HAVE_LIBXXF86DGA) */
1513 return E_UNEXPECTED;
1514 #endif /* defined(HAVE_LIBXXF86DGA) */
1517 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1518 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1520 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1521 this,lpddsd,lpdsf,lpunk);
1523 if (TRACE_ON(ddraw)) {
1524 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1525 _dump_DDSD(lpddsd->dwFlags);
1526 fprintf(stderr,"caps ");
1527 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1528 fprintf(stderr,"]\n");
1531 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1533 this->lpvtbl->fnAddRef(this);
1534 (*lpdsf)->s.ddraw = this;
1535 (*lpdsf)->ref = 1;
1536 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1538 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1539 lpddsd->dwWidth = this->d.width;
1540 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1541 lpddsd->dwHeight = this->d.height;
1542 (*lpdsf)->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1544 (*lpdsf)->s.width = lpddsd->dwWidth;
1545 (*lpdsf)->s.height = lpddsd->dwHeight;
1547 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1548 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)) {
1550 /* No XImage for a offscreen buffer */
1551 (*lpdsf)->t.xlib.image = NULL;
1552 (*lpdsf)->t.xlib.on_screen = FALSE;
1553 (*lpdsf)->s.lpitch = lpddsd->dwWidth * (this->d.depth / 8);
1555 TRACE(ddraw,"using system memory for a primary surface\n");
1556 } else {
1557 XImage *img;
1559 TRACE(ddraw,"using standard XImage for a primary surface\n");
1561 /* In this case, create an XImage */
1562 img =
1563 TSXCreateImage( display,
1564 DefaultVisualOfScreen(screen),
1565 this->d.depth,
1566 ZPixmap,
1568 (*lpdsf)->s.surface,
1569 (*lpdsf)->s.width,
1570 (*lpdsf)->s.height,
1572 (*lpdsf)->s.width * (this->d.depth / 8)
1574 (*lpdsf)->t.xlib.image = img;
1575 (*lpdsf)->t.xlib.on_screen = TRUE;
1576 (*lpdsf)->s.lpitch = img->bytes_per_line;
1578 /* Check for backbuffers */
1579 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1580 LPDIRECTDRAWSURFACE3 back;
1582 if (lpddsd->dwBackBufferCount>1)
1583 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1585 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1587 this->lpvtbl->fnAddRef(this);
1588 back->s.ddraw = this;
1590 back->ref = 1;
1591 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
1592 /* FIXME: !8 bit images */
1593 back->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1594 img->width*img->height*(this->d.depth / 8)
1596 back->t.xlib.image = TSXCreateImage(display,
1597 DefaultVisualOfScreen(screen),
1598 this->d.depth,
1599 ZPixmap,
1601 back->s.surface,
1602 this->d.width,
1603 this->d.height,
1605 this->d.width*(this->d.depth / 8)
1607 back->t.xlib.on_screen = FALSE;
1608 back->s.width = this->d.width;
1609 back->s.height = this->d.height;
1610 back->s.lpitch = back->t.xlib.image->bytes_per_line;
1611 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1612 * one! */
1616 return 0;
1619 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
1620 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1622 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1623 *dst = src; /* FIXME */
1624 return 0;
1627 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1628 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
1630 int i;
1631 const struct {
1632 int mask;
1633 char *name;
1634 } flagmap[] = {
1635 FE(DDSCL_FULLSCREEN)
1636 FE(DDSCL_ALLOWREBOOT)
1637 FE(DDSCL_NOWINDOWCHANGES)
1638 FE(DDSCL_NORMAL)
1639 FE(DDSCL_ALLOWMODEX)
1640 FE(DDSCL_EXCLUSIVE)
1641 FE(DDSCL_SETFOCUSWINDOW)
1642 FE(DDSCL_SETDEVICEWINDOW)
1643 FE(DDSCL_CREATEDEVICEWINDOW)
1646 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
1647 if(TRACE_ON(ddraw)){
1648 dbg_decl_str(ddraw, 512);
1649 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1650 if (flagmap[i].mask & cooplevel)
1651 dsprintf(ddraw, "%s ", flagmap[i].name);
1652 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1654 this->d.mainWindow = hwnd;
1655 return 0;
1659 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
1660 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1662 #ifdef HAVE_LIBXXF86DGA
1663 int i,*depths,depcount;
1665 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
1667 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1668 for (i=0;i<depcount;i++)
1669 if (depths[i]==depth)
1670 break;
1671 TSXFree(depths);
1672 if (i==depcount) {/* not found */
1673 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1674 return DDERR_UNSUPPORTEDMODE;
1676 if (this->d.width < width) {
1677 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
1678 return DDERR_UNSUPPORTEDMODE;
1680 this->d.width = width;
1681 this->d.height = height;
1682 /* adjust fb_height, so we don't overlap */
1683 if (this->e.dga.fb_height < height)
1684 this->e.dga.fb_height = height;
1685 this->d.depth = depth;
1687 /* FIXME: this function OVERWRITES several signal handlers.
1688 * can we save them? and restore them later? In a way that
1689 * it works for the library too?
1691 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
1692 #ifdef DIABLO_HACK
1693 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
1694 #endif
1696 #ifdef RESTORE_SIGNALS
1697 SIGNAL_InitEmulator();
1698 #endif
1699 return 0;
1700 #else /* defined(HAVE_LIBXXF86DGA) */
1701 return E_UNEXPECTED;
1702 #endif /* defined(HAVE_LIBXXF86DGA) */
1705 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
1706 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1708 int i,*depths,depcount;
1709 char buf[200];
1711 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
1712 this, width, height, depth);
1714 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1715 for (i=0;i<depcount;i++)
1716 if (depths[i]==depth)
1717 break;
1718 TSXFree(depths);
1719 if (i==depcount) {/* not found */
1720 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
1721 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
1722 return DDERR_UNSUPPORTEDMODE;
1725 if (this->d.width < width) {
1726 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld",width,height,depth,width,this->d.width);
1727 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
1728 return DDERR_UNSUPPORTEDMODE;
1731 if (this->e.xlib.window)
1732 DestroyWindow32(this->e.xlib.window);
1733 this->e.xlib.window = CreateWindowEx32A(
1735 "WINE_DirectDraw",
1736 "WINE_DirectDraw",
1737 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1738 0,0,
1739 width,
1740 height,
1744 NULL
1747 /* Store this with the window. We'll use it for the window procedure */
1748 SetWindowLong32A(this->e.xlib.window,ddrawXlibThisOffset,(LONG)this);
1750 this->e.xlib.paintable = 1;
1752 ShowWindow32(this->e.xlib.window,TRUE);
1753 UpdateWindow32(this->e.xlib.window);
1755 assert(this->e.xlib.window);
1757 this->e.xlib.drawable = WIN_FindWndPtr(this->e.xlib.window)->window;
1759 /* We don't have a context for this window. Host off the desktop */
1760 if( !this->e.xlib.drawable )
1762 this->e.xlib.drawable = WIN_GetDesktop()->window;
1765 this->d.width = width;
1766 this->d.height = height;
1768 /* adjust fb_height, so we don't overlap */
1770 if (this->e.dga.fb_height < height)
1771 this->e.dga.fb_height = height;*/
1772 this->d.depth = depth;
1773 return 0;
1776 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
1777 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1779 #ifdef HAVE_LIBXXF86DGA
1780 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1781 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
1782 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1783 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1784 if (caps2) {
1785 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
1786 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1787 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1789 return 0;
1790 #else /* defined(HAVE_LIBXXF86DGA) */
1791 return E_UNEXPECTED;
1792 #endif /* defined(HAVE_LIBXXF86DGA) */
1795 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
1796 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1798 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1799 /* FIXME: Xlib */
1800 caps1->dwVidMemTotal = 2048*1024;
1801 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1802 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1803 if (caps2) {
1804 caps2->dwVidMemTotal = 2048*1024;
1805 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
1806 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
1808 /* END FIXME: Xlib */
1809 return 0;
1812 static HRESULT WINAPI IDirectDraw2_CreateClipper(
1813 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
1815 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
1816 this,x,lpddclip,lpunk
1818 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1819 (*lpddclip)->ref = 1;
1820 (*lpddclip)->lpvtbl = &ddclipvt;
1821 return 0;
1824 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
1825 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1827 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1828 if (*lpddpal == NULL) return E_OUTOFMEMORY;
1829 (*lpddpal)->ref = 1;
1830 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1831 (*lpddpal)->installed = 0;
1832 if (this->d.depth<=8) {
1833 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
1834 } else {
1835 /* we don't want palettes in hicolor or truecolor */
1836 (*lpddpal)->cm = 0;
1838 return 0;
1841 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
1842 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1844 HRESULT res;
1845 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1846 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
1847 if (res != 0) return res;
1848 (*lpddpal)->lpvtbl = &dga_ddpalvt;
1849 return 0;
1852 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
1853 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1855 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1856 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1857 if (*lpddpal == NULL) return E_OUTOFMEMORY;
1858 (*lpddpal)->ref = 1;
1859 (*lpddpal)->installed = 0;
1861 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1862 this->lpvtbl->fnAddRef(this);
1864 if (this->d.depth<=8) {
1865 (*lpddpal)->cm = TSXCreateColormap(display,this->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
1866 /* FIXME: this is not correct, when using -managed */
1867 TSXInstallColormap(display,(*lpddpal)->cm);
1869 else
1871 /* we don't want palettes in hicolor or truecolor */
1872 (*lpddpal)->cm = 0;
1875 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
1876 return 0;
1879 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1880 #ifdef HAVE_LIBXXF86DGA
1881 TRACE(ddraw, "(%p)->()\n",this);
1882 Sleep(1000);
1883 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
1884 #ifdef RESTORE_SIGNALS
1885 SIGNAL_InitEmulator();
1886 #endif
1887 return 0;
1888 #else /* defined(HAVE_LIBXXF86DGA) */
1889 return E_UNEXPECTED;
1890 #endif
1893 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1894 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
1895 Sleep(1000);
1896 return 0;
1899 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
1900 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
1902 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
1903 return 0;
1906 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
1907 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1909 return ++(this->ref);
1912 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
1913 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1915 #ifdef HAVE_LIBXXF86DGA
1916 if (!--(this->ref)) {
1917 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
1918 #ifdef RESTORE_SIGNALS
1919 SIGNAL_InitEmulator();
1920 #endif
1921 HeapFree(GetProcessHeap(),0,this);
1922 return 0;
1924 #endif /* defined(HAVE_LIBXXF86DGA) */
1925 return this->ref;
1928 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
1929 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1931 if (!--(this->ref)) {
1932 HeapFree(GetProcessHeap(),0,this);
1933 return 0;
1935 /* FIXME: destroy window ... */
1936 return this->ref;
1939 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
1940 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
1942 char xrefiid[50];
1944 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1945 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1946 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1947 *obj = this;
1948 this->lpvtbl->fnAddRef(this);
1949 return 0;
1951 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1952 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
1953 this->lpvtbl->fnAddRef(this);
1954 *obj = this;
1955 return 0;
1957 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1958 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
1959 this->lpvtbl->fnAddRef(this);
1960 *obj = this;
1961 return 0;
1963 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1964 LPDIRECT3D d3d;
1966 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1967 d3d->ref = 1;
1968 d3d->ddraw = (LPDIRECTDRAW)this;
1969 this->lpvtbl->fnAddRef(this);
1970 d3d->lpvtbl = &d3dvt;
1971 *obj = d3d;
1972 return 0;
1974 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1975 LPDIRECT3D2 d3d;
1977 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1978 d3d->ref = 1;
1979 d3d->ddraw = (LPDIRECTDRAW)this;
1980 this->lpvtbl->fnAddRef(this);
1981 d3d->lpvtbl = &d3d2vt;
1982 *obj = d3d;
1983 return 0;
1985 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
1986 return OLE_E_ENUM_NOMORE;
1989 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
1990 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
1992 char xrefiid[50];
1994 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1995 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1996 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1997 *obj = this;
1998 this->lpvtbl->fnAddRef(this);
1999 return 0;
2001 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2002 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2003 this->lpvtbl->fnAddRef(this);
2004 *obj = this;
2005 return 0;
2007 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2008 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2009 this->lpvtbl->fnAddRef(this);
2010 *obj = this;
2011 return 0;
2013 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2014 LPDIRECT3D d3d;
2016 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2017 d3d->ref = 1;
2018 d3d->ddraw = (LPDIRECTDRAW)this;
2019 this->lpvtbl->fnAddRef(this);
2020 d3d->lpvtbl = &d3dvt;
2021 *obj = d3d;
2022 return 0;
2024 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2025 LPDIRECT3D2 d3d;
2027 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2028 d3d->ref = 1;
2029 d3d->ddraw = (LPDIRECTDRAW)this;
2030 this->lpvtbl->fnAddRef(this);
2031 d3d->lpvtbl = &d3d2vt;
2032 *obj = d3d;
2033 return 0;
2035 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2036 return OLE_E_ENUM_NOMORE;
2039 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2040 LPDIRECTDRAW2 this,BOOL32 *status
2042 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2043 *status = TRUE;
2044 return 0;
2047 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2048 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2050 DDSURFACEDESC ddsfd;
2051 static struct {
2052 int w,h;
2053 } modes[5] = { /* some of the usual modes */
2054 {512,384},
2055 {640,400},
2056 {640,480},
2057 {800,600},
2058 {1024,768},
2060 static int depths[4] = {8,16,24,32};
2061 int i,j;
2063 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2064 ddsfd.dwSize = sizeof(ddsfd);
2065 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2066 if (dwFlags & DDEDM_REFRESHRATES) {
2067 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2068 ddsfd.x.dwRefreshRate = 60;
2071 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2072 ddsfd.dwBackBufferCount = 1;
2073 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2074 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2075 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2076 if (depths[i]==8) {
2077 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2078 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2079 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2080 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2081 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2082 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2083 } else {
2084 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2086 /* FIXME: We should query those from X itself */
2087 switch (depths[i]) {
2088 case 16:
2089 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2090 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2091 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2092 break;
2093 case 24:
2094 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2095 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2096 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2097 break;
2098 case 32:
2099 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2100 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2101 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2102 break;
2105 ddsfd.dwWidth = screenWidth;
2106 ddsfd.dwHeight = screenHeight;
2107 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2108 if (!modescb(&ddsfd,context)) return 0;
2110 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2111 ddsfd.dwWidth = modes[i].w;
2112 ddsfd.dwHeight = modes[i].h;
2113 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2114 if (!modescb(&ddsfd,context)) return 0;
2117 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2118 /* modeX is not standard VGA */
2120 ddsfd.dwHeight = 200;
2121 ddsfd.dwWidth = 320;
2122 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2123 if (!modescb(&ddsfd,context)) return 0;
2126 return DD_OK;
2129 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2130 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2132 #ifdef HAVE_LIBXXF86DGA
2133 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2134 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2135 lpddsfd->dwHeight = screenHeight;
2136 lpddsfd->dwWidth = screenWidth;
2137 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2138 lpddsfd->dwBackBufferCount = 1;
2139 lpddsfd->x.dwRefreshRate = 60;
2140 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2141 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2142 return DD_OK;
2143 #else /* defined(HAVE_LIBXXF86DGA) */
2144 return E_UNEXPECTED;
2145 #endif /* defined(HAVE_LIBXXF86DGA) */
2148 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2149 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2151 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2152 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2153 lpddsfd->dwHeight = screenHeight;
2154 lpddsfd->dwWidth = screenWidth;
2155 /* POOLE FIXME: Xlib */
2156 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2157 /* END FIXME: Xlib */
2158 lpddsfd->dwBackBufferCount = 1;
2159 lpddsfd->x.dwRefreshRate = 60;
2160 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2161 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2162 return DD_OK;
2165 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2166 TRACE(ddraw,"(%p)->()\n",this);
2167 return DD_OK;
2170 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2171 LPDIRECTDRAW2 this,LPDWORD freq
2173 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2174 *freq = 60*100; /* 60 Hz */
2175 return 0;
2178 /* what can we directly decompress? */
2179 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2180 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2182 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2183 return 0;
2186 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2187 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2189 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2190 return 0;
2193 static HRESULT WINAPI IDirectDraw2_Compact(
2194 LPDIRECTDRAW2 this )
2196 FIXME(ddraw,"(%p)->()\n", this );
2198 return DD_OK;
2202 /* Note: Hack so we can reuse the old functions without compiler warnings */
2203 #ifdef __GNUC__
2204 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2205 #else
2206 # define XCAST(fun) (void*)
2207 #endif
2209 static struct IDirectDraw_VTable dga_ddvt = {
2210 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2211 XCAST(AddRef)IDirectDraw2_AddRef,
2212 XCAST(Release)DGA_IDirectDraw2_Release,
2213 XCAST(Compact)IDirectDraw2_Compact,
2214 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2215 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2216 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2217 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2218 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2219 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2220 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2221 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2222 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2223 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2224 XCAST(GetGDISurface)15,
2225 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2226 XCAST(GetScanLine)17,
2227 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2228 XCAST(Initialize)19,
2229 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2230 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2231 DGA_IDirectDraw_SetDisplayMode,
2232 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2235 static struct IDirectDraw_VTable xlib_ddvt = {
2236 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2237 XCAST(AddRef)IDirectDraw2_AddRef,
2238 XCAST(Release)Xlib_IDirectDraw2_Release,
2239 XCAST(Compact)IDirectDraw2_Compact,
2240 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2241 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2242 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2243 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2244 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2245 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2246 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2247 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2248 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2249 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2250 XCAST(GetGDISurface)15,
2251 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2252 XCAST(GetScanLine)17,
2253 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2254 XCAST(Initialize)19,
2255 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2256 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2257 Xlib_IDirectDraw_SetDisplayMode,
2258 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2261 /*****************************************************************************
2262 * IDirectDraw2
2267 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2268 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2270 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2273 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2274 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2276 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2279 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2280 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2282 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2283 this,ddscaps,total,free
2285 if (total) *total = this->e.dga.fb_memsize * 1024;
2286 if (free) *free = this->e.dga.fb_memsize * 1024;
2287 return 0;
2290 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2291 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2293 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2294 this,ddscaps,total,free
2296 if (total) *total = 2048 * 1024;
2297 if (free) *free = 2048 * 1024;
2298 return 0;
2301 static IDirectDraw2_VTable dga_dd2vt = {
2302 DGA_IDirectDraw2_QueryInterface,
2303 IDirectDraw2_AddRef,
2304 DGA_IDirectDraw2_Release,
2305 IDirectDraw2_Compact,
2306 IDirectDraw2_CreateClipper,
2307 DGA_IDirectDraw2_CreatePalette,
2308 DGA_IDirectDraw2_CreateSurface,
2309 (void*)8,
2310 IDirectDraw2_EnumDisplayModes,
2311 IDirectDraw2_EnumSurfaces,
2312 IDirectDraw2_FlipToGDISurface,
2313 DGA_IDirectDraw2_GetCaps,
2314 DGA_IDirectDraw2_GetDisplayMode,
2315 IDirectDraw2_GetFourCCCodes,
2316 (void*)15,
2317 IDirectDraw2_GetMonitorFrequency,
2318 (void*)17,
2319 IDirectDraw2_GetVerticalBlankStatus,
2320 (void*)19,
2321 DGA_IDirectDraw2_RestoreDisplayMode,
2322 IDirectDraw2_SetCooperativeLevel,
2323 DGA_IDirectDraw2_SetDisplayMode,
2324 IDirectDraw2_WaitForVerticalBlank,
2325 DGA_IDirectDraw2_GetAvailableVidMem
2328 static struct IDirectDraw2_VTable xlib_dd2vt = {
2329 Xlib_IDirectDraw2_QueryInterface,
2330 IDirectDraw2_AddRef,
2331 Xlib_IDirectDraw2_Release,
2332 IDirectDraw2_Compact,
2333 IDirectDraw2_CreateClipper,
2334 Xlib_IDirectDraw2_CreatePalette,
2335 Xlib_IDirectDraw2_CreateSurface,
2336 (void*)8,
2337 IDirectDraw2_EnumDisplayModes,
2338 IDirectDraw2_EnumSurfaces,
2339 IDirectDraw2_FlipToGDISurface,
2340 Xlib_IDirectDraw2_GetCaps,
2341 Xlib_IDirectDraw2_GetDisplayMode,
2342 IDirectDraw2_GetFourCCCodes,
2343 (void*)15,
2344 IDirectDraw2_GetMonitorFrequency,
2345 (void*)17,
2346 IDirectDraw2_GetVerticalBlankStatus,
2347 (void*)19,
2348 Xlib_IDirectDraw2_RestoreDisplayMode,
2349 IDirectDraw2_SetCooperativeLevel,
2350 Xlib_IDirectDraw2_SetDisplayMode,
2351 IDirectDraw2_WaitForVerticalBlank,
2352 Xlib_IDirectDraw2_GetAvailableVidMem
2355 /******************************************************************************
2356 * DirectDrawCreate
2359 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2360 #ifdef HAVE_LIBXXF86DGA
2361 int memsize,banksize,width,major,minor,flags,height;
2362 char *addr;
2364 if (getuid() != 0) {
2365 MSG("Must be root to use XF86DGA!\n");
2366 MessageBox32A(0,"Using the XF86DGA extension requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2367 return E_UNEXPECTED;
2369 if (!DDRAW_DGA_Available()) {
2370 TRACE(ddraw,"No XF86DGA detected.\n");
2371 return DDERR_GENERIC;
2373 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2374 (*lplpDD)->lpvtbl = &dga_ddvt;
2375 (*lplpDD)->ref = 1;
2376 TSXF86DGAQueryVersion(display,&major,&minor);
2377 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2378 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2379 if (!(flags & XF86DGADirectPresent))
2380 MSG("direct video is NOT PRESENT.\n");
2381 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2382 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2383 addr,width,banksize,memsize
2385 (*lplpDD)->e.dga.fb_width = width;
2386 (*lplpDD)->d.width = width;
2387 (*lplpDD)->e.dga.fb_addr = addr;
2388 (*lplpDD)->e.dga.fb_memsize = memsize;
2389 (*lplpDD)->e.dga.fb_banksize = banksize;
2391 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2392 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2393 (*lplpDD)->e.dga.fb_height = screenHeight;
2394 #ifdef DIABLO_HACK
2395 (*lplpDD)->e.dga.vpmask = 1;
2396 #else
2397 (*lplpDD)->e.dga.vpmask = 0;
2398 #endif
2400 /* just assume the default depth is the DGA depth too */
2401 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2402 #ifdef RESTORE_SIGNALS
2403 SIGNAL_InitEmulator();
2404 #endif
2405 return 0;
2406 #else /* defined(HAVE_LIBXXF86DGA) */
2407 return DDERR_INVALIDDIRECTDRAWGUID;
2408 #endif /* defined(HAVE_LIBXXF86DGA) */
2411 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2413 LRESULT ret;
2414 LPDIRECTDRAW ddraw = NULL;
2415 DWORD lastError;
2417 /*FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2419 SetLastError( ERROR_SUCCESS );
2420 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2421 if( (!ddraw) &&
2422 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2425 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2428 if( ddraw )
2430 /* Perform any special direct draw functions */
2431 if (msg==WM_PAINT)
2432 ddraw->e.xlib.paintable = 1;
2434 /* Now let the application deal with the rest of this */
2435 if( ddraw->d.mainWindow )
2438 /* Don't think that we actually need to call this but...
2439 might as well be on the safe side of things... */
2440 ret = DefWindowProc32A( hwnd, msg, wParam, lParam );
2442 if( !ret )
2444 /* We didn't handle the message - give it to the application */
2445 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow))
2446 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2447 ddraw->d.mainWindow, msg, wParam, lParam );
2451 else
2453 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2457 else
2459 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2462 return ret;
2465 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2466 WNDCLASS32A wc;
2467 int have_xshm = 0;
2468 WND* pParentWindow;
2470 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2471 (*lplpDD)->lpvtbl = &xlib_ddvt;
2472 (*lplpDD)->ref = 1;
2473 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
2474 (*lplpDD)->e.xlib.use_xshm = have_xshm;
2475 wc.style = CS_GLOBALCLASS;
2476 wc.lpfnWndProc = Xlib_DDWndProc;
2477 wc.cbClsExtra = 0;
2478 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
2479 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
2481 /* We can be a child of the desktop since we're really important */
2482 pParentWindow = WIN_GetDesktop();
2483 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
2484 wc.hInstance = 0;
2486 wc.hIcon = 0;
2487 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
2488 wc.hbrBackground= NULL_BRUSH;
2489 wc.lpszMenuName = 0;
2490 wc.lpszClassName= "WINE_DirectDraw";
2492 (*lplpDD)->e.xlib.winclass = RegisterClass32A(&wc);
2494 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2495 (*lplpDD)->d.height = screenHeight;
2496 (*lplpDD)->d.width = screenWidth;
2497 return 0;
2500 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
2501 char xclsid[50];
2503 if (HIWORD(lpGUID))
2504 WINE_StringFromCLSID(lpGUID,xclsid);
2505 else {
2506 sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID);
2507 lpGUID = NULL;
2510 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
2512 if (!lpGUID) {
2513 /* if they didn't request a particular interface, use the best
2514 * supported one */
2515 if (DDRAW_DGA_Available())
2516 lpGUID = &DGA_DirectDraw_GUID;
2517 else
2518 lpGUID = &XLIB_DirectDraw_GUID;
2521 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
2522 return DGA_DirectDrawCreate(lplpDD, pUnkOuter);
2523 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
2524 return Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
2526 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
2527 return DDERR_INVALIDDIRECTDRAWGUID;