- beginning of implementation of Direct3D2 (DX 5.0) and associated classes
[wine/multimedia.git] / graphics / ddraw.c
blobe0a61b3ea29305247aaf73f6286eb362de171fac
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
5 */
6 /* XF86DGA:
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
10 * is running.
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
17 #include "config.h"
18 #include <unistd.h>
19 #include <assert.h>
20 #include "ts_xlib.h"
21 #include "ts_xutil.h"
22 #include <sys/signal.h>
23 #include <fcntl.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include "windows.h"
28 #ifdef HAVE_LIBXXF86VM
29 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
30 this is a crude hack to get around it */
31 #define XMD_H
32 #include "ts_xf86vmode.h"
33 #endif
35 #include "winerror.h"
36 #include "interfaces.h"
37 #include "gdi.h"
38 #include "heap.h"
39 #include "ldt.h"
40 #include "dc.h"
41 #include "win.h"
42 #include "miscemu.h"
43 #include "ddraw.h"
44 #include "d3d.h"
45 #include "debug.h"
46 #include "compobj.h"
47 #include "spy.h"
48 #include "message.h"
49 #include "x11drv.h"
50 #include "options.h"
52 #ifdef HAVE_LIBXXF86DGA
53 #include "ts_xf86dga.h"
54 #endif
56 #ifdef HAVE_LIBXXSHM
57 #include <sys/types.h>
58 #include <sys/ipc.h>
59 #include <sys/shm.h>
60 #include "ts_xshm.h"
61 #endif
63 /* This for all the enumeration and creation of D3D-related objects */
64 #include "d3d_private.h"
66 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
67 #undef DIABLO_HACK
69 /* Restore signal handlers overwritten by XF86DGA
70 * this is a define, for it will only work in emulator mode
72 #undef RESTORE_SIGNALS
74 /* Where do these GUIDs come from? mkuuid.
75 * They exist solely to distinguish between the targets Wine support,
76 * and should be different than any other GUIDs in existence.
78 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
79 0xe2dcb020,
80 0xdc60,
81 0x11d1,
82 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
85 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
86 0x1574a740,
87 0xdc61,
88 0x11d1,
89 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
92 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
93 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
94 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
95 static struct IDirectDrawClipper_VTable ddclipvt;
96 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
97 static struct IDirect3D_VTable d3dvt;
98 static struct IDirect3D2_VTable d3d2vt;
100 #ifdef HAVE_LIBXXF86VM
101 static XF86VidModeModeInfo *orig_mode = NULL;
102 #endif
104 BOOL32
105 DDRAW_DGA_Available()
107 #ifdef HAVE_LIBXXF86DGA
108 int evbase, evret, fd;
110 if (Options.noDGA)
111 return 0;
113 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
114 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
115 /* others. --stephenc */
116 if ((fd = open("/dev/mem", O_RDWR)) != -1)
117 close(fd);
119 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
120 #else /* defined(HAVE_LIBXXF86DGA) */
121 return 0;
122 #endif /* defined(HAVE_LIBXXF86DGA) */
125 HRESULT WINAPI
126 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
127 if (DDRAW_DGA_Available()) {
128 TRACE(ddraw, "Enumerating DGA interface\n");
129 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
131 TRACE(ddraw, "Enumerating Xlib interface\n");
132 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
133 TRACE(ddraw, "Enumerating Default interface\n");
134 ddenumproc(NULL,"WINE (default)","display",data);
135 return DD_OK;
138 /* What is this doing here? */
139 HRESULT WINAPI
140 DSoundHelp(DWORD x,DWORD y,DWORD z) {
141 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
142 return 0;
146 /******************************************************************************
147 * internal helper functions
149 static void _dump_DDBLTFX(DWORD flagmask) {
150 int i;
151 const struct {
152 DWORD mask;
153 char *name;
154 } flags[] = {
155 #define FE(x) { x, #x},
156 FE(DDBLTFX_ARITHSTRETCHY)
157 FE(DDBLTFX_MIRRORLEFTRIGHT)
158 FE(DDBLTFX_MIRRORUPDOWN)
159 FE(DDBLTFX_NOTEARING)
160 FE(DDBLTFX_ROTATE180)
161 FE(DDBLTFX_ROTATE270)
162 FE(DDBLTFX_ROTATE90)
163 FE(DDBLTFX_ZBUFFERRANGE)
164 FE(DDBLTFX_ZBUFFERBASEDEST)
166 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
167 if (flags[i].mask & flagmask) {
168 DUMP("%s ",flags[i].name);
171 DUMP("\n");
175 static void _dump_DDBLTFAST(DWORD flagmask) {
176 int i;
177 const struct {
178 DWORD mask;
179 char *name;
180 } flags[] = {
181 #define FE(x) { x, #x},
182 FE(DDBLTFAST_NOCOLORKEY)
183 FE(DDBLTFAST_SRCCOLORKEY)
184 FE(DDBLTFAST_DESTCOLORKEY)
185 FE(DDBLTFAST_WAIT)
187 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
188 if (flags[i].mask & flagmask)
189 DUMP("%s ",flags[i].name);
190 DUMP("\n");
193 static void _dump_DDBLT(DWORD flagmask) {
194 int i;
195 const struct {
196 DWORD mask;
197 char *name;
198 } flags[] = {
199 #define FE(x) { x, #x},
200 FE(DDBLT_ALPHADEST)
201 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
202 FE(DDBLT_ALPHADESTNEG)
203 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
204 FE(DDBLT_ALPHAEDGEBLEND)
205 FE(DDBLT_ALPHASRC)
206 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
207 FE(DDBLT_ALPHASRCNEG)
208 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
209 FE(DDBLT_ASYNC)
210 FE(DDBLT_COLORFILL)
211 FE(DDBLT_DDFX)
212 FE(DDBLT_DDROPS)
213 FE(DDBLT_KEYDEST)
214 FE(DDBLT_KEYDESTOVERRIDE)
215 FE(DDBLT_KEYSRC)
216 FE(DDBLT_KEYSRCOVERRIDE)
217 FE(DDBLT_ROP)
218 FE(DDBLT_ROTATIONANGLE)
219 FE(DDBLT_ZBUFFER)
220 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
221 FE(DDBLT_ZBUFFERDESTOVERRIDE)
222 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
223 FE(DDBLT_ZBUFFERSRCOVERRIDE)
224 FE(DDBLT_WAIT)
225 FE(DDBLT_DEPTHFILL)
227 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
228 if (flags[i].mask & flagmask)
229 DUMP("%s ",flags[i].name);
232 static void _dump_DDSCAPS(DWORD flagmask) {
233 int i;
234 const struct {
235 DWORD mask;
236 char *name;
237 } flags[] = {
238 #define FE(x) { x, #x},
239 FE(DDSCAPS_RESERVED1)
240 FE(DDSCAPS_ALPHA)
241 FE(DDSCAPS_BACKBUFFER)
242 FE(DDSCAPS_COMPLEX)
243 FE(DDSCAPS_FLIP)
244 FE(DDSCAPS_FRONTBUFFER)
245 FE(DDSCAPS_OFFSCREENPLAIN)
246 FE(DDSCAPS_OVERLAY)
247 FE(DDSCAPS_PALETTE)
248 FE(DDSCAPS_PRIMARYSURFACE)
249 FE(DDSCAPS_PRIMARYSURFACELEFT)
250 FE(DDSCAPS_SYSTEMMEMORY)
251 FE(DDSCAPS_TEXTURE)
252 FE(DDSCAPS_3DDEVICE)
253 FE(DDSCAPS_VIDEOMEMORY)
254 FE(DDSCAPS_VISIBLE)
255 FE(DDSCAPS_WRITEONLY)
256 FE(DDSCAPS_ZBUFFER)
257 FE(DDSCAPS_OWNDC)
258 FE(DDSCAPS_LIVEVIDEO)
259 FE(DDSCAPS_HWCODEC)
260 FE(DDSCAPS_MODEX)
261 FE(DDSCAPS_MIPMAP)
262 FE(DDSCAPS_RESERVED2)
263 FE(DDSCAPS_ALLOCONLOAD)
264 FE(DDSCAPS_VIDEOPORT)
265 FE(DDSCAPS_LOCALVIDMEM)
266 FE(DDSCAPS_NONLOCALVIDMEM)
267 FE(DDSCAPS_STANDARDVGAMODE)
268 FE(DDSCAPS_OPTIMIZED)
270 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
271 if (flags[i].mask & flagmask)
272 DUMP("%s ",flags[i].name);
273 DUMP("\n");
276 static void _dump_DDSD(DWORD flagmask) {
277 int i;
278 const struct {
279 DWORD mask;
280 char *name;
281 } flags[] = {
282 FE(DDSD_CAPS)
283 FE(DDSD_HEIGHT)
284 FE(DDSD_WIDTH)
285 FE(DDSD_PITCH)
286 FE(DDSD_BACKBUFFERCOUNT)
287 FE(DDSD_ZBUFFERBITDEPTH)
288 FE(DDSD_ALPHABITDEPTH)
289 FE(DDSD_PIXELFORMAT)
290 FE(DDSD_CKDESTOVERLAY)
291 FE(DDSD_CKDESTBLT)
292 FE(DDSD_CKSRCOVERLAY)
293 FE(DDSD_CKSRCBLT)
294 FE(DDSD_MIPMAPCOUNT)
295 FE(DDSD_REFRESHRATE)
296 FE(DDSD_LINEARSIZE)
297 FE(DDSD_LPSURFACE)
299 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
300 if (flags[i].mask & flagmask)
301 DUMP("%s ",flags[i].name);
302 DUMP("\n");
305 static void _dump_DDCOLORKEY(DWORD flagmask) {
306 int i;
307 const struct {
308 DWORD mask;
309 char *name;
310 } flags[] = {
311 #define FE(x) { x, #x},
312 FE(DDPF_ALPHAPIXELS)
313 FE(DDPF_ALPHA)
314 FE(DDPF_FOURCC)
315 FE(DDPF_PALETTEINDEXED4)
316 FE(DDPF_PALETTEINDEXEDTO8)
317 FE(DDPF_PALETTEINDEXED8)
318 FE(DDPF_RGB)
319 FE(DDPF_COMPRESSED)
320 FE(DDPF_RGBTOYUV)
321 FE(DDPF_YUV)
322 FE(DDPF_ZBUFFER)
323 FE(DDPF_PALETTEINDEXED1)
324 FE(DDPF_PALETTEINDEXED2)
325 FE(DDPF_ZPIXELS)
327 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
328 if (flags[i].mask & flagmask)
329 DUMP("%s ",flags[i].name);
330 DUMP("\n");
333 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
334 DUMP("Size : %ld\n", pf->dwSize);
335 if (pf->dwFlags)
336 _dump_DDCOLORKEY(pf->dwFlags);
337 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
338 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
339 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
340 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
343 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
344 static XVisualInfo *vi;
345 XVisualInfo vt;
346 int nitems;
348 if (!vi)
349 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
351 pf->dwFourCC = 0;
352 pf->dwSize = sizeof(DDPIXELFORMAT);
353 if (ddraw->d.depth==8) {
354 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
355 pf->x.dwRGBBitCount = 8;
356 pf->y.dwRBitMask = 0;
357 pf->z.dwGBitMask = 0;
358 pf->xx.dwBBitMask = 0;
359 pf->xy.dwRGBAlphaBitMask= 0;
360 return 0;
362 if (ddraw->d.depth==16) {
363 pf->dwFlags = DDPF_RGB;
364 pf->x.dwRGBBitCount = 16;
365 pf->y.dwRBitMask = vi[0].red_mask;
366 pf->z.dwGBitMask = vi[0].green_mask;
367 pf->xx.dwBBitMask = vi[0].blue_mask;
368 pf->xy.dwRGBAlphaBitMask= 0;
369 return 0;
371 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
372 return DDERR_GENERIC;
375 /******************************************************************************
376 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
378 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
379 * DDS and DDS2 use those functions. (Function calls did not change (except
380 * using different DirectDrawSurfaceX version), just added flags and functions)
382 static HRESULT WINAPI IDirectDrawSurface3_Lock(
383 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
385 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
386 this,lprect,lpddsd,flags,(DWORD)hnd);
387 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
388 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
389 this,lprect,lpddsd,flags,(DWORD)hnd);
391 /* First, copy the Surface description */
392 *lpddsd = this->s.surface_desc;
394 /* If asked only for a part, change the surface pointer */
395 if (lprect) {
396 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
397 lprect->top,lprect->left,lprect->bottom,lprect->right
399 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
400 (lprect->top*this->s.surface_desc.lPitch) +
401 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
402 } else {
403 assert(this->s.surface_desc.y.lpSurface);
405 return DD_OK;
408 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
409 LPDIRECTDRAWSURFACE3 this,LPVOID surface
411 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
412 return DD_OK;
415 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
416 LPDIRECTDRAWSURFACE3 this,LPVOID surface)
418 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
420 if (!this->s.ddraw->e.xlib.paintable)
421 return DD_OK;
423 /* Only redraw the screen when unlocking the buffer that is on screen */
424 if ((this->t.xlib.image != NULL) &&
425 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
426 #ifdef HAVE_LIBXXSHM
427 if (this->s.ddraw->e.xlib.xshm_active)
428 TSXShmPutImage(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,
435 False);
436 else
437 #endif
438 TSXPutImage( display,
439 this->s.ddraw->e.xlib.drawable,
440 DefaultGCOfScreen(screen),
441 this->t.xlib.image,
442 0, 0, 0, 0,
443 this->t.xlib.image->width,
444 this->t.xlib.image->height);
446 if (this->s.palette && this->s.palette->cm)
447 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
450 return DD_OK;
453 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
454 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
456 #ifdef HAVE_LIBXXF86DGA
457 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
458 if (!flipto) {
459 if (this->s.backbuffer)
460 flipto = this->s.backbuffer;
461 else
462 flipto = this;
464 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
466 if (flipto->s.palette && flipto->s.palette->cm) {
467 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
469 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
471 if (flipto!=this) {
472 int tmp;
473 LPVOID ptmp;
475 tmp = this->t.dga.fb_height;
476 this->t.dga.fb_height = flipto->t.dga.fb_height;
477 flipto->t.dga.fb_height = tmp;
479 ptmp = this->s.surface_desc.y.lpSurface;
480 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
481 flipto->s.surface_desc.y.lpSurface = ptmp;
483 return DD_OK;
484 #else /* defined(HAVE_LIBXXF86DGA) */
485 return E_UNEXPECTED;
486 #endif /* defined(HAVE_LIBXXF86DGA) */
489 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
490 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
492 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
493 if (!this->s.ddraw->e.xlib.paintable)
494 return DD_OK;
496 if (!flipto) {
497 if (this->s.backbuffer)
498 flipto = this->s.backbuffer;
499 else
500 flipto = this;
503 #ifdef HAVE_LIBXXSHM
504 if (this->s.ddraw->e.xlib.xshm_active) {
505 TSXShmPutImage(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,
512 False);
513 } else
514 #endif
515 TSXPutImage(display,
516 this->s.ddraw->e.xlib.drawable,
517 DefaultGCOfScreen(screen),
518 flipto->t.xlib.image,
519 0, 0, 0, 0,
520 flipto->t.xlib.image->width,
521 flipto->t.xlib.image->height);
523 if (flipto->s.palette && flipto->s.palette->cm) {
524 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,flipto->s.palette->cm);
526 if (flipto!=this) {
527 XImage *tmp;
528 LPVOID *surf;
529 tmp = this->t.xlib.image;
530 this->t.xlib.image = flipto->t.xlib.image;
531 flipto->t.xlib.image = tmp;
532 surf = this->s.surface_desc.y.lpSurface;
533 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
534 flipto->s.surface_desc.y.lpSurface = surf;
536 return DD_OK;
540 /* The IDirectDrawSurface3::SetPalette method attaches the specified
541 * DirectDrawPalette object to a surface. The surface uses this palette for all
542 * subsequent operations. The palette change takes place immediately.
544 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
545 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
547 int i;
548 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
550 if( !(pal->cm) && (this->s.ddraw->d.depth<=8))
552 pal->cm = TSXCreateColormap(display,this->s.ddraw->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
554 /* FIXME: this is not correct, when using -managed (XSetWindowColormap??) */
555 TSXInstallColormap(display,pal->cm);
557 for (i=0;i<256;i++) {
558 XColor xc;
560 xc.red = pal->palents[i].peRed<<8;
561 xc.blue = pal->palents[i].peBlue<<8;
562 xc.green = pal->palents[i].peGreen<<8;
563 xc.flags = DoRed|DoBlue|DoGreen;
564 xc.pixel = i;
565 TSXStoreColor(display,pal->cm,&xc);
569 /* According to spec, we are only supposed to
570 * AddRef if this is not the same palette.
572 if( this->s.palette != pal )
574 if( pal != NULL )
575 pal->lpvtbl->fnAddRef( pal );
576 if( this->s.palette != NULL )
577 this->s.palette->lpvtbl->fnRelease( this->s.palette );
578 this->s.palette = pal;
580 /* I think that we need to attach it to all backbuffers...*/
581 if( this->s.backbuffer ) {
582 if( this->s.backbuffer->s.palette )
583 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
584 this->s.backbuffer->s.palette );
585 this->s.backbuffer->s.palette = pal;
586 if( pal )
587 pal->lpvtbl->fnAddRef( pal );
589 /* Perform the refresh */
590 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
592 return DD_OK;
595 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
596 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
598 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
599 #ifdef HAVE_LIBXXF86DGA
600 /* According to spec, we are only supposed to
601 * AddRef if this is not the same palette.
603 if( this->s.palette != pal )
605 if( pal != NULL )
606 pal->lpvtbl->fnAddRef( pal );
607 if( this->s.palette != NULL )
608 this->s.palette->lpvtbl->fnRelease( this->s.palette );
609 this->s.palette = pal;
611 /* I think that we need to attach it to all backbuffers...*/
612 if( this->s.backbuffer ) {
613 if( this->s.backbuffer->s.palette )
614 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
615 this->s.backbuffer->s.palette = pal;
616 if( pal ) pal->lpvtbl->fnAddRef( pal );
618 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
620 return DD_OK;
621 #else /* defined(HAVE_LIBXXF86DGA) */
622 return E_UNEXPECTED;
623 #endif /* defined(HAVE_LIBXXF86DGA) */
628 static HRESULT WINAPI IDirectDrawSurface3_Blt(
629 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
631 RECT32 xdst,xsrc;
632 DDSURFACEDESC ddesc,sdesc;
633 int i,j;
635 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
636 this,rdst,src,rsrc,dwFlags,lpbltfx);
638 if (src != NULL)
639 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
640 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
642 if (TRACE_ON(ddraw)) {
643 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
644 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
645 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
646 if (dwFlags & DDBLT_DDFX) {
647 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
651 if (rdst) {
652 memcpy(&xdst,rdst,sizeof(xdst));
653 } else {
654 xdst.top = 0;
655 xdst.bottom = ddesc.dwHeight;
656 xdst.left = 0;
657 xdst.right = ddesc.dwWidth;
660 if (rsrc) {
661 memcpy(&xsrc,rsrc,sizeof(xsrc));
662 } else {
663 if (src) {
664 xsrc.top = 0;
665 xsrc.bottom = sdesc.dwHeight;
666 xsrc.left = 0;
667 xsrc.right = sdesc.dwWidth;
668 } else {
669 memset(&xsrc,0,sizeof(xsrc));
673 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
675 if (dwFlags & DDBLT_COLORFILL) {
676 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
677 LPBYTE xline,xpixel;
679 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
680 for (i=xdst.top;i<xdst.bottom;i++) {
681 xpixel = xline+bpp*xdst.left;
683 for (j=xdst.left;j<xdst.right;j++) {
684 /* FIXME: this only works on little endian
685 * architectures, where DWORD starts with low
686 * byte first!
688 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
689 xpixel += bpp;
691 xline += ddesc.lPitch;
693 dwFlags &= ~(DDBLT_COLORFILL);
696 if (!src) {
697 if (dwFlags) {
698 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
700 return DD_OK;
703 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
704 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
705 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
706 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
707 !dwFlags
709 memcpy(ddesc.y.lpSurface,
710 sdesc.y.lpSurface,
711 ddesc.dwHeight * ddesc.lPitch);
712 } else {
713 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
714 int srcheight = xsrc.bottom - xsrc.top;
715 int srcwidth = xsrc.right - xsrc.left;
716 int dstheight = xdst.bottom - xdst.top;
717 int dstwidth = xdst.right - xdst.left;
718 int width = (xsrc.right - xsrc.left) * bpp;
719 int h;
721 /* Sanity check for rectangle sizes */
722 if ((srcheight != dstheight) || (srcwidth != dstwidth)) {
723 int x, y;
725 /* I think we should do a Blit with 'stretching' here....
726 Tomb Raider II uses this to display the background during the menu selection
727 when the screen resolution is != than 40x480 */
728 TRACE(ddraw, "Blt with stretching\n");
730 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
731 if (bpp == 1) {
732 /* In this case, we cannot do any anti-aliasing */
733 for (y = xdst.top; y < xdst.bottom; y++) {
734 for (x = xdst.left; x < xdst.right; x++) {
735 double sx, sy;
736 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
737 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
739 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
740 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
742 dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
745 } else {
746 FIXME(ddraw, "Not done yet for depth != 8\n");
748 } else {
749 /* Same size => fast blit */
750 for (h = 0; h < srcheight; h++) {
751 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
752 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
753 width);
758 if (dwFlags && FIXME_ON(ddraw)) {
759 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
762 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
763 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
765 return DD_OK;
768 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
769 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
771 int i,bpp;
772 DDSURFACEDESC ddesc,sdesc;
774 if (TRACE_ON(ddraw)) {
775 TRACE(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
776 this,dstx,dsty,src,rsrc,trans
778 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
779 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
781 /* We need to lock the surfaces, or we won't get refreshes when done. */
782 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
783 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
784 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
785 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
786 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
787 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
788 (rsrc->right-rsrc->left)*bpp
791 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
792 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
793 return DD_OK;
796 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
797 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
799 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
800 this,ddbltbatch,x,y
802 return DD_OK;
805 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
806 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
808 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
809 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
810 return DD_OK;
813 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
814 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
815 ) {
816 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
817 this,ddsd);
819 /* Simply copy the surface description stored in the object */
820 *ddsd = this->s.surface_desc;
822 if (TRACE_ON(ddraw)) {
823 fprintf(stderr," flags: ");
824 _dump_DDSD(ddsd->dwFlags);
825 if (ddsd->dwFlags & DDSD_CAPS) {
826 fprintf(stderr, " caps: ");
827 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
829 fprintf(stderr,"\n");
832 return DD_OK;
835 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
836 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
838 return ++(this->ref);
841 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
842 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
844 #ifdef HAVE_LIBXXF86DGA
845 if (!--(this->ref)) {
846 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
847 /* clear out of surface list */
848 if (this->t.dga.fb_height == -1) {
849 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
850 } else {
851 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
853 HeapFree(GetProcessHeap(),0,this);
854 return 0;
856 #endif /* defined(HAVE_LIBXXF86DGA) */
857 return this->ref;
860 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
861 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
863 if (!--(this->ref)) {
864 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
866 if( this->s.backbuffer )
867 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
869 if (this->t.xlib.image != NULL) {
870 this->t.xlib.image->data = NULL;
872 #ifdef HAVE_LIBXXSHM
873 if (this->s.ddraw->e.xlib.xshm_active) {
874 TSXShmDetach(display, &(this->t.xlib.shminfo));
875 TSXDestroyImage(this->t.xlib.image);
876 shmdt(this->t.xlib.shminfo.shmaddr);
877 } else {
878 #endif
879 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
880 TSXDestroyImage(this->t.xlib.image);
881 #ifdef HAVE_LIBXXSHM
883 #endif
885 this->t.xlib.image = 0;
886 } else {
887 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
890 if (this->s.palette)
891 this->s.palette->lpvtbl->fnRelease(this->s.palette);
893 HeapFree(GetProcessHeap(),0,this);
894 return 0;
897 return this->ref;
900 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
901 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
903 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
904 this, lpddsd, lpdsf);
906 if (TRACE_ON(ddraw)) {
907 TRACE(ddraw," caps ");
908 _dump_DDSCAPS(lpddsd->dwCaps);
911 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
912 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
913 return E_FAIL;
916 /* FIXME: should handle more than one backbuffer */
917 *lpdsf = this->s.backbuffer;
919 if( this->s.backbuffer )
920 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
922 return DD_OK;
925 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
926 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
928 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
930 return DDERR_ALREADYINITIALIZED;
933 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
934 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
936 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
938 *pf = this->s.surface_desc.ddpfPixelFormat;
940 return DD_OK;
943 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
944 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
945 return DD_OK;
948 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
949 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
951 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
952 return DD_OK;
955 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
956 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
958 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
959 return DD_OK;
962 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
963 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
965 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
967 /* This hack will be enough for the moment */
968 if (this->s.backbuffer == NULL)
969 this->s.backbuffer = surf;
970 return DD_OK;
973 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
974 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
975 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
976 return DD_OK;
979 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
980 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
981 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
982 return DD_OK;
986 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
987 char xrefiid[50];
989 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
990 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
992 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
993 * the same interface. And IUnknown does that too of course.
995 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
996 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
997 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
998 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1000 *obj = this;
1001 this->lpvtbl->fnAddRef(this);
1003 TRACE(ddraw, " Creating IDirect3DSurfaceX interface (%p)\n", *obj);
1005 return S_OK;
1007 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1009 /* Texture interface */
1010 *obj = d3dtexture2_create(this);
1011 this->lpvtbl->fnAddRef(this);
1013 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1015 return S_OK;
1017 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1019 /* Texture interface */
1020 *obj = d3dtexture_create(this);
1021 this->lpvtbl->fnAddRef(this);
1023 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1025 return S_OK;
1027 else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj))
1029 /* It is the OpenGL Direct3D Device */
1030 this->lpvtbl->fnAddRef(this);
1032 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1034 return S_OK;
1037 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1038 return OLE_E_ENUM_NOMORE;
1041 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
1042 TRACE(ddraw,"(%p)->(), stub!\n",this);
1043 return DD_OK; /* hmm */
1046 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1047 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
1048 return DD_OK;
1051 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
1052 FIXME(ddraw,"(%p)->(),stub!\n",this);
1053 return DD_OK;
1056 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
1057 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey )
1059 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);
1061 if( dwFlags & DDCKEY_SRCBLT )
1063 dwFlags &= ~DDCKEY_SRCBLT;
1064 memcpy( &(this->s.ckSrcBlt), ckey, sizeof( *ckey ) );
1067 if( dwFlags & DDCKEY_DESTBLT )
1069 dwFlags &= ~DDCKEY_DESTBLT;
1070 memcpy( &(this->s.ckDestBlt), ckey, sizeof( *ckey ) );
1073 if( dwFlags & DDCKEY_SRCOVERLAY )
1075 dwFlags &= ~DDCKEY_SRCOVERLAY;
1076 memcpy( &(this->s.ckSrcOverlay), ckey, sizeof( *ckey ) );
1078 if( dwFlags & DDCKEY_DESTOVERLAY )
1080 dwFlags &= ~DDCKEY_DESTOVERLAY;
1081 memcpy( &(this->s.ckDestOverlay), ckey, sizeof( *ckey ) );
1084 if( dwFlags )
1086 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1089 return DD_OK;
1093 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
1094 LPDIRECTDRAWSURFACE3 this,
1095 LPRECT32 lpRect )
1097 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
1099 return DD_OK;
1102 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
1103 LPDIRECTDRAWSURFACE3 this,
1104 DWORD dwFlags,
1105 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
1107 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1109 return DD_OK;
1112 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
1113 LPDIRECTDRAWSURFACE3 this,
1114 DWORD dwFlags,
1115 LPVOID lpContext,
1116 LPDDENUMSURFACESCALLBACK lpfnCallback )
1118 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1119 lpContext, lpfnCallback );
1121 return DD_OK;
1124 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
1125 LPDIRECTDRAWSURFACE3 this,
1126 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1128 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1130 return DD_OK;
1133 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
1134 LPDIRECTDRAWSURFACE3 this,
1135 DWORD dwFlags,
1136 LPDDCOLORKEY lpDDColorKey )
1138 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);
1140 if( dwFlags & DDCKEY_SRCBLT ) {
1141 dwFlags &= ~DDCKEY_SRCBLT;
1142 memcpy( lpDDColorKey, &(this->s.ckSrcBlt), sizeof( *lpDDColorKey ) );
1145 if( dwFlags & DDCKEY_DESTBLT )
1147 dwFlags &= ~DDCKEY_DESTBLT;
1148 memcpy( lpDDColorKey, &(this->s.ckDestBlt), sizeof( *lpDDColorKey ) );
1151 if( dwFlags & DDCKEY_SRCOVERLAY )
1153 dwFlags &= ~DDCKEY_SRCOVERLAY;
1154 memcpy( lpDDColorKey, &(this->s.ckSrcOverlay), sizeof( *lpDDColorKey ) );
1157 if( dwFlags & DDCKEY_DESTOVERLAY )
1159 dwFlags &= ~DDCKEY_DESTOVERLAY;
1160 memcpy( lpDDColorKey, &(this->s.ckDestOverlay), sizeof( *lpDDColorKey ) );
1163 if( dwFlags )
1165 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1168 return DD_OK;
1171 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
1172 LPDIRECTDRAWSURFACE3 this,
1173 DWORD dwFlags )
1175 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1177 return DD_OK;
1180 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
1181 LPDIRECTDRAWSURFACE3 this,
1182 LPDIRECTDRAWPALETTE* lplpDDPalette )
1184 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1186 return DD_OK;
1189 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
1190 LPDIRECTDRAWSURFACE3 this,
1191 LONG lX,
1192 LONG lY)
1194 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1196 return DD_OK;
1199 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
1200 LPDIRECTDRAWSURFACE3 this,
1201 LPRECT32 lpSrcRect,
1202 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
1203 LPRECT32 lpDestRect,
1204 DWORD dwFlags,
1205 LPDDOVERLAYFX lpDDOverlayFx )
1207 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1208 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1210 return DD_OK;
1213 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
1214 LPDIRECTDRAWSURFACE3 this,
1215 DWORD dwFlags )
1217 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1219 return DD_OK;
1222 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
1223 LPDIRECTDRAWSURFACE3 this,
1224 DWORD dwFlags,
1225 LPDIRECTDRAWSURFACE3 lpDDSReference )
1227 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1229 return DD_OK;
1232 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
1233 LPDIRECTDRAWSURFACE3 this,
1234 LPVOID* lplpDD )
1236 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1238 /* Not sure about that... */
1239 *lplpDD = (void *) this->s.ddraw;
1241 return DD_OK;
1244 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
1245 LPDIRECTDRAWSURFACE3 this,
1246 DWORD dwFlags )
1248 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1250 return DD_OK;
1253 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
1254 LPDIRECTDRAWSURFACE3 this,
1255 DWORD dwFlags )
1257 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1259 return DD_OK;
1262 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1263 LPDIRECTDRAWSURFACE3 this,
1264 LPDDSURFACEDESC lpDDSD,
1265 DWORD dwFlags )
1267 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1269 return DD_OK;
1272 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1273 IDirectDrawSurface3_QueryInterface,
1274 IDirectDrawSurface3_AddRef,
1275 DGA_IDirectDrawSurface3_Release,
1276 IDirectDrawSurface3_AddAttachedSurface,
1277 IDirectDrawSurface3_AddOverlayDirtyRect,
1278 IDirectDrawSurface3_Blt,
1279 IDirectDrawSurface3_BltBatch,
1280 IDirectDrawSurface3_BltFast,
1281 IDirectDrawSurface3_DeleteAttachedSurface,
1282 IDirectDrawSurface3_EnumAttachedSurfaces,
1283 IDirectDrawSurface3_EnumOverlayZOrders,
1284 DGA_IDirectDrawSurface3_Flip,
1285 IDirectDrawSurface3_GetAttachedSurface,
1286 IDirectDrawSurface3_GetBltStatus,
1287 IDirectDrawSurface3_GetCaps,
1288 IDirectDrawSurface3_GetClipper,
1289 IDirectDrawSurface3_GetColorKey,
1290 IDirectDrawSurface3_GetDC,
1291 IDirectDrawSurface3_GetFlipStatus,
1292 IDirectDrawSurface3_GetOverlayPosition,
1293 IDirectDrawSurface3_GetPalette,
1294 IDirectDrawSurface3_GetPixelFormat,
1295 IDirectDrawSurface3_GetSurfaceDesc,
1296 IDirectDrawSurface3_Initialize,
1297 IDirectDrawSurface3_IsLost,
1298 IDirectDrawSurface3_Lock,
1299 IDirectDrawSurface3_ReleaseDC,
1300 IDirectDrawSurface3_Restore,
1301 IDirectDrawSurface3_SetClipper,
1302 IDirectDrawSurface3_SetColorKey,
1303 IDirectDrawSurface3_SetOverlayPosition,
1304 DGA_IDirectDrawSurface3_SetPalette,
1305 DGA_IDirectDrawSurface3_Unlock,
1306 IDirectDrawSurface3_UpdateOverlay,
1307 IDirectDrawSurface3_UpdateOverlayDisplay,
1308 IDirectDrawSurface3_UpdateOverlayZOrder,
1309 IDirectDrawSurface3_GetDDInterface,
1310 IDirectDrawSurface3_PageLock,
1311 IDirectDrawSurface3_PageUnlock,
1312 IDirectDrawSurface3_SetSurfaceDesc,
1315 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1316 IDirectDrawSurface3_QueryInterface,
1317 IDirectDrawSurface3_AddRef,
1318 Xlib_IDirectDrawSurface3_Release,
1319 IDirectDrawSurface3_AddAttachedSurface,
1320 IDirectDrawSurface3_AddOverlayDirtyRect,
1321 IDirectDrawSurface3_Blt,
1322 IDirectDrawSurface3_BltBatch,
1323 IDirectDrawSurface3_BltFast,
1324 IDirectDrawSurface3_DeleteAttachedSurface,
1325 IDirectDrawSurface3_EnumAttachedSurfaces,
1326 IDirectDrawSurface3_EnumOverlayZOrders,
1327 Xlib_IDirectDrawSurface3_Flip,
1328 IDirectDrawSurface3_GetAttachedSurface,
1329 IDirectDrawSurface3_GetBltStatus,
1330 IDirectDrawSurface3_GetCaps,
1331 IDirectDrawSurface3_GetClipper,
1332 IDirectDrawSurface3_GetColorKey,
1333 IDirectDrawSurface3_GetDC,
1334 IDirectDrawSurface3_GetFlipStatus,
1335 IDirectDrawSurface3_GetOverlayPosition,
1336 IDirectDrawSurface3_GetPalette,
1337 IDirectDrawSurface3_GetPixelFormat,
1338 IDirectDrawSurface3_GetSurfaceDesc,
1339 IDirectDrawSurface3_Initialize,
1340 IDirectDrawSurface3_IsLost,
1341 IDirectDrawSurface3_Lock,
1342 IDirectDrawSurface3_ReleaseDC,
1343 IDirectDrawSurface3_Restore,
1344 IDirectDrawSurface3_SetClipper,
1345 IDirectDrawSurface3_SetColorKey,
1346 IDirectDrawSurface3_SetOverlayPosition,
1347 Xlib_IDirectDrawSurface3_SetPalette,
1348 Xlib_IDirectDrawSurface3_Unlock,
1349 IDirectDrawSurface3_UpdateOverlay,
1350 IDirectDrawSurface3_UpdateOverlayDisplay,
1351 IDirectDrawSurface3_UpdateOverlayZOrder,
1352 IDirectDrawSurface3_GetDDInterface,
1353 IDirectDrawSurface3_PageLock,
1354 IDirectDrawSurface3_PageUnlock,
1355 IDirectDrawSurface3_SetSurfaceDesc,
1358 /******************************************************************************
1359 * DirectDrawCreateClipper (DDRAW.7)
1361 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1362 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1363 LPUNKNOWN pUnkOuter)
1365 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1367 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1368 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1369 (*lplpDDClipper)->ref = 1;
1371 return DD_OK;
1374 /******************************************************************************
1375 * IDirectDrawClipper
1377 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1378 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1380 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1381 return DD_OK;
1384 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1385 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1387 this->ref--;
1388 if (this->ref)
1389 return this->ref;
1390 HeapFree(GetProcessHeap(),0,this);
1391 return 0;
1394 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1395 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1397 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1398 if (hmm) *hmm=0;
1399 return DD_OK;
1402 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1403 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1405 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1406 return DD_OK;
1409 static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
1410 LPDIRECTDRAWCLIPPER this,
1411 REFIID riid,
1412 LPVOID* ppvObj )
1414 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
1415 return OLE_E_ENUM_NOMORE;
1418 static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
1420 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1421 return ++(this->ref);
1424 static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
1425 LPDIRECTDRAWCLIPPER this,
1426 HWND32* HWndPtr )
1428 FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
1429 return DD_OK;
1432 static HRESULT WINAPI IDirectDrawClipper_Initialize(
1433 LPDIRECTDRAWCLIPPER this,
1434 LPDIRECTDRAW lpDD,
1435 DWORD dwFlags )
1437 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
1438 return DD_OK;
1441 static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
1442 LPDIRECTDRAWCLIPPER this,
1443 BOOL32* lpbChanged )
1445 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
1446 return DD_OK;
1449 static struct IDirectDrawClipper_VTable ddclipvt = {
1450 IDirectDrawClipper_QueryInterface,
1451 IDirectDrawClipper_AddRef,
1452 IDirectDrawClipper_Release,
1453 IDirectDrawClipper_GetClipList,
1454 IDirectDrawClipper_GetHWnd,
1455 IDirectDrawClipper_Initialize,
1456 IDirectDrawClipper_IsClipListChanged,
1457 IDirectDrawClipper_SetClipList,
1458 IDirectDrawClipper_SetHwnd
1462 /******************************************************************************
1463 * IDirectDrawPalette
1465 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1466 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1468 int i;
1470 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1471 this,x,start,count,palent);
1473 if (!this->cm) /* should not happen */ {
1474 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1475 return DDERR_GENERIC;
1477 for (i=0;i<count;i++) {
1478 palent[i].peRed = this->palents[start+i].peRed;
1479 palent[i].peBlue = this->palents[start+i].peBlue;
1480 palent[i].peGreen = this->palents[start+i].peGreen;
1481 palent[i].peFlags = this->palents[start+i].peFlags;
1484 return DD_OK;
1487 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1488 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1490 XColor xc;
1491 int i;
1493 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1494 this,x,start,count,palent
1496 for (i=0;i<count;i++) {
1497 xc.red = palent[i].peRed<<8;
1498 xc.blue = palent[i].peBlue<<8;
1499 xc.green = palent[i].peGreen<<8;
1500 xc.flags = DoRed|DoBlue|DoGreen;
1501 xc.pixel = start+i;
1503 if (this->cm)
1504 TSXStoreColor(display,this->cm,&xc);
1506 this->palents[start+i].peRed = palent[i].peRed;
1507 this->palents[start+i].peBlue = palent[i].peBlue;
1508 this->palents[start+i].peGreen = palent[i].peGreen;
1509 this->palents[start+i].peFlags = palent[i].peFlags;
1511 if (!this->cm) /* should not happen */ {
1513 return DD_OK;
1516 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1517 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1519 #ifdef HAVE_LIBXXF86DGA
1520 XColor xc;
1521 Colormap cm;
1522 int i;
1524 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1525 this,x,start,count,palent
1527 if (!this->cm) /* should not happen */ {
1528 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1529 return DDERR_GENERIC;
1531 /* FIXME: free colorcells instead of freeing whole map */
1532 cm = this->cm;
1533 this->cm = TSXCopyColormapAndFree(display,this->cm);
1534 TSXFreeColormap(display,cm);
1536 for (i=0;i<count;i++) {
1537 xc.red = palent[i].peRed<<8;
1538 xc.blue = palent[i].peBlue<<8;
1539 xc.green = palent[i].peGreen<<8;
1540 xc.flags = DoRed|DoBlue|DoGreen;
1541 xc.pixel = i+start;
1543 TSXStoreColor(display,this->cm,&xc);
1545 this->palents[start+i].peRed = palent[i].peRed;
1546 this->palents[start+i].peBlue = palent[i].peBlue;
1547 this->palents[start+i].peGreen = palent[i].peGreen;
1548 this->palents[start+i].peFlags = palent[i].peFlags;
1550 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1551 return DD_OK;
1552 #else /* defined(HAVE_LIBXXF86DGA) */
1553 return E_UNEXPECTED;
1554 #endif /* defined(HAVE_LIBXXF86DGA) */
1557 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1558 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1559 if (!--(this->ref)) {
1560 if (this->cm) {
1561 TSXFreeColormap(display,this->cm);
1562 this->cm = 0;
1564 HeapFree(GetProcessHeap(),0,this);
1565 return 0;
1567 return this->ref;
1570 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1572 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1573 return ++(this->ref);
1576 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1577 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1579 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1581 return DDERR_ALREADYINITIALIZED;
1584 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1585 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1587 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1588 return DD_OK;
1591 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1592 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1594 char xrefiid[50];
1596 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1597 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1599 return S_OK;
1602 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1603 IDirectDrawPalette_QueryInterface,
1604 IDirectDrawPalette_AddRef,
1605 IDirectDrawPalette_Release,
1606 IDirectDrawPalette_GetCaps,
1607 IDirectDrawPalette_GetEntries,
1608 IDirectDrawPalette_Initialize,
1609 DGA_IDirectDrawPalette_SetEntries
1612 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1613 IDirectDrawPalette_QueryInterface,
1614 IDirectDrawPalette_AddRef,
1615 IDirectDrawPalette_Release,
1616 IDirectDrawPalette_GetCaps,
1617 IDirectDrawPalette_GetEntries,
1618 IDirectDrawPalette_Initialize,
1619 Xlib_IDirectDrawPalette_SetEntries
1622 /*******************************************************************************
1623 * IDirect3D
1625 static HRESULT WINAPI IDirect3D_QueryInterface(
1626 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1628 /* FIXME: Not sure if this is correct */
1629 char xrefiid[50];
1631 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1632 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1633 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1634 *obj = this;
1635 this->lpvtbl->fnAddRef(this);
1637 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
1639 return S_OK;
1641 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1642 LPDIRECT3D d3d;
1644 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1645 d3d->ref = 1;
1646 d3d->ddraw = (LPDIRECTDRAW)this;
1647 this->lpvtbl->fnAddRef(this);
1648 d3d->lpvtbl = &d3dvt;
1649 *obj = d3d;
1651 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
1653 return S_OK;
1655 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1656 LPDIRECT3D2 d3d;
1658 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1659 d3d->ref = 1;
1660 d3d->ddraw = (LPDIRECTDRAW)this;
1661 this->lpvtbl->fnAddRef(this);
1662 d3d->lpvtbl = &d3d2vt;
1663 *obj = d3d;
1665 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
1667 return S_OK;
1669 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1670 return OLE_E_ENUM_NOMORE;
1673 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1674 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1676 return ++(this->ref);
1679 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1681 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1683 if (!--(this->ref)) {
1684 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1685 HeapFree(GetProcessHeap(),0,this);
1686 return 0;
1688 return this->ref;
1691 static HRESULT WINAPI IDirect3D_Initialize(
1692 LPDIRECT3D this, REFIID refiid )
1694 /* FIXME: Not sure if this is correct */
1695 char xrefiid[50];
1697 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1698 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1700 return DDERR_ALREADYINITIALIZED;
1703 static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this,
1704 LPD3DENUMDEVICESCALLBACK cb,
1705 LPVOID context) {
1706 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1708 /* Call functions defined in d3ddevices.c */
1709 if (d3d_OpenGL_dx3(cb, context))
1710 return DD_OK;
1712 return DD_OK;
1715 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,
1716 LPDIRECT3DLIGHT *lplight,
1717 IUnknown *lpunk)
1719 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
1721 /* Call the creation function that is located in d3dlight.c */
1722 *lplight = d3dlight_create_dx3(this);
1724 return DD_OK;
1727 static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this,
1728 LPDIRECT3DMATERIAL *lpmaterial,
1729 IUnknown *lpunk)
1731 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
1733 /* Call the creation function that is located in d3dviewport.c */
1734 *lpmaterial = d3dmaterial_create(this);
1736 return DD_OK;
1739 static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this,
1740 LPDIRECT3DVIEWPORT *lpviewport,
1741 IUnknown *lpunk)
1743 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
1745 /* Call the creation function that is located in d3dviewport.c */
1746 *lpviewport = d3dviewport_create(this);
1748 return DD_OK;
1751 static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this,
1752 LPD3DFINDDEVICESEARCH lpfinddevsrc,
1753 LPD3DFINDDEVICERESULT lpfinddevrst)
1755 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
1757 return DD_OK;
1760 static struct IDirect3D_VTable d3dvt = {
1761 IDirect3D_QueryInterface,
1762 IDirect3D_AddRef,
1763 IDirect3D_Release,
1764 IDirect3D_Initialize,
1765 IDirect3D_EnumDevices,
1766 IDirect3D_CreateLight,
1767 IDirect3D_CreateMaterial,
1768 IDirect3D_CreateViewport,
1769 IDirect3D_FindDevice
1772 /*******************************************************************************
1773 * IDirect3D2
1775 static HRESULT WINAPI IDirect3D2_QueryInterface(
1776 LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) {
1777 /* For the moment, we use the same function as in IDirect3D */
1778 TRACE(ddraw, "Calling IDirect3D enumerating function.\n");
1780 return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj);
1783 static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) {
1784 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1786 return ++(this->ref);
1789 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1790 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1792 if (!--(this->ref)) {
1793 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1794 HeapFree(GetProcessHeap(),0,this);
1795 return 0;
1797 return this->ref;
1800 static HRESULT WINAPI IDirect3D2_EnumDevices(
1801 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1803 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1805 /* Call functions defined in d3ddevices.c */
1806 if (d3d_OpenGL(cb, context))
1807 return DD_OK;
1809 return DD_OK;
1812 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,
1813 LPDIRECT3DLIGHT *lplight,
1814 IUnknown *lpunk)
1816 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
1818 /* Call the creation function that is located in d3dlight.c */
1819 *lplight = d3dlight_create(this);
1821 return DD_OK;
1824 static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this,
1825 LPDIRECT3DMATERIAL2 *lpmaterial,
1826 IUnknown *lpunk)
1828 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
1830 /* Call the creation function that is located in d3dviewport.c */
1831 *lpmaterial = d3dmaterial2_create(this);
1833 return DD_OK;
1836 static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this,
1837 LPDIRECT3DVIEWPORT2 *lpviewport,
1838 IUnknown *lpunk)
1840 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
1842 /* Call the creation function that is located in d3dviewport.c */
1843 *lpviewport = d3dviewport2_create(this);
1845 return DD_OK;
1848 static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this,
1849 LPD3DFINDDEVICESEARCH lpfinddevsrc,
1850 LPD3DFINDDEVICERESULT lpfinddevrst)
1852 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
1854 return DD_OK;
1857 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,
1858 REFCLSID rguid,
1859 LPDIRECTDRAWSURFACE surface,
1860 LPDIRECT3DDEVICE2 *device)
1862 char xbuf[50];
1864 WINE_StringFromCLSID(rguid,xbuf);
1865 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device);
1867 if (is_OpenGL(rguid, surface, device, this)) {
1868 this->lpvtbl->fnAddRef(this);
1869 return DD_OK;
1872 return DDERR_INVALIDPARAMS;
1875 static struct IDirect3D2_VTable d3d2vt = {
1876 IDirect3D2_QueryInterface,
1877 IDirect3D2_AddRef,
1878 IDirect3D2_Release,
1879 IDirect3D2_EnumDevices,
1880 IDirect3D2_CreateLight,
1881 IDirect3D2_CreateMaterial,
1882 IDirect3D2_CreateViewport,
1883 IDirect3D2_FindDevice,
1884 IDirect3D2_CreateDevice
1887 /*******************************************************************************
1888 * IDirectDraw
1891 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1892 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1894 static INT32 ddrawXlibThisOffset = 0;
1896 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
1897 LPDDSURFACEDESC lpddsd,
1898 LPDIRECTDRAWSURFACE lpdsf)
1900 int bpp;
1902 /* The surface was already allocated when entering in this function */
1903 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
1905 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
1906 /* This is a Z Buffer */
1907 bpp = lpddsd->x.dwZBufferBitDepth;
1908 } else {
1909 /* This is a standard image */
1910 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
1911 /* No pixel format => use DirectDraw's format */
1912 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
1913 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
1914 } else {
1915 /* To check what the program wants */
1916 if (TRACE_ON(ddraw)) {
1917 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
1922 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
1923 bpp = 1;
1924 } else {
1925 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
1928 /* Copy the surface description */
1929 lpdsf->s.surface_desc = *lpddsd;
1931 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1932 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
1933 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
1935 return DD_OK;
1938 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1939 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1941 #ifdef HAVE_LIBXXF86DGA
1942 int i;
1944 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1945 if (TRACE_ON(ddraw)) {
1946 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1947 _dump_DDSD(lpddsd->dwFlags);
1948 fprintf(stderr,"caps ");
1949 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1950 fprintf(stderr,"]\n");
1953 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1954 this->lpvtbl->fnAddRef(this);
1956 (*lpdsf)->ref = 1;
1957 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1958 (*lpdsf)->s.ddraw = this;
1959 (*lpdsf)->s.palette = NULL;
1960 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
1962 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1963 lpddsd->dwWidth = this->d.width;
1964 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1965 lpddsd->dwHeight = this->d.height;
1967 /* Check if this a 'primary surface' or not */
1968 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1969 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1971 /* This is THE primary surface => there is DGA-specific code */
1972 /* First, store the surface description */
1973 (*lpdsf)->s.surface_desc = *lpddsd;
1975 /* Find a viewport */
1976 for (i=0;i<32;i++)
1977 if (!(this->e.dga.vpmask & (1<<i)))
1978 break;
1979 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1980 /* if i == 32 or maximum ... return error */
1981 this->e.dga.vpmask|=(1<<i);
1982 (*lpdsf)->s.surface_desc.y.lpSurface =
1983 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1984 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1985 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
1986 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
1988 /* Add flags if there were not present */
1989 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1990 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1991 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1992 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1993 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1994 (*lpdsf)->s.backbuffer = NULL;
1996 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1997 LPDIRECTDRAWSURFACE3 back;
1999 if (lpddsd->dwBackBufferCount>1)
2000 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2002 (*lpdsf)->s.backbuffer = back =
2003 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
2004 this->lpvtbl->fnAddRef(this);
2005 back->ref = 1;
2006 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
2007 for (i=0;i<32;i++)
2008 if (!(this->e.dga.vpmask & (1<<i)))
2009 break;
2010 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2011 /* if i == 32 or maximum ... return error */
2012 this->e.dga.vpmask|=(1<<i);
2013 back->t.dga.fb_height = i*this->e.dga.fb_height;
2015 /* Copy the surface description from the front buffer */
2016 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2017 /* Change the parameters that are not the same */
2018 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
2019 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
2020 back->s.ddraw = this;
2021 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2022 * one! */
2024 /* Add relevant info to front and back buffers */
2025 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2026 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2027 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2028 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2030 } else {
2031 /* There is no DGA-specific code here...
2032 Go to the common surface creation function */
2033 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2036 return DD_OK;
2037 #else /* defined(HAVE_LIBXXF86DGA) */
2038 return E_UNEXPECTED;
2039 #endif /* defined(HAVE_LIBXXF86DGA) */
2042 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
2043 XImage *img;
2045 #ifdef HAVE_LIBXXSHM
2046 if (this->e.xlib.xshm_active) {
2047 img = TSXShmCreateImage(display,
2048 DefaultVisualOfScreen(screen),
2049 this->d.depth,
2050 ZPixmap,
2051 NULL,
2052 &(lpdsf->t.xlib.shminfo),
2053 lpdsf->s.surface_desc.dwWidth,
2054 lpdsf->s.surface_desc.dwHeight);
2056 if (img == NULL)
2057 return NULL;
2059 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2060 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2061 TSXDestroyImage(img);
2062 return NULL;
2065 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2067 if (img->data == (char *) -1) {
2068 TSXDestroyImage(img);
2069 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2070 return NULL;
2072 lpdsf->t.xlib.shminfo.readOnly = False;
2074 TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
2075 TSXSync(display, False);
2077 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2079 lpdsf->s.surface_desc.y.lpSurface = img->data;
2080 } else {
2081 #endif
2082 /* Allocate surface memory */
2083 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2084 lpdsf->s.surface_desc.dwWidth *
2085 lpdsf->s.surface_desc.dwHeight *
2086 (this->d.depth / 8));
2088 /* In this case, create an XImage */
2089 img =
2090 TSXCreateImage(display,
2091 DefaultVisualOfScreen(screen),
2092 this->d.depth,
2093 ZPixmap,
2095 lpdsf->s.surface_desc.y.lpSurface,
2096 lpdsf->s.surface_desc.dwWidth,
2097 lpdsf->s.surface_desc.dwHeight,
2099 lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8)
2102 #ifdef HAVE_LIBXXSHM
2104 #endif
2105 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2107 return img;
2110 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
2111 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2113 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2114 this,lpddsd,lpdsf,lpunk);
2116 if (TRACE_ON(ddraw)) {
2117 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2118 _dump_DDSD(lpddsd->dwFlags);
2119 fprintf(stderr,"caps ");
2120 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2121 fprintf(stderr,"]\n");
2124 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2126 this->lpvtbl->fnAddRef(this);
2127 (*lpdsf)->s.ddraw = this;
2128 (*lpdsf)->ref = 1;
2129 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
2130 (*lpdsf)->s.palette = NULL;
2131 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2133 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2134 lpddsd->dwWidth = this->d.width;
2135 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2136 lpddsd->dwHeight = this->d.height;
2138 /* Check if this a 'primary surface' or not */
2139 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2140 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2141 XImage *img;
2143 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
2145 /* First, store the surface description */
2146 (*lpdsf)->s.surface_desc = *lpddsd;
2148 /* Create the XImage */
2149 img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
2150 if (img == NULL)
2151 return DDERR_OUTOFMEMORY;
2152 (*lpdsf)->t.xlib.image = img;
2154 /* Add flags if there were not present */
2155 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2156 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2157 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2158 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
2159 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2160 (*lpdsf)->s.backbuffer = NULL;
2162 /* Check for backbuffers */
2163 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2164 LPDIRECTDRAWSURFACE3 back;
2165 XImage *img;
2167 if (lpddsd->dwBackBufferCount>1)
2168 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2170 (*lpdsf)->s.backbuffer = back =
2171 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
2173 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2175 this->lpvtbl->fnAddRef(this);
2176 back->s.ddraw = this;
2178 back->ref = 1;
2179 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
2180 /* Copy the surface description from the front buffer */
2181 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2183 /* Create the XImage */
2184 img = create_ximage(this, back);
2185 if (img == NULL)
2186 return DDERR_OUTOFMEMORY;
2187 back->t.xlib.image = img;
2189 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2190 * one! */
2192 /* Add relevant info to front and back buffers */
2193 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2194 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2195 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2196 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2198 } else {
2199 /* There is no Xlib-specific code here...
2200 Go to the common surface creation function */
2201 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2204 return DD_OK;
2207 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
2208 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2210 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
2211 *dst = src; /* FIXME */
2212 return DD_OK;
2216 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2217 * even when the approbiate bitmasks are not specified.
2219 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
2220 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
2222 int i;
2223 const struct {
2224 int mask;
2225 char *name;
2226 } flagmap[] = {
2227 FE(DDSCL_FULLSCREEN)
2228 FE(DDSCL_ALLOWREBOOT)
2229 FE(DDSCL_NOWINDOWCHANGES)
2230 FE(DDSCL_NORMAL)
2231 FE(DDSCL_ALLOWMODEX)
2232 FE(DDSCL_EXCLUSIVE)
2233 FE(DDSCL_SETFOCUSWINDOW)
2234 FE(DDSCL_SETDEVICEWINDOW)
2235 FE(DDSCL_CREATEDEVICEWINDOW)
2238 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
2239 if(TRACE_ON(ddraw)){
2240 dbg_decl_str(ddraw, 512);
2241 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2242 if (flagmap[i].mask & cooplevel)
2243 dsprintf(ddraw, "%s ", flagmap[i].name);
2244 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2246 this->d.mainWindow = hwnd;
2248 /* This will be overwritten in the case of Full Screen mode.
2249 Windowed games could work with that :-) */
2250 this->e.xlib.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(hwnd)->pDriverData)->window;
2252 return DD_OK;
2255 /* Small helper to either use the cooperative window or create a new
2256 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2258 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
2259 RECT32 rect;
2261 /* Do not destroy the application supplied cooperative window */
2262 if (this->d.window && this->d.window != this->d.mainWindow) {
2263 DestroyWindow32(this->d.window);
2264 this->d.window = 0;
2266 /* Sanity check cooperative window before assigning it to drawing. */
2267 if ( IsWindow32(this->d.mainWindow) &&
2268 IsWindowVisible32(this->d.mainWindow)
2270 GetWindowRect32(this->d.mainWindow,&rect);
2271 if (((rect.right-rect.left) >= this->d.width) &&
2272 ((rect.bottom-rect.top) >= this->d.height)
2274 this->d.window = this->d.mainWindow;
2276 /* ... failed, create new one. */
2277 if (!this->d.window) {
2278 this->d.window = CreateWindowEx32A(
2280 "WINE_DirectDraw",
2281 "WINE_DirectDraw",
2282 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2283 0,0,
2284 this->d.width,
2285 this->d.height,
2289 NULL
2291 /*Store THIS with the window. We'll use it in the window procedure*/
2292 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
2293 ShowWindow32(this->d.window,TRUE);
2294 UpdateWindow32(this->d.window);
2296 SetFocus32(this->d.window);
2299 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
2300 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2302 #ifdef HAVE_LIBXXF86DGA
2303 int i,*depths,depcount,mode_count;
2305 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2307 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2308 for (i=0;i<depcount;i++)
2309 if (depths[i]==depth)
2310 break;
2311 TSXFree(depths);
2312 if (i==depcount) {/* not found */
2313 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2314 return DDERR_UNSUPPORTEDMODE;
2316 if (this->d.width < width) {
2317 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2318 return DDERR_UNSUPPORTEDMODE;
2320 this->d.width = width;
2321 this->d.height = height;
2322 this->d.depth = depth;
2324 /* adjust fb_height, so we don't overlap */
2325 if (this->e.dga.fb_height < height)
2326 this->e.dga.fb_height = height;
2327 _common_IDirectDraw_SetDisplayMode(this);
2329 #ifdef HAVE_LIBXXF86VM
2331 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2332 XF86VidModeModeLine mod_tmp;
2333 int dotclock_tmp;
2335 /* save original video mode and set fullscreen if available*/
2336 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2337 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2338 orig_mode->hdisplay = mod_tmp.hdisplay;
2339 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2340 orig_mode->hsyncend = mod_tmp.hsyncend;
2341 orig_mode->htotal = mod_tmp.htotal;
2342 orig_mode->vdisplay = mod_tmp.vdisplay;
2343 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2344 orig_mode->vsyncend = mod_tmp.vsyncend;
2345 orig_mode->vtotal = mod_tmp.vtotal;
2346 orig_mode->flags = mod_tmp.flags;
2347 orig_mode->private = mod_tmp.private;
2349 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2350 for (i=0;i<mode_count;i++)
2352 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2354 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2355 *vidmode = *(all_modes[i]);
2356 break;
2357 } else
2358 TSXFree(all_modes[i]->private);
2360 TSXFree(all_modes);
2362 if (!vidmode)
2363 WARN(ddraw, "Fullscreen mode not available!\n");
2365 if (vidmode)
2367 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2368 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2371 #endif
2373 /* FIXME: this function OVERWRITES several signal handlers.
2374 * can we save them? and restore them later? In a way that
2375 * it works for the library too?
2377 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2378 #ifdef DIABLO_HACK
2379 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2380 #endif
2382 #ifdef RESTORE_SIGNALS
2383 SIGNAL_InitEmulator();
2384 #endif
2385 return DD_OK;
2386 #else /* defined(HAVE_LIBXXF86DGA) */
2387 return E_UNEXPECTED;
2388 #endif /* defined(HAVE_LIBXXF86DGA) */
2391 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2392 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2394 int i,*depths,depcount;
2395 char buf[200];
2397 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2398 this, width, height, depth);
2400 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2401 for (i=0;i<depcount;i++)
2402 if (depths[i]==depth)
2403 break;
2404 TSXFree(depths);
2405 if (i==depcount) {/* not found */
2406 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2407 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2408 return DDERR_UNSUPPORTEDMODE;
2410 this->d.width = width;
2411 this->d.height = height;
2412 this->d.depth = depth;
2414 _common_IDirectDraw_SetDisplayMode(this);
2416 this->e.xlib.paintable = 1;
2417 this->e.xlib.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window;
2418 /* We don't have a context for this window. Host off the desktop */
2419 if( !this->e.xlib.drawable )
2420 this->e.xlib.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
2421 return DD_OK;
2424 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2425 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2427 #ifdef HAVE_LIBXXF86DGA
2428 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2429 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2430 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2431 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2432 if (caps2) {
2433 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2434 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2435 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2437 return DD_OK;
2438 #else /* defined(HAVE_LIBXXF86DGA) */
2439 return E_UNEXPECTED;
2440 #endif /* defined(HAVE_LIBXXF86DGA) */
2443 static void fill_caps(LPDDCAPS caps) {
2444 /* This function tries to fill the capabilities of Wine's DDraw implementation.
2445 Need to be fixed, though.. */
2446 if (caps == NULL)
2447 return;
2449 caps->dwSize = sizeof(*caps);
2450 caps->dwCaps = DDCAPS_3D | DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
2451 DDCAPS_CANBLTSYSMEM | DDCAPS_PALETTE | DDCAPS_ZBLTS;
2452 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NO2DDURING3DSCENE | DDCAPS2_NOPAGELOCKREQUIRED |
2453 DDCAPS2_WIDESURFACES;
2454 caps->dwCKeyCaps = 0;
2455 caps->dwFXCaps = 0;
2456 caps->dwFXAlphaCaps = 0;
2457 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
2458 caps->dwSVCaps = 0;
2459 caps->dwZBufferBitDepths = DDBD_16;
2460 /* I put here 8 Mo so that D3D applications will believe they have enough memory
2461 to put textures in video memory.
2462 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
2463 for example) ? */
2464 caps->dwVidMemTotal = 8192 * 1024;
2465 caps->dwVidMemFree = 8192 * 1024;
2466 /* These are all the supported capabilities of the surfaces */
2467 caps->ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
2468 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
2469 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE |
2470 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE | DDSCAPS_ZBUFFER;
2473 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2474 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2476 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2478 /* Put the same caps for the two capabilities */
2479 fill_caps(caps1);
2480 fill_caps(caps2);
2482 return DD_OK;
2485 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2486 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2488 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2489 this,x,lpddclip,lpunk
2491 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2492 (*lpddclip)->ref = 1;
2493 (*lpddclip)->lpvtbl = &ddclipvt;
2494 return DD_OK;
2497 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2498 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2500 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2501 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2502 (*lpddpal)->ref = 1;
2503 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2504 (*lpddpal)->installed = 0;
2505 if (this->d.depth<=8) {
2506 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
2507 } else {
2508 /* we don't want palettes in hicolor or truecolor */
2509 (*lpddpal)->cm = 0;
2512 if (palent)
2514 /* Initialize the palette based on the passed palent struct */
2515 FIXME(ddraw,"needs to handle palent (%p)\n",palent);
2517 return DD_OK;
2520 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2521 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2523 HRESULT res;
2524 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2525 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
2526 if (res != 0) return res;
2527 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2528 return DD_OK;
2531 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2532 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2534 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2535 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2537 if (*lpddpal == NULL)
2538 return E_OUTOFMEMORY;
2540 (*lpddpal)->ref = 1;
2541 (*lpddpal)->installed = 0;
2542 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2544 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2545 this->lpvtbl->fnAddRef(this);
2547 if (palent)
2548 FIXME(ddraw,"needs to handle palent (%p)\n",palent);
2550 return DD_OK;
2553 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2554 #ifdef HAVE_LIBXXF86DGA
2555 TRACE(ddraw, "(%p)->()\n",this);
2556 Sleep(1000);
2557 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2558 #ifdef RESTORE_SIGNALS
2559 SIGNAL_InitEmulator();
2560 #endif
2561 return DD_OK;
2562 #else /* defined(HAVE_LIBXXF86DGA) */
2563 return E_UNEXPECTED;
2564 #endif
2567 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2568 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
2569 Sleep(1000);
2570 return DD_OK;
2573 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
2574 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
2576 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
2577 return DD_OK;
2580 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
2581 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2583 return ++(this->ref);
2586 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2587 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2589 #ifdef HAVE_LIBXXF86DGA
2590 if (!--(this->ref)) {
2591 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2593 #ifdef HAVE_LIBXXF86VM
2594 if (orig_mode)
2595 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), orig_mode);
2596 if (orig_mode->privsize)
2597 TSXFree(orig_mode->private);
2598 free(orig_mode);
2599 orig_mode = NULL;
2600 #endif
2602 #ifdef RESTORE_SIGNALS
2603 SIGNAL_InitEmulator();
2604 #endif
2605 HeapFree(GetProcessHeap(),0,this);
2606 return 0;
2608 #endif /* defined(HAVE_LIBXXF86DGA) */
2609 return this->ref;
2612 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2613 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2615 if (!--(this->ref)) {
2616 HeapFree(GetProcessHeap(),0,this);
2617 return 0;
2619 /* FIXME: destroy window ... */
2620 return this->ref;
2623 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
2624 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2626 char xrefiid[50];
2628 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2629 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2630 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2631 *obj = this;
2632 this->lpvtbl->fnAddRef(this);
2634 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
2636 return S_OK;
2638 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2639 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
2640 this->lpvtbl->fnAddRef(this);
2641 *obj = this;
2643 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
2645 return S_OK;
2647 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2648 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
2649 this->lpvtbl->fnAddRef(this);
2650 *obj = this;
2652 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
2654 return S_OK;
2656 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2657 LPDIRECT3D d3d;
2659 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2660 d3d->ref = 1;
2661 d3d->ddraw = (LPDIRECTDRAW)this;
2662 this->lpvtbl->fnAddRef(this);
2663 d3d->lpvtbl = &d3dvt;
2664 *obj = d3d;
2666 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2668 return S_OK;
2670 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2671 LPDIRECT3D2 d3d;
2673 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2674 d3d->ref = 1;
2675 d3d->ddraw = (LPDIRECTDRAW)this;
2676 this->lpvtbl->fnAddRef(this);
2677 d3d->lpvtbl = &d3d2vt;
2678 *obj = d3d;
2680 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2682 return S_OK;
2684 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2685 return OLE_E_ENUM_NOMORE;
2688 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
2689 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2691 char xrefiid[50];
2693 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2694 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2695 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2696 *obj = this;
2697 this->lpvtbl->fnAddRef(this);
2699 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
2701 return S_OK;
2703 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2704 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2705 this->lpvtbl->fnAddRef(this);
2706 *obj = this;
2708 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
2710 return S_OK;
2712 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2713 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2714 this->lpvtbl->fnAddRef(this);
2715 *obj = this;
2717 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
2719 return S_OK;
2721 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2722 LPDIRECT3D d3d;
2724 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2725 d3d->ref = 1;
2726 d3d->ddraw = (LPDIRECTDRAW)this;
2727 this->lpvtbl->fnAddRef(this);
2728 d3d->lpvtbl = &d3dvt;
2729 *obj = d3d;
2731 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
2733 return S_OK;
2735 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2736 LPDIRECT3D2 d3d;
2738 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2739 d3d->ref = 1;
2740 d3d->ddraw = (LPDIRECTDRAW)this;
2741 this->lpvtbl->fnAddRef(this);
2742 d3d->lpvtbl = &d3d2vt;
2743 *obj = d3d;
2745 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
2747 return S_OK;
2749 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2750 return OLE_E_ENUM_NOMORE;
2753 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2754 LPDIRECTDRAW2 this,BOOL32 *status
2756 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2757 *status = TRUE;
2758 return DD_OK;
2761 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2762 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2764 DDSURFACEDESC ddsfd;
2765 static struct {
2766 int w,h;
2767 } modes[5] = { /* some of the usual modes */
2768 {512,384},
2769 {640,400},
2770 {640,480},
2771 {800,600},
2772 {1024,768},
2774 static int depths[4] = {8,16,24,32};
2775 int i,j;
2777 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2778 ddsfd.dwSize = sizeof(ddsfd);
2779 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2780 if (dwFlags & DDEDM_REFRESHRATES) {
2781 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2782 ddsfd.x.dwRefreshRate = 60;
2785 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2786 ddsfd.dwBackBufferCount = 1;
2787 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2788 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2789 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2790 /* FIXME: those masks would have to be set in depth > 8 */
2791 if (depths[i]==8) {
2792 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2793 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2794 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2795 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2796 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2797 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2798 } else {
2799 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2801 /* FIXME: We should query those from X itself */
2802 switch (depths[i]) {
2803 case 16:
2804 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2805 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2806 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2807 break;
2808 case 24:
2809 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2810 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2811 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2812 break;
2813 case 32:
2814 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2815 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2816 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2817 break;
2821 ddsfd.dwWidth = screenWidth;
2822 ddsfd.dwHeight = screenHeight;
2823 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2824 if (!modescb(&ddsfd,context)) return DD_OK;
2826 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2827 ddsfd.dwWidth = modes[j].w;
2828 ddsfd.dwHeight = modes[j].h;
2829 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2830 if (!modescb(&ddsfd,context)) return DD_OK;
2833 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2834 /* modeX is not standard VGA */
2836 ddsfd.dwHeight = 200;
2837 ddsfd.dwWidth = 320;
2838 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2839 if (!modescb(&ddsfd,context)) return DD_OK;
2842 return DD_OK;
2845 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2846 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2848 #ifdef HAVE_LIBXXF86DGA
2849 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2850 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2851 lpddsfd->dwHeight = screenHeight;
2852 lpddsfd->dwWidth = screenWidth;
2853 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2854 lpddsfd->dwBackBufferCount = 1;
2855 lpddsfd->x.dwRefreshRate = 60;
2856 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2857 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2858 return DD_OK;
2859 #else /* defined(HAVE_LIBXXF86DGA) */
2860 return E_UNEXPECTED;
2861 #endif /* defined(HAVE_LIBXXF86DGA) */
2864 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2865 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2867 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2868 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2869 lpddsfd->dwHeight = screenHeight;
2870 lpddsfd->dwWidth = screenWidth;
2871 /* POOLE FIXME: Xlib */
2872 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2873 /* END FIXME: Xlib */
2874 lpddsfd->dwBackBufferCount = 1;
2875 lpddsfd->x.dwRefreshRate = 60;
2876 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2877 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2878 return DD_OK;
2881 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2882 TRACE(ddraw,"(%p)->()\n",this);
2883 return DD_OK;
2886 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2887 LPDIRECTDRAW2 this,LPDWORD freq
2889 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2890 *freq = 60*100; /* 60 Hz */
2891 return DD_OK;
2894 /* what can we directly decompress? */
2895 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2896 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2898 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2899 return DD_OK;
2902 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2903 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2905 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2906 return DD_OK;
2909 static HRESULT WINAPI IDirectDraw2_Compact(
2910 LPDIRECTDRAW2 this )
2912 FIXME(ddraw,"(%p)->()\n", this );
2914 return DD_OK;
2918 /* Note: Hack so we can reuse the old functions without compiler warnings */
2919 #ifdef __GNUC__
2920 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2921 #else
2922 # define XCAST(fun) (void*)
2923 #endif
2925 static struct IDirectDraw_VTable dga_ddvt = {
2926 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2927 XCAST(AddRef)IDirectDraw2_AddRef,
2928 XCAST(Release)DGA_IDirectDraw2_Release,
2929 XCAST(Compact)IDirectDraw2_Compact,
2930 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2931 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2932 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2933 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2934 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2935 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2936 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2937 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2938 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2939 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2940 XCAST(GetGDISurface)15,
2941 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2942 XCAST(GetScanLine)17,
2943 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2944 XCAST(Initialize)19,
2945 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2946 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2947 DGA_IDirectDraw_SetDisplayMode,
2948 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2951 static struct IDirectDraw_VTable xlib_ddvt = {
2952 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2953 XCAST(AddRef)IDirectDraw2_AddRef,
2954 XCAST(Release)Xlib_IDirectDraw2_Release,
2955 XCAST(Compact)IDirectDraw2_Compact,
2956 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2957 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2958 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2959 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2960 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2961 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2962 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2963 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2964 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2965 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2966 XCAST(GetGDISurface)15,
2967 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2968 XCAST(GetScanLine)17,
2969 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2970 XCAST(Initialize)19,
2971 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2972 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2973 Xlib_IDirectDraw_SetDisplayMode,
2974 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2977 /*****************************************************************************
2978 * IDirectDraw2
2983 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2984 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2986 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2989 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2990 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2992 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2995 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2996 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2998 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2999 this,ddscaps,total,free
3001 if (total) *total = this->e.dga.fb_memsize * 1024;
3002 if (free) *free = this->e.dga.fb_memsize * 1024;
3003 return DD_OK;
3006 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
3007 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3009 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3010 this,ddscaps,total,free
3012 if (total) *total = 2048 * 1024;
3013 if (free) *free = 2048 * 1024;
3014 return DD_OK;
3017 static IDirectDraw2_VTable dga_dd2vt = {
3018 DGA_IDirectDraw2_QueryInterface,
3019 IDirectDraw2_AddRef,
3020 DGA_IDirectDraw2_Release,
3021 IDirectDraw2_Compact,
3022 IDirectDraw2_CreateClipper,
3023 DGA_IDirectDraw2_CreatePalette,
3024 DGA_IDirectDraw2_CreateSurface,
3025 (void*)8,
3026 IDirectDraw2_EnumDisplayModes,
3027 IDirectDraw2_EnumSurfaces,
3028 IDirectDraw2_FlipToGDISurface,
3029 DGA_IDirectDraw2_GetCaps,
3030 DGA_IDirectDraw2_GetDisplayMode,
3031 IDirectDraw2_GetFourCCCodes,
3032 (void*)15,
3033 IDirectDraw2_GetMonitorFrequency,
3034 (void*)17,
3035 IDirectDraw2_GetVerticalBlankStatus,
3036 (void*)19,
3037 DGA_IDirectDraw2_RestoreDisplayMode,
3038 IDirectDraw2_SetCooperativeLevel,
3039 DGA_IDirectDraw2_SetDisplayMode,
3040 IDirectDraw2_WaitForVerticalBlank,
3041 DGA_IDirectDraw2_GetAvailableVidMem
3044 static struct IDirectDraw2_VTable xlib_dd2vt = {
3045 Xlib_IDirectDraw2_QueryInterface,
3046 IDirectDraw2_AddRef,
3047 Xlib_IDirectDraw2_Release,
3048 IDirectDraw2_Compact,
3049 IDirectDraw2_CreateClipper,
3050 Xlib_IDirectDraw2_CreatePalette,
3051 Xlib_IDirectDraw2_CreateSurface,
3052 (void*)8,
3053 IDirectDraw2_EnumDisplayModes,
3054 IDirectDraw2_EnumSurfaces,
3055 IDirectDraw2_FlipToGDISurface,
3056 Xlib_IDirectDraw2_GetCaps,
3057 Xlib_IDirectDraw2_GetDisplayMode,
3058 IDirectDraw2_GetFourCCCodes,
3059 (void*)15,
3060 IDirectDraw2_GetMonitorFrequency,
3061 (void*)17,
3062 IDirectDraw2_GetVerticalBlankStatus,
3063 (void*)19,
3064 Xlib_IDirectDraw2_RestoreDisplayMode,
3065 IDirectDraw2_SetCooperativeLevel,
3066 Xlib_IDirectDraw2_SetDisplayMode,
3067 IDirectDraw2_WaitForVerticalBlank,
3068 Xlib_IDirectDraw2_GetAvailableVidMem
3071 /******************************************************************************
3072 * DirectDrawCreate
3075 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
3077 LRESULT ret;
3078 LPDIRECTDRAW ddraw = NULL;
3079 DWORD lastError;
3081 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
3083 SetLastError( ERROR_SUCCESS );
3084 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
3085 if( (!ddraw) &&
3086 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
3089 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
3092 if( ddraw )
3094 /* Perform any special direct draw functions */
3095 if (msg==WM_PAINT)
3096 ddraw->e.xlib.paintable = 1;
3098 /* Now let the application deal with the rest of this */
3099 if( ddraw->d.mainWindow )
3102 /* Don't think that we actually need to call this but...
3103 might as well be on the safe side of things... */
3105 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
3106 it should be the procedures of our fake window that gets called
3107 instead of those of the window provided by the application.
3108 And with this patch, mouse clicks work with Monkey Island III
3109 - Lionel */
3110 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
3112 if( !ret )
3114 /* We didn't handle the message - give it to the application */
3115 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
3116 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
3117 ddraw->d.mainWindow, msg, wParam, lParam );
3121 } else {
3122 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
3126 else
3128 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
3131 return ret;
3134 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
3135 #ifdef HAVE_LIBXXF86DGA
3136 int memsize,banksize,width,major,minor,flags,height;
3137 char *addr;
3138 int fd;
3140 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
3141 if ((fd = open("/dev/mem", O_RDWR)) != -1)
3142 close(fd);
3144 if (fd == -1) {
3145 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
3146 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
3147 return E_UNEXPECTED;
3149 if (!DDRAW_DGA_Available()) {
3150 TRACE(ddraw,"No XF86DGA detected.\n");
3151 return DDERR_GENERIC;
3153 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3154 (*lplpDD)->lpvtbl = &dga_ddvt;
3155 (*lplpDD)->ref = 1;
3156 TSXF86DGAQueryVersion(display,&major,&minor);
3157 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
3158 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
3159 if (!(flags & XF86DGADirectPresent))
3160 MSG("direct video is NOT PRESENT.\n");
3161 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
3162 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
3163 addr,width,banksize,memsize
3165 (*lplpDD)->e.dga.fb_width = width;
3166 (*lplpDD)->d.width = width;
3167 (*lplpDD)->e.dga.fb_addr = addr;
3168 (*lplpDD)->e.dga.fb_memsize = memsize;
3169 (*lplpDD)->e.dga.fb_banksize = banksize;
3171 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
3172 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3173 (*lplpDD)->e.dga.fb_height = screenHeight;
3174 #ifdef DIABLO_HACK
3175 (*lplpDD)->e.dga.vpmask = 1;
3176 #else
3177 (*lplpDD)->e.dga.vpmask = 0;
3178 #endif
3180 /* just assume the default depth is the DGA depth too */
3181 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
3182 #ifdef RESTORE_SIGNALS
3183 SIGNAL_InitEmulator();
3184 #endif
3186 return DD_OK;
3187 #else /* defined(HAVE_LIBXXF86DGA) */
3188 return DDERR_INVALIDDIRECTDRAWGUID;
3189 #endif /* defined(HAVE_LIBXXF86DGA) */
3192 BOOL32
3193 DDRAW_XSHM_Available()
3195 #ifdef HAVE_LIBXXSHM
3196 if (TSXShmQueryExtension(display))
3198 int major, minor;
3199 Bool shpix;
3201 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
3202 return 1;
3203 else
3204 return 0;
3206 else
3207 return 0;
3208 #else
3209 return 0;
3210 #endif
3213 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
3215 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3216 (*lplpDD)->lpvtbl = &xlib_ddvt;
3217 (*lplpDD)->ref = 1;
3218 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
3220 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
3221 (*lplpDD)->d.height = screenHeight;
3222 (*lplpDD)->d.width = screenWidth;
3224 #ifdef HAVE_LIBXXSHM
3225 /* Test if XShm is available.
3226 As XShm is not ready yet for 'prime-time', it is disabled for now */
3227 if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
3228 TRACE(ddraw, "Using XShm extesion.\n");
3229 #endif
3231 return DD_OK;
3234 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
3235 char xclsid[50];
3236 WNDCLASS32A wc;
3237 WND* pParentWindow;
3238 HRESULT ret;
3240 if (HIWORD(lpGUID))
3241 WINE_StringFromCLSID(lpGUID,xclsid);
3242 else {
3243 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
3244 lpGUID = NULL;
3247 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
3249 if (!lpGUID) {
3250 /* if they didn't request a particular interface, use the best
3251 * supported one */
3252 if (DDRAW_DGA_Available())
3253 lpGUID = &DGA_DirectDraw_GUID;
3254 else
3255 lpGUID = &XLIB_DirectDraw_GUID;
3258 wc.style = CS_GLOBALCLASS;
3259 wc.lpfnWndProc = Xlib_DDWndProc;
3260 wc.cbClsExtra = 0;
3261 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
3262 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
3264 /* We can be a child of the desktop since we're really important */
3265 pParentWindow = WIN_GetDesktop();
3266 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
3267 wc.hInstance = 0;
3269 wc.hIcon = 0;
3270 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
3271 wc.hbrBackground= NULL_BRUSH;
3272 wc.lpszMenuName = 0;
3273 wc.lpszClassName= "WINE_DirectDraw";
3274 RegisterClass32A(&wc);
3276 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
3277 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
3278 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
3279 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
3280 else
3281 goto err;
3283 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
3284 return ret;
3286 err:
3287 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
3288 return DDERR_INVALIDDIRECTDRAWGUID;