Shell_GetCachedImageIndex32[A|W] implemented.
[wine/multimedia.git] / graphics / ddraw.c
blob474d2b050f1c1898a3f78f97dab2040a15a5ac3d
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 */
5 /* XF86DGA:
6 * When DirectVideo mode is enabled you can no longer use 'normal' X
7 * applications nor can you switch to a virtual console. Also, enabling
8 * only works, if you have switched to the screen where the application
9 * is running.
10 * Some ways to debug this stuff are:
11 * - A terminal connected to the serial port. Can be bought used for cheap.
12 * (This is the method I am using.)
13 * - Another machine connected over some kind of network.
16 #include "config.h"
17 #include <unistd.h>
18 #include <assert.h>
19 #include "ts_xlib.h"
20 #include "ts_xutil.h"
21 #include <sys/signal.h>
22 #include <fcntl.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include "windows.h"
27 #ifdef HAVE_LIBXXF86VM
28 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
29 this is a crude hack to get around it */
30 #define XMD_H
31 #include "ts_xf86vmode.h"
32 #endif
34 #include "winerror.h"
35 #include "interfaces.h"
36 #include "gdi.h"
37 #include "heap.h"
38 #include "ldt.h"
39 #include "dc.h"
40 #include "win.h"
41 #include "miscemu.h"
42 #include "ddraw.h"
43 #include "d3d.h"
44 #include "debug.h"
45 #include "compobj.h"
46 #include "spy.h"
47 #include "message.h"
48 #include "x11drv.h"
49 #include "options.h"
51 #ifdef HAVE_LIBXXF86DGA
52 #include "ts_xf86dga.h"
53 #endif
55 #ifdef HAVE_LIBXXSHM
56 #include <sys/types.h>
57 #include <sys/ipc.h>
58 #include <sys/shm.h>
59 #include "ts_xshm.h"
60 #endif
62 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
63 #undef DIABLO_HACK
65 /* Restore signal handlers overwritten by XF86DGA
66 * this is a define, for it will only work in emulator mode
68 #undef RESTORE_SIGNALS
70 /* Where do these GUIDs come from? mkuuid.
71 * They exist solely to distinguish between the targets Wine support,
72 * and should be different than any other GUIDs in existence.
74 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
75 0xe2dcb020,
76 0xdc60,
77 0x11d1,
78 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
81 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
82 0x1574a740,
83 0xdc61,
84 0x11d1,
85 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
88 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
89 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
90 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
91 static struct IDirectDrawClipper_VTable ddclipvt;
92 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
93 static struct IDirect3D_VTable d3dvt;
94 static struct IDirect3D2_VTable d3d2vt;
96 #ifdef HAVE_LIBXXF86VM
97 static XF86VidModeModeInfo *orig_mode = NULL;
98 #endif
100 BOOL32
101 DDRAW_DGA_Available()
103 #ifdef HAVE_LIBXXF86DGA
104 int evbase, evret, fd;
106 if (Options.noDGA)
107 return 0;
109 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
110 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
111 /* others. --stephenc */
112 if ((fd = open("/dev/mem", O_RDWR)) != -1)
113 close(fd);
115 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
116 #else /* defined(HAVE_LIBXXF86DGA) */
117 return 0;
118 #endif /* defined(HAVE_LIBXXF86DGA) */
121 HRESULT WINAPI
122 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
123 if (DDRAW_DGA_Available()) {
124 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
126 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
127 ddenumproc(NULL,"WINE","display",data);
128 return DD_OK;
131 /* What is this doing here? */
132 HRESULT WINAPI
133 DSoundHelp(DWORD x,DWORD y,DWORD z) {
134 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
135 return 0;
139 /******************************************************************************
140 * internal helper functions
142 static void _dump_DDBLTFX(DWORD flagmask) {
143 int i;
144 const struct {
145 DWORD mask;
146 char *name;
147 } flags[] = {
148 #define FE(x) { x, #x},
149 FE(DDBLTFX_ARITHSTRETCHY)
150 FE(DDBLTFX_MIRRORLEFTRIGHT)
151 FE(DDBLTFX_MIRRORUPDOWN)
152 FE(DDBLTFX_NOTEARING)
153 FE(DDBLTFX_ROTATE180)
154 FE(DDBLTFX_ROTATE270)
155 FE(DDBLTFX_ROTATE90)
156 FE(DDBLTFX_ZBUFFERRANGE)
157 FE(DDBLTFX_ZBUFFERBASEDEST)
159 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
160 if (flags[i].mask & flagmask) {
161 DUMP("%s ",flags[i].name);
164 DUMP("\n");
168 static void _dump_DDBLTFAST(DWORD flagmask) {
169 int i;
170 const struct {
171 DWORD mask;
172 char *name;
173 } flags[] = {
174 #define FE(x) { x, #x},
175 FE(DDBLTFAST_NOCOLORKEY)
176 FE(DDBLTFAST_SRCCOLORKEY)
177 FE(DDBLTFAST_DESTCOLORKEY)
178 FE(DDBLTFAST_WAIT)
180 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
181 if (flags[i].mask & flagmask)
182 DUMP("%s ",flags[i].name);
183 DUMP("\n");
186 static void _dump_DDBLT(DWORD flagmask) {
187 int i;
188 const struct {
189 DWORD mask;
190 char *name;
191 } flags[] = {
192 #define FE(x) { x, #x},
193 FE(DDBLT_ALPHADEST)
194 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
195 FE(DDBLT_ALPHADESTNEG)
196 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
197 FE(DDBLT_ALPHAEDGEBLEND)
198 FE(DDBLT_ALPHASRC)
199 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
200 FE(DDBLT_ALPHASRCNEG)
201 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
202 FE(DDBLT_ASYNC)
203 FE(DDBLT_COLORFILL)
204 FE(DDBLT_DDFX)
205 FE(DDBLT_DDROPS)
206 FE(DDBLT_KEYDEST)
207 FE(DDBLT_KEYDESTOVERRIDE)
208 FE(DDBLT_KEYSRC)
209 FE(DDBLT_KEYSRCOVERRIDE)
210 FE(DDBLT_ROP)
211 FE(DDBLT_ROTATIONANGLE)
212 FE(DDBLT_ZBUFFER)
213 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
214 FE(DDBLT_ZBUFFERDESTOVERRIDE)
215 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
216 FE(DDBLT_ZBUFFERSRCOVERRIDE)
217 FE(DDBLT_WAIT)
218 FE(DDBLT_DEPTHFILL)
220 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
221 if (flags[i].mask & flagmask)
222 DUMP("%s ",flags[i].name);
225 static void _dump_DDSCAPS(DWORD flagmask) {
226 int i;
227 const struct {
228 DWORD mask;
229 char *name;
230 } flags[] = {
231 #define FE(x) { x, #x},
232 FE(DDSCAPS_RESERVED1)
233 FE(DDSCAPS_ALPHA)
234 FE(DDSCAPS_BACKBUFFER)
235 FE(DDSCAPS_COMPLEX)
236 FE(DDSCAPS_FLIP)
237 FE(DDSCAPS_FRONTBUFFER)
238 FE(DDSCAPS_OFFSCREENPLAIN)
239 FE(DDSCAPS_OVERLAY)
240 FE(DDSCAPS_PALETTE)
241 FE(DDSCAPS_PRIMARYSURFACE)
242 FE(DDSCAPS_PRIMARYSURFACELEFT)
243 FE(DDSCAPS_SYSTEMMEMORY)
244 FE(DDSCAPS_TEXTURE)
245 FE(DDSCAPS_3DDEVICE)
246 FE(DDSCAPS_VIDEOMEMORY)
247 FE(DDSCAPS_VISIBLE)
248 FE(DDSCAPS_WRITEONLY)
249 FE(DDSCAPS_ZBUFFER)
250 FE(DDSCAPS_OWNDC)
251 FE(DDSCAPS_LIVEVIDEO)
252 FE(DDSCAPS_HWCODEC)
253 FE(DDSCAPS_MODEX)
254 FE(DDSCAPS_MIPMAP)
255 FE(DDSCAPS_RESERVED2)
256 FE(DDSCAPS_ALLOCONLOAD)
257 FE(DDSCAPS_VIDEOPORT)
258 FE(DDSCAPS_LOCALVIDMEM)
259 FE(DDSCAPS_NONLOCALVIDMEM)
260 FE(DDSCAPS_STANDARDVGAMODE)
261 FE(DDSCAPS_OPTIMIZED)
263 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
264 if (flags[i].mask & flagmask)
265 DUMP("%s ",flags[i].name);
266 DUMP("\n");
269 static void _dump_DDSD(DWORD flagmask) {
270 int i;
271 const struct {
272 DWORD mask;
273 char *name;
274 } flags[] = {
275 FE(DDSD_CAPS)
276 FE(DDSD_HEIGHT)
277 FE(DDSD_WIDTH)
278 FE(DDSD_PITCH)
279 FE(DDSD_BACKBUFFERCOUNT)
280 FE(DDSD_ZBUFFERBITDEPTH)
281 FE(DDSD_ALPHABITDEPTH)
282 FE(DDSD_PIXELFORMAT)
283 FE(DDSD_CKDESTOVERLAY)
284 FE(DDSD_CKDESTBLT)
285 FE(DDSD_CKSRCOVERLAY)
286 FE(DDSD_CKSRCBLT)
287 FE(DDSD_MIPMAPCOUNT)
288 FE(DDSD_REFRESHRATE)
289 FE(DDSD_LINEARSIZE)
290 FE(DDSD_LPSURFACE)
292 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
293 if (flags[i].mask & flagmask)
294 DUMP("%s ",flags[i].name);
295 DUMP("\n");
298 static void _dump_DDCOLORKEY(DWORD flagmask) {
299 int i;
300 const struct {
301 DWORD mask;
302 char *name;
303 } flags[] = {
304 #define FE(x) { x, #x},
305 FE(DDPF_ALPHAPIXELS)
306 FE(DDPF_ALPHA)
307 FE(DDPF_FOURCC)
308 FE(DDPF_PALETTEINDEXED4)
309 FE(DDPF_PALETTEINDEXEDTO8)
310 FE(DDPF_PALETTEINDEXED8)
311 FE(DDPF_RGB)
312 FE(DDPF_COMPRESSED)
313 FE(DDPF_RGBTOYUV)
314 FE(DDPF_YUV)
315 FE(DDPF_ZBUFFER)
316 FE(DDPF_PALETTEINDEXED1)
317 FE(DDPF_PALETTEINDEXED2)
318 FE(DDPF_ZPIXELS)
320 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
321 if (flags[i].mask & flagmask)
322 DUMP("%s ",flags[i].name);
323 DUMP("\n");
326 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
327 _dump_DDCOLORKEY(pf->dwFlags);
328 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
329 DUMP("RBG bit cbout : %ld\n", pf->x.dwRGBBitCount);
330 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
331 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
334 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
335 static XVisualInfo *vi;
336 XVisualInfo vt;
337 int nitems;
339 if (!vi)
340 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
342 pf->dwFourCC = 0;
343 if (ddraw->d.depth==8) {
344 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
345 pf->x.dwRGBBitCount = 8;
346 pf->y.dwRBitMask = 0;
347 pf->z.dwGBitMask = 0;
348 pf->xx.dwBBitMask = 0;
349 pf->xy.dwRGBAlphaBitMask= 0;
350 return 0;
352 if (ddraw->d.depth==16) {
353 pf->dwFlags = DDPF_RGB;
354 pf->x.dwRGBBitCount = 16;
355 pf->y.dwRBitMask = vi[0].red_mask;
356 pf->z.dwGBitMask = vi[0].green_mask;
357 pf->xx.dwBBitMask = vi[0].blue_mask;
358 pf->xy.dwRGBAlphaBitMask= 0;
359 return 0;
361 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
362 return DDERR_GENERIC;
365 /******************************************************************************
366 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
368 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
369 * DDS and DDS2 use those functions. (Function calls did not change (except
370 * using different DirectDrawSurfaceX version), just added flags and functions)
372 static HRESULT WINAPI IDirectDrawSurface3_Lock(
373 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
375 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
376 this,lprect,lpddsd,flags,(DWORD)hnd);
377 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
378 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
379 this,lprect,lpddsd,flags,(DWORD)hnd);
381 /* First, copy the Surface description */
382 *lpddsd = this->s.surface_desc;
384 /* If asked only for a part, change the surface pointer */
385 if (lprect) {
386 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
387 lprect->top,lprect->left,lprect->bottom,lprect->right
389 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
390 (lprect->top*this->s.surface_desc.lPitch) +
391 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
392 } else {
393 assert(this->s.surface_desc.y.lpSurface);
395 return DD_OK;
398 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
399 LPDIRECTDRAWSURFACE3 this,LPVOID surface
401 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
402 return DD_OK;
405 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
406 LPDIRECTDRAWSURFACE3 this,LPVOID surface)
408 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
410 if (!this->s.ddraw->e.xlib.paintable)
411 return DD_OK;
413 /* Only redraw the screen when unlocking the buffer that is on screen */
414 if ((this->t.xlib.image != NULL) &&
415 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
416 #ifdef HAVE_LIBXXSHM
417 if (this->s.ddraw->e.xlib.xshm_active)
418 TSXShmPutImage(display,
419 this->s.ddraw->e.xlib.drawable,
420 DefaultGCOfScreen(screen),
421 this->t.xlib.image,
422 0, 0, 0, 0,
423 this->t.xlib.image->width,
424 this->t.xlib.image->height,
425 False);
426 else
427 #endif
428 TSXPutImage( display,
429 this->s.ddraw->e.xlib.drawable,
430 DefaultGCOfScreen(screen),
431 this->t.xlib.image,
432 0, 0, 0, 0,
433 this->t.xlib.image->width,
434 this->t.xlib.image->height);
436 if (this->s.palette && this->s.palette->cm)
437 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
440 return DD_OK;
443 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
444 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
446 #ifdef HAVE_LIBXXF86DGA
447 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
448 if (!flipto) {
449 if (this->s.backbuffer)
450 flipto = this->s.backbuffer;
451 else
452 flipto = this;
454 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
456 if (flipto->s.palette && flipto->s.palette->cm) {
457 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
459 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
461 if (flipto!=this) {
462 int tmp;
463 LPVOID ptmp;
465 tmp = this->t.dga.fb_height;
466 this->t.dga.fb_height = flipto->t.dga.fb_height;
467 flipto->t.dga.fb_height = tmp;
469 ptmp = this->s.surface_desc.y.lpSurface;
470 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
471 flipto->s.surface_desc.y.lpSurface = ptmp;
473 return DD_OK;
474 #else /* defined(HAVE_LIBXXF86DGA) */
475 return E_UNEXPECTED;
476 #endif /* defined(HAVE_LIBXXF86DGA) */
479 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
480 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
482 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
483 if (!this->s.ddraw->e.xlib.paintable)
484 return DD_OK;
486 if (!flipto) {
487 if (this->s.backbuffer)
488 flipto = this->s.backbuffer;
489 else
490 flipto = this;
493 #ifdef HAVE_LIBXXSHM
494 if (this->s.ddraw->e.xlib.xshm_active) {
495 TSXShmPutImage(display,
496 this->s.ddraw->e.xlib.drawable,
497 DefaultGCOfScreen(screen),
498 flipto->t.xlib.image,
499 0, 0, 0, 0,
500 flipto->t.xlib.image->width,
501 flipto->t.xlib.image->height,
502 False);
503 } else
504 #endif
505 TSXPutImage(display,
506 this->s.ddraw->e.xlib.drawable,
507 DefaultGCOfScreen(screen),
508 flipto->t.xlib.image,
509 0, 0, 0, 0,
510 flipto->t.xlib.image->width,
511 flipto->t.xlib.image->height);
513 if (flipto->s.palette && flipto->s.palette->cm) {
514 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,flipto->s.palette->cm);
516 if (flipto!=this) {
517 XImage *tmp;
518 LPVOID *surf;
519 tmp = this->t.xlib.image;
520 this->t.xlib.image = flipto->t.xlib.image;
521 flipto->t.xlib.image = tmp;
522 surf = this->s.surface_desc.y.lpSurface;
523 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
524 flipto->s.surface_desc.y.lpSurface = surf;
526 return DD_OK;
530 /* The IDirectDrawSurface3::SetPalette method attaches the specified
531 * DirectDrawPalette object to a surface. The surface uses this palette for all
532 * subsequent operations. The palette change takes place immediately.
534 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
535 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
537 int i;
538 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
540 if( !(pal->cm) && (this->s.ddraw->d.depth<=8))
542 pal->cm = TSXCreateColormap(display,this->s.ddraw->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
544 /* FIXME: this is not correct, when using -managed (XSetWindowColormap??) */
545 TSXInstallColormap(display,pal->cm);
547 for (i=0;i<256;i++) {
548 XColor xc;
550 xc.red = pal->palents[i].peRed<<8;
551 xc.blue = pal->palents[i].peBlue<<8;
552 xc.green = pal->palents[i].peGreen<<8;
553 xc.flags = DoRed|DoBlue|DoGreen;
554 xc.pixel = i;
555 TSXStoreColor(display,pal->cm,&xc);
559 /* According to spec, we are only supposed to
560 * AddRef if this is not the same palette.
562 if( this->s.palette != pal )
564 if( pal != NULL )
565 pal->lpvtbl->fnAddRef( pal );
566 if( this->s.palette != NULL )
567 this->s.palette->lpvtbl->fnRelease( this->s.palette );
568 this->s.palette = pal;
570 /* I think that we need to attach it to all backbuffers...*/
571 if( this->s.backbuffer ) {
572 if( this->s.backbuffer->s.palette )
573 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
574 this->s.backbuffer->s.palette );
575 this->s.backbuffer->s.palette = pal;
576 if( pal )
577 pal->lpvtbl->fnAddRef( pal );
579 /* Perform the refresh */
580 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
582 return DD_OK;
585 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
586 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
588 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
589 #ifdef HAVE_LIBXXF86DGA
590 /* According to spec, we are only supposed to
591 * AddRef if this is not the same palette.
593 if( this->s.palette != pal )
595 if( pal != NULL )
596 pal->lpvtbl->fnAddRef( pal );
597 if( this->s.palette != NULL )
598 this->s.palette->lpvtbl->fnRelease( this->s.palette );
599 this->s.palette = pal;
601 /* I think that we need to attach it to all backbuffers...*/
602 if( this->s.backbuffer ) {
603 if( this->s.backbuffer->s.palette )
604 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
605 this->s.backbuffer->s.palette = pal;
606 if( pal ) pal->lpvtbl->fnAddRef( pal );
608 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
610 return DD_OK;
611 #else /* defined(HAVE_LIBXXF86DGA) */
612 return E_UNEXPECTED;
613 #endif /* defined(HAVE_LIBXXF86DGA) */
618 static HRESULT WINAPI IDirectDrawSurface3_Blt(
619 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
621 RECT32 xdst,xsrc;
622 DDSURFACEDESC ddesc,sdesc;
623 int i,j;
625 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
626 this,rdst,src,rsrc,dwFlags,lpbltfx);
628 if (src != NULL)
629 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
630 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
632 if (TRACE_ON(ddraw)) {
633 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
634 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
635 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
636 if (dwFlags & DDBLT_DDFX) {
637 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
641 if (rdst) {
642 memcpy(&xdst,rdst,sizeof(xdst));
643 } else {
644 xdst.top = 0;
645 xdst.bottom = ddesc.dwHeight;
646 xdst.left = 0;
647 xdst.right = ddesc.dwWidth;
650 if (rsrc) {
651 memcpy(&xsrc,rsrc,sizeof(xsrc));
652 } else {
653 if (src) {
654 xsrc.top = 0;
655 xsrc.bottom = sdesc.dwHeight;
656 xsrc.left = 0;
657 xsrc.right = sdesc.dwWidth;
658 } else {
659 memset(&xsrc,0,sizeof(xsrc));
663 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
665 if (dwFlags & DDBLT_COLORFILL) {
666 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
667 LPBYTE xline,xpixel;
669 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
670 for (i=xdst.top;i<xdst.bottom;i++) {
671 xpixel = xline+bpp*xdst.left;
673 for (j=xdst.left;j<xdst.right;j++) {
674 /* FIXME: this only works on little endian
675 * architectures, where DWORD starts with low
676 * byte first!
678 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
679 xpixel += bpp;
681 xline += ddesc.lPitch;
683 dwFlags &= ~(DDBLT_COLORFILL);
686 if (!src) {
687 if (dwFlags) {
688 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
690 return DD_OK;
693 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
694 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
695 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
696 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
697 !dwFlags
699 memcpy(ddesc.y.lpSurface,
700 sdesc.y.lpSurface,
701 ddesc.dwHeight * ddesc.lPitch);
702 } else {
703 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
704 int height = xsrc.bottom - xsrc.top;
705 int width = (xsrc.right - xsrc.left) * bpp;
706 int h;
708 for (h = 0; h < height; h++) {
709 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
710 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
711 width);
715 if (dwFlags && FIXME_ON(ddraw)) {
716 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
719 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
720 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
722 return DD_OK;
725 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
726 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
728 int i,bpp;
729 DDSURFACEDESC ddesc,sdesc;
731 if (TRACE_ON(ddraw)) {
732 TRACE(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
733 this,dstx,dsty,src,rsrc,trans
735 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
736 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
738 /* We need to lock the surfaces, or we won't get refreshes when done. */
739 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
740 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
741 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
742 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
743 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
744 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
745 (rsrc->right-rsrc->left)*bpp
748 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
749 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
750 return DD_OK;
753 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
754 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
756 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
757 this,ddbltbatch,x,y
759 return DD_OK;
762 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
763 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
765 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
766 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
767 return DD_OK;
770 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
771 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
772 ) {
773 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
774 this,ddsd);
776 /* Simply copy the surface description stored in the object */
777 *ddsd = this->s.surface_desc;
779 if (TRACE_ON(ddraw)) {
780 fprintf(stderr," flags: ");
781 _dump_DDSD(ddsd->dwFlags);
782 if (ddsd->dwFlags & DDSD_CAPS) {
783 fprintf(stderr, " caps: ");
784 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
786 fprintf(stderr,"\n");
789 return DD_OK;
792 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
793 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
795 return ++(this->ref);
798 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
799 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
801 #ifdef HAVE_LIBXXF86DGA
802 if (!--(this->ref)) {
803 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
804 /* clear out of surface list */
805 if (this->t.dga.fb_height == -1) {
806 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
807 } else {
808 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
810 HeapFree(GetProcessHeap(),0,this);
811 return 0;
813 #endif /* defined(HAVE_LIBXXF86DGA) */
814 return this->ref;
817 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
818 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
820 if (!--(this->ref)) {
821 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
823 if( this->s.backbuffer )
824 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
826 if (this->t.xlib.image != NULL) {
827 this->t.xlib.image->data = NULL;
829 #ifdef HAVE_LIBXXSHM
830 if (this->s.ddraw->e.xlib.xshm_active) {
831 TSXShmDetach(display, &(this->t.xlib.shminfo));
832 TSXDestroyImage(this->t.xlib.image);
833 shmdt(this->t.xlib.shminfo.shmaddr);
834 } else {
835 #endif
836 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
837 TSXDestroyImage(this->t.xlib.image);
838 #ifdef HAVE_LIBXXSHM
840 #endif
842 this->t.xlib.image = 0;
843 } else {
844 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
847 if (this->s.palette)
848 this->s.palette->lpvtbl->fnRelease(this->s.palette);
850 HeapFree(GetProcessHeap(),0,this);
851 return 0;
854 return this->ref;
857 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
858 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
860 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
861 this, lpddsd, lpdsf);
863 if (TRACE_ON(ddraw)) {
864 TRACE(ddraw," caps ");
865 _dump_DDSCAPS(lpddsd->dwCaps);
868 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
869 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
870 return E_FAIL;
873 /* FIXME: should handle more than one backbuffer */
874 *lpdsf = this->s.backbuffer;
876 if( this->s.backbuffer )
877 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
879 return DD_OK;
882 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
883 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
885 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
887 return DDERR_ALREADYINITIALIZED;
890 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
891 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
893 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
895 *pf = this->s.surface_desc.ddpfPixelFormat;
897 return DD_OK;
900 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
901 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
902 return DD_OK;
905 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
906 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
908 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
909 return DD_OK;
912 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
913 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
915 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
916 return DD_OK;
919 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
920 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
922 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
924 /* This hack will be enough for the moment */
925 if (this->s.backbuffer == NULL)
926 this->s.backbuffer = surf;
927 return DD_OK;
930 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
931 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
932 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
933 return DD_OK;
936 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
937 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
938 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
939 return DD_OK;
943 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
944 char xrefiid[50];
946 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
947 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
949 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
950 * the same interface. And IUnknown does that too of course.
952 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
953 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
954 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
955 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
957 *obj = this;
958 this->lpvtbl->fnAddRef(this);
959 return S_OK;
961 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
962 return OLE_E_ENUM_NOMORE;
965 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
966 TRACE(ddraw,"(%p)->(), stub!\n",this);
967 return DD_OK; /* hmm */
970 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
971 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
972 return DD_OK;
975 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
976 FIXME(ddraw,"(%p)->(),stub!\n",this);
977 return DD_OK;
980 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
981 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey )
983 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);
985 if( dwFlags & DDCKEY_SRCBLT )
987 dwFlags &= ~DDCKEY_SRCBLT;
988 memcpy( &(this->s.ckSrcBlt), ckey, sizeof( *ckey ) );
991 if( dwFlags & DDCKEY_DESTBLT )
993 dwFlags &= ~DDCKEY_DESTBLT;
994 memcpy( &(this->s.ckDestBlt), ckey, sizeof( *ckey ) );
997 if( dwFlags & DDCKEY_SRCOVERLAY )
999 dwFlags &= ~DDCKEY_SRCOVERLAY;
1000 memcpy( &(this->s.ckSrcOverlay), ckey, sizeof( *ckey ) );
1002 if( dwFlags & DDCKEY_DESTOVERLAY )
1004 dwFlags &= ~DDCKEY_DESTOVERLAY;
1005 memcpy( &(this->s.ckDestOverlay), ckey, sizeof( *ckey ) );
1008 if( dwFlags )
1010 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1013 return DD_OK;
1017 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
1018 LPDIRECTDRAWSURFACE3 this,
1019 LPRECT32 lpRect )
1021 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
1023 return DD_OK;
1026 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
1027 LPDIRECTDRAWSURFACE3 this,
1028 DWORD dwFlags,
1029 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
1031 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1033 return DD_OK;
1036 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
1037 LPDIRECTDRAWSURFACE3 this,
1038 DWORD dwFlags,
1039 LPVOID lpContext,
1040 LPDDENUMSURFACESCALLBACK lpfnCallback )
1042 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1043 lpContext, lpfnCallback );
1045 return DD_OK;
1048 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
1049 LPDIRECTDRAWSURFACE3 this,
1050 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1052 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1054 return DD_OK;
1057 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
1058 LPDIRECTDRAWSURFACE3 this,
1059 DWORD dwFlags,
1060 LPDDCOLORKEY lpDDColorKey )
1062 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);
1064 if( dwFlags & DDCKEY_SRCBLT ) {
1065 dwFlags &= ~DDCKEY_SRCBLT;
1066 memcpy( lpDDColorKey, &(this->s.ckSrcBlt), sizeof( *lpDDColorKey ) );
1069 if( dwFlags & DDCKEY_DESTBLT )
1071 dwFlags &= ~DDCKEY_DESTBLT;
1072 memcpy( lpDDColorKey, &(this->s.ckDestBlt), sizeof( *lpDDColorKey ) );
1075 if( dwFlags & DDCKEY_SRCOVERLAY )
1077 dwFlags &= ~DDCKEY_SRCOVERLAY;
1078 memcpy( lpDDColorKey, &(this->s.ckSrcOverlay), sizeof( *lpDDColorKey ) );
1081 if( dwFlags & DDCKEY_DESTOVERLAY )
1083 dwFlags &= ~DDCKEY_DESTOVERLAY;
1084 memcpy( lpDDColorKey, &(this->s.ckDestOverlay), sizeof( *lpDDColorKey ) );
1087 if( dwFlags )
1089 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1092 return DD_OK;
1095 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
1096 LPDIRECTDRAWSURFACE3 this,
1097 DWORD dwFlags )
1099 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1101 return DD_OK;
1104 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
1105 LPDIRECTDRAWSURFACE3 this,
1106 LPDIRECTDRAWPALETTE* lplpDDPalette )
1108 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1110 return DD_OK;
1113 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
1114 LPDIRECTDRAWSURFACE3 this,
1115 LONG lX,
1116 LONG lY)
1118 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1120 return DD_OK;
1123 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
1124 LPDIRECTDRAWSURFACE3 this,
1125 LPRECT32 lpSrcRect,
1126 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
1127 LPRECT32 lpDestRect,
1128 DWORD dwFlags,
1129 LPDDOVERLAYFX lpDDOverlayFx )
1131 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1132 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1134 return DD_OK;
1137 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
1138 LPDIRECTDRAWSURFACE3 this,
1139 DWORD dwFlags )
1141 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1143 return DD_OK;
1146 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
1147 LPDIRECTDRAWSURFACE3 this,
1148 DWORD dwFlags,
1149 LPDIRECTDRAWSURFACE3 lpDDSReference )
1151 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1153 return DD_OK;
1156 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
1157 LPDIRECTDRAWSURFACE3 this,
1158 LPVOID* lplpDD )
1160 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1162 return DD_OK;
1165 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
1166 LPDIRECTDRAWSURFACE3 this,
1167 DWORD dwFlags )
1169 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1171 return DD_OK;
1174 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
1175 LPDIRECTDRAWSURFACE3 this,
1176 DWORD dwFlags )
1178 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1180 return DD_OK;
1183 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1184 LPDIRECTDRAWSURFACE3 this,
1185 LPDDSURFACEDESC lpDDSD,
1186 DWORD dwFlags )
1188 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1190 return DD_OK;
1193 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1194 IDirectDrawSurface3_QueryInterface,
1195 IDirectDrawSurface3_AddRef,
1196 DGA_IDirectDrawSurface3_Release,
1197 IDirectDrawSurface3_AddAttachedSurface,
1198 IDirectDrawSurface3_AddOverlayDirtyRect,
1199 IDirectDrawSurface3_Blt,
1200 IDirectDrawSurface3_BltBatch,
1201 IDirectDrawSurface3_BltFast,
1202 IDirectDrawSurface3_DeleteAttachedSurface,
1203 IDirectDrawSurface3_EnumAttachedSurfaces,
1204 IDirectDrawSurface3_EnumOverlayZOrders,
1205 DGA_IDirectDrawSurface3_Flip,
1206 IDirectDrawSurface3_GetAttachedSurface,
1207 IDirectDrawSurface3_GetBltStatus,
1208 IDirectDrawSurface3_GetCaps,
1209 IDirectDrawSurface3_GetClipper,
1210 IDirectDrawSurface3_GetColorKey,
1211 IDirectDrawSurface3_GetDC,
1212 IDirectDrawSurface3_GetFlipStatus,
1213 IDirectDrawSurface3_GetOverlayPosition,
1214 IDirectDrawSurface3_GetPalette,
1215 IDirectDrawSurface3_GetPixelFormat,
1216 IDirectDrawSurface3_GetSurfaceDesc,
1217 IDirectDrawSurface3_Initialize,
1218 IDirectDrawSurface3_IsLost,
1219 IDirectDrawSurface3_Lock,
1220 IDirectDrawSurface3_ReleaseDC,
1221 IDirectDrawSurface3_Restore,
1222 IDirectDrawSurface3_SetClipper,
1223 IDirectDrawSurface3_SetColorKey,
1224 IDirectDrawSurface3_SetOverlayPosition,
1225 DGA_IDirectDrawSurface3_SetPalette,
1226 DGA_IDirectDrawSurface3_Unlock,
1227 IDirectDrawSurface3_UpdateOverlay,
1228 IDirectDrawSurface3_UpdateOverlayDisplay,
1229 IDirectDrawSurface3_UpdateOverlayZOrder,
1230 IDirectDrawSurface3_GetDDInterface,
1231 IDirectDrawSurface3_PageLock,
1232 IDirectDrawSurface3_PageUnlock,
1233 IDirectDrawSurface3_SetSurfaceDesc,
1236 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1237 IDirectDrawSurface3_QueryInterface,
1238 IDirectDrawSurface3_AddRef,
1239 Xlib_IDirectDrawSurface3_Release,
1240 IDirectDrawSurface3_AddAttachedSurface,
1241 IDirectDrawSurface3_AddOverlayDirtyRect,
1242 IDirectDrawSurface3_Blt,
1243 IDirectDrawSurface3_BltBatch,
1244 IDirectDrawSurface3_BltFast,
1245 IDirectDrawSurface3_DeleteAttachedSurface,
1246 IDirectDrawSurface3_EnumAttachedSurfaces,
1247 IDirectDrawSurface3_EnumOverlayZOrders,
1248 Xlib_IDirectDrawSurface3_Flip,
1249 IDirectDrawSurface3_GetAttachedSurface,
1250 IDirectDrawSurface3_GetBltStatus,
1251 IDirectDrawSurface3_GetCaps,
1252 IDirectDrawSurface3_GetClipper,
1253 IDirectDrawSurface3_GetColorKey,
1254 IDirectDrawSurface3_GetDC,
1255 IDirectDrawSurface3_GetFlipStatus,
1256 IDirectDrawSurface3_GetOverlayPosition,
1257 IDirectDrawSurface3_GetPalette,
1258 IDirectDrawSurface3_GetPixelFormat,
1259 IDirectDrawSurface3_GetSurfaceDesc,
1260 IDirectDrawSurface3_Initialize,
1261 IDirectDrawSurface3_IsLost,
1262 IDirectDrawSurface3_Lock,
1263 IDirectDrawSurface3_ReleaseDC,
1264 IDirectDrawSurface3_Restore,
1265 IDirectDrawSurface3_SetClipper,
1266 IDirectDrawSurface3_SetColorKey,
1267 IDirectDrawSurface3_SetOverlayPosition,
1268 Xlib_IDirectDrawSurface3_SetPalette,
1269 Xlib_IDirectDrawSurface3_Unlock,
1270 IDirectDrawSurface3_UpdateOverlay,
1271 IDirectDrawSurface3_UpdateOverlayDisplay,
1272 IDirectDrawSurface3_UpdateOverlayZOrder,
1273 IDirectDrawSurface3_GetDDInterface,
1274 IDirectDrawSurface3_PageLock,
1275 IDirectDrawSurface3_PageUnlock,
1276 IDirectDrawSurface3_SetSurfaceDesc,
1279 /******************************************************************************
1280 * DirectDrawCreateClipper (DDRAW.7)
1282 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1283 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1284 LPUNKNOWN pUnkOuter)
1286 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1288 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1289 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1290 (*lplpDDClipper)->ref = 1;
1292 return DD_OK;
1295 /******************************************************************************
1296 * IDirectDrawClipper
1298 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1299 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1301 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1302 return DD_OK;
1305 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1306 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1308 this->ref--;
1309 if (this->ref)
1310 return this->ref;
1311 HeapFree(GetProcessHeap(),0,this);
1312 return 0;
1315 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1316 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1318 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1319 if (hmm) *hmm=0;
1320 return DD_OK;
1323 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1324 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1326 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1327 return DD_OK;
1330 static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
1331 LPDIRECTDRAWCLIPPER this,
1332 REFIID riid,
1333 LPVOID* ppvObj )
1335 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
1336 return OLE_E_ENUM_NOMORE;
1339 static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
1341 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1342 return ++(this->ref);
1345 static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
1346 LPDIRECTDRAWCLIPPER this,
1347 HWND32* HWndPtr )
1349 FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
1350 return DD_OK;
1353 static HRESULT WINAPI IDirectDrawClipper_Initialize(
1354 LPDIRECTDRAWCLIPPER this,
1355 LPDIRECTDRAW lpDD,
1356 DWORD dwFlags )
1358 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
1359 return DD_OK;
1362 static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
1363 LPDIRECTDRAWCLIPPER this,
1364 BOOL32* lpbChanged )
1366 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
1367 return DD_OK;
1370 static struct IDirectDrawClipper_VTable ddclipvt = {
1371 IDirectDrawClipper_QueryInterface,
1372 IDirectDrawClipper_AddRef,
1373 IDirectDrawClipper_Release,
1374 IDirectDrawClipper_GetClipList,
1375 IDirectDrawClipper_GetHWnd,
1376 IDirectDrawClipper_Initialize,
1377 IDirectDrawClipper_IsClipListChanged,
1378 IDirectDrawClipper_SetClipList,
1379 IDirectDrawClipper_SetHwnd
1383 /******************************************************************************
1384 * IDirectDrawPalette
1386 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1387 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1389 int i;
1391 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1392 this,x,start,count,palent);
1394 if (!this->cm) /* should not happen */ {
1395 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1396 return DDERR_GENERIC;
1398 for (i=0;i<count;i++) {
1399 palent[i].peRed = this->palents[start+i].peRed;
1400 palent[i].peBlue = this->palents[start+i].peBlue;
1401 palent[i].peGreen = this->palents[start+i].peGreen;
1402 palent[i].peFlags = this->palents[start+i].peFlags;
1405 return DD_OK;
1408 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1409 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1411 XColor xc;
1412 int i;
1414 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1415 this,x,start,count,palent
1417 for (i=0;i<count;i++) {
1418 xc.red = palent[i].peRed<<8;
1419 xc.blue = palent[i].peBlue<<8;
1420 xc.green = palent[i].peGreen<<8;
1421 xc.flags = DoRed|DoBlue|DoGreen;
1422 xc.pixel = start+i;
1424 if (this->cm)
1425 TSXStoreColor(display,this->cm,&xc);
1427 this->palents[start+i].peRed = palent[i].peRed;
1428 this->palents[start+i].peBlue = palent[i].peBlue;
1429 this->palents[start+i].peGreen = palent[i].peGreen;
1430 this->palents[start+i].peFlags = palent[i].peFlags;
1432 if (!this->cm) /* should not happen */ {
1434 return DD_OK;
1437 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1438 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1440 #ifdef HAVE_LIBXXF86DGA
1441 XColor xc;
1442 Colormap cm;
1443 int i;
1445 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1446 this,x,start,count,palent
1448 if (!this->cm) /* should not happen */ {
1449 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1450 return DDERR_GENERIC;
1452 /* FIXME: free colorcells instead of freeing whole map */
1453 cm = this->cm;
1454 this->cm = TSXCopyColormapAndFree(display,this->cm);
1455 TSXFreeColormap(display,cm);
1457 for (i=0;i<count;i++) {
1458 xc.red = palent[i].peRed<<8;
1459 xc.blue = palent[i].peBlue<<8;
1460 xc.green = palent[i].peGreen<<8;
1461 xc.flags = DoRed|DoBlue|DoGreen;
1462 xc.pixel = i+start;
1464 TSXStoreColor(display,this->cm,&xc);
1466 this->palents[start+i].peRed = palent[i].peRed;
1467 this->palents[start+i].peBlue = palent[i].peBlue;
1468 this->palents[start+i].peGreen = palent[i].peGreen;
1469 this->palents[start+i].peFlags = palent[i].peFlags;
1471 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1472 return DD_OK;
1473 #else /* defined(HAVE_LIBXXF86DGA) */
1474 return E_UNEXPECTED;
1475 #endif /* defined(HAVE_LIBXXF86DGA) */
1478 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1479 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1480 if (!--(this->ref)) {
1481 if (this->cm) {
1482 TSXFreeColormap(display,this->cm);
1483 this->cm = 0;
1485 HeapFree(GetProcessHeap(),0,this);
1486 return 0;
1488 return this->ref;
1491 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1493 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1494 return ++(this->ref);
1497 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1498 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1500 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1502 return DDERR_ALREADYINITIALIZED;
1505 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1506 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1508 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1509 return DD_OK;
1512 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1513 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1515 char xrefiid[50];
1517 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1518 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1520 return S_OK;
1523 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1524 IDirectDrawPalette_QueryInterface,
1525 IDirectDrawPalette_AddRef,
1526 IDirectDrawPalette_Release,
1527 IDirectDrawPalette_GetCaps,
1528 IDirectDrawPalette_GetEntries,
1529 IDirectDrawPalette_Initialize,
1530 DGA_IDirectDrawPalette_SetEntries
1533 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1534 IDirectDrawPalette_QueryInterface,
1535 IDirectDrawPalette_AddRef,
1536 IDirectDrawPalette_Release,
1537 IDirectDrawPalette_GetCaps,
1538 IDirectDrawPalette_GetEntries,
1539 IDirectDrawPalette_Initialize,
1540 Xlib_IDirectDrawPalette_SetEntries
1543 /*******************************************************************************
1544 * IDirect3D
1546 static HRESULT WINAPI IDirect3D_QueryInterface(
1547 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1549 /* FIXME: Not sure if this is correct */
1550 char xrefiid[50];
1552 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1553 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1554 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1555 *obj = this;
1556 this->lpvtbl->fnAddRef(this);
1557 return S_OK;
1559 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1560 LPDIRECT3D d3d;
1562 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1563 d3d->ref = 1;
1564 d3d->ddraw = (LPDIRECTDRAW)this;
1565 this->lpvtbl->fnAddRef(this);
1566 d3d->lpvtbl = &d3dvt;
1567 *obj = d3d;
1568 return S_OK;
1570 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1571 LPDIRECT3D2 d3d;
1573 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1574 d3d->ref = 1;
1575 d3d->ddraw = (LPDIRECTDRAW)this;
1576 this->lpvtbl->fnAddRef(this);
1577 d3d->lpvtbl = &d3d2vt;
1578 *obj = d3d;
1579 return S_OK;
1581 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1582 return OLE_E_ENUM_NOMORE;
1585 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1586 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1588 return ++(this->ref);
1591 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1593 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1595 if (!--(this->ref)) {
1596 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1597 HeapFree(GetProcessHeap(),0,this);
1598 return 0;
1600 return this->ref;
1603 static HRESULT WINAPI IDirect3D_Initialize(
1604 LPDIRECT3D this, REFIID refiid )
1606 /* FIXME: Not sure if this is correct */
1607 char xrefiid[50];
1609 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1610 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1612 return DDERR_ALREADYINITIALIZED;
1615 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,LPDIRECT3DLIGHT *light,IUnknown* lpunk) {
1616 FIXME(ddraw,"(%p)->(%p,%p)\n",this,light,lpunk);
1617 return E_FAIL;
1620 typedef LPVOID LPDIRECT3DDEVICE;
1622 static HRESULT WINAPI IDirect3D_CreateDevice(LPDIRECT3D this,LPCLSID rclsid,LPDIRECTDRAWSURFACE surf,LPDIRECT3DDEVICE *d3dev) {
1623 char xclsid[50];
1625 WINE_StringFromCLSID(rclsid,xclsid);
1626 FIXME(ddraw,"(%p)->(%s,%p,%p), no Direct3D devices implemented yet!\n",this,xclsid,surf,d3dev);
1627 return E_FAIL; /* D3DERR_INVALID_DEVICE probably */
1630 static HRESULT WINAPI IDirect3D_EnumDevices(
1631 LPDIRECT3D this,
1632 LPD3DENUMDEVICESCALLBACK a,
1633 LPVOID b )
1635 FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
1636 return DD_OK;
1639 static HRESULT WINAPI IDirect3D_CreateMaterial(
1640 LPDIRECT3D this,
1641 LPDIRECT3DMATERIAL* a,
1642 IUnknown* b)
1644 FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
1645 return DD_OK;
1648 static HRESULT WINAPI IDirect3D_CreateViewport(
1649 LPDIRECT3D this,
1650 LPDIRECT3DVIEWPORT* a,
1651 IUnknown* b )
1653 FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
1654 return DD_OK;
1657 static HRESULT WINAPI IDirect3D_FindDevice(
1658 LPDIRECT3D this,
1659 LPD3DFINDDEVICESEARCH a,
1660 LPD3DFINDDEVICERESULT b )
1662 FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
1663 return DD_OK;
1667 /*******************************************************************************
1668 * IDirect3D
1670 static struct IDirect3D_VTable d3dvt = {
1671 IDirect3D_QueryInterface,
1672 IDirect3D_AddRef,
1673 IDirect3D_Release,
1674 IDirect3D_Initialize,
1675 IDirect3D_EnumDevices,
1676 IDirect3D_CreateLight,
1677 IDirect3D_CreateMaterial,
1678 IDirect3D_CreateViewport,
1679 IDirect3D_FindDevice,
1682 /*******************************************************************************
1683 * IDirect3D2
1685 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1686 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1688 if (!--(this->ref)) {
1689 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1690 HeapFree(GetProcessHeap(),0,this);
1691 return 0;
1693 return this->ref;
1696 static HRESULT WINAPI IDirect3D2_EnumDevices(
1697 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1699 D3DDEVICEDESC d1,d2;
1701 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1702 #if 0
1703 d1.dwSize = sizeof(d1);
1704 d1.dwFlags = 0;
1706 d2.dwSize = sizeof(d2);
1707 d2.dwFlags = 0;
1708 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1709 #endif
1710 return DD_OK;
1713 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,REFCLSID rclsid,LPDIRECTDRAWSURFACE surf,LPDIRECT3DDEVICE2 *d3dev) {
1714 char xclsid[50];
1716 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
1717 FIXME(ddraw,"(%p)->(%s,%p,%p), no Direct3D devices implemented yet!\n",this,xclsid,surf,d3dev);
1718 return E_FAIL; /* D3DERR_INVALID_DEVICE probably */
1721 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,LPDIRECT3DLIGHT *light,IUnknown* lpunk) {
1722 FIXME(ddraw,"(%p)->(%p,%p)\n",this,light,lpunk);
1723 return E_FAIL;
1726 static struct IDirect3D2_VTable d3d2vt = {
1727 (void*)IDirect3D_QueryInterface,
1728 (void*)IDirect3D_AddRef,
1729 IDirect3D2_Release,
1730 IDirect3D2_EnumDevices,
1731 (void*)IDirect3D_EnumDevices,
1732 (void*)IDirect3D_CreateLight,
1733 (void*)IDirect3D_CreateMaterial,
1734 (void*)IDirect3D_CreateViewport,
1735 (void*)IDirect3D_FindDevice,
1738 /*******************************************************************************
1739 * IDirectDraw
1742 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1743 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1745 static INT32 ddrawXlibThisOffset = 0;
1747 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
1748 LPDDSURFACEDESC lpddsd,
1749 LPDIRECTDRAWSURFACE lpdsf)
1751 int bpp;
1753 /* The surface was already allocated when entering in this function */
1754 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
1755 /* No pixel format => use DirectDraw's format */
1756 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
1757 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
1758 } else {
1759 /* To check what the program wants */
1760 if (TRACE_ON(ddraw)) {
1761 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
1765 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
1767 /* Copy the surface description */
1768 lpdsf->s.surface_desc = *lpddsd;
1770 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1771 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
1772 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
1774 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
1776 return DD_OK;
1779 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1780 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1782 #ifdef HAVE_LIBXXF86DGA
1783 int i;
1785 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1786 if (TRACE_ON(ddraw)) {
1787 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1788 _dump_DDSD(lpddsd->dwFlags);
1789 fprintf(stderr,"caps ");
1790 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1791 fprintf(stderr,"]\n");
1794 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1795 this->lpvtbl->fnAddRef(this);
1797 (*lpdsf)->ref = 1;
1798 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1799 (*lpdsf)->s.ddraw = this;
1800 (*lpdsf)->s.palette = NULL;
1801 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
1803 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1804 lpddsd->dwWidth = this->d.width;
1805 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1806 lpddsd->dwHeight = this->d.height;
1808 /* Check if this a 'primary surface' or not */
1809 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1810 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1812 /* This is THE primary surface => there is DGA-specific code */
1813 /* First, store the surface description */
1814 (*lpdsf)->s.surface_desc = *lpddsd;
1816 /* Find a viewport */
1817 for (i=0;i<32;i++)
1818 if (!(this->e.dga.vpmask & (1<<i)))
1819 break;
1820 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1821 /* if i == 32 or maximum ... return error */
1822 this->e.dga.vpmask|=(1<<i);
1823 (*lpdsf)->s.surface_desc.y.lpSurface =
1824 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1825 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1826 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
1827 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
1829 /* Add flags if there were not present */
1830 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1831 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1832 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1833 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1834 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1835 (*lpdsf)->s.backbuffer = NULL;
1837 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1838 LPDIRECTDRAWSURFACE3 back;
1840 if (lpddsd->dwBackBufferCount>1)
1841 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1843 (*lpdsf)->s.backbuffer = back =
1844 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1845 this->lpvtbl->fnAddRef(this);
1846 back->ref = 1;
1847 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1848 for (i=0;i<32;i++)
1849 if (!(this->e.dga.vpmask & (1<<i)))
1850 break;
1851 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1852 /* if i == 32 or maximum ... return error */
1853 this->e.dga.vpmask|=(1<<i);
1854 back->t.dga.fb_height = i*this->e.dga.fb_height;
1856 /* Copy the surface description from the front buffer */
1857 back->s.surface_desc = (*lpdsf)->s.surface_desc;
1858 /* Change the parameters that are not the same */
1859 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
1860 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1861 back->s.ddraw = this;
1862 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1863 * one! */
1865 /* Add relevant info to front and back buffers */
1866 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1867 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
1868 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1869 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
1871 } else {
1872 /* There is no DGA-specific code here...
1873 Go to the common surface creation function */
1874 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
1877 return DD_OK;
1878 #else /* defined(HAVE_LIBXXF86DGA) */
1879 return E_UNEXPECTED;
1880 #endif /* defined(HAVE_LIBXXF86DGA) */
1883 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
1884 XImage *img;
1886 #ifdef HAVE_LIBXXSHM
1887 if (this->e.xlib.xshm_active) {
1888 img = TSXShmCreateImage(display,
1889 DefaultVisualOfScreen(screen),
1890 this->d.depth,
1891 ZPixmap,
1892 NULL,
1893 &(lpdsf->t.xlib.shminfo),
1894 lpdsf->s.surface_desc.dwWidth,
1895 lpdsf->s.surface_desc.dwHeight);
1897 if (img == NULL)
1898 return NULL;
1900 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
1901 if (lpdsf->t.xlib.shminfo.shmid < 0) {
1902 TSXDestroyImage(img);
1903 return NULL;
1906 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
1908 if (img->data == (char *) -1) {
1909 TSXDestroyImage(img);
1910 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1911 return NULL;
1913 lpdsf->t.xlib.shminfo.readOnly = False;
1915 TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
1916 TSXSync(display, False);
1918 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1920 lpdsf->s.surface_desc.y.lpSurface = img->data;
1921 } else {
1922 #endif
1923 /* Allocate surface memory */
1924 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1925 lpdsf->s.surface_desc.dwWidth *
1926 lpdsf->s.surface_desc.dwHeight *
1927 (this->d.depth / 8));
1929 /* In this case, create an XImage */
1930 img =
1931 TSXCreateImage(display,
1932 DefaultVisualOfScreen(screen),
1933 this->d.depth,
1934 ZPixmap,
1936 lpdsf->s.surface_desc.y.lpSurface,
1937 lpdsf->s.surface_desc.dwWidth,
1938 lpdsf->s.surface_desc.dwHeight,
1940 lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8)
1943 #ifdef HAVE_LIBXXSHM
1945 #endif
1946 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
1948 return img;
1951 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1952 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1954 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1955 this,lpddsd,lpdsf,lpunk);
1957 if (TRACE_ON(ddraw)) {
1958 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1959 _dump_DDSD(lpddsd->dwFlags);
1960 fprintf(stderr,"caps ");
1961 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1962 fprintf(stderr,"]\n");
1965 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1967 this->lpvtbl->fnAddRef(this);
1968 (*lpdsf)->s.ddraw = this;
1969 (*lpdsf)->ref = 1;
1970 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1971 (*lpdsf)->s.palette = NULL;
1972 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
1974 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1975 lpddsd->dwWidth = this->d.width;
1976 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1977 lpddsd->dwHeight = this->d.height;
1979 /* Check if this a 'primary surface' or not */
1980 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1981 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1982 XImage *img;
1984 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
1986 /* First, store the surface description */
1987 (*lpdsf)->s.surface_desc = *lpddsd;
1989 /* Create the XImage */
1990 img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
1991 if (img == NULL)
1992 return DDERR_OUTOFMEMORY;
1993 (*lpdsf)->t.xlib.image = img;
1995 /* Add flags if there were not present */
1996 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1997 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1998 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1999 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
2000 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2001 (*lpdsf)->s.backbuffer = NULL;
2003 /* Check for backbuffers */
2004 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2005 LPDIRECTDRAWSURFACE3 back;
2006 XImage *img;
2008 if (lpddsd->dwBackBufferCount>1)
2009 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2011 (*lpdsf)->s.backbuffer = back =
2012 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
2014 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2016 this->lpvtbl->fnAddRef(this);
2017 back->s.ddraw = this;
2019 back->ref = 1;
2020 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
2021 /* Copy the surface description from the front buffer */
2022 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2024 /* Create the XImage */
2025 img = create_ximage(this, back);
2026 if (img == NULL)
2027 return DDERR_OUTOFMEMORY;
2028 back->t.xlib.image = img;
2030 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2031 * one! */
2033 /* Add relevant info to front and back buffers */
2034 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2035 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2036 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2037 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2039 } else {
2040 /* There is no Xlib-specific code here...
2041 Go to the common surface creation function */
2042 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2045 return DD_OK;
2048 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
2049 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2051 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
2052 *dst = src; /* FIXME */
2053 return DD_OK;
2057 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2058 * even when the approbiate bitmasks are not specified.
2060 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
2061 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
2063 int i;
2064 const struct {
2065 int mask;
2066 char *name;
2067 } flagmap[] = {
2068 FE(DDSCL_FULLSCREEN)
2069 FE(DDSCL_ALLOWREBOOT)
2070 FE(DDSCL_NOWINDOWCHANGES)
2071 FE(DDSCL_NORMAL)
2072 FE(DDSCL_ALLOWMODEX)
2073 FE(DDSCL_EXCLUSIVE)
2074 FE(DDSCL_SETFOCUSWINDOW)
2075 FE(DDSCL_SETDEVICEWINDOW)
2076 FE(DDSCL_CREATEDEVICEWINDOW)
2079 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
2080 if(TRACE_ON(ddraw)){
2081 dbg_decl_str(ddraw, 512);
2082 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2083 if (flagmap[i].mask & cooplevel)
2084 dsprintf(ddraw, "%s ", flagmap[i].name);
2085 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2087 this->d.mainWindow = hwnd;
2088 return DD_OK;
2091 /* Small helper to either use the cooperative window or create a new
2092 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2094 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
2095 RECT32 rect;
2097 /* Do not destroy the application supplied cooperative window */
2098 if (this->d.window && this->d.window != this->d.mainWindow) {
2099 DestroyWindow32(this->d.window);
2100 this->d.window = 0;
2102 /* Sanity check cooperative window before assigning it to drawing. */
2103 if ( IsWindow32(this->d.mainWindow) &&
2104 IsWindowVisible32(this->d.mainWindow)
2106 GetWindowRect32(this->d.mainWindow,&rect);
2107 if (((rect.right-rect.left) >= this->d.width) &&
2108 ((rect.bottom-rect.top) >= this->d.height)
2110 this->d.window = this->d.mainWindow;
2112 /* ... failed, create new one. */
2113 if (!this->d.window) {
2114 this->d.window = CreateWindowEx32A(
2116 "WINE_DirectDraw",
2117 "WINE_DirectDraw",
2118 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2119 0,0,
2120 this->d.width,
2121 this->d.height,
2125 NULL
2127 /*Store THIS with the window. We'll use it in the window procedure*/
2128 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
2129 ShowWindow32(this->d.window,TRUE);
2130 UpdateWindow32(this->d.window);
2132 SetFocus32(this->d.window);
2135 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
2136 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2138 #ifdef HAVE_LIBXXF86DGA
2139 int i,*depths,depcount,mode_count;
2141 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2143 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2144 for (i=0;i<depcount;i++)
2145 if (depths[i]==depth)
2146 break;
2147 TSXFree(depths);
2148 if (i==depcount) {/* not found */
2149 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2150 return DDERR_UNSUPPORTEDMODE;
2152 if (this->d.width < width) {
2153 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2154 return DDERR_UNSUPPORTEDMODE;
2156 this->d.width = width;
2157 this->d.height = height;
2158 this->d.depth = depth;
2160 /* adjust fb_height, so we don't overlap */
2161 if (this->e.dga.fb_height < height)
2162 this->e.dga.fb_height = height;
2163 _common_IDirectDraw_SetDisplayMode(this);
2165 #ifdef HAVE_LIBXXF86VM
2167 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2168 XF86VidModeModeLine mod_tmp;
2169 int dotclock_tmp;
2171 /* save original video mode and set fullscreen if available*/
2172 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2173 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2174 orig_mode->hdisplay = mod_tmp.hdisplay;
2175 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2176 orig_mode->hsyncend = mod_tmp.hsyncend;
2177 orig_mode->htotal = mod_tmp.htotal;
2178 orig_mode->vdisplay = mod_tmp.vdisplay;
2179 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2180 orig_mode->vsyncend = mod_tmp.vsyncend;
2181 orig_mode->vtotal = mod_tmp.vtotal;
2182 orig_mode->flags = mod_tmp.flags;
2183 orig_mode->private = mod_tmp.private;
2185 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2186 for (i=0;i<mode_count;i++)
2188 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2190 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2191 *vidmode = *(all_modes[i]);
2192 break;
2193 } else
2194 TSXFree(all_modes[i]->private);
2196 TSXFree(all_modes);
2198 if (!vidmode)
2199 WARN(ddraw, "Fullscreen mode not available!\n");
2201 if (vidmode)
2203 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2204 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2207 #endif
2209 /* FIXME: this function OVERWRITES several signal handlers.
2210 * can we save them? and restore them later? In a way that
2211 * it works for the library too?
2213 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2214 #ifdef DIABLO_HACK
2215 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2216 #endif
2218 #ifdef RESTORE_SIGNALS
2219 SIGNAL_InitEmulator();
2220 #endif
2221 return DD_OK;
2222 #else /* defined(HAVE_LIBXXF86DGA) */
2223 return E_UNEXPECTED;
2224 #endif /* defined(HAVE_LIBXXF86DGA) */
2227 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2228 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2230 int i,*depths,depcount;
2231 char buf[200];
2233 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2234 this, width, height, depth);
2236 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2237 for (i=0;i<depcount;i++)
2238 if (depths[i]==depth)
2239 break;
2240 TSXFree(depths);
2241 if (i==depcount) {/* not found */
2242 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2243 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2244 return DDERR_UNSUPPORTEDMODE;
2246 this->d.width = width;
2247 this->d.height = height;
2248 this->d.depth = depth;
2250 _common_IDirectDraw_SetDisplayMode(this);
2252 this->e.xlib.paintable = 1;
2253 this->e.xlib.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window;
2254 /* We don't have a context for this window. Host off the desktop */
2255 if( !this->e.xlib.drawable )
2256 this->e.xlib.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
2257 return DD_OK;
2260 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2261 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2263 #ifdef HAVE_LIBXXF86DGA
2264 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2265 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2266 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2267 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2268 if (caps2) {
2269 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2270 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2271 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2273 return DD_OK;
2274 #else /* defined(HAVE_LIBXXF86DGA) */
2275 return E_UNEXPECTED;
2276 #endif /* defined(HAVE_LIBXXF86DGA) */
2279 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2280 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2282 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2283 /* FIXME: Xlib */
2284 caps1->dwVidMemTotal = 2048*1024;
2285 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2286 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2287 if (caps2) {
2288 caps2->dwVidMemTotal = 2048*1024;
2289 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2290 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2292 /* END FIXME: Xlib */
2293 return DD_OK;
2296 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2297 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2299 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2300 this,x,lpddclip,lpunk
2302 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2303 (*lpddclip)->ref = 1;
2304 (*lpddclip)->lpvtbl = &ddclipvt;
2305 return DD_OK;
2308 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2309 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2311 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2312 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2313 (*lpddpal)->ref = 1;
2314 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2315 (*lpddpal)->installed = 0;
2316 if (this->d.depth<=8) {
2317 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
2318 } else {
2319 /* we don't want palettes in hicolor or truecolor */
2320 (*lpddpal)->cm = 0;
2323 if (palent)
2325 /* Initialize the palette based on the passed palent struct */
2326 FIXME(ddraw,"needs to handle palent (%p)\n",palent);
2329 return DD_OK;
2332 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2333 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2335 HRESULT res;
2336 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2337 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
2338 if (res != 0) return res;
2339 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2340 return DD_OK;
2343 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2344 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2346 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2347 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2349 if (*lpddpal == NULL)
2350 return E_OUTOFMEMORY;
2352 (*lpddpal)->ref = 1;
2353 (*lpddpal)->installed = 0;
2354 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2356 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2357 this->lpvtbl->fnAddRef(this);
2359 if (palent)
2360 FIXME(ddraw,"needs to handle palent (%p)\n",palent);
2362 return DD_OK;
2365 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2366 #ifdef HAVE_LIBXXF86DGA
2367 TRACE(ddraw, "(%p)->()\n",this);
2368 Sleep(1000);
2369 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2370 #ifdef RESTORE_SIGNALS
2371 SIGNAL_InitEmulator();
2372 #endif
2373 return 0;
2374 #else /* defined(HAVE_LIBXXF86DGA) */
2375 return E_UNEXPECTED;
2376 #endif
2379 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2380 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
2381 Sleep(1000);
2382 return DD_OK;
2385 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
2386 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
2388 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
2389 return DD_OK;
2392 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
2393 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2395 return ++(this->ref);
2398 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2399 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2401 #ifdef HAVE_LIBXXF86DGA
2402 if (!--(this->ref)) {
2403 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2405 #ifdef HAVE_LIBXXF86VM
2406 if (orig_mode)
2407 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), orig_mode);
2408 if (orig_mode->privsize)
2409 TSXFree(orig_mode->private);
2410 free(orig_mode);
2411 orig_mode = NULL;
2412 #endif
2414 #ifdef RESTORE_SIGNALS
2415 SIGNAL_InitEmulator();
2416 #endif
2417 HeapFree(GetProcessHeap(),0,this);
2418 return 0;
2420 #endif /* defined(HAVE_LIBXXF86DGA) */
2421 return this->ref;
2424 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2425 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2427 if (!--(this->ref)) {
2428 HeapFree(GetProcessHeap(),0,this);
2429 return 0;
2431 /* FIXME: destroy window ... */
2432 return this->ref;
2435 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
2436 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2438 char xrefiid[50];
2440 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2441 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2442 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2443 *obj = this;
2444 this->lpvtbl->fnAddRef(this);
2445 return S_OK;
2447 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2448 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
2449 this->lpvtbl->fnAddRef(this);
2450 *obj = this;
2451 return S_OK;
2453 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2454 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
2455 this->lpvtbl->fnAddRef(this);
2456 *obj = this;
2457 return S_OK;
2459 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2460 LPDIRECT3D d3d;
2462 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2463 d3d->ref = 1;
2464 d3d->ddraw = (LPDIRECTDRAW)this;
2465 this->lpvtbl->fnAddRef(this);
2466 d3d->lpvtbl = &d3dvt;
2467 *obj = d3d;
2468 return S_OK;
2470 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2471 LPDIRECT3D2 d3d;
2473 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2474 d3d->ref = 1;
2475 d3d->ddraw = (LPDIRECTDRAW)this;
2476 this->lpvtbl->fnAddRef(this);
2477 d3d->lpvtbl = &d3d2vt;
2478 *obj = d3d;
2479 return S_OK;
2481 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2482 return OLE_E_ENUM_NOMORE;
2485 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
2486 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2488 char xrefiid[50];
2490 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2491 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2492 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2493 *obj = this;
2494 this->lpvtbl->fnAddRef(this);
2495 return S_OK;
2497 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2498 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2499 this->lpvtbl->fnAddRef(this);
2500 *obj = this;
2501 return S_OK;
2503 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2504 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2505 this->lpvtbl->fnAddRef(this);
2506 *obj = this;
2507 return S_OK;
2509 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2510 LPDIRECT3D d3d;
2512 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2513 d3d->ref = 1;
2514 d3d->ddraw = (LPDIRECTDRAW)this;
2515 this->lpvtbl->fnAddRef(this);
2516 d3d->lpvtbl = &d3dvt;
2517 *obj = d3d;
2518 return S_OK;
2520 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2521 LPDIRECT3D2 d3d;
2523 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2524 d3d->ref = 1;
2525 d3d->ddraw = (LPDIRECTDRAW)this;
2526 this->lpvtbl->fnAddRef(this);
2527 d3d->lpvtbl = &d3d2vt;
2528 *obj = d3d;
2529 return S_OK;
2531 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2532 return OLE_E_ENUM_NOMORE;
2535 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2536 LPDIRECTDRAW2 this,BOOL32 *status
2538 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2539 *status = TRUE;
2540 return DD_OK;
2543 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2544 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2546 DDSURFACEDESC ddsfd;
2547 static struct {
2548 int w,h;
2549 } modes[5] = { /* some of the usual modes */
2550 {512,384},
2551 {640,400},
2552 {640,480},
2553 {800,600},
2554 {1024,768},
2556 static int depths[4] = {8,16,24,32};
2557 int i,j;
2559 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2560 ddsfd.dwSize = sizeof(ddsfd);
2561 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2562 if (dwFlags & DDEDM_REFRESHRATES) {
2563 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2564 ddsfd.x.dwRefreshRate = 60;
2567 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2568 ddsfd.dwBackBufferCount = 1;
2569 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2570 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2571 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2572 /* FIXME: those masks would have to be set in depth > 8 */
2573 if (depths[i]==8) {
2574 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2575 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2576 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2577 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2578 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2579 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2580 } else {
2581 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2583 /* FIXME: We should query those from X itself */
2584 switch (depths[i]) {
2585 case 16:
2586 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2587 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2588 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2589 break;
2590 case 24:
2591 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2592 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2593 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2594 break;
2595 case 32:
2596 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2597 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2598 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2599 break;
2603 ddsfd.dwWidth = screenWidth;
2604 ddsfd.dwHeight = screenHeight;
2605 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2606 if (!modescb(&ddsfd,context)) return DD_OK;
2608 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2609 ddsfd.dwWidth = modes[j].w;
2610 ddsfd.dwHeight = modes[j].h;
2611 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2612 if (!modescb(&ddsfd,context)) return DD_OK;
2615 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2616 /* modeX is not standard VGA */
2618 ddsfd.dwHeight = 200;
2619 ddsfd.dwWidth = 320;
2620 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2621 if (!modescb(&ddsfd,context)) return DD_OK;
2624 return DD_OK;
2627 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2628 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2630 #ifdef HAVE_LIBXXF86DGA
2631 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2632 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2633 lpddsfd->dwHeight = screenHeight;
2634 lpddsfd->dwWidth = screenWidth;
2635 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2636 lpddsfd->dwBackBufferCount = 1;
2637 lpddsfd->x.dwRefreshRate = 60;
2638 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2639 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2640 return DD_OK;
2641 #else /* defined(HAVE_LIBXXF86DGA) */
2642 return E_UNEXPECTED;
2643 #endif /* defined(HAVE_LIBXXF86DGA) */
2646 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2647 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2649 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2650 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2651 lpddsfd->dwHeight = screenHeight;
2652 lpddsfd->dwWidth = screenWidth;
2653 /* POOLE FIXME: Xlib */
2654 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2655 /* END FIXME: Xlib */
2656 lpddsfd->dwBackBufferCount = 1;
2657 lpddsfd->x.dwRefreshRate = 60;
2658 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2659 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2660 return DD_OK;
2663 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2664 TRACE(ddraw,"(%p)->()\n",this);
2665 return DD_OK;
2668 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2669 LPDIRECTDRAW2 this,LPDWORD freq
2671 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2672 *freq = 60*100; /* 60 Hz */
2673 return DD_OK;
2676 /* what can we directly decompress? */
2677 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2678 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2680 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2681 return DD_OK;
2684 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2685 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2688 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2690 return DD_OK;
2693 static HRESULT WINAPI IDirectDraw2_Compact(
2694 LPDIRECTDRAW2 this )
2696 FIXME(ddraw,"(%p)->()\n", this );
2698 return DD_OK;
2702 /* Note: Hack so we can reuse the old functions without compiler warnings */
2703 #ifdef __GNUC__
2704 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2705 #else
2706 # define XCAST(fun) (void*)
2707 #endif
2709 static struct IDirectDraw_VTable dga_ddvt = {
2710 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2711 XCAST(AddRef)IDirectDraw2_AddRef,
2712 XCAST(Release)DGA_IDirectDraw2_Release,
2713 XCAST(Compact)IDirectDraw2_Compact,
2714 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2715 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2716 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2717 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2718 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2719 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2720 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2721 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2722 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2723 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2724 XCAST(GetGDISurface)15,
2725 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2726 XCAST(GetScanLine)17,
2727 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2728 XCAST(Initialize)19,
2729 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2730 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2731 DGA_IDirectDraw_SetDisplayMode,
2732 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2735 static struct IDirectDraw_VTable xlib_ddvt = {
2736 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2737 XCAST(AddRef)IDirectDraw2_AddRef,
2738 XCAST(Release)Xlib_IDirectDraw2_Release,
2739 XCAST(Compact)IDirectDraw2_Compact,
2740 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2741 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2742 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2743 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2744 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2745 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2746 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2747 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2748 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2749 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2750 XCAST(GetGDISurface)15,
2751 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2752 XCAST(GetScanLine)17,
2753 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2754 XCAST(Initialize)19,
2755 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2756 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2757 Xlib_IDirectDraw_SetDisplayMode,
2758 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2761 /*****************************************************************************
2762 * IDirectDraw2
2767 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2768 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2770 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2773 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2774 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2776 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2779 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2780 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2782 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2783 this,ddscaps,total,free
2785 if (total) *total = this->e.dga.fb_memsize * 1024;
2786 if (free) *free = this->e.dga.fb_memsize * 1024;
2787 return DD_OK;
2790 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2791 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2793 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2794 this,ddscaps,total,free
2796 if (total) *total = 2048 * 1024;
2797 if (free) *free = 2048 * 1024;
2798 return DD_OK;
2801 static IDirectDraw2_VTable dga_dd2vt = {
2802 DGA_IDirectDraw2_QueryInterface,
2803 IDirectDraw2_AddRef,
2804 DGA_IDirectDraw2_Release,
2805 IDirectDraw2_Compact,
2806 IDirectDraw2_CreateClipper,
2807 DGA_IDirectDraw2_CreatePalette,
2808 DGA_IDirectDraw2_CreateSurface,
2809 (void*)8,
2810 IDirectDraw2_EnumDisplayModes,
2811 IDirectDraw2_EnumSurfaces,
2812 IDirectDraw2_FlipToGDISurface,
2813 DGA_IDirectDraw2_GetCaps,
2814 DGA_IDirectDraw2_GetDisplayMode,
2815 IDirectDraw2_GetFourCCCodes,
2816 (void*)15,
2817 IDirectDraw2_GetMonitorFrequency,
2818 (void*)17,
2819 IDirectDraw2_GetVerticalBlankStatus,
2820 (void*)19,
2821 DGA_IDirectDraw2_RestoreDisplayMode,
2822 IDirectDraw2_SetCooperativeLevel,
2823 DGA_IDirectDraw2_SetDisplayMode,
2824 IDirectDraw2_WaitForVerticalBlank,
2825 DGA_IDirectDraw2_GetAvailableVidMem
2828 static struct IDirectDraw2_VTable xlib_dd2vt = {
2829 Xlib_IDirectDraw2_QueryInterface,
2830 IDirectDraw2_AddRef,
2831 Xlib_IDirectDraw2_Release,
2832 IDirectDraw2_Compact,
2833 IDirectDraw2_CreateClipper,
2834 Xlib_IDirectDraw2_CreatePalette,
2835 Xlib_IDirectDraw2_CreateSurface,
2836 (void*)8,
2837 IDirectDraw2_EnumDisplayModes,
2838 IDirectDraw2_EnumSurfaces,
2839 IDirectDraw2_FlipToGDISurface,
2840 Xlib_IDirectDraw2_GetCaps,
2841 Xlib_IDirectDraw2_GetDisplayMode,
2842 IDirectDraw2_GetFourCCCodes,
2843 (void*)15,
2844 IDirectDraw2_GetMonitorFrequency,
2845 (void*)17,
2846 IDirectDraw2_GetVerticalBlankStatus,
2847 (void*)19,
2848 Xlib_IDirectDraw2_RestoreDisplayMode,
2849 IDirectDraw2_SetCooperativeLevel,
2850 Xlib_IDirectDraw2_SetDisplayMode,
2851 IDirectDraw2_WaitForVerticalBlank,
2852 Xlib_IDirectDraw2_GetAvailableVidMem
2855 /******************************************************************************
2856 * DirectDrawCreate
2859 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2861 LRESULT ret;
2862 LPDIRECTDRAW ddraw = NULL;
2863 DWORD lastError;
2865 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2867 SetLastError( ERROR_SUCCESS );
2868 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2869 if( (!ddraw) &&
2870 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2873 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2876 if( ddraw )
2878 /* Perform any special direct draw functions */
2879 if (msg==WM_PAINT)
2880 ddraw->e.xlib.paintable = 1;
2882 /* Now let the application deal with the rest of this */
2883 if( ddraw->d.mainWindow )
2886 /* Don't think that we actually need to call this but...
2887 might as well be on the safe side of things... */
2889 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
2890 it should be the procedures of our fake window that gets called
2891 instead of those of the window provided by the application.
2892 And with this patch, mouse clicks work with Monkey Island III
2893 - Lionel */
2894 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2896 if( !ret )
2898 /* We didn't handle the message - give it to the application */
2899 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
2900 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2901 ddraw->d.mainWindow, msg, wParam, lParam );
2905 } else {
2906 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
2910 else
2912 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2915 return ret;
2918 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2919 #ifdef HAVE_LIBXXF86DGA
2920 int memsize,banksize,width,major,minor,flags,height;
2921 char *addr;
2922 int fd;
2924 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
2925 if ((fd = open("/dev/mem", O_RDWR)) != -1)
2926 close(fd);
2928 if (fd == -1) {
2929 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
2930 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2931 return E_UNEXPECTED;
2933 if (!DDRAW_DGA_Available()) {
2934 TRACE(ddraw,"No XF86DGA detected.\n");
2935 return DDERR_GENERIC;
2937 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2938 (*lplpDD)->lpvtbl = &dga_ddvt;
2939 (*lplpDD)->ref = 1;
2940 TSXF86DGAQueryVersion(display,&major,&minor);
2941 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2942 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2943 if (!(flags & XF86DGADirectPresent))
2944 MSG("direct video is NOT PRESENT.\n");
2945 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2946 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2947 addr,width,banksize,memsize
2949 (*lplpDD)->e.dga.fb_width = width;
2950 (*lplpDD)->d.width = width;
2951 (*lplpDD)->e.dga.fb_addr = addr;
2952 (*lplpDD)->e.dga.fb_memsize = memsize;
2953 (*lplpDD)->e.dga.fb_banksize = banksize;
2955 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2956 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2957 (*lplpDD)->e.dga.fb_height = screenHeight;
2958 #ifdef DIABLO_HACK
2959 (*lplpDD)->e.dga.vpmask = 1;
2960 #else
2961 (*lplpDD)->e.dga.vpmask = 0;
2962 #endif
2964 /* just assume the default depth is the DGA depth too */
2965 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2966 #ifdef RESTORE_SIGNALS
2967 SIGNAL_InitEmulator();
2968 #endif
2970 return DD_OK;
2971 #else /* defined(HAVE_LIBXXF86DGA) */
2972 return DDERR_INVALIDDIRECTDRAWGUID;
2973 #endif /* defined(HAVE_LIBXXF86DGA) */
2976 BOOL32
2977 DDRAW_XSHM_Available()
2979 #ifdef HAVE_LIBXXSHM
2980 if (TSXShmQueryExtension(display))
2982 int major, minor;
2983 Bool shpix;
2985 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
2986 return 1;
2987 else
2988 return 0;
2990 else
2991 return 0;
2992 #else
2993 return 0;
2994 #endif
2997 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2999 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3000 (*lplpDD)->lpvtbl = &xlib_ddvt;
3001 (*lplpDD)->ref = 1;
3002 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
3004 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
3005 (*lplpDD)->d.height = screenHeight;
3006 (*lplpDD)->d.width = screenWidth;
3008 #ifdef HAVE_LIBXXSHM
3009 /* Test if XShm is available.
3010 As XShm is not ready yet for 'prime-time', it is disabled for now */
3011 if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
3012 TRACE(ddraw, "Using XShm extesion.\n");
3013 #endif
3015 return DD_OK;
3018 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
3019 char xclsid[50];
3020 WNDCLASS32A wc;
3021 WND* pParentWindow;
3022 HRESULT ret;
3024 if (HIWORD(lpGUID))
3025 WINE_StringFromCLSID(lpGUID,xclsid);
3026 else {
3027 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
3028 lpGUID = NULL;
3031 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
3033 if (!lpGUID) {
3034 /* if they didn't request a particular interface, use the best
3035 * supported one */
3036 if (DDRAW_DGA_Available())
3037 lpGUID = &DGA_DirectDraw_GUID;
3038 else
3039 lpGUID = &XLIB_DirectDraw_GUID;
3042 wc.style = CS_GLOBALCLASS;
3043 wc.lpfnWndProc = Xlib_DDWndProc;
3044 wc.cbClsExtra = 0;
3045 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
3046 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
3048 /* We can be a child of the desktop since we're really important */
3049 pParentWindow = WIN_GetDesktop();
3050 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
3051 wc.hInstance = 0;
3053 wc.hIcon = 0;
3054 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
3055 wc.hbrBackground= NULL_BRUSH;
3056 wc.lpszMenuName = 0;
3057 wc.lpszClassName= "WINE_DirectDraw";
3058 RegisterClass32A(&wc);
3060 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
3061 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
3062 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
3063 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
3064 else
3065 goto err;
3067 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
3068 return ret;
3070 err:
3071 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
3072 return DDERR_INVALIDDIRECTDRAWGUID;