Implemented the OleCreateFontIndirect method and the associated COM
[wine.git] / graphics / ddraw.c
blob3f21ef48888fff7469288f60ef1b7f1b99981d42
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>
50 #include "winerror.h"
51 #include "gdi.h"
52 #include "heap.h"
53 #include "ldt.h"
54 #include "dc.h"
55 #include "win.h"
56 #include "miscemu.h"
57 #include "ddraw.h"
58 #include "d3d.h"
59 #include "debug.h"
60 #include "spy.h"
61 #include "message.h"
62 #include "options.h"
63 #include "objbase.h"
64 #include "monitor.h"
66 /* This for all the enumeration and creation of D3D-related objects */
67 #include "d3d_private.h"
69 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
70 #undef DIABLO_HACK
72 /* Restore signal handlers overwritten by XF86DGA
74 #define RESTORE_SIGNALS
76 /* Where do these GUIDs come from? mkuuid.
77 * They exist solely to distinguish between the targets Wine support,
78 * and should be different than any other GUIDs in existence.
80 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
81 0xe2dcb020,
82 0xdc60,
83 0x11d1,
84 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
87 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
88 0x1574a740,
89 0xdc61,
90 0x11d1,
91 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
94 static struct IDirectDrawSurface4_VTable dga_dds4vt, xlib_dds4vt;
95 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
96 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
97 static struct IDirectDraw4_VTable dga_dd4vt, xlib_dd4vt;
98 static struct IDirectDrawClipper_VTable ddclipvt;
99 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
100 static struct IDirect3D_VTable d3dvt;
101 static struct IDirect3D2_VTable d3d2vt;
103 #ifdef HAVE_LIBXXF86VM
104 static XF86VidModeModeInfo *orig_mode = NULL;
105 #endif
107 #ifdef HAVE_LIBXXSHM
108 static int XShmErrorFlag = 0;
109 #endif
111 BOOL32
112 DDRAW_DGA_Available(void)
114 #ifdef HAVE_LIBXXF86DGA
115 int evbase, evret, fd;
117 if (Options.noDGA)
118 return 0;
120 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
121 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
122 /* others. --stephenc */
123 if ((fd = open("/dev/mem", O_RDWR)) != -1)
124 close(fd);
126 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
127 #else /* defined(HAVE_LIBXXF86DGA) */
128 return 0;
129 #endif /* defined(HAVE_LIBXXF86DGA) */
132 HRESULT WINAPI
133 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
134 if (DDRAW_DGA_Available()) {
135 TRACE(ddraw, "Enumerating DGA interface\n");
136 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
138 TRACE(ddraw, "Enumerating Xlib interface\n");
139 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
140 TRACE(ddraw, "Enumerating Default interface\n");
141 ddenumproc(NULL,"WINE (default)","display",data);
142 return DD_OK;
145 /* What is this doing here? */
146 HRESULT WINAPI
147 DSoundHelp(DWORD x,DWORD y,DWORD z) {
148 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
149 return 0;
153 /******************************************************************************
154 * internal helper functions
156 static void _dump_DDBLTFX(DWORD flagmask) {
157 int i;
158 const struct {
159 DWORD mask;
160 char *name;
161 } flags[] = {
162 #define FE(x) { x, #x},
163 FE(DDBLTFX_ARITHSTRETCHY)
164 FE(DDBLTFX_MIRRORLEFTRIGHT)
165 FE(DDBLTFX_MIRRORUPDOWN)
166 FE(DDBLTFX_NOTEARING)
167 FE(DDBLTFX_ROTATE180)
168 FE(DDBLTFX_ROTATE270)
169 FE(DDBLTFX_ROTATE90)
170 FE(DDBLTFX_ZBUFFERRANGE)
171 FE(DDBLTFX_ZBUFFERBASEDEST)
173 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
174 if (flags[i].mask & flagmask) {
175 DUMP("%s ",flags[i].name);
178 DUMP("\n");
182 static void _dump_DDBLTFAST(DWORD flagmask) {
183 int i;
184 const struct {
185 DWORD mask;
186 char *name;
187 } flags[] = {
188 #define FE(x) { x, #x},
189 FE(DDBLTFAST_NOCOLORKEY)
190 FE(DDBLTFAST_SRCCOLORKEY)
191 FE(DDBLTFAST_DESTCOLORKEY)
192 FE(DDBLTFAST_WAIT)
194 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
195 if (flags[i].mask & flagmask)
196 DUMP("%s ",flags[i].name);
197 DUMP("\n");
200 static void _dump_DDBLT(DWORD flagmask) {
201 int i;
202 const struct {
203 DWORD mask;
204 char *name;
205 } flags[] = {
206 #define FE(x) { x, #x},
207 FE(DDBLT_ALPHADEST)
208 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
209 FE(DDBLT_ALPHADESTNEG)
210 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
211 FE(DDBLT_ALPHAEDGEBLEND)
212 FE(DDBLT_ALPHASRC)
213 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
214 FE(DDBLT_ALPHASRCNEG)
215 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
216 FE(DDBLT_ASYNC)
217 FE(DDBLT_COLORFILL)
218 FE(DDBLT_DDFX)
219 FE(DDBLT_DDROPS)
220 FE(DDBLT_KEYDEST)
221 FE(DDBLT_KEYDESTOVERRIDE)
222 FE(DDBLT_KEYSRC)
223 FE(DDBLT_KEYSRCOVERRIDE)
224 FE(DDBLT_ROP)
225 FE(DDBLT_ROTATIONANGLE)
226 FE(DDBLT_ZBUFFER)
227 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
228 FE(DDBLT_ZBUFFERDESTOVERRIDE)
229 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
230 FE(DDBLT_ZBUFFERSRCOVERRIDE)
231 FE(DDBLT_WAIT)
232 FE(DDBLT_DEPTHFILL)
234 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
235 if (flags[i].mask & flagmask)
236 DUMP("%s ",flags[i].name);
237 DUMP("\n");
240 static void _dump_DDSCAPS(DWORD flagmask) {
241 int i;
242 const struct {
243 DWORD mask;
244 char *name;
245 } flags[] = {
246 #define FE(x) { x, #x},
247 FE(DDSCAPS_RESERVED1)
248 FE(DDSCAPS_ALPHA)
249 FE(DDSCAPS_BACKBUFFER)
250 FE(DDSCAPS_COMPLEX)
251 FE(DDSCAPS_FLIP)
252 FE(DDSCAPS_FRONTBUFFER)
253 FE(DDSCAPS_OFFSCREENPLAIN)
254 FE(DDSCAPS_OVERLAY)
255 FE(DDSCAPS_PALETTE)
256 FE(DDSCAPS_PRIMARYSURFACE)
257 FE(DDSCAPS_PRIMARYSURFACELEFT)
258 FE(DDSCAPS_SYSTEMMEMORY)
259 FE(DDSCAPS_TEXTURE)
260 FE(DDSCAPS_3DDEVICE)
261 FE(DDSCAPS_VIDEOMEMORY)
262 FE(DDSCAPS_VISIBLE)
263 FE(DDSCAPS_WRITEONLY)
264 FE(DDSCAPS_ZBUFFER)
265 FE(DDSCAPS_OWNDC)
266 FE(DDSCAPS_LIVEVIDEO)
267 FE(DDSCAPS_HWCODEC)
268 FE(DDSCAPS_MODEX)
269 FE(DDSCAPS_MIPMAP)
270 FE(DDSCAPS_RESERVED2)
271 FE(DDSCAPS_ALLOCONLOAD)
272 FE(DDSCAPS_VIDEOPORT)
273 FE(DDSCAPS_LOCALVIDMEM)
274 FE(DDSCAPS_NONLOCALVIDMEM)
275 FE(DDSCAPS_STANDARDVGAMODE)
276 FE(DDSCAPS_OPTIMIZED)
278 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
279 if (flags[i].mask & flagmask)
280 DUMP("%s ",flags[i].name);
281 DUMP("\n");
284 static void _dump_DDSD(DWORD flagmask) {
285 int i;
286 const struct {
287 DWORD mask;
288 char *name;
289 } flags[] = {
290 FE(DDSD_CAPS)
291 FE(DDSD_HEIGHT)
292 FE(DDSD_WIDTH)
293 FE(DDSD_PITCH)
294 FE(DDSD_BACKBUFFERCOUNT)
295 FE(DDSD_ZBUFFERBITDEPTH)
296 FE(DDSD_ALPHABITDEPTH)
297 FE(DDSD_PIXELFORMAT)
298 FE(DDSD_CKDESTOVERLAY)
299 FE(DDSD_CKDESTBLT)
300 FE(DDSD_CKSRCOVERLAY)
301 FE(DDSD_CKSRCBLT)
302 FE(DDSD_MIPMAPCOUNT)
303 FE(DDSD_REFRESHRATE)
304 FE(DDSD_LINEARSIZE)
305 FE(DDSD_LPSURFACE)
307 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
308 if (flags[i].mask & flagmask)
309 DUMP("%s ",flags[i].name);
310 DUMP("\n");
313 static void _dump_DDCOLORKEY(DWORD flagmask) {
314 int i;
315 const struct {
316 DWORD mask;
317 char *name;
318 } flags[] = {
319 #define FE(x) { x, #x},
320 FE(DDPF_ALPHAPIXELS)
321 FE(DDPF_ALPHA)
322 FE(DDPF_FOURCC)
323 FE(DDPF_PALETTEINDEXED4)
324 FE(DDPF_PALETTEINDEXEDTO8)
325 FE(DDPF_PALETTEINDEXED8)
326 FE(DDPF_RGB)
327 FE(DDPF_COMPRESSED)
328 FE(DDPF_RGBTOYUV)
329 FE(DDPF_YUV)
330 FE(DDPF_ZBUFFER)
331 FE(DDPF_PALETTEINDEXED1)
332 FE(DDPF_PALETTEINDEXED2)
333 FE(DDPF_ZPIXELS)
335 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
336 if (flags[i].mask & flagmask)
337 DUMP("%s ",flags[i].name);
338 DUMP("\n");
341 static void _dump_paletteformat(DWORD dwFlags) {
342 int i;
343 const struct {
344 DWORD mask;
345 char *name;
346 } flags[] = {
347 #define FE(x) { x, #x},
348 FE(DDPCAPS_4BIT)
349 FE(DDPCAPS_8BITENTRIES)
350 FE(DDPCAPS_8BIT)
351 FE(DDPCAPS_INITIALIZE)
352 FE(DDPCAPS_PRIMARYSURFACE)
353 FE(DDPCAPS_PRIMARYSURFACELEFT)
354 FE(DDPCAPS_ALLOW256)
355 FE(DDPCAPS_VSYNC)
356 FE(DDPCAPS_1BIT)
357 FE(DDPCAPS_2BIT)
358 FE(DDPCAPS_ALPHA)
360 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
361 if (flags[i].mask & dwFlags)
362 DUMP("%s ",flags[i].name);
363 DUMP("\n");
366 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
367 DUMP("Size : %ld\n", pf->dwSize);
368 if (pf->dwFlags)
369 _dump_DDCOLORKEY(pf->dwFlags);
370 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
371 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
372 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
373 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
376 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
377 static XVisualInfo *vi;
378 XVisualInfo vt;
379 int nitems;
381 if (!vi)
382 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
384 pf->dwFourCC = 0;
385 pf->dwSize = sizeof(DDPIXELFORMAT);
386 if (ddraw->d.depth==8) {
387 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
388 pf->x.dwRGBBitCount = 8;
389 pf->y.dwRBitMask = 0;
390 pf->z.dwGBitMask = 0;
391 pf->xx.dwBBitMask = 0;
392 pf->xy.dwRGBAlphaBitMask= 0;
393 return 0;
395 if (ddraw->d.depth==16) {
396 pf->dwFlags = DDPF_RGB;
397 pf->x.dwRGBBitCount = 16;
398 pf->y.dwRBitMask = vi[0].red_mask;
399 pf->z.dwGBitMask = vi[0].green_mask;
400 pf->xx.dwBBitMask = vi[0].blue_mask;
401 pf->xy.dwRGBAlphaBitMask= 0;
402 return 0;
404 if (ddraw->d.depth==24) {
405 pf->dwFlags = DDPF_RGB;
406 pf->x.dwRGBBitCount = 24;
407 pf->y.dwRBitMask = vi[0].red_mask;
408 pf->z.dwGBitMask = vi[0].green_mask;
409 pf->xx.dwBBitMask = vi[0].blue_mask;
410 pf->xy.dwRGBAlphaBitMask= 0;
411 return 0;
413 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
414 return DDERR_GENERIC;
417 /******************************************************************************
418 * IDirectDrawSurface methods
420 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
421 * DDS and DDS2 use those functions. (Function calls did not change (except
422 * using different DirectDrawSurfaceX version), just added flags and functions)
424 static HRESULT WINAPI IDirectDrawSurface4_Lock(
425 LPDIRECTDRAWSURFACE4 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
427 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
428 this,lprect,lpddsd,flags,(DWORD)hnd);
429 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
430 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
431 this,lprect,lpddsd,flags,(DWORD)hnd);
433 /* First, copy the Surface description */
434 *lpddsd = this->s.surface_desc;
435 TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
436 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
438 /* If asked only for a part, change the surface pointer */
439 if (lprect) {
440 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
441 lprect->top,lprect->left,lprect->bottom,lprect->right
443 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
444 (lprect->top*this->s.surface_desc.lPitch) +
445 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
446 } else {
447 assert(this->s.surface_desc.y.lpSurface);
449 return DD_OK;
452 static HRESULT WINAPI DGA_IDirectDrawSurface4_Unlock(
453 LPDIRECTDRAWSURFACE4 this,LPVOID surface
455 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
456 return DD_OK;
459 static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4 this) {
460 if (this->s.ddraw->d.depth != this->s.ddraw->d.screen_depth) {
461 /* Pixel convertion ! */
462 if ((this->s.ddraw->d.depth == 8) && (this->s.ddraw->d.screen_depth == 16)) {
463 unsigned char *src = (unsigned char *) this->s.surface_desc.y.lpSurface;
464 unsigned short *dst = (unsigned short *) this->t.xlib.image->data;
465 unsigned short *pal;
466 int x, y;
468 if (this->s.palette != NULL) {
469 pal = (unsigned short *) this->s.palette->screen_palents;
470 for (y = 0; y < this->s.surface_desc.dwHeight; y++) {
471 for (x = 0; x < this->s.surface_desc.dwWidth; x++) {
472 dst[x + y * this->s.surface_desc.lPitch] = pal[src[x + y * this->s.surface_desc.lPitch]];
475 } else {
476 WARN(ddraw, "No palette set...\n");
477 memset(dst, 0, this->s.surface_desc.lPitch * this->s.surface_desc.dwHeight * 2);
479 } else {
480 ERR(ddraw, "Unsupported pixel convertion...\n");
484 #ifdef HAVE_LIBXXSHM
485 if (this->s.ddraw->e.xlib.xshm_active)
486 TSXShmPutImage(display,
487 this->s.ddraw->d.drawable,
488 DefaultGCOfScreen(X11DRV_GetXScreen()),
489 this->t.xlib.image,
490 0, 0, 0, 0,
491 this->t.xlib.image->width,
492 this->t.xlib.image->height,
493 False);
494 else
495 #endif
496 TSXPutImage( display,
497 this->s.ddraw->d.drawable,
498 DefaultGCOfScreen(X11DRV_GetXScreen()),
499 this->t.xlib.image,
500 0, 0, 0, 0,
501 this->t.xlib.image->width,
502 this->t.xlib.image->height);
505 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Unlock(
506 LPDIRECTDRAWSURFACE4 this,LPVOID surface)
508 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
510 if (!this->s.ddraw->d.paintable)
511 return DD_OK;
513 /* Only redraw the screen when unlocking the buffer that is on screen */
514 if ((this->t.xlib.image != NULL) &&
515 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
516 Xlib_copy_surface_on_screen(this);
518 if (this->s.palette && this->s.palette->cm)
519 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
522 return DD_OK;
525 static HRESULT WINAPI DGA_IDirectDrawSurface4_Flip(
526 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
528 #ifdef HAVE_LIBXXF86DGA
529 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
530 if (!flipto) {
531 if (this->s.backbuffer)
532 flipto = this->s.backbuffer;
533 else
534 flipto = this;
536 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
538 if (flipto->s.palette && flipto->s.palette->cm) {
539 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
541 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
543 if (flipto!=this) {
544 int tmp;
545 LPVOID ptmp;
547 tmp = this->t.dga.fb_height;
548 this->t.dga.fb_height = flipto->t.dga.fb_height;
549 flipto->t.dga.fb_height = tmp;
551 ptmp = this->s.surface_desc.y.lpSurface;
552 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
553 flipto->s.surface_desc.y.lpSurface = ptmp;
555 return DD_OK;
556 #else /* defined(HAVE_LIBXXF86DGA) */
557 return E_UNEXPECTED;
558 #endif /* defined(HAVE_LIBXXF86DGA) */
561 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Flip(
562 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
564 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
565 if (!this->s.ddraw->d.paintable)
566 return DD_OK;
568 if (!flipto) {
569 if (this->s.backbuffer)
570 flipto = this->s.backbuffer;
571 else
572 flipto = this;
575 Xlib_copy_surface_on_screen(this);
577 if (flipto->s.palette && flipto->s.palette->cm) {
578 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,flipto->s.palette->cm);
580 if (flipto!=this) {
581 XImage *tmp;
582 LPVOID *surf;
583 tmp = this->t.xlib.image;
584 this->t.xlib.image = flipto->t.xlib.image;
585 flipto->t.xlib.image = tmp;
586 surf = this->s.surface_desc.y.lpSurface;
587 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
588 flipto->s.surface_desc.y.lpSurface = surf;
590 return DD_OK;
594 /* The IDirectDrawSurface4::SetPalette method attaches the specified
595 * DirectDrawPalette object to a surface. The surface uses this palette for all
596 * subsequent operations. The palette change takes place immediately.
598 static HRESULT WINAPI Xlib_IDirectDrawSurface4_SetPalette(
599 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
601 int i;
602 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
604 if (pal == NULL) {
605 if( this->s.palette != NULL )
606 this->s.palette->lpvtbl->fnRelease( this->s.palette );
607 this->s.palette = pal;
609 return DD_OK;
612 if( !(pal->cm) && (this->s.ddraw->d.screen_depth<=8))
614 pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,
615 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
617 if (!Options.managed)
618 TSXInstallColormap(display,pal->cm);
620 for (i=0;i<256;i++) {
621 XColor xc;
623 xc.red = pal->palents[i].peRed<<8;
624 xc.blue = pal->palents[i].peBlue<<8;
625 xc.green = pal->palents[i].peGreen<<8;
626 xc.flags = DoRed|DoBlue|DoGreen;
627 xc.pixel = i;
628 TSXStoreColor(display,pal->cm,&xc);
630 TSXInstallColormap(display,pal->cm);
633 /* According to spec, we are only supposed to
634 * AddRef if this is not the same palette.
636 if( this->s.palette != pal )
638 if( pal != NULL )
639 pal->lpvtbl->fnAddRef( pal );
640 if( this->s.palette != NULL )
641 this->s.palette->lpvtbl->fnRelease( this->s.palette );
642 this->s.palette = pal;
644 /* I think that we need to attach it to all backbuffers...*/
645 if( this->s.backbuffer ) {
646 if( this->s.backbuffer->s.palette )
647 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
648 this->s.backbuffer->s.palette );
649 this->s.backbuffer->s.palette = pal;
650 if( pal )
651 pal->lpvtbl->fnAddRef( pal );
653 /* Perform the refresh */
654 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
656 return DD_OK;
659 static HRESULT WINAPI DGA_IDirectDrawSurface4_SetPalette(
660 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
662 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
663 #ifdef HAVE_LIBXXF86DGA
664 /* According to spec, we are only supposed to
665 * AddRef if this is not the same palette.
667 if( this->s.palette != pal )
669 if( pal != NULL )
670 pal->lpvtbl->fnAddRef( pal );
671 if( this->s.palette != NULL )
672 this->s.palette->lpvtbl->fnRelease( this->s.palette );
673 this->s.palette = pal;
675 /* I think that we need to attach it to all backbuffers...*/
676 if( this->s.backbuffer ) {
677 if( this->s.backbuffer->s.palette )
678 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
679 this->s.backbuffer->s.palette = pal;
680 if( pal ) pal->lpvtbl->fnAddRef( pal );
682 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
684 return DD_OK;
685 #else /* defined(HAVE_LIBXXF86DGA) */
686 return E_UNEXPECTED;
687 #endif /* defined(HAVE_LIBXXF86DGA) */
692 static HRESULT WINAPI IDirectDrawSurface4_Blt(
693 LPDIRECTDRAWSURFACE4 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE4 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
695 RECT32 xdst,xsrc;
696 DDSURFACEDESC ddesc,sdesc;
697 int i,j;
699 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
700 this,rdst,src,rsrc,dwFlags,lpbltfx);
702 if (src != NULL)
703 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
704 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
706 if (TRACE_ON(ddraw)) {
707 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
708 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
709 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
710 if (dwFlags & DDBLT_DDFX) {
711 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
715 if (rdst) {
716 memcpy(&xdst,rdst,sizeof(xdst));
717 } else {
718 xdst.top = 0;
719 xdst.bottom = ddesc.dwHeight;
720 xdst.left = 0;
721 xdst.right = ddesc.dwWidth;
724 if (rsrc) {
725 memcpy(&xsrc,rsrc,sizeof(xsrc));
726 } else {
727 if (src) {
728 xsrc.top = 0;
729 xsrc.bottom = sdesc.dwHeight;
730 xsrc.left = 0;
731 xsrc.right = sdesc.dwWidth;
732 } else {
733 memset(&xsrc,0,sizeof(xsrc));
737 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
739 /* First, all the 'source-less' blits */
740 if (dwFlags & DDBLT_COLORFILL) {
741 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
742 LPBYTE xline,xpixel;
744 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
745 for (i=xdst.top;i<xdst.bottom;i++) {
746 xpixel = xline+bpp*xdst.left;
748 for (j=xdst.left;j<xdst.right;j++) {
749 /* FIXME: this only works on little endian
750 * architectures, where DWORD starts with low
751 * byte first!
753 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
754 xpixel += bpp;
756 xline += ddesc.lPitch;
758 dwFlags &= ~(DDBLT_COLORFILL);
761 if (dwFlags & DDBLT_DEPTHFILL) {
762 #ifdef HAVE_MESAGL
763 GLboolean ztest;
765 /* Clears the screen */
766 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
767 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
768 glGetBooleanv(GL_DEPTH_TEST, &ztest);
769 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
770 glClear(GL_DEPTH_BUFFER_BIT);
771 glDepthMask(ztest);
773 dwFlags &= ~(DDBLT_DEPTHFILL);
774 #endif HAVE_MESAGL
777 if (!src) {
778 if (dwFlags) {
779 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
781 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
782 return DD_OK;
785 /* Now the 'with source' blits */
787 /* Standard 'full-surface' blit without special effects */
788 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
789 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
790 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
791 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
792 !dwFlags
794 memcpy(ddesc.y.lpSurface,
795 sdesc.y.lpSurface,
796 ddesc.dwHeight * ddesc.lPitch);
797 } else {
798 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
799 int srcheight = xsrc.bottom - xsrc.top;
800 int srcwidth = xsrc.right - xsrc.left;
801 int dstheight = xdst.bottom - xdst.top;
802 int dstwidth = xdst.right - xdst.left;
803 int width = (xsrc.right - xsrc.left) * bpp;
804 int h;
806 /* Sanity check for rectangle sizes */
807 if ((srcheight != dstheight) || (srcwidth != dstwidth)) {
808 int x, y;
810 /* I think we should do a Blit with 'stretching' here....
811 Tomb Raider II uses this to display the background during the menu selection
812 when the screen resolution is != than 640x480 */
813 TRACE(ddraw, "Blt with stretching\n");
815 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
816 if (bpp == 1) {
817 /* In this case, we cannot do any anti-aliasing */
818 if(dwFlags & DDBLT_KEYSRC) {
819 for (y = xdst.top; y < xdst.bottom; y++) {
820 for (x = xdst.left; x < xdst.right; x++) {
821 double sx, sy;
822 unsigned char tmp;
823 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
824 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
826 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
827 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
829 tmp = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
831 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
832 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
833 dbuf[(y * ddesc.lPitch) + x] = tmp;
836 } else {
837 for (y = xdst.top; y < xdst.bottom; y++) {
838 for (x = xdst.left; x < xdst.right; x++) {
839 double sx, sy;
840 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
841 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
843 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
844 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
846 dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
850 } else {
851 FIXME(ddraw, "Not done yet for depth != 8\n");
853 } else {
854 /* Same size => fast blit */
855 if (dwFlags & DDBLT_KEYSRC) {
856 switch (bpp) {
857 case 1: {
858 unsigned char tmp,*psrc,*pdst;
859 int h,i;
861 for (h = 0; h < srcheight; h++) {
862 psrc=sdesc.y.lpSurface +
863 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
864 pdst=ddesc.y.lpSurface +
865 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
866 for(i=0;i<srcwidth;i++) {
867 tmp=*(psrc + i);
868 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
869 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
870 *(pdst + i)=tmp;
873 dwFlags&=~(DDBLT_KEYSRC);
874 } break;
876 case 2: {
877 unsigned short tmp,*psrc,*pdst;
878 int h,i;
880 for (h = 0; h < srcheight; h++) {
881 psrc=sdesc.y.lpSurface +
882 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
883 pdst=ddesc.y.lpSurface +
884 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
885 for(i=0;i<srcwidth;i++) {
886 tmp=*(psrc + i);
887 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
888 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
889 *(pdst + i)=tmp;
892 dwFlags&=~(DDBLT_KEYSRC);
893 } break;
895 default:
896 FIXME(ddraw, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
898 } else {
899 /* Non-stretching Blt without color keying */
900 for (h = 0; h < srcheight; h++) {
901 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
902 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
903 width);
909 if (dwFlags && FIXME_ON(ddraw)) {
910 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
913 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
914 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
916 return DD_OK;
919 static HRESULT WINAPI IDirectDrawSurface4_BltFast(
920 LPDIRECTDRAWSURFACE4 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT32 rsrc,DWORD trans
922 int i,bpp,w,h;
923 DDSURFACEDESC ddesc,sdesc;
925 if (1 || TRACE_ON(ddraw)) {
926 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
927 this,dstx,dsty,src,rsrc,trans
929 FIXME(ddraw," trans:");
930 if (FIXME_ON(ddraw))
931 _dump_DDBLTFAST(trans);
932 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
934 /* We need to lock the surfaces, or we won't get refreshes when done. */
935 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
936 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
937 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
938 h=rsrc->bottom-rsrc->top;
939 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
940 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
941 if (h<0) h=0;
942 w=rsrc->right-rsrc->left;
943 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
944 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
945 if (w<0) w=0;
947 for (i=0;i<h;i++) {
948 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
949 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
950 w*bpp
953 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
954 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
955 return DD_OK;
958 static HRESULT WINAPI IDirectDrawSurface4_BltBatch(
959 LPDIRECTDRAWSURFACE4 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
961 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
962 this,ddbltbatch,x,y
964 return DD_OK;
967 static HRESULT WINAPI IDirectDrawSurface4_GetCaps(
968 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS caps
970 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
971 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
972 return DD_OK;
975 static HRESULT WINAPI IDirectDrawSurface4_GetSurfaceDesc(
976 LPDIRECTDRAWSURFACE4 this,LPDDSURFACEDESC ddsd
977 ) {
978 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
979 this,ddsd);
981 /* Simply copy the surface description stored in the object */
982 *ddsd = this->s.surface_desc;
984 if (TRACE_ON(ddraw)) {
985 fprintf(stderr," flags: ");
986 _dump_DDSD(ddsd->dwFlags);
987 if (ddsd->dwFlags & DDSD_CAPS) {
988 fprintf(stderr, " caps: ");
989 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
991 fprintf(stderr,"\n");
994 return DD_OK;
997 static ULONG WINAPI IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4 this) {
998 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1000 return ++(this->ref);
1003 static ULONG WINAPI DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1004 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1006 #ifdef HAVE_LIBXXF86DGA
1007 if (!--(this->ref)) {
1008 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1009 /* clear out of surface list */
1010 if (this->t.dga.fb_height == -1) {
1011 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1012 } else {
1013 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
1016 /* Free the backbuffer */
1017 if (this->s.backbuffer)
1018 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1020 HeapFree(GetProcessHeap(),0,this);
1021 return 0;
1023 #endif /* defined(HAVE_LIBXXF86DGA) */
1024 return this->ref;
1027 static ULONG WINAPI Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1028 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1030 if (!--(this->ref)) {
1031 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1033 if( this->s.backbuffer )
1034 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1036 if (this->t.xlib.image != NULL) {
1037 if (this->s.ddraw->d.depth != this->s.ddraw->d.screen_depth) {
1038 /* In pixel conversion mode, there are two buffers to release... */
1039 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1041 #ifdef HAVE_LIBXXSHM
1042 if (this->s.ddraw->e.xlib.xshm_active) {
1043 TSXShmDetach(display, &(this->t.xlib.shminfo));
1044 TSXDestroyImage(this->t.xlib.image);
1045 shmdt(this->t.xlib.shminfo.shmaddr);
1046 } else {
1047 #endif
1048 HeapFree(GetProcessHeap(),0,this->t.xlib.image->data);
1049 this->t.xlib.image->data = NULL;
1050 TSXDestroyImage(this->t.xlib.image);
1051 #ifdef HAVE_LIBXXSHM
1053 #endif
1055 } else {
1056 this->t.xlib.image->data = NULL;
1058 #ifdef HAVE_LIBXXSHM
1059 if (this->s.ddraw->e.xlib.xshm_active) {
1060 TSXShmDetach(display, &(this->t.xlib.shminfo));
1061 TSXDestroyImage(this->t.xlib.image);
1062 shmdt(this->t.xlib.shminfo.shmaddr);
1063 } else {
1064 #endif
1065 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1066 TSXDestroyImage(this->t.xlib.image);
1067 #ifdef HAVE_LIBXXSHM
1069 #endif
1072 this->t.xlib.image = 0;
1073 } else {
1074 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1077 if (this->s.palette)
1078 this->s.palette->lpvtbl->fnRelease(this->s.palette);
1080 HeapFree(GetProcessHeap(),0,this);
1081 return 0;
1084 return this->ref;
1087 static HRESULT WINAPI IDirectDrawSurface4_GetAttachedSurface(
1088 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1090 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1091 this, lpddsd, lpdsf);
1093 if (TRACE_ON(ddraw)) {
1094 TRACE(ddraw," caps ");
1095 _dump_DDSCAPS(lpddsd->dwCaps);
1098 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1099 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1100 return E_FAIL;
1103 /* FIXME: should handle more than one backbuffer */
1104 *lpdsf = this->s.backbuffer;
1106 if( this->s.backbuffer )
1107 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
1109 return DD_OK;
1112 static HRESULT WINAPI IDirectDrawSurface4_Initialize(
1113 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1115 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
1117 return DDERR_ALREADYINITIALIZED;
1120 static HRESULT WINAPI IDirectDrawSurface4_GetPixelFormat(
1121 LPDIRECTDRAWSURFACE4 this,LPDDPIXELFORMAT pf
1123 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
1125 *pf = this->s.surface_desc.ddpfPixelFormat;
1127 return DD_OK;
1130 static HRESULT WINAPI IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4 this,DWORD dwFlags) {
1131 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
1132 return DD_OK;
1135 static HRESULT WINAPI IDirectDrawSurface4_GetOverlayPosition(
1136 LPDIRECTDRAWSURFACE4 this,LPLONG x1,LPLONG x2
1138 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
1139 return DD_OK;
1142 static HRESULT WINAPI IDirectDrawSurface4_SetClipper(
1143 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWCLIPPER clipper
1145 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
1146 return DD_OK;
1149 static HRESULT WINAPI IDirectDrawSurface4_AddAttachedSurface(
1150 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 surf
1152 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
1154 this->lpvtbl->fnAddRef(this);
1156 /* This hack will be enough for the moment */
1157 if (this->s.backbuffer == NULL)
1158 this->s.backbuffer = surf;
1159 return DD_OK;
1162 static HRESULT WINAPI IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4 this,HDC32* lphdc) {
1163 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
1164 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1165 return DD_OK;
1168 static HRESULT WINAPI IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4 this,HDC32 hdc) {
1169 DDSURFACEDESC desc;
1170 DWORD x, y;
1172 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
1173 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1175 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1176 I fill it with 'dummy' values to have something on the screen */
1177 this->lpvtbl->fnLock(this,NULL,&desc,0,0);
1178 for (y = 0; y < desc.dwHeight; y++) {
1179 for (x = 0; x < desc.dwWidth; x++) {
1180 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) this + x + y;
1183 this->lpvtbl->fnUnlock(this,NULL);
1185 return DD_OK;
1189 static HRESULT WINAPI IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4 this,REFIID refiid,LPVOID *obj) {
1190 char xrefiid[50];
1192 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1193 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1195 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1196 * the same interface. And IUnknown does that too of course.
1198 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1199 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1200 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1201 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1202 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1204 *obj = this;
1205 this->lpvtbl->fnAddRef(this);
1207 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1209 return S_OK;
1211 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1213 /* Texture interface */
1214 *obj = d3dtexture2_create(this);
1215 this->lpvtbl->fnAddRef(this);
1217 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1219 return S_OK;
1221 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1223 /* Texture interface */
1224 *obj = d3dtexture_create(this);
1225 this->lpvtbl->fnAddRef(this);
1227 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1229 return S_OK;
1231 else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj))
1233 /* It is the OpenGL Direct3D Device */
1234 this->lpvtbl->fnAddRef(this);
1236 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1238 return S_OK;
1241 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1242 return OLE_E_ENUM_NOMORE;
1245 static HRESULT WINAPI IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4 this) {
1246 TRACE(ddraw,"(%p)->(), stub!\n",this);
1247 return DD_OK; /* hmm */
1250 static HRESULT WINAPI IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1251 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
1252 return DD_OK;
1255 static HRESULT WINAPI IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4 this) {
1256 FIXME(ddraw,"(%p)->(),stub!\n",this);
1257 return DD_OK;
1260 static HRESULT WINAPI IDirectDrawSurface4_SetColorKey(
1261 LPDIRECTDRAWSURFACE4 this, DWORD dwFlags, LPDDCOLORKEY ckey )
1263 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);
1265 if( dwFlags & DDCKEY_SRCBLT )
1267 dwFlags &= ~DDCKEY_SRCBLT;
1268 this->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1269 memcpy( &(this->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1272 if( dwFlags & DDCKEY_DESTBLT )
1274 dwFlags &= ~DDCKEY_DESTBLT;
1275 this->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1276 memcpy( &(this->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1279 if( dwFlags & DDCKEY_SRCOVERLAY )
1281 dwFlags &= ~DDCKEY_SRCOVERLAY;
1282 this->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1283 memcpy( &(this->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1286 if( dwFlags & DDCKEY_DESTOVERLAY )
1288 dwFlags &= ~DDCKEY_DESTOVERLAY;
1289 this->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1290 memcpy( &(this->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1293 if( dwFlags )
1295 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1298 return DD_OK;
1302 static HRESULT WINAPI IDirectDrawSurface4_AddOverlayDirtyRect(
1303 LPDIRECTDRAWSURFACE4 this,
1304 LPRECT32 lpRect )
1306 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
1308 return DD_OK;
1311 static HRESULT WINAPI IDirectDrawSurface4_DeleteAttachedSurface(
1312 LPDIRECTDRAWSURFACE4 this,
1313 DWORD dwFlags,
1314 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1316 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1318 return DD_OK;
1321 static HRESULT WINAPI IDirectDrawSurface4_EnumOverlayZOrders(
1322 LPDIRECTDRAWSURFACE4 this,
1323 DWORD dwFlags,
1324 LPVOID lpContext,
1325 LPDDENUMSURFACESCALLBACK lpfnCallback )
1327 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1328 lpContext, lpfnCallback );
1330 return DD_OK;
1333 static HRESULT WINAPI IDirectDrawSurface4_GetClipper(
1334 LPDIRECTDRAWSURFACE4 this,
1335 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1337 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1339 return DD_OK;
1342 static HRESULT WINAPI IDirectDrawSurface4_GetColorKey(
1343 LPDIRECTDRAWSURFACE4 this,
1344 DWORD dwFlags,
1345 LPDDCOLORKEY lpDDColorKey )
1347 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);
1349 if( dwFlags & DDCKEY_SRCBLT ) {
1350 dwFlags &= ~DDCKEY_SRCBLT;
1351 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1354 if( dwFlags & DDCKEY_DESTBLT )
1356 dwFlags &= ~DDCKEY_DESTBLT;
1357 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1360 if( dwFlags & DDCKEY_SRCOVERLAY )
1362 dwFlags &= ~DDCKEY_SRCOVERLAY;
1363 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1366 if( dwFlags & DDCKEY_DESTOVERLAY )
1368 dwFlags &= ~DDCKEY_DESTOVERLAY;
1369 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1372 if( dwFlags )
1374 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1377 return DD_OK;
1380 static HRESULT WINAPI IDirectDrawSurface4_GetFlipStatus(
1381 LPDIRECTDRAWSURFACE4 this,
1382 DWORD dwFlags )
1384 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1386 return DD_OK;
1389 static HRESULT WINAPI IDirectDrawSurface4_GetPalette(
1390 LPDIRECTDRAWSURFACE4 this,
1391 LPDIRECTDRAWPALETTE* lplpDDPalette )
1393 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1395 return DD_OK;
1398 static HRESULT WINAPI IDirectDrawSurface4_SetOverlayPosition(
1399 LPDIRECTDRAWSURFACE4 this,
1400 LONG lX,
1401 LONG lY)
1403 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1405 return DD_OK;
1408 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlay(
1409 LPDIRECTDRAWSURFACE4 this,
1410 LPRECT32 lpSrcRect,
1411 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1412 LPRECT32 lpDestRect,
1413 DWORD dwFlags,
1414 LPDDOVERLAYFX lpDDOverlayFx )
1416 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1417 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1419 return DD_OK;
1422 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayDisplay(
1423 LPDIRECTDRAWSURFACE4 this,
1424 DWORD dwFlags )
1426 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1428 return DD_OK;
1431 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayZOrder(
1432 LPDIRECTDRAWSURFACE4 this,
1433 DWORD dwFlags,
1434 LPDIRECTDRAWSURFACE4 lpDDSReference )
1436 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1438 return DD_OK;
1441 static HRESULT WINAPI IDirectDrawSurface4_GetDDInterface(
1442 LPDIRECTDRAWSURFACE4 this,
1443 LPVOID* lplpDD )
1445 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1447 /* Not sure about that... */
1448 *lplpDD = (void *) this->s.ddraw;
1450 return DD_OK;
1453 static HRESULT WINAPI IDirectDrawSurface4_PageLock(
1454 LPDIRECTDRAWSURFACE4 this,
1455 DWORD dwFlags )
1457 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1459 return DD_OK;
1462 static HRESULT WINAPI IDirectDrawSurface4_PageUnlock(
1463 LPDIRECTDRAWSURFACE4 this,
1464 DWORD dwFlags )
1466 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1468 return DD_OK;
1471 static HRESULT WINAPI IDirectDrawSurface4_SetSurfaceDesc(
1472 LPDIRECTDRAWSURFACE4 this,
1473 LPDDSURFACEDESC lpDDSD,
1474 DWORD dwFlags )
1476 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1478 return DD_OK;
1481 static HRESULT WINAPI IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4 this,
1482 REFGUID guidTag,
1483 LPVOID lpData,
1484 DWORD cbSize,
1485 DWORD dwFlags) {
1486 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag, lpData, cbSize, dwFlags);
1488 return DD_OK;
1491 static HRESULT WINAPI IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4 this,
1492 REFGUID guidTag,
1493 LPVOID lpBuffer,
1494 LPDWORD lpcbBufferSize) {
1495 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", this, guidTag, lpBuffer, lpcbBufferSize);
1497 return DD_OK;
1500 static HRESULT WINAPI IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4 this,
1501 REFGUID guidTag) {
1502 FIXME(ddraw, "(%p)->(%p)\n", this, guidTag);
1504 return DD_OK;
1507 static HRESULT WINAPI IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4 this,
1508 LPDWORD lpValue) {
1509 FIXME(ddraw, "(%p)->(%p)\n", this, lpValue);
1511 return DD_OK;
1514 static HRESULT WINAPI IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 this) {
1515 FIXME(ddraw, "(%p)\n", this);
1517 return DD_OK;
1520 static struct IDirectDrawSurface4_VTable dga_dds4vt = {
1521 IDirectDrawSurface4_QueryInterface,
1522 IDirectDrawSurface4_AddRef,
1523 DGA_IDirectDrawSurface4_Release,
1524 IDirectDrawSurface4_AddAttachedSurface,
1525 IDirectDrawSurface4_AddOverlayDirtyRect,
1526 IDirectDrawSurface4_Blt,
1527 IDirectDrawSurface4_BltBatch,
1528 IDirectDrawSurface4_BltFast,
1529 IDirectDrawSurface4_DeleteAttachedSurface,
1530 IDirectDrawSurface4_EnumAttachedSurfaces,
1531 IDirectDrawSurface4_EnumOverlayZOrders,
1532 DGA_IDirectDrawSurface4_Flip,
1533 IDirectDrawSurface4_GetAttachedSurface,
1534 IDirectDrawSurface4_GetBltStatus,
1535 IDirectDrawSurface4_GetCaps,
1536 IDirectDrawSurface4_GetClipper,
1537 IDirectDrawSurface4_GetColorKey,
1538 IDirectDrawSurface4_GetDC,
1539 IDirectDrawSurface4_GetFlipStatus,
1540 IDirectDrawSurface4_GetOverlayPosition,
1541 IDirectDrawSurface4_GetPalette,
1542 IDirectDrawSurface4_GetPixelFormat,
1543 IDirectDrawSurface4_GetSurfaceDesc,
1544 IDirectDrawSurface4_Initialize,
1545 IDirectDrawSurface4_IsLost,
1546 IDirectDrawSurface4_Lock,
1547 IDirectDrawSurface4_ReleaseDC,
1548 IDirectDrawSurface4_Restore,
1549 IDirectDrawSurface4_SetClipper,
1550 IDirectDrawSurface4_SetColorKey,
1551 IDirectDrawSurface4_SetOverlayPosition,
1552 DGA_IDirectDrawSurface4_SetPalette,
1553 DGA_IDirectDrawSurface4_Unlock,
1554 IDirectDrawSurface4_UpdateOverlay,
1555 IDirectDrawSurface4_UpdateOverlayDisplay,
1556 IDirectDrawSurface4_UpdateOverlayZOrder,
1557 IDirectDrawSurface4_GetDDInterface,
1558 IDirectDrawSurface4_PageLock,
1559 IDirectDrawSurface4_PageUnlock,
1560 IDirectDrawSurface4_SetSurfaceDesc,
1561 IDirectDrawSurface4_SetPrivateData,
1562 IDirectDrawSurface4_GetPrivateData,
1563 IDirectDrawSurface4_FreePrivateData,
1564 IDirectDrawSurface4_GetUniquenessValue,
1565 IDirectDrawSurface4_ChangeUniquenessValue
1568 static struct IDirectDrawSurface4_VTable xlib_dds4vt = {
1569 IDirectDrawSurface4_QueryInterface,
1570 IDirectDrawSurface4_AddRef,
1571 Xlib_IDirectDrawSurface4_Release,
1572 IDirectDrawSurface4_AddAttachedSurface,
1573 IDirectDrawSurface4_AddOverlayDirtyRect,
1574 IDirectDrawSurface4_Blt,
1575 IDirectDrawSurface4_BltBatch,
1576 IDirectDrawSurface4_BltFast,
1577 IDirectDrawSurface4_DeleteAttachedSurface,
1578 IDirectDrawSurface4_EnumAttachedSurfaces,
1579 IDirectDrawSurface4_EnumOverlayZOrders,
1580 Xlib_IDirectDrawSurface4_Flip,
1581 IDirectDrawSurface4_GetAttachedSurface,
1582 IDirectDrawSurface4_GetBltStatus,
1583 IDirectDrawSurface4_GetCaps,
1584 IDirectDrawSurface4_GetClipper,
1585 IDirectDrawSurface4_GetColorKey,
1586 IDirectDrawSurface4_GetDC,
1587 IDirectDrawSurface4_GetFlipStatus,
1588 IDirectDrawSurface4_GetOverlayPosition,
1589 IDirectDrawSurface4_GetPalette,
1590 IDirectDrawSurface4_GetPixelFormat,
1591 IDirectDrawSurface4_GetSurfaceDesc,
1592 IDirectDrawSurface4_Initialize,
1593 IDirectDrawSurface4_IsLost,
1594 IDirectDrawSurface4_Lock,
1595 IDirectDrawSurface4_ReleaseDC,
1596 IDirectDrawSurface4_Restore,
1597 IDirectDrawSurface4_SetClipper,
1598 IDirectDrawSurface4_SetColorKey,
1599 IDirectDrawSurface4_SetOverlayPosition,
1600 Xlib_IDirectDrawSurface4_SetPalette,
1601 Xlib_IDirectDrawSurface4_Unlock,
1602 IDirectDrawSurface4_UpdateOverlay,
1603 IDirectDrawSurface4_UpdateOverlayDisplay,
1604 IDirectDrawSurface4_UpdateOverlayZOrder,
1605 IDirectDrawSurface4_GetDDInterface,
1606 IDirectDrawSurface4_PageLock,
1607 IDirectDrawSurface4_PageUnlock,
1608 IDirectDrawSurface4_SetSurfaceDesc,
1609 IDirectDrawSurface4_SetPrivateData,
1610 IDirectDrawSurface4_GetPrivateData,
1611 IDirectDrawSurface4_FreePrivateData,
1612 IDirectDrawSurface4_GetUniquenessValue,
1613 IDirectDrawSurface4_ChangeUniquenessValue
1616 /******************************************************************************
1617 * DirectDrawCreateClipper (DDRAW.7)
1619 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1620 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1621 LPUNKNOWN pUnkOuter)
1623 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1625 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1626 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1627 (*lplpDDClipper)->ref = 1;
1629 return DD_OK;
1632 /******************************************************************************
1633 * IDirectDrawClipper
1635 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1636 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1638 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1639 return DD_OK;
1642 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1643 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1645 this->ref--;
1646 if (this->ref)
1647 return this->ref;
1648 HeapFree(GetProcessHeap(),0,this);
1649 return 0;
1652 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1653 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1655 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1656 if (hmm) *hmm=0;
1657 return DD_OK;
1660 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1661 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1663 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1664 return DD_OK;
1667 static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
1668 LPDIRECTDRAWCLIPPER this,
1669 REFIID riid,
1670 LPVOID* ppvObj )
1672 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
1673 return OLE_E_ENUM_NOMORE;
1676 static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
1678 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1679 return ++(this->ref);
1682 static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
1683 LPDIRECTDRAWCLIPPER this,
1684 HWND32* HWndPtr )
1686 FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
1687 return DD_OK;
1690 static HRESULT WINAPI IDirectDrawClipper_Initialize(
1691 LPDIRECTDRAWCLIPPER this,
1692 LPDIRECTDRAW lpDD,
1693 DWORD dwFlags )
1695 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
1696 return DD_OK;
1699 static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
1700 LPDIRECTDRAWCLIPPER this,
1701 BOOL32* lpbChanged )
1703 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
1704 return DD_OK;
1707 static struct IDirectDrawClipper_VTable ddclipvt = {
1708 IDirectDrawClipper_QueryInterface,
1709 IDirectDrawClipper_AddRef,
1710 IDirectDrawClipper_Release,
1711 IDirectDrawClipper_GetClipList,
1712 IDirectDrawClipper_GetHWnd,
1713 IDirectDrawClipper_Initialize,
1714 IDirectDrawClipper_IsClipListChanged,
1715 IDirectDrawClipper_SetClipList,
1716 IDirectDrawClipper_SetHwnd
1720 /******************************************************************************
1721 * IDirectDrawPalette
1723 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1724 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1726 int i;
1728 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1729 this,x,start,count,palent);
1731 if (!this->cm) /* should not happen */ {
1732 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1733 return DDERR_GENERIC;
1735 for (i=0;i<count;i++) {
1736 palent[i].peRed = this->palents[start+i].peRed;
1737 palent[i].peBlue = this->palents[start+i].peBlue;
1738 palent[i].peGreen = this->palents[start+i].peGreen;
1739 palent[i].peFlags = this->palents[start+i].peFlags;
1742 return DD_OK;
1745 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1746 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1748 XColor xc;
1749 int i;
1751 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1752 this,x,start,count,palent
1754 for (i=0;i<count;i++) {
1755 xc.red = palent[i].peRed<<8;
1756 xc.blue = palent[i].peBlue<<8;
1757 xc.green = palent[i].peGreen<<8;
1758 xc.flags = DoRed|DoBlue|DoGreen;
1759 xc.pixel = start+i;
1761 if (this->cm)
1762 TSXStoreColor(display,this->cm,&xc);
1764 this->palents[start+i].peRed = palent[i].peRed;
1765 this->palents[start+i].peBlue = palent[i].peBlue;
1766 this->palents[start+i].peGreen = palent[i].peGreen;
1767 this->palents[start+i].peFlags = palent[i].peFlags;
1770 /* Now, if we are in 'depth conversion mode', update the screen palette */
1771 if (this->ddraw->d.depth != this->ddraw->d.screen_depth) {
1772 int i;
1774 switch (this->ddraw->d.screen_depth) {
1775 case 16: {
1776 unsigned short *screen_palette = (unsigned short *) this->screen_palents;
1778 for (i = 0; i < count; i++) {
1779 screen_palette[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
1780 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
1781 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
1783 } break;
1785 default:
1786 ERR(ddraw, "Memory corruption !\n");
1787 break;
1791 if (!this->cm) /* should not happen */ {
1793 return DD_OK;
1796 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1797 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1799 #ifdef HAVE_LIBXXF86DGA
1800 XColor xc;
1801 Colormap cm;
1802 int i;
1804 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1805 this,x,start,count,palent
1807 if (!this->cm) /* should not happen */ {
1808 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1809 return DDERR_GENERIC;
1811 /* FIXME: free colorcells instead of freeing whole map */
1812 cm = this->cm;
1813 this->cm = TSXCopyColormapAndFree(display,this->cm);
1814 TSXFreeColormap(display,cm);
1816 for (i=0;i<count;i++) {
1817 xc.red = palent[i].peRed<<8;
1818 xc.blue = palent[i].peBlue<<8;
1819 xc.green = palent[i].peGreen<<8;
1820 xc.flags = DoRed|DoBlue|DoGreen;
1821 xc.pixel = i+start;
1823 TSXStoreColor(display,this->cm,&xc);
1825 this->palents[start+i].peRed = palent[i].peRed;
1826 this->palents[start+i].peBlue = palent[i].peBlue;
1827 this->palents[start+i].peGreen = palent[i].peGreen;
1828 this->palents[start+i].peFlags = palent[i].peFlags;
1830 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1831 return DD_OK;
1832 #else /* defined(HAVE_LIBXXF86DGA) */
1833 return E_UNEXPECTED;
1834 #endif /* defined(HAVE_LIBXXF86DGA) */
1837 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1838 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1839 if (!--(this->ref)) {
1840 if (this->cm) {
1841 TSXFreeColormap(display,this->cm);
1842 this->cm = 0;
1844 HeapFree(GetProcessHeap(),0,this);
1845 return 0;
1847 return this->ref;
1850 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1852 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1853 return ++(this->ref);
1856 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1857 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1859 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1861 return DDERR_ALREADYINITIALIZED;
1864 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1865 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1867 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1868 return DD_OK;
1871 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1872 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1874 char xrefiid[50];
1876 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1877 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1879 return S_OK;
1882 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1883 IDirectDrawPalette_QueryInterface,
1884 IDirectDrawPalette_AddRef,
1885 IDirectDrawPalette_Release,
1886 IDirectDrawPalette_GetCaps,
1887 IDirectDrawPalette_GetEntries,
1888 IDirectDrawPalette_Initialize,
1889 DGA_IDirectDrawPalette_SetEntries
1892 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1893 IDirectDrawPalette_QueryInterface,
1894 IDirectDrawPalette_AddRef,
1895 IDirectDrawPalette_Release,
1896 IDirectDrawPalette_GetCaps,
1897 IDirectDrawPalette_GetEntries,
1898 IDirectDrawPalette_Initialize,
1899 Xlib_IDirectDrawPalette_SetEntries
1902 /*******************************************************************************
1903 * IDirect3D
1905 static HRESULT WINAPI IDirect3D_QueryInterface(
1906 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1908 /* FIXME: Not sure if this is correct */
1909 char xrefiid[50];
1911 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1912 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1913 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1914 *obj = this;
1915 this->lpvtbl->fnAddRef(this);
1917 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
1919 return S_OK;
1921 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1922 LPDIRECT3D d3d;
1924 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1925 d3d->ref = 1;
1926 d3d->ddraw = (LPDIRECTDRAW)this;
1927 this->lpvtbl->fnAddRef(this);
1928 d3d->lpvtbl = &d3dvt;
1929 *obj = d3d;
1931 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
1933 return S_OK;
1935 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
1936 LPDIRECT3D2 d3d;
1938 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1939 d3d->ref = 1;
1940 d3d->ddraw = (LPDIRECTDRAW)this;
1941 this->lpvtbl->fnAddRef(this);
1942 d3d->lpvtbl = &d3d2vt;
1943 *obj = d3d;
1945 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
1947 return S_OK;
1949 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1950 return OLE_E_ENUM_NOMORE;
1953 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1954 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1956 return ++(this->ref);
1959 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1961 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1963 if (!--(this->ref)) {
1964 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1965 HeapFree(GetProcessHeap(),0,this);
1966 return 0;
1968 return this->ref;
1971 static HRESULT WINAPI IDirect3D_Initialize(
1972 LPDIRECT3D this, REFIID refiid )
1974 /* FIXME: Not sure if this is correct */
1975 char xrefiid[50];
1977 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1978 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1980 return DDERR_ALREADYINITIALIZED;
1983 static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this,
1984 LPD3DENUMDEVICESCALLBACK cb,
1985 LPVOID context) {
1986 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1988 /* Call functions defined in d3ddevices.c */
1989 if (d3d_OpenGL_dx3(cb, context))
1990 return DD_OK;
1992 return DD_OK;
1995 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,
1996 LPDIRECT3DLIGHT *lplight,
1997 IUnknown *lpunk)
1999 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
2001 /* Call the creation function that is located in d3dlight.c */
2002 *lplight = d3dlight_create_dx3(this);
2004 return DD_OK;
2007 static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this,
2008 LPDIRECT3DMATERIAL *lpmaterial,
2009 IUnknown *lpunk)
2011 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2013 /* Call the creation function that is located in d3dviewport.c */
2014 *lpmaterial = d3dmaterial_create(this);
2016 return DD_OK;
2019 static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this,
2020 LPDIRECT3DVIEWPORT *lpviewport,
2021 IUnknown *lpunk)
2023 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2025 /* Call the creation function that is located in d3dviewport.c */
2026 *lpviewport = d3dviewport_create(this);
2028 return DD_OK;
2031 static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this,
2032 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2033 LPD3DFINDDEVICERESULT lpfinddevrst)
2035 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2037 return DD_OK;
2040 static struct IDirect3D_VTable d3dvt = {
2041 IDirect3D_QueryInterface,
2042 IDirect3D_AddRef,
2043 IDirect3D_Release,
2044 IDirect3D_Initialize,
2045 IDirect3D_EnumDevices,
2046 IDirect3D_CreateLight,
2047 IDirect3D_CreateMaterial,
2048 IDirect3D_CreateViewport,
2049 IDirect3D_FindDevice
2052 /*******************************************************************************
2053 * IDirect3D2
2055 static HRESULT WINAPI IDirect3D2_QueryInterface(
2056 LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) {
2057 /* For the moment, we use the same function as in IDirect3D */
2058 TRACE(ddraw, "Calling IDirect3D enumerating function.\n");
2060 return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj);
2063 static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) {
2064 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2066 return ++(this->ref);
2069 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
2070 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2072 if (!--(this->ref)) {
2073 this->ddraw->lpvtbl->fnRelease(this->ddraw);
2074 HeapFree(GetProcessHeap(),0,this);
2075 return 0;
2077 return this->ref;
2080 static HRESULT WINAPI IDirect3D2_EnumDevices(
2081 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2083 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
2085 /* Call functions defined in d3ddevices.c */
2086 if (d3d_OpenGL(cb, context))
2087 return DD_OK;
2089 return DD_OK;
2092 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,
2093 LPDIRECT3DLIGHT *lplight,
2094 IUnknown *lpunk)
2096 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
2098 /* Call the creation function that is located in d3dlight.c */
2099 *lplight = d3dlight_create(this);
2101 return DD_OK;
2104 static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this,
2105 LPDIRECT3DMATERIAL2 *lpmaterial,
2106 IUnknown *lpunk)
2108 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2110 /* Call the creation function that is located in d3dviewport.c */
2111 *lpmaterial = d3dmaterial2_create(this);
2113 return DD_OK;
2116 static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this,
2117 LPDIRECT3DVIEWPORT2 *lpviewport,
2118 IUnknown *lpunk)
2120 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2122 /* Call the creation function that is located in d3dviewport.c */
2123 *lpviewport = d3dviewport2_create(this);
2125 return DD_OK;
2128 static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this,
2129 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2130 LPD3DFINDDEVICERESULT lpfinddevrst)
2132 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2134 return DD_OK;
2137 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,
2138 REFCLSID rguid,
2139 LPDIRECTDRAWSURFACE surface,
2140 LPDIRECT3DDEVICE2 *device)
2142 char xbuf[50];
2144 WINE_StringFromCLSID(rguid,xbuf);
2145 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device);
2147 if (is_OpenGL(rguid, surface, device, this)) {
2148 this->lpvtbl->fnAddRef(this);
2149 return DD_OK;
2152 return DDERR_INVALIDPARAMS;
2155 static struct IDirect3D2_VTable d3d2vt = {
2156 IDirect3D2_QueryInterface,
2157 IDirect3D2_AddRef,
2158 IDirect3D2_Release,
2159 IDirect3D2_EnumDevices,
2160 IDirect3D2_CreateLight,
2161 IDirect3D2_CreateMaterial,
2162 IDirect3D2_CreateViewport,
2163 IDirect3D2_FindDevice,
2164 IDirect3D2_CreateDevice
2167 /*******************************************************************************
2168 * IDirectDraw
2171 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2172 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2174 static INT32 ddrawXlibThisOffset = 0;
2176 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
2177 LPDDSURFACEDESC lpddsd,
2178 LPDIRECTDRAWSURFACE lpdsf)
2180 int bpp;
2182 /* The surface was already allocated when entering in this function */
2183 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2185 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2186 /* This is a Z Buffer */
2187 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2188 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2189 } else {
2190 /* This is a standard image */
2191 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2192 /* No pixel format => use DirectDraw's format */
2193 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
2194 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2195 } else {
2196 /* To check what the program wants */
2197 if (TRACE_ON(ddraw)) {
2198 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2202 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2203 bpp = 1;
2204 } else {
2205 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2209 /* Copy the surface description */
2210 lpdsf->s.surface_desc = *lpddsd;
2212 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2213 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2214 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2216 return DD_OK;
2219 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
2220 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2222 #ifdef HAVE_LIBXXF86DGA
2223 int i;
2225 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
2226 if (TRACE_ON(ddraw)) {
2227 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2228 _dump_DDSD(lpddsd->dwFlags);
2229 fprintf(stderr,"caps ");
2230 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2231 fprintf(stderr,"]\n");
2234 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2235 this->lpvtbl->fnAddRef(this);
2237 (*lpdsf)->ref = 1;
2238 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds4vt;
2239 (*lpdsf)->s.ddraw = this;
2240 (*lpdsf)->s.palette = NULL;
2241 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2243 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2244 lpddsd->dwWidth = this->d.width;
2245 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2246 lpddsd->dwHeight = this->d.height;
2248 /* Check if this a 'primary surface' or not */
2249 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2250 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2252 /* This is THE primary surface => there is DGA-specific code */
2253 /* First, store the surface description */
2254 (*lpdsf)->s.surface_desc = *lpddsd;
2256 /* Find a viewport */
2257 for (i=0;i<32;i++)
2258 if (!(this->e.dga.vpmask & (1<<i)))
2259 break;
2260 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2261 /* if i == 32 or maximum ... return error */
2262 this->e.dga.vpmask|=(1<<i);
2263 (*lpdsf)->s.surface_desc.y.lpSurface =
2264 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
2265 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
2266 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
2267 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
2269 /* Add flags if there were not present */
2270 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2271 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2272 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2273 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d.width,this->d.height,lpddsd->lPitch);
2274 /* We put our surface always in video memory */
2275 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2276 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2277 (*lpdsf)->s.backbuffer = NULL;
2279 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2280 LPDIRECTDRAWSURFACE4 back;
2282 if (lpddsd->dwBackBufferCount>1)
2283 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2285 (*lpdsf)->s.backbuffer = back =
2286 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2287 this->lpvtbl->fnAddRef(this);
2288 back->ref = 1;
2289 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&dga_dds4vt;
2290 for (i=0;i<32;i++)
2291 if (!(this->e.dga.vpmask & (1<<i)))
2292 break;
2293 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2294 /* if i == 32 or maximum ... return error */
2295 this->e.dga.vpmask|=(1<<i);
2296 back->t.dga.fb_height = i*this->e.dga.fb_height;
2298 /* Copy the surface description from the front buffer */
2299 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2300 /* Change the parameters that are not the same */
2301 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
2302 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
2303 back->s.ddraw = this;
2304 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2305 * one! */
2307 /* Add relevant info to front and back buffers */
2308 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2309 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2310 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2311 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2312 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2314 } else {
2315 /* There is no DGA-specific code here...
2316 Go to the common surface creation function */
2317 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2320 return DD_OK;
2321 #else /* defined(HAVE_LIBXXF86DGA) */
2322 return E_UNEXPECTED;
2323 #endif /* defined(HAVE_LIBXXF86DGA) */
2326 #ifdef HAVE_LIBXXSHM
2327 /* Error handlers for Image creation */
2328 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2329 XShmErrorFlag = 1;
2330 return 0;
2333 static XImage *create_xshmimage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2334 XImage *img;
2335 int (*WineXHandler)(Display *, XErrorEvent *);
2337 img = TSXShmCreateImage(display,
2338 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2339 this->d.screen_depth,
2340 ZPixmap,
2341 NULL,
2342 &(lpdsf->t.xlib.shminfo),
2343 lpdsf->s.surface_desc.dwWidth,
2344 lpdsf->s.surface_desc.dwHeight);
2346 if (img == NULL) {
2347 ERR(ddraw, "Error creating XShm image. Reverting to standard X images !\n");
2348 this->e.xlib.xshm_active = 0;
2349 return NULL;
2352 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2353 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2354 ERR(ddraw, "Error creating shared memory segment. Reverting to standard X images !\n");
2355 this->e.xlib.xshm_active = 0;
2356 TSXDestroyImage(img);
2357 return NULL;
2360 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2362 if (img->data == (char *) -1) {
2363 ERR(ddraw, "Error attaching shared memory segment. Reverting to standard X images !\n");
2364 this->e.xlib.xshm_active = 0;
2365 TSXDestroyImage(img);
2366 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2367 return NULL;
2369 lpdsf->t.xlib.shminfo.readOnly = False;
2371 /* This is where things start to get trickier....
2372 First, we flush the current X connections to be sure to catch all non-XShm related
2373 errors */
2374 TSXSync(display, False);
2375 /* Then we enter in the non-thread safe part of the tests */
2376 EnterCriticalSection( &X11DRV_CritSection );
2378 /* Reset the error flag, sets our new error handler and try to attach the surface */
2379 XShmErrorFlag = 0;
2380 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2381 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2382 XSync(display, False);
2384 /* Check the error flag */
2385 if (XShmErrorFlag) {
2386 /* An error occured */
2387 XFlush(display);
2388 XShmErrorFlag = 0;
2389 XDestroyImage(img);
2390 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2391 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2392 XSetErrorHandler(WineXHandler);
2394 ERR(ddraw, "Error attaching shared memory segment to X server. Reverting to standard X images !\n");
2395 this->e.xlib.xshm_active = 0;
2397 /* Leave the critical section */
2398 LeaveCriticalSection( &X11DRV_CritSection );
2400 return NULL;
2403 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2404 but it may be a bit overkill.... */
2405 XSetErrorHandler(WineXHandler);
2406 LeaveCriticalSection( &X11DRV_CritSection );
2408 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2410 if (this->d.depth != this->d.screen_depth) {
2411 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2412 lpdsf->s.surface_desc.dwWidth *
2413 lpdsf->s.surface_desc.dwHeight *
2414 (this->d.depth / 8));
2415 } else {
2416 lpdsf->s.surface_desc.y.lpSurface = img->data;
2419 return img;
2421 #endif /* HAVE_LIBXXSHM */
2423 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2424 XImage *img = NULL;
2425 void *img_data;
2427 #ifdef HAVE_LIBXXSHM
2428 if (this->e.xlib.xshm_active) {
2429 img = create_xshmimage(this, lpdsf);
2432 if (img == NULL) {
2433 #endif
2434 /* Allocate surface memory */
2435 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2436 lpdsf->s.surface_desc.dwWidth *
2437 lpdsf->s.surface_desc.dwHeight *
2438 (this->d.depth / 8));
2440 if (this->d.depth != this->d.screen_depth) {
2441 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2442 lpdsf->s.surface_desc.dwWidth *
2443 lpdsf->s.surface_desc.dwHeight *
2444 (this->d.screen_depth / 8));
2445 } else {
2446 img_data = lpdsf->s.surface_desc.y.lpSurface;
2449 /* In this case, create an XImage */
2450 img =
2451 TSXCreateImage(display,
2452 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2453 this->d.screen_depth,
2454 ZPixmap,
2456 img_data,
2457 lpdsf->s.surface_desc.dwWidth,
2458 lpdsf->s.surface_desc.dwHeight,
2460 lpdsf->s.surface_desc.dwWidth * (this->d.screen_depth / 8)
2463 #ifdef HAVE_LIBXXSHM
2465 #endif
2466 if (this->d.depth != this->d.screen_depth) {
2467 lpdsf->s.surface_desc.lPitch = (this->d.depth / 8) * lpdsf->s.surface_desc.dwWidth;
2468 } else {
2469 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2472 return img;
2475 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
2476 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2478 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2479 this,lpddsd,lpdsf,lpunk);
2481 if (TRACE_ON(ddraw)) {
2482 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2483 _dump_DDSD(lpddsd->dwFlags);
2484 fprintf(stderr,"caps ");
2485 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2486 fprintf(stderr,"]\n");
2489 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2491 this->lpvtbl->fnAddRef(this);
2492 (*lpdsf)->s.ddraw = this;
2493 (*lpdsf)->ref = 1;
2494 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds4vt;
2495 (*lpdsf)->s.palette = NULL;
2496 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2498 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2499 lpddsd->dwWidth = this->d.width;
2500 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2501 lpddsd->dwHeight = this->d.height;
2503 /* Check if this a 'primary surface' or not */
2504 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2505 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2506 XImage *img;
2508 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
2510 /* First, store the surface description */
2511 (*lpdsf)->s.surface_desc = *lpddsd;
2513 /* Create the XImage */
2514 img = create_ximage(this, (LPDIRECTDRAWSURFACE4) *lpdsf);
2515 if (img == NULL)
2516 return DDERR_OUTOFMEMORY;
2517 (*lpdsf)->t.xlib.image = img;
2519 /* Add flags if there were not present */
2520 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2521 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2522 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2523 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2524 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2525 (*lpdsf)->s.backbuffer = NULL;
2527 /* Check for backbuffers */
2528 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2529 LPDIRECTDRAWSURFACE4 back;
2530 XImage *img;
2532 if (lpddsd->dwBackBufferCount>1)
2533 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2535 (*lpdsf)->s.backbuffer = back =
2536 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2538 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2540 this->lpvtbl->fnAddRef(this);
2541 back->s.ddraw = this;
2543 back->ref = 1;
2544 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&xlib_dds4vt;
2545 /* Copy the surface description from the front buffer */
2546 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2548 /* Create the XImage */
2549 img = create_ximage(this, back);
2550 if (img == NULL)
2551 return DDERR_OUTOFMEMORY;
2552 back->t.xlib.image = img;
2554 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2555 * one! */
2557 /* Add relevant info to front and back buffers */
2558 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2559 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2560 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2561 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2562 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2564 } else {
2565 /* There is no Xlib-specific code here...
2566 Go to the common surface creation function */
2567 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2570 return DD_OK;
2573 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
2574 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2576 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
2577 *dst = src; /* FIXME */
2578 return DD_OK;
2582 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2583 * even when the approbiate bitmasks are not specified.
2585 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
2586 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
2588 int i;
2589 const struct {
2590 int mask;
2591 char *name;
2592 } flagmap[] = {
2593 FE(DDSCL_FULLSCREEN)
2594 FE(DDSCL_ALLOWREBOOT)
2595 FE(DDSCL_NOWINDOWCHANGES)
2596 FE(DDSCL_NORMAL)
2597 FE(DDSCL_ALLOWMODEX)
2598 FE(DDSCL_EXCLUSIVE)
2599 FE(DDSCL_SETFOCUSWINDOW)
2600 FE(DDSCL_SETDEVICEWINDOW)
2601 FE(DDSCL_CREATEDEVICEWINDOW)
2604 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
2605 if(TRACE_ON(ddraw)){
2606 dbg_decl_str(ddraw, 512);
2607 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2608 if (flagmap[i].mask & cooplevel)
2609 dsprintf(ddraw, "%s ", flagmap[i].name);
2610 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2612 this->d.mainWindow = hwnd;
2614 /* This will be overwritten in the case of Full Screen mode.
2615 Windowed games could work with that :-) */
2616 if (hwnd)
2617 this->d.drawable = X11DRV_WND_GetXWindow(WIN_FindWndPtr(hwnd));
2619 return DD_OK;
2622 /* Small helper to either use the cooperative window or create a new
2623 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2625 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
2626 RECT32 rect;
2628 /* Do not destroy the application supplied cooperative window */
2629 if (this->d.window && this->d.window != this->d.mainWindow) {
2630 DestroyWindow32(this->d.window);
2631 this->d.window = 0;
2633 /* Sanity check cooperative window before assigning it to drawing. */
2634 if ( IsWindow32(this->d.mainWindow) &&
2635 IsWindowVisible32(this->d.mainWindow)
2637 GetWindowRect32(this->d.mainWindow,&rect);
2638 if (((rect.right-rect.left) >= this->d.width) &&
2639 ((rect.bottom-rect.top) >= this->d.height)
2641 this->d.window = this->d.mainWindow;
2643 /* ... failed, create new one. */
2644 if (!this->d.window) {
2645 this->d.window = CreateWindowEx32A(
2647 "WINE_DirectDraw",
2648 "WINE_DirectDraw",
2649 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2650 0,0,
2651 this->d.width,
2652 this->d.height,
2656 NULL
2658 /*Store THIS with the window. We'll use it in the window procedure*/
2659 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
2660 ShowWindow32(this->d.window,TRUE);
2661 UpdateWindow32(this->d.window);
2663 SetFocus32(this->d.window);
2666 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
2667 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2669 #ifdef HAVE_LIBXXF86DGA
2670 int i,*depths,depcount,mode_count;
2672 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2674 /* We hope getting the asked for depth */
2675 this->d.screen_depth = depth;
2677 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2679 for (i=0;i<depcount;i++)
2680 if (depths[i]==depth)
2681 break;
2682 TSXFree(depths);
2683 if (i==depcount) {/* not found */
2684 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2685 return DDERR_UNSUPPORTEDMODE;
2687 if (this->d.width < width) {
2688 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2689 return DDERR_UNSUPPORTEDMODE;
2691 this->d.width = width;
2692 this->d.height = height;
2693 this->d.depth = depth;
2695 /* adjust fb_height, so we don't overlap */
2696 if (this->e.dga.fb_height < height)
2697 this->e.dga.fb_height = height;
2698 _common_IDirectDraw_SetDisplayMode(this);
2700 #ifdef HAVE_LIBXXF86VM
2702 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2703 XF86VidModeModeLine mod_tmp;
2704 /* int dotclock_tmp; */
2706 /* save original video mode and set fullscreen if available*/
2707 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2708 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2709 orig_mode->hdisplay = mod_tmp.hdisplay;
2710 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2711 orig_mode->hsyncend = mod_tmp.hsyncend;
2712 orig_mode->htotal = mod_tmp.htotal;
2713 orig_mode->vdisplay = mod_tmp.vdisplay;
2714 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2715 orig_mode->vsyncend = mod_tmp.vsyncend;
2716 orig_mode->vtotal = mod_tmp.vtotal;
2717 orig_mode->flags = mod_tmp.flags;
2718 orig_mode->private = mod_tmp.private;
2720 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2721 for (i=0;i<mode_count;i++)
2723 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2725 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2726 *vidmode = *(all_modes[i]);
2727 break;
2728 } else
2729 TSXFree(all_modes[i]->private);
2731 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
2732 TSXFree(all_modes);
2734 if (!vidmode)
2735 WARN(ddraw, "Fullscreen mode not available!\n");
2737 if (vidmode)
2739 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
2740 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2741 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
2742 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2743 #endif
2746 #endif
2748 /* FIXME: this function OVERWRITES several signal handlers.
2749 * can we save them? and restore them later? In a way that
2750 * it works for the library too?
2752 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2753 #ifdef DIABLO_HACK
2754 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2755 #else
2756 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2757 #endif
2759 #ifdef RESTORE_SIGNALS
2760 SIGNAL_InitHandlers();
2761 #endif
2762 return DD_OK;
2763 #else /* defined(HAVE_LIBXXF86DGA) */
2764 return E_UNEXPECTED;
2765 #endif /* defined(HAVE_LIBXXF86DGA) */
2768 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2769 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2771 int i,*depths,depcount;
2772 char buf[200];
2774 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2775 this, width, height, depth);
2777 /* We hope getting the asked for depth */
2778 this->d.screen_depth = depth;
2780 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2782 for (i=0;i<depcount;i++)
2783 if (depths[i]==depth)
2784 break;
2785 if (i==depcount) {/* not found */
2786 for (i=0;i<depcount;i++)
2787 if (depths[i]==16)
2788 break;
2790 if (i==depcount) {
2791 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2792 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2793 TSXFree(depths);
2794 return DDERR_UNSUPPORTEDMODE;
2795 } else {
2796 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
2797 this->d.screen_depth = 16;
2800 TSXFree(depths);
2802 this->d.width = width;
2803 this->d.height = height;
2804 this->d.depth = depth;
2806 _common_IDirectDraw_SetDisplayMode(this);
2808 this->d.paintable = 1;
2809 this->d.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window;
2810 /* We don't have a context for this window. Host off the desktop */
2811 if( !this->d.drawable )
2812 this->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
2813 return DD_OK;
2816 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2817 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2819 #ifdef HAVE_LIBXXF86DGA
2820 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2821 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2822 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2823 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2824 if (caps2) {
2825 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2826 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2827 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2829 return DD_OK;
2830 #else /* defined(HAVE_LIBXXF86DGA) */
2831 return E_UNEXPECTED;
2832 #endif /* defined(HAVE_LIBXXF86DGA) */
2835 static void fill_caps(LPDDCAPS caps) {
2836 /* This function tries to fill the capabilities of Wine's DDraw implementation.
2837 Need to be fixed, though.. */
2838 if (caps == NULL)
2839 return;
2841 caps->dwSize = sizeof(*caps);
2842 caps->dwCaps = DDCAPS_3D | DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
2843 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_ZBLTS;
2844 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NO2DDURING3DSCENE | DDCAPS2_NOPAGELOCKREQUIRED |
2845 DDCAPS2_WIDESURFACES;
2846 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
2847 caps->dwFXCaps = 0;
2848 caps->dwFXAlphaCaps = 0;
2849 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
2850 caps->dwSVCaps = 0;
2851 caps->dwZBufferBitDepths = DDBD_16;
2852 /* I put here 8 Mo so that D3D applications will believe they have enough memory
2853 to put textures in video memory.
2854 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
2855 for example) ? */
2856 caps->dwVidMemTotal = 8192 * 1024;
2857 caps->dwVidMemFree = 8192 * 1024;
2858 /* These are all the supported capabilities of the surfaces */
2859 caps->ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
2860 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
2861 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE |
2862 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE | DDSCAPS_ZBUFFER;
2865 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2866 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2868 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2870 /* Put the same caps for the two capabilities */
2871 fill_caps(caps1);
2872 fill_caps(caps2);
2874 return DD_OK;
2877 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2878 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2880 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2881 this,x,lpddclip,lpunk
2883 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2884 (*lpddclip)->ref = 1;
2885 (*lpddclip)->lpvtbl = &ddclipvt;
2886 return DD_OK;
2889 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2890 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk,int *psize
2892 int size = 0;
2894 if (TRACE_ON(ddraw))
2895 _dump_paletteformat(dwFlags);
2897 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2898 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2899 (*lpddpal)->ref = 1;
2900 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2901 (*lpddpal)->installed = 0;
2903 if (dwFlags & DDPCAPS_1BIT)
2904 size = 2;
2905 else if (dwFlags & DDPCAPS_2BIT)
2906 size = 4;
2907 else if (dwFlags & DDPCAPS_4BIT)
2908 size = 16;
2909 else if (dwFlags & DDPCAPS_8BIT)
2910 size = 256;
2911 else
2912 ERR(ddraw, "unhandled palette format\n");
2913 *psize = size;
2915 if (palent)
2917 /* Now, if we are in 'depth conversion mode', create the screen palette */
2918 if (this->d.depth != this->d.screen_depth) {
2919 int i;
2921 switch (this->d.screen_depth) {
2922 case 16: {
2923 unsigned short *screen_palette = (unsigned short *) (*lpddpal)->screen_palents;
2925 for (i = 0; i < size; i++) {
2926 screen_palette[i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
2927 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
2928 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
2930 } break;
2932 default:
2933 ERR(ddraw, "Memory corruption ! (depth=%ld, screen_depth=%ld)\n",this->d.depth,this->d.screen_depth);
2934 break;
2938 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
2939 } else if (this->d.depth != this->d.screen_depth) {
2940 int i;
2942 switch (this->d.screen_depth) {
2943 case 16: {
2944 unsigned short *screen_palette = (unsigned short *) (*lpddpal)->screen_palents;
2946 for (i = 0; i < size; i++) {
2947 screen_palette[i] = 0xFFFF;
2949 } break;
2951 default:
2952 ERR(ddraw, "Memory corruption !\n");
2953 break;
2957 return DD_OK;
2960 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2961 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2963 HRESULT res;
2964 int xsize = 0,i;
2966 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
2967 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
2968 if (res != 0) return res;
2969 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2970 if (this->d.depth<=8) {
2971 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
2972 } else {
2973 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
2974 (*lpddpal)->cm = 0;
2976 if (((*lpddpal)->cm)&&xsize) {
2977 for (i=0;i<xsize;i++) {
2978 XColor xc;
2980 xc.red = (*lpddpal)->palents[i].peRed<<8;
2981 xc.blue = (*lpddpal)->palents[i].peBlue<<8;
2982 xc.green = (*lpddpal)->palents[i].peGreen<<8;
2983 xc.flags = DoRed|DoBlue|DoGreen;
2984 xc.pixel = i;
2985 TSXStoreColor(display,(*lpddpal)->cm,&xc);
2988 return DD_OK;
2991 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2992 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2994 int xsize;
2995 HRESULT res;
2997 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
2998 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
2999 if (res != 0) return res;
3000 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
3001 return DD_OK;
3004 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3005 #ifdef HAVE_LIBXXF86DGA
3006 TRACE(ddraw, "(%p)->()\n",this);
3007 Sleep(1000);
3008 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3009 #ifdef RESTORE_SIGNALS
3010 SIGNAL_InitHandlers();
3011 #endif
3012 return DD_OK;
3013 #else /* defined(HAVE_LIBXXF86DGA) */
3014 return E_UNEXPECTED;
3015 #endif
3018 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3019 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
3020 Sleep(1000);
3021 return DD_OK;
3024 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
3025 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
3027 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
3028 return DD_OK;
3031 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
3032 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
3034 return ++(this->ref);
3037 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3038 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3040 #ifdef HAVE_LIBXXF86DGA
3041 if (!--(this->ref)) {
3042 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3043 if (this->d.window && (this->d.mainWindow != this->d.window))
3044 DestroyWindow32(this->d.window);
3045 #ifdef HAVE_LIBXXF86VM
3046 if (orig_mode) {
3047 TSXF86VidModeSwitchToMode(
3048 display,
3049 DefaultScreen(display),
3050 orig_mode);
3051 if (orig_mode->privsize)
3052 TSXFree(orig_mode->private);
3053 free(orig_mode);
3054 orig_mode = NULL;
3056 #endif
3058 #ifdef RESTORE_SIGNALS
3059 SIGNAL_InitHandlers();
3060 #endif
3061 HeapFree(GetProcessHeap(),0,this);
3062 return 0;
3064 #endif /* defined(HAVE_LIBXXF86DGA) */
3065 return this->ref;
3068 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3069 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3071 if (!--(this->ref)) {
3072 if (this->d.window && (this->d.mainWindow != this->d.window))
3073 DestroyWindow32(this->d.window);
3074 HeapFree(GetProcessHeap(),0,this);
3075 return 0;
3077 /* FIXME: destroy window ... */
3078 return this->ref;
3081 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
3082 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3084 char xrefiid[50];
3086 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3087 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3088 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3089 *obj = this;
3090 this->lpvtbl->fnAddRef(this);
3092 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3094 return S_OK;
3096 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3097 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
3098 this->lpvtbl->fnAddRef(this);
3099 *obj = this;
3101 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3103 return S_OK;
3105 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3106 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
3107 this->lpvtbl->fnAddRef(this);
3108 *obj = this;
3110 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3112 return S_OK;
3114 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3115 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd4vt;
3116 this->lpvtbl->fnAddRef(this);
3117 *obj = this;
3119 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3121 return S_OK;
3123 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3124 LPDIRECT3D d3d;
3126 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3127 d3d->ref = 1;
3128 d3d->ddraw = (LPDIRECTDRAW)this;
3129 this->lpvtbl->fnAddRef(this);
3130 d3d->lpvtbl = &d3dvt;
3131 *obj = d3d;
3133 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3135 return S_OK;
3137 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3138 LPDIRECT3D2 d3d;
3140 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3141 d3d->ref = 1;
3142 d3d->ddraw = (LPDIRECTDRAW)this;
3143 this->lpvtbl->fnAddRef(this);
3144 d3d->lpvtbl = &d3d2vt;
3145 *obj = d3d;
3147 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3149 return S_OK;
3151 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3152 return OLE_E_ENUM_NOMORE;
3155 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
3156 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3158 char xrefiid[50];
3160 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3161 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3162 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3163 *obj = this;
3164 this->lpvtbl->fnAddRef(this);
3166 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3168 return S_OK;
3170 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3171 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
3172 this->lpvtbl->fnAddRef(this);
3173 *obj = this;
3175 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3177 return S_OK;
3179 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3180 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
3181 this->lpvtbl->fnAddRef(this);
3182 *obj = this;
3184 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3186 return S_OK;
3188 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3189 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd4vt;
3190 this->lpvtbl->fnAddRef(this);
3191 *obj = this;
3193 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3195 return S_OK;
3197 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3198 LPDIRECT3D d3d;
3200 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3201 d3d->ref = 1;
3202 d3d->ddraw = (LPDIRECTDRAW)this;
3203 this->lpvtbl->fnAddRef(this);
3204 d3d->lpvtbl = &d3dvt;
3205 *obj = d3d;
3207 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3209 return S_OK;
3211 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3212 LPDIRECT3D2 d3d;
3214 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3215 d3d->ref = 1;
3216 d3d->ddraw = (LPDIRECTDRAW)this;
3217 this->lpvtbl->fnAddRef(this);
3218 d3d->lpvtbl = &d3d2vt;
3219 *obj = d3d;
3221 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3223 return S_OK;
3225 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3226 return OLE_E_ENUM_NOMORE;
3229 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
3230 LPDIRECTDRAW2 this,BOOL32 *status
3232 TRACE(ddraw,"(%p)->(%p)\n",this,status);
3233 *status = TRUE;
3234 return DD_OK;
3237 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
3238 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3240 DDSURFACEDESC ddsfd;
3241 static struct {
3242 int w,h;
3243 } modes[5] = { /* some of the usual modes */
3244 {512,384},
3245 {640,400},
3246 {640,480},
3247 {800,600},
3248 {1024,768},
3250 static int depths[4] = {8,16,24,32};
3251 int i,j;
3253 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
3254 ddsfd.dwSize = sizeof(ddsfd);
3255 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3256 if (dwFlags & DDEDM_REFRESHRATES) {
3257 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3258 ddsfd.x.dwRefreshRate = 60;
3261 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3262 ddsfd.dwBackBufferCount = 1;
3263 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3264 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3265 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3266 /* FIXME: those masks would have to be set in depth > 8 */
3267 if (depths[i]==8) {
3268 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3269 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3270 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3271 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3272 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3273 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3274 } else {
3275 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3277 /* FIXME: We should query those from X itself */
3278 switch (depths[i]) {
3279 case 16:
3280 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3281 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3282 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3283 break;
3284 case 24:
3285 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3286 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3287 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3288 break;
3289 case 32:
3290 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3291 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3292 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3293 break;
3297 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3298 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3299 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3300 if (!modescb(&ddsfd,context)) return DD_OK;
3302 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3303 ddsfd.dwWidth = modes[j].w;
3304 ddsfd.dwHeight = modes[j].h;
3305 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3306 if (!modescb(&ddsfd,context)) return DD_OK;
3309 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3310 /* modeX is not standard VGA */
3312 ddsfd.dwHeight = 200;
3313 ddsfd.dwWidth = 320;
3314 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3315 if (!modescb(&ddsfd,context)) return DD_OK;
3318 return DD_OK;
3321 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
3322 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3324 #ifdef HAVE_LIBXXF86DGA
3325 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
3326 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3327 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3328 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3329 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
3330 lpddsfd->dwBackBufferCount = 1;
3331 lpddsfd->x.dwRefreshRate = 60;
3332 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3333 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
3334 return DD_OK;
3335 #else /* defined(HAVE_LIBXXF86DGA) */
3336 return E_UNEXPECTED;
3337 #endif /* defined(HAVE_LIBXXF86DGA) */
3340 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
3341 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3343 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
3344 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3345 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3346 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3347 /* POOLE FIXME: Xlib */
3348 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
3349 /* END FIXME: Xlib */
3350 lpddsfd->dwBackBufferCount = 1;
3351 lpddsfd->x.dwRefreshRate = 60;
3352 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3353 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
3354 return DD_OK;
3357 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
3358 TRACE(ddraw,"(%p)->()\n",this);
3359 return DD_OK;
3362 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
3363 LPDIRECTDRAW2 this,LPDWORD freq
3365 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
3366 *freq = 60*100; /* 60 Hz */
3367 return DD_OK;
3370 /* what can we directly decompress? */
3371 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
3372 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
3374 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
3375 return DD_OK;
3378 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
3379 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
3381 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
3382 return DD_OK;
3385 static HRESULT WINAPI IDirectDraw2_Compact(
3386 LPDIRECTDRAW2 this )
3388 FIXME(ddraw,"(%p)->()\n", this );
3390 return DD_OK;
3393 static HRESULT WINAPI IDirectDraw2_GetGDISurface(LPDIRECTDRAW2 this,
3394 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
3395 FIXME(ddraw,"(%p)->(%p)\n", this, lplpGDIDDSSurface);
3397 return DD_OK;
3400 static HRESULT WINAPI IDirectDraw2_GetScanLine(LPDIRECTDRAW2 this,
3401 LPDWORD lpdwScanLine) {
3402 FIXME(ddraw,"(%p)->(%p)\n", this, lpdwScanLine);
3404 return DD_OK;
3407 static HRESULT WINAPI IDirectDraw2_Initialize(LPDIRECTDRAW2 this,
3408 GUID *lpGUID) {
3409 FIXME(ddraw,"(%p)->(%p)\n", this, lpGUID);
3411 return DD_OK;
3414 /* Note: Hack so we can reuse the old functions without compiler warnings */
3415 #ifdef __GNUC__
3416 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
3417 #else
3418 # define XCAST(fun) (void*)
3419 #endif
3421 static struct IDirectDraw_VTable dga_ddvt = {
3422 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3423 XCAST(AddRef)IDirectDraw2_AddRef,
3424 XCAST(Release)DGA_IDirectDraw2_Release,
3425 XCAST(Compact)IDirectDraw2_Compact,
3426 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3427 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3428 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3429 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3430 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3431 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3432 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3433 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3434 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3435 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3436 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3437 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3438 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3439 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3440 XCAST(Initialize)IDirectDraw2_Initialize,
3441 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3442 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3443 DGA_IDirectDraw_SetDisplayMode,
3444 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3447 static struct IDirectDraw_VTable xlib_ddvt = {
3448 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3449 XCAST(AddRef)IDirectDraw2_AddRef,
3450 XCAST(Release)Xlib_IDirectDraw2_Release,
3451 XCAST(Compact)IDirectDraw2_Compact,
3452 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3453 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3454 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3455 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3456 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3457 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3458 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3459 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3460 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3461 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3462 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3463 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3464 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3465 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3466 XCAST(Initialize)IDirectDraw2_Initialize,
3467 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3468 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3469 Xlib_IDirectDraw_SetDisplayMode,
3470 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3473 #undef XCAST
3475 /*****************************************************************************
3476 * IDirectDraw2
3481 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
3482 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3484 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3487 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
3488 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3490 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3493 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
3494 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3496 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3497 this,ddscaps,total,free
3499 if (total) *total = this->e.dga.fb_memsize * 1024;
3500 if (free) *free = this->e.dga.fb_memsize * 1024;
3501 return DD_OK;
3504 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
3505 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3507 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3508 this,ddscaps,total,free
3510 if (total) *total = 2048 * 1024;
3511 if (free) *free = 2048 * 1024;
3512 return DD_OK;
3515 static IDirectDraw2_VTable dga_dd2vt = {
3516 DGA_IDirectDraw2_QueryInterface,
3517 IDirectDraw2_AddRef,
3518 DGA_IDirectDraw2_Release,
3519 IDirectDraw2_Compact,
3520 IDirectDraw2_CreateClipper,
3521 DGA_IDirectDraw2_CreatePalette,
3522 DGA_IDirectDraw2_CreateSurface,
3523 IDirectDraw2_DuplicateSurface,
3524 IDirectDraw2_EnumDisplayModes,
3525 IDirectDraw2_EnumSurfaces,
3526 IDirectDraw2_FlipToGDISurface,
3527 DGA_IDirectDraw2_GetCaps,
3528 DGA_IDirectDraw2_GetDisplayMode,
3529 IDirectDraw2_GetFourCCCodes,
3530 IDirectDraw2_GetGDISurface,
3531 IDirectDraw2_GetMonitorFrequency,
3532 IDirectDraw2_GetScanLine,
3533 IDirectDraw2_GetVerticalBlankStatus,
3534 IDirectDraw2_Initialize,
3535 DGA_IDirectDraw2_RestoreDisplayMode,
3536 IDirectDraw2_SetCooperativeLevel,
3537 DGA_IDirectDraw2_SetDisplayMode,
3538 IDirectDraw2_WaitForVerticalBlank,
3539 DGA_IDirectDraw2_GetAvailableVidMem
3542 static struct IDirectDraw2_VTable xlib_dd2vt = {
3543 Xlib_IDirectDraw2_QueryInterface,
3544 IDirectDraw2_AddRef,
3545 Xlib_IDirectDraw2_Release,
3546 IDirectDraw2_Compact,
3547 IDirectDraw2_CreateClipper,
3548 Xlib_IDirectDraw2_CreatePalette,
3549 Xlib_IDirectDraw2_CreateSurface,
3550 IDirectDraw2_DuplicateSurface,
3551 IDirectDraw2_EnumDisplayModes,
3552 IDirectDraw2_EnumSurfaces,
3553 IDirectDraw2_FlipToGDISurface,
3554 Xlib_IDirectDraw2_GetCaps,
3555 Xlib_IDirectDraw2_GetDisplayMode,
3556 IDirectDraw2_GetFourCCCodes,
3557 IDirectDraw2_GetGDISurface,
3558 IDirectDraw2_GetMonitorFrequency,
3559 IDirectDraw2_GetScanLine,
3560 IDirectDraw2_GetVerticalBlankStatus,
3561 IDirectDraw2_Initialize,
3562 Xlib_IDirectDraw2_RestoreDisplayMode,
3563 IDirectDraw2_SetCooperativeLevel,
3564 Xlib_IDirectDraw2_SetDisplayMode,
3565 IDirectDraw2_WaitForVerticalBlank,
3566 Xlib_IDirectDraw2_GetAvailableVidMem
3569 /*****************************************************************************
3570 * IDirectDraw4
3574 static HRESULT WINAPI IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4 this,
3575 HDC32 hdc,
3576 LPDIRECTDRAWSURFACE *lpDDS) {
3577 FIXME(ddraw, "(%p)->(%08ld,%p)\n", this, (DWORD) hdc, lpDDS);
3579 return DD_OK;
3582 static HRESULT WINAPI IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4 this) {
3583 FIXME(ddraw, "(%p)->()\n", this);
3585 return DD_OK;
3588 static HRESULT WINAPI IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4 this) {
3589 FIXME(ddraw, "(%p)->()\n", this);
3591 return DD_OK;
3594 static HRESULT WINAPI IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4 this,
3595 LPDDDEVICEIDENTIFIER lpdddi,
3596 DWORD dwFlags) {
3597 FIXME(ddraw, "(%p)->(%p,%08lx)\n", this, lpdddi, dwFlags);
3599 return DD_OK;
3602 #ifdef __GNUC__
3603 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
3604 #else
3605 # define XCAST(fun) (void*)
3606 #endif
3609 static struct IDirectDraw4_VTable dga_dd4vt = {
3610 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3611 XCAST(AddRef)IDirectDraw2_AddRef,
3612 XCAST(Release)DGA_IDirectDraw2_Release,
3613 XCAST(Compact)IDirectDraw2_Compact,
3614 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3615 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3616 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3617 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3618 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3619 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3620 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3621 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3622 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3623 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3624 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3625 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3626 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3627 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3628 XCAST(Initialize)IDirectDraw2_Initialize,
3629 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3630 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3631 XCAST(SetDisplayMode)DGA_IDirectDraw_SetDisplayMode,
3632 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3633 XCAST(GetAvailableVidMem)DGA_IDirectDraw2_GetAvailableVidMem,
3634 IDirectDraw4_GetSurfaceFromDC,
3635 IDirectDraw4_RestoreAllSurfaces,
3636 IDirectDraw4_TestCooperativeLevel,
3637 IDirectDraw4_GetDeviceIdentifier
3640 static struct IDirectDraw4_VTable xlib_dd4vt = {
3641 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3642 XCAST(AddRef)IDirectDraw2_AddRef,
3643 XCAST(Release)Xlib_IDirectDraw2_Release,
3644 XCAST(Compact)IDirectDraw2_Compact,
3645 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3646 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3647 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3648 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3649 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3650 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3651 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3652 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3653 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3654 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3655 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3656 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3657 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3658 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3659 XCAST(Initialize)IDirectDraw2_Initialize,
3660 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3661 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3662 XCAST(SetDisplayMode)Xlib_IDirectDraw_SetDisplayMode,
3663 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3664 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2_GetAvailableVidMem,
3665 IDirectDraw4_GetSurfaceFromDC,
3666 IDirectDraw4_RestoreAllSurfaces,
3667 IDirectDraw4_TestCooperativeLevel,
3668 IDirectDraw4_GetDeviceIdentifier
3671 #undef XCAST
3673 /******************************************************************************
3674 * DirectDrawCreate
3677 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
3679 LRESULT ret;
3680 LPDIRECTDRAW ddraw = NULL;
3681 DWORD lastError;
3683 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
3685 SetLastError( ERROR_SUCCESS );
3686 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
3687 if( (!ddraw) &&
3688 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
3691 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
3694 if( ddraw )
3696 /* Perform any special direct draw functions */
3697 if (msg==WM_PAINT)
3698 ddraw->d.paintable = 1;
3700 /* Now let the application deal with the rest of this */
3701 if( ddraw->d.mainWindow )
3704 /* Don't think that we actually need to call this but...
3705 might as well be on the safe side of things... */
3707 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
3708 it should be the procedures of our fake window that gets called
3709 instead of those of the window provided by the application.
3710 And with this patch, mouse clicks work with Monkey Island III
3711 - Lionel */
3712 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
3714 if( !ret )
3716 /* We didn't handle the message - give it to the application */
3717 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
3718 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
3719 ddraw->d.mainWindow, msg, wParam, lParam );
3723 } else {
3724 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
3728 else
3730 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
3733 return ret;
3736 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
3737 #ifdef HAVE_LIBXXF86DGA
3738 int memsize,banksize,width,major,minor,flags,height;
3739 char *addr;
3740 int fd;
3742 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
3743 if ((fd = open("/dev/mem", O_RDWR)) != -1)
3744 close(fd);
3746 if (fd == -1) {
3747 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
3748 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
3749 return E_UNEXPECTED;
3751 if (!DDRAW_DGA_Available()) {
3752 TRACE(ddraw,"No XF86DGA detected.\n");
3753 return DDERR_GENERIC;
3755 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3756 (*lplpDD)->lpvtbl = &dga_ddvt;
3757 (*lplpDD)->ref = 1;
3758 TSXF86DGAQueryVersion(display,&major,&minor);
3759 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
3760 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
3761 if (!(flags & XF86DGADirectPresent))
3762 MSG("direct video is NOT PRESENT.\n");
3763 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
3764 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
3765 addr,width,banksize,memsize
3767 (*lplpDD)->e.dga.fb_width = width;
3768 (*lplpDD)->d.width = width;
3769 (*lplpDD)->e.dga.fb_addr = addr;
3770 (*lplpDD)->e.dga.fb_memsize = memsize;
3771 (*lplpDD)->e.dga.fb_banksize = banksize;
3773 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
3774 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3775 (*lplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3776 #ifdef DIABLO_HACK
3777 (*lplpDD)->e.dga.vpmask = 1;
3778 #else
3779 (*lplpDD)->e.dga.vpmask = 0;
3780 #endif
3782 /* just assume the default depth is the DGA depth too */
3783 (*lplpDD)->d.screen_depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3784 (*lplpDD)->d.depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3785 #ifdef RESTORE_SIGNALS
3786 SIGNAL_InitHandlers();
3787 #endif
3789 return DD_OK;
3790 #else /* defined(HAVE_LIBXXF86DGA) */
3791 return DDERR_INVALIDDIRECTDRAWGUID;
3792 #endif /* defined(HAVE_LIBXXF86DGA) */
3795 BOOL32
3796 DDRAW_XSHM_Available(void)
3798 #ifdef HAVE_LIBXXSHM
3799 if (TSXShmQueryExtension(display))
3801 int major, minor;
3802 Bool shpix;
3804 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
3805 return 1;
3806 else
3807 return 0;
3809 else
3810 return 0;
3811 #else
3812 return 0;
3813 #endif
3816 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
3818 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3819 (*lplpDD)->lpvtbl = &xlib_ddvt;
3820 (*lplpDD)->ref = 1;
3821 (*lplpDD)->d.drawable = 0; /* in SetDisplayMode */
3823 /* At DirectDraw creation, the depth is the default depth */
3824 (*lplpDD)->d.depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3825 (*lplpDD)->d.screen_depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3826 (*lplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3827 (*lplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3829 #ifdef HAVE_LIBXXSHM
3830 /* Test if XShm is available. */
3831 if (((*lplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
3832 TRACE(ddraw, "Using XShm extension.\n");
3833 #endif
3835 return DD_OK;
3838 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
3839 char xclsid[50];
3840 WNDCLASS32A wc;
3841 WND* pParentWindow;
3842 HRESULT ret;
3844 if (HIWORD(lpGUID))
3845 WINE_StringFromCLSID(lpGUID,xclsid);
3846 else {
3847 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
3848 lpGUID = NULL;
3851 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
3853 if (!lpGUID) {
3854 /* if they didn't request a particular interface, use the best
3855 * supported one */
3856 if (DDRAW_DGA_Available())
3857 lpGUID = &DGA_DirectDraw_GUID;
3858 else
3859 lpGUID = &XLIB_DirectDraw_GUID;
3862 wc.style = CS_GLOBALCLASS;
3863 wc.lpfnWndProc = Xlib_DDWndProc;
3864 wc.cbClsExtra = 0;
3865 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
3866 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
3868 /* We can be a child of the desktop since we're really important */
3869 pParentWindow = WIN_GetDesktop();
3870 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
3871 wc.hInstance = 0;
3873 wc.hIcon = 0;
3874 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
3875 wc.hbrBackground= NULL_BRUSH;
3876 wc.lpszMenuName = 0;
3877 wc.lpszClassName= "WINE_DirectDraw";
3878 RegisterClass32A(&wc);
3880 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
3881 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
3882 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
3883 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
3884 else
3885 goto err;
3888 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
3889 return ret;
3891 err:
3892 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
3893 return DDERR_INVALIDDIRECTDRAWGUID;