294 missing WINAPI added.
[wine/multimedia.git] / graphics / ddraw.c
blob46260a74b2c2ef880a7fdc0fe21a11ff75a6a632
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 */
5 /* XF86DGA:
6 * When DirectVideo mode is enabled you can no longer use 'normal' X
7 * applications nor can you switch to a virtual console. Also, enabling
8 * only works, if you have switched to the screen where the application
9 * is running.
10 * Some ways to debug this stuff are:
11 * - A terminal connected to the serial port. Can be bought used for cheap.
12 * (This is the method I am using.)
13 * - Another machine connected over some kind of network.
16 #include "config.h"
17 #include <unistd.h>
18 #include <assert.h>
19 #include "ts_xlib.h"
20 #include <sys/signal.h>
21 #include <fcntl.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include "windows.h"
26 #ifdef HAVE_LIBXXF86VM
27 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
28 this is a crude hack to get around it */
29 #define XMD_H
30 #include "ts_xf86vmode.h"
31 #endif
33 #include "winerror.h"
34 #include "interfaces.h"
35 #include "gdi.h"
36 #include "heap.h"
37 #include "ldt.h"
38 #include "dc.h"
39 #include "win.h"
40 #include "miscemu.h"
41 #include "ddraw.h"
42 #include "d3d.h"
43 #include "debug.h"
44 #include "compobj.h"
45 #include "spy.h"
46 #include "message.h"
47 #include "x11drv.h"
48 #include "options.h"
50 #ifdef HAVE_LIBXXF86DGA
51 #include "ts_xf86dga.h"
52 #endif
54 #ifdef HAVE_LIBXXSHM
55 #include <sys/types.h>
56 #include <sys/ipc.h>
57 #include <sys/shm.h>
58 #include "ts_xshm.h"
59 #endif
61 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
62 #undef DIABLO_HACK
64 /* Restore signal handlers overwritten by XF86DGA
65 * this is a define, for it will only work in emulator mode
67 #undef RESTORE_SIGNALS
69 /* Where do these GUIDs come from? mkuuid.
70 * They exist solely to distinguish between the targets Wine support,
71 * and should be different than any other GUIDs in existence.
73 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
74 0xe2dcb020,
75 0xdc60,
76 0x11d1,
77 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
80 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
81 0x1574a740,
82 0xdc61,
83 0x11d1,
84 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
87 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
88 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
89 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
90 static struct IDirectDrawClipper_VTable ddclipvt;
91 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
92 static struct IDirect3D_VTable d3dvt;
93 static struct IDirect3D2_VTable d3d2vt;
95 BOOL32
96 DDRAW_DGA_Available()
98 #ifdef HAVE_LIBXXF86DGA
99 int evbase, evret, fd;
101 if (Options.noDGA)
102 return 0;
104 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
105 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
106 /* others. --stephenc */
107 if ((fd = open("/dev/mem", O_RDWR)) != -1)
108 close(fd);
110 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
111 #else /* defined(HAVE_LIBXXF86DGA) */
112 return 0;
113 #endif /* defined(HAVE_LIBXXF86DGA) */
116 HRESULT WINAPI
117 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
118 if (DDRAW_DGA_Available()) {
119 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
121 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
122 ddenumproc(NULL,"WINE","display",data);
123 return 0;
126 /* What is this doing here? */
127 HRESULT WINAPI
128 DSoundHelp(DWORD x,DWORD y,DWORD z) {
129 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
130 return 0;
134 /******************************************************************************
135 * internal helper functions
137 static void _dump_DDBLTFX(DWORD flagmask) {
138 int i;
139 const struct {
140 DWORD mask;
141 char *name;
142 } flags[] = {
143 #define FE(x) { x, #x},
144 FE(DDBLTFX_ARITHSTRETCHY)
145 FE(DDBLTFX_MIRRORLEFTRIGHT)
146 FE(DDBLTFX_MIRRORUPDOWN)
147 FE(DDBLTFX_NOTEARING)
148 FE(DDBLTFX_ROTATE180)
149 FE(DDBLTFX_ROTATE270)
150 FE(DDBLTFX_ROTATE90)
151 FE(DDBLTFX_ZBUFFERRANGE)
152 FE(DDBLTFX_ZBUFFERBASEDEST)
154 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
155 if (flags[i].mask & flagmask) {
156 DUMP("%s ",flags[i].name);
159 DUMP("\n");
163 static void _dump_DDBLTFAST(DWORD flagmask) {
164 int i;
165 const struct {
166 DWORD mask;
167 char *name;
168 } flags[] = {
169 #define FE(x) { x, #x},
170 FE(DDBLTFAST_NOCOLORKEY)
171 FE(DDBLTFAST_SRCCOLORKEY)
172 FE(DDBLTFAST_DESTCOLORKEY)
173 FE(DDBLTFAST_WAIT)
175 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
176 if (flags[i].mask & flagmask)
177 DUMP("%s ",flags[i].name);
178 DUMP("\n");
181 static void _dump_DDBLT(DWORD flagmask) {
182 int i;
183 const struct {
184 DWORD mask;
185 char *name;
186 } flags[] = {
187 #define FE(x) { x, #x},
188 FE(DDBLT_ALPHADEST)
189 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
190 FE(DDBLT_ALPHADESTNEG)
191 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
192 FE(DDBLT_ALPHAEDGEBLEND)
193 FE(DDBLT_ALPHASRC)
194 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
195 FE(DDBLT_ALPHASRCNEG)
196 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
197 FE(DDBLT_ASYNC)
198 FE(DDBLT_COLORFILL)
199 FE(DDBLT_DDFX)
200 FE(DDBLT_DDROPS)
201 FE(DDBLT_KEYDEST)
202 FE(DDBLT_KEYDESTOVERRIDE)
203 FE(DDBLT_KEYSRC)
204 FE(DDBLT_KEYSRCOVERRIDE)
205 FE(DDBLT_ROP)
206 FE(DDBLT_ROTATIONANGLE)
207 FE(DDBLT_ZBUFFER)
208 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
209 FE(DDBLT_ZBUFFERDESTOVERRIDE)
210 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
211 FE(DDBLT_ZBUFFERSRCOVERRIDE)
212 FE(DDBLT_WAIT)
213 FE(DDBLT_DEPTHFILL)
215 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
216 if (flags[i].mask & flagmask)
217 DUMP("%s ",flags[i].name);
220 static void _dump_DDSCAPS(DWORD flagmask) {
221 int i;
222 const struct {
223 DWORD mask;
224 char *name;
225 } flags[] = {
226 #define FE(x) { x, #x},
227 FE(DDSCAPS_RESERVED1)
228 FE(DDSCAPS_ALPHA)
229 FE(DDSCAPS_BACKBUFFER)
230 FE(DDSCAPS_COMPLEX)
231 FE(DDSCAPS_FLIP)
232 FE(DDSCAPS_FRONTBUFFER)
233 FE(DDSCAPS_OFFSCREENPLAIN)
234 FE(DDSCAPS_OVERLAY)
235 FE(DDSCAPS_PALETTE)
236 FE(DDSCAPS_PRIMARYSURFACE)
237 FE(DDSCAPS_PRIMARYSURFACELEFT)
238 FE(DDSCAPS_SYSTEMMEMORY)
239 FE(DDSCAPS_TEXTURE)
240 FE(DDSCAPS_3DDEVICE)
241 FE(DDSCAPS_VIDEOMEMORY)
242 FE(DDSCAPS_VISIBLE)
243 FE(DDSCAPS_WRITEONLY)
244 FE(DDSCAPS_ZBUFFER)
245 FE(DDSCAPS_OWNDC)
246 FE(DDSCAPS_LIVEVIDEO)
247 FE(DDSCAPS_HWCODEC)
248 FE(DDSCAPS_MODEX)
249 FE(DDSCAPS_MIPMAP)
250 FE(DDSCAPS_RESERVED2)
251 FE(DDSCAPS_ALLOCONLOAD)
252 FE(DDSCAPS_VIDEOPORT)
253 FE(DDSCAPS_LOCALVIDMEM)
254 FE(DDSCAPS_NONLOCALVIDMEM)
255 FE(DDSCAPS_STANDARDVGAMODE)
256 FE(DDSCAPS_OPTIMIZED)
258 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
259 if (flags[i].mask & flagmask)
260 DUMP("%s ",flags[i].name);
261 DUMP("\n");
264 static void _dump_DDSD(DWORD flagmask) {
265 int i;
266 const struct {
267 DWORD mask;
268 char *name;
269 } flags[] = {
270 FE(DDSD_CAPS)
271 FE(DDSD_HEIGHT)
272 FE(DDSD_WIDTH)
273 FE(DDSD_PITCH)
274 FE(DDSD_BACKBUFFERCOUNT)
275 FE(DDSD_ZBUFFERBITDEPTH)
276 FE(DDSD_ALPHABITDEPTH)
277 FE(DDSD_PIXELFORMAT)
278 FE(DDSD_CKDESTOVERLAY)
279 FE(DDSD_CKDESTBLT)
280 FE(DDSD_CKSRCOVERLAY)
281 FE(DDSD_CKSRCBLT)
282 FE(DDSD_MIPMAPCOUNT)
283 FE(DDSD_REFRESHRATE)
284 FE(DDSD_LINEARSIZE)
285 FE(DDSD_LPSURFACE)
287 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
288 if (flags[i].mask & flagmask)
289 DUMP("%s ",flags[i].name);
290 DUMP("\n");
293 static void _dump_DDCOLORKEY(DWORD flagmask) {
294 int i;
295 const struct {
296 DWORD mask;
297 char *name;
298 } flags[] = {
299 #define FE(x) { x, #x},
300 FE(DDPF_ALPHAPIXELS)
301 FE(DDPF_ALPHA)
302 FE(DDPF_FOURCC)
303 FE(DDPF_PALETTEINDEXED4)
304 FE(DDPF_PALETTEINDEXEDTO8)
305 FE(DDPF_PALETTEINDEXED8)
306 FE(DDPF_RGB)
307 FE(DDPF_COMPRESSED)
308 FE(DDPF_RGBTOYUV)
309 FE(DDPF_YUV)
310 FE(DDPF_ZBUFFER)
311 FE(DDPF_PALETTEINDEXED1)
312 FE(DDPF_PALETTEINDEXED2)
313 FE(DDPF_ZPIXELS)
315 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
316 if (flags[i].mask & flagmask)
317 DUMP("%s ",flags[i].name);
318 DUMP("\n");
321 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
322 _dump_DDCOLORKEY(pf->dwFlags);
323 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
324 DUMP("RBG bit cbout : %ld\n", pf->x.dwRGBBitCount);
325 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
326 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
329 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
330 static XVisualInfo *vi;
331 XVisualInfo vt;
332 int nitems;
334 if (!vi)
335 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
337 pf->dwFourCC = 0;
338 if (ddraw->d.depth==8) {
339 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
340 pf->x.dwRGBBitCount = 8;
341 pf->y.dwRBitMask = 0;
342 pf->z.dwGBitMask = 0;
343 pf->xx.dwBBitMask = 0;
344 pf->xy.dwRGBAlphaBitMask= 0;
345 return 0;
347 if (ddraw->d.depth==16) {
348 pf->dwFlags = DDPF_RGB;
349 pf->x.dwRGBBitCount = 16;
350 pf->y.dwRBitMask = vi[0].red_mask;
351 pf->z.dwGBitMask = vi[0].green_mask;
352 pf->xx.dwBBitMask = vi[0].blue_mask;
353 pf->xy.dwRGBAlphaBitMask= 0;
354 return 0;
356 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
357 return DDERR_GENERIC;
360 /******************************************************************************
361 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
363 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
364 * DDS and DDS2 use those functions. (Function calls did not change (except
365 * using different DirectDrawSurfaceX version), just added flags and functions)
367 static HRESULT WINAPI IDirectDrawSurface3_Lock(
368 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
370 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
371 this,lprect,lpddsd,flags,(DWORD)hnd);
372 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
373 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
374 this,lprect,lpddsd,flags,(DWORD)hnd);
376 /* First, copy the Surface description */
377 *lpddsd = this->s.surface_desc;
379 /* If asked only for a part, change the surface pointer */
380 if (lprect) {
381 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
382 lprect->top,lprect->left,lprect->bottom,lprect->right
384 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
385 (lprect->top*this->s.surface_desc.lPitch) +
386 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
387 } else {
388 assert(this->s.surface_desc.y.lpSurface);
390 return 0;
393 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
394 LPDIRECTDRAWSURFACE3 this,LPVOID surface
396 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
397 return 0;
400 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
401 LPDIRECTDRAWSURFACE3 this,LPVOID surface)
403 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
405 if (!this->s.ddraw->e.xlib.paintable)
406 return DD_OK;
408 /* Only redraw the screen when unlocking the buffer that is on screen */
409 if ((this->t.xlib.image != NULL) &&
410 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
411 #ifdef HAVE_LIBXXSHM
412 if (this->s.ddraw->e.xlib.xshm_active)
413 TSXShmPutImage(display,
414 this->s.ddraw->e.xlib.drawable,
415 DefaultGCOfScreen(screen),
416 this->t.xlib.image,
417 0, 0, 0, 0,
418 this->t.xlib.image->width,
419 this->t.xlib.image->height,
420 False);
421 else
422 #endif
423 TSXPutImage( display,
424 this->s.ddraw->e.xlib.drawable,
425 DefaultGCOfScreen(screen),
426 this->t.xlib.image,
427 0, 0, 0, 0,
428 this->t.xlib.image->width,
429 this->t.xlib.image->height);
431 if (this->s.palette && this->s.palette->cm)
432 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
435 return DD_OK;
438 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
439 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
441 #ifdef HAVE_LIBXXF86DGA
442 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
443 if (!flipto) {
444 if (this->s.backbuffer)
445 flipto = this->s.backbuffer;
446 else
447 flipto = this;
449 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
451 if (flipto->s.palette && flipto->s.palette->cm) {
452 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
454 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
456 if (flipto!=this) {
457 int tmp;
458 LPVOID ptmp;
460 tmp = this->t.dga.fb_height;
461 this->t.dga.fb_height = flipto->t.dga.fb_height;
462 flipto->t.dga.fb_height = tmp;
464 ptmp = this->s.surface_desc.y.lpSurface;
465 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
466 flipto->s.surface_desc.y.lpSurface = ptmp;
468 return 0;
469 #else /* defined(HAVE_LIBXXF86DGA) */
470 return E_UNEXPECTED;
471 #endif /* defined(HAVE_LIBXXF86DGA) */
474 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
475 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
477 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
478 if (!this->s.ddraw->e.xlib.paintable)
479 return 0;
481 if (!flipto) {
482 if (this->s.backbuffer)
483 flipto = this->s.backbuffer;
484 else
485 flipto = this;
488 #ifdef HAVE_LIBXXSHM
489 if (this->s.ddraw->e.xlib.xshm_active) {
490 TSXShmPutImage(display,
491 this->s.ddraw->e.xlib.drawable,
492 DefaultGCOfScreen(screen),
493 flipto->t.xlib.image,
494 0, 0, 0, 0,
495 flipto->t.xlib.image->width,
496 flipto->t.xlib.image->height,
497 False);
498 } else
499 #endif
500 TSXPutImage(display,
501 this->s.ddraw->e.xlib.drawable,
502 DefaultGCOfScreen(screen),
503 flipto->t.xlib.image,
504 0, 0, 0, 0,
505 flipto->t.xlib.image->width,
506 flipto->t.xlib.image->height);
508 if (flipto->s.palette && flipto->s.palette->cm) {
509 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,flipto->s.palette->cm);
511 if (flipto!=this) {
512 XImage *tmp;
513 LPVOID *surf;
514 tmp = this->t.xlib.image;
515 this->t.xlib.image = flipto->t.xlib.image;
516 flipto->t.xlib.image = tmp;
517 surf = this->s.surface_desc.y.lpSurface;
518 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
519 flipto->s.surface_desc.y.lpSurface = surf;
521 return 0;
525 /* The IDirectDrawSurface3::SetPalette method attaches the specified
526 * DirectDrawPalette object to a surface. The surface uses this palette for all
527 * subsequent operations. The palette change takes place immediately.
529 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
530 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
532 int i;
533 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
535 if (!(pal->cm) && (this->s.ddraw->d.depth<=8)) {
536 pal->cm = TSXCreateColormap(display,this->s.ddraw->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
537 /* FIXME: this is not correct, when using -managed */
538 TSXInstallColormap(display,pal->cm);
539 for (i=0;i<256;i++) {
540 XColor xc;
542 xc.red = pal->palents[i].peRed<<8;
543 xc.blue = pal->palents[i].peBlue<<8;
544 xc.green = pal->palents[i].peGreen<<8;
545 xc.flags = DoRed|DoBlue|DoGreen;
546 xc.pixel = i;
547 TSXStoreColor(display,pal->cm,&xc);
550 /* According to spec, we are only supposed to
551 * AddRef if this is not the same palette.
553 if( this->s.palette != pal )
555 if( pal != NULL )
556 pal->lpvtbl->fnAddRef( pal );
557 if( this->s.palette != NULL )
558 this->s.palette->lpvtbl->fnRelease( this->s.palette );
559 this->s.palette = pal;
561 /* I think that we need to attach it to all backbuffers...*/
562 if( this->s.backbuffer ) {
563 if( this->s.backbuffer->s.palette )
564 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
565 this->s.backbuffer->s.palette );
566 this->s.backbuffer->s.palette = pal;
567 if( pal )
568 pal->lpvtbl->fnAddRef( pal );
570 /* Perform the refresh */
571 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
573 return 0;
576 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
577 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
579 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
580 #ifdef HAVE_LIBXXF86DGA
581 /* According to spec, we are only supposed to
582 * AddRef if this is not the same palette.
584 if( this->s.palette != pal )
586 if( pal != NULL )
587 pal->lpvtbl->fnAddRef( pal );
588 if( this->s.palette != NULL )
589 this->s.palette->lpvtbl->fnRelease( this->s.palette );
590 this->s.palette = pal;
592 /* I think that we need to attach it to all backbuffers...*/
593 if( this->s.backbuffer ) {
594 if( this->s.backbuffer->s.palette )
595 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
596 this->s.backbuffer->s.palette = pal;
597 if( pal ) pal->lpvtbl->fnAddRef( pal );
599 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
601 return 0;
602 #else /* defined(HAVE_LIBXXF86DGA) */
603 return E_UNEXPECTED;
604 #endif /* defined(HAVE_LIBXXF86DGA) */
609 static HRESULT WINAPI IDirectDrawSurface3_Blt(
610 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
612 RECT32 xdst,xsrc;
613 DDSURFACEDESC ddesc,sdesc;
614 int i,j;
616 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
617 this,rdst,src,rsrc,dwFlags,lpbltfx);
619 if (src != NULL)
620 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
621 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
623 if (TRACE_ON(ddraw)) {
624 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
625 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
626 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
627 if (dwFlags & DDBLT_DDFX) {
628 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
632 if (rdst) {
633 memcpy(&xdst,rdst,sizeof(xdst));
634 } else {
635 xdst.top = 0;
636 xdst.bottom = ddesc.dwHeight;
637 xdst.left = 0;
638 xdst.right = ddesc.dwWidth;
641 if (rsrc) {
642 memcpy(&xsrc,rsrc,sizeof(xsrc));
643 } else {
644 if (src) {
645 xsrc.top = 0;
646 xsrc.bottom = sdesc.dwHeight;
647 xsrc.left = 0;
648 xsrc.right = sdesc.dwWidth;
649 } else {
650 memset(&xsrc,0,sizeof(xsrc));
654 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
656 if (dwFlags & DDBLT_COLORFILL) {
657 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
658 LPBYTE xline,xpixel;
660 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
661 for (i=xdst.top;i<xdst.bottom;i++) {
662 xpixel = xline+bpp*xdst.left;
664 for (j=xdst.left;j<xdst.right;j++) {
665 /* FIXME: this only works on little endian
666 * architectures, where DWORD starts with low
667 * byte first!
669 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
670 xpixel += bpp;
672 xline += ddesc.lPitch;
674 dwFlags &= ~(DDBLT_COLORFILL);
677 if (!src) {
678 if (dwFlags) {
679 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
681 return 0;
684 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
685 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
686 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
687 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
688 !dwFlags
690 memcpy(ddesc.y.lpSurface,
691 sdesc.y.lpSurface,
692 ddesc.dwHeight * ddesc.lPitch);
693 } else {
694 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
695 int height = xsrc.bottom - xsrc.top;
696 int width = (xsrc.right - xsrc.left) * bpp;
697 int h;
699 for (h = 0; h < height; h++) {
700 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
701 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
702 width);
706 if (dwFlags && FIXME_ON(ddraw)) {
707 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
710 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
711 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
713 return 0;
716 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
717 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
719 int i,bpp;
720 DDSURFACEDESC ddesc,sdesc;
722 if (TRACE_ON(ddraw)) {
723 TRACE(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
724 this,dstx,dsty,src,rsrc,trans
726 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
727 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
729 /* We need to lock the surfaces, or we won't get refreshes when done. */
730 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
731 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
732 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
733 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
734 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
735 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
736 (rsrc->right-rsrc->left)*bpp
739 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
740 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
741 return 0;
744 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
745 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
747 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
748 this,ddbltbatch,x,y
750 return 0;
753 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
754 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
756 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
757 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
758 return 0;
761 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
762 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
763 ) {
764 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
765 this,ddsd);
767 /* Simply copy the surface description stored in the object */
768 *ddsd = this->s.surface_desc;
770 if (TRACE_ON(ddraw)) {
771 fprintf(stderr," flags: ");
772 _dump_DDSD(ddsd->dwFlags);
773 if (ddsd->dwFlags & DDSD_CAPS) {
774 fprintf(stderr, " caps: ");
775 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
777 fprintf(stderr,"\n");
780 return 0;
783 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
784 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
786 return ++(this->ref);
789 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
790 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
792 #ifdef HAVE_LIBXXF86DGA
793 if (!--(this->ref)) {
794 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
795 /* clear out of surface list */
796 if (this->t.dga.fb_height == -1) {
797 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
798 } else {
799 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
801 HeapFree(GetProcessHeap(),0,this);
802 return 0;
804 #endif /* defined(HAVE_LIBXXF86DGA) */
805 return this->ref;
808 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
809 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
811 if (!--(this->ref)) {
812 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
814 if( this->s.backbuffer )
815 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
817 if (this->t.xlib.image != NULL) {
818 this->t.xlib.image->data = NULL;
820 #ifdef HAVE_LIBXXSHM
821 if (this->s.ddraw->e.xlib.xshm_active) {
822 TSXShmDetach(display, &(this->t.xlib.shminfo));
823 TSXDestroyImage(this->t.xlib.image);
824 shmdt(this->t.xlib.shminfo.shmaddr);
825 } else {
826 #endif
827 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
828 TSXDestroyImage(this->t.xlib.image);
829 #ifdef HAVE_LIBXXSHM
831 #endif
833 this->t.xlib.image = 0;
834 } else {
835 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
838 if (this->s.palette)
839 this->s.palette->lpvtbl->fnRelease(this->s.palette);
841 HeapFree(GetProcessHeap(),0,this);
842 return 0;
845 return this->ref;
848 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
849 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
851 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
852 this, lpddsd, lpdsf);
854 if (TRACE_ON(ddraw)) {
855 TRACE(ddraw," caps ");
856 _dump_DDSCAPS(lpddsd->dwCaps);
859 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
860 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
861 return E_FAIL;
864 /* FIXME: should handle more than one backbuffer */
865 *lpdsf = this->s.backbuffer;
867 if( this->s.backbuffer )
868 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
870 return 0;
873 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
874 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
876 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
878 return DDERR_ALREADYINITIALIZED;
881 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
882 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
884 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
886 *pf = this->s.surface_desc.ddpfPixelFormat;
888 return 0;
891 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
892 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
893 return 0;
896 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
897 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
899 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
900 return 0;
903 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
904 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
906 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
907 return 0;
910 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
911 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
913 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
915 /* This hack will be enough for the moment */
916 if (this->s.backbuffer == NULL)
917 this->s.backbuffer = surf;
918 return 0;
921 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
922 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
923 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
924 return 0;
927 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
928 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
929 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
930 return 0;
934 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
935 char xrefiid[50];
937 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
938 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
940 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
941 * the same interface. And IUnknown does that too of course.
943 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
944 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
945 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
946 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
948 *obj = this;
949 this->lpvtbl->fnAddRef(this);
950 return 0;
952 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
953 return OLE_E_ENUM_NOMORE;
956 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
957 TRACE(ddraw,"(%p)->(), stub!\n",this);
958 return 0; /* hmm */
961 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
962 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
963 return 0;
966 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
967 FIXME(ddraw,"(%p)->(),stub!\n",this);
968 return 0;
971 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
972 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
974 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
976 if( dwFlags & DDCKEY_SRCBLT )
977 dwFlags &= ~DDCKEY_SRCBLT;
978 if( dwFlags )
979 TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
980 return DD_OK;
983 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
984 LPDIRECTDRAWSURFACE3 this,
985 LPRECT32 lpRect )
987 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
989 return DD_OK;
992 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
993 LPDIRECTDRAWSURFACE3 this,
994 DWORD dwFlags,
995 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
997 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
999 return DD_OK;
1002 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
1003 LPDIRECTDRAWSURFACE3 this,
1004 DWORD dwFlags,
1005 LPVOID lpContext,
1006 LPDDENUMSURFACESCALLBACK lpfnCallback )
1008 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1009 lpContext, lpfnCallback );
1011 return DD_OK;
1014 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
1015 LPDIRECTDRAWSURFACE3 this,
1016 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1018 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1020 return DD_OK;
1023 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
1024 LPDIRECTDRAWSURFACE3 this,
1025 DWORD dwFlags,
1026 LPDDCOLORKEY lpDDColorKey )
1028 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDColorKey);
1030 return DD_OK;
1033 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
1034 LPDIRECTDRAWSURFACE3 this,
1035 DWORD dwFlags )
1037 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1039 return DD_OK;
1042 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
1043 LPDIRECTDRAWSURFACE3 this,
1044 LPDIRECTDRAWPALETTE* lplpDDPalette )
1046 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1048 return DD_OK;
1051 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
1052 LPDIRECTDRAWSURFACE3 this,
1053 LONG lX,
1054 LONG lY)
1056 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1058 return DD_OK;
1061 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
1062 LPDIRECTDRAWSURFACE3 this,
1063 LPRECT32 lpSrcRect,
1064 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
1065 LPRECT32 lpDestRect,
1066 DWORD dwFlags,
1067 LPDDOVERLAYFX lpDDOverlayFx )
1069 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1070 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1072 return DD_OK;
1075 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
1076 LPDIRECTDRAWSURFACE3 this,
1077 DWORD dwFlags )
1079 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1081 return DD_OK;
1084 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
1085 LPDIRECTDRAWSURFACE3 this,
1086 DWORD dwFlags,
1087 LPDIRECTDRAWSURFACE3 lpDDSReference )
1089 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1091 return DD_OK;
1094 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
1095 LPDIRECTDRAWSURFACE3 this,
1096 LPVOID* lplpDD )
1098 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1100 return DD_OK;
1103 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
1104 LPDIRECTDRAWSURFACE3 this,
1105 DWORD dwFlags )
1107 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1109 return DD_OK;
1112 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
1113 LPDIRECTDRAWSURFACE3 this,
1114 DWORD dwFlags )
1116 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1118 return DD_OK;
1121 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1122 LPDIRECTDRAWSURFACE3 this,
1123 LPDDSURFACEDESC lpDDSD,
1124 DWORD dwFlags )
1126 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1128 return DD_OK;
1131 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1132 IDirectDrawSurface3_QueryInterface,
1133 IDirectDrawSurface3_AddRef,
1134 DGA_IDirectDrawSurface3_Release,
1135 IDirectDrawSurface3_AddAttachedSurface,
1136 IDirectDrawSurface3_AddOverlayDirtyRect,
1137 IDirectDrawSurface3_Blt,
1138 IDirectDrawSurface3_BltBatch,
1139 IDirectDrawSurface3_BltFast,
1140 IDirectDrawSurface3_DeleteAttachedSurface,
1141 IDirectDrawSurface3_EnumAttachedSurfaces,
1142 IDirectDrawSurface3_EnumOverlayZOrders,
1143 DGA_IDirectDrawSurface3_Flip,
1144 IDirectDrawSurface3_GetAttachedSurface,
1145 IDirectDrawSurface3_GetBltStatus,
1146 IDirectDrawSurface3_GetCaps,
1147 IDirectDrawSurface3_GetClipper,
1148 IDirectDrawSurface3_GetColorKey,
1149 IDirectDrawSurface3_GetDC,
1150 IDirectDrawSurface3_GetFlipStatus,
1151 IDirectDrawSurface3_GetOverlayPosition,
1152 IDirectDrawSurface3_GetPalette,
1153 IDirectDrawSurface3_GetPixelFormat,
1154 IDirectDrawSurface3_GetSurfaceDesc,
1155 IDirectDrawSurface3_Initialize,
1156 IDirectDrawSurface3_IsLost,
1157 IDirectDrawSurface3_Lock,
1158 IDirectDrawSurface3_ReleaseDC,
1159 IDirectDrawSurface3_Restore,
1160 IDirectDrawSurface3_SetClipper,
1161 IDirectDrawSurface3_SetColorKey,
1162 IDirectDrawSurface3_SetOverlayPosition,
1163 DGA_IDirectDrawSurface3_SetPalette,
1164 DGA_IDirectDrawSurface3_Unlock,
1165 IDirectDrawSurface3_UpdateOverlay,
1166 IDirectDrawSurface3_UpdateOverlayDisplay,
1167 IDirectDrawSurface3_UpdateOverlayZOrder,
1168 IDirectDrawSurface3_GetDDInterface,
1169 IDirectDrawSurface3_PageLock,
1170 IDirectDrawSurface3_PageUnlock,
1171 IDirectDrawSurface3_SetSurfaceDesc,
1174 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1175 IDirectDrawSurface3_QueryInterface,
1176 IDirectDrawSurface3_AddRef,
1177 Xlib_IDirectDrawSurface3_Release,
1178 IDirectDrawSurface3_AddAttachedSurface,
1179 IDirectDrawSurface3_AddOverlayDirtyRect,
1180 IDirectDrawSurface3_Blt,
1181 IDirectDrawSurface3_BltBatch,
1182 IDirectDrawSurface3_BltFast,
1183 IDirectDrawSurface3_DeleteAttachedSurface,
1184 IDirectDrawSurface3_EnumAttachedSurfaces,
1185 IDirectDrawSurface3_EnumOverlayZOrders,
1186 Xlib_IDirectDrawSurface3_Flip,
1187 IDirectDrawSurface3_GetAttachedSurface,
1188 IDirectDrawSurface3_GetBltStatus,
1189 IDirectDrawSurface3_GetCaps,
1190 IDirectDrawSurface3_GetClipper,
1191 IDirectDrawSurface3_GetColorKey,
1192 IDirectDrawSurface3_GetDC,
1193 IDirectDrawSurface3_GetFlipStatus,
1194 IDirectDrawSurface3_GetOverlayPosition,
1195 IDirectDrawSurface3_GetPalette,
1196 IDirectDrawSurface3_GetPixelFormat,
1197 IDirectDrawSurface3_GetSurfaceDesc,
1198 IDirectDrawSurface3_Initialize,
1199 IDirectDrawSurface3_IsLost,
1200 IDirectDrawSurface3_Lock,
1201 IDirectDrawSurface3_ReleaseDC,
1202 IDirectDrawSurface3_Restore,
1203 IDirectDrawSurface3_SetClipper,
1204 IDirectDrawSurface3_SetColorKey,
1205 IDirectDrawSurface3_SetOverlayPosition,
1206 Xlib_IDirectDrawSurface3_SetPalette,
1207 Xlib_IDirectDrawSurface3_Unlock,
1208 IDirectDrawSurface3_UpdateOverlay,
1209 IDirectDrawSurface3_UpdateOverlayDisplay,
1210 IDirectDrawSurface3_UpdateOverlayZOrder,
1211 IDirectDrawSurface3_GetDDInterface,
1212 IDirectDrawSurface3_PageLock,
1213 IDirectDrawSurface3_PageUnlock,
1214 IDirectDrawSurface3_SetSurfaceDesc,
1217 /******************************************************************************
1218 * DirectDrawCreateClipper (DDRAW.7)
1220 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1221 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1222 LPUNKNOWN pUnkOuter)
1224 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1226 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1227 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1228 (*lplpDDClipper)->ref = 1;
1230 return 0;
1233 /******************************************************************************
1234 * IDirectDrawClipper
1236 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1237 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1239 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1240 return 0;
1243 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1244 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1246 this->ref--;
1247 if (this->ref)
1248 return this->ref;
1249 HeapFree(GetProcessHeap(),0,this);
1250 return 0;
1253 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1254 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1256 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1257 if (hmm) *hmm=0;
1258 return 0;
1261 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1262 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1264 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1265 return 0;
1268 static struct IDirectDrawClipper_VTable ddclipvt = {
1269 (void*)1,
1270 (void*)2,
1271 IDirectDrawClipper_Release,
1272 IDirectDrawClipper_GetClipList,
1273 (void*)5,
1274 (void*)6,
1275 (void*)7,
1276 IDirectDrawClipper_SetClipList,
1277 IDirectDrawClipper_SetHwnd
1280 /******************************************************************************
1281 * IDirectDrawPalette
1283 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1284 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1286 int i;
1288 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1289 this,x,start,count,palent);
1291 if (!this->cm) /* should not happen */ {
1292 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1293 return DDERR_GENERIC;
1295 for (i=0;i<count;i++) {
1296 palent[i].peRed = this->palents[start+i].peRed;
1297 palent[i].peBlue = this->palents[start+i].peBlue;
1298 palent[i].peGreen = this->palents[start+i].peGreen;
1299 palent[i].peFlags = this->palents[start+i].peFlags;
1302 return 0;
1305 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1306 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1308 XColor xc;
1309 int i;
1311 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1312 this,x,start,count,palent
1314 for (i=0;i<count;i++) {
1315 xc.red = palent[i].peRed<<8;
1316 xc.blue = palent[i].peBlue<<8;
1317 xc.green = palent[i].peGreen<<8;
1318 xc.flags = DoRed|DoBlue|DoGreen;
1319 xc.pixel = start+i;
1321 if (this->cm)
1322 TSXStoreColor(display,this->cm,&xc);
1324 this->palents[start+i].peRed = palent[i].peRed;
1325 this->palents[start+i].peBlue = palent[i].peBlue;
1326 this->palents[start+i].peGreen = palent[i].peGreen;
1327 this->palents[start+i].peFlags = palent[i].peFlags;
1329 if (!this->cm) /* should not happen */ {
1331 return 0;
1334 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1335 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1337 #ifdef HAVE_LIBXXF86DGA
1338 XColor xc;
1339 Colormap cm;
1340 int i;
1342 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1343 this,x,start,count,palent
1345 if (!this->cm) /* should not happen */ {
1346 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1347 return DDERR_GENERIC;
1349 /* FIXME: free colorcells instead of freeing whole map */
1350 cm = this->cm;
1351 this->cm = TSXCopyColormapAndFree(display,this->cm);
1352 TSXFreeColormap(display,cm);
1354 for (i=0;i<count;i++) {
1355 xc.red = palent[i].peRed<<8;
1356 xc.blue = palent[i].peBlue<<8;
1357 xc.green = palent[i].peGreen<<8;
1358 xc.flags = DoRed|DoBlue|DoGreen;
1359 xc.pixel = i+start;
1361 TSXStoreColor(display,this->cm,&xc);
1363 this->palents[start+i].peRed = palent[i].peRed;
1364 this->palents[start+i].peBlue = palent[i].peBlue;
1365 this->palents[start+i].peGreen = palent[i].peGreen;
1366 this->palents[start+i].peFlags = palent[i].peFlags;
1368 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1369 return 0;
1370 #else /* defined(HAVE_LIBXXF86DGA) */
1371 return E_UNEXPECTED;
1372 #endif /* defined(HAVE_LIBXXF86DGA) */
1375 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1376 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1377 if (!--(this->ref)) {
1378 if (this->cm) {
1379 TSXFreeColormap(display,this->cm);
1380 this->cm = 0;
1382 HeapFree(GetProcessHeap(),0,this);
1383 return 0;
1385 return this->ref;
1388 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1390 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1391 return ++(this->ref);
1394 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1395 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1397 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1399 return DDERR_ALREADYINITIALIZED;
1402 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1403 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1405 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1406 return DD_OK;
1409 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1410 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1412 char xrefiid[50];
1414 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1415 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1417 return S_OK;
1420 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1421 IDirectDrawPalette_QueryInterface,
1422 IDirectDrawPalette_AddRef,
1423 IDirectDrawPalette_Release,
1424 IDirectDrawPalette_GetCaps,
1425 IDirectDrawPalette_GetEntries,
1426 IDirectDrawPalette_Initialize,
1427 DGA_IDirectDrawPalette_SetEntries
1430 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1431 IDirectDrawPalette_QueryInterface,
1432 IDirectDrawPalette_AddRef,
1433 IDirectDrawPalette_Release,
1434 IDirectDrawPalette_GetCaps,
1435 IDirectDrawPalette_GetEntries,
1436 IDirectDrawPalette_Initialize,
1437 Xlib_IDirectDrawPalette_SetEntries
1440 /*******************************************************************************
1441 * IDirect3D
1443 static HRESULT WINAPI IDirect3D_QueryInterface(
1444 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1446 /* FIXME: Not sure if this is correct */
1447 char xrefiid[50];
1449 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1450 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1451 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1452 *obj = this;
1453 this->lpvtbl->fnAddRef(this);
1454 return 0;
1456 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1457 LPDIRECT3D d3d;
1459 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1460 d3d->ref = 1;
1461 d3d->ddraw = (LPDIRECTDRAW)this;
1462 this->lpvtbl->fnAddRef(this);
1463 d3d->lpvtbl = &d3dvt;
1464 *obj = d3d;
1465 return 0;
1467 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1468 LPDIRECT3D2 d3d;
1470 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1471 d3d->ref = 1;
1472 d3d->ddraw = (LPDIRECTDRAW)this;
1473 this->lpvtbl->fnAddRef(this);
1474 d3d->lpvtbl = &d3d2vt;
1475 *obj = d3d;
1476 return 0;
1478 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1479 return OLE_E_ENUM_NOMORE;
1482 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1483 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1485 return ++(this->ref);
1488 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1490 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1492 if (!--(this->ref)) {
1493 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1494 HeapFree(GetProcessHeap(),0,this);
1495 return 0;
1497 return this->ref;
1500 static HRESULT WINAPI IDirect3D_Initialize(
1501 LPDIRECT3D this, REFIID refiid )
1503 /* FIXME: Not sure if this is correct */
1504 char xrefiid[50];
1506 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1507 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1509 return DDERR_ALREADYINITIALIZED;
1512 /*******************************************************************************
1513 * IDirect3D
1515 static struct IDirect3D_VTable d3dvt = {
1516 (void*)IDirect3D_QueryInterface,
1517 (void*)IDirect3D_AddRef,
1518 (void*)IDirect3D_Release,
1519 IDirect3D_Initialize,
1520 (void*)5,
1521 (void*)6,
1522 (void*)7,
1523 (void*)8,
1524 (void*)9,
1527 /*******************************************************************************
1528 * IDirect3D2
1530 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1531 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1533 if (!--(this->ref)) {
1534 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1535 HeapFree(GetProcessHeap(),0,this);
1536 return 0;
1538 return this->ref;
1541 static HRESULT WINAPI IDirect3D2_EnumDevices(
1542 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1544 D3DDEVICEDESC d1,d2;
1546 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1547 #if 0
1548 d1.dwSize = sizeof(d1);
1549 d1.dwFlags = 0;
1551 d2.dwSize = sizeof(d2);
1552 d2.dwFlags = 0;
1553 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1554 #endif
1555 return 0;
1558 static struct IDirect3D2_VTable d3d2vt = {
1559 (void*)1,
1560 (void*)2,
1561 IDirect3D2_Release,
1562 IDirect3D2_EnumDevices,
1563 (void*)5,
1564 (void*)6,
1565 (void*)7,
1566 (void*)8,
1567 (void*)9,
1570 /*******************************************************************************
1571 * IDirectDraw
1574 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1575 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1577 static INT32 ddrawXlibThisOffset = 0;
1579 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
1580 LPDDSURFACEDESC lpddsd,
1581 LPDIRECTDRAWSURFACE lpdsf)
1583 int bpp;
1585 /* The surface was already allocated when entering in this function */
1586 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
1587 /* No pixel format => use DirectDraw's format */
1588 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
1589 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
1590 } else {
1591 /* To check what the program wants */
1592 if (TRACE_ON(ddraw)) {
1593 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
1597 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
1599 /* Copy the surface description */
1600 lpdsf->s.surface_desc = *lpddsd;
1602 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1603 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
1604 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
1606 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
1608 return 0;
1611 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1612 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1614 #ifdef HAVE_LIBXXF86DGA
1615 int i;
1617 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1618 if (TRACE_ON(ddraw)) {
1619 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1620 _dump_DDSD(lpddsd->dwFlags);
1621 fprintf(stderr,"caps ");
1622 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1623 fprintf(stderr,"]\n");
1626 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1627 this->lpvtbl->fnAddRef(this);
1628 (*lpdsf)->ref = 1;
1629 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1630 (*lpdsf)->s.ddraw = this;
1631 (*lpdsf)->s.palette = NULL;
1632 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
1634 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1635 lpddsd->dwWidth = this->d.width;
1636 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1637 lpddsd->dwHeight = this->d.height;
1639 /* Check if this a 'primary surface' or not */
1640 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1641 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1643 /* This is THE primary surface => there is DGA-specific code */
1644 /* First, store the surface description */
1645 (*lpdsf)->s.surface_desc = *lpddsd;
1647 /* Find a viewport */
1648 for (i=0;i<32;i++)
1649 if (!(this->e.dga.vpmask & (1<<i)))
1650 break;
1651 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1652 /* if i == 32 or maximum ... return error */
1653 this->e.dga.vpmask|=(1<<i);
1654 (*lpdsf)->s.surface_desc.y.lpSurface =
1655 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1656 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1657 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
1658 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
1660 /* Add flags if there were not present */
1661 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1662 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1663 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1664 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1665 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1666 (*lpdsf)->s.backbuffer = NULL;
1668 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1669 LPDIRECTDRAWSURFACE3 back;
1671 if (lpddsd->dwBackBufferCount>1)
1672 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1674 (*lpdsf)->s.backbuffer = back =
1675 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1676 this->lpvtbl->fnAddRef(this);
1677 back->ref = 1;
1678 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1679 for (i=0;i<32;i++)
1680 if (!(this->e.dga.vpmask & (1<<i)))
1681 break;
1682 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1683 /* if i == 32 or maximum ... return error */
1684 this->e.dga.vpmask|=(1<<i);
1685 back->t.dga.fb_height = i*this->e.dga.fb_height;
1687 /* Copy the surface description from the front buffer */
1688 back->s.surface_desc = (*lpdsf)->s.surface_desc;
1689 /* Change the parameters that are not the same */
1690 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
1691 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1692 back->s.ddraw = this;
1693 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1694 * one! */
1696 /* Add relevant info to front and back buffers */
1697 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1698 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
1699 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1700 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
1702 } else {
1703 /* There is no DGA-specific code here...
1704 Go to the common surface creation function */
1705 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
1708 return 0;
1709 #else /* defined(HAVE_LIBXXF86DGA) */
1710 return E_UNEXPECTED;
1711 #endif /* defined(HAVE_LIBXXF86DGA) */
1714 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
1715 XImage *img;
1717 #ifdef HAVE_LIBXXSHM
1718 if (this->e.xlib.xshm_active) {
1719 img = TSXShmCreateImage(display,
1720 DefaultVisualOfScreen(screen),
1721 this->d.depth,
1722 ZPixmap,
1723 NULL,
1724 &(lpdsf->t.xlib.shminfo),
1725 lpdsf->s.surface_desc.dwWidth,
1726 lpdsf->s.surface_desc.dwHeight);
1728 if (img == NULL)
1729 return NULL;
1731 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
1732 if (lpdsf->t.xlib.shminfo.shmid < 0) {
1733 TSXDestroyImage(img);
1734 return NULL;
1737 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
1739 if (img->data == (char *) -1) {
1740 TSXDestroyImage(img);
1741 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1742 return NULL;
1744 lpdsf->t.xlib.shminfo.readOnly = False;
1746 TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
1747 TSXSync(display, False);
1749 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1751 lpdsf->s.surface_desc.y.lpSurface = img->data;
1752 } else {
1753 #endif
1754 /* Allocate surface memory */
1755 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1756 lpdsf->s.surface_desc.dwWidth *
1757 lpdsf->s.surface_desc.dwHeight *
1758 (this->d.depth / 8));
1760 /* In this case, create an XImage */
1761 img =
1762 TSXCreateImage(display,
1763 DefaultVisualOfScreen(screen),
1764 this->d.depth,
1765 ZPixmap,
1767 lpdsf->s.surface_desc.y.lpSurface,
1768 lpdsf->s.surface_desc.dwWidth,
1769 lpdsf->s.surface_desc.dwHeight,
1771 lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8)
1774 #ifdef HAVE_LIBXXSHM
1776 #endif
1777 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
1779 return img;
1782 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1783 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1785 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1786 this,lpddsd,lpdsf,lpunk);
1788 if (TRACE_ON(ddraw)) {
1789 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1790 _dump_DDSD(lpddsd->dwFlags);
1791 fprintf(stderr,"caps ");
1792 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1793 fprintf(stderr,"]\n");
1796 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1798 this->lpvtbl->fnAddRef(this);
1799 (*lpdsf)->s.ddraw = this;
1800 (*lpdsf)->ref = 1;
1801 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1802 (*lpdsf)->s.palette = NULL;
1803 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
1805 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1806 lpddsd->dwWidth = this->d.width;
1807 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1808 lpddsd->dwHeight = this->d.height;
1810 /* Check if this a 'primary surface' or not */
1811 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1812 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1813 XImage *img;
1815 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
1817 /* First, store the surface description */
1818 (*lpdsf)->s.surface_desc = *lpddsd;
1820 /* Create the XImage */
1821 img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
1822 if (img == NULL)
1823 return DDERR_OUTOFMEMORY;
1824 (*lpdsf)->t.xlib.image = img;
1826 /* Add flags if there were not present */
1827 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1828 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1829 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1830 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1831 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1832 (*lpdsf)->s.backbuffer = NULL;
1834 /* Check for backbuffers */
1835 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1836 LPDIRECTDRAWSURFACE3 back;
1837 XImage *img;
1839 if (lpddsd->dwBackBufferCount>1)
1840 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1842 (*lpdsf)->s.backbuffer = back =
1843 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1845 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
1847 this->lpvtbl->fnAddRef(this);
1848 back->s.ddraw = this;
1850 back->ref = 1;
1851 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
1852 /* Copy the surface description from the front buffer */
1853 back->s.surface_desc = (*lpdsf)->s.surface_desc;
1855 /* Create the XImage */
1856 img = create_ximage(this, back);
1857 if (img == NULL)
1858 return DDERR_OUTOFMEMORY;
1859 back->t.xlib.image = img;
1861 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1862 * one! */
1864 /* Add relevant info to front and back buffers */
1865 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1866 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
1867 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1868 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
1870 } else {
1871 /* There is no Xlib-specific code here...
1872 Go to the common surface creation function */
1873 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
1876 return 0;
1879 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
1880 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1882 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1883 *dst = src; /* FIXME */
1884 return 0;
1888 * The Xlib Implementation tries to use the passed hwnd as drawing window,
1889 * even when the approbiate bitmasks are not specified.
1891 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1892 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
1894 int i;
1895 const struct {
1896 int mask;
1897 char *name;
1898 } flagmap[] = {
1899 FE(DDSCL_FULLSCREEN)
1900 FE(DDSCL_ALLOWREBOOT)
1901 FE(DDSCL_NOWINDOWCHANGES)
1902 FE(DDSCL_NORMAL)
1903 FE(DDSCL_ALLOWMODEX)
1904 FE(DDSCL_EXCLUSIVE)
1905 FE(DDSCL_SETFOCUSWINDOW)
1906 FE(DDSCL_SETDEVICEWINDOW)
1907 FE(DDSCL_CREATEDEVICEWINDOW)
1910 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
1911 if(TRACE_ON(ddraw)){
1912 dbg_decl_str(ddraw, 512);
1913 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1914 if (flagmap[i].mask & cooplevel)
1915 dsprintf(ddraw, "%s ", flagmap[i].name);
1916 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1918 this->d.mainWindow = hwnd;
1919 return 0;
1922 /* Small helper to either use the cooperative window or create a new
1923 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
1925 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
1926 RECT32 rect;
1928 /* Do not destroy the application supplied cooperative window */
1929 if (this->d.window && this->d.window != this->d.mainWindow) {
1930 DestroyWindow32(this->d.window);
1931 this->d.window = 0;
1933 /* Sanity check cooperative window before assigning it to drawing. */
1934 if ( IsWindow32(this->d.mainWindow) &&
1935 IsWindowVisible32(this->d.mainWindow)
1937 GetWindowRect32(this->d.mainWindow,&rect);
1938 if (((rect.right-rect.left) >= this->d.width) &&
1939 ((rect.bottom-rect.top) >= this->d.height)
1941 this->d.window = this->d.mainWindow;
1943 /* ... failed, create new one. */
1944 if (!this->d.window) {
1945 this->d.window = CreateWindowEx32A(
1947 "WINE_DirectDraw",
1948 "WINE_DirectDraw",
1949 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1950 0,0,
1951 this->d.width,
1952 this->d.height,
1956 NULL
1958 /*Store THIS with the window. We'll use it in the window procedure*/
1959 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
1960 ShowWindow32(this->d.window,TRUE);
1961 UpdateWindow32(this->d.window);
1963 SetFocus32(this->d.window);
1966 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
1967 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1969 #ifdef HAVE_LIBXXF86DGA
1970 int i,*depths,depcount,mode_count;
1972 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
1974 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1975 for (i=0;i<depcount;i++)
1976 if (depths[i]==depth)
1977 break;
1978 TSXFree(depths);
1979 if (i==depcount) {/* not found */
1980 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1981 return DDERR_UNSUPPORTEDMODE;
1983 if (this->d.width < width) {
1984 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
1985 return DDERR_UNSUPPORTEDMODE;
1987 this->d.width = width;
1988 this->d.height = height;
1989 this->d.depth = depth;
1991 /* adjust fb_height, so we don't overlap */
1992 if (this->e.dga.fb_height < height)
1993 this->e.dga.fb_height = height;
1994 _common_IDirectDraw_SetDisplayMode(this);
1996 #ifdef HAVE_LIBXXF86VM
1998 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
1999 /* set fullscreen mode */
2000 /* do we need to save the old video mode and restore it when we exit? */
2002 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2003 for (i=0;i<mode_count;i++)
2005 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2007 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2008 *vidmode = *(all_modes[i]);
2009 break;
2010 } else
2011 TSXFree(all_modes[i]->private);
2013 TSXFree(all_modes);
2015 if (!vidmode)
2016 WARN(ddraw, "Fullscreen mode not available!\n");
2018 if (vidmode)
2019 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2021 #endif
2023 /* FIXME: this function OVERWRITES several signal handlers.
2024 * can we save them? and restore them later? In a way that
2025 * it works for the library too?
2027 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2028 #ifdef DIABLO_HACK
2029 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2030 #endif
2032 #ifdef RESTORE_SIGNALS
2033 SIGNAL_InitEmulator();
2034 #endif
2035 return 0;
2036 #else /* defined(HAVE_LIBXXF86DGA) */
2037 return E_UNEXPECTED;
2038 #endif /* defined(HAVE_LIBXXF86DGA) */
2041 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2042 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2044 int i,*depths,depcount;
2045 char buf[200];
2047 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2048 this, width, height, depth);
2050 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2051 for (i=0;i<depcount;i++)
2052 if (depths[i]==depth)
2053 break;
2054 TSXFree(depths);
2055 if (i==depcount) {/* not found */
2056 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2057 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2058 return DDERR_UNSUPPORTEDMODE;
2060 this->d.width = width;
2061 this->d.height = height;
2062 this->d.depth = depth;
2064 _common_IDirectDraw_SetDisplayMode(this);
2066 this->e.xlib.paintable = 1;
2067 this->e.xlib.drawable = WIN_FindWndPtr(this->d.window)->window;
2068 /* We don't have a context for this window. Host off the desktop */
2069 if( !this->e.xlib.drawable )
2070 this->e.xlib.drawable = WIN_GetDesktop()->window;
2071 return 0;
2074 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2075 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2077 #ifdef HAVE_LIBXXF86DGA
2078 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2079 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2080 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2081 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2082 if (caps2) {
2083 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2084 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2085 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2087 return 0;
2088 #else /* defined(HAVE_LIBXXF86DGA) */
2089 return E_UNEXPECTED;
2090 #endif /* defined(HAVE_LIBXXF86DGA) */
2093 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2094 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2096 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2097 /* FIXME: Xlib */
2098 caps1->dwVidMemTotal = 2048*1024;
2099 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2100 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2101 if (caps2) {
2102 caps2->dwVidMemTotal = 2048*1024;
2103 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2104 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2106 /* END FIXME: Xlib */
2107 return 0;
2110 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2111 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2113 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2114 this,x,lpddclip,lpunk
2116 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2117 (*lpddclip)->ref = 1;
2118 (*lpddclip)->lpvtbl = &ddclipvt;
2119 return 0;
2122 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2123 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2125 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2126 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2127 (*lpddpal)->ref = 1;
2128 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2129 (*lpddpal)->installed = 0;
2130 if (this->d.depth<=8) {
2131 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
2132 } else {
2133 /* we don't want palettes in hicolor or truecolor */
2134 (*lpddpal)->cm = 0;
2136 return 0;
2139 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2140 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2142 HRESULT res;
2143 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2144 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
2145 if (res != 0) return res;
2146 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2147 return 0;
2150 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2151 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2153 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2154 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2155 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2156 (*lpddpal)->ref = 1;
2157 (*lpddpal)->installed = 0;
2158 if (palent)
2159 FIXME(ddraw,"needs to handle palent (%p)\n",palent);
2161 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2162 this->lpvtbl->fnAddRef(this);
2163 (*lpddpal)->cm = 0;
2165 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2166 return 0;
2169 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2170 #ifdef HAVE_LIBXXF86DGA
2171 TRACE(ddraw, "(%p)->()\n",this);
2172 Sleep(1000);
2173 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2174 #ifdef RESTORE_SIGNALS
2175 SIGNAL_InitEmulator();
2176 #endif
2177 return 0;
2178 #else /* defined(HAVE_LIBXXF86DGA) */
2179 return E_UNEXPECTED;
2180 #endif
2183 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2184 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
2185 Sleep(1000);
2186 return 0;
2189 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
2190 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
2192 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
2193 return 0;
2196 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
2197 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2199 return ++(this->ref);
2202 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2203 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2205 #ifdef HAVE_LIBXXF86DGA
2206 if (!--(this->ref)) {
2207 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2208 #ifdef RESTORE_SIGNALS
2209 SIGNAL_InitEmulator();
2210 #endif
2211 HeapFree(GetProcessHeap(),0,this);
2212 return 0;
2214 #endif /* defined(HAVE_LIBXXF86DGA) */
2215 return this->ref;
2218 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2219 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2221 if (!--(this->ref)) {
2222 HeapFree(GetProcessHeap(),0,this);
2223 return 0;
2225 /* FIXME: destroy window ... */
2226 return this->ref;
2229 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
2230 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2232 char xrefiid[50];
2234 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2235 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2236 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2237 *obj = this;
2238 this->lpvtbl->fnAddRef(this);
2239 return 0;
2241 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2242 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
2243 this->lpvtbl->fnAddRef(this);
2244 *obj = this;
2245 return 0;
2247 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2248 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
2249 this->lpvtbl->fnAddRef(this);
2250 *obj = this;
2251 return 0;
2253 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2254 LPDIRECT3D d3d;
2256 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2257 d3d->ref = 1;
2258 d3d->ddraw = (LPDIRECTDRAW)this;
2259 this->lpvtbl->fnAddRef(this);
2260 d3d->lpvtbl = &d3dvt;
2261 *obj = d3d;
2262 return 0;
2264 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2265 LPDIRECT3D2 d3d;
2267 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2268 d3d->ref = 1;
2269 d3d->ddraw = (LPDIRECTDRAW)this;
2270 this->lpvtbl->fnAddRef(this);
2271 d3d->lpvtbl = &d3d2vt;
2272 *obj = d3d;
2273 return 0;
2275 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2276 return OLE_E_ENUM_NOMORE;
2279 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
2280 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2282 char xrefiid[50];
2284 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2285 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2286 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2287 *obj = this;
2288 this->lpvtbl->fnAddRef(this);
2289 return 0;
2291 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2292 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2293 this->lpvtbl->fnAddRef(this);
2294 *obj = this;
2295 return 0;
2297 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2298 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2299 this->lpvtbl->fnAddRef(this);
2300 *obj = this;
2301 return 0;
2303 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2304 LPDIRECT3D d3d;
2306 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2307 d3d->ref = 1;
2308 d3d->ddraw = (LPDIRECTDRAW)this;
2309 this->lpvtbl->fnAddRef(this);
2310 d3d->lpvtbl = &d3dvt;
2311 *obj = d3d;
2312 return 0;
2314 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2315 LPDIRECT3D2 d3d;
2317 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2318 d3d->ref = 1;
2319 d3d->ddraw = (LPDIRECTDRAW)this;
2320 this->lpvtbl->fnAddRef(this);
2321 d3d->lpvtbl = &d3d2vt;
2322 *obj = d3d;
2323 return 0;
2325 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2326 return OLE_E_ENUM_NOMORE;
2329 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2330 LPDIRECTDRAW2 this,BOOL32 *status
2332 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2333 *status = TRUE;
2334 return 0;
2337 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2338 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2340 DDSURFACEDESC ddsfd;
2341 static struct {
2342 int w,h;
2343 } modes[5] = { /* some of the usual modes */
2344 {512,384},
2345 {640,400},
2346 {640,480},
2347 {800,600},
2348 {1024,768},
2350 static int depths[4] = {8,16,24,32};
2351 int i,j;
2353 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2354 ddsfd.dwSize = sizeof(ddsfd);
2355 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2356 if (dwFlags & DDEDM_REFRESHRATES) {
2357 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2358 ddsfd.x.dwRefreshRate = 60;
2361 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2362 ddsfd.dwBackBufferCount = 1;
2363 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2364 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2365 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2366 /* FIXME: those masks would have to be set in depth > 8 */
2367 if (depths[i]==8) {
2368 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2369 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2370 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2371 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2372 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2373 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2374 } else {
2375 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2377 /* FIXME: We should query those from X itself */
2378 switch (depths[i]) {
2379 case 16:
2380 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2381 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2382 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2383 break;
2384 case 24:
2385 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2386 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2387 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2388 break;
2389 case 32:
2390 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2391 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2392 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2393 break;
2397 ddsfd.dwWidth = screenWidth;
2398 ddsfd.dwHeight = screenHeight;
2399 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2400 if (!modescb(&ddsfd,context)) return 0;
2402 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2403 ddsfd.dwWidth = modes[j].w;
2404 ddsfd.dwHeight = modes[j].h;
2405 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2406 if (!modescb(&ddsfd,context)) return 0;
2409 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2410 /* modeX is not standard VGA */
2412 ddsfd.dwHeight = 200;
2413 ddsfd.dwWidth = 320;
2414 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2415 if (!modescb(&ddsfd,context)) return 0;
2418 return DD_OK;
2421 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2422 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2424 #ifdef HAVE_LIBXXF86DGA
2425 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2426 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2427 lpddsfd->dwHeight = screenHeight;
2428 lpddsfd->dwWidth = screenWidth;
2429 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2430 lpddsfd->dwBackBufferCount = 1;
2431 lpddsfd->x.dwRefreshRate = 60;
2432 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2433 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2434 return DD_OK;
2435 #else /* defined(HAVE_LIBXXF86DGA) */
2436 return E_UNEXPECTED;
2437 #endif /* defined(HAVE_LIBXXF86DGA) */
2440 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2441 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2443 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2444 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2445 lpddsfd->dwHeight = screenHeight;
2446 lpddsfd->dwWidth = screenWidth;
2447 /* POOLE FIXME: Xlib */
2448 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2449 /* END FIXME: Xlib */
2450 lpddsfd->dwBackBufferCount = 1;
2451 lpddsfd->x.dwRefreshRate = 60;
2452 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2453 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2454 return DD_OK;
2457 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2458 TRACE(ddraw,"(%p)->()\n",this);
2459 return DD_OK;
2462 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2463 LPDIRECTDRAW2 this,LPDWORD freq
2465 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2466 *freq = 60*100; /* 60 Hz */
2467 return 0;
2470 /* what can we directly decompress? */
2471 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2472 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2474 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2475 return 0;
2478 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2479 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2481 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2482 return 0;
2485 static HRESULT WINAPI IDirectDraw2_Compact(
2486 LPDIRECTDRAW2 this )
2488 FIXME(ddraw,"(%p)->()\n", this );
2490 return DD_OK;
2494 /* Note: Hack so we can reuse the old functions without compiler warnings */
2495 #ifdef __GNUC__
2496 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2497 #else
2498 # define XCAST(fun) (void*)
2499 #endif
2501 static struct IDirectDraw_VTable dga_ddvt = {
2502 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2503 XCAST(AddRef)IDirectDraw2_AddRef,
2504 XCAST(Release)DGA_IDirectDraw2_Release,
2505 XCAST(Compact)IDirectDraw2_Compact,
2506 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2507 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2508 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2509 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2510 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2511 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2512 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2513 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2514 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2515 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2516 XCAST(GetGDISurface)15,
2517 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2518 XCAST(GetScanLine)17,
2519 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2520 XCAST(Initialize)19,
2521 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2522 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2523 DGA_IDirectDraw_SetDisplayMode,
2524 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2527 static struct IDirectDraw_VTable xlib_ddvt = {
2528 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2529 XCAST(AddRef)IDirectDraw2_AddRef,
2530 XCAST(Release)Xlib_IDirectDraw2_Release,
2531 XCAST(Compact)IDirectDraw2_Compact,
2532 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2533 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2534 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2535 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2536 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2537 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2538 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2539 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2540 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2541 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2542 XCAST(GetGDISurface)15,
2543 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2544 XCAST(GetScanLine)17,
2545 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2546 XCAST(Initialize)19,
2547 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2548 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2549 Xlib_IDirectDraw_SetDisplayMode,
2550 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2553 /*****************************************************************************
2554 * IDirectDraw2
2559 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2560 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2562 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2565 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2566 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2568 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2571 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2572 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2574 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2575 this,ddscaps,total,free
2577 if (total) *total = this->e.dga.fb_memsize * 1024;
2578 if (free) *free = this->e.dga.fb_memsize * 1024;
2579 return 0;
2582 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2583 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2585 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2586 this,ddscaps,total,free
2588 if (total) *total = 2048 * 1024;
2589 if (free) *free = 2048 * 1024;
2590 return 0;
2593 static IDirectDraw2_VTable dga_dd2vt = {
2594 DGA_IDirectDraw2_QueryInterface,
2595 IDirectDraw2_AddRef,
2596 DGA_IDirectDraw2_Release,
2597 IDirectDraw2_Compact,
2598 IDirectDraw2_CreateClipper,
2599 DGA_IDirectDraw2_CreatePalette,
2600 DGA_IDirectDraw2_CreateSurface,
2601 (void*)8,
2602 IDirectDraw2_EnumDisplayModes,
2603 IDirectDraw2_EnumSurfaces,
2604 IDirectDraw2_FlipToGDISurface,
2605 DGA_IDirectDraw2_GetCaps,
2606 DGA_IDirectDraw2_GetDisplayMode,
2607 IDirectDraw2_GetFourCCCodes,
2608 (void*)15,
2609 IDirectDraw2_GetMonitorFrequency,
2610 (void*)17,
2611 IDirectDraw2_GetVerticalBlankStatus,
2612 (void*)19,
2613 DGA_IDirectDraw2_RestoreDisplayMode,
2614 IDirectDraw2_SetCooperativeLevel,
2615 DGA_IDirectDraw2_SetDisplayMode,
2616 IDirectDraw2_WaitForVerticalBlank,
2617 DGA_IDirectDraw2_GetAvailableVidMem
2620 static struct IDirectDraw2_VTable xlib_dd2vt = {
2621 Xlib_IDirectDraw2_QueryInterface,
2622 IDirectDraw2_AddRef,
2623 Xlib_IDirectDraw2_Release,
2624 IDirectDraw2_Compact,
2625 IDirectDraw2_CreateClipper,
2626 Xlib_IDirectDraw2_CreatePalette,
2627 Xlib_IDirectDraw2_CreateSurface,
2628 (void*)8,
2629 IDirectDraw2_EnumDisplayModes,
2630 IDirectDraw2_EnumSurfaces,
2631 IDirectDraw2_FlipToGDISurface,
2632 Xlib_IDirectDraw2_GetCaps,
2633 Xlib_IDirectDraw2_GetDisplayMode,
2634 IDirectDraw2_GetFourCCCodes,
2635 (void*)15,
2636 IDirectDraw2_GetMonitorFrequency,
2637 (void*)17,
2638 IDirectDraw2_GetVerticalBlankStatus,
2639 (void*)19,
2640 Xlib_IDirectDraw2_RestoreDisplayMode,
2641 IDirectDraw2_SetCooperativeLevel,
2642 Xlib_IDirectDraw2_SetDisplayMode,
2643 IDirectDraw2_WaitForVerticalBlank,
2644 Xlib_IDirectDraw2_GetAvailableVidMem
2647 /******************************************************************************
2648 * DirectDrawCreate
2651 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2653 LRESULT ret;
2654 LPDIRECTDRAW ddraw = NULL;
2655 DWORD lastError;
2657 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2659 SetLastError( ERROR_SUCCESS );
2660 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2661 if( (!ddraw) &&
2662 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2665 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2668 if( ddraw )
2670 /* Perform any special direct draw functions */
2671 if (msg==WM_PAINT)
2672 ddraw->e.xlib.paintable = 1;
2674 /* Now let the application deal with the rest of this */
2675 if( ddraw->d.mainWindow )
2678 /* Don't think that we actually need to call this but...
2679 might as well be on the safe side of things... */
2681 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
2682 it should be the procedures of our fake window that gets called
2683 instead of those of the window provided by the application.
2684 And with this patch, mouse clicks work with Monkey Island III
2685 - Lionel */
2686 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2688 if( !ret )
2690 /* We didn't handle the message - give it to the application */
2691 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
2692 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2693 ddraw->d.mainWindow, msg, wParam, lParam );
2697 } else {
2698 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
2702 else
2704 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2707 return ret;
2710 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2711 #ifdef HAVE_LIBXXF86DGA
2712 int memsize,banksize,width,major,minor,flags,height;
2713 char *addr;
2714 int fd;
2716 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
2717 if ((fd = open("/dev/mem", O_RDWR)) != -1)
2718 close(fd);
2720 if (fd == -1) {
2721 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
2722 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2723 return E_UNEXPECTED;
2725 if (!DDRAW_DGA_Available()) {
2726 TRACE(ddraw,"No XF86DGA detected.\n");
2727 return DDERR_GENERIC;
2729 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2730 (*lplpDD)->lpvtbl = &dga_ddvt;
2731 (*lplpDD)->ref = 1;
2732 TSXF86DGAQueryVersion(display,&major,&minor);
2733 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2734 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2735 if (!(flags & XF86DGADirectPresent))
2736 MSG("direct video is NOT PRESENT.\n");
2737 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2738 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2739 addr,width,banksize,memsize
2741 (*lplpDD)->e.dga.fb_width = width;
2742 (*lplpDD)->d.width = width;
2743 (*lplpDD)->e.dga.fb_addr = addr;
2744 (*lplpDD)->e.dga.fb_memsize = memsize;
2745 (*lplpDD)->e.dga.fb_banksize = banksize;
2747 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2748 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2749 (*lplpDD)->e.dga.fb_height = screenHeight;
2750 #ifdef DIABLO_HACK
2751 (*lplpDD)->e.dga.vpmask = 1;
2752 #else
2753 (*lplpDD)->e.dga.vpmask = 0;
2754 #endif
2756 /* just assume the default depth is the DGA depth too */
2757 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2758 #ifdef RESTORE_SIGNALS
2759 SIGNAL_InitEmulator();
2760 #endif
2762 return 0;
2763 #else /* defined(HAVE_LIBXXF86DGA) */
2764 return DDERR_INVALIDDIRECTDRAWGUID;
2765 #endif /* defined(HAVE_LIBXXF86DGA) */
2768 BOOL32
2769 DDRAW_XSHM_Available()
2771 #ifdef HAVE_LIBXXSHM
2772 if (TSXShmQueryExtension(display))
2774 int major, minor;
2775 Bool shpix;
2777 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
2778 return 1;
2779 else
2780 return 0;
2782 else
2783 return 0;
2784 #else
2785 return 0;
2786 #endif
2789 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2791 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2792 (*lplpDD)->lpvtbl = &xlib_ddvt;
2793 (*lplpDD)->ref = 1;
2794 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
2796 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2797 (*lplpDD)->d.height = screenHeight;
2798 (*lplpDD)->d.width = screenWidth;
2800 #ifdef HAVE_LIBXXSHM
2801 /* Test if XShm is available.
2802 As XShm is not ready yet for 'prime-time', it is disabled for now */
2803 if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
2804 TRACE(ddraw, "Using XShm extesion.\n");
2805 #endif
2807 return 0;
2810 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
2811 char xclsid[50];
2812 WNDCLASS32A wc;
2813 WND* pParentWindow;
2814 HRESULT ret;
2816 if (HIWORD(lpGUID))
2817 WINE_StringFromCLSID(lpGUID,xclsid);
2818 else {
2819 sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID);
2820 lpGUID = NULL;
2823 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
2825 if (!lpGUID) {
2826 /* if they didn't request a particular interface, use the best
2827 * supported one */
2828 if (DDRAW_DGA_Available())
2829 lpGUID = &DGA_DirectDraw_GUID;
2830 else
2831 lpGUID = &XLIB_DirectDraw_GUID;
2834 wc.style = CS_GLOBALCLASS;
2835 wc.lpfnWndProc = Xlib_DDWndProc;
2836 wc.cbClsExtra = 0;
2837 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
2838 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
2840 /* We can be a child of the desktop since we're really important */
2841 pParentWindow = WIN_GetDesktop();
2842 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
2843 wc.hInstance = 0;
2845 wc.hIcon = 0;
2846 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
2847 wc.hbrBackground= NULL_BRUSH;
2848 wc.lpszMenuName = 0;
2849 wc.lpszClassName= "WINE_DirectDraw";
2850 RegisterClass32A(&wc);
2852 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
2853 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
2854 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
2855 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
2856 else
2857 goto err;
2859 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
2860 return ret;
2862 err:
2863 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
2864 return DDERR_INVALIDDIRECTDRAWGUID;