Stubs for IDirect3D(2)::CreateLight and CreateDevice to avoid crashes.
[wine/multimedia.git] / graphics / ddraw.c
blob6ad5f8e7e21ce0307f91fb9fc729862d7f9e75ec
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 0;
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 0;
397 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
398 LPDIRECTDRAWSURFACE3 this,LPVOID surface
400 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
401 return 0;
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 0;
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 0;
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 0;
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)->SetPalette(%p)\n",this,pal);
539 if (!(pal->cm) && (this->s.ddraw->d.depth<=8)) {
540 pal->cm = TSXCreateColormap(display,this->s.ddraw->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
541 /* FIXME: this is not correct, when using -managed */
542 TSXInstallColormap(display,pal->cm);
543 for (i=0;i<256;i++) {
544 XColor xc;
546 xc.red = pal->palents[i].peRed<<8;
547 xc.blue = pal->palents[i].peBlue<<8;
548 xc.green = pal->palents[i].peGreen<<8;
549 xc.flags = DoRed|DoBlue|DoGreen;
550 xc.pixel = i;
551 TSXStoreColor(display,pal->cm,&xc);
554 /* According to spec, we are only supposed to
555 * AddRef if this is not the same palette.
557 if( this->s.palette != pal )
559 if( pal != NULL )
560 pal->lpvtbl->fnAddRef( pal );
561 if( this->s.palette != NULL )
562 this->s.palette->lpvtbl->fnRelease( this->s.palette );
563 this->s.palette = pal;
565 /* I think that we need to attach it to all backbuffers...*/
566 if( this->s.backbuffer ) {
567 if( this->s.backbuffer->s.palette )
568 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
569 this->s.backbuffer->s.palette );
570 this->s.backbuffer->s.palette = pal;
571 if( pal )
572 pal->lpvtbl->fnAddRef( pal );
574 /* Perform the refresh */
575 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
577 return 0;
580 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
581 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
583 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
584 #ifdef HAVE_LIBXXF86DGA
585 /* According to spec, we are only supposed to
586 * AddRef if this is not the same palette.
588 if( this->s.palette != pal )
590 if( pal != NULL )
591 pal->lpvtbl->fnAddRef( pal );
592 if( this->s.palette != NULL )
593 this->s.palette->lpvtbl->fnRelease( this->s.palette );
594 this->s.palette = pal;
596 /* I think that we need to attach it to all backbuffers...*/
597 if( this->s.backbuffer ) {
598 if( this->s.backbuffer->s.palette )
599 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
600 this->s.backbuffer->s.palette = pal;
601 if( pal ) pal->lpvtbl->fnAddRef( pal );
603 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
605 return 0;
606 #else /* defined(HAVE_LIBXXF86DGA) */
607 return E_UNEXPECTED;
608 #endif /* defined(HAVE_LIBXXF86DGA) */
613 static HRESULT WINAPI IDirectDrawSurface3_Blt(
614 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
616 RECT32 xdst,xsrc;
617 DDSURFACEDESC ddesc,sdesc;
618 int i,j;
620 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
621 this,rdst,src,rsrc,dwFlags,lpbltfx);
623 if (src != NULL)
624 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
625 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
627 if (TRACE_ON(ddraw)) {
628 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
629 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
630 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
631 if (dwFlags & DDBLT_DDFX) {
632 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
636 if (rdst) {
637 memcpy(&xdst,rdst,sizeof(xdst));
638 } else {
639 xdst.top = 0;
640 xdst.bottom = ddesc.dwHeight;
641 xdst.left = 0;
642 xdst.right = ddesc.dwWidth;
645 if (rsrc) {
646 memcpy(&xsrc,rsrc,sizeof(xsrc));
647 } else {
648 if (src) {
649 xsrc.top = 0;
650 xsrc.bottom = sdesc.dwHeight;
651 xsrc.left = 0;
652 xsrc.right = sdesc.dwWidth;
653 } else {
654 memset(&xsrc,0,sizeof(xsrc));
658 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
660 if (dwFlags & DDBLT_COLORFILL) {
661 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
662 LPBYTE xline,xpixel;
664 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
665 for (i=xdst.top;i<xdst.bottom;i++) {
666 xpixel = xline+bpp*xdst.left;
668 for (j=xdst.left;j<xdst.right;j++) {
669 /* FIXME: this only works on little endian
670 * architectures, where DWORD starts with low
671 * byte first!
673 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
674 xpixel += bpp;
676 xline += ddesc.lPitch;
678 dwFlags &= ~(DDBLT_COLORFILL);
681 if (!src) {
682 if (dwFlags) {
683 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
685 return 0;
688 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
689 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
690 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
691 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
692 !dwFlags
694 memcpy(ddesc.y.lpSurface,
695 sdesc.y.lpSurface,
696 ddesc.dwHeight * ddesc.lPitch);
697 } else {
698 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
699 int height = xsrc.bottom - xsrc.top;
700 int width = (xsrc.right - xsrc.left) * bpp;
701 int h;
703 for (h = 0; h < height; h++) {
704 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
705 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
706 width);
710 if (dwFlags && FIXME_ON(ddraw)) {
711 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
714 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
715 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
717 return 0;
720 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
721 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
723 int i,bpp;
724 DDSURFACEDESC ddesc,sdesc;
726 if (TRACE_ON(ddraw)) {
727 TRACE(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
728 this,dstx,dsty,src,rsrc,trans
730 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
731 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
733 /* We need to lock the surfaces, or we won't get refreshes when done. */
734 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
735 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
736 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
737 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
738 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
739 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
740 (rsrc->right-rsrc->left)*bpp
743 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
744 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
745 return 0;
748 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
749 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
751 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
752 this,ddbltbatch,x,y
754 return 0;
757 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
758 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
760 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
761 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
762 return 0;
765 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
766 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
767 ) {
768 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
769 this,ddsd);
771 /* Simply copy the surface description stored in the object */
772 *ddsd = this->s.surface_desc;
774 if (TRACE_ON(ddraw)) {
775 fprintf(stderr," flags: ");
776 _dump_DDSD(ddsd->dwFlags);
777 if (ddsd->dwFlags & DDSD_CAPS) {
778 fprintf(stderr, " caps: ");
779 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
781 fprintf(stderr,"\n");
784 return 0;
787 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
788 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
790 return ++(this->ref);
793 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
794 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
796 #ifdef HAVE_LIBXXF86DGA
797 if (!--(this->ref)) {
798 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
799 /* clear out of surface list */
800 if (this->t.dga.fb_height == -1) {
801 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
802 } else {
803 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
805 HeapFree(GetProcessHeap(),0,this);
806 return 0;
808 #endif /* defined(HAVE_LIBXXF86DGA) */
809 return this->ref;
812 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
813 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
815 if (!--(this->ref)) {
816 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
818 if( this->s.backbuffer )
819 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
821 if (this->t.xlib.image != NULL) {
822 this->t.xlib.image->data = NULL;
824 #ifdef HAVE_LIBXXSHM
825 if (this->s.ddraw->e.xlib.xshm_active) {
826 TSXShmDetach(display, &(this->t.xlib.shminfo));
827 TSXDestroyImage(this->t.xlib.image);
828 shmdt(this->t.xlib.shminfo.shmaddr);
829 } else {
830 #endif
831 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
832 TSXDestroyImage(this->t.xlib.image);
833 #ifdef HAVE_LIBXXSHM
835 #endif
837 this->t.xlib.image = 0;
838 } else {
839 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
842 if (this->s.palette)
843 this->s.palette->lpvtbl->fnRelease(this->s.palette);
845 HeapFree(GetProcessHeap(),0,this);
846 return 0;
849 return this->ref;
852 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
853 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
855 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
856 this, lpddsd, lpdsf);
858 if (TRACE_ON(ddraw)) {
859 TRACE(ddraw," caps ");
860 _dump_DDSCAPS(lpddsd->dwCaps);
863 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
864 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
865 return E_FAIL;
868 /* FIXME: should handle more than one backbuffer */
869 *lpdsf = this->s.backbuffer;
871 if( this->s.backbuffer )
872 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
874 return 0;
877 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
878 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
880 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
882 return DDERR_ALREADYINITIALIZED;
885 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
886 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
888 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
890 *pf = this->s.surface_desc.ddpfPixelFormat;
892 return 0;
895 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
896 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
897 return 0;
900 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
901 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
903 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
904 return 0;
907 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
908 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
910 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
911 return 0;
914 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
915 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
917 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
919 /* This hack will be enough for the moment */
920 if (this->s.backbuffer == NULL)
921 this->s.backbuffer = surf;
922 return 0;
925 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
926 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
927 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
928 return 0;
931 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
932 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
933 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
934 return 0;
938 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
939 char xrefiid[50];
941 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
942 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
944 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
945 * the same interface. And IUnknown does that too of course.
947 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
948 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
949 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
950 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
952 *obj = this;
953 this->lpvtbl->fnAddRef(this);
954 return 0;
956 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
957 return OLE_E_ENUM_NOMORE;
960 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
961 TRACE(ddraw,"(%p)->(), stub!\n",this);
962 return 0; /* hmm */
965 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
966 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
967 return 0;
970 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
971 FIXME(ddraw,"(%p)->(),stub!\n",this);
972 return 0;
975 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
976 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
978 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
980 if( dwFlags & DDCKEY_SRCBLT )
981 dwFlags &= ~DDCKEY_SRCBLT;
982 if( dwFlags )
983 TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
984 return DD_OK;
987 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
988 LPDIRECTDRAWSURFACE3 this,
989 LPRECT32 lpRect )
991 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
993 return DD_OK;
996 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
997 LPDIRECTDRAWSURFACE3 this,
998 DWORD dwFlags,
999 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
1001 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1003 return DD_OK;
1006 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
1007 LPDIRECTDRAWSURFACE3 this,
1008 DWORD dwFlags,
1009 LPVOID lpContext,
1010 LPDDENUMSURFACESCALLBACK lpfnCallback )
1012 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1013 lpContext, lpfnCallback );
1015 return DD_OK;
1018 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
1019 LPDIRECTDRAWSURFACE3 this,
1020 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1022 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1024 return DD_OK;
1027 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
1028 LPDIRECTDRAWSURFACE3 this,
1029 DWORD dwFlags,
1030 LPDDCOLORKEY lpDDColorKey )
1032 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDColorKey);
1034 return DD_OK;
1037 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
1038 LPDIRECTDRAWSURFACE3 this,
1039 DWORD dwFlags )
1041 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1043 return DD_OK;
1046 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
1047 LPDIRECTDRAWSURFACE3 this,
1048 LPDIRECTDRAWPALETTE* lplpDDPalette )
1050 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1052 return DD_OK;
1055 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
1056 LPDIRECTDRAWSURFACE3 this,
1057 LONG lX,
1058 LONG lY)
1060 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1062 return DD_OK;
1065 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
1066 LPDIRECTDRAWSURFACE3 this,
1067 LPRECT32 lpSrcRect,
1068 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
1069 LPRECT32 lpDestRect,
1070 DWORD dwFlags,
1071 LPDDOVERLAYFX lpDDOverlayFx )
1073 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1074 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1076 return DD_OK;
1079 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
1080 LPDIRECTDRAWSURFACE3 this,
1081 DWORD dwFlags )
1083 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1085 return DD_OK;
1088 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
1089 LPDIRECTDRAWSURFACE3 this,
1090 DWORD dwFlags,
1091 LPDIRECTDRAWSURFACE3 lpDDSReference )
1093 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1095 return DD_OK;
1098 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
1099 LPDIRECTDRAWSURFACE3 this,
1100 LPVOID* lplpDD )
1102 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1104 return DD_OK;
1107 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
1108 LPDIRECTDRAWSURFACE3 this,
1109 DWORD dwFlags )
1111 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1113 return DD_OK;
1116 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
1117 LPDIRECTDRAWSURFACE3 this,
1118 DWORD dwFlags )
1120 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1122 return DD_OK;
1125 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1126 LPDIRECTDRAWSURFACE3 this,
1127 LPDDSURFACEDESC lpDDSD,
1128 DWORD dwFlags )
1130 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1132 return DD_OK;
1135 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1136 IDirectDrawSurface3_QueryInterface,
1137 IDirectDrawSurface3_AddRef,
1138 DGA_IDirectDrawSurface3_Release,
1139 IDirectDrawSurface3_AddAttachedSurface,
1140 IDirectDrawSurface3_AddOverlayDirtyRect,
1141 IDirectDrawSurface3_Blt,
1142 IDirectDrawSurface3_BltBatch,
1143 IDirectDrawSurface3_BltFast,
1144 IDirectDrawSurface3_DeleteAttachedSurface,
1145 IDirectDrawSurface3_EnumAttachedSurfaces,
1146 IDirectDrawSurface3_EnumOverlayZOrders,
1147 DGA_IDirectDrawSurface3_Flip,
1148 IDirectDrawSurface3_GetAttachedSurface,
1149 IDirectDrawSurface3_GetBltStatus,
1150 IDirectDrawSurface3_GetCaps,
1151 IDirectDrawSurface3_GetClipper,
1152 IDirectDrawSurface3_GetColorKey,
1153 IDirectDrawSurface3_GetDC,
1154 IDirectDrawSurface3_GetFlipStatus,
1155 IDirectDrawSurface3_GetOverlayPosition,
1156 IDirectDrawSurface3_GetPalette,
1157 IDirectDrawSurface3_GetPixelFormat,
1158 IDirectDrawSurface3_GetSurfaceDesc,
1159 IDirectDrawSurface3_Initialize,
1160 IDirectDrawSurface3_IsLost,
1161 IDirectDrawSurface3_Lock,
1162 IDirectDrawSurface3_ReleaseDC,
1163 IDirectDrawSurface3_Restore,
1164 IDirectDrawSurface3_SetClipper,
1165 IDirectDrawSurface3_SetColorKey,
1166 IDirectDrawSurface3_SetOverlayPosition,
1167 DGA_IDirectDrawSurface3_SetPalette,
1168 DGA_IDirectDrawSurface3_Unlock,
1169 IDirectDrawSurface3_UpdateOverlay,
1170 IDirectDrawSurface3_UpdateOverlayDisplay,
1171 IDirectDrawSurface3_UpdateOverlayZOrder,
1172 IDirectDrawSurface3_GetDDInterface,
1173 IDirectDrawSurface3_PageLock,
1174 IDirectDrawSurface3_PageUnlock,
1175 IDirectDrawSurface3_SetSurfaceDesc,
1178 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1179 IDirectDrawSurface3_QueryInterface,
1180 IDirectDrawSurface3_AddRef,
1181 Xlib_IDirectDrawSurface3_Release,
1182 IDirectDrawSurface3_AddAttachedSurface,
1183 IDirectDrawSurface3_AddOverlayDirtyRect,
1184 IDirectDrawSurface3_Blt,
1185 IDirectDrawSurface3_BltBatch,
1186 IDirectDrawSurface3_BltFast,
1187 IDirectDrawSurface3_DeleteAttachedSurface,
1188 IDirectDrawSurface3_EnumAttachedSurfaces,
1189 IDirectDrawSurface3_EnumOverlayZOrders,
1190 Xlib_IDirectDrawSurface3_Flip,
1191 IDirectDrawSurface3_GetAttachedSurface,
1192 IDirectDrawSurface3_GetBltStatus,
1193 IDirectDrawSurface3_GetCaps,
1194 IDirectDrawSurface3_GetClipper,
1195 IDirectDrawSurface3_GetColorKey,
1196 IDirectDrawSurface3_GetDC,
1197 IDirectDrawSurface3_GetFlipStatus,
1198 IDirectDrawSurface3_GetOverlayPosition,
1199 IDirectDrawSurface3_GetPalette,
1200 IDirectDrawSurface3_GetPixelFormat,
1201 IDirectDrawSurface3_GetSurfaceDesc,
1202 IDirectDrawSurface3_Initialize,
1203 IDirectDrawSurface3_IsLost,
1204 IDirectDrawSurface3_Lock,
1205 IDirectDrawSurface3_ReleaseDC,
1206 IDirectDrawSurface3_Restore,
1207 IDirectDrawSurface3_SetClipper,
1208 IDirectDrawSurface3_SetColorKey,
1209 IDirectDrawSurface3_SetOverlayPosition,
1210 Xlib_IDirectDrawSurface3_SetPalette,
1211 Xlib_IDirectDrawSurface3_Unlock,
1212 IDirectDrawSurface3_UpdateOverlay,
1213 IDirectDrawSurface3_UpdateOverlayDisplay,
1214 IDirectDrawSurface3_UpdateOverlayZOrder,
1215 IDirectDrawSurface3_GetDDInterface,
1216 IDirectDrawSurface3_PageLock,
1217 IDirectDrawSurface3_PageUnlock,
1218 IDirectDrawSurface3_SetSurfaceDesc,
1221 /******************************************************************************
1222 * DirectDrawCreateClipper (DDRAW.7)
1224 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1225 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1226 LPUNKNOWN pUnkOuter)
1228 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1230 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1231 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1232 (*lplpDDClipper)->ref = 1;
1234 return 0;
1237 /******************************************************************************
1238 * IDirectDrawClipper
1240 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1241 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1243 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1244 return 0;
1247 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1248 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1250 this->ref--;
1251 if (this->ref)
1252 return this->ref;
1253 HeapFree(GetProcessHeap(),0,this);
1254 return 0;
1257 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1258 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1260 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1261 if (hmm) *hmm=0;
1262 return 0;
1265 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1266 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1268 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1269 return 0;
1272 static struct IDirectDrawClipper_VTable ddclipvt = {
1273 (void*)1,
1274 (void*)2,
1275 IDirectDrawClipper_Release,
1276 IDirectDrawClipper_GetClipList,
1277 (void*)5,
1278 (void*)6,
1279 (void*)7,
1280 IDirectDrawClipper_SetClipList,
1281 IDirectDrawClipper_SetHwnd
1284 /******************************************************************************
1285 * IDirectDrawPalette
1287 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1288 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1290 int i;
1292 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1293 this,x,start,count,palent);
1295 if (!this->cm) /* should not happen */ {
1296 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1297 return DDERR_GENERIC;
1299 for (i=0;i<count;i++) {
1300 palent[i].peRed = this->palents[start+i].peRed;
1301 palent[i].peBlue = this->palents[start+i].peBlue;
1302 palent[i].peGreen = this->palents[start+i].peGreen;
1303 palent[i].peFlags = this->palents[start+i].peFlags;
1306 return 0;
1309 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1310 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1312 XColor xc;
1313 int i;
1315 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1316 this,x,start,count,palent
1318 for (i=0;i<count;i++) {
1319 xc.red = palent[i].peRed<<8;
1320 xc.blue = palent[i].peBlue<<8;
1321 xc.green = palent[i].peGreen<<8;
1322 xc.flags = DoRed|DoBlue|DoGreen;
1323 xc.pixel = start+i;
1325 if (this->cm)
1326 TSXStoreColor(display,this->cm,&xc);
1328 this->palents[start+i].peRed = palent[i].peRed;
1329 this->palents[start+i].peBlue = palent[i].peBlue;
1330 this->palents[start+i].peGreen = palent[i].peGreen;
1331 this->palents[start+i].peFlags = palent[i].peFlags;
1333 if (!this->cm) /* should not happen */ {
1335 return 0;
1338 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1339 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1341 #ifdef HAVE_LIBXXF86DGA
1342 XColor xc;
1343 Colormap cm;
1344 int i;
1346 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1347 this,x,start,count,palent
1349 if (!this->cm) /* should not happen */ {
1350 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1351 return DDERR_GENERIC;
1353 /* FIXME: free colorcells instead of freeing whole map */
1354 cm = this->cm;
1355 this->cm = TSXCopyColormapAndFree(display,this->cm);
1356 TSXFreeColormap(display,cm);
1358 for (i=0;i<count;i++) {
1359 xc.red = palent[i].peRed<<8;
1360 xc.blue = palent[i].peBlue<<8;
1361 xc.green = palent[i].peGreen<<8;
1362 xc.flags = DoRed|DoBlue|DoGreen;
1363 xc.pixel = i+start;
1365 TSXStoreColor(display,this->cm,&xc);
1367 this->palents[start+i].peRed = palent[i].peRed;
1368 this->palents[start+i].peBlue = palent[i].peBlue;
1369 this->palents[start+i].peGreen = palent[i].peGreen;
1370 this->palents[start+i].peFlags = palent[i].peFlags;
1372 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1373 return 0;
1374 #else /* defined(HAVE_LIBXXF86DGA) */
1375 return E_UNEXPECTED;
1376 #endif /* defined(HAVE_LIBXXF86DGA) */
1379 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1380 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1381 if (!--(this->ref)) {
1382 if (this->cm) {
1383 TSXFreeColormap(display,this->cm);
1384 this->cm = 0;
1386 HeapFree(GetProcessHeap(),0,this);
1387 return 0;
1389 return this->ref;
1392 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1394 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1395 return ++(this->ref);
1398 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1399 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1401 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1403 return DDERR_ALREADYINITIALIZED;
1406 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1407 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1409 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1410 return DD_OK;
1413 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1414 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1416 char xrefiid[50];
1418 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1419 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1421 return S_OK;
1424 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1425 IDirectDrawPalette_QueryInterface,
1426 IDirectDrawPalette_AddRef,
1427 IDirectDrawPalette_Release,
1428 IDirectDrawPalette_GetCaps,
1429 IDirectDrawPalette_GetEntries,
1430 IDirectDrawPalette_Initialize,
1431 DGA_IDirectDrawPalette_SetEntries
1434 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1435 IDirectDrawPalette_QueryInterface,
1436 IDirectDrawPalette_AddRef,
1437 IDirectDrawPalette_Release,
1438 IDirectDrawPalette_GetCaps,
1439 IDirectDrawPalette_GetEntries,
1440 IDirectDrawPalette_Initialize,
1441 Xlib_IDirectDrawPalette_SetEntries
1444 /*******************************************************************************
1445 * IDirect3D
1447 static HRESULT WINAPI IDirect3D_QueryInterface(
1448 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1450 /* FIXME: Not sure if this is correct */
1451 char xrefiid[50];
1453 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1454 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1455 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1456 *obj = this;
1457 this->lpvtbl->fnAddRef(this);
1458 return 0;
1460 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1461 LPDIRECT3D d3d;
1463 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1464 d3d->ref = 1;
1465 d3d->ddraw = (LPDIRECTDRAW)this;
1466 this->lpvtbl->fnAddRef(this);
1467 d3d->lpvtbl = &d3dvt;
1468 *obj = d3d;
1469 return 0;
1471 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1472 LPDIRECT3D2 d3d;
1474 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1475 d3d->ref = 1;
1476 d3d->ddraw = (LPDIRECTDRAW)this;
1477 this->lpvtbl->fnAddRef(this);
1478 d3d->lpvtbl = &d3d2vt;
1479 *obj = d3d;
1480 return 0;
1482 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1483 return OLE_E_ENUM_NOMORE;
1486 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1487 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1489 return ++(this->ref);
1492 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1494 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1496 if (!--(this->ref)) {
1497 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1498 HeapFree(GetProcessHeap(),0,this);
1499 return 0;
1501 return this->ref;
1504 static HRESULT WINAPI IDirect3D_Initialize(
1505 LPDIRECT3D this, REFIID refiid )
1507 /* FIXME: Not sure if this is correct */
1508 char xrefiid[50];
1510 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1511 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1513 return DDERR_ALREADYINITIALIZED;
1516 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,LPDIRECT3DLIGHT *light,IUnknown* lpunk) {
1517 FIXME(ddraw,"(%p)->(%p,%p)\n",this,light,lpunk);
1518 return E_FAIL;
1521 typedef LPVOID LPDIRECT3DDEVICE;
1523 static HRESULT WINAPI IDirect3D_CreateDevice(LPDIRECT3D this,LPCLSID rclsid,LPDIRECTDRAWSURFACE surf,LPDIRECT3DDEVICE *d3dev) {
1524 char xclsid[50];
1526 WINE_StringFromCLSID(rclsid,xclsid);
1527 FIXME(ddraw,"(%p)->(%s,%p,%p), no Direct3D devices implemented yet!\n",this,xclsid,surf,d3dev);
1528 return E_FAIL; /* D3DERR_INVALID_DEVICE probably */
1531 /*******************************************************************************
1532 * IDirect3D
1534 static struct IDirect3D_VTable d3dvt = {
1535 IDirect3D_QueryInterface,
1536 IDirect3D_AddRef,
1537 IDirect3D_Release,
1538 IDirect3D_Initialize,
1539 IDirect3D_CreateLight,
1540 (void*)6,
1541 (void*)7,
1542 (void*)8,
1543 IDirect3D_CreateDevice,
1546 /*******************************************************************************
1547 * IDirect3D2
1549 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1550 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1552 if (!--(this->ref)) {
1553 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1554 HeapFree(GetProcessHeap(),0,this);
1555 return 0;
1557 return this->ref;
1560 static HRESULT WINAPI IDirect3D2_EnumDevices(
1561 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1563 D3DDEVICEDESC d1,d2;
1565 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1566 #if 0
1567 d1.dwSize = sizeof(d1);
1568 d1.dwFlags = 0;
1570 d2.dwSize = sizeof(d2);
1571 d2.dwFlags = 0;
1572 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1573 #endif
1574 return 0;
1577 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,REFCLSID rclsid,LPDIRECTDRAWSURFACE surf,LPDIRECT3DDEVICE2 *d3dev) {
1578 char xclsid[50];
1580 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
1581 FIXME(ddraw,"(%p)->(%s,%p,%p), no Direct3D devices implemented yet!\n",this,xclsid,surf,d3dev);
1582 return E_FAIL; /* D3DERR_INVALID_DEVICE probably */
1585 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,LPDIRECT3DLIGHT *light,IUnknown* lpunk) {
1586 FIXME(ddraw,"(%p)->(%p,%p)\n",this,light,lpunk);
1587 return E_FAIL;
1590 static struct IDirect3D2_VTable d3d2vt = {
1591 (void*)1,
1592 (void*)2,
1593 IDirect3D2_Release,
1594 IDirect3D2_EnumDevices,
1595 IDirect3D2_CreateLight,
1596 (void*)6,
1597 (void*)7,
1598 (void*)8,
1599 IDirect3D2_CreateDevice,
1602 /*******************************************************************************
1603 * IDirectDraw
1606 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1607 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1609 static INT32 ddrawXlibThisOffset = 0;
1611 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
1612 LPDDSURFACEDESC lpddsd,
1613 LPDIRECTDRAWSURFACE lpdsf)
1615 int bpp;
1617 /* The surface was already allocated when entering in this function */
1618 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
1619 /* No pixel format => use DirectDraw's format */
1620 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
1621 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
1622 } else {
1623 /* To check what the program wants */
1624 if (TRACE_ON(ddraw)) {
1625 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
1629 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
1631 /* Copy the surface description */
1632 lpdsf->s.surface_desc = *lpddsd;
1634 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1635 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
1636 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
1638 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
1640 return 0;
1643 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1644 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1646 #ifdef HAVE_LIBXXF86DGA
1647 int i;
1649 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1650 if (TRACE_ON(ddraw)) {
1651 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1652 _dump_DDSD(lpddsd->dwFlags);
1653 fprintf(stderr,"caps ");
1654 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1655 fprintf(stderr,"]\n");
1658 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1659 this->lpvtbl->fnAddRef(this);
1660 (*lpdsf)->ref = 1;
1661 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1662 (*lpdsf)->s.ddraw = this;
1663 (*lpdsf)->s.palette = NULL;
1664 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
1666 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1667 lpddsd->dwWidth = this->d.width;
1668 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1669 lpddsd->dwHeight = this->d.height;
1671 /* Check if this a 'primary surface' or not */
1672 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1673 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1675 /* This is THE primary surface => there is DGA-specific code */
1676 /* First, store the surface description */
1677 (*lpdsf)->s.surface_desc = *lpddsd;
1679 /* Find a viewport */
1680 for (i=0;i<32;i++)
1681 if (!(this->e.dga.vpmask & (1<<i)))
1682 break;
1683 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1684 /* if i == 32 or maximum ... return error */
1685 this->e.dga.vpmask|=(1<<i);
1686 (*lpdsf)->s.surface_desc.y.lpSurface =
1687 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1688 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1689 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
1690 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
1692 /* Add flags if there were not present */
1693 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1694 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1695 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1696 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1697 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1698 (*lpdsf)->s.backbuffer = NULL;
1700 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1701 LPDIRECTDRAWSURFACE3 back;
1703 if (lpddsd->dwBackBufferCount>1)
1704 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1706 (*lpdsf)->s.backbuffer = back =
1707 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1708 this->lpvtbl->fnAddRef(this);
1709 back->ref = 1;
1710 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1711 for (i=0;i<32;i++)
1712 if (!(this->e.dga.vpmask & (1<<i)))
1713 break;
1714 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1715 /* if i == 32 or maximum ... return error */
1716 this->e.dga.vpmask|=(1<<i);
1717 back->t.dga.fb_height = i*this->e.dga.fb_height;
1719 /* Copy the surface description from the front buffer */
1720 back->s.surface_desc = (*lpdsf)->s.surface_desc;
1721 /* Change the parameters that are not the same */
1722 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
1723 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1724 back->s.ddraw = this;
1725 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1726 * one! */
1728 /* Add relevant info to front and back buffers */
1729 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1730 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
1731 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1732 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
1734 } else {
1735 /* There is no DGA-specific code here...
1736 Go to the common surface creation function */
1737 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
1740 return 0;
1741 #else /* defined(HAVE_LIBXXF86DGA) */
1742 return E_UNEXPECTED;
1743 #endif /* defined(HAVE_LIBXXF86DGA) */
1746 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
1747 XImage *img;
1749 #ifdef HAVE_LIBXXSHM
1750 if (this->e.xlib.xshm_active) {
1751 img = TSXShmCreateImage(display,
1752 DefaultVisualOfScreen(screen),
1753 this->d.depth,
1754 ZPixmap,
1755 NULL,
1756 &(lpdsf->t.xlib.shminfo),
1757 lpdsf->s.surface_desc.dwWidth,
1758 lpdsf->s.surface_desc.dwHeight);
1760 if (img == NULL)
1761 return NULL;
1763 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
1764 if (lpdsf->t.xlib.shminfo.shmid < 0) {
1765 TSXDestroyImage(img);
1766 return NULL;
1769 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
1771 if (img->data == (char *) -1) {
1772 TSXDestroyImage(img);
1773 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1774 return NULL;
1776 lpdsf->t.xlib.shminfo.readOnly = False;
1778 TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
1779 TSXSync(display, False);
1781 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1783 lpdsf->s.surface_desc.y.lpSurface = img->data;
1784 } else {
1785 #endif
1786 /* Allocate surface memory */
1787 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1788 lpdsf->s.surface_desc.dwWidth *
1789 lpdsf->s.surface_desc.dwHeight *
1790 (this->d.depth / 8));
1792 /* In this case, create an XImage */
1793 img =
1794 TSXCreateImage(display,
1795 DefaultVisualOfScreen(screen),
1796 this->d.depth,
1797 ZPixmap,
1799 lpdsf->s.surface_desc.y.lpSurface,
1800 lpdsf->s.surface_desc.dwWidth,
1801 lpdsf->s.surface_desc.dwHeight,
1803 lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8)
1806 #ifdef HAVE_LIBXXSHM
1808 #endif
1809 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
1811 return img;
1814 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1815 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1817 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1818 this,lpddsd,lpdsf,lpunk);
1820 if (TRACE_ON(ddraw)) {
1821 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1822 _dump_DDSD(lpddsd->dwFlags);
1823 fprintf(stderr,"caps ");
1824 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1825 fprintf(stderr,"]\n");
1828 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1830 this->lpvtbl->fnAddRef(this);
1831 (*lpdsf)->s.ddraw = this;
1832 (*lpdsf)->ref = 1;
1833 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1834 (*lpdsf)->s.palette = NULL;
1835 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
1837 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1838 lpddsd->dwWidth = this->d.width;
1839 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1840 lpddsd->dwHeight = this->d.height;
1842 /* Check if this a 'primary surface' or not */
1843 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1844 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1845 XImage *img;
1847 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
1849 /* First, store the surface description */
1850 (*lpdsf)->s.surface_desc = *lpddsd;
1852 /* Create the XImage */
1853 img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
1854 if (img == NULL)
1855 return DDERR_OUTOFMEMORY;
1856 (*lpdsf)->t.xlib.image = img;
1858 /* Add flags if there were not present */
1859 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1860 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1861 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1862 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1863 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1864 (*lpdsf)->s.backbuffer = NULL;
1866 /* Check for backbuffers */
1867 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1868 LPDIRECTDRAWSURFACE3 back;
1869 XImage *img;
1871 if (lpddsd->dwBackBufferCount>1)
1872 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1874 (*lpdsf)->s.backbuffer = back =
1875 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1877 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
1879 this->lpvtbl->fnAddRef(this);
1880 back->s.ddraw = this;
1882 back->ref = 1;
1883 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
1884 /* Copy the surface description from the front buffer */
1885 back->s.surface_desc = (*lpdsf)->s.surface_desc;
1887 /* Create the XImage */
1888 img = create_ximage(this, back);
1889 if (img == NULL)
1890 return DDERR_OUTOFMEMORY;
1891 back->t.xlib.image = img;
1893 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1894 * one! */
1896 /* Add relevant info to front and back buffers */
1897 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1898 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
1899 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1900 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
1902 } else {
1903 /* There is no Xlib-specific code here...
1904 Go to the common surface creation function */
1905 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
1908 return 0;
1911 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
1912 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1914 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1915 *dst = src; /* FIXME */
1916 return 0;
1920 * The Xlib Implementation tries to use the passed hwnd as drawing window,
1921 * even when the approbiate bitmasks are not specified.
1923 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1924 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
1926 int i;
1927 const struct {
1928 int mask;
1929 char *name;
1930 } flagmap[] = {
1931 FE(DDSCL_FULLSCREEN)
1932 FE(DDSCL_ALLOWREBOOT)
1933 FE(DDSCL_NOWINDOWCHANGES)
1934 FE(DDSCL_NORMAL)
1935 FE(DDSCL_ALLOWMODEX)
1936 FE(DDSCL_EXCLUSIVE)
1937 FE(DDSCL_SETFOCUSWINDOW)
1938 FE(DDSCL_SETDEVICEWINDOW)
1939 FE(DDSCL_CREATEDEVICEWINDOW)
1942 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
1943 if(TRACE_ON(ddraw)){
1944 dbg_decl_str(ddraw, 512);
1945 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1946 if (flagmap[i].mask & cooplevel)
1947 dsprintf(ddraw, "%s ", flagmap[i].name);
1948 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1950 this->d.mainWindow = hwnd;
1951 return 0;
1954 /* Small helper to either use the cooperative window or create a new
1955 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
1957 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
1958 RECT32 rect;
1960 /* Do not destroy the application supplied cooperative window */
1961 if (this->d.window && this->d.window != this->d.mainWindow) {
1962 DestroyWindow32(this->d.window);
1963 this->d.window = 0;
1965 /* Sanity check cooperative window before assigning it to drawing. */
1966 if ( IsWindow32(this->d.mainWindow) &&
1967 IsWindowVisible32(this->d.mainWindow)
1969 GetWindowRect32(this->d.mainWindow,&rect);
1970 if (((rect.right-rect.left) >= this->d.width) &&
1971 ((rect.bottom-rect.top) >= this->d.height)
1973 this->d.window = this->d.mainWindow;
1975 /* ... failed, create new one. */
1976 if (!this->d.window) {
1977 this->d.window = CreateWindowEx32A(
1979 "WINE_DirectDraw",
1980 "WINE_DirectDraw",
1981 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1982 0,0,
1983 this->d.width,
1984 this->d.height,
1988 NULL
1990 /*Store THIS with the window. We'll use it in the window procedure*/
1991 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
1992 ShowWindow32(this->d.window,TRUE);
1993 UpdateWindow32(this->d.window);
1995 SetFocus32(this->d.window);
1998 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
1999 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2001 #ifdef HAVE_LIBXXF86DGA
2002 int i,*depths,depcount,mode_count;
2004 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2006 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2007 for (i=0;i<depcount;i++)
2008 if (depths[i]==depth)
2009 break;
2010 TSXFree(depths);
2011 if (i==depcount) {/* not found */
2012 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2013 return DDERR_UNSUPPORTEDMODE;
2015 if (this->d.width < width) {
2016 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2017 return DDERR_UNSUPPORTEDMODE;
2019 this->d.width = width;
2020 this->d.height = height;
2021 this->d.depth = depth;
2023 /* adjust fb_height, so we don't overlap */
2024 if (this->e.dga.fb_height < height)
2025 this->e.dga.fb_height = height;
2026 _common_IDirectDraw_SetDisplayMode(this);
2028 #ifdef HAVE_LIBXXF86VM
2030 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2031 XF86VidModeModeLine mod_tmp;
2032 int dotclock_tmp;
2034 /* save original video mode and set fullscreen if available*/
2035 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2036 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2037 orig_mode->hdisplay = mod_tmp.hdisplay;
2038 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2039 orig_mode->hsyncend = mod_tmp.hsyncend;
2040 orig_mode->htotal = mod_tmp.htotal;
2041 orig_mode->vdisplay = mod_tmp.vdisplay;
2042 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2043 orig_mode->vsyncend = mod_tmp.vsyncend;
2044 orig_mode->vtotal = mod_tmp.vtotal;
2045 orig_mode->flags = mod_tmp.flags;
2046 orig_mode->private = mod_tmp.private;
2048 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2049 for (i=0;i<mode_count;i++)
2051 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2053 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2054 *vidmode = *(all_modes[i]);
2055 break;
2056 } else
2057 TSXFree(all_modes[i]->private);
2059 TSXFree(all_modes);
2061 if (!vidmode)
2062 WARN(ddraw, "Fullscreen mode not available!\n");
2064 if (vidmode)
2066 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2067 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2070 #endif
2072 /* FIXME: this function OVERWRITES several signal handlers.
2073 * can we save them? and restore them later? In a way that
2074 * it works for the library too?
2076 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2077 #ifdef DIABLO_HACK
2078 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2079 #endif
2081 #ifdef RESTORE_SIGNALS
2082 SIGNAL_InitEmulator();
2083 #endif
2084 return 0;
2085 #else /* defined(HAVE_LIBXXF86DGA) */
2086 return E_UNEXPECTED;
2087 #endif /* defined(HAVE_LIBXXF86DGA) */
2090 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2091 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2093 int i,*depths,depcount;
2094 char buf[200];
2096 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2097 this, width, height, depth);
2099 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2100 for (i=0;i<depcount;i++)
2101 if (depths[i]==depth)
2102 break;
2103 TSXFree(depths);
2104 if (i==depcount) {/* not found */
2105 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2106 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2107 return DDERR_UNSUPPORTEDMODE;
2109 this->d.width = width;
2110 this->d.height = height;
2111 this->d.depth = depth;
2113 _common_IDirectDraw_SetDisplayMode(this);
2115 this->e.xlib.paintable = 1;
2116 this->e.xlib.drawable = WIN_FindWndPtr(this->d.window)->window;
2117 /* We don't have a context for this window. Host off the desktop */
2118 if( !this->e.xlib.drawable )
2119 this->e.xlib.drawable = WIN_GetDesktop()->window;
2120 return 0;
2123 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2124 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2126 #ifdef HAVE_LIBXXF86DGA
2127 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2128 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2129 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2130 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2131 if (caps2) {
2132 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2133 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2134 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2136 return 0;
2137 #else /* defined(HAVE_LIBXXF86DGA) */
2138 return E_UNEXPECTED;
2139 #endif /* defined(HAVE_LIBXXF86DGA) */
2142 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2143 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2145 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2146 /* FIXME: Xlib */
2147 caps1->dwVidMemTotal = 2048*1024;
2148 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2149 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2150 if (caps2) {
2151 caps2->dwVidMemTotal = 2048*1024;
2152 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2153 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2155 /* END FIXME: Xlib */
2156 return 0;
2159 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2160 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2162 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2163 this,x,lpddclip,lpunk
2165 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2166 (*lpddclip)->ref = 1;
2167 (*lpddclip)->lpvtbl = &ddclipvt;
2168 return 0;
2171 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2172 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2174 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2175 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2176 (*lpddpal)->ref = 1;
2177 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2178 (*lpddpal)->installed = 0;
2179 if (this->d.depth<=8) {
2180 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
2181 } else {
2182 /* we don't want palettes in hicolor or truecolor */
2183 (*lpddpal)->cm = 0;
2185 return 0;
2188 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2189 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2191 HRESULT res;
2192 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2193 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
2194 if (res != 0) return res;
2195 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2196 return 0;
2199 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2200 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2202 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2203 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2204 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2205 (*lpddpal)->ref = 1;
2206 (*lpddpal)->installed = 0;
2207 if (palent)
2208 FIXME(ddraw,"needs to handle palent (%p)\n",palent);
2210 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2211 this->lpvtbl->fnAddRef(this);
2212 (*lpddpal)->cm = 0;
2214 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2215 return 0;
2218 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2219 #ifdef HAVE_LIBXXF86DGA
2220 TRACE(ddraw, "(%p)->()\n",this);
2221 Sleep(1000);
2222 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2223 #ifdef RESTORE_SIGNALS
2224 SIGNAL_InitEmulator();
2225 #endif
2226 return 0;
2227 #else /* defined(HAVE_LIBXXF86DGA) */
2228 return E_UNEXPECTED;
2229 #endif
2232 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2233 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
2234 Sleep(1000);
2235 return 0;
2238 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
2239 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
2241 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
2242 return 0;
2245 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
2246 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2248 return ++(this->ref);
2251 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2252 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2254 #ifdef HAVE_LIBXXF86DGA
2255 if (!--(this->ref)) {
2256 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2258 #ifdef HAVE_LIBXXF86VM
2259 if (orig_mode)
2260 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), orig_mode);
2261 if (orig_mode->privsize)
2262 TSXFree(orig_mode->private);
2263 free(orig_mode);
2264 orig_mode = NULL;
2265 #endif
2267 #ifdef RESTORE_SIGNALS
2268 SIGNAL_InitEmulator();
2269 #endif
2270 HeapFree(GetProcessHeap(),0,this);
2271 return 0;
2273 #endif /* defined(HAVE_LIBXXF86DGA) */
2274 return this->ref;
2277 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2278 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2280 if (!--(this->ref)) {
2281 HeapFree(GetProcessHeap(),0,this);
2282 return 0;
2284 /* FIXME: destroy window ... */
2285 return this->ref;
2288 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
2289 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2291 char xrefiid[50];
2293 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2294 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2295 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2296 *obj = this;
2297 this->lpvtbl->fnAddRef(this);
2298 return 0;
2300 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2301 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
2302 this->lpvtbl->fnAddRef(this);
2303 *obj = this;
2304 return 0;
2306 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2307 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
2308 this->lpvtbl->fnAddRef(this);
2309 *obj = this;
2310 return 0;
2312 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2313 LPDIRECT3D d3d;
2315 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2316 d3d->ref = 1;
2317 d3d->ddraw = (LPDIRECTDRAW)this;
2318 this->lpvtbl->fnAddRef(this);
2319 d3d->lpvtbl = &d3dvt;
2320 *obj = d3d;
2321 return 0;
2323 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2324 LPDIRECT3D2 d3d;
2326 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2327 d3d->ref = 1;
2328 d3d->ddraw = (LPDIRECTDRAW)this;
2329 this->lpvtbl->fnAddRef(this);
2330 d3d->lpvtbl = &d3d2vt;
2331 *obj = d3d;
2332 return 0;
2334 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2335 return OLE_E_ENUM_NOMORE;
2338 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
2339 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2341 char xrefiid[50];
2343 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2344 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2345 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2346 *obj = this;
2347 this->lpvtbl->fnAddRef(this);
2348 return 0;
2350 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2351 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2352 this->lpvtbl->fnAddRef(this);
2353 *obj = this;
2354 return 0;
2356 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2357 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2358 this->lpvtbl->fnAddRef(this);
2359 *obj = this;
2360 return 0;
2362 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2363 LPDIRECT3D d3d;
2365 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2366 d3d->ref = 1;
2367 d3d->ddraw = (LPDIRECTDRAW)this;
2368 this->lpvtbl->fnAddRef(this);
2369 d3d->lpvtbl = &d3dvt;
2370 *obj = d3d;
2371 return 0;
2373 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2374 LPDIRECT3D2 d3d;
2376 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2377 d3d->ref = 1;
2378 d3d->ddraw = (LPDIRECTDRAW)this;
2379 this->lpvtbl->fnAddRef(this);
2380 d3d->lpvtbl = &d3d2vt;
2381 *obj = d3d;
2382 return 0;
2384 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2385 return OLE_E_ENUM_NOMORE;
2388 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2389 LPDIRECTDRAW2 this,BOOL32 *status
2391 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2392 *status = TRUE;
2393 return 0;
2396 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2397 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2399 DDSURFACEDESC ddsfd;
2400 static struct {
2401 int w,h;
2402 } modes[5] = { /* some of the usual modes */
2403 {512,384},
2404 {640,400},
2405 {640,480},
2406 {800,600},
2407 {1024,768},
2409 static int depths[4] = {8,16,24,32};
2410 int i,j;
2412 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2413 ddsfd.dwSize = sizeof(ddsfd);
2414 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2415 if (dwFlags & DDEDM_REFRESHRATES) {
2416 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2417 ddsfd.x.dwRefreshRate = 60;
2420 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2421 ddsfd.dwBackBufferCount = 1;
2422 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2423 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2424 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2425 /* FIXME: those masks would have to be set in depth > 8 */
2426 if (depths[i]==8) {
2427 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2428 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2429 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2430 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2431 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2432 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2433 } else {
2434 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2436 /* FIXME: We should query those from X itself */
2437 switch (depths[i]) {
2438 case 16:
2439 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2440 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2441 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2442 break;
2443 case 24:
2444 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2445 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2446 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2447 break;
2448 case 32:
2449 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2450 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2451 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2452 break;
2456 ddsfd.dwWidth = screenWidth;
2457 ddsfd.dwHeight = screenHeight;
2458 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2459 if (!modescb(&ddsfd,context)) return 0;
2461 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2462 ddsfd.dwWidth = modes[j].w;
2463 ddsfd.dwHeight = modes[j].h;
2464 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2465 if (!modescb(&ddsfd,context)) return 0;
2468 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2469 /* modeX is not standard VGA */
2471 ddsfd.dwHeight = 200;
2472 ddsfd.dwWidth = 320;
2473 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2474 if (!modescb(&ddsfd,context)) return 0;
2477 return DD_OK;
2480 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2481 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2483 #ifdef HAVE_LIBXXF86DGA
2484 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2485 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2486 lpddsfd->dwHeight = screenHeight;
2487 lpddsfd->dwWidth = screenWidth;
2488 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2489 lpddsfd->dwBackBufferCount = 1;
2490 lpddsfd->x.dwRefreshRate = 60;
2491 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2492 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2493 return DD_OK;
2494 #else /* defined(HAVE_LIBXXF86DGA) */
2495 return E_UNEXPECTED;
2496 #endif /* defined(HAVE_LIBXXF86DGA) */
2499 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2500 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2502 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2503 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2504 lpddsfd->dwHeight = screenHeight;
2505 lpddsfd->dwWidth = screenWidth;
2506 /* POOLE FIXME: Xlib */
2507 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2508 /* END FIXME: Xlib */
2509 lpddsfd->dwBackBufferCount = 1;
2510 lpddsfd->x.dwRefreshRate = 60;
2511 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2512 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2513 return DD_OK;
2516 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2517 TRACE(ddraw,"(%p)->()\n",this);
2518 return DD_OK;
2521 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2522 LPDIRECTDRAW2 this,LPDWORD freq
2524 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2525 *freq = 60*100; /* 60 Hz */
2526 return 0;
2529 /* what can we directly decompress? */
2530 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2531 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2533 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2534 return 0;
2537 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2538 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2540 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2541 return 0;
2544 static HRESULT WINAPI IDirectDraw2_Compact(
2545 LPDIRECTDRAW2 this )
2547 FIXME(ddraw,"(%p)->()\n", this );
2549 return DD_OK;
2553 /* Note: Hack so we can reuse the old functions without compiler warnings */
2554 #ifdef __GNUC__
2555 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2556 #else
2557 # define XCAST(fun) (void*)
2558 #endif
2560 static struct IDirectDraw_VTable dga_ddvt = {
2561 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2562 XCAST(AddRef)IDirectDraw2_AddRef,
2563 XCAST(Release)DGA_IDirectDraw2_Release,
2564 XCAST(Compact)IDirectDraw2_Compact,
2565 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2566 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2567 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2568 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2569 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2570 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2571 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2572 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2573 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2574 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2575 XCAST(GetGDISurface)15,
2576 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2577 XCAST(GetScanLine)17,
2578 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2579 XCAST(Initialize)19,
2580 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2581 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2582 DGA_IDirectDraw_SetDisplayMode,
2583 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2586 static struct IDirectDraw_VTable xlib_ddvt = {
2587 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2588 XCAST(AddRef)IDirectDraw2_AddRef,
2589 XCAST(Release)Xlib_IDirectDraw2_Release,
2590 XCAST(Compact)IDirectDraw2_Compact,
2591 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2592 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2593 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2594 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2595 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2596 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2597 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2598 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2599 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2600 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2601 XCAST(GetGDISurface)15,
2602 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2603 XCAST(GetScanLine)17,
2604 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2605 XCAST(Initialize)19,
2606 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2607 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2608 Xlib_IDirectDraw_SetDisplayMode,
2609 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2612 /*****************************************************************************
2613 * IDirectDraw2
2618 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2619 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2621 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2624 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2625 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2627 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2630 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2631 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2633 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2634 this,ddscaps,total,free
2636 if (total) *total = this->e.dga.fb_memsize * 1024;
2637 if (free) *free = this->e.dga.fb_memsize * 1024;
2638 return 0;
2641 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2642 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2644 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2645 this,ddscaps,total,free
2647 if (total) *total = 2048 * 1024;
2648 if (free) *free = 2048 * 1024;
2649 return 0;
2652 static IDirectDraw2_VTable dga_dd2vt = {
2653 DGA_IDirectDraw2_QueryInterface,
2654 IDirectDraw2_AddRef,
2655 DGA_IDirectDraw2_Release,
2656 IDirectDraw2_Compact,
2657 IDirectDraw2_CreateClipper,
2658 DGA_IDirectDraw2_CreatePalette,
2659 DGA_IDirectDraw2_CreateSurface,
2660 (void*)8,
2661 IDirectDraw2_EnumDisplayModes,
2662 IDirectDraw2_EnumSurfaces,
2663 IDirectDraw2_FlipToGDISurface,
2664 DGA_IDirectDraw2_GetCaps,
2665 DGA_IDirectDraw2_GetDisplayMode,
2666 IDirectDraw2_GetFourCCCodes,
2667 (void*)15,
2668 IDirectDraw2_GetMonitorFrequency,
2669 (void*)17,
2670 IDirectDraw2_GetVerticalBlankStatus,
2671 (void*)19,
2672 DGA_IDirectDraw2_RestoreDisplayMode,
2673 IDirectDraw2_SetCooperativeLevel,
2674 DGA_IDirectDraw2_SetDisplayMode,
2675 IDirectDraw2_WaitForVerticalBlank,
2676 DGA_IDirectDraw2_GetAvailableVidMem
2679 static struct IDirectDraw2_VTable xlib_dd2vt = {
2680 Xlib_IDirectDraw2_QueryInterface,
2681 IDirectDraw2_AddRef,
2682 Xlib_IDirectDraw2_Release,
2683 IDirectDraw2_Compact,
2684 IDirectDraw2_CreateClipper,
2685 Xlib_IDirectDraw2_CreatePalette,
2686 Xlib_IDirectDraw2_CreateSurface,
2687 (void*)8,
2688 IDirectDraw2_EnumDisplayModes,
2689 IDirectDraw2_EnumSurfaces,
2690 IDirectDraw2_FlipToGDISurface,
2691 Xlib_IDirectDraw2_GetCaps,
2692 Xlib_IDirectDraw2_GetDisplayMode,
2693 IDirectDraw2_GetFourCCCodes,
2694 (void*)15,
2695 IDirectDraw2_GetMonitorFrequency,
2696 (void*)17,
2697 IDirectDraw2_GetVerticalBlankStatus,
2698 (void*)19,
2699 Xlib_IDirectDraw2_RestoreDisplayMode,
2700 IDirectDraw2_SetCooperativeLevel,
2701 Xlib_IDirectDraw2_SetDisplayMode,
2702 IDirectDraw2_WaitForVerticalBlank,
2703 Xlib_IDirectDraw2_GetAvailableVidMem
2706 /******************************************************************************
2707 * DirectDrawCreate
2710 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2712 LRESULT ret;
2713 LPDIRECTDRAW ddraw = NULL;
2714 DWORD lastError;
2716 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2718 SetLastError( ERROR_SUCCESS );
2719 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2720 if( (!ddraw) &&
2721 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2724 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2727 if( ddraw )
2729 /* Perform any special direct draw functions */
2730 if (msg==WM_PAINT)
2731 ddraw->e.xlib.paintable = 1;
2733 /* Now let the application deal with the rest of this */
2734 if( ddraw->d.mainWindow )
2737 /* Don't think that we actually need to call this but...
2738 might as well be on the safe side of things... */
2740 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
2741 it should be the procedures of our fake window that gets called
2742 instead of those of the window provided by the application.
2743 And with this patch, mouse clicks work with Monkey Island III
2744 - Lionel */
2745 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2747 if( !ret )
2749 /* We didn't handle the message - give it to the application */
2750 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
2751 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2752 ddraw->d.mainWindow, msg, wParam, lParam );
2756 } else {
2757 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
2761 else
2763 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2766 return ret;
2769 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2770 #ifdef HAVE_LIBXXF86DGA
2771 int memsize,banksize,width,major,minor,flags,height;
2772 char *addr;
2773 int fd;
2775 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
2776 if ((fd = open("/dev/mem", O_RDWR)) != -1)
2777 close(fd);
2779 if (fd == -1) {
2780 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
2781 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2782 return E_UNEXPECTED;
2784 if (!DDRAW_DGA_Available()) {
2785 TRACE(ddraw,"No XF86DGA detected.\n");
2786 return DDERR_GENERIC;
2788 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2789 (*lplpDD)->lpvtbl = &dga_ddvt;
2790 (*lplpDD)->ref = 1;
2791 TSXF86DGAQueryVersion(display,&major,&minor);
2792 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2793 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2794 if (!(flags & XF86DGADirectPresent))
2795 MSG("direct video is NOT PRESENT.\n");
2796 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2797 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2798 addr,width,banksize,memsize
2800 (*lplpDD)->e.dga.fb_width = width;
2801 (*lplpDD)->d.width = width;
2802 (*lplpDD)->e.dga.fb_addr = addr;
2803 (*lplpDD)->e.dga.fb_memsize = memsize;
2804 (*lplpDD)->e.dga.fb_banksize = banksize;
2806 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2807 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2808 (*lplpDD)->e.dga.fb_height = screenHeight;
2809 #ifdef DIABLO_HACK
2810 (*lplpDD)->e.dga.vpmask = 1;
2811 #else
2812 (*lplpDD)->e.dga.vpmask = 0;
2813 #endif
2815 /* just assume the default depth is the DGA depth too */
2816 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2817 #ifdef RESTORE_SIGNALS
2818 SIGNAL_InitEmulator();
2819 #endif
2821 return 0;
2822 #else /* defined(HAVE_LIBXXF86DGA) */
2823 return DDERR_INVALIDDIRECTDRAWGUID;
2824 #endif /* defined(HAVE_LIBXXF86DGA) */
2827 BOOL32
2828 DDRAW_XSHM_Available()
2830 #ifdef HAVE_LIBXXSHM
2831 if (TSXShmQueryExtension(display))
2833 int major, minor;
2834 Bool shpix;
2836 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
2837 return 1;
2838 else
2839 return 0;
2841 else
2842 return 0;
2843 #else
2844 return 0;
2845 #endif
2848 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2850 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2851 (*lplpDD)->lpvtbl = &xlib_ddvt;
2852 (*lplpDD)->ref = 1;
2853 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
2855 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2856 (*lplpDD)->d.height = screenHeight;
2857 (*lplpDD)->d.width = screenWidth;
2859 #ifdef HAVE_LIBXXSHM
2860 /* Test if XShm is available.
2861 As XShm is not ready yet for 'prime-time', it is disabled for now */
2862 if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
2863 TRACE(ddraw, "Using XShm extesion.\n");
2864 #endif
2866 return 0;
2869 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
2870 char xclsid[50];
2871 WNDCLASS32A wc;
2872 WND* pParentWindow;
2873 HRESULT ret;
2875 if (HIWORD(lpGUID))
2876 WINE_StringFromCLSID(lpGUID,xclsid);
2877 else {
2878 sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID);
2879 lpGUID = NULL;
2882 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
2884 if (!lpGUID) {
2885 /* if they didn't request a particular interface, use the best
2886 * supported one */
2887 if (DDRAW_DGA_Available())
2888 lpGUID = &DGA_DirectDraw_GUID;
2889 else
2890 lpGUID = &XLIB_DirectDraw_GUID;
2893 wc.style = CS_GLOBALCLASS;
2894 wc.lpfnWndProc = Xlib_DDWndProc;
2895 wc.cbClsExtra = 0;
2896 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
2897 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
2899 /* We can be a child of the desktop since we're really important */
2900 pParentWindow = WIN_GetDesktop();
2901 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
2902 wc.hInstance = 0;
2904 wc.hIcon = 0;
2905 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
2906 wc.hbrBackground= NULL_BRUSH;
2907 wc.lpszMenuName = 0;
2908 wc.lpszClassName= "WINE_DirectDraw";
2909 RegisterClass32A(&wc);
2911 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
2912 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
2913 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
2914 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
2915 else
2916 goto err;
2918 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
2919 return ret;
2921 err:
2922 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
2923 return DDERR_INVALIDDIRECTDRAWGUID;