Since SetParent now hides/shows, explicitly invalidating DCs in the
[wine.git] / graphics / ddraw.c
blobfdf2f9680022b90cc55517071b6ca593f8ab8b0f
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
5 */
6 /* XF86DGA:
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
10 * is running.
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
17 #include "config.h"
19 #include "ts_xlib.h"
20 #include "ts_xutil.h"
22 #ifdef HAVE_LIBXXSHM
23 #include <sys/types.h>
24 #include <sys/ipc.h>
25 #include <sys/shm.h>
26 #include "ts_xshm.h"
27 #endif /* defined(HAVE_LIBXXSHM) */
29 #ifdef HAVE_LIBXXF86DGA
30 #include "ts_xf86dga.h"
31 #endif /* defined(HAVE_LIBXXF86DGA) */
33 #ifdef HAVE_LIBXXF86VM
34 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
35 this is a crude hack to get around it */
36 #define XMD_H
37 #include "wintypes.h"
38 #include "ts_xf86vmode.h"
39 #endif /* defined(HAVE_LIBXXF86VM) */
41 #include "x11drv.h"
43 #include <unistd.h>
44 #include <assert.h>
45 #include <sys/signal.h>
46 #include <fcntl.h>
47 #include <string.h>
48 #include <stdlib.h>
49 #include "windows.h"
51 #include "winerror.h"
52 #include "gdi.h"
53 #include "heap.h"
54 #include "ldt.h"
55 #include "dc.h"
56 #include "win.h"
57 #include "miscemu.h"
58 #include "ddraw.h"
59 #include "d3d.h"
60 #include "debug.h"
61 #include "spy.h"
62 #include "message.h"
63 #include "options.h"
64 #include "objbase.h"
65 #include "monitor.h"
67 /* This for all the enumeration and creation of D3D-related objects */
68 #include "d3d_private.h"
70 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
71 #undef DIABLO_HACK
73 /* Restore signal handlers overwritten by XF86DGA
75 #define RESTORE_SIGNALS
77 /* Where do these GUIDs come from? mkuuid.
78 * They exist solely to distinguish between the targets Wine support,
79 * and should be different than any other GUIDs in existence.
81 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
82 0xe2dcb020,
83 0xdc60,
84 0x11d1,
85 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
88 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
89 0x1574a740,
90 0xdc61,
91 0x11d1,
92 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
95 static struct IDirectDrawSurface4_VTable dga_dds4vt, xlib_dds4vt;
96 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
97 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
98 static struct IDirectDraw4_VTable dga_dd4vt, xlib_dd4vt;
99 static struct IDirectDrawClipper_VTable ddclipvt;
100 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
101 static struct IDirect3D_VTable d3dvt;
102 static struct IDirect3D2_VTable d3d2vt;
104 #ifdef HAVE_LIBXXF86VM
105 static XF86VidModeModeInfo *orig_mode = NULL;
106 #endif
108 #ifdef HAVE_LIBXXSHM
109 static int XShmErrorFlag = 0;
110 #endif
112 BOOL32
113 DDRAW_DGA_Available(void)
115 #ifdef HAVE_LIBXXF86DGA
116 int evbase, evret, fd;
118 if (Options.noDGA)
119 return 0;
121 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
122 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
123 /* others. --stephenc */
124 if ((fd = open("/dev/mem", O_RDWR)) != -1)
125 close(fd);
127 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
128 #else /* defined(HAVE_LIBXXF86DGA) */
129 return 0;
130 #endif /* defined(HAVE_LIBXXF86DGA) */
133 HRESULT WINAPI
134 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
135 if (DDRAW_DGA_Available()) {
136 TRACE(ddraw, "Enumerating DGA interface\n");
137 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
139 TRACE(ddraw, "Enumerating Xlib interface\n");
140 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
141 TRACE(ddraw, "Enumerating Default interface\n");
142 ddenumproc(NULL,"WINE (default)","display",data);
143 return DD_OK;
146 /* What is this doing here? */
147 HRESULT WINAPI
148 DSoundHelp(DWORD x,DWORD y,DWORD z) {
149 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
150 return 0;
154 /******************************************************************************
155 * internal helper functions
157 static void _dump_DDBLTFX(DWORD flagmask) {
158 int i;
159 const struct {
160 DWORD mask;
161 char *name;
162 } flags[] = {
163 #define FE(x) { x, #x},
164 FE(DDBLTFX_ARITHSTRETCHY)
165 FE(DDBLTFX_MIRRORLEFTRIGHT)
166 FE(DDBLTFX_MIRRORUPDOWN)
167 FE(DDBLTFX_NOTEARING)
168 FE(DDBLTFX_ROTATE180)
169 FE(DDBLTFX_ROTATE270)
170 FE(DDBLTFX_ROTATE90)
171 FE(DDBLTFX_ZBUFFERRANGE)
172 FE(DDBLTFX_ZBUFFERBASEDEST)
174 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
175 if (flags[i].mask & flagmask) {
176 DUMP("%s ",flags[i].name);
179 DUMP("\n");
183 static void _dump_DDBLTFAST(DWORD flagmask) {
184 int i;
185 const struct {
186 DWORD mask;
187 char *name;
188 } flags[] = {
189 #define FE(x) { x, #x},
190 FE(DDBLTFAST_NOCOLORKEY)
191 FE(DDBLTFAST_SRCCOLORKEY)
192 FE(DDBLTFAST_DESTCOLORKEY)
193 FE(DDBLTFAST_WAIT)
195 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
196 if (flags[i].mask & flagmask)
197 DUMP("%s ",flags[i].name);
198 DUMP("\n");
201 static void _dump_DDBLT(DWORD flagmask) {
202 int i;
203 const struct {
204 DWORD mask;
205 char *name;
206 } flags[] = {
207 #define FE(x) { x, #x},
208 FE(DDBLT_ALPHADEST)
209 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
210 FE(DDBLT_ALPHADESTNEG)
211 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
212 FE(DDBLT_ALPHAEDGEBLEND)
213 FE(DDBLT_ALPHASRC)
214 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
215 FE(DDBLT_ALPHASRCNEG)
216 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
217 FE(DDBLT_ASYNC)
218 FE(DDBLT_COLORFILL)
219 FE(DDBLT_DDFX)
220 FE(DDBLT_DDROPS)
221 FE(DDBLT_KEYDEST)
222 FE(DDBLT_KEYDESTOVERRIDE)
223 FE(DDBLT_KEYSRC)
224 FE(DDBLT_KEYSRCOVERRIDE)
225 FE(DDBLT_ROP)
226 FE(DDBLT_ROTATIONANGLE)
227 FE(DDBLT_ZBUFFER)
228 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
229 FE(DDBLT_ZBUFFERDESTOVERRIDE)
230 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
231 FE(DDBLT_ZBUFFERSRCOVERRIDE)
232 FE(DDBLT_WAIT)
233 FE(DDBLT_DEPTHFILL)
235 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
236 if (flags[i].mask & flagmask)
237 DUMP("%s ",flags[i].name);
238 DUMP("\n");
241 static void _dump_DDSCAPS(DWORD flagmask) {
242 int i;
243 const struct {
244 DWORD mask;
245 char *name;
246 } flags[] = {
247 #define FE(x) { x, #x},
248 FE(DDSCAPS_RESERVED1)
249 FE(DDSCAPS_ALPHA)
250 FE(DDSCAPS_BACKBUFFER)
251 FE(DDSCAPS_COMPLEX)
252 FE(DDSCAPS_FLIP)
253 FE(DDSCAPS_FRONTBUFFER)
254 FE(DDSCAPS_OFFSCREENPLAIN)
255 FE(DDSCAPS_OVERLAY)
256 FE(DDSCAPS_PALETTE)
257 FE(DDSCAPS_PRIMARYSURFACE)
258 FE(DDSCAPS_PRIMARYSURFACELEFT)
259 FE(DDSCAPS_SYSTEMMEMORY)
260 FE(DDSCAPS_TEXTURE)
261 FE(DDSCAPS_3DDEVICE)
262 FE(DDSCAPS_VIDEOMEMORY)
263 FE(DDSCAPS_VISIBLE)
264 FE(DDSCAPS_WRITEONLY)
265 FE(DDSCAPS_ZBUFFER)
266 FE(DDSCAPS_OWNDC)
267 FE(DDSCAPS_LIVEVIDEO)
268 FE(DDSCAPS_HWCODEC)
269 FE(DDSCAPS_MODEX)
270 FE(DDSCAPS_MIPMAP)
271 FE(DDSCAPS_RESERVED2)
272 FE(DDSCAPS_ALLOCONLOAD)
273 FE(DDSCAPS_VIDEOPORT)
274 FE(DDSCAPS_LOCALVIDMEM)
275 FE(DDSCAPS_NONLOCALVIDMEM)
276 FE(DDSCAPS_STANDARDVGAMODE)
277 FE(DDSCAPS_OPTIMIZED)
279 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
280 if (flags[i].mask & flagmask)
281 DUMP("%s ",flags[i].name);
282 DUMP("\n");
285 static void _dump_DDSD(DWORD flagmask) {
286 int i;
287 const struct {
288 DWORD mask;
289 char *name;
290 } flags[] = {
291 FE(DDSD_CAPS)
292 FE(DDSD_HEIGHT)
293 FE(DDSD_WIDTH)
294 FE(DDSD_PITCH)
295 FE(DDSD_BACKBUFFERCOUNT)
296 FE(DDSD_ZBUFFERBITDEPTH)
297 FE(DDSD_ALPHABITDEPTH)
298 FE(DDSD_PIXELFORMAT)
299 FE(DDSD_CKDESTOVERLAY)
300 FE(DDSD_CKDESTBLT)
301 FE(DDSD_CKSRCOVERLAY)
302 FE(DDSD_CKSRCBLT)
303 FE(DDSD_MIPMAPCOUNT)
304 FE(DDSD_REFRESHRATE)
305 FE(DDSD_LINEARSIZE)
306 FE(DDSD_LPSURFACE)
308 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
309 if (flags[i].mask & flagmask)
310 DUMP("%s ",flags[i].name);
311 DUMP("\n");
314 static void _dump_DDCOLORKEY(DWORD flagmask) {
315 int i;
316 const struct {
317 DWORD mask;
318 char *name;
319 } flags[] = {
320 #define FE(x) { x, #x},
321 FE(DDPF_ALPHAPIXELS)
322 FE(DDPF_ALPHA)
323 FE(DDPF_FOURCC)
324 FE(DDPF_PALETTEINDEXED4)
325 FE(DDPF_PALETTEINDEXEDTO8)
326 FE(DDPF_PALETTEINDEXED8)
327 FE(DDPF_RGB)
328 FE(DDPF_COMPRESSED)
329 FE(DDPF_RGBTOYUV)
330 FE(DDPF_YUV)
331 FE(DDPF_ZBUFFER)
332 FE(DDPF_PALETTEINDEXED1)
333 FE(DDPF_PALETTEINDEXED2)
334 FE(DDPF_ZPIXELS)
336 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
337 if (flags[i].mask & flagmask)
338 DUMP("%s ",flags[i].name);
339 DUMP("\n");
342 static void _dump_paletteformat(DWORD dwFlags) {
343 int i;
344 const struct {
345 DWORD mask;
346 char *name;
347 } flags[] = {
348 #define FE(x) { x, #x},
349 FE(DDPCAPS_4BIT)
350 FE(DDPCAPS_8BITENTRIES)
351 FE(DDPCAPS_8BIT)
352 FE(DDPCAPS_INITIALIZE)
353 FE(DDPCAPS_PRIMARYSURFACE)
354 FE(DDPCAPS_PRIMARYSURFACELEFT)
355 FE(DDPCAPS_ALLOW256)
356 FE(DDPCAPS_VSYNC)
357 FE(DDPCAPS_1BIT)
358 FE(DDPCAPS_2BIT)
359 FE(DDPCAPS_ALPHA)
361 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
362 if (flags[i].mask & dwFlags)
363 DUMP("%s ",flags[i].name);
364 DUMP("\n");
367 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
368 DUMP("Size : %ld\n", pf->dwSize);
369 if (pf->dwFlags)
370 _dump_DDCOLORKEY(pf->dwFlags);
371 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
372 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
373 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
374 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
377 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
378 static XVisualInfo *vi;
379 XVisualInfo vt;
380 int nitems;
382 if (!vi)
383 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
385 pf->dwFourCC = 0;
386 pf->dwSize = sizeof(DDPIXELFORMAT);
387 if (ddraw->d.depth==8) {
388 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
389 pf->x.dwRGBBitCount = 8;
390 pf->y.dwRBitMask = 0;
391 pf->z.dwGBitMask = 0;
392 pf->xx.dwBBitMask = 0;
393 pf->xy.dwRGBAlphaBitMask= 0;
394 return 0;
396 if (ddraw->d.depth==16) {
397 pf->dwFlags = DDPF_RGB;
398 pf->x.dwRGBBitCount = 16;
399 pf->y.dwRBitMask = vi[0].red_mask;
400 pf->z.dwGBitMask = vi[0].green_mask;
401 pf->xx.dwBBitMask = vi[0].blue_mask;
402 pf->xy.dwRGBAlphaBitMask= 0;
403 return 0;
405 if (ddraw->d.depth==24) {
406 pf->dwFlags = DDPF_RGB;
407 pf->x.dwRGBBitCount = 24;
408 pf->y.dwRBitMask = vi[0].red_mask;
409 pf->z.dwGBitMask = vi[0].green_mask;
410 pf->xx.dwBBitMask = vi[0].blue_mask;
411 pf->xy.dwRGBAlphaBitMask= 0;
412 return 0;
414 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
415 return DDERR_GENERIC;
418 /******************************************************************************
419 * IDirectDrawSurface methods
421 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
422 * DDS and DDS2 use those functions. (Function calls did not change (except
423 * using different DirectDrawSurfaceX version), just added flags and functions)
425 static HRESULT WINAPI IDirectDrawSurface4_Lock(
426 LPDIRECTDRAWSURFACE4 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
428 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
429 this,lprect,lpddsd,flags,(DWORD)hnd);
430 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
431 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
432 this,lprect,lpddsd,flags,(DWORD)hnd);
434 /* First, copy the Surface description */
435 *lpddsd = this->s.surface_desc;
436 TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
437 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
439 /* If asked only for a part, change the surface pointer */
440 if (lprect) {
441 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
442 lprect->top,lprect->left,lprect->bottom,lprect->right
444 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
445 (lprect->top*this->s.surface_desc.lPitch) +
446 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
447 } else {
448 assert(this->s.surface_desc.y.lpSurface);
450 return DD_OK;
453 static HRESULT WINAPI DGA_IDirectDrawSurface4_Unlock(
454 LPDIRECTDRAWSURFACE4 this,LPVOID surface
456 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
457 return DD_OK;
460 static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4 this) {
461 if (this->s.ddraw->d.depth != this->s.ddraw->d.screen_depth) {
462 /* Pixel convertion ! */
463 if ((this->s.ddraw->d.depth == 8) && (this->s.ddraw->d.screen_depth == 16)) {
464 unsigned char *src = (unsigned char *) this->s.surface_desc.y.lpSurface;
465 unsigned short *dst = (unsigned short *) this->t.xlib.image->data;
466 unsigned short *pal;
467 int x, y;
469 if (this->s.palette != NULL) {
470 pal = (unsigned short *) this->s.palette->screen_palents;
471 for (y = 0; y < this->s.surface_desc.dwHeight; y++) {
472 for (x = 0; x < this->s.surface_desc.dwWidth; x++) {
473 dst[x + y * this->s.surface_desc.lPitch] = pal[src[x + y * this->s.surface_desc.lPitch]];
476 } else {
477 WARN(ddraw, "No palette set...\n");
478 memset(dst, 0, this->s.surface_desc.lPitch * this->s.surface_desc.dwHeight * 2);
480 } else {
481 ERR(ddraw, "Unsupported pixel convertion...\n");
485 #ifdef HAVE_LIBXXSHM
486 if (this->s.ddraw->e.xlib.xshm_active)
487 TSXShmPutImage(display,
488 this->s.ddraw->d.drawable,
489 DefaultGCOfScreen(X11DRV_GetXScreen()),
490 this->t.xlib.image,
491 0, 0, 0, 0,
492 this->t.xlib.image->width,
493 this->t.xlib.image->height,
494 False);
495 else
496 #endif
497 TSXPutImage( display,
498 this->s.ddraw->d.drawable,
499 DefaultGCOfScreen(X11DRV_GetXScreen()),
500 this->t.xlib.image,
501 0, 0, 0, 0,
502 this->t.xlib.image->width,
503 this->t.xlib.image->height);
506 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Unlock(
507 LPDIRECTDRAWSURFACE4 this,LPVOID surface)
509 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
511 if (!this->s.ddraw->d.paintable)
512 return DD_OK;
514 /* Only redraw the screen when unlocking the buffer that is on screen */
515 if ((this->t.xlib.image != NULL) &&
516 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
517 Xlib_copy_surface_on_screen(this);
519 if (this->s.palette && this->s.palette->cm)
520 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
523 return DD_OK;
526 static HRESULT WINAPI DGA_IDirectDrawSurface4_Flip(
527 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
529 #ifdef HAVE_LIBXXF86DGA
530 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
531 if (!flipto) {
532 if (this->s.backbuffer)
533 flipto = this->s.backbuffer;
534 else
535 flipto = this;
537 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
539 if (flipto->s.palette && flipto->s.palette->cm) {
540 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
542 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
544 if (flipto!=this) {
545 int tmp;
546 LPVOID ptmp;
548 tmp = this->t.dga.fb_height;
549 this->t.dga.fb_height = flipto->t.dga.fb_height;
550 flipto->t.dga.fb_height = tmp;
552 ptmp = this->s.surface_desc.y.lpSurface;
553 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
554 flipto->s.surface_desc.y.lpSurface = ptmp;
556 return DD_OK;
557 #else /* defined(HAVE_LIBXXF86DGA) */
558 return E_UNEXPECTED;
559 #endif /* defined(HAVE_LIBXXF86DGA) */
562 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Flip(
563 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
565 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
566 if (!this->s.ddraw->d.paintable)
567 return DD_OK;
569 if (!flipto) {
570 if (this->s.backbuffer)
571 flipto = this->s.backbuffer;
572 else
573 flipto = this;
576 Xlib_copy_surface_on_screen(this);
578 if (flipto->s.palette && flipto->s.palette->cm) {
579 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,flipto->s.palette->cm);
581 if (flipto!=this) {
582 XImage *tmp;
583 LPVOID *surf;
584 tmp = this->t.xlib.image;
585 this->t.xlib.image = flipto->t.xlib.image;
586 flipto->t.xlib.image = tmp;
587 surf = this->s.surface_desc.y.lpSurface;
588 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
589 flipto->s.surface_desc.y.lpSurface = surf;
591 return DD_OK;
595 /* The IDirectDrawSurface4::SetPalette method attaches the specified
596 * DirectDrawPalette object to a surface. The surface uses this palette for all
597 * subsequent operations. The palette change takes place immediately.
599 static HRESULT WINAPI Xlib_IDirectDrawSurface4_SetPalette(
600 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
602 int i;
603 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
605 if (pal == NULL) {
606 if( this->s.palette != NULL )
607 this->s.palette->lpvtbl->fnRelease( this->s.palette );
608 this->s.palette = pal;
610 return DD_OK;
613 if( !(pal->cm) && (this->s.ddraw->d.screen_depth<=8))
615 pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,
616 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
618 if (!Options.managed)
619 TSXInstallColormap(display,pal->cm);
621 for (i=0;i<256;i++) {
622 XColor xc;
624 xc.red = pal->palents[i].peRed<<8;
625 xc.blue = pal->palents[i].peBlue<<8;
626 xc.green = pal->palents[i].peGreen<<8;
627 xc.flags = DoRed|DoBlue|DoGreen;
628 xc.pixel = i;
629 TSXStoreColor(display,pal->cm,&xc);
631 TSXInstallColormap(display,pal->cm);
634 /* According to spec, we are only supposed to
635 * AddRef if this is not the same palette.
637 if( this->s.palette != pal )
639 if( pal != NULL )
640 pal->lpvtbl->fnAddRef( pal );
641 if( this->s.palette != NULL )
642 this->s.palette->lpvtbl->fnRelease( this->s.palette );
643 this->s.palette = pal;
645 /* I think that we need to attach it to all backbuffers...*/
646 if( this->s.backbuffer ) {
647 if( this->s.backbuffer->s.palette )
648 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
649 this->s.backbuffer->s.palette );
650 this->s.backbuffer->s.palette = pal;
651 if( pal )
652 pal->lpvtbl->fnAddRef( pal );
654 /* Perform the refresh */
655 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
657 return DD_OK;
660 static HRESULT WINAPI DGA_IDirectDrawSurface4_SetPalette(
661 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
663 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
664 #ifdef HAVE_LIBXXF86DGA
665 /* According to spec, we are only supposed to
666 * AddRef if this is not the same palette.
668 if( this->s.palette != pal )
670 if( pal != NULL )
671 pal->lpvtbl->fnAddRef( pal );
672 if( this->s.palette != NULL )
673 this->s.palette->lpvtbl->fnRelease( this->s.palette );
674 this->s.palette = pal;
676 /* I think that we need to attach it to all backbuffers...*/
677 if( this->s.backbuffer ) {
678 if( this->s.backbuffer->s.palette )
679 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
680 this->s.backbuffer->s.palette = pal;
681 if( pal ) pal->lpvtbl->fnAddRef( pal );
683 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
685 return DD_OK;
686 #else /* defined(HAVE_LIBXXF86DGA) */
687 return E_UNEXPECTED;
688 #endif /* defined(HAVE_LIBXXF86DGA) */
693 static HRESULT WINAPI IDirectDrawSurface4_Blt(
694 LPDIRECTDRAWSURFACE4 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE4 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
696 RECT32 xdst,xsrc;
697 DDSURFACEDESC ddesc,sdesc;
698 int i,j;
700 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
701 this,rdst,src,rsrc,dwFlags,lpbltfx);
703 if (src != NULL)
704 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
705 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
707 if (TRACE_ON(ddraw)) {
708 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
709 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
710 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
711 if (dwFlags & DDBLT_DDFX) {
712 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
716 if (rdst) {
717 memcpy(&xdst,rdst,sizeof(xdst));
718 } else {
719 xdst.top = 0;
720 xdst.bottom = ddesc.dwHeight;
721 xdst.left = 0;
722 xdst.right = ddesc.dwWidth;
725 if (rsrc) {
726 memcpy(&xsrc,rsrc,sizeof(xsrc));
727 } else {
728 if (src) {
729 xsrc.top = 0;
730 xsrc.bottom = sdesc.dwHeight;
731 xsrc.left = 0;
732 xsrc.right = sdesc.dwWidth;
733 } else {
734 memset(&xsrc,0,sizeof(xsrc));
738 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
740 /* First, all the 'source-less' blits */
741 if (dwFlags & DDBLT_COLORFILL) {
742 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
743 LPBYTE xline,xpixel;
745 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
746 for (i=xdst.top;i<xdst.bottom;i++) {
747 xpixel = xline+bpp*xdst.left;
749 for (j=xdst.left;j<xdst.right;j++) {
750 /* FIXME: this only works on little endian
751 * architectures, where DWORD starts with low
752 * byte first!
754 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
755 xpixel += bpp;
757 xline += ddesc.lPitch;
759 dwFlags &= ~(DDBLT_COLORFILL);
762 if (dwFlags & DDBLT_DEPTHFILL) {
763 #ifdef HAVE_MESAGL
764 GLboolean ztest;
766 /* Clears the screen */
767 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
768 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
769 glGetBooleanv(GL_DEPTH_TEST, &ztest);
770 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
771 glClear(GL_DEPTH_BUFFER_BIT);
772 glDepthMask(ztest);
774 dwFlags &= ~(DDBLT_DEPTHFILL);
775 #endif HAVE_MESAGL
778 if (!src) {
779 if (dwFlags) {
780 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
782 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
783 return DD_OK;
786 /* Now the 'with source' blits */
788 /* Standard 'full-surface' blit without special effects */
789 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
790 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
791 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
792 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
793 !dwFlags
795 memcpy(ddesc.y.lpSurface,
796 sdesc.y.lpSurface,
797 ddesc.dwHeight * ddesc.lPitch);
798 } else {
799 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
800 int srcheight = xsrc.bottom - xsrc.top;
801 int srcwidth = xsrc.right - xsrc.left;
802 int dstheight = xdst.bottom - xdst.top;
803 int dstwidth = xdst.right - xdst.left;
804 int width = (xsrc.right - xsrc.left) * bpp;
805 int h;
807 /* Sanity check for rectangle sizes */
808 if ((srcheight != dstheight) || (srcwidth != dstwidth)) {
809 int x, y;
811 /* I think we should do a Blit with 'stretching' here....
812 Tomb Raider II uses this to display the background during the menu selection
813 when the screen resolution is != than 640x480 */
814 TRACE(ddraw, "Blt with stretching\n");
816 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
817 if (bpp == 1) {
818 /* In this case, we cannot do any anti-aliasing */
819 if(dwFlags & DDBLT_KEYSRC) {
820 for (y = xdst.top; y < xdst.bottom; y++) {
821 for (x = xdst.left; x < xdst.right; x++) {
822 double sx, sy;
823 unsigned char tmp;
824 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
825 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
827 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
828 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
830 tmp = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
832 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
833 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
834 dbuf[(y * ddesc.lPitch) + x] = tmp;
837 } else {
838 for (y = xdst.top; y < xdst.bottom; y++) {
839 for (x = xdst.left; x < xdst.right; x++) {
840 double sx, sy;
841 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
842 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
844 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
845 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
847 dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
851 } else {
852 FIXME(ddraw, "Not done yet for depth != 8\n");
854 } else {
855 /* Same size => fast blit */
856 if (dwFlags & DDBLT_KEYSRC) {
857 switch (bpp) {
858 case 1: {
859 unsigned char tmp,*psrc,*pdst;
860 int h,i;
862 for (h = 0; h < srcheight; h++) {
863 psrc=sdesc.y.lpSurface +
864 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
865 pdst=ddesc.y.lpSurface +
866 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
867 for(i=0;i<srcwidth;i++) {
868 tmp=*(psrc + i);
869 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
870 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
871 *(pdst + i)=tmp;
874 dwFlags&=~(DDBLT_KEYSRC);
875 } break;
877 case 2: {
878 unsigned short tmp,*psrc,*pdst;
879 int h,i;
881 for (h = 0; h < srcheight; h++) {
882 psrc=sdesc.y.lpSurface +
883 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
884 pdst=ddesc.y.lpSurface +
885 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
886 for(i=0;i<srcwidth;i++) {
887 tmp=*(psrc + i);
888 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
889 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
890 *(pdst + i)=tmp;
893 dwFlags&=~(DDBLT_KEYSRC);
894 } break;
896 default:
897 FIXME(ddraw, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
899 } else {
900 /* Non-stretching Blt without color keying */
901 for (h = 0; h < srcheight; h++) {
902 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
903 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
904 width);
910 if (dwFlags && FIXME_ON(ddraw)) {
911 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
914 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
915 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
917 return DD_OK;
920 static HRESULT WINAPI IDirectDrawSurface4_BltFast(
921 LPDIRECTDRAWSURFACE4 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT32 rsrc,DWORD trans
923 int i,bpp,w,h;
924 DDSURFACEDESC ddesc,sdesc;
926 if (1 || TRACE_ON(ddraw)) {
927 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
928 this,dstx,dsty,src,rsrc,trans
930 FIXME(ddraw," trans:");
931 if (FIXME_ON(ddraw))
932 _dump_DDBLTFAST(trans);
933 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
935 /* We need to lock the surfaces, or we won't get refreshes when done. */
936 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
937 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
938 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
939 h=rsrc->bottom-rsrc->top;
940 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
941 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
942 if (h<0) h=0;
943 w=rsrc->right-rsrc->left;
944 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
945 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
946 if (w<0) w=0;
948 for (i=0;i<h;i++) {
949 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
950 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
951 w*bpp
954 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
955 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
956 return DD_OK;
959 static HRESULT WINAPI IDirectDrawSurface4_BltBatch(
960 LPDIRECTDRAWSURFACE4 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
962 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
963 this,ddbltbatch,x,y
965 return DD_OK;
968 static HRESULT WINAPI IDirectDrawSurface4_GetCaps(
969 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS caps
971 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
972 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
973 return DD_OK;
976 static HRESULT WINAPI IDirectDrawSurface4_GetSurfaceDesc(
977 LPDIRECTDRAWSURFACE4 this,LPDDSURFACEDESC ddsd
978 ) {
979 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
980 this,ddsd);
982 /* Simply copy the surface description stored in the object */
983 *ddsd = this->s.surface_desc;
985 if (TRACE_ON(ddraw)) {
986 fprintf(stderr," flags: ");
987 _dump_DDSD(ddsd->dwFlags);
988 if (ddsd->dwFlags & DDSD_CAPS) {
989 fprintf(stderr, " caps: ");
990 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
992 fprintf(stderr,"\n");
995 return DD_OK;
998 static ULONG WINAPI IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4 this) {
999 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1001 return ++(this->ref);
1004 static ULONG WINAPI DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1005 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1007 #ifdef HAVE_LIBXXF86DGA
1008 if (!--(this->ref)) {
1009 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1010 /* clear out of surface list */
1011 if (this->t.dga.fb_height == -1) {
1012 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1013 } else {
1014 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
1017 /* Free the backbuffer */
1018 if (this->s.backbuffer)
1019 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1021 HeapFree(GetProcessHeap(),0,this);
1022 return 0;
1024 #endif /* defined(HAVE_LIBXXF86DGA) */
1025 return this->ref;
1028 static ULONG WINAPI Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1029 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1031 if (!--(this->ref)) {
1032 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1034 if( this->s.backbuffer )
1035 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1037 if (this->t.xlib.image != NULL) {
1038 if (this->s.ddraw->d.depth != this->s.ddraw->d.screen_depth) {
1039 /* In pixel conversion mode, there are two buffers to release... */
1040 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1042 #ifdef HAVE_LIBXXSHM
1043 if (this->s.ddraw->e.xlib.xshm_active) {
1044 TSXShmDetach(display, &(this->t.xlib.shminfo));
1045 TSXDestroyImage(this->t.xlib.image);
1046 shmdt(this->t.xlib.shminfo.shmaddr);
1047 } else {
1048 #endif
1049 HeapFree(GetProcessHeap(),0,this->t.xlib.image->data);
1050 this->t.xlib.image->data = NULL;
1051 TSXDestroyImage(this->t.xlib.image);
1052 #ifdef HAVE_LIBXXSHM
1054 #endif
1056 } else {
1057 this->t.xlib.image->data = NULL;
1059 #ifdef HAVE_LIBXXSHM
1060 if (this->s.ddraw->e.xlib.xshm_active) {
1061 TSXShmDetach(display, &(this->t.xlib.shminfo));
1062 TSXDestroyImage(this->t.xlib.image);
1063 shmdt(this->t.xlib.shminfo.shmaddr);
1064 } else {
1065 #endif
1066 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1067 TSXDestroyImage(this->t.xlib.image);
1068 #ifdef HAVE_LIBXXSHM
1070 #endif
1073 this->t.xlib.image = 0;
1074 } else {
1075 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1078 if (this->s.palette)
1079 this->s.palette->lpvtbl->fnRelease(this->s.palette);
1081 HeapFree(GetProcessHeap(),0,this);
1082 return 0;
1085 return this->ref;
1088 static HRESULT WINAPI IDirectDrawSurface4_GetAttachedSurface(
1089 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1091 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1092 this, lpddsd, lpdsf);
1094 if (TRACE_ON(ddraw)) {
1095 TRACE(ddraw," caps ");
1096 _dump_DDSCAPS(lpddsd->dwCaps);
1099 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1100 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1101 return E_FAIL;
1104 /* FIXME: should handle more than one backbuffer */
1105 *lpdsf = this->s.backbuffer;
1107 if( this->s.backbuffer )
1108 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
1110 return DD_OK;
1113 static HRESULT WINAPI IDirectDrawSurface4_Initialize(
1114 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1116 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
1118 return DDERR_ALREADYINITIALIZED;
1121 static HRESULT WINAPI IDirectDrawSurface4_GetPixelFormat(
1122 LPDIRECTDRAWSURFACE4 this,LPDDPIXELFORMAT pf
1124 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
1126 *pf = this->s.surface_desc.ddpfPixelFormat;
1128 return DD_OK;
1131 static HRESULT WINAPI IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4 this,DWORD dwFlags) {
1132 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
1133 return DD_OK;
1136 static HRESULT WINAPI IDirectDrawSurface4_GetOverlayPosition(
1137 LPDIRECTDRAWSURFACE4 this,LPLONG x1,LPLONG x2
1139 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
1140 return DD_OK;
1143 static HRESULT WINAPI IDirectDrawSurface4_SetClipper(
1144 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWCLIPPER clipper
1146 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
1147 return DD_OK;
1150 static HRESULT WINAPI IDirectDrawSurface4_AddAttachedSurface(
1151 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 surf
1153 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
1155 this->lpvtbl->fnAddRef(this);
1157 /* This hack will be enough for the moment */
1158 if (this->s.backbuffer == NULL)
1159 this->s.backbuffer = surf;
1160 return DD_OK;
1163 static HRESULT WINAPI IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4 this,HDC32* lphdc) {
1164 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
1165 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1166 return DD_OK;
1169 static HRESULT WINAPI IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4 this,HDC32 hdc) {
1170 DDSURFACEDESC desc;
1171 DWORD x, y;
1173 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
1174 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1176 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1177 I fill it with 'dummy' values to have something on the screen */
1178 this->lpvtbl->fnLock(this,NULL,&desc,0,0);
1179 for (y = 0; y < desc.dwHeight; y++) {
1180 for (x = 0; x < desc.dwWidth; x++) {
1181 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) this + x + y;
1184 this->lpvtbl->fnUnlock(this,NULL);
1186 return DD_OK;
1190 static HRESULT WINAPI IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4 this,REFIID refiid,LPVOID *obj) {
1191 char xrefiid[50];
1193 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1194 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1196 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1197 * the same interface. And IUnknown does that too of course.
1199 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1200 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1201 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1202 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1203 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1205 *obj = this;
1206 this->lpvtbl->fnAddRef(this);
1208 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1210 return S_OK;
1212 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1214 /* Texture interface */
1215 *obj = d3dtexture2_create(this);
1216 this->lpvtbl->fnAddRef(this);
1218 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1220 return S_OK;
1222 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1224 /* Texture interface */
1225 *obj = d3dtexture_create(this);
1226 this->lpvtbl->fnAddRef(this);
1228 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1230 return S_OK;
1232 else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj))
1234 /* It is the OpenGL Direct3D Device */
1235 this->lpvtbl->fnAddRef(this);
1237 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1239 return S_OK;
1242 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1243 return OLE_E_ENUM_NOMORE;
1246 static HRESULT WINAPI IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4 this) {
1247 TRACE(ddraw,"(%p)->(), stub!\n",this);
1248 return DD_OK; /* hmm */
1251 static HRESULT WINAPI IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1252 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
1253 return DD_OK;
1256 static HRESULT WINAPI IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4 this) {
1257 FIXME(ddraw,"(%p)->(),stub!\n",this);
1258 return DD_OK;
1261 static HRESULT WINAPI IDirectDrawSurface4_SetColorKey(
1262 LPDIRECTDRAWSURFACE4 this, DWORD dwFlags, LPDDCOLORKEY ckey )
1264 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);
1266 if( dwFlags & DDCKEY_SRCBLT )
1268 dwFlags &= ~DDCKEY_SRCBLT;
1269 this->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1270 memcpy( &(this->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1273 if( dwFlags & DDCKEY_DESTBLT )
1275 dwFlags &= ~DDCKEY_DESTBLT;
1276 this->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1277 memcpy( &(this->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1280 if( dwFlags & DDCKEY_SRCOVERLAY )
1282 dwFlags &= ~DDCKEY_SRCOVERLAY;
1283 this->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1284 memcpy( &(this->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1287 if( dwFlags & DDCKEY_DESTOVERLAY )
1289 dwFlags &= ~DDCKEY_DESTOVERLAY;
1290 this->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1291 memcpy( &(this->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1294 if( dwFlags )
1296 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1299 return DD_OK;
1303 static HRESULT WINAPI IDirectDrawSurface4_AddOverlayDirtyRect(
1304 LPDIRECTDRAWSURFACE4 this,
1305 LPRECT32 lpRect )
1307 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
1309 return DD_OK;
1312 static HRESULT WINAPI IDirectDrawSurface4_DeleteAttachedSurface(
1313 LPDIRECTDRAWSURFACE4 this,
1314 DWORD dwFlags,
1315 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1317 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1319 return DD_OK;
1322 static HRESULT WINAPI IDirectDrawSurface4_EnumOverlayZOrders(
1323 LPDIRECTDRAWSURFACE4 this,
1324 DWORD dwFlags,
1325 LPVOID lpContext,
1326 LPDDENUMSURFACESCALLBACK lpfnCallback )
1328 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1329 lpContext, lpfnCallback );
1331 return DD_OK;
1334 static HRESULT WINAPI IDirectDrawSurface4_GetClipper(
1335 LPDIRECTDRAWSURFACE4 this,
1336 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1338 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1340 return DD_OK;
1343 static HRESULT WINAPI IDirectDrawSurface4_GetColorKey(
1344 LPDIRECTDRAWSURFACE4 this,
1345 DWORD dwFlags,
1346 LPDDCOLORKEY lpDDColorKey )
1348 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);
1350 if( dwFlags & DDCKEY_SRCBLT ) {
1351 dwFlags &= ~DDCKEY_SRCBLT;
1352 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1355 if( dwFlags & DDCKEY_DESTBLT )
1357 dwFlags &= ~DDCKEY_DESTBLT;
1358 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1361 if( dwFlags & DDCKEY_SRCOVERLAY )
1363 dwFlags &= ~DDCKEY_SRCOVERLAY;
1364 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1367 if( dwFlags & DDCKEY_DESTOVERLAY )
1369 dwFlags &= ~DDCKEY_DESTOVERLAY;
1370 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1373 if( dwFlags )
1375 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1378 return DD_OK;
1381 static HRESULT WINAPI IDirectDrawSurface4_GetFlipStatus(
1382 LPDIRECTDRAWSURFACE4 this,
1383 DWORD dwFlags )
1385 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1387 return DD_OK;
1390 static HRESULT WINAPI IDirectDrawSurface4_GetPalette(
1391 LPDIRECTDRAWSURFACE4 this,
1392 LPDIRECTDRAWPALETTE* lplpDDPalette )
1394 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1396 return DD_OK;
1399 static HRESULT WINAPI IDirectDrawSurface4_SetOverlayPosition(
1400 LPDIRECTDRAWSURFACE4 this,
1401 LONG lX,
1402 LONG lY)
1404 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1406 return DD_OK;
1409 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlay(
1410 LPDIRECTDRAWSURFACE4 this,
1411 LPRECT32 lpSrcRect,
1412 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1413 LPRECT32 lpDestRect,
1414 DWORD dwFlags,
1415 LPDDOVERLAYFX lpDDOverlayFx )
1417 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1418 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1420 return DD_OK;
1423 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayDisplay(
1424 LPDIRECTDRAWSURFACE4 this,
1425 DWORD dwFlags )
1427 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1429 return DD_OK;
1432 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayZOrder(
1433 LPDIRECTDRAWSURFACE4 this,
1434 DWORD dwFlags,
1435 LPDIRECTDRAWSURFACE4 lpDDSReference )
1437 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1439 return DD_OK;
1442 static HRESULT WINAPI IDirectDrawSurface4_GetDDInterface(
1443 LPDIRECTDRAWSURFACE4 this,
1444 LPVOID* lplpDD )
1446 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1448 /* Not sure about that... */
1449 *lplpDD = (void *) this->s.ddraw;
1451 return DD_OK;
1454 static HRESULT WINAPI IDirectDrawSurface4_PageLock(
1455 LPDIRECTDRAWSURFACE4 this,
1456 DWORD dwFlags )
1458 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1460 return DD_OK;
1463 static HRESULT WINAPI IDirectDrawSurface4_PageUnlock(
1464 LPDIRECTDRAWSURFACE4 this,
1465 DWORD dwFlags )
1467 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1469 return DD_OK;
1472 static HRESULT WINAPI IDirectDrawSurface4_SetSurfaceDesc(
1473 LPDIRECTDRAWSURFACE4 this,
1474 LPDDSURFACEDESC lpDDSD,
1475 DWORD dwFlags )
1477 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1479 return DD_OK;
1482 static HRESULT WINAPI IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4 this,
1483 REFGUID guidTag,
1484 LPVOID lpData,
1485 DWORD cbSize,
1486 DWORD dwFlags) {
1487 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag, lpData, cbSize, dwFlags);
1489 return DD_OK;
1492 static HRESULT WINAPI IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4 this,
1493 REFGUID guidTag,
1494 LPVOID lpBuffer,
1495 LPDWORD lpcbBufferSize) {
1496 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", this, guidTag, lpBuffer, lpcbBufferSize);
1498 return DD_OK;
1501 static HRESULT WINAPI IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4 this,
1502 REFGUID guidTag) {
1503 FIXME(ddraw, "(%p)->(%p)\n", this, guidTag);
1505 return DD_OK;
1508 static HRESULT WINAPI IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4 this,
1509 LPDWORD lpValue) {
1510 FIXME(ddraw, "(%p)->(%p)\n", this, lpValue);
1512 return DD_OK;
1515 static HRESULT WINAPI IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 this) {
1516 FIXME(ddraw, "(%p)\n", this);
1518 return DD_OK;
1521 static struct IDirectDrawSurface4_VTable dga_dds4vt = {
1522 IDirectDrawSurface4_QueryInterface,
1523 IDirectDrawSurface4_AddRef,
1524 DGA_IDirectDrawSurface4_Release,
1525 IDirectDrawSurface4_AddAttachedSurface,
1526 IDirectDrawSurface4_AddOverlayDirtyRect,
1527 IDirectDrawSurface4_Blt,
1528 IDirectDrawSurface4_BltBatch,
1529 IDirectDrawSurface4_BltFast,
1530 IDirectDrawSurface4_DeleteAttachedSurface,
1531 IDirectDrawSurface4_EnumAttachedSurfaces,
1532 IDirectDrawSurface4_EnumOverlayZOrders,
1533 DGA_IDirectDrawSurface4_Flip,
1534 IDirectDrawSurface4_GetAttachedSurface,
1535 IDirectDrawSurface4_GetBltStatus,
1536 IDirectDrawSurface4_GetCaps,
1537 IDirectDrawSurface4_GetClipper,
1538 IDirectDrawSurface4_GetColorKey,
1539 IDirectDrawSurface4_GetDC,
1540 IDirectDrawSurface4_GetFlipStatus,
1541 IDirectDrawSurface4_GetOverlayPosition,
1542 IDirectDrawSurface4_GetPalette,
1543 IDirectDrawSurface4_GetPixelFormat,
1544 IDirectDrawSurface4_GetSurfaceDesc,
1545 IDirectDrawSurface4_Initialize,
1546 IDirectDrawSurface4_IsLost,
1547 IDirectDrawSurface4_Lock,
1548 IDirectDrawSurface4_ReleaseDC,
1549 IDirectDrawSurface4_Restore,
1550 IDirectDrawSurface4_SetClipper,
1551 IDirectDrawSurface4_SetColorKey,
1552 IDirectDrawSurface4_SetOverlayPosition,
1553 DGA_IDirectDrawSurface4_SetPalette,
1554 DGA_IDirectDrawSurface4_Unlock,
1555 IDirectDrawSurface4_UpdateOverlay,
1556 IDirectDrawSurface4_UpdateOverlayDisplay,
1557 IDirectDrawSurface4_UpdateOverlayZOrder,
1558 IDirectDrawSurface4_GetDDInterface,
1559 IDirectDrawSurface4_PageLock,
1560 IDirectDrawSurface4_PageUnlock,
1561 IDirectDrawSurface4_SetSurfaceDesc,
1562 IDirectDrawSurface4_SetPrivateData,
1563 IDirectDrawSurface4_GetPrivateData,
1564 IDirectDrawSurface4_FreePrivateData,
1565 IDirectDrawSurface4_GetUniquenessValue,
1566 IDirectDrawSurface4_ChangeUniquenessValue
1569 static struct IDirectDrawSurface4_VTable xlib_dds4vt = {
1570 IDirectDrawSurface4_QueryInterface,
1571 IDirectDrawSurface4_AddRef,
1572 Xlib_IDirectDrawSurface4_Release,
1573 IDirectDrawSurface4_AddAttachedSurface,
1574 IDirectDrawSurface4_AddOverlayDirtyRect,
1575 IDirectDrawSurface4_Blt,
1576 IDirectDrawSurface4_BltBatch,
1577 IDirectDrawSurface4_BltFast,
1578 IDirectDrawSurface4_DeleteAttachedSurface,
1579 IDirectDrawSurface4_EnumAttachedSurfaces,
1580 IDirectDrawSurface4_EnumOverlayZOrders,
1581 Xlib_IDirectDrawSurface4_Flip,
1582 IDirectDrawSurface4_GetAttachedSurface,
1583 IDirectDrawSurface4_GetBltStatus,
1584 IDirectDrawSurface4_GetCaps,
1585 IDirectDrawSurface4_GetClipper,
1586 IDirectDrawSurface4_GetColorKey,
1587 IDirectDrawSurface4_GetDC,
1588 IDirectDrawSurface4_GetFlipStatus,
1589 IDirectDrawSurface4_GetOverlayPosition,
1590 IDirectDrawSurface4_GetPalette,
1591 IDirectDrawSurface4_GetPixelFormat,
1592 IDirectDrawSurface4_GetSurfaceDesc,
1593 IDirectDrawSurface4_Initialize,
1594 IDirectDrawSurface4_IsLost,
1595 IDirectDrawSurface4_Lock,
1596 IDirectDrawSurface4_ReleaseDC,
1597 IDirectDrawSurface4_Restore,
1598 IDirectDrawSurface4_SetClipper,
1599 IDirectDrawSurface4_SetColorKey,
1600 IDirectDrawSurface4_SetOverlayPosition,
1601 Xlib_IDirectDrawSurface4_SetPalette,
1602 Xlib_IDirectDrawSurface4_Unlock,
1603 IDirectDrawSurface4_UpdateOverlay,
1604 IDirectDrawSurface4_UpdateOverlayDisplay,
1605 IDirectDrawSurface4_UpdateOverlayZOrder,
1606 IDirectDrawSurface4_GetDDInterface,
1607 IDirectDrawSurface4_PageLock,
1608 IDirectDrawSurface4_PageUnlock,
1609 IDirectDrawSurface4_SetSurfaceDesc,
1610 IDirectDrawSurface4_SetPrivateData,
1611 IDirectDrawSurface4_GetPrivateData,
1612 IDirectDrawSurface4_FreePrivateData,
1613 IDirectDrawSurface4_GetUniquenessValue,
1614 IDirectDrawSurface4_ChangeUniquenessValue
1617 /******************************************************************************
1618 * DirectDrawCreateClipper (DDRAW.7)
1620 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1621 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1622 LPUNKNOWN pUnkOuter)
1624 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1626 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1627 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1628 (*lplpDDClipper)->ref = 1;
1630 return DD_OK;
1633 /******************************************************************************
1634 * IDirectDrawClipper
1636 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1637 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1639 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1640 return DD_OK;
1643 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1644 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1646 this->ref--;
1647 if (this->ref)
1648 return this->ref;
1649 HeapFree(GetProcessHeap(),0,this);
1650 return 0;
1653 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1654 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1656 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1657 if (hmm) *hmm=0;
1658 return DD_OK;
1661 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1662 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1664 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1665 return DD_OK;
1668 static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
1669 LPDIRECTDRAWCLIPPER this,
1670 REFIID riid,
1671 LPVOID* ppvObj )
1673 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
1674 return OLE_E_ENUM_NOMORE;
1677 static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
1679 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1680 return ++(this->ref);
1683 static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
1684 LPDIRECTDRAWCLIPPER this,
1685 HWND32* HWndPtr )
1687 FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
1688 return DD_OK;
1691 static HRESULT WINAPI IDirectDrawClipper_Initialize(
1692 LPDIRECTDRAWCLIPPER this,
1693 LPDIRECTDRAW lpDD,
1694 DWORD dwFlags )
1696 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
1697 return DD_OK;
1700 static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
1701 LPDIRECTDRAWCLIPPER this,
1702 BOOL32* lpbChanged )
1704 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
1705 return DD_OK;
1708 static struct IDirectDrawClipper_VTable ddclipvt = {
1709 IDirectDrawClipper_QueryInterface,
1710 IDirectDrawClipper_AddRef,
1711 IDirectDrawClipper_Release,
1712 IDirectDrawClipper_GetClipList,
1713 IDirectDrawClipper_GetHWnd,
1714 IDirectDrawClipper_Initialize,
1715 IDirectDrawClipper_IsClipListChanged,
1716 IDirectDrawClipper_SetClipList,
1717 IDirectDrawClipper_SetHwnd
1721 /******************************************************************************
1722 * IDirectDrawPalette
1724 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1725 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1727 int i;
1729 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1730 this,x,start,count,palent);
1732 if (!this->cm) /* should not happen */ {
1733 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1734 return DDERR_GENERIC;
1736 for (i=0;i<count;i++) {
1737 palent[i].peRed = this->palents[start+i].peRed;
1738 palent[i].peBlue = this->palents[start+i].peBlue;
1739 palent[i].peGreen = this->palents[start+i].peGreen;
1740 palent[i].peFlags = this->palents[start+i].peFlags;
1743 return DD_OK;
1746 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1747 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1749 XColor xc;
1750 int i;
1752 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1753 this,x,start,count,palent
1755 for (i=0;i<count;i++) {
1756 xc.red = palent[i].peRed<<8;
1757 xc.blue = palent[i].peBlue<<8;
1758 xc.green = palent[i].peGreen<<8;
1759 xc.flags = DoRed|DoBlue|DoGreen;
1760 xc.pixel = start+i;
1762 if (this->cm)
1763 TSXStoreColor(display,this->cm,&xc);
1765 this->palents[start+i].peRed = palent[i].peRed;
1766 this->palents[start+i].peBlue = palent[i].peBlue;
1767 this->palents[start+i].peGreen = palent[i].peGreen;
1768 this->palents[start+i].peFlags = palent[i].peFlags;
1771 /* Now, if we are in 'depth conversion mode', update the screen palette */
1772 if (this->ddraw->d.depth != this->ddraw->d.screen_depth) {
1773 int i;
1775 switch (this->ddraw->d.screen_depth) {
1776 case 16: {
1777 unsigned short *screen_palette = (unsigned short *) this->screen_palents;
1779 for (i = 0; i < count; i++) {
1780 screen_palette[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
1781 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
1782 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
1784 } break;
1786 default:
1787 ERR(ddraw, "Memory corruption !\n");
1788 break;
1792 if (!this->cm) /* should not happen */ {
1794 return DD_OK;
1797 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1798 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1800 #ifdef HAVE_LIBXXF86DGA
1801 XColor xc;
1802 Colormap cm;
1803 int i;
1805 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1806 this,x,start,count,palent
1808 if (!this->cm) /* should not happen */ {
1809 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1810 return DDERR_GENERIC;
1812 /* FIXME: free colorcells instead of freeing whole map */
1813 cm = this->cm;
1814 this->cm = TSXCopyColormapAndFree(display,this->cm);
1815 TSXFreeColormap(display,cm);
1817 for (i=0;i<count;i++) {
1818 xc.red = palent[i].peRed<<8;
1819 xc.blue = palent[i].peBlue<<8;
1820 xc.green = palent[i].peGreen<<8;
1821 xc.flags = DoRed|DoBlue|DoGreen;
1822 xc.pixel = i+start;
1824 TSXStoreColor(display,this->cm,&xc);
1826 this->palents[start+i].peRed = palent[i].peRed;
1827 this->palents[start+i].peBlue = palent[i].peBlue;
1828 this->palents[start+i].peGreen = palent[i].peGreen;
1829 this->palents[start+i].peFlags = palent[i].peFlags;
1831 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1832 return DD_OK;
1833 #else /* defined(HAVE_LIBXXF86DGA) */
1834 return E_UNEXPECTED;
1835 #endif /* defined(HAVE_LIBXXF86DGA) */
1838 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1839 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1840 if (!--(this->ref)) {
1841 if (this->cm) {
1842 TSXFreeColormap(display,this->cm);
1843 this->cm = 0;
1845 HeapFree(GetProcessHeap(),0,this);
1846 return 0;
1848 return this->ref;
1851 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1853 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1854 return ++(this->ref);
1857 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1858 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1860 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1862 return DDERR_ALREADYINITIALIZED;
1865 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1866 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1868 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1869 return DD_OK;
1872 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1873 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1875 char xrefiid[50];
1877 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1878 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1880 return S_OK;
1883 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1884 IDirectDrawPalette_QueryInterface,
1885 IDirectDrawPalette_AddRef,
1886 IDirectDrawPalette_Release,
1887 IDirectDrawPalette_GetCaps,
1888 IDirectDrawPalette_GetEntries,
1889 IDirectDrawPalette_Initialize,
1890 DGA_IDirectDrawPalette_SetEntries
1893 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1894 IDirectDrawPalette_QueryInterface,
1895 IDirectDrawPalette_AddRef,
1896 IDirectDrawPalette_Release,
1897 IDirectDrawPalette_GetCaps,
1898 IDirectDrawPalette_GetEntries,
1899 IDirectDrawPalette_Initialize,
1900 Xlib_IDirectDrawPalette_SetEntries
1903 /*******************************************************************************
1904 * IDirect3D
1906 static HRESULT WINAPI IDirect3D_QueryInterface(
1907 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1909 /* FIXME: Not sure if this is correct */
1910 char xrefiid[50];
1912 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1913 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1914 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1915 *obj = this;
1916 this->lpvtbl->fnAddRef(this);
1918 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
1920 return S_OK;
1922 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1923 LPDIRECT3D d3d;
1925 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1926 d3d->ref = 1;
1927 d3d->ddraw = (LPDIRECTDRAW)this;
1928 this->lpvtbl->fnAddRef(this);
1929 d3d->lpvtbl = &d3dvt;
1930 *obj = d3d;
1932 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
1934 return S_OK;
1936 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
1937 LPDIRECT3D2 d3d;
1939 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1940 d3d->ref = 1;
1941 d3d->ddraw = (LPDIRECTDRAW)this;
1942 this->lpvtbl->fnAddRef(this);
1943 d3d->lpvtbl = &d3d2vt;
1944 *obj = d3d;
1946 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
1948 return S_OK;
1950 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1951 return OLE_E_ENUM_NOMORE;
1954 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1955 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1957 return ++(this->ref);
1960 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1962 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1964 if (!--(this->ref)) {
1965 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1966 HeapFree(GetProcessHeap(),0,this);
1967 return 0;
1969 return this->ref;
1972 static HRESULT WINAPI IDirect3D_Initialize(
1973 LPDIRECT3D this, REFIID refiid )
1975 /* FIXME: Not sure if this is correct */
1976 char xrefiid[50];
1978 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1979 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1981 return DDERR_ALREADYINITIALIZED;
1984 static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this,
1985 LPD3DENUMDEVICESCALLBACK cb,
1986 LPVOID context) {
1987 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1989 /* Call functions defined in d3ddevices.c */
1990 if (d3d_OpenGL_dx3(cb, context))
1991 return DD_OK;
1993 return DD_OK;
1996 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,
1997 LPDIRECT3DLIGHT *lplight,
1998 IUnknown *lpunk)
2000 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
2002 /* Call the creation function that is located in d3dlight.c */
2003 *lplight = d3dlight_create_dx3(this);
2005 return DD_OK;
2008 static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this,
2009 LPDIRECT3DMATERIAL *lpmaterial,
2010 IUnknown *lpunk)
2012 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2014 /* Call the creation function that is located in d3dviewport.c */
2015 *lpmaterial = d3dmaterial_create(this);
2017 return DD_OK;
2020 static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this,
2021 LPDIRECT3DVIEWPORT *lpviewport,
2022 IUnknown *lpunk)
2024 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2026 /* Call the creation function that is located in d3dviewport.c */
2027 *lpviewport = d3dviewport_create(this);
2029 return DD_OK;
2032 static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this,
2033 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2034 LPD3DFINDDEVICERESULT lpfinddevrst)
2036 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2038 return DD_OK;
2041 static struct IDirect3D_VTable d3dvt = {
2042 IDirect3D_QueryInterface,
2043 IDirect3D_AddRef,
2044 IDirect3D_Release,
2045 IDirect3D_Initialize,
2046 IDirect3D_EnumDevices,
2047 IDirect3D_CreateLight,
2048 IDirect3D_CreateMaterial,
2049 IDirect3D_CreateViewport,
2050 IDirect3D_FindDevice
2053 /*******************************************************************************
2054 * IDirect3D2
2056 static HRESULT WINAPI IDirect3D2_QueryInterface(
2057 LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) {
2058 /* For the moment, we use the same function as in IDirect3D */
2059 TRACE(ddraw, "Calling IDirect3D enumerating function.\n");
2061 return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj);
2064 static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) {
2065 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2067 return ++(this->ref);
2070 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
2071 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2073 if (!--(this->ref)) {
2074 this->ddraw->lpvtbl->fnRelease(this->ddraw);
2075 HeapFree(GetProcessHeap(),0,this);
2076 return 0;
2078 return this->ref;
2081 static HRESULT WINAPI IDirect3D2_EnumDevices(
2082 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2084 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
2086 /* Call functions defined in d3ddevices.c */
2087 if (d3d_OpenGL(cb, context))
2088 return DD_OK;
2090 return DD_OK;
2093 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,
2094 LPDIRECT3DLIGHT *lplight,
2095 IUnknown *lpunk)
2097 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
2099 /* Call the creation function that is located in d3dlight.c */
2100 *lplight = d3dlight_create(this);
2102 return DD_OK;
2105 static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this,
2106 LPDIRECT3DMATERIAL2 *lpmaterial,
2107 IUnknown *lpunk)
2109 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2111 /* Call the creation function that is located in d3dviewport.c */
2112 *lpmaterial = d3dmaterial2_create(this);
2114 return DD_OK;
2117 static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this,
2118 LPDIRECT3DVIEWPORT2 *lpviewport,
2119 IUnknown *lpunk)
2121 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2123 /* Call the creation function that is located in d3dviewport.c */
2124 *lpviewport = d3dviewport2_create(this);
2126 return DD_OK;
2129 static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this,
2130 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2131 LPD3DFINDDEVICERESULT lpfinddevrst)
2133 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2135 return DD_OK;
2138 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,
2139 REFCLSID rguid,
2140 LPDIRECTDRAWSURFACE surface,
2141 LPDIRECT3DDEVICE2 *device)
2143 char xbuf[50];
2145 WINE_StringFromCLSID(rguid,xbuf);
2146 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device);
2148 if (is_OpenGL(rguid, surface, device, this)) {
2149 this->lpvtbl->fnAddRef(this);
2150 return DD_OK;
2153 return DDERR_INVALIDPARAMS;
2156 static struct IDirect3D2_VTable d3d2vt = {
2157 IDirect3D2_QueryInterface,
2158 IDirect3D2_AddRef,
2159 IDirect3D2_Release,
2160 IDirect3D2_EnumDevices,
2161 IDirect3D2_CreateLight,
2162 IDirect3D2_CreateMaterial,
2163 IDirect3D2_CreateViewport,
2164 IDirect3D2_FindDevice,
2165 IDirect3D2_CreateDevice
2168 /*******************************************************************************
2169 * IDirectDraw
2172 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2173 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2175 static INT32 ddrawXlibThisOffset = 0;
2177 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
2178 LPDDSURFACEDESC lpddsd,
2179 LPDIRECTDRAWSURFACE lpdsf)
2181 int bpp;
2183 /* The surface was already allocated when entering in this function */
2184 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2186 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2187 /* This is a Z Buffer */
2188 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2189 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2190 } else {
2191 /* This is a standard image */
2192 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2193 /* No pixel format => use DirectDraw's format */
2194 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
2195 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2196 } else {
2197 /* To check what the program wants */
2198 if (TRACE_ON(ddraw)) {
2199 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2203 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2204 bpp = 1;
2205 } else {
2206 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2210 /* Copy the surface description */
2211 lpdsf->s.surface_desc = *lpddsd;
2213 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2214 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2215 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2217 return DD_OK;
2220 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
2221 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2223 #ifdef HAVE_LIBXXF86DGA
2224 int i;
2226 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
2227 if (TRACE_ON(ddraw)) {
2228 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2229 _dump_DDSD(lpddsd->dwFlags);
2230 fprintf(stderr,"caps ");
2231 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2232 fprintf(stderr,"]\n");
2235 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2236 this->lpvtbl->fnAddRef(this);
2238 (*lpdsf)->ref = 1;
2239 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds4vt;
2240 (*lpdsf)->s.ddraw = this;
2241 (*lpdsf)->s.palette = NULL;
2242 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2244 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2245 lpddsd->dwWidth = this->d.width;
2246 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2247 lpddsd->dwHeight = this->d.height;
2249 /* Check if this a 'primary surface' or not */
2250 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2251 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2253 /* This is THE primary surface => there is DGA-specific code */
2254 /* First, store the surface description */
2255 (*lpdsf)->s.surface_desc = *lpddsd;
2257 /* Find a viewport */
2258 for (i=0;i<32;i++)
2259 if (!(this->e.dga.vpmask & (1<<i)))
2260 break;
2261 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2262 /* if i == 32 or maximum ... return error */
2263 this->e.dga.vpmask|=(1<<i);
2264 (*lpdsf)->s.surface_desc.y.lpSurface =
2265 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
2266 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
2267 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
2268 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
2270 /* Add flags if there were not present */
2271 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2272 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2273 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2274 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d.width,this->d.height,lpddsd->lPitch);
2275 /* We put our surface always in video memory */
2276 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2277 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2278 (*lpdsf)->s.backbuffer = NULL;
2280 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2281 LPDIRECTDRAWSURFACE4 back;
2283 if (lpddsd->dwBackBufferCount>1)
2284 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2286 (*lpdsf)->s.backbuffer = back =
2287 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2288 this->lpvtbl->fnAddRef(this);
2289 back->ref = 1;
2290 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&dga_dds4vt;
2291 for (i=0;i<32;i++)
2292 if (!(this->e.dga.vpmask & (1<<i)))
2293 break;
2294 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2295 /* if i == 32 or maximum ... return error */
2296 this->e.dga.vpmask|=(1<<i);
2297 back->t.dga.fb_height = i*this->e.dga.fb_height;
2299 /* Copy the surface description from the front buffer */
2300 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2301 /* Change the parameters that are not the same */
2302 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
2303 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
2304 back->s.ddraw = this;
2305 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2306 * one! */
2308 /* Add relevant info to front and back buffers */
2309 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2310 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2311 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2312 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2313 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2315 } else {
2316 /* There is no DGA-specific code here...
2317 Go to the common surface creation function */
2318 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2321 return DD_OK;
2322 #else /* defined(HAVE_LIBXXF86DGA) */
2323 return E_UNEXPECTED;
2324 #endif /* defined(HAVE_LIBXXF86DGA) */
2327 #ifdef HAVE_LIBXXSHM
2328 /* Error handlers for Image creation */
2329 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2330 XShmErrorFlag = 1;
2331 return 0;
2334 static XImage *create_xshmimage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2335 XImage *img;
2336 int (*WineXHandler)(Display *, XErrorEvent *);
2338 img = TSXShmCreateImage(display,
2339 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2340 this->d.screen_depth,
2341 ZPixmap,
2342 NULL,
2343 &(lpdsf->t.xlib.shminfo),
2344 lpdsf->s.surface_desc.dwWidth,
2345 lpdsf->s.surface_desc.dwHeight);
2347 if (img == NULL) {
2348 ERR(ddraw, "Error creating XShm image. Reverting to standard X images !\n");
2349 this->e.xlib.xshm_active = 0;
2350 return NULL;
2353 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2354 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2355 ERR(ddraw, "Error creating shared memory segment. Reverting to standard X images !\n");
2356 this->e.xlib.xshm_active = 0;
2357 TSXDestroyImage(img);
2358 return NULL;
2361 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2363 if (img->data == (char *) -1) {
2364 ERR(ddraw, "Error attaching shared memory segment. Reverting to standard X images !\n");
2365 this->e.xlib.xshm_active = 0;
2366 TSXDestroyImage(img);
2367 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2368 return NULL;
2370 lpdsf->t.xlib.shminfo.readOnly = False;
2372 /* This is where things start to get trickier....
2373 First, we flush the current X connections to be sure to catch all non-XShm related
2374 errors */
2375 TSXSync(display, False);
2376 /* Then we enter in the non-thread safe part of the tests */
2377 EnterCriticalSection( &X11DRV_CritSection );
2379 /* Reset the error flag, sets our new error handler and try to attach the surface */
2380 XShmErrorFlag = 0;
2381 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2382 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2383 XSync(display, False);
2385 /* Check the error flag */
2386 if (XShmErrorFlag) {
2387 /* An error occured */
2388 XFlush(display);
2389 XShmErrorFlag = 0;
2390 XDestroyImage(img);
2391 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2392 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2393 XSetErrorHandler(WineXHandler);
2395 ERR(ddraw, "Error attaching shared memory segment to X server. Reverting to standard X images !\n");
2396 this->e.xlib.xshm_active = 0;
2398 /* Leave the critical section */
2399 LeaveCriticalSection( &X11DRV_CritSection );
2401 return NULL;
2404 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2405 but it may be a bit overkill.... */
2406 XSetErrorHandler(WineXHandler);
2407 LeaveCriticalSection( &X11DRV_CritSection );
2409 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2411 if (this->d.depth != this->d.screen_depth) {
2412 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2413 lpdsf->s.surface_desc.dwWidth *
2414 lpdsf->s.surface_desc.dwHeight *
2415 (this->d.depth / 8));
2416 } else {
2417 lpdsf->s.surface_desc.y.lpSurface = img->data;
2420 return img;
2422 #endif /* HAVE_LIBXXSHM */
2424 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2425 XImage *img = NULL;
2426 void *img_data;
2428 #ifdef HAVE_LIBXXSHM
2429 if (this->e.xlib.xshm_active) {
2430 img = create_xshmimage(this, lpdsf);
2433 if (img == NULL) {
2434 #endif
2435 /* Allocate surface memory */
2436 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2437 lpdsf->s.surface_desc.dwWidth *
2438 lpdsf->s.surface_desc.dwHeight *
2439 (this->d.depth / 8));
2441 if (this->d.depth != this->d.screen_depth) {
2442 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2443 lpdsf->s.surface_desc.dwWidth *
2444 lpdsf->s.surface_desc.dwHeight *
2445 (this->d.screen_depth / 8));
2446 } else {
2447 img_data = lpdsf->s.surface_desc.y.lpSurface;
2450 /* In this case, create an XImage */
2451 img =
2452 TSXCreateImage(display,
2453 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2454 this->d.screen_depth,
2455 ZPixmap,
2457 img_data,
2458 lpdsf->s.surface_desc.dwWidth,
2459 lpdsf->s.surface_desc.dwHeight,
2461 lpdsf->s.surface_desc.dwWidth * (this->d.screen_depth / 8)
2464 #ifdef HAVE_LIBXXSHM
2466 #endif
2467 if (this->d.depth != this->d.screen_depth) {
2468 lpdsf->s.surface_desc.lPitch = (this->d.depth / 8) * lpdsf->s.surface_desc.dwWidth;
2469 } else {
2470 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2473 return img;
2476 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
2477 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2479 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2480 this,lpddsd,lpdsf,lpunk);
2482 if (TRACE_ON(ddraw)) {
2483 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2484 _dump_DDSD(lpddsd->dwFlags);
2485 fprintf(stderr,"caps ");
2486 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2487 fprintf(stderr,"]\n");
2490 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2492 this->lpvtbl->fnAddRef(this);
2493 (*lpdsf)->s.ddraw = this;
2494 (*lpdsf)->ref = 1;
2495 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds4vt;
2496 (*lpdsf)->s.palette = NULL;
2497 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2499 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2500 lpddsd->dwWidth = this->d.width;
2501 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2502 lpddsd->dwHeight = this->d.height;
2504 /* Check if this a 'primary surface' or not */
2505 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2506 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2507 XImage *img;
2509 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
2511 /* First, store the surface description */
2512 (*lpdsf)->s.surface_desc = *lpddsd;
2514 /* Create the XImage */
2515 img = create_ximage(this, (LPDIRECTDRAWSURFACE4) *lpdsf);
2516 if (img == NULL)
2517 return DDERR_OUTOFMEMORY;
2518 (*lpdsf)->t.xlib.image = img;
2520 /* Add flags if there were not present */
2521 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2522 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2523 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2524 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2525 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2526 (*lpdsf)->s.backbuffer = NULL;
2528 /* Check for backbuffers */
2529 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2530 LPDIRECTDRAWSURFACE4 back;
2531 XImage *img;
2533 if (lpddsd->dwBackBufferCount>1)
2534 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2536 (*lpdsf)->s.backbuffer = back =
2537 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2539 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2541 this->lpvtbl->fnAddRef(this);
2542 back->s.ddraw = this;
2544 back->ref = 1;
2545 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&xlib_dds4vt;
2546 /* Copy the surface description from the front buffer */
2547 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2549 /* Create the XImage */
2550 img = create_ximage(this, back);
2551 if (img == NULL)
2552 return DDERR_OUTOFMEMORY;
2553 back->t.xlib.image = img;
2555 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2556 * one! */
2558 /* Add relevant info to front and back buffers */
2559 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2560 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2561 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2562 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2563 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2565 } else {
2566 /* There is no Xlib-specific code here...
2567 Go to the common surface creation function */
2568 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2571 return DD_OK;
2574 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
2575 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2577 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
2578 *dst = src; /* FIXME */
2579 return DD_OK;
2583 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2584 * even when the approbiate bitmasks are not specified.
2586 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
2587 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
2589 int i;
2590 const struct {
2591 int mask;
2592 char *name;
2593 } flagmap[] = {
2594 FE(DDSCL_FULLSCREEN)
2595 FE(DDSCL_ALLOWREBOOT)
2596 FE(DDSCL_NOWINDOWCHANGES)
2597 FE(DDSCL_NORMAL)
2598 FE(DDSCL_ALLOWMODEX)
2599 FE(DDSCL_EXCLUSIVE)
2600 FE(DDSCL_SETFOCUSWINDOW)
2601 FE(DDSCL_SETDEVICEWINDOW)
2602 FE(DDSCL_CREATEDEVICEWINDOW)
2605 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
2606 if(TRACE_ON(ddraw)){
2607 dbg_decl_str(ddraw, 512);
2608 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2609 if (flagmap[i].mask & cooplevel)
2610 dsprintf(ddraw, "%s ", flagmap[i].name);
2611 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2613 this->d.mainWindow = hwnd;
2615 /* This will be overwritten in the case of Full Screen mode.
2616 Windowed games could work with that :-) */
2617 if (hwnd)
2618 this->d.drawable = X11DRV_WND_GetXWindow(WIN_FindWndPtr(hwnd));
2620 return DD_OK;
2623 /* Small helper to either use the cooperative window or create a new
2624 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2626 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
2627 RECT32 rect;
2629 /* Do not destroy the application supplied cooperative window */
2630 if (this->d.window && this->d.window != this->d.mainWindow) {
2631 DestroyWindow32(this->d.window);
2632 this->d.window = 0;
2634 /* Sanity check cooperative window before assigning it to drawing. */
2635 if ( IsWindow32(this->d.mainWindow) &&
2636 IsWindowVisible32(this->d.mainWindow)
2638 GetWindowRect32(this->d.mainWindow,&rect);
2639 if (((rect.right-rect.left) >= this->d.width) &&
2640 ((rect.bottom-rect.top) >= this->d.height)
2642 this->d.window = this->d.mainWindow;
2644 /* ... failed, create new one. */
2645 if (!this->d.window) {
2646 this->d.window = CreateWindowEx32A(
2648 "WINE_DirectDraw",
2649 "WINE_DirectDraw",
2650 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2651 0,0,
2652 this->d.width,
2653 this->d.height,
2657 NULL
2659 /*Store THIS with the window. We'll use it in the window procedure*/
2660 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
2661 ShowWindow32(this->d.window,TRUE);
2662 UpdateWindow32(this->d.window);
2664 SetFocus32(this->d.window);
2667 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
2668 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2670 #ifdef HAVE_LIBXXF86DGA
2671 int i,*depths,depcount,mode_count;
2673 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2675 /* We hope getting the asked for depth */
2676 this->d.screen_depth = depth;
2678 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2680 for (i=0;i<depcount;i++)
2681 if (depths[i]==depth)
2682 break;
2683 TSXFree(depths);
2684 if (i==depcount) {/* not found */
2685 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2686 return DDERR_UNSUPPORTEDMODE;
2688 if (this->d.width < width) {
2689 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2690 return DDERR_UNSUPPORTEDMODE;
2692 this->d.width = width;
2693 this->d.height = height;
2694 this->d.depth = depth;
2696 /* adjust fb_height, so we don't overlap */
2697 if (this->e.dga.fb_height < height)
2698 this->e.dga.fb_height = height;
2699 _common_IDirectDraw_SetDisplayMode(this);
2701 #ifdef HAVE_LIBXXF86VM
2703 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2704 XF86VidModeModeLine mod_tmp;
2705 /* int dotclock_tmp; */
2707 /* save original video mode and set fullscreen if available*/
2708 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2709 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2710 orig_mode->hdisplay = mod_tmp.hdisplay;
2711 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2712 orig_mode->hsyncend = mod_tmp.hsyncend;
2713 orig_mode->htotal = mod_tmp.htotal;
2714 orig_mode->vdisplay = mod_tmp.vdisplay;
2715 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2716 orig_mode->vsyncend = mod_tmp.vsyncend;
2717 orig_mode->vtotal = mod_tmp.vtotal;
2718 orig_mode->flags = mod_tmp.flags;
2719 orig_mode->private = mod_tmp.private;
2721 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2722 for (i=0;i<mode_count;i++)
2724 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2726 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2727 *vidmode = *(all_modes[i]);
2728 break;
2729 } else
2730 TSXFree(all_modes[i]->private);
2732 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
2733 TSXFree(all_modes);
2735 if (!vidmode)
2736 WARN(ddraw, "Fullscreen mode not available!\n");
2738 if (vidmode)
2740 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
2741 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2742 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
2743 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2744 #endif
2747 #endif
2749 /* FIXME: this function OVERWRITES several signal handlers.
2750 * can we save them? and restore them later? In a way that
2751 * it works for the library too?
2753 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2754 #ifdef DIABLO_HACK
2755 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2756 #else
2757 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2758 #endif
2760 #ifdef RESTORE_SIGNALS
2761 SIGNAL_InitHandlers();
2762 #endif
2763 return DD_OK;
2764 #else /* defined(HAVE_LIBXXF86DGA) */
2765 return E_UNEXPECTED;
2766 #endif /* defined(HAVE_LIBXXF86DGA) */
2769 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2770 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2772 int i,*depths,depcount;
2773 char buf[200];
2775 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2776 this, width, height, depth);
2778 /* We hope getting the asked for depth */
2779 this->d.screen_depth = depth;
2781 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2783 for (i=0;i<depcount;i++)
2784 if (depths[i]==depth)
2785 break;
2786 if (i==depcount) {/* not found */
2787 for (i=0;i<depcount;i++)
2788 if (depths[i]==16)
2789 break;
2791 if (i==depcount) {
2792 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2793 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2794 TSXFree(depths);
2795 return DDERR_UNSUPPORTEDMODE;
2796 } else {
2797 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
2798 this->d.screen_depth = 16;
2801 TSXFree(depths);
2803 this->d.width = width;
2804 this->d.height = height;
2805 this->d.depth = depth;
2807 _common_IDirectDraw_SetDisplayMode(this);
2809 this->d.paintable = 1;
2810 this->d.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window;
2811 /* We don't have a context for this window. Host off the desktop */
2812 if( !this->d.drawable )
2813 this->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
2814 return DD_OK;
2817 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2818 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2820 #ifdef HAVE_LIBXXF86DGA
2821 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2822 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2823 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2824 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2825 if (caps2) {
2826 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2827 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2828 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2830 return DD_OK;
2831 #else /* defined(HAVE_LIBXXF86DGA) */
2832 return E_UNEXPECTED;
2833 #endif /* defined(HAVE_LIBXXF86DGA) */
2836 static void fill_caps(LPDDCAPS caps) {
2837 /* This function tries to fill the capabilities of Wine's DDraw implementation.
2838 Need to be fixed, though.. */
2839 if (caps == NULL)
2840 return;
2842 caps->dwSize = sizeof(*caps);
2843 caps->dwCaps = DDCAPS_3D | DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
2844 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_ZBLTS;
2845 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NO2DDURING3DSCENE | DDCAPS2_NOPAGELOCKREQUIRED |
2846 DDCAPS2_WIDESURFACES;
2847 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
2848 caps->dwFXCaps = 0;
2849 caps->dwFXAlphaCaps = 0;
2850 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
2851 caps->dwSVCaps = 0;
2852 caps->dwZBufferBitDepths = DDBD_16;
2853 /* I put here 8 Mo so that D3D applications will believe they have enough memory
2854 to put textures in video memory.
2855 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
2856 for example) ? */
2857 caps->dwVidMemTotal = 8192 * 1024;
2858 caps->dwVidMemFree = 8192 * 1024;
2859 /* These are all the supported capabilities of the surfaces */
2860 caps->ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
2861 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
2862 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE |
2863 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE | DDSCAPS_ZBUFFER;
2866 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2867 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2869 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2871 /* Put the same caps for the two capabilities */
2872 fill_caps(caps1);
2873 fill_caps(caps2);
2875 return DD_OK;
2878 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2879 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2881 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2882 this,x,lpddclip,lpunk
2884 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2885 (*lpddclip)->ref = 1;
2886 (*lpddclip)->lpvtbl = &ddclipvt;
2887 return DD_OK;
2890 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2891 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk,int *psize
2893 int size = 0;
2895 if (TRACE_ON(ddraw))
2896 _dump_paletteformat(dwFlags);
2898 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2899 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2900 (*lpddpal)->ref = 1;
2901 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2902 (*lpddpal)->installed = 0;
2904 if (dwFlags & DDPCAPS_1BIT)
2905 size = 2;
2906 else if (dwFlags & DDPCAPS_2BIT)
2907 size = 4;
2908 else if (dwFlags & DDPCAPS_4BIT)
2909 size = 16;
2910 else if (dwFlags & DDPCAPS_8BIT)
2911 size = 256;
2912 else
2913 ERR(ddraw, "unhandled palette format\n");
2914 *psize = size;
2916 if (palent)
2918 /* Now, if we are in 'depth conversion mode', create the screen palette */
2919 if (this->d.depth != this->d.screen_depth) {
2920 int i;
2922 switch (this->d.screen_depth) {
2923 case 16: {
2924 unsigned short *screen_palette = (unsigned short *) (*lpddpal)->screen_palents;
2926 for (i = 0; i < size; i++) {
2927 screen_palette[i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
2928 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
2929 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
2931 } break;
2933 default:
2934 ERR(ddraw, "Memory corruption ! (depth=%ld, screen_depth=%ld)\n",this->d.depth,this->d.screen_depth);
2935 break;
2939 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
2940 } else if (this->d.depth != this->d.screen_depth) {
2941 int i;
2943 switch (this->d.screen_depth) {
2944 case 16: {
2945 unsigned short *screen_palette = (unsigned short *) (*lpddpal)->screen_palents;
2947 for (i = 0; i < size; i++) {
2948 screen_palette[i] = 0xFFFF;
2950 } break;
2952 default:
2953 ERR(ddraw, "Memory corruption !\n");
2954 break;
2958 return DD_OK;
2961 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2962 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2964 HRESULT res;
2965 int xsize = 0,i;
2967 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
2968 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
2969 if (res != 0) return res;
2970 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2971 if (this->d.depth<=8) {
2972 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
2973 } else {
2974 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
2975 (*lpddpal)->cm = 0;
2977 if (((*lpddpal)->cm)&&xsize) {
2978 for (i=0;i<xsize;i++) {
2979 XColor xc;
2981 xc.red = (*lpddpal)->palents[i].peRed<<8;
2982 xc.blue = (*lpddpal)->palents[i].peBlue<<8;
2983 xc.green = (*lpddpal)->palents[i].peGreen<<8;
2984 xc.flags = DoRed|DoBlue|DoGreen;
2985 xc.pixel = i;
2986 TSXStoreColor(display,(*lpddpal)->cm,&xc);
2989 return DD_OK;
2992 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2993 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2995 int xsize;
2996 HRESULT res;
2998 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
2999 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
3000 if (res != 0) return res;
3001 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
3002 return DD_OK;
3005 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3006 #ifdef HAVE_LIBXXF86DGA
3007 TRACE(ddraw, "(%p)->()\n",this);
3008 Sleep(1000);
3009 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3010 #ifdef RESTORE_SIGNALS
3011 SIGNAL_InitHandlers();
3012 #endif
3013 return DD_OK;
3014 #else /* defined(HAVE_LIBXXF86DGA) */
3015 return E_UNEXPECTED;
3016 #endif
3019 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3020 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
3021 Sleep(1000);
3022 return DD_OK;
3025 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
3026 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
3028 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
3029 return DD_OK;
3032 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
3033 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
3035 return ++(this->ref);
3038 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3039 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3041 #ifdef HAVE_LIBXXF86DGA
3042 if (!--(this->ref)) {
3043 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3044 if (this->d.window && (this->d.mainWindow != this->d.window))
3045 DestroyWindow32(this->d.window);
3046 #ifdef HAVE_LIBXXF86VM
3047 if (orig_mode) {
3048 TSXF86VidModeSwitchToMode(
3049 display,
3050 DefaultScreen(display),
3051 orig_mode);
3052 if (orig_mode->privsize)
3053 TSXFree(orig_mode->private);
3054 free(orig_mode);
3055 orig_mode = NULL;
3057 #endif
3059 #ifdef RESTORE_SIGNALS
3060 SIGNAL_InitHandlers();
3061 #endif
3062 HeapFree(GetProcessHeap(),0,this);
3063 return 0;
3065 #endif /* defined(HAVE_LIBXXF86DGA) */
3066 return this->ref;
3069 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3070 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3072 if (!--(this->ref)) {
3073 if (this->d.window && (this->d.mainWindow != this->d.window))
3074 DestroyWindow32(this->d.window);
3075 HeapFree(GetProcessHeap(),0,this);
3076 return 0;
3078 /* FIXME: destroy window ... */
3079 return this->ref;
3082 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
3083 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3085 char xrefiid[50];
3087 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3088 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3089 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3090 *obj = this;
3091 this->lpvtbl->fnAddRef(this);
3093 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3095 return S_OK;
3097 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3098 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
3099 this->lpvtbl->fnAddRef(this);
3100 *obj = this;
3102 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3104 return S_OK;
3106 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3107 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
3108 this->lpvtbl->fnAddRef(this);
3109 *obj = this;
3111 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3113 return S_OK;
3115 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3116 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd4vt;
3117 this->lpvtbl->fnAddRef(this);
3118 *obj = this;
3120 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3122 return S_OK;
3124 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3125 LPDIRECT3D d3d;
3127 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3128 d3d->ref = 1;
3129 d3d->ddraw = (LPDIRECTDRAW)this;
3130 this->lpvtbl->fnAddRef(this);
3131 d3d->lpvtbl = &d3dvt;
3132 *obj = d3d;
3134 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3136 return S_OK;
3138 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3139 LPDIRECT3D2 d3d;
3141 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3142 d3d->ref = 1;
3143 d3d->ddraw = (LPDIRECTDRAW)this;
3144 this->lpvtbl->fnAddRef(this);
3145 d3d->lpvtbl = &d3d2vt;
3146 *obj = d3d;
3148 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3150 return S_OK;
3152 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3153 return OLE_E_ENUM_NOMORE;
3156 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
3157 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3159 char xrefiid[50];
3161 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3162 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3163 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3164 *obj = this;
3165 this->lpvtbl->fnAddRef(this);
3167 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3169 return S_OK;
3171 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3172 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
3173 this->lpvtbl->fnAddRef(this);
3174 *obj = this;
3176 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3178 return S_OK;
3180 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3181 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
3182 this->lpvtbl->fnAddRef(this);
3183 *obj = this;
3185 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3187 return S_OK;
3189 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3190 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd4vt;
3191 this->lpvtbl->fnAddRef(this);
3192 *obj = this;
3194 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3196 return S_OK;
3198 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3199 LPDIRECT3D d3d;
3201 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3202 d3d->ref = 1;
3203 d3d->ddraw = (LPDIRECTDRAW)this;
3204 this->lpvtbl->fnAddRef(this);
3205 d3d->lpvtbl = &d3dvt;
3206 *obj = d3d;
3208 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3210 return S_OK;
3212 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3213 LPDIRECT3D2 d3d;
3215 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3216 d3d->ref = 1;
3217 d3d->ddraw = (LPDIRECTDRAW)this;
3218 this->lpvtbl->fnAddRef(this);
3219 d3d->lpvtbl = &d3d2vt;
3220 *obj = d3d;
3222 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3224 return S_OK;
3226 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3227 return OLE_E_ENUM_NOMORE;
3230 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
3231 LPDIRECTDRAW2 this,BOOL32 *status
3233 TRACE(ddraw,"(%p)->(%p)\n",this,status);
3234 *status = TRUE;
3235 return DD_OK;
3238 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
3239 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3241 DDSURFACEDESC ddsfd;
3242 static struct {
3243 int w,h;
3244 } modes[5] = { /* some of the usual modes */
3245 {512,384},
3246 {640,400},
3247 {640,480},
3248 {800,600},
3249 {1024,768},
3251 static int depths[4] = {8,16,24,32};
3252 int i,j;
3254 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
3255 ddsfd.dwSize = sizeof(ddsfd);
3256 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3257 if (dwFlags & DDEDM_REFRESHRATES) {
3258 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3259 ddsfd.x.dwRefreshRate = 60;
3262 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3263 ddsfd.dwBackBufferCount = 1;
3264 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3265 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3266 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3267 /* FIXME: those masks would have to be set in depth > 8 */
3268 if (depths[i]==8) {
3269 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3270 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3271 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3272 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3273 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3274 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3275 } else {
3276 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3278 /* FIXME: We should query those from X itself */
3279 switch (depths[i]) {
3280 case 16:
3281 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3282 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3283 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3284 break;
3285 case 24:
3286 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3287 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3288 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3289 break;
3290 case 32:
3291 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3292 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3293 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3294 break;
3298 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3299 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3300 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3301 if (!modescb(&ddsfd,context)) return DD_OK;
3303 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3304 ddsfd.dwWidth = modes[j].w;
3305 ddsfd.dwHeight = modes[j].h;
3306 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3307 if (!modescb(&ddsfd,context)) return DD_OK;
3310 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3311 /* modeX is not standard VGA */
3313 ddsfd.dwHeight = 200;
3314 ddsfd.dwWidth = 320;
3315 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3316 if (!modescb(&ddsfd,context)) return DD_OK;
3319 return DD_OK;
3322 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
3323 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3325 #ifdef HAVE_LIBXXF86DGA
3326 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
3327 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3328 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3329 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3330 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
3331 lpddsfd->dwBackBufferCount = 1;
3332 lpddsfd->x.dwRefreshRate = 60;
3333 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3334 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
3335 return DD_OK;
3336 #else /* defined(HAVE_LIBXXF86DGA) */
3337 return E_UNEXPECTED;
3338 #endif /* defined(HAVE_LIBXXF86DGA) */
3341 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
3342 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3344 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
3345 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3346 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3347 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3348 /* POOLE FIXME: Xlib */
3349 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
3350 /* END FIXME: Xlib */
3351 lpddsfd->dwBackBufferCount = 1;
3352 lpddsfd->x.dwRefreshRate = 60;
3353 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3354 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
3355 return DD_OK;
3358 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
3359 TRACE(ddraw,"(%p)->()\n",this);
3360 return DD_OK;
3363 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
3364 LPDIRECTDRAW2 this,LPDWORD freq
3366 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
3367 *freq = 60*100; /* 60 Hz */
3368 return DD_OK;
3371 /* what can we directly decompress? */
3372 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
3373 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
3375 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
3376 return DD_OK;
3379 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
3380 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
3382 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
3383 return DD_OK;
3386 static HRESULT WINAPI IDirectDraw2_Compact(
3387 LPDIRECTDRAW2 this )
3389 FIXME(ddraw,"(%p)->()\n", this );
3391 return DD_OK;
3394 static HRESULT WINAPI IDirectDraw2_GetGDISurface(LPDIRECTDRAW2 this,
3395 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
3396 FIXME(ddraw,"(%p)->(%p)\n", this, lplpGDIDDSSurface);
3398 return DD_OK;
3401 static HRESULT WINAPI IDirectDraw2_GetScanLine(LPDIRECTDRAW2 this,
3402 LPDWORD lpdwScanLine) {
3403 FIXME(ddraw,"(%p)->(%p)\n", this, lpdwScanLine);
3405 return DD_OK;
3408 static HRESULT WINAPI IDirectDraw2_Initialize(LPDIRECTDRAW2 this,
3409 GUID *lpGUID) {
3410 FIXME(ddraw,"(%p)->(%p)\n", this, lpGUID);
3412 return DD_OK;
3415 /* Note: Hack so we can reuse the old functions without compiler warnings */
3416 #ifdef __GNUC__
3417 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
3418 #else
3419 # define XCAST(fun) (void*)
3420 #endif
3422 static struct IDirectDraw_VTable dga_ddvt = {
3423 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3424 XCAST(AddRef)IDirectDraw2_AddRef,
3425 XCAST(Release)DGA_IDirectDraw2_Release,
3426 XCAST(Compact)IDirectDraw2_Compact,
3427 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3428 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3429 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3430 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3431 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3432 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3433 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3434 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3435 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3436 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3437 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3438 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3439 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3440 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3441 XCAST(Initialize)IDirectDraw2_Initialize,
3442 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3443 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3444 DGA_IDirectDraw_SetDisplayMode,
3445 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3448 static struct IDirectDraw_VTable xlib_ddvt = {
3449 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3450 XCAST(AddRef)IDirectDraw2_AddRef,
3451 XCAST(Release)Xlib_IDirectDraw2_Release,
3452 XCAST(Compact)IDirectDraw2_Compact,
3453 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3454 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3455 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3456 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3457 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3458 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3459 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3460 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3461 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3462 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3463 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3464 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3465 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3466 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3467 XCAST(Initialize)IDirectDraw2_Initialize,
3468 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3469 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3470 Xlib_IDirectDraw_SetDisplayMode,
3471 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3474 #undef XCAST
3476 /*****************************************************************************
3477 * IDirectDraw2
3482 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
3483 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3485 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3488 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
3489 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3491 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3494 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
3495 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3497 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3498 this,ddscaps,total,free
3500 if (total) *total = this->e.dga.fb_memsize * 1024;
3501 if (free) *free = this->e.dga.fb_memsize * 1024;
3502 return DD_OK;
3505 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
3506 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3508 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3509 this,ddscaps,total,free
3511 if (total) *total = 2048 * 1024;
3512 if (free) *free = 2048 * 1024;
3513 return DD_OK;
3516 static IDirectDraw2_VTable dga_dd2vt = {
3517 DGA_IDirectDraw2_QueryInterface,
3518 IDirectDraw2_AddRef,
3519 DGA_IDirectDraw2_Release,
3520 IDirectDraw2_Compact,
3521 IDirectDraw2_CreateClipper,
3522 DGA_IDirectDraw2_CreatePalette,
3523 DGA_IDirectDraw2_CreateSurface,
3524 IDirectDraw2_DuplicateSurface,
3525 IDirectDraw2_EnumDisplayModes,
3526 IDirectDraw2_EnumSurfaces,
3527 IDirectDraw2_FlipToGDISurface,
3528 DGA_IDirectDraw2_GetCaps,
3529 DGA_IDirectDraw2_GetDisplayMode,
3530 IDirectDraw2_GetFourCCCodes,
3531 IDirectDraw2_GetGDISurface,
3532 IDirectDraw2_GetMonitorFrequency,
3533 IDirectDraw2_GetScanLine,
3534 IDirectDraw2_GetVerticalBlankStatus,
3535 IDirectDraw2_Initialize,
3536 DGA_IDirectDraw2_RestoreDisplayMode,
3537 IDirectDraw2_SetCooperativeLevel,
3538 DGA_IDirectDraw2_SetDisplayMode,
3539 IDirectDraw2_WaitForVerticalBlank,
3540 DGA_IDirectDraw2_GetAvailableVidMem
3543 static struct IDirectDraw2_VTable xlib_dd2vt = {
3544 Xlib_IDirectDraw2_QueryInterface,
3545 IDirectDraw2_AddRef,
3546 Xlib_IDirectDraw2_Release,
3547 IDirectDraw2_Compact,
3548 IDirectDraw2_CreateClipper,
3549 Xlib_IDirectDraw2_CreatePalette,
3550 Xlib_IDirectDraw2_CreateSurface,
3551 IDirectDraw2_DuplicateSurface,
3552 IDirectDraw2_EnumDisplayModes,
3553 IDirectDraw2_EnumSurfaces,
3554 IDirectDraw2_FlipToGDISurface,
3555 Xlib_IDirectDraw2_GetCaps,
3556 Xlib_IDirectDraw2_GetDisplayMode,
3557 IDirectDraw2_GetFourCCCodes,
3558 IDirectDraw2_GetGDISurface,
3559 IDirectDraw2_GetMonitorFrequency,
3560 IDirectDraw2_GetScanLine,
3561 IDirectDraw2_GetVerticalBlankStatus,
3562 IDirectDraw2_Initialize,
3563 Xlib_IDirectDraw2_RestoreDisplayMode,
3564 IDirectDraw2_SetCooperativeLevel,
3565 Xlib_IDirectDraw2_SetDisplayMode,
3566 IDirectDraw2_WaitForVerticalBlank,
3567 Xlib_IDirectDraw2_GetAvailableVidMem
3570 /*****************************************************************************
3571 * IDirectDraw4
3575 static HRESULT WINAPI IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4 this,
3576 HDC32 hdc,
3577 LPDIRECTDRAWSURFACE *lpDDS) {
3578 FIXME(ddraw, "(%p)->(%08ld,%p)\n", this, (DWORD) hdc, lpDDS);
3580 return DD_OK;
3583 static HRESULT WINAPI IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4 this) {
3584 FIXME(ddraw, "(%p)->()\n", this);
3586 return DD_OK;
3589 static HRESULT WINAPI IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4 this) {
3590 FIXME(ddraw, "(%p)->()\n", this);
3592 return DD_OK;
3595 static HRESULT WINAPI IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4 this,
3596 LPDDDEVICEIDENTIFIER lpdddi,
3597 DWORD dwFlags) {
3598 FIXME(ddraw, "(%p)->(%p,%08lx)\n", this, lpdddi, dwFlags);
3600 return DD_OK;
3603 #ifdef __GNUC__
3604 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
3605 #else
3606 # define XCAST(fun) (void*)
3607 #endif
3610 static struct IDirectDraw4_VTable dga_dd4vt = {
3611 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3612 XCAST(AddRef)IDirectDraw2_AddRef,
3613 XCAST(Release)DGA_IDirectDraw2_Release,
3614 XCAST(Compact)IDirectDraw2_Compact,
3615 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3616 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3617 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3618 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3619 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3620 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3621 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3622 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3623 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3624 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3625 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3626 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3627 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3628 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3629 XCAST(Initialize)IDirectDraw2_Initialize,
3630 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3631 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3632 XCAST(SetDisplayMode)DGA_IDirectDraw_SetDisplayMode,
3633 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3634 XCAST(GetAvailableVidMem)DGA_IDirectDraw2_GetAvailableVidMem,
3635 IDirectDraw4_GetSurfaceFromDC,
3636 IDirectDraw4_RestoreAllSurfaces,
3637 IDirectDraw4_TestCooperativeLevel,
3638 IDirectDraw4_GetDeviceIdentifier
3641 static struct IDirectDraw4_VTable xlib_dd4vt = {
3642 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3643 XCAST(AddRef)IDirectDraw2_AddRef,
3644 XCAST(Release)Xlib_IDirectDraw2_Release,
3645 XCAST(Compact)IDirectDraw2_Compact,
3646 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3647 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3648 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3649 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3650 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3651 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3652 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3653 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3654 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3655 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3656 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3657 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3658 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3659 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3660 XCAST(Initialize)IDirectDraw2_Initialize,
3661 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3662 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3663 XCAST(SetDisplayMode)Xlib_IDirectDraw_SetDisplayMode,
3664 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3665 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2_GetAvailableVidMem,
3666 IDirectDraw4_GetSurfaceFromDC,
3667 IDirectDraw4_RestoreAllSurfaces,
3668 IDirectDraw4_TestCooperativeLevel,
3669 IDirectDraw4_GetDeviceIdentifier
3672 #undef XCAST
3674 /******************************************************************************
3675 * DirectDrawCreate
3678 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
3680 LRESULT ret;
3681 LPDIRECTDRAW ddraw = NULL;
3682 DWORD lastError;
3684 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
3686 SetLastError( ERROR_SUCCESS );
3687 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
3688 if( (!ddraw) &&
3689 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
3692 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
3695 if( ddraw )
3697 /* Perform any special direct draw functions */
3698 if (msg==WM_PAINT)
3699 ddraw->d.paintable = 1;
3701 /* Now let the application deal with the rest of this */
3702 if( ddraw->d.mainWindow )
3705 /* Don't think that we actually need to call this but...
3706 might as well be on the safe side of things... */
3708 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
3709 it should be the procedures of our fake window that gets called
3710 instead of those of the window provided by the application.
3711 And with this patch, mouse clicks work with Monkey Island III
3712 - Lionel */
3713 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
3715 if( !ret )
3717 /* We didn't handle the message - give it to the application */
3718 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
3719 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
3720 ddraw->d.mainWindow, msg, wParam, lParam );
3724 } else {
3725 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
3729 else
3731 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
3734 return ret;
3737 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
3738 #ifdef HAVE_LIBXXF86DGA
3739 int memsize,banksize,width,major,minor,flags,height;
3740 char *addr;
3741 int fd;
3743 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
3744 if ((fd = open("/dev/mem", O_RDWR)) != -1)
3745 close(fd);
3747 if (fd == -1) {
3748 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
3749 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
3750 return E_UNEXPECTED;
3752 if (!DDRAW_DGA_Available()) {
3753 TRACE(ddraw,"No XF86DGA detected.\n");
3754 return DDERR_GENERIC;
3756 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3757 (*lplpDD)->lpvtbl = &dga_ddvt;
3758 (*lplpDD)->ref = 1;
3759 TSXF86DGAQueryVersion(display,&major,&minor);
3760 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
3761 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
3762 if (!(flags & XF86DGADirectPresent))
3763 MSG("direct video is NOT PRESENT.\n");
3764 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
3765 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
3766 addr,width,banksize,memsize
3768 (*lplpDD)->e.dga.fb_width = width;
3769 (*lplpDD)->d.width = width;
3770 (*lplpDD)->e.dga.fb_addr = addr;
3771 (*lplpDD)->e.dga.fb_memsize = memsize;
3772 (*lplpDD)->e.dga.fb_banksize = banksize;
3774 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
3775 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3776 (*lplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3777 #ifdef DIABLO_HACK
3778 (*lplpDD)->e.dga.vpmask = 1;
3779 #else
3780 (*lplpDD)->e.dga.vpmask = 0;
3781 #endif
3783 /* just assume the default depth is the DGA depth too */
3784 (*lplpDD)->d.screen_depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3785 (*lplpDD)->d.depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3786 #ifdef RESTORE_SIGNALS
3787 SIGNAL_InitHandlers();
3788 #endif
3790 return DD_OK;
3791 #else /* defined(HAVE_LIBXXF86DGA) */
3792 return DDERR_INVALIDDIRECTDRAWGUID;
3793 #endif /* defined(HAVE_LIBXXF86DGA) */
3796 BOOL32
3797 DDRAW_XSHM_Available(void)
3799 #ifdef HAVE_LIBXXSHM
3800 if (TSXShmQueryExtension(display))
3802 int major, minor;
3803 Bool shpix;
3805 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
3806 return 1;
3807 else
3808 return 0;
3810 else
3811 return 0;
3812 #else
3813 return 0;
3814 #endif
3817 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
3819 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3820 (*lplpDD)->lpvtbl = &xlib_ddvt;
3821 (*lplpDD)->ref = 1;
3822 (*lplpDD)->d.drawable = 0; /* in SetDisplayMode */
3824 /* At DirectDraw creation, the depth is the default depth */
3825 (*lplpDD)->d.depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3826 (*lplpDD)->d.screen_depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3827 (*lplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3828 (*lplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3830 #ifdef HAVE_LIBXXSHM
3831 /* Test if XShm is available. */
3832 if (((*lplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
3833 TRACE(ddraw, "Using XShm extension.\n");
3834 #endif
3836 return DD_OK;
3839 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
3840 char xclsid[50];
3841 WNDCLASS32A wc;
3842 WND* pParentWindow;
3843 HRESULT ret;
3845 if (HIWORD(lpGUID))
3846 WINE_StringFromCLSID(lpGUID,xclsid);
3847 else {
3848 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
3849 lpGUID = NULL;
3852 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
3854 if (!lpGUID) {
3855 /* if they didn't request a particular interface, use the best
3856 * supported one */
3857 if (DDRAW_DGA_Available())
3858 lpGUID = &DGA_DirectDraw_GUID;
3859 else
3860 lpGUID = &XLIB_DirectDraw_GUID;
3863 wc.style = CS_GLOBALCLASS;
3864 wc.lpfnWndProc = Xlib_DDWndProc;
3865 wc.cbClsExtra = 0;
3866 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
3867 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
3869 /* We can be a child of the desktop since we're really important */
3870 pParentWindow = WIN_GetDesktop();
3871 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
3872 wc.hInstance = 0;
3874 wc.hIcon = 0;
3875 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
3876 wc.hbrBackground= NULL_BRUSH;
3877 wc.lpszMenuName = 0;
3878 wc.lpszClassName= "WINE_DirectDraw";
3879 RegisterClass32A(&wc);
3881 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
3882 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
3883 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
3884 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
3885 else
3886 goto err;
3889 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
3890 return ret;
3892 err:
3893 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
3894 return DDERR_INVALIDDIRECTDRAWGUID;