IPaddress common control implementation. First try; needs more work to
[wine/multimedia.git] / graphics / ddraw.c
blobb3511fa37a456ea5293e938601990924466239dc
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 #ifdef HAVE_LIBXXF86VM
96 static XF86VidModeModeInfo *orig_mode = NULL;
97 #endif
99 BOOL32
100 DDRAW_DGA_Available()
102 #ifdef HAVE_LIBXXF86DGA
103 int evbase, evret, fd;
105 if (Options.noDGA)
106 return 0;
108 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
109 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
110 /* others. --stephenc */
111 if ((fd = open("/dev/mem", O_RDWR)) != -1)
112 close(fd);
114 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
115 #else /* defined(HAVE_LIBXXF86DGA) */
116 return 0;
117 #endif /* defined(HAVE_LIBXXF86DGA) */
120 HRESULT WINAPI
121 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
122 if (DDRAW_DGA_Available()) {
123 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
125 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
126 ddenumproc(NULL,"WINE","display",data);
127 return DD_OK;
130 /* What is this doing here? */
131 HRESULT WINAPI
132 DSoundHelp(DWORD x,DWORD y,DWORD z) {
133 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
134 return 0;
138 /******************************************************************************
139 * internal helper functions
141 static void _dump_DDBLTFX(DWORD flagmask) {
142 int i;
143 const struct {
144 DWORD mask;
145 char *name;
146 } flags[] = {
147 #define FE(x) { x, #x},
148 FE(DDBLTFX_ARITHSTRETCHY)
149 FE(DDBLTFX_MIRRORLEFTRIGHT)
150 FE(DDBLTFX_MIRRORUPDOWN)
151 FE(DDBLTFX_NOTEARING)
152 FE(DDBLTFX_ROTATE180)
153 FE(DDBLTFX_ROTATE270)
154 FE(DDBLTFX_ROTATE90)
155 FE(DDBLTFX_ZBUFFERRANGE)
156 FE(DDBLTFX_ZBUFFERBASEDEST)
158 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
159 if (flags[i].mask & flagmask) {
160 DUMP("%s ",flags[i].name);
163 DUMP("\n");
167 static void _dump_DDBLTFAST(DWORD flagmask) {
168 int i;
169 const struct {
170 DWORD mask;
171 char *name;
172 } flags[] = {
173 #define FE(x) { x, #x},
174 FE(DDBLTFAST_NOCOLORKEY)
175 FE(DDBLTFAST_SRCCOLORKEY)
176 FE(DDBLTFAST_DESTCOLORKEY)
177 FE(DDBLTFAST_WAIT)
179 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
180 if (flags[i].mask & flagmask)
181 DUMP("%s ",flags[i].name);
182 DUMP("\n");
185 static void _dump_DDBLT(DWORD flagmask) {
186 int i;
187 const struct {
188 DWORD mask;
189 char *name;
190 } flags[] = {
191 #define FE(x) { x, #x},
192 FE(DDBLT_ALPHADEST)
193 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
194 FE(DDBLT_ALPHADESTNEG)
195 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
196 FE(DDBLT_ALPHAEDGEBLEND)
197 FE(DDBLT_ALPHASRC)
198 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
199 FE(DDBLT_ALPHASRCNEG)
200 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
201 FE(DDBLT_ASYNC)
202 FE(DDBLT_COLORFILL)
203 FE(DDBLT_DDFX)
204 FE(DDBLT_DDROPS)
205 FE(DDBLT_KEYDEST)
206 FE(DDBLT_KEYDESTOVERRIDE)
207 FE(DDBLT_KEYSRC)
208 FE(DDBLT_KEYSRCOVERRIDE)
209 FE(DDBLT_ROP)
210 FE(DDBLT_ROTATIONANGLE)
211 FE(DDBLT_ZBUFFER)
212 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
213 FE(DDBLT_ZBUFFERDESTOVERRIDE)
214 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
215 FE(DDBLT_ZBUFFERSRCOVERRIDE)
216 FE(DDBLT_WAIT)
217 FE(DDBLT_DEPTHFILL)
219 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
220 if (flags[i].mask & flagmask)
221 DUMP("%s ",flags[i].name);
224 static void _dump_DDSCAPS(DWORD flagmask) {
225 int i;
226 const struct {
227 DWORD mask;
228 char *name;
229 } flags[] = {
230 #define FE(x) { x, #x},
231 FE(DDSCAPS_RESERVED1)
232 FE(DDSCAPS_ALPHA)
233 FE(DDSCAPS_BACKBUFFER)
234 FE(DDSCAPS_COMPLEX)
235 FE(DDSCAPS_FLIP)
236 FE(DDSCAPS_FRONTBUFFER)
237 FE(DDSCAPS_OFFSCREENPLAIN)
238 FE(DDSCAPS_OVERLAY)
239 FE(DDSCAPS_PALETTE)
240 FE(DDSCAPS_PRIMARYSURFACE)
241 FE(DDSCAPS_PRIMARYSURFACELEFT)
242 FE(DDSCAPS_SYSTEMMEMORY)
243 FE(DDSCAPS_TEXTURE)
244 FE(DDSCAPS_3DDEVICE)
245 FE(DDSCAPS_VIDEOMEMORY)
246 FE(DDSCAPS_VISIBLE)
247 FE(DDSCAPS_WRITEONLY)
248 FE(DDSCAPS_ZBUFFER)
249 FE(DDSCAPS_OWNDC)
250 FE(DDSCAPS_LIVEVIDEO)
251 FE(DDSCAPS_HWCODEC)
252 FE(DDSCAPS_MODEX)
253 FE(DDSCAPS_MIPMAP)
254 FE(DDSCAPS_RESERVED2)
255 FE(DDSCAPS_ALLOCONLOAD)
256 FE(DDSCAPS_VIDEOPORT)
257 FE(DDSCAPS_LOCALVIDMEM)
258 FE(DDSCAPS_NONLOCALVIDMEM)
259 FE(DDSCAPS_STANDARDVGAMODE)
260 FE(DDSCAPS_OPTIMIZED)
262 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
263 if (flags[i].mask & flagmask)
264 DUMP("%s ",flags[i].name);
265 DUMP("\n");
268 static void _dump_DDSD(DWORD flagmask) {
269 int i;
270 const struct {
271 DWORD mask;
272 char *name;
273 } flags[] = {
274 FE(DDSD_CAPS)
275 FE(DDSD_HEIGHT)
276 FE(DDSD_WIDTH)
277 FE(DDSD_PITCH)
278 FE(DDSD_BACKBUFFERCOUNT)
279 FE(DDSD_ZBUFFERBITDEPTH)
280 FE(DDSD_ALPHABITDEPTH)
281 FE(DDSD_PIXELFORMAT)
282 FE(DDSD_CKDESTOVERLAY)
283 FE(DDSD_CKDESTBLT)
284 FE(DDSD_CKSRCOVERLAY)
285 FE(DDSD_CKSRCBLT)
286 FE(DDSD_MIPMAPCOUNT)
287 FE(DDSD_REFRESHRATE)
288 FE(DDSD_LINEARSIZE)
289 FE(DDSD_LPSURFACE)
291 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
292 if (flags[i].mask & flagmask)
293 DUMP("%s ",flags[i].name);
294 DUMP("\n");
297 static void _dump_DDCOLORKEY(DWORD flagmask) {
298 int i;
299 const struct {
300 DWORD mask;
301 char *name;
302 } flags[] = {
303 #define FE(x) { x, #x},
304 FE(DDPF_ALPHAPIXELS)
305 FE(DDPF_ALPHA)
306 FE(DDPF_FOURCC)
307 FE(DDPF_PALETTEINDEXED4)
308 FE(DDPF_PALETTEINDEXEDTO8)
309 FE(DDPF_PALETTEINDEXED8)
310 FE(DDPF_RGB)
311 FE(DDPF_COMPRESSED)
312 FE(DDPF_RGBTOYUV)
313 FE(DDPF_YUV)
314 FE(DDPF_ZBUFFER)
315 FE(DDPF_PALETTEINDEXED1)
316 FE(DDPF_PALETTEINDEXED2)
317 FE(DDPF_ZPIXELS)
319 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
320 if (flags[i].mask & flagmask)
321 DUMP("%s ",flags[i].name);
322 DUMP("\n");
325 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
326 _dump_DDCOLORKEY(pf->dwFlags);
327 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
328 DUMP("RBG bit cbout : %ld\n", pf->x.dwRGBBitCount);
329 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
330 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
333 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
334 static XVisualInfo *vi;
335 XVisualInfo vt;
336 int nitems;
338 if (!vi)
339 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
341 pf->dwFourCC = 0;
342 if (ddraw->d.depth==8) {
343 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
344 pf->x.dwRGBBitCount = 8;
345 pf->y.dwRBitMask = 0;
346 pf->z.dwGBitMask = 0;
347 pf->xx.dwBBitMask = 0;
348 pf->xy.dwRGBAlphaBitMask= 0;
349 return 0;
351 if (ddraw->d.depth==16) {
352 pf->dwFlags = DDPF_RGB;
353 pf->x.dwRGBBitCount = 16;
354 pf->y.dwRBitMask = vi[0].red_mask;
355 pf->z.dwGBitMask = vi[0].green_mask;
356 pf->xx.dwBBitMask = vi[0].blue_mask;
357 pf->xy.dwRGBAlphaBitMask= 0;
358 return 0;
360 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
361 return DDERR_GENERIC;
364 /******************************************************************************
365 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
367 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
368 * DDS and DDS2 use those functions. (Function calls did not change (except
369 * using different DirectDrawSurfaceX version), just added flags and functions)
371 static HRESULT WINAPI IDirectDrawSurface3_Lock(
372 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
374 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
375 this,lprect,lpddsd,flags,(DWORD)hnd);
376 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
377 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
378 this,lprect,lpddsd,flags,(DWORD)hnd);
380 /* First, copy the Surface description */
381 *lpddsd = this->s.surface_desc;
383 /* If asked only for a part, change the surface pointer */
384 if (lprect) {
385 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
386 lprect->top,lprect->left,lprect->bottom,lprect->right
388 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
389 (lprect->top*this->s.surface_desc.lPitch) +
390 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
391 } else {
392 assert(this->s.surface_desc.y.lpSurface);
394 return DD_OK;
397 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
398 LPDIRECTDRAWSURFACE3 this,LPVOID surface
400 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
401 return DD_OK;
404 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
405 LPDIRECTDRAWSURFACE3 this,LPVOID surface)
407 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
409 if (!this->s.ddraw->e.xlib.paintable)
410 return DD_OK;
412 /* Only redraw the screen when unlocking the buffer that is on screen */
413 if ((this->t.xlib.image != NULL) &&
414 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
415 #ifdef HAVE_LIBXXSHM
416 if (this->s.ddraw->e.xlib.xshm_active)
417 TSXShmPutImage(display,
418 this->s.ddraw->e.xlib.drawable,
419 DefaultGCOfScreen(screen),
420 this->t.xlib.image,
421 0, 0, 0, 0,
422 this->t.xlib.image->width,
423 this->t.xlib.image->height,
424 False);
425 else
426 #endif
427 TSXPutImage( display,
428 this->s.ddraw->e.xlib.drawable,
429 DefaultGCOfScreen(screen),
430 this->t.xlib.image,
431 0, 0, 0, 0,
432 this->t.xlib.image->width,
433 this->t.xlib.image->height);
435 if (this->s.palette && this->s.palette->cm)
436 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
439 return DD_OK;
442 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
443 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
445 #ifdef HAVE_LIBXXF86DGA
446 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
447 if (!flipto) {
448 if (this->s.backbuffer)
449 flipto = this->s.backbuffer;
450 else
451 flipto = this;
453 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
455 if (flipto->s.palette && flipto->s.palette->cm) {
456 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
458 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
460 if (flipto!=this) {
461 int tmp;
462 LPVOID ptmp;
464 tmp = this->t.dga.fb_height;
465 this->t.dga.fb_height = flipto->t.dga.fb_height;
466 flipto->t.dga.fb_height = tmp;
468 ptmp = this->s.surface_desc.y.lpSurface;
469 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
470 flipto->s.surface_desc.y.lpSurface = ptmp;
472 return DD_OK;
473 #else /* defined(HAVE_LIBXXF86DGA) */
474 return E_UNEXPECTED;
475 #endif /* defined(HAVE_LIBXXF86DGA) */
478 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
479 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
481 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
482 if (!this->s.ddraw->e.xlib.paintable)
483 return DD_OK;
485 if (!flipto) {
486 if (this->s.backbuffer)
487 flipto = this->s.backbuffer;
488 else
489 flipto = this;
492 #ifdef HAVE_LIBXXSHM
493 if (this->s.ddraw->e.xlib.xshm_active) {
494 TSXShmPutImage(display,
495 this->s.ddraw->e.xlib.drawable,
496 DefaultGCOfScreen(screen),
497 flipto->t.xlib.image,
498 0, 0, 0, 0,
499 flipto->t.xlib.image->width,
500 flipto->t.xlib.image->height,
501 False);
502 } else
503 #endif
504 TSXPutImage(display,
505 this->s.ddraw->e.xlib.drawable,
506 DefaultGCOfScreen(screen),
507 flipto->t.xlib.image,
508 0, 0, 0, 0,
509 flipto->t.xlib.image->width,
510 flipto->t.xlib.image->height);
512 if (flipto->s.palette && flipto->s.palette->cm) {
513 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,flipto->s.palette->cm);
515 if (flipto!=this) {
516 XImage *tmp;
517 LPVOID *surf;
518 tmp = this->t.xlib.image;
519 this->t.xlib.image = flipto->t.xlib.image;
520 flipto->t.xlib.image = tmp;
521 surf = this->s.surface_desc.y.lpSurface;
522 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
523 flipto->s.surface_desc.y.lpSurface = surf;
525 return DD_OK;
529 /* The IDirectDrawSurface3::SetPalette method attaches the specified
530 * DirectDrawPalette object to a surface. The surface uses this palette for all
531 * subsequent operations. The palette change takes place immediately.
533 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
534 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
536 int i;
537 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
539 if( !(pal->cm) && (this->s.ddraw->d.depth<=8))
541 pal->cm = TSXCreateColormap(display,this->s.ddraw->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
543 /* FIXME: this is not correct, when using -managed (XSetWindowColormap??) */
544 TSXInstallColormap(display,pal->cm);
546 for (i=0;i<256;i++) {
547 XColor xc;
549 xc.red = pal->palents[i].peRed<<8;
550 xc.blue = pal->palents[i].peBlue<<8;
551 xc.green = pal->palents[i].peGreen<<8;
552 xc.flags = DoRed|DoBlue|DoGreen;
553 xc.pixel = i;
554 TSXStoreColor(display,pal->cm,&xc);
558 /* According to spec, we are only supposed to
559 * AddRef if this is not the same palette.
561 if( this->s.palette != pal )
563 if( pal != NULL )
564 pal->lpvtbl->fnAddRef( pal );
565 if( this->s.palette != NULL )
566 this->s.palette->lpvtbl->fnRelease( this->s.palette );
567 this->s.palette = pal;
569 /* I think that we need to attach it to all backbuffers...*/
570 if( this->s.backbuffer ) {
571 if( this->s.backbuffer->s.palette )
572 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
573 this->s.backbuffer->s.palette );
574 this->s.backbuffer->s.palette = pal;
575 if( pal )
576 pal->lpvtbl->fnAddRef( pal );
578 /* Perform the refresh */
579 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
581 return DD_OK;
584 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
585 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
587 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
588 #ifdef HAVE_LIBXXF86DGA
589 /* According to spec, we are only supposed to
590 * AddRef if this is not the same palette.
592 if( this->s.palette != pal )
594 if( pal != NULL )
595 pal->lpvtbl->fnAddRef( pal );
596 if( this->s.palette != NULL )
597 this->s.palette->lpvtbl->fnRelease( this->s.palette );
598 this->s.palette = pal;
600 /* I think that we need to attach it to all backbuffers...*/
601 if( this->s.backbuffer ) {
602 if( this->s.backbuffer->s.palette )
603 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
604 this->s.backbuffer->s.palette = pal;
605 if( pal ) pal->lpvtbl->fnAddRef( pal );
607 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
609 return DD_OK;
610 #else /* defined(HAVE_LIBXXF86DGA) */
611 return E_UNEXPECTED;
612 #endif /* defined(HAVE_LIBXXF86DGA) */
617 static HRESULT WINAPI IDirectDrawSurface3_Blt(
618 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
620 RECT32 xdst,xsrc;
621 DDSURFACEDESC ddesc,sdesc;
622 int i,j;
624 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
625 this,rdst,src,rsrc,dwFlags,lpbltfx);
627 if (src != NULL)
628 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
629 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
631 if (TRACE_ON(ddraw)) {
632 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
633 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
634 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
635 if (dwFlags & DDBLT_DDFX) {
636 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
640 if (rdst) {
641 memcpy(&xdst,rdst,sizeof(xdst));
642 } else {
643 xdst.top = 0;
644 xdst.bottom = ddesc.dwHeight;
645 xdst.left = 0;
646 xdst.right = ddesc.dwWidth;
649 if (rsrc) {
650 memcpy(&xsrc,rsrc,sizeof(xsrc));
651 } else {
652 if (src) {
653 xsrc.top = 0;
654 xsrc.bottom = sdesc.dwHeight;
655 xsrc.left = 0;
656 xsrc.right = sdesc.dwWidth;
657 } else {
658 memset(&xsrc,0,sizeof(xsrc));
662 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
664 if (dwFlags & DDBLT_COLORFILL) {
665 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
666 LPBYTE xline,xpixel;
668 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
669 for (i=xdst.top;i<xdst.bottom;i++) {
670 xpixel = xline+bpp*xdst.left;
672 for (j=xdst.left;j<xdst.right;j++) {
673 /* FIXME: this only works on little endian
674 * architectures, where DWORD starts with low
675 * byte first!
677 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
678 xpixel += bpp;
680 xline += ddesc.lPitch;
682 dwFlags &= ~(DDBLT_COLORFILL);
685 if (!src) {
686 if (dwFlags) {
687 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
689 return DD_OK;
692 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
693 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
694 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
695 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
696 !dwFlags
698 memcpy(ddesc.y.lpSurface,
699 sdesc.y.lpSurface,
700 ddesc.dwHeight * ddesc.lPitch);
701 } else {
702 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
703 int height = xsrc.bottom - xsrc.top;
704 int width = (xsrc.right - xsrc.left) * bpp;
705 int h;
707 for (h = 0; h < height; h++) {
708 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
709 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
710 width);
714 if (dwFlags && FIXME_ON(ddraw)) {
715 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
718 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
719 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
721 return DD_OK;
724 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
725 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
727 int i,bpp;
728 DDSURFACEDESC ddesc,sdesc;
730 if (TRACE_ON(ddraw)) {
731 TRACE(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
732 this,dstx,dsty,src,rsrc,trans
734 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
735 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
737 /* We need to lock the surfaces, or we won't get refreshes when done. */
738 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
739 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
740 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
741 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
742 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
743 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
744 (rsrc->right-rsrc->left)*bpp
747 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
748 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
749 return DD_OK;
752 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
753 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
755 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
756 this,ddbltbatch,x,y
758 return DD_OK;
761 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
762 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
764 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
765 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
766 return DD_OK;
769 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
770 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
771 ) {
772 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
773 this,ddsd);
775 /* Simply copy the surface description stored in the object */
776 *ddsd = this->s.surface_desc;
778 if (TRACE_ON(ddraw)) {
779 fprintf(stderr," flags: ");
780 _dump_DDSD(ddsd->dwFlags);
781 if (ddsd->dwFlags & DDSD_CAPS) {
782 fprintf(stderr, " caps: ");
783 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
785 fprintf(stderr,"\n");
788 return DD_OK;
791 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
792 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
794 return ++(this->ref);
797 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
798 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
800 #ifdef HAVE_LIBXXF86DGA
801 if (!--(this->ref)) {
802 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
803 /* clear out of surface list */
804 if (this->t.dga.fb_height == -1) {
805 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
806 } else {
807 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
809 HeapFree(GetProcessHeap(),0,this);
810 return 0;
812 #endif /* defined(HAVE_LIBXXF86DGA) */
813 return this->ref;
816 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
817 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
819 if (!--(this->ref)) {
820 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
822 if( this->s.backbuffer )
823 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
825 if (this->t.xlib.image != NULL) {
826 this->t.xlib.image->data = NULL;
828 #ifdef HAVE_LIBXXSHM
829 if (this->s.ddraw->e.xlib.xshm_active) {
830 TSXShmDetach(display, &(this->t.xlib.shminfo));
831 TSXDestroyImage(this->t.xlib.image);
832 shmdt(this->t.xlib.shminfo.shmaddr);
833 } else {
834 #endif
835 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
836 TSXDestroyImage(this->t.xlib.image);
837 #ifdef HAVE_LIBXXSHM
839 #endif
841 this->t.xlib.image = 0;
842 } else {
843 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
846 if (this->s.palette)
847 this->s.palette->lpvtbl->fnRelease(this->s.palette);
849 HeapFree(GetProcessHeap(),0,this);
850 return 0;
853 return this->ref;
856 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
857 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
859 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
860 this, lpddsd, lpdsf);
862 if (TRACE_ON(ddraw)) {
863 TRACE(ddraw," caps ");
864 _dump_DDSCAPS(lpddsd->dwCaps);
867 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
868 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
869 return E_FAIL;
872 /* FIXME: should handle more than one backbuffer */
873 *lpdsf = this->s.backbuffer;
875 if( this->s.backbuffer )
876 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
878 return DD_OK;
881 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
882 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
884 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
886 return DDERR_ALREADYINITIALIZED;
889 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
890 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
892 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
894 *pf = this->s.surface_desc.ddpfPixelFormat;
896 return DD_OK;
899 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
900 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
901 return DD_OK;
904 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
905 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
907 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
908 return DD_OK;
911 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
912 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
914 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
915 return DD_OK;
918 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
919 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
921 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
923 /* This hack will be enough for the moment */
924 if (this->s.backbuffer == NULL)
925 this->s.backbuffer = surf;
926 return DD_OK;
929 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
930 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
931 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
932 return DD_OK;
935 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
936 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
937 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
938 return DD_OK;
942 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
943 char xrefiid[50];
945 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
946 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
948 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
949 * the same interface. And IUnknown does that too of course.
951 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
952 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
953 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
954 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
956 *obj = this;
957 this->lpvtbl->fnAddRef(this);
958 return S_OK;
960 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
961 return OLE_E_ENUM_NOMORE;
964 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
965 TRACE(ddraw,"(%p)->(), stub!\n",this);
966 return DD_OK; /* hmm */
969 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
970 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
971 return DD_OK;
974 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
975 FIXME(ddraw,"(%p)->(),stub!\n",this);
976 return DD_OK;
979 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
980 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey )
982 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);
984 if( dwFlags & DDCKEY_SRCBLT )
986 dwFlags &= ~DDCKEY_SRCBLT;
987 memcpy( &(this->s.ckSrcBlt), ckey, sizeof( *ckey ) );
990 if( dwFlags & DDCKEY_DESTBLT )
992 dwFlags &= ~DDCKEY_DESTBLT;
993 memcpy( &(this->s.ckDestBlt), ckey, sizeof( *ckey ) );
996 if( dwFlags & DDCKEY_SRCOVERLAY )
998 dwFlags &= ~DDCKEY_SRCOVERLAY;
999 memcpy( &(this->s.ckSrcOverlay), ckey, sizeof( *ckey ) );
1001 if( dwFlags & DDCKEY_DESTOVERLAY )
1003 dwFlags &= ~DDCKEY_DESTOVERLAY;
1004 memcpy( &(this->s.ckDestOverlay), ckey, sizeof( *ckey ) );
1007 if( dwFlags )
1009 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1012 return DD_OK;
1016 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
1017 LPDIRECTDRAWSURFACE3 this,
1018 LPRECT32 lpRect )
1020 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
1022 return DD_OK;
1025 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
1026 LPDIRECTDRAWSURFACE3 this,
1027 DWORD dwFlags,
1028 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
1030 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1032 return DD_OK;
1035 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
1036 LPDIRECTDRAWSURFACE3 this,
1037 DWORD dwFlags,
1038 LPVOID lpContext,
1039 LPDDENUMSURFACESCALLBACK lpfnCallback )
1041 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1042 lpContext, lpfnCallback );
1044 return DD_OK;
1047 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
1048 LPDIRECTDRAWSURFACE3 this,
1049 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1051 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1053 return DD_OK;
1056 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
1057 LPDIRECTDRAWSURFACE3 this,
1058 DWORD dwFlags,
1059 LPDDCOLORKEY lpDDColorKey )
1061 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);
1063 if( dwFlags & DDCKEY_SRCBLT ) {
1064 dwFlags &= ~DDCKEY_SRCBLT;
1065 memcpy( lpDDColorKey, &(this->s.ckSrcBlt), sizeof( *lpDDColorKey ) );
1068 if( dwFlags & DDCKEY_DESTBLT )
1070 dwFlags &= ~DDCKEY_DESTBLT;
1071 memcpy( lpDDColorKey, &(this->s.ckDestBlt), sizeof( *lpDDColorKey ) );
1074 if( dwFlags & DDCKEY_SRCOVERLAY )
1076 dwFlags &= ~DDCKEY_SRCOVERLAY;
1077 memcpy( lpDDColorKey, &(this->s.ckSrcOverlay), sizeof( *lpDDColorKey ) );
1080 if( dwFlags & DDCKEY_DESTOVERLAY )
1082 dwFlags &= ~DDCKEY_DESTOVERLAY;
1083 memcpy( lpDDColorKey, &(this->s.ckDestOverlay), sizeof( *lpDDColorKey ) );
1086 if( dwFlags )
1088 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1091 return DD_OK;
1094 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
1095 LPDIRECTDRAWSURFACE3 this,
1096 DWORD dwFlags )
1098 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1100 return DD_OK;
1103 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
1104 LPDIRECTDRAWSURFACE3 this,
1105 LPDIRECTDRAWPALETTE* lplpDDPalette )
1107 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1109 return DD_OK;
1112 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
1113 LPDIRECTDRAWSURFACE3 this,
1114 LONG lX,
1115 LONG lY)
1117 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1119 return DD_OK;
1122 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
1123 LPDIRECTDRAWSURFACE3 this,
1124 LPRECT32 lpSrcRect,
1125 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
1126 LPRECT32 lpDestRect,
1127 DWORD dwFlags,
1128 LPDDOVERLAYFX lpDDOverlayFx )
1130 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1131 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1133 return DD_OK;
1136 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
1137 LPDIRECTDRAWSURFACE3 this,
1138 DWORD dwFlags )
1140 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1142 return DD_OK;
1145 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
1146 LPDIRECTDRAWSURFACE3 this,
1147 DWORD dwFlags,
1148 LPDIRECTDRAWSURFACE3 lpDDSReference )
1150 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1152 return DD_OK;
1155 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
1156 LPDIRECTDRAWSURFACE3 this,
1157 LPVOID* lplpDD )
1159 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1161 return DD_OK;
1164 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
1165 LPDIRECTDRAWSURFACE3 this,
1166 DWORD dwFlags )
1168 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1170 return DD_OK;
1173 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
1174 LPDIRECTDRAWSURFACE3 this,
1175 DWORD dwFlags )
1177 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1179 return DD_OK;
1182 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1183 LPDIRECTDRAWSURFACE3 this,
1184 LPDDSURFACEDESC lpDDSD,
1185 DWORD dwFlags )
1187 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1189 return DD_OK;
1192 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1193 IDirectDrawSurface3_QueryInterface,
1194 IDirectDrawSurface3_AddRef,
1195 DGA_IDirectDrawSurface3_Release,
1196 IDirectDrawSurface3_AddAttachedSurface,
1197 IDirectDrawSurface3_AddOverlayDirtyRect,
1198 IDirectDrawSurface3_Blt,
1199 IDirectDrawSurface3_BltBatch,
1200 IDirectDrawSurface3_BltFast,
1201 IDirectDrawSurface3_DeleteAttachedSurface,
1202 IDirectDrawSurface3_EnumAttachedSurfaces,
1203 IDirectDrawSurface3_EnumOverlayZOrders,
1204 DGA_IDirectDrawSurface3_Flip,
1205 IDirectDrawSurface3_GetAttachedSurface,
1206 IDirectDrawSurface3_GetBltStatus,
1207 IDirectDrawSurface3_GetCaps,
1208 IDirectDrawSurface3_GetClipper,
1209 IDirectDrawSurface3_GetColorKey,
1210 IDirectDrawSurface3_GetDC,
1211 IDirectDrawSurface3_GetFlipStatus,
1212 IDirectDrawSurface3_GetOverlayPosition,
1213 IDirectDrawSurface3_GetPalette,
1214 IDirectDrawSurface3_GetPixelFormat,
1215 IDirectDrawSurface3_GetSurfaceDesc,
1216 IDirectDrawSurface3_Initialize,
1217 IDirectDrawSurface3_IsLost,
1218 IDirectDrawSurface3_Lock,
1219 IDirectDrawSurface3_ReleaseDC,
1220 IDirectDrawSurface3_Restore,
1221 IDirectDrawSurface3_SetClipper,
1222 IDirectDrawSurface3_SetColorKey,
1223 IDirectDrawSurface3_SetOverlayPosition,
1224 DGA_IDirectDrawSurface3_SetPalette,
1225 DGA_IDirectDrawSurface3_Unlock,
1226 IDirectDrawSurface3_UpdateOverlay,
1227 IDirectDrawSurface3_UpdateOverlayDisplay,
1228 IDirectDrawSurface3_UpdateOverlayZOrder,
1229 IDirectDrawSurface3_GetDDInterface,
1230 IDirectDrawSurface3_PageLock,
1231 IDirectDrawSurface3_PageUnlock,
1232 IDirectDrawSurface3_SetSurfaceDesc,
1235 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1236 IDirectDrawSurface3_QueryInterface,
1237 IDirectDrawSurface3_AddRef,
1238 Xlib_IDirectDrawSurface3_Release,
1239 IDirectDrawSurface3_AddAttachedSurface,
1240 IDirectDrawSurface3_AddOverlayDirtyRect,
1241 IDirectDrawSurface3_Blt,
1242 IDirectDrawSurface3_BltBatch,
1243 IDirectDrawSurface3_BltFast,
1244 IDirectDrawSurface3_DeleteAttachedSurface,
1245 IDirectDrawSurface3_EnumAttachedSurfaces,
1246 IDirectDrawSurface3_EnumOverlayZOrders,
1247 Xlib_IDirectDrawSurface3_Flip,
1248 IDirectDrawSurface3_GetAttachedSurface,
1249 IDirectDrawSurface3_GetBltStatus,
1250 IDirectDrawSurface3_GetCaps,
1251 IDirectDrawSurface3_GetClipper,
1252 IDirectDrawSurface3_GetColorKey,
1253 IDirectDrawSurface3_GetDC,
1254 IDirectDrawSurface3_GetFlipStatus,
1255 IDirectDrawSurface3_GetOverlayPosition,
1256 IDirectDrawSurface3_GetPalette,
1257 IDirectDrawSurface3_GetPixelFormat,
1258 IDirectDrawSurface3_GetSurfaceDesc,
1259 IDirectDrawSurface3_Initialize,
1260 IDirectDrawSurface3_IsLost,
1261 IDirectDrawSurface3_Lock,
1262 IDirectDrawSurface3_ReleaseDC,
1263 IDirectDrawSurface3_Restore,
1264 IDirectDrawSurface3_SetClipper,
1265 IDirectDrawSurface3_SetColorKey,
1266 IDirectDrawSurface3_SetOverlayPosition,
1267 Xlib_IDirectDrawSurface3_SetPalette,
1268 Xlib_IDirectDrawSurface3_Unlock,
1269 IDirectDrawSurface3_UpdateOverlay,
1270 IDirectDrawSurface3_UpdateOverlayDisplay,
1271 IDirectDrawSurface3_UpdateOverlayZOrder,
1272 IDirectDrawSurface3_GetDDInterface,
1273 IDirectDrawSurface3_PageLock,
1274 IDirectDrawSurface3_PageUnlock,
1275 IDirectDrawSurface3_SetSurfaceDesc,
1278 /******************************************************************************
1279 * DirectDrawCreateClipper (DDRAW.7)
1281 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1282 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1283 LPUNKNOWN pUnkOuter)
1285 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1287 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1288 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1289 (*lplpDDClipper)->ref = 1;
1291 return DD_OK;
1294 /******************************************************************************
1295 * IDirectDrawClipper
1297 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1298 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1300 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1301 return DD_OK;
1304 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1305 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1307 this->ref--;
1308 if (this->ref)
1309 return this->ref;
1310 HeapFree(GetProcessHeap(),0,this);
1311 return 0;
1314 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1315 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1317 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1318 if (hmm) *hmm=0;
1319 return DD_OK;
1322 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1323 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1325 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1326 return DD_OK;
1329 static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
1330 LPDIRECTDRAWCLIPPER this,
1331 REFIID riid,
1332 LPVOID* ppvObj )
1334 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
1335 return OLE_E_ENUM_NOMORE;
1338 static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
1340 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1341 return ++(this->ref);
1344 static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
1345 LPDIRECTDRAWCLIPPER this,
1346 HWND32* HWndPtr )
1348 FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
1349 return DD_OK;
1352 static HRESULT WINAPI IDirectDrawClipper_Initialize(
1353 LPDIRECTDRAWCLIPPER this,
1354 LPDIRECTDRAW lpDD,
1355 DWORD dwFlags )
1357 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
1358 return DD_OK;
1361 static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
1362 LPDIRECTDRAWCLIPPER this,
1363 BOOL32* lpbChanged )
1365 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
1366 return DD_OK;
1369 static struct IDirectDrawClipper_VTable ddclipvt = {
1370 IDirectDrawClipper_QueryInterface,
1371 IDirectDrawClipper_AddRef,
1372 IDirectDrawClipper_Release,
1373 IDirectDrawClipper_GetClipList,
1374 IDirectDrawClipper_GetHWnd,
1375 IDirectDrawClipper_Initialize,
1376 IDirectDrawClipper_IsClipListChanged,
1377 IDirectDrawClipper_SetClipList,
1378 IDirectDrawClipper_SetHwnd
1382 /******************************************************************************
1383 * IDirectDrawPalette
1385 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1386 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1388 int i;
1390 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1391 this,x,start,count,palent);
1393 if (!this->cm) /* should not happen */ {
1394 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1395 return DDERR_GENERIC;
1397 for (i=0;i<count;i++) {
1398 palent[i].peRed = this->palents[start+i].peRed;
1399 palent[i].peBlue = this->palents[start+i].peBlue;
1400 palent[i].peGreen = this->palents[start+i].peGreen;
1401 palent[i].peFlags = this->palents[start+i].peFlags;
1404 return DD_OK;
1407 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1408 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1410 XColor xc;
1411 int i;
1413 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1414 this,x,start,count,palent
1416 for (i=0;i<count;i++) {
1417 xc.red = palent[i].peRed<<8;
1418 xc.blue = palent[i].peBlue<<8;
1419 xc.green = palent[i].peGreen<<8;
1420 xc.flags = DoRed|DoBlue|DoGreen;
1421 xc.pixel = start+i;
1423 if (this->cm)
1424 TSXStoreColor(display,this->cm,&xc);
1426 this->palents[start+i].peRed = palent[i].peRed;
1427 this->palents[start+i].peBlue = palent[i].peBlue;
1428 this->palents[start+i].peGreen = palent[i].peGreen;
1429 this->palents[start+i].peFlags = palent[i].peFlags;
1431 if (!this->cm) /* should not happen */ {
1433 return DD_OK;
1436 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1437 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1439 #ifdef HAVE_LIBXXF86DGA
1440 XColor xc;
1441 Colormap cm;
1442 int i;
1444 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1445 this,x,start,count,palent
1447 if (!this->cm) /* should not happen */ {
1448 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1449 return DDERR_GENERIC;
1451 /* FIXME: free colorcells instead of freeing whole map */
1452 cm = this->cm;
1453 this->cm = TSXCopyColormapAndFree(display,this->cm);
1454 TSXFreeColormap(display,cm);
1456 for (i=0;i<count;i++) {
1457 xc.red = palent[i].peRed<<8;
1458 xc.blue = palent[i].peBlue<<8;
1459 xc.green = palent[i].peGreen<<8;
1460 xc.flags = DoRed|DoBlue|DoGreen;
1461 xc.pixel = i+start;
1463 TSXStoreColor(display,this->cm,&xc);
1465 this->palents[start+i].peRed = palent[i].peRed;
1466 this->palents[start+i].peBlue = palent[i].peBlue;
1467 this->palents[start+i].peGreen = palent[i].peGreen;
1468 this->palents[start+i].peFlags = palent[i].peFlags;
1470 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1471 return DD_OK;
1472 #else /* defined(HAVE_LIBXXF86DGA) */
1473 return E_UNEXPECTED;
1474 #endif /* defined(HAVE_LIBXXF86DGA) */
1477 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1478 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1479 if (!--(this->ref)) {
1480 if (this->cm) {
1481 TSXFreeColormap(display,this->cm);
1482 this->cm = 0;
1484 HeapFree(GetProcessHeap(),0,this);
1485 return 0;
1487 return this->ref;
1490 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1492 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1493 return ++(this->ref);
1496 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1497 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1499 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1501 return DDERR_ALREADYINITIALIZED;
1504 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1505 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1507 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1508 return DD_OK;
1511 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1512 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1514 char xrefiid[50];
1516 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1517 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1519 return S_OK;
1522 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1523 IDirectDrawPalette_QueryInterface,
1524 IDirectDrawPalette_AddRef,
1525 IDirectDrawPalette_Release,
1526 IDirectDrawPalette_GetCaps,
1527 IDirectDrawPalette_GetEntries,
1528 IDirectDrawPalette_Initialize,
1529 DGA_IDirectDrawPalette_SetEntries
1532 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1533 IDirectDrawPalette_QueryInterface,
1534 IDirectDrawPalette_AddRef,
1535 IDirectDrawPalette_Release,
1536 IDirectDrawPalette_GetCaps,
1537 IDirectDrawPalette_GetEntries,
1538 IDirectDrawPalette_Initialize,
1539 Xlib_IDirectDrawPalette_SetEntries
1542 /*******************************************************************************
1543 * IDirect3D
1545 static HRESULT WINAPI IDirect3D_QueryInterface(
1546 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1548 /* FIXME: Not sure if this is correct */
1549 char xrefiid[50];
1551 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1552 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1553 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1554 *obj = this;
1555 this->lpvtbl->fnAddRef(this);
1556 return S_OK;
1558 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1559 LPDIRECT3D d3d;
1561 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1562 d3d->ref = 1;
1563 d3d->ddraw = (LPDIRECTDRAW)this;
1564 this->lpvtbl->fnAddRef(this);
1565 d3d->lpvtbl = &d3dvt;
1566 *obj = d3d;
1567 return S_OK;
1569 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1570 LPDIRECT3D2 d3d;
1572 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1573 d3d->ref = 1;
1574 d3d->ddraw = (LPDIRECTDRAW)this;
1575 this->lpvtbl->fnAddRef(this);
1576 d3d->lpvtbl = &d3d2vt;
1577 *obj = d3d;
1578 return S_OK;
1580 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1581 return OLE_E_ENUM_NOMORE;
1584 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1585 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1587 return ++(this->ref);
1590 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1592 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1594 if (!--(this->ref)) {
1595 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1596 HeapFree(GetProcessHeap(),0,this);
1597 return 0;
1599 return this->ref;
1602 static HRESULT WINAPI IDirect3D_Initialize(
1603 LPDIRECT3D this, REFIID refiid )
1605 /* FIXME: Not sure if this is correct */
1606 char xrefiid[50];
1608 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1609 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1611 return DDERR_ALREADYINITIALIZED;
1614 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,LPDIRECT3DLIGHT *light,IUnknown* lpunk) {
1615 FIXME(ddraw,"(%p)->(%p,%p)\n",this,light,lpunk);
1616 return E_FAIL;
1619 typedef LPVOID LPDIRECT3DDEVICE;
1621 static HRESULT WINAPI IDirect3D_CreateDevice(LPDIRECT3D this,LPCLSID rclsid,LPDIRECTDRAWSURFACE surf,LPDIRECT3DDEVICE *d3dev) {
1622 char xclsid[50];
1624 WINE_StringFromCLSID(rclsid,xclsid);
1625 FIXME(ddraw,"(%p)->(%s,%p,%p), no Direct3D devices implemented yet!\n",this,xclsid,surf,d3dev);
1626 return E_FAIL; /* D3DERR_INVALID_DEVICE probably */
1629 static HRESULT WINAPI IDirect3D_EnumDevices(
1630 LPDIRECT3D this,
1631 LPD3DENUMDEVICESCALLBACK a,
1632 LPVOID b )
1634 FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
1635 return DD_OK;
1638 static HRESULT WINAPI IDirect3D_CreateMaterial(
1639 LPDIRECT3D this,
1640 LPDIRECT3DMATERIAL* a,
1641 IUnknown* b)
1643 FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
1644 return DD_OK;
1647 static HRESULT WINAPI IDirect3D_CreateViewport(
1648 LPDIRECT3D this,
1649 LPDIRECT3DVIEWPORT* a,
1650 IUnknown* b )
1652 FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
1653 return DD_OK;
1656 static HRESULT WINAPI IDirect3D_FindDevice(
1657 LPDIRECT3D this,
1658 LPD3DFINDDEVICESEARCH a,
1659 LPD3DFINDDEVICERESULT b )
1661 FIXME( ddraw,"(%p)->(%p,%p)\n",this,a,b);
1662 return DD_OK;
1666 /*******************************************************************************
1667 * IDirect3D
1669 static struct IDirect3D_VTable d3dvt = {
1670 IDirect3D_QueryInterface,
1671 IDirect3D_AddRef,
1672 IDirect3D_Release,
1673 IDirect3D_Initialize,
1674 IDirect3D_EnumDevices,
1675 IDirect3D_CreateLight,
1676 IDirect3D_CreateMaterial,
1677 IDirect3D_CreateViewport,
1678 IDirect3D_FindDevice,
1681 /*******************************************************************************
1682 * IDirect3D2
1684 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1685 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1687 if (!--(this->ref)) {
1688 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1689 HeapFree(GetProcessHeap(),0,this);
1690 return 0;
1692 return this->ref;
1695 static HRESULT WINAPI IDirect3D2_EnumDevices(
1696 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1698 D3DDEVICEDESC d1,d2;
1700 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1701 #if 0
1702 d1.dwSize = sizeof(d1);
1703 d1.dwFlags = 0;
1705 d2.dwSize = sizeof(d2);
1706 d2.dwFlags = 0;
1707 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1708 #endif
1709 return DD_OK;
1712 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,REFCLSID rclsid,LPDIRECTDRAWSURFACE surf,LPDIRECT3DDEVICE2 *d3dev) {
1713 char xclsid[50];
1715 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
1716 FIXME(ddraw,"(%p)->(%s,%p,%p), no Direct3D devices implemented yet!\n",this,xclsid,surf,d3dev);
1717 return E_FAIL; /* D3DERR_INVALID_DEVICE probably */
1720 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,LPDIRECT3DLIGHT *light,IUnknown* lpunk) {
1721 FIXME(ddraw,"(%p)->(%p,%p)\n",this,light,lpunk);
1722 return E_FAIL;
1725 static struct IDirect3D2_VTable d3d2vt = {
1726 (void*)IDirect3D_QueryInterface,
1727 (void*)IDirect3D_AddRef,
1728 IDirect3D2_Release,
1729 IDirect3D2_EnumDevices,
1730 (void*)IDirect3D_EnumDevices,
1731 (void*)IDirect3D_CreateLight,
1732 (void*)IDirect3D_CreateMaterial,
1733 (void*)IDirect3D_CreateViewport,
1734 (void*)IDirect3D_FindDevice,
1737 /*******************************************************************************
1738 * IDirectDraw
1741 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1742 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1744 static INT32 ddrawXlibThisOffset = 0;
1746 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
1747 LPDDSURFACEDESC lpddsd,
1748 LPDIRECTDRAWSURFACE lpdsf)
1750 int bpp;
1752 /* The surface was already allocated when entering in this function */
1753 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
1754 /* No pixel format => use DirectDraw's format */
1755 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
1756 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
1757 } else {
1758 /* To check what the program wants */
1759 if (TRACE_ON(ddraw)) {
1760 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
1764 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
1766 /* Copy the surface description */
1767 lpdsf->s.surface_desc = *lpddsd;
1769 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1770 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
1771 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
1773 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
1775 return DD_OK;
1778 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1779 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1781 #ifdef HAVE_LIBXXF86DGA
1782 int i;
1784 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1785 if (TRACE_ON(ddraw)) {
1786 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1787 _dump_DDSD(lpddsd->dwFlags);
1788 fprintf(stderr,"caps ");
1789 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1790 fprintf(stderr,"]\n");
1793 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1794 this->lpvtbl->fnAddRef(this);
1796 (*lpdsf)->ref = 1;
1797 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1798 (*lpdsf)->s.ddraw = this;
1799 (*lpdsf)->s.palette = NULL;
1800 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
1802 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1803 lpddsd->dwWidth = this->d.width;
1804 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1805 lpddsd->dwHeight = this->d.height;
1807 /* Check if this a 'primary surface' or not */
1808 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1809 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1811 /* This is THE primary surface => there is DGA-specific code */
1812 /* First, store the surface description */
1813 (*lpdsf)->s.surface_desc = *lpddsd;
1815 /* Find a viewport */
1816 for (i=0;i<32;i++)
1817 if (!(this->e.dga.vpmask & (1<<i)))
1818 break;
1819 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1820 /* if i == 32 or maximum ... return error */
1821 this->e.dga.vpmask|=(1<<i);
1822 (*lpdsf)->s.surface_desc.y.lpSurface =
1823 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1824 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1825 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
1826 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
1828 /* Add flags if there were not present */
1829 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1830 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1831 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1832 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1833 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1834 (*lpdsf)->s.backbuffer = NULL;
1836 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1837 LPDIRECTDRAWSURFACE3 back;
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));
1844 this->lpvtbl->fnAddRef(this);
1845 back->ref = 1;
1846 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1847 for (i=0;i<32;i++)
1848 if (!(this->e.dga.vpmask & (1<<i)))
1849 break;
1850 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1851 /* if i == 32 or maximum ... return error */
1852 this->e.dga.vpmask|=(1<<i);
1853 back->t.dga.fb_height = i*this->e.dga.fb_height;
1855 /* Copy the surface description from the front buffer */
1856 back->s.surface_desc = (*lpdsf)->s.surface_desc;
1857 /* Change the parameters that are not the same */
1858 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
1859 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1860 back->s.ddraw = this;
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 DGA-specific code here...
1872 Go to the common surface creation function */
1873 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
1876 return DD_OK;
1877 #else /* defined(HAVE_LIBXXF86DGA) */
1878 return E_UNEXPECTED;
1879 #endif /* defined(HAVE_LIBXXF86DGA) */
1882 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
1883 XImage *img;
1885 #ifdef HAVE_LIBXXSHM
1886 if (this->e.xlib.xshm_active) {
1887 img = TSXShmCreateImage(display,
1888 DefaultVisualOfScreen(screen),
1889 this->d.depth,
1890 ZPixmap,
1891 NULL,
1892 &(lpdsf->t.xlib.shminfo),
1893 lpdsf->s.surface_desc.dwWidth,
1894 lpdsf->s.surface_desc.dwHeight);
1896 if (img == NULL)
1897 return NULL;
1899 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
1900 if (lpdsf->t.xlib.shminfo.shmid < 0) {
1901 TSXDestroyImage(img);
1902 return NULL;
1905 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
1907 if (img->data == (char *) -1) {
1908 TSXDestroyImage(img);
1909 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1910 return NULL;
1912 lpdsf->t.xlib.shminfo.readOnly = False;
1914 TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
1915 TSXSync(display, False);
1917 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1919 lpdsf->s.surface_desc.y.lpSurface = img->data;
1920 } else {
1921 #endif
1922 /* Allocate surface memory */
1923 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1924 lpdsf->s.surface_desc.dwWidth *
1925 lpdsf->s.surface_desc.dwHeight *
1926 (this->d.depth / 8));
1928 /* In this case, create an XImage */
1929 img =
1930 TSXCreateImage(display,
1931 DefaultVisualOfScreen(screen),
1932 this->d.depth,
1933 ZPixmap,
1935 lpdsf->s.surface_desc.y.lpSurface,
1936 lpdsf->s.surface_desc.dwWidth,
1937 lpdsf->s.surface_desc.dwHeight,
1939 lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8)
1942 #ifdef HAVE_LIBXXSHM
1944 #endif
1945 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
1947 return img;
1950 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1951 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1953 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1954 this,lpddsd,lpdsf,lpunk);
1956 if (TRACE_ON(ddraw)) {
1957 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1958 _dump_DDSD(lpddsd->dwFlags);
1959 fprintf(stderr,"caps ");
1960 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1961 fprintf(stderr,"]\n");
1964 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1966 this->lpvtbl->fnAddRef(this);
1967 (*lpdsf)->s.ddraw = this;
1968 (*lpdsf)->ref = 1;
1969 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1970 (*lpdsf)->s.palette = NULL;
1971 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
1973 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1974 lpddsd->dwWidth = this->d.width;
1975 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1976 lpddsd->dwHeight = this->d.height;
1978 /* Check if this a 'primary surface' or not */
1979 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1980 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1981 XImage *img;
1983 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
1985 /* First, store the surface description */
1986 (*lpdsf)->s.surface_desc = *lpddsd;
1988 /* Create the XImage */
1989 img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
1990 if (img == NULL)
1991 return DDERR_OUTOFMEMORY;
1992 (*lpdsf)->t.xlib.image = img;
1994 /* Add flags if there were not present */
1995 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1996 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1997 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1998 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1999 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2000 (*lpdsf)->s.backbuffer = NULL;
2002 /* Check for backbuffers */
2003 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2004 LPDIRECTDRAWSURFACE3 back;
2005 XImage *img;
2007 if (lpddsd->dwBackBufferCount>1)
2008 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2010 (*lpdsf)->s.backbuffer = back =
2011 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
2013 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2015 this->lpvtbl->fnAddRef(this);
2016 back->s.ddraw = this;
2018 back->ref = 1;
2019 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
2020 /* Copy the surface description from the front buffer */
2021 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2023 /* Create the XImage */
2024 img = create_ximage(this, back);
2025 if (img == NULL)
2026 return DDERR_OUTOFMEMORY;
2027 back->t.xlib.image = img;
2029 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2030 * one! */
2032 /* Add relevant info to front and back buffers */
2033 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2034 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2035 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2036 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2038 } else {
2039 /* There is no Xlib-specific code here...
2040 Go to the common surface creation function */
2041 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2044 return DD_OK;
2047 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
2048 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2050 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
2051 *dst = src; /* FIXME */
2052 return DD_OK;
2056 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2057 * even when the approbiate bitmasks are not specified.
2059 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
2060 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
2062 int i;
2063 const struct {
2064 int mask;
2065 char *name;
2066 } flagmap[] = {
2067 FE(DDSCL_FULLSCREEN)
2068 FE(DDSCL_ALLOWREBOOT)
2069 FE(DDSCL_NOWINDOWCHANGES)
2070 FE(DDSCL_NORMAL)
2071 FE(DDSCL_ALLOWMODEX)
2072 FE(DDSCL_EXCLUSIVE)
2073 FE(DDSCL_SETFOCUSWINDOW)
2074 FE(DDSCL_SETDEVICEWINDOW)
2075 FE(DDSCL_CREATEDEVICEWINDOW)
2078 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
2079 if(TRACE_ON(ddraw)){
2080 dbg_decl_str(ddraw, 512);
2081 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2082 if (flagmap[i].mask & cooplevel)
2083 dsprintf(ddraw, "%s ", flagmap[i].name);
2084 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2086 this->d.mainWindow = hwnd;
2087 return DD_OK;
2090 /* Small helper to either use the cooperative window or create a new
2091 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2093 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
2094 RECT32 rect;
2096 /* Do not destroy the application supplied cooperative window */
2097 if (this->d.window && this->d.window != this->d.mainWindow) {
2098 DestroyWindow32(this->d.window);
2099 this->d.window = 0;
2101 /* Sanity check cooperative window before assigning it to drawing. */
2102 if ( IsWindow32(this->d.mainWindow) &&
2103 IsWindowVisible32(this->d.mainWindow)
2105 GetWindowRect32(this->d.mainWindow,&rect);
2106 if (((rect.right-rect.left) >= this->d.width) &&
2107 ((rect.bottom-rect.top) >= this->d.height)
2109 this->d.window = this->d.mainWindow;
2111 /* ... failed, create new one. */
2112 if (!this->d.window) {
2113 this->d.window = CreateWindowEx32A(
2115 "WINE_DirectDraw",
2116 "WINE_DirectDraw",
2117 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2118 0,0,
2119 this->d.width,
2120 this->d.height,
2124 NULL
2126 /*Store THIS with the window. We'll use it in the window procedure*/
2127 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
2128 ShowWindow32(this->d.window,TRUE);
2129 UpdateWindow32(this->d.window);
2131 SetFocus32(this->d.window);
2134 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
2135 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2137 #ifdef HAVE_LIBXXF86DGA
2138 int i,*depths,depcount,mode_count;
2140 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2142 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2143 for (i=0;i<depcount;i++)
2144 if (depths[i]==depth)
2145 break;
2146 TSXFree(depths);
2147 if (i==depcount) {/* not found */
2148 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2149 return DDERR_UNSUPPORTEDMODE;
2151 if (this->d.width < width) {
2152 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2153 return DDERR_UNSUPPORTEDMODE;
2155 this->d.width = width;
2156 this->d.height = height;
2157 this->d.depth = depth;
2159 /* adjust fb_height, so we don't overlap */
2160 if (this->e.dga.fb_height < height)
2161 this->e.dga.fb_height = height;
2162 _common_IDirectDraw_SetDisplayMode(this);
2164 #ifdef HAVE_LIBXXF86VM
2166 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2167 XF86VidModeModeLine mod_tmp;
2168 int dotclock_tmp;
2170 /* save original video mode and set fullscreen if available*/
2171 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2172 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2173 orig_mode->hdisplay = mod_tmp.hdisplay;
2174 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2175 orig_mode->hsyncend = mod_tmp.hsyncend;
2176 orig_mode->htotal = mod_tmp.htotal;
2177 orig_mode->vdisplay = mod_tmp.vdisplay;
2178 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2179 orig_mode->vsyncend = mod_tmp.vsyncend;
2180 orig_mode->vtotal = mod_tmp.vtotal;
2181 orig_mode->flags = mod_tmp.flags;
2182 orig_mode->private = mod_tmp.private;
2184 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2185 for (i=0;i<mode_count;i++)
2187 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2189 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2190 *vidmode = *(all_modes[i]);
2191 break;
2192 } else
2193 TSXFree(all_modes[i]->private);
2195 TSXFree(all_modes);
2197 if (!vidmode)
2198 WARN(ddraw, "Fullscreen mode not available!\n");
2200 if (vidmode)
2202 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2203 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2206 #endif
2208 /* FIXME: this function OVERWRITES several signal handlers.
2209 * can we save them? and restore them later? In a way that
2210 * it works for the library too?
2212 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2213 #ifdef DIABLO_HACK
2214 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2215 #endif
2217 #ifdef RESTORE_SIGNALS
2218 SIGNAL_InitEmulator();
2219 #endif
2220 return DD_OK;
2221 #else /* defined(HAVE_LIBXXF86DGA) */
2222 return E_UNEXPECTED;
2223 #endif /* defined(HAVE_LIBXXF86DGA) */
2226 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2227 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2229 int i,*depths,depcount;
2230 char buf[200];
2232 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2233 this, width, height, depth);
2235 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2236 for (i=0;i<depcount;i++)
2237 if (depths[i]==depth)
2238 break;
2239 TSXFree(depths);
2240 if (i==depcount) {/* not found */
2241 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2242 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2243 return DDERR_UNSUPPORTEDMODE;
2245 this->d.width = width;
2246 this->d.height = height;
2247 this->d.depth = depth;
2249 _common_IDirectDraw_SetDisplayMode(this);
2251 this->e.xlib.paintable = 1;
2252 this->e.xlib.drawable = WIN_FindWndPtr(this->d.window)->window;
2253 /* We don't have a context for this window. Host off the desktop */
2254 if( !this->e.xlib.drawable )
2255 this->e.xlib.drawable = WIN_GetDesktop()->window;
2256 return DD_OK;
2259 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2260 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2262 #ifdef HAVE_LIBXXF86DGA
2263 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2264 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2265 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2266 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2267 if (caps2) {
2268 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2269 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2270 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2272 return DD_OK;
2273 #else /* defined(HAVE_LIBXXF86DGA) */
2274 return E_UNEXPECTED;
2275 #endif /* defined(HAVE_LIBXXF86DGA) */
2278 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2279 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2281 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2282 /* FIXME: Xlib */
2283 caps1->dwVidMemTotal = 2048*1024;
2284 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2285 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2286 if (caps2) {
2287 caps2->dwVidMemTotal = 2048*1024;
2288 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2289 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2291 /* END FIXME: Xlib */
2292 return DD_OK;
2295 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2296 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2298 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2299 this,x,lpddclip,lpunk
2301 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2302 (*lpddclip)->ref = 1;
2303 (*lpddclip)->lpvtbl = &ddclipvt;
2304 return DD_OK;
2307 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2308 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2310 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2311 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2312 (*lpddpal)->ref = 1;
2313 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2314 (*lpddpal)->installed = 0;
2315 if (this->d.depth<=8) {
2316 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
2317 } else {
2318 /* we don't want palettes in hicolor or truecolor */
2319 (*lpddpal)->cm = 0;
2322 if (palent)
2324 /* Initialize the palette based on the passed palent struct */
2325 FIXME(ddraw,"needs to handle palent (%p)\n",palent);
2328 return DD_OK;
2331 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2332 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2334 HRESULT res;
2335 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2336 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
2337 if (res != 0) return res;
2338 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2339 return DD_OK;
2342 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2343 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2345 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2346 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2348 if (*lpddpal == NULL)
2349 return E_OUTOFMEMORY;
2351 (*lpddpal)->ref = 1;
2352 (*lpddpal)->installed = 0;
2353 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2355 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2356 this->lpvtbl->fnAddRef(this);
2358 if (palent)
2359 FIXME(ddraw,"needs to handle palent (%p)\n",palent);
2361 return DD_OK;
2364 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2365 #ifdef HAVE_LIBXXF86DGA
2366 TRACE(ddraw, "(%p)->()\n",this);
2367 Sleep(1000);
2368 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2369 #ifdef RESTORE_SIGNALS
2370 SIGNAL_InitEmulator();
2371 #endif
2372 return 0;
2373 #else /* defined(HAVE_LIBXXF86DGA) */
2374 return E_UNEXPECTED;
2375 #endif
2378 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2379 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
2380 Sleep(1000);
2381 return DD_OK;
2384 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
2385 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
2387 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
2388 return DD_OK;
2391 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
2392 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2394 return ++(this->ref);
2397 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2398 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2400 #ifdef HAVE_LIBXXF86DGA
2401 if (!--(this->ref)) {
2402 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2404 #ifdef HAVE_LIBXXF86VM
2405 if (orig_mode)
2406 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), orig_mode);
2407 if (orig_mode->privsize)
2408 TSXFree(orig_mode->private);
2409 free(orig_mode);
2410 orig_mode = NULL;
2411 #endif
2413 #ifdef RESTORE_SIGNALS
2414 SIGNAL_InitEmulator();
2415 #endif
2416 HeapFree(GetProcessHeap(),0,this);
2417 return 0;
2419 #endif /* defined(HAVE_LIBXXF86DGA) */
2420 return this->ref;
2423 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2424 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2426 if (!--(this->ref)) {
2427 HeapFree(GetProcessHeap(),0,this);
2428 return 0;
2430 /* FIXME: destroy window ... */
2431 return this->ref;
2434 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
2435 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2437 char xrefiid[50];
2439 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2440 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2441 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2442 *obj = this;
2443 this->lpvtbl->fnAddRef(this);
2444 return S_OK;
2446 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2447 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
2448 this->lpvtbl->fnAddRef(this);
2449 *obj = this;
2450 return S_OK;
2452 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2453 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
2454 this->lpvtbl->fnAddRef(this);
2455 *obj = this;
2456 return S_OK;
2458 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2459 LPDIRECT3D d3d;
2461 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2462 d3d->ref = 1;
2463 d3d->ddraw = (LPDIRECTDRAW)this;
2464 this->lpvtbl->fnAddRef(this);
2465 d3d->lpvtbl = &d3dvt;
2466 *obj = d3d;
2467 return S_OK;
2469 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2470 LPDIRECT3D2 d3d;
2472 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2473 d3d->ref = 1;
2474 d3d->ddraw = (LPDIRECTDRAW)this;
2475 this->lpvtbl->fnAddRef(this);
2476 d3d->lpvtbl = &d3d2vt;
2477 *obj = d3d;
2478 return S_OK;
2480 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2481 return OLE_E_ENUM_NOMORE;
2484 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
2485 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2487 char xrefiid[50];
2489 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2490 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2491 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2492 *obj = this;
2493 this->lpvtbl->fnAddRef(this);
2494 return S_OK;
2496 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2497 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2498 this->lpvtbl->fnAddRef(this);
2499 *obj = this;
2500 return S_OK;
2502 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2503 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2504 this->lpvtbl->fnAddRef(this);
2505 *obj = this;
2506 return S_OK;
2508 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2509 LPDIRECT3D d3d;
2511 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2512 d3d->ref = 1;
2513 d3d->ddraw = (LPDIRECTDRAW)this;
2514 this->lpvtbl->fnAddRef(this);
2515 d3d->lpvtbl = &d3dvt;
2516 *obj = d3d;
2517 return S_OK;
2519 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2520 LPDIRECT3D2 d3d;
2522 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2523 d3d->ref = 1;
2524 d3d->ddraw = (LPDIRECTDRAW)this;
2525 this->lpvtbl->fnAddRef(this);
2526 d3d->lpvtbl = &d3d2vt;
2527 *obj = d3d;
2528 return S_OK;
2530 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2531 return OLE_E_ENUM_NOMORE;
2534 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2535 LPDIRECTDRAW2 this,BOOL32 *status
2537 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2538 *status = TRUE;
2539 return DD_OK;
2542 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2543 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2545 DDSURFACEDESC ddsfd;
2546 static struct {
2547 int w,h;
2548 } modes[5] = { /* some of the usual modes */
2549 {512,384},
2550 {640,400},
2551 {640,480},
2552 {800,600},
2553 {1024,768},
2555 static int depths[4] = {8,16,24,32};
2556 int i,j;
2558 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2559 ddsfd.dwSize = sizeof(ddsfd);
2560 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2561 if (dwFlags & DDEDM_REFRESHRATES) {
2562 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2563 ddsfd.x.dwRefreshRate = 60;
2566 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2567 ddsfd.dwBackBufferCount = 1;
2568 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2569 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2570 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2571 /* FIXME: those masks would have to be set in depth > 8 */
2572 if (depths[i]==8) {
2573 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2574 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2575 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2576 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2577 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2578 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2579 } else {
2580 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2582 /* FIXME: We should query those from X itself */
2583 switch (depths[i]) {
2584 case 16:
2585 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2586 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2587 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2588 break;
2589 case 24:
2590 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2591 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2592 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2593 break;
2594 case 32:
2595 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2596 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2597 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2598 break;
2602 ddsfd.dwWidth = screenWidth;
2603 ddsfd.dwHeight = screenHeight;
2604 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2605 if (!modescb(&ddsfd,context)) return DD_OK;
2607 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2608 ddsfd.dwWidth = modes[j].w;
2609 ddsfd.dwHeight = modes[j].h;
2610 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2611 if (!modescb(&ddsfd,context)) return DD_OK;
2614 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2615 /* modeX is not standard VGA */
2617 ddsfd.dwHeight = 200;
2618 ddsfd.dwWidth = 320;
2619 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2620 if (!modescb(&ddsfd,context)) return DD_OK;
2623 return DD_OK;
2626 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2627 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2629 #ifdef HAVE_LIBXXF86DGA
2630 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2631 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2632 lpddsfd->dwHeight = screenHeight;
2633 lpddsfd->dwWidth = screenWidth;
2634 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2635 lpddsfd->dwBackBufferCount = 1;
2636 lpddsfd->x.dwRefreshRate = 60;
2637 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2638 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2639 return DD_OK;
2640 #else /* defined(HAVE_LIBXXF86DGA) */
2641 return E_UNEXPECTED;
2642 #endif /* defined(HAVE_LIBXXF86DGA) */
2645 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2646 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2648 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2649 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2650 lpddsfd->dwHeight = screenHeight;
2651 lpddsfd->dwWidth = screenWidth;
2652 /* POOLE FIXME: Xlib */
2653 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2654 /* END FIXME: Xlib */
2655 lpddsfd->dwBackBufferCount = 1;
2656 lpddsfd->x.dwRefreshRate = 60;
2657 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2658 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2659 return DD_OK;
2662 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2663 TRACE(ddraw,"(%p)->()\n",this);
2664 return DD_OK;
2667 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2668 LPDIRECTDRAW2 this,LPDWORD freq
2670 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2671 *freq = 60*100; /* 60 Hz */
2672 return DD_OK;
2675 /* what can we directly decompress? */
2676 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2677 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2679 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2680 return DD_OK;
2683 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2684 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2687 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2689 return DD_OK;
2692 static HRESULT WINAPI IDirectDraw2_Compact(
2693 LPDIRECTDRAW2 this )
2695 FIXME(ddraw,"(%p)->()\n", this );
2697 return DD_OK;
2701 /* Note: Hack so we can reuse the old functions without compiler warnings */
2702 #ifdef __GNUC__
2703 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2704 #else
2705 # define XCAST(fun) (void*)
2706 #endif
2708 static struct IDirectDraw_VTable dga_ddvt = {
2709 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2710 XCAST(AddRef)IDirectDraw2_AddRef,
2711 XCAST(Release)DGA_IDirectDraw2_Release,
2712 XCAST(Compact)IDirectDraw2_Compact,
2713 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2714 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2715 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2716 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2717 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2718 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2719 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2720 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2721 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2722 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2723 XCAST(GetGDISurface)15,
2724 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2725 XCAST(GetScanLine)17,
2726 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2727 XCAST(Initialize)19,
2728 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2729 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2730 DGA_IDirectDraw_SetDisplayMode,
2731 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2734 static struct IDirectDraw_VTable xlib_ddvt = {
2735 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2736 XCAST(AddRef)IDirectDraw2_AddRef,
2737 XCAST(Release)Xlib_IDirectDraw2_Release,
2738 XCAST(Compact)IDirectDraw2_Compact,
2739 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2740 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2741 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2742 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2743 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2744 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2745 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2746 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2747 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2748 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2749 XCAST(GetGDISurface)15,
2750 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2751 XCAST(GetScanLine)17,
2752 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2753 XCAST(Initialize)19,
2754 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2755 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2756 Xlib_IDirectDraw_SetDisplayMode,
2757 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2760 /*****************************************************************************
2761 * IDirectDraw2
2766 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2767 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2769 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2772 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2773 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2775 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2778 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2779 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2781 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2782 this,ddscaps,total,free
2784 if (total) *total = this->e.dga.fb_memsize * 1024;
2785 if (free) *free = this->e.dga.fb_memsize * 1024;
2786 return DD_OK;
2789 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2790 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2792 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2793 this,ddscaps,total,free
2795 if (total) *total = 2048 * 1024;
2796 if (free) *free = 2048 * 1024;
2797 return DD_OK;
2800 static IDirectDraw2_VTable dga_dd2vt = {
2801 DGA_IDirectDraw2_QueryInterface,
2802 IDirectDraw2_AddRef,
2803 DGA_IDirectDraw2_Release,
2804 IDirectDraw2_Compact,
2805 IDirectDraw2_CreateClipper,
2806 DGA_IDirectDraw2_CreatePalette,
2807 DGA_IDirectDraw2_CreateSurface,
2808 (void*)8,
2809 IDirectDraw2_EnumDisplayModes,
2810 IDirectDraw2_EnumSurfaces,
2811 IDirectDraw2_FlipToGDISurface,
2812 DGA_IDirectDraw2_GetCaps,
2813 DGA_IDirectDraw2_GetDisplayMode,
2814 IDirectDraw2_GetFourCCCodes,
2815 (void*)15,
2816 IDirectDraw2_GetMonitorFrequency,
2817 (void*)17,
2818 IDirectDraw2_GetVerticalBlankStatus,
2819 (void*)19,
2820 DGA_IDirectDraw2_RestoreDisplayMode,
2821 IDirectDraw2_SetCooperativeLevel,
2822 DGA_IDirectDraw2_SetDisplayMode,
2823 IDirectDraw2_WaitForVerticalBlank,
2824 DGA_IDirectDraw2_GetAvailableVidMem
2827 static struct IDirectDraw2_VTable xlib_dd2vt = {
2828 Xlib_IDirectDraw2_QueryInterface,
2829 IDirectDraw2_AddRef,
2830 Xlib_IDirectDraw2_Release,
2831 IDirectDraw2_Compact,
2832 IDirectDraw2_CreateClipper,
2833 Xlib_IDirectDraw2_CreatePalette,
2834 Xlib_IDirectDraw2_CreateSurface,
2835 (void*)8,
2836 IDirectDraw2_EnumDisplayModes,
2837 IDirectDraw2_EnumSurfaces,
2838 IDirectDraw2_FlipToGDISurface,
2839 Xlib_IDirectDraw2_GetCaps,
2840 Xlib_IDirectDraw2_GetDisplayMode,
2841 IDirectDraw2_GetFourCCCodes,
2842 (void*)15,
2843 IDirectDraw2_GetMonitorFrequency,
2844 (void*)17,
2845 IDirectDraw2_GetVerticalBlankStatus,
2846 (void*)19,
2847 Xlib_IDirectDraw2_RestoreDisplayMode,
2848 IDirectDraw2_SetCooperativeLevel,
2849 Xlib_IDirectDraw2_SetDisplayMode,
2850 IDirectDraw2_WaitForVerticalBlank,
2851 Xlib_IDirectDraw2_GetAvailableVidMem
2854 /******************************************************************************
2855 * DirectDrawCreate
2858 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2860 LRESULT ret;
2861 LPDIRECTDRAW ddraw = NULL;
2862 DWORD lastError;
2864 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2866 SetLastError( ERROR_SUCCESS );
2867 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2868 if( (!ddraw) &&
2869 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2872 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2875 if( ddraw )
2877 /* Perform any special direct draw functions */
2878 if (msg==WM_PAINT)
2879 ddraw->e.xlib.paintable = 1;
2881 /* Now let the application deal with the rest of this */
2882 if( ddraw->d.mainWindow )
2885 /* Don't think that we actually need to call this but...
2886 might as well be on the safe side of things... */
2888 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
2889 it should be the procedures of our fake window that gets called
2890 instead of those of the window provided by the application.
2891 And with this patch, mouse clicks work with Monkey Island III
2892 - Lionel */
2893 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2895 if( !ret )
2897 /* We didn't handle the message - give it to the application */
2898 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
2899 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2900 ddraw->d.mainWindow, msg, wParam, lParam );
2904 } else {
2905 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
2909 else
2911 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2914 return ret;
2917 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2918 #ifdef HAVE_LIBXXF86DGA
2919 int memsize,banksize,width,major,minor,flags,height;
2920 char *addr;
2921 int fd;
2923 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
2924 if ((fd = open("/dev/mem", O_RDWR)) != -1)
2925 close(fd);
2927 if (fd == -1) {
2928 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
2929 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2930 return E_UNEXPECTED;
2932 if (!DDRAW_DGA_Available()) {
2933 TRACE(ddraw,"No XF86DGA detected.\n");
2934 return DDERR_GENERIC;
2936 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2937 (*lplpDD)->lpvtbl = &dga_ddvt;
2938 (*lplpDD)->ref = 1;
2939 TSXF86DGAQueryVersion(display,&major,&minor);
2940 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2941 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2942 if (!(flags & XF86DGADirectPresent))
2943 MSG("direct video is NOT PRESENT.\n");
2944 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2945 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2946 addr,width,banksize,memsize
2948 (*lplpDD)->e.dga.fb_width = width;
2949 (*lplpDD)->d.width = width;
2950 (*lplpDD)->e.dga.fb_addr = addr;
2951 (*lplpDD)->e.dga.fb_memsize = memsize;
2952 (*lplpDD)->e.dga.fb_banksize = banksize;
2954 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2955 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2956 (*lplpDD)->e.dga.fb_height = screenHeight;
2957 #ifdef DIABLO_HACK
2958 (*lplpDD)->e.dga.vpmask = 1;
2959 #else
2960 (*lplpDD)->e.dga.vpmask = 0;
2961 #endif
2963 /* just assume the default depth is the DGA depth too */
2964 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2965 #ifdef RESTORE_SIGNALS
2966 SIGNAL_InitEmulator();
2967 #endif
2969 return DD_OK;
2970 #else /* defined(HAVE_LIBXXF86DGA) */
2971 return DDERR_INVALIDDIRECTDRAWGUID;
2972 #endif /* defined(HAVE_LIBXXF86DGA) */
2975 BOOL32
2976 DDRAW_XSHM_Available()
2978 #ifdef HAVE_LIBXXSHM
2979 if (TSXShmQueryExtension(display))
2981 int major, minor;
2982 Bool shpix;
2984 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
2985 return 1;
2986 else
2987 return 0;
2989 else
2990 return 0;
2991 #else
2992 return 0;
2993 #endif
2996 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2998 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2999 (*lplpDD)->lpvtbl = &xlib_ddvt;
3000 (*lplpDD)->ref = 1;
3001 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
3003 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
3004 (*lplpDD)->d.height = screenHeight;
3005 (*lplpDD)->d.width = screenWidth;
3007 #ifdef HAVE_LIBXXSHM
3008 /* Test if XShm is available.
3009 As XShm is not ready yet for 'prime-time', it is disabled for now */
3010 if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
3011 TRACE(ddraw, "Using XShm extesion.\n");
3012 #endif
3014 return DD_OK;
3017 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
3018 char xclsid[50];
3019 WNDCLASS32A wc;
3020 WND* pParentWindow;
3021 HRESULT ret;
3023 if (HIWORD(lpGUID))
3024 WINE_StringFromCLSID(lpGUID,xclsid);
3025 else {
3026 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
3027 lpGUID = NULL;
3030 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
3032 if (!lpGUID) {
3033 /* if they didn't request a particular interface, use the best
3034 * supported one */
3035 if (DDRAW_DGA_Available())
3036 lpGUID = &DGA_DirectDraw_GUID;
3037 else
3038 lpGUID = &XLIB_DirectDraw_GUID;
3041 wc.style = CS_GLOBALCLASS;
3042 wc.lpfnWndProc = Xlib_DDWndProc;
3043 wc.cbClsExtra = 0;
3044 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
3045 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
3047 /* We can be a child of the desktop since we're really important */
3048 pParentWindow = WIN_GetDesktop();
3049 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
3050 wc.hInstance = 0;
3052 wc.hIcon = 0;
3053 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
3054 wc.hbrBackground= NULL_BRUSH;
3055 wc.lpszMenuName = 0;
3056 wc.lpszClassName= "WINE_DirectDraw";
3057 RegisterClass32A(&wc);
3059 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
3060 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
3061 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
3062 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
3063 else
3064 goto err;
3066 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
3067 return ret;
3069 err:
3070 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
3071 return DDERR_INVALIDDIRECTDRAWGUID;