Authors: Paul Quinn <paulq@corel.ca>, Zygo Blaxell <zygob@corel.ca>
[wine/multimedia.git] / graphics / ddraw.c
blob1fb88782fae62ccfacf84880ff52f1e0f43925c5
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 "dc.h"
54 #include "win.h"
55 #include "miscemu.h"
56 #include "ddraw.h"
57 #include "d3d.h"
58 #include "debug.h"
59 #include "spy.h"
60 #include "message.h"
61 #include "options.h"
62 #include "monitor.h"
64 /* This for all the enumeration and creation of D3D-related objects */
65 #include "d3d_private.h"
67 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
68 #undef DIABLO_HACK
70 /* Restore signal handlers overwritten by XF86DGA
72 #define RESTORE_SIGNALS
74 /* Where do these GUIDs come from? mkuuid.
75 * They exist solely to distinguish between the targets Wine support,
76 * and should be different than any other GUIDs in existence.
78 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
79 0xe2dcb020,
80 0xdc60,
81 0x11d1,
82 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
85 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
86 0x1574a740,
87 0xdc61,
88 0x11d1,
89 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
92 static struct IDirectDrawSurface4_VTable dga_dds4vt, xlib_dds4vt;
93 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
94 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
95 static struct IDirectDraw4_VTable dga_dd4vt, xlib_dd4vt;
96 static struct IDirectDrawClipper_VTable ddclipvt;
97 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
98 static struct IDirect3D_VTable d3dvt;
99 static struct IDirect3D2_VTable d3d2vt;
101 #ifdef HAVE_LIBXXF86VM
102 static XF86VidModeModeInfo *orig_mode = NULL;
103 #endif
105 #ifdef HAVE_LIBXXSHM
106 static int XShmErrorFlag = 0;
107 #endif
109 BOOL32
110 DDRAW_DGA_Available(void)
112 #ifdef HAVE_LIBXXF86DGA
113 int evbase, evret, fd;
115 if (Options.noDGA)
116 return 0;
118 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
119 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
120 /* others. --stephenc */
121 if ((fd = open("/dev/mem", O_RDWR)) != -1)
122 close(fd);
124 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
125 #else /* defined(HAVE_LIBXXF86DGA) */
126 return 0;
127 #endif /* defined(HAVE_LIBXXF86DGA) */
130 HRESULT WINAPI
131 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
132 if (DDRAW_DGA_Available()) {
133 TRACE(ddraw, "Enumerating DGA interface\n");
134 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
136 TRACE(ddraw, "Enumerating Xlib interface\n");
137 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
138 TRACE(ddraw, "Enumerating Default interface\n");
139 ddenumproc(NULL,"WINE (default)","display",data);
140 return DD_OK;
143 /* What is this doing here? */
144 HRESULT WINAPI
145 DSoundHelp(DWORD x,DWORD y,DWORD z) {
146 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
147 return 0;
151 /******************************************************************************
152 * internal helper functions
154 static void _dump_DDBLTFX(DWORD flagmask) {
155 int i;
156 const struct {
157 DWORD mask;
158 char *name;
159 } flags[] = {
160 #define FE(x) { x, #x},
161 FE(DDBLTFX_ARITHSTRETCHY)
162 FE(DDBLTFX_MIRRORLEFTRIGHT)
163 FE(DDBLTFX_MIRRORUPDOWN)
164 FE(DDBLTFX_NOTEARING)
165 FE(DDBLTFX_ROTATE180)
166 FE(DDBLTFX_ROTATE270)
167 FE(DDBLTFX_ROTATE90)
168 FE(DDBLTFX_ZBUFFERRANGE)
169 FE(DDBLTFX_ZBUFFERBASEDEST)
171 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
172 if (flags[i].mask & flagmask) {
173 DUMP("%s ",flags[i].name);
176 DUMP("\n");
180 static void _dump_DDBLTFAST(DWORD flagmask) {
181 int i;
182 const struct {
183 DWORD mask;
184 char *name;
185 } flags[] = {
186 #define FE(x) { x, #x},
187 FE(DDBLTFAST_NOCOLORKEY)
188 FE(DDBLTFAST_SRCCOLORKEY)
189 FE(DDBLTFAST_DESTCOLORKEY)
190 FE(DDBLTFAST_WAIT)
192 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
193 if (flags[i].mask & flagmask)
194 DUMP("%s ",flags[i].name);
195 DUMP("\n");
198 static void _dump_DDBLT(DWORD flagmask) {
199 int i;
200 const struct {
201 DWORD mask;
202 char *name;
203 } flags[] = {
204 #define FE(x) { x, #x},
205 FE(DDBLT_ALPHADEST)
206 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
207 FE(DDBLT_ALPHADESTNEG)
208 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
209 FE(DDBLT_ALPHAEDGEBLEND)
210 FE(DDBLT_ALPHASRC)
211 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
212 FE(DDBLT_ALPHASRCNEG)
213 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
214 FE(DDBLT_ASYNC)
215 FE(DDBLT_COLORFILL)
216 FE(DDBLT_DDFX)
217 FE(DDBLT_DDROPS)
218 FE(DDBLT_KEYDEST)
219 FE(DDBLT_KEYDESTOVERRIDE)
220 FE(DDBLT_KEYSRC)
221 FE(DDBLT_KEYSRCOVERRIDE)
222 FE(DDBLT_ROP)
223 FE(DDBLT_ROTATIONANGLE)
224 FE(DDBLT_ZBUFFER)
225 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
226 FE(DDBLT_ZBUFFERDESTOVERRIDE)
227 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
228 FE(DDBLT_ZBUFFERSRCOVERRIDE)
229 FE(DDBLT_WAIT)
230 FE(DDBLT_DEPTHFILL)
232 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
233 if (flags[i].mask & flagmask)
234 DUMP("%s ",flags[i].name);
235 DUMP("\n");
238 static void _dump_DDSCAPS(DWORD flagmask) {
239 int i;
240 const struct {
241 DWORD mask;
242 char *name;
243 } flags[] = {
244 #define FE(x) { x, #x},
245 FE(DDSCAPS_RESERVED1)
246 FE(DDSCAPS_ALPHA)
247 FE(DDSCAPS_BACKBUFFER)
248 FE(DDSCAPS_COMPLEX)
249 FE(DDSCAPS_FLIP)
250 FE(DDSCAPS_FRONTBUFFER)
251 FE(DDSCAPS_OFFSCREENPLAIN)
252 FE(DDSCAPS_OVERLAY)
253 FE(DDSCAPS_PALETTE)
254 FE(DDSCAPS_PRIMARYSURFACE)
255 FE(DDSCAPS_PRIMARYSURFACELEFT)
256 FE(DDSCAPS_SYSTEMMEMORY)
257 FE(DDSCAPS_TEXTURE)
258 FE(DDSCAPS_3DDEVICE)
259 FE(DDSCAPS_VIDEOMEMORY)
260 FE(DDSCAPS_VISIBLE)
261 FE(DDSCAPS_WRITEONLY)
262 FE(DDSCAPS_ZBUFFER)
263 FE(DDSCAPS_OWNDC)
264 FE(DDSCAPS_LIVEVIDEO)
265 FE(DDSCAPS_HWCODEC)
266 FE(DDSCAPS_MODEX)
267 FE(DDSCAPS_MIPMAP)
268 FE(DDSCAPS_RESERVED2)
269 FE(DDSCAPS_ALLOCONLOAD)
270 FE(DDSCAPS_VIDEOPORT)
271 FE(DDSCAPS_LOCALVIDMEM)
272 FE(DDSCAPS_NONLOCALVIDMEM)
273 FE(DDSCAPS_STANDARDVGAMODE)
274 FE(DDSCAPS_OPTIMIZED)
276 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
277 if (flags[i].mask & flagmask)
278 DUMP("%s ",flags[i].name);
279 DUMP("\n");
282 static void _dump_DDSD(DWORD flagmask) {
283 int i;
284 const struct {
285 DWORD mask;
286 char *name;
287 } flags[] = {
288 FE(DDSD_CAPS)
289 FE(DDSD_HEIGHT)
290 FE(DDSD_WIDTH)
291 FE(DDSD_PITCH)
292 FE(DDSD_BACKBUFFERCOUNT)
293 FE(DDSD_ZBUFFERBITDEPTH)
294 FE(DDSD_ALPHABITDEPTH)
295 FE(DDSD_PIXELFORMAT)
296 FE(DDSD_CKDESTOVERLAY)
297 FE(DDSD_CKDESTBLT)
298 FE(DDSD_CKSRCOVERLAY)
299 FE(DDSD_CKSRCBLT)
300 FE(DDSD_MIPMAPCOUNT)
301 FE(DDSD_REFRESHRATE)
302 FE(DDSD_LINEARSIZE)
303 FE(DDSD_LPSURFACE)
305 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
306 if (flags[i].mask & flagmask)
307 DUMP("%s ",flags[i].name);
308 DUMP("\n");
311 static void _dump_DDCOLORKEY(DWORD flagmask) {
312 int i;
313 const struct {
314 DWORD mask;
315 char *name;
316 } flags[] = {
317 #define FE(x) { x, #x},
318 FE(DDPF_ALPHAPIXELS)
319 FE(DDPF_ALPHA)
320 FE(DDPF_FOURCC)
321 FE(DDPF_PALETTEINDEXED4)
322 FE(DDPF_PALETTEINDEXEDTO8)
323 FE(DDPF_PALETTEINDEXED8)
324 FE(DDPF_RGB)
325 FE(DDPF_COMPRESSED)
326 FE(DDPF_RGBTOYUV)
327 FE(DDPF_YUV)
328 FE(DDPF_ZBUFFER)
329 FE(DDPF_PALETTEINDEXED1)
330 FE(DDPF_PALETTEINDEXED2)
331 FE(DDPF_ZPIXELS)
333 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
334 if (flags[i].mask & flagmask)
335 DUMP("%s ",flags[i].name);
336 DUMP("\n");
339 static void _dump_paletteformat(DWORD dwFlags) {
340 int i;
341 const struct {
342 DWORD mask;
343 char *name;
344 } flags[] = {
345 #define FE(x) { x, #x},
346 FE(DDPCAPS_4BIT)
347 FE(DDPCAPS_8BITENTRIES)
348 FE(DDPCAPS_8BIT)
349 FE(DDPCAPS_INITIALIZE)
350 FE(DDPCAPS_PRIMARYSURFACE)
351 FE(DDPCAPS_PRIMARYSURFACELEFT)
352 FE(DDPCAPS_ALLOW256)
353 FE(DDPCAPS_VSYNC)
354 FE(DDPCAPS_1BIT)
355 FE(DDPCAPS_2BIT)
356 FE(DDPCAPS_ALPHA)
358 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
359 if (flags[i].mask & dwFlags)
360 DUMP("%s ",flags[i].name);
361 DUMP("\n");
364 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
365 DUMP("Size : %ld\n", pf->dwSize);
366 if (pf->dwFlags)
367 _dump_DDCOLORKEY(pf->dwFlags);
368 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
369 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
370 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
371 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
374 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
375 static XVisualInfo *vi;
376 XVisualInfo vt;
377 int nitems;
379 if (!vi)
380 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
382 pf->dwFourCC = 0;
383 pf->dwSize = sizeof(DDPIXELFORMAT);
384 if (ddraw->d.depth==8) {
385 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
386 pf->x.dwRGBBitCount = 8;
387 pf->y.dwRBitMask = 0;
388 pf->z.dwGBitMask = 0;
389 pf->xx.dwBBitMask = 0;
390 pf->xy.dwRGBAlphaBitMask= 0;
391 return 0;
393 if (ddraw->d.depth==16) {
394 pf->dwFlags = DDPF_RGB;
395 pf->x.dwRGBBitCount = 16;
396 pf->y.dwRBitMask = vi[0].red_mask;
397 pf->z.dwGBitMask = vi[0].green_mask;
398 pf->xx.dwBBitMask = vi[0].blue_mask;
399 pf->xy.dwRGBAlphaBitMask= 0;
400 return 0;
402 if (ddraw->d.depth==24) {
403 pf->dwFlags = DDPF_RGB;
404 pf->x.dwRGBBitCount = 24;
405 pf->y.dwRBitMask = vi[0].red_mask;
406 pf->z.dwGBitMask = vi[0].green_mask;
407 pf->xx.dwBBitMask = vi[0].blue_mask;
408 pf->xy.dwRGBAlphaBitMask= 0;
409 return 0;
411 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
412 return DDERR_GENERIC;
415 /******************************************************************************
416 * IDirectDrawSurface methods
418 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
419 * DDS and DDS2 use those functions. (Function calls did not change (except
420 * using different DirectDrawSurfaceX version), just added flags and functions)
422 static HRESULT WINAPI IDirectDrawSurface4_Lock(
423 LPDIRECTDRAWSURFACE4 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
425 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
426 this,lprect,lpddsd,flags,(DWORD)hnd);
427 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
428 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
429 this,lprect,lpddsd,flags,(DWORD)hnd);
431 /* First, copy the Surface description */
432 *lpddsd = this->s.surface_desc;
433 TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
434 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
436 /* If asked only for a part, change the surface pointer */
437 if (lprect) {
438 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
439 lprect->top,lprect->left,lprect->bottom,lprect->right
441 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
442 (lprect->top*this->s.surface_desc.lPitch) +
443 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
444 } else {
445 assert(this->s.surface_desc.y.lpSurface);
447 return DD_OK;
450 static HRESULT WINAPI DGA_IDirectDrawSurface4_Unlock(
451 LPDIRECTDRAWSURFACE4 this,LPVOID surface
453 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
454 return DD_OK;
457 static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4 this) {
458 if (this->s.ddraw->d.depth != this->s.ddraw->d.screen_depth) {
459 /* Pixel convertion ! */
460 if ((this->s.ddraw->d.depth == 8) && (this->s.ddraw->d.screen_depth == 16)) {
461 unsigned char *src = (unsigned char *) this->s.surface_desc.y.lpSurface;
462 unsigned short *dst = (unsigned short *) this->t.xlib.image->data;
463 unsigned short *pal;
464 int x, y;
466 if (this->s.palette != NULL) {
467 pal = (unsigned short *) this->s.palette->screen_palents;
468 for (y = 0; y < this->s.surface_desc.dwHeight; y++) {
469 for (x = 0; x < this->s.surface_desc.dwWidth; x++) {
470 dst[x + y * this->s.surface_desc.lPitch] = pal[src[x + y * this->s.surface_desc.lPitch]];
473 } else {
474 WARN(ddraw, "No palette set...\n");
475 memset(dst, 0, this->s.surface_desc.lPitch * this->s.surface_desc.dwHeight * 2);
477 } else {
478 ERR(ddraw, "Unsupported pixel convertion...\n");
482 #ifdef HAVE_LIBXXSHM
483 if (this->s.ddraw->e.xlib.xshm_active)
484 TSXShmPutImage(display,
485 this->s.ddraw->d.drawable,
486 DefaultGCOfScreen(X11DRV_GetXScreen()),
487 this->t.xlib.image,
488 0, 0, 0, 0,
489 this->t.xlib.image->width,
490 this->t.xlib.image->height,
491 False);
492 else
493 #endif
494 TSXPutImage( display,
495 this->s.ddraw->d.drawable,
496 DefaultGCOfScreen(X11DRV_GetXScreen()),
497 this->t.xlib.image,
498 0, 0, 0, 0,
499 this->t.xlib.image->width,
500 this->t.xlib.image->height);
503 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Unlock(
504 LPDIRECTDRAWSURFACE4 this,LPVOID surface)
506 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
508 if (!this->s.ddraw->d.paintable)
509 return DD_OK;
511 /* Only redraw the screen when unlocking the buffer that is on screen */
512 if ((this->t.xlib.image != NULL) &&
513 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
514 Xlib_copy_surface_on_screen(this);
516 if (this->s.palette && this->s.palette->cm)
517 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
520 return DD_OK;
523 static HRESULT WINAPI DGA_IDirectDrawSurface4_Flip(
524 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
526 #ifdef HAVE_LIBXXF86DGA
527 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
528 if (!flipto) {
529 if (this->s.backbuffer)
530 flipto = this->s.backbuffer;
531 else
532 flipto = this;
534 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
536 if (flipto->s.palette && flipto->s.palette->cm) {
537 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
539 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
541 if (flipto!=this) {
542 int tmp;
543 LPVOID ptmp;
545 tmp = this->t.dga.fb_height;
546 this->t.dga.fb_height = flipto->t.dga.fb_height;
547 flipto->t.dga.fb_height = tmp;
549 ptmp = this->s.surface_desc.y.lpSurface;
550 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
551 flipto->s.surface_desc.y.lpSurface = ptmp;
553 return DD_OK;
554 #else /* defined(HAVE_LIBXXF86DGA) */
555 return E_UNEXPECTED;
556 #endif /* defined(HAVE_LIBXXF86DGA) */
559 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Flip(
560 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
562 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
563 if (!this->s.ddraw->d.paintable)
564 return DD_OK;
566 if (!flipto) {
567 if (this->s.backbuffer)
568 flipto = this->s.backbuffer;
569 else
570 flipto = this;
573 Xlib_copy_surface_on_screen(this);
575 if (flipto->s.palette && flipto->s.palette->cm) {
576 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,flipto->s.palette->cm);
578 if (flipto!=this) {
579 XImage *tmp;
580 LPVOID *surf;
581 tmp = this->t.xlib.image;
582 this->t.xlib.image = flipto->t.xlib.image;
583 flipto->t.xlib.image = tmp;
584 surf = this->s.surface_desc.y.lpSurface;
585 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
586 flipto->s.surface_desc.y.lpSurface = surf;
588 return DD_OK;
592 /* The IDirectDrawSurface4::SetPalette method attaches the specified
593 * DirectDrawPalette object to a surface. The surface uses this palette for all
594 * subsequent operations. The palette change takes place immediately.
596 static HRESULT WINAPI Xlib_IDirectDrawSurface4_SetPalette(
597 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
599 int i;
600 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
602 if (pal == NULL) {
603 if( this->s.palette != NULL )
604 this->s.palette->lpvtbl->fnRelease( this->s.palette );
605 this->s.palette = pal;
607 return DD_OK;
610 if( !(pal->cm) && (this->s.ddraw->d.screen_depth<=8))
612 pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,
613 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
615 if (!Options.managed)
616 TSXInstallColormap(display,pal->cm);
618 for (i=0;i<256;i++) {
619 XColor xc;
621 xc.red = pal->palents[i].peRed<<8;
622 xc.blue = pal->palents[i].peBlue<<8;
623 xc.green = pal->palents[i].peGreen<<8;
624 xc.flags = DoRed|DoBlue|DoGreen;
625 xc.pixel = i;
626 TSXStoreColor(display,pal->cm,&xc);
628 TSXInstallColormap(display,pal->cm);
631 /* According to spec, we are only supposed to
632 * AddRef if this is not the same palette.
634 if( this->s.palette != pal )
636 if( pal != NULL )
637 pal->lpvtbl->fnAddRef( pal );
638 if( this->s.palette != NULL )
639 this->s.palette->lpvtbl->fnRelease( this->s.palette );
640 this->s.palette = pal;
642 /* I think that we need to attach it to all backbuffers...*/
643 if( this->s.backbuffer ) {
644 if( this->s.backbuffer->s.palette )
645 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
646 this->s.backbuffer->s.palette );
647 this->s.backbuffer->s.palette = pal;
648 if( pal )
649 pal->lpvtbl->fnAddRef( pal );
651 /* Perform the refresh */
652 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
654 return DD_OK;
657 static HRESULT WINAPI DGA_IDirectDrawSurface4_SetPalette(
658 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
660 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
661 #ifdef HAVE_LIBXXF86DGA
662 /* According to spec, we are only supposed to
663 * AddRef if this is not the same palette.
665 if( this->s.palette != pal )
667 if( pal != NULL )
668 pal->lpvtbl->fnAddRef( pal );
669 if( this->s.palette != NULL )
670 this->s.palette->lpvtbl->fnRelease( this->s.palette );
671 this->s.palette = pal;
673 /* I think that we need to attach it to all backbuffers...*/
674 if( this->s.backbuffer ) {
675 if( this->s.backbuffer->s.palette )
676 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
677 this->s.backbuffer->s.palette = pal;
678 if( pal ) pal->lpvtbl->fnAddRef( pal );
680 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
682 return DD_OK;
683 #else /* defined(HAVE_LIBXXF86DGA) */
684 return E_UNEXPECTED;
685 #endif /* defined(HAVE_LIBXXF86DGA) */
690 static HRESULT WINAPI IDirectDrawSurface4_Blt(
691 LPDIRECTDRAWSURFACE4 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE4 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
693 RECT32 xdst,xsrc;
694 DDSURFACEDESC ddesc,sdesc;
695 int i,j;
697 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
698 this,rdst,src,rsrc,dwFlags,lpbltfx);
700 if (src != NULL)
701 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
702 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
704 if (TRACE_ON(ddraw)) {
705 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
706 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
707 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
708 if (dwFlags & DDBLT_DDFX) {
709 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
713 if (rdst) {
714 memcpy(&xdst,rdst,sizeof(xdst));
715 } else {
716 xdst.top = 0;
717 xdst.bottom = ddesc.dwHeight;
718 xdst.left = 0;
719 xdst.right = ddesc.dwWidth;
722 if (rsrc) {
723 memcpy(&xsrc,rsrc,sizeof(xsrc));
724 } else {
725 if (src) {
726 xsrc.top = 0;
727 xsrc.bottom = sdesc.dwHeight;
728 xsrc.left = 0;
729 xsrc.right = sdesc.dwWidth;
730 } else {
731 memset(&xsrc,0,sizeof(xsrc));
735 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
737 /* First, all the 'source-less' blits */
738 if (dwFlags & DDBLT_COLORFILL) {
739 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
740 LPBYTE xline,xpixel;
742 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
743 for (i=xdst.top;i<xdst.bottom;i++) {
744 xpixel = xline+bpp*xdst.left;
746 for (j=xdst.left;j<xdst.right;j++) {
747 /* FIXME: this only works on little endian
748 * architectures, where DWORD starts with low
749 * byte first!
751 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
752 xpixel += bpp;
754 xline += ddesc.lPitch;
756 dwFlags &= ~(DDBLT_COLORFILL);
759 if (dwFlags & DDBLT_DEPTHFILL) {
760 #ifdef HAVE_MESAGL
761 GLboolean ztest;
763 /* Clears the screen */
764 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
765 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
766 glGetBooleanv(GL_DEPTH_TEST, &ztest);
767 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
768 glClear(GL_DEPTH_BUFFER_BIT);
769 glDepthMask(ztest);
771 dwFlags &= ~(DDBLT_DEPTHFILL);
772 #endif HAVE_MESAGL
775 if (!src) {
776 if (dwFlags) {
777 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
779 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
780 return DD_OK;
783 /* Now the 'with source' blits */
785 /* Standard 'full-surface' blit without special effects */
786 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
787 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
788 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
789 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
790 !dwFlags
792 memcpy(ddesc.y.lpSurface,
793 sdesc.y.lpSurface,
794 ddesc.dwHeight * ddesc.lPitch);
795 } else {
796 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
797 int srcheight = xsrc.bottom - xsrc.top;
798 int srcwidth = xsrc.right - xsrc.left;
799 int dstheight = xdst.bottom - xdst.top;
800 int dstwidth = xdst.right - xdst.left;
801 int width = (xsrc.right - xsrc.left) * bpp;
802 int h;
804 /* Sanity check for rectangle sizes */
805 if ((srcheight != dstheight) || (srcwidth != dstwidth)) {
806 int x, y;
808 /* I think we should do a Blit with 'stretching' here....
809 Tomb Raider II uses this to display the background during the menu selection
810 when the screen resolution is != than 640x480 */
811 TRACE(ddraw, "Blt with stretching\n");
813 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
814 if (bpp == 1) {
815 /* In this case, we cannot do any anti-aliasing */
816 if(dwFlags & DDBLT_KEYSRC) {
817 for (y = xdst.top; y < xdst.bottom; y++) {
818 for (x = xdst.left; x < xdst.right; x++) {
819 double sx, sy;
820 unsigned char tmp;
821 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
822 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
824 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
825 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
827 tmp = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
829 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
830 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
831 dbuf[(y * ddesc.lPitch) + x] = tmp;
834 } else {
835 for (y = xdst.top; y < xdst.bottom; y++) {
836 for (x = xdst.left; x < xdst.right; x++) {
837 double sx, sy;
838 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
839 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
841 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
842 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
844 dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
848 } else {
849 FIXME(ddraw, "Not done yet for depth != 8\n");
851 } else {
852 /* Same size => fast blit */
853 if (dwFlags & DDBLT_KEYSRC) {
854 switch (bpp) {
855 case 1: {
856 unsigned char tmp,*psrc,*pdst;
857 int h,i;
859 for (h = 0; h < srcheight; h++) {
860 psrc=sdesc.y.lpSurface +
861 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
862 pdst=ddesc.y.lpSurface +
863 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
864 for(i=0;i<srcwidth;i++) {
865 tmp=*(psrc + i);
866 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
867 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
868 *(pdst + i)=tmp;
871 dwFlags&=~(DDBLT_KEYSRC);
872 } break;
874 case 2: {
875 unsigned short tmp,*psrc,*pdst;
876 int h,i;
878 for (h = 0; h < srcheight; h++) {
879 psrc=sdesc.y.lpSurface +
880 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
881 pdst=ddesc.y.lpSurface +
882 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
883 for(i=0;i<srcwidth;i++) {
884 tmp=*(psrc + i);
885 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
886 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
887 *(pdst + i)=tmp;
890 dwFlags&=~(DDBLT_KEYSRC);
891 } break;
893 default:
894 FIXME(ddraw, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
896 } else {
897 /* Non-stretching Blt without color keying */
898 for (h = 0; h < srcheight; h++) {
899 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
900 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
901 width);
907 if (dwFlags && FIXME_ON(ddraw)) {
908 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
911 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
912 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
914 return DD_OK;
917 static HRESULT WINAPI IDirectDrawSurface4_BltFast(
918 LPDIRECTDRAWSURFACE4 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT32 rsrc,DWORD trans
920 int i,bpp,w,h;
921 DDSURFACEDESC ddesc,sdesc;
923 if (1 || TRACE_ON(ddraw)) {
924 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
925 this,dstx,dsty,src,rsrc,trans
927 FIXME(ddraw," trans:");
928 if (FIXME_ON(ddraw))
929 _dump_DDBLTFAST(trans);
930 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
932 /* We need to lock the surfaces, or we won't get refreshes when done. */
933 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
934 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
935 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
936 h=rsrc->bottom-rsrc->top;
937 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
938 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
939 if (h<0) h=0;
940 w=rsrc->right-rsrc->left;
941 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
942 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
943 if (w<0) w=0;
945 for (i=0;i<h;i++) {
946 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
947 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
948 w*bpp
951 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
952 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
953 return DD_OK;
956 static HRESULT WINAPI IDirectDrawSurface4_BltBatch(
957 LPDIRECTDRAWSURFACE4 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
959 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
960 this,ddbltbatch,x,y
962 return DD_OK;
965 static HRESULT WINAPI IDirectDrawSurface4_GetCaps(
966 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS caps
968 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
969 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
970 return DD_OK;
973 static HRESULT WINAPI IDirectDrawSurface4_GetSurfaceDesc(
974 LPDIRECTDRAWSURFACE4 this,LPDDSURFACEDESC ddsd
975 ) {
976 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
977 this,ddsd);
979 /* Simply copy the surface description stored in the object */
980 *ddsd = this->s.surface_desc;
982 if (TRACE_ON(ddraw)) {
983 fprintf(stderr," flags: ");
984 _dump_DDSD(ddsd->dwFlags);
985 if (ddsd->dwFlags & DDSD_CAPS) {
986 fprintf(stderr, " caps: ");
987 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
989 fprintf(stderr,"\n");
992 return DD_OK;
995 static ULONG WINAPI IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4 this) {
996 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
998 return ++(this->ref);
1001 static ULONG WINAPI DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1002 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1004 #ifdef HAVE_LIBXXF86DGA
1005 if (!--(this->ref)) {
1006 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1007 /* clear out of surface list */
1008 if (this->t.dga.fb_height == -1) {
1009 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1010 } else {
1011 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
1014 /* Free the backbuffer */
1015 if (this->s.backbuffer)
1016 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1018 HeapFree(GetProcessHeap(),0,this);
1019 return 0;
1021 #endif /* defined(HAVE_LIBXXF86DGA) */
1022 return this->ref;
1025 static ULONG WINAPI Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1026 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1028 if (!--(this->ref)) {
1029 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1031 if( this->s.backbuffer )
1032 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1034 if (this->t.xlib.image != NULL) {
1035 if (this->s.ddraw->d.depth != this->s.ddraw->d.screen_depth) {
1036 /* In pixel conversion mode, there are two buffers to release... */
1037 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1039 #ifdef HAVE_LIBXXSHM
1040 if (this->s.ddraw->e.xlib.xshm_active) {
1041 TSXShmDetach(display, &(this->t.xlib.shminfo));
1042 TSXDestroyImage(this->t.xlib.image);
1043 shmdt(this->t.xlib.shminfo.shmaddr);
1044 } else {
1045 #endif
1046 HeapFree(GetProcessHeap(),0,this->t.xlib.image->data);
1047 this->t.xlib.image->data = NULL;
1048 TSXDestroyImage(this->t.xlib.image);
1049 #ifdef HAVE_LIBXXSHM
1051 #endif
1053 } else {
1054 this->t.xlib.image->data = NULL;
1056 #ifdef HAVE_LIBXXSHM
1057 if (this->s.ddraw->e.xlib.xshm_active) {
1058 TSXShmDetach(display, &(this->t.xlib.shminfo));
1059 TSXDestroyImage(this->t.xlib.image);
1060 shmdt(this->t.xlib.shminfo.shmaddr);
1061 } else {
1062 #endif
1063 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1064 TSXDestroyImage(this->t.xlib.image);
1065 #ifdef HAVE_LIBXXSHM
1067 #endif
1070 this->t.xlib.image = 0;
1071 } else {
1072 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1075 if (this->s.palette)
1076 this->s.palette->lpvtbl->fnRelease(this->s.palette);
1078 HeapFree(GetProcessHeap(),0,this);
1079 return 0;
1082 return this->ref;
1085 static HRESULT WINAPI IDirectDrawSurface4_GetAttachedSurface(
1086 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1088 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1089 this, lpddsd, lpdsf);
1091 if (TRACE_ON(ddraw)) {
1092 TRACE(ddraw," caps ");
1093 _dump_DDSCAPS(lpddsd->dwCaps);
1096 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1097 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1098 return E_FAIL;
1101 /* FIXME: should handle more than one backbuffer */
1102 *lpdsf = this->s.backbuffer;
1104 if( this->s.backbuffer )
1105 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
1107 return DD_OK;
1110 static HRESULT WINAPI IDirectDrawSurface4_Initialize(
1111 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1113 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
1115 return DDERR_ALREADYINITIALIZED;
1118 static HRESULT WINAPI IDirectDrawSurface4_GetPixelFormat(
1119 LPDIRECTDRAWSURFACE4 this,LPDDPIXELFORMAT pf
1121 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
1123 *pf = this->s.surface_desc.ddpfPixelFormat;
1125 return DD_OK;
1128 static HRESULT WINAPI IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4 this,DWORD dwFlags) {
1129 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
1130 return DD_OK;
1133 static HRESULT WINAPI IDirectDrawSurface4_GetOverlayPosition(
1134 LPDIRECTDRAWSURFACE4 this,LPLONG x1,LPLONG x2
1136 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
1137 return DD_OK;
1140 static HRESULT WINAPI IDirectDrawSurface4_SetClipper(
1141 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWCLIPPER clipper
1143 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
1144 return DD_OK;
1147 static HRESULT WINAPI IDirectDrawSurface4_AddAttachedSurface(
1148 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 surf
1150 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
1152 this->lpvtbl->fnAddRef(this);
1154 /* This hack will be enough for the moment */
1155 if (this->s.backbuffer == NULL)
1156 this->s.backbuffer = surf;
1157 return DD_OK;
1160 static HRESULT WINAPI IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4 this,HDC32* lphdc) {
1161 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
1162 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1163 return DD_OK;
1166 static HRESULT WINAPI IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4 this,HDC32 hdc) {
1167 DDSURFACEDESC desc;
1168 DWORD x, y;
1170 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
1171 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1173 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1174 I fill it with 'dummy' values to have something on the screen */
1175 this->lpvtbl->fnLock(this,NULL,&desc,0,0);
1176 for (y = 0; y < desc.dwHeight; y++) {
1177 for (x = 0; x < desc.dwWidth; x++) {
1178 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) this + x + y;
1181 this->lpvtbl->fnUnlock(this,NULL);
1183 return DD_OK;
1187 static HRESULT WINAPI IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4 this,REFIID refiid,LPVOID *obj) {
1188 char xrefiid[50];
1190 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1191 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1193 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1194 * the same interface. And IUnknown does that too of course.
1196 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1197 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1198 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1199 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1200 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1202 *obj = this;
1203 this->lpvtbl->fnAddRef(this);
1205 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1207 return S_OK;
1209 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1211 /* Texture interface */
1212 *obj = d3dtexture2_create(this);
1213 this->lpvtbl->fnAddRef(this);
1215 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1217 return S_OK;
1219 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1221 /* Texture interface */
1222 *obj = d3dtexture_create(this);
1223 this->lpvtbl->fnAddRef(this);
1225 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1227 return S_OK;
1229 else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj))
1231 /* It is the OpenGL Direct3D Device */
1232 this->lpvtbl->fnAddRef(this);
1234 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1236 return S_OK;
1239 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1240 return OLE_E_ENUM_NOMORE;
1243 static HRESULT WINAPI IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4 this) {
1244 TRACE(ddraw,"(%p)->(), stub!\n",this);
1245 return DD_OK; /* hmm */
1248 static HRESULT WINAPI IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1249 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
1250 return DD_OK;
1253 static HRESULT WINAPI IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4 this) {
1254 FIXME(ddraw,"(%p)->(),stub!\n",this);
1255 return DD_OK;
1258 static HRESULT WINAPI IDirectDrawSurface4_SetColorKey(
1259 LPDIRECTDRAWSURFACE4 this, DWORD dwFlags, LPDDCOLORKEY ckey )
1261 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);
1263 if( dwFlags & DDCKEY_SRCBLT )
1265 dwFlags &= ~DDCKEY_SRCBLT;
1266 this->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1267 memcpy( &(this->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1270 if( dwFlags & DDCKEY_DESTBLT )
1272 dwFlags &= ~DDCKEY_DESTBLT;
1273 this->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1274 memcpy( &(this->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1277 if( dwFlags & DDCKEY_SRCOVERLAY )
1279 dwFlags &= ~DDCKEY_SRCOVERLAY;
1280 this->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1281 memcpy( &(this->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1284 if( dwFlags & DDCKEY_DESTOVERLAY )
1286 dwFlags &= ~DDCKEY_DESTOVERLAY;
1287 this->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1288 memcpy( &(this->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1291 if( dwFlags )
1293 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1296 return DD_OK;
1300 static HRESULT WINAPI IDirectDrawSurface4_AddOverlayDirtyRect(
1301 LPDIRECTDRAWSURFACE4 this,
1302 LPRECT32 lpRect )
1304 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
1306 return DD_OK;
1309 static HRESULT WINAPI IDirectDrawSurface4_DeleteAttachedSurface(
1310 LPDIRECTDRAWSURFACE4 this,
1311 DWORD dwFlags,
1312 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1314 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1316 return DD_OK;
1319 static HRESULT WINAPI IDirectDrawSurface4_EnumOverlayZOrders(
1320 LPDIRECTDRAWSURFACE4 this,
1321 DWORD dwFlags,
1322 LPVOID lpContext,
1323 LPDDENUMSURFACESCALLBACK lpfnCallback )
1325 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1326 lpContext, lpfnCallback );
1328 return DD_OK;
1331 static HRESULT WINAPI IDirectDrawSurface4_GetClipper(
1332 LPDIRECTDRAWSURFACE4 this,
1333 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1335 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1337 return DD_OK;
1340 static HRESULT WINAPI IDirectDrawSurface4_GetColorKey(
1341 LPDIRECTDRAWSURFACE4 this,
1342 DWORD dwFlags,
1343 LPDDCOLORKEY lpDDColorKey )
1345 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);
1347 if( dwFlags & DDCKEY_SRCBLT ) {
1348 dwFlags &= ~DDCKEY_SRCBLT;
1349 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1352 if( dwFlags & DDCKEY_DESTBLT )
1354 dwFlags &= ~DDCKEY_DESTBLT;
1355 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1358 if( dwFlags & DDCKEY_SRCOVERLAY )
1360 dwFlags &= ~DDCKEY_SRCOVERLAY;
1361 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1364 if( dwFlags & DDCKEY_DESTOVERLAY )
1366 dwFlags &= ~DDCKEY_DESTOVERLAY;
1367 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1370 if( dwFlags )
1372 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1375 return DD_OK;
1378 static HRESULT WINAPI IDirectDrawSurface4_GetFlipStatus(
1379 LPDIRECTDRAWSURFACE4 this,
1380 DWORD dwFlags )
1382 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1384 return DD_OK;
1387 static HRESULT WINAPI IDirectDrawSurface4_GetPalette(
1388 LPDIRECTDRAWSURFACE4 this,
1389 LPDIRECTDRAWPALETTE* lplpDDPalette )
1391 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1393 return DD_OK;
1396 static HRESULT WINAPI IDirectDrawSurface4_SetOverlayPosition(
1397 LPDIRECTDRAWSURFACE4 this,
1398 LONG lX,
1399 LONG lY)
1401 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1403 return DD_OK;
1406 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlay(
1407 LPDIRECTDRAWSURFACE4 this,
1408 LPRECT32 lpSrcRect,
1409 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1410 LPRECT32 lpDestRect,
1411 DWORD dwFlags,
1412 LPDDOVERLAYFX lpDDOverlayFx )
1414 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1415 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1417 return DD_OK;
1420 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayDisplay(
1421 LPDIRECTDRAWSURFACE4 this,
1422 DWORD dwFlags )
1424 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1426 return DD_OK;
1429 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayZOrder(
1430 LPDIRECTDRAWSURFACE4 this,
1431 DWORD dwFlags,
1432 LPDIRECTDRAWSURFACE4 lpDDSReference )
1434 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1436 return DD_OK;
1439 static HRESULT WINAPI IDirectDrawSurface4_GetDDInterface(
1440 LPDIRECTDRAWSURFACE4 this,
1441 LPVOID* lplpDD )
1443 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1445 /* Not sure about that... */
1446 *lplpDD = (void *) this->s.ddraw;
1448 return DD_OK;
1451 static HRESULT WINAPI IDirectDrawSurface4_PageLock(
1452 LPDIRECTDRAWSURFACE4 this,
1453 DWORD dwFlags )
1455 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1457 return DD_OK;
1460 static HRESULT WINAPI IDirectDrawSurface4_PageUnlock(
1461 LPDIRECTDRAWSURFACE4 this,
1462 DWORD dwFlags )
1464 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1466 return DD_OK;
1469 static HRESULT WINAPI IDirectDrawSurface4_SetSurfaceDesc(
1470 LPDIRECTDRAWSURFACE4 this,
1471 LPDDSURFACEDESC lpDDSD,
1472 DWORD dwFlags )
1474 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1476 return DD_OK;
1479 static HRESULT WINAPI IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4 this,
1480 REFGUID guidTag,
1481 LPVOID lpData,
1482 DWORD cbSize,
1483 DWORD dwFlags) {
1484 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag, lpData, cbSize, dwFlags);
1486 return DD_OK;
1489 static HRESULT WINAPI IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4 this,
1490 REFGUID guidTag,
1491 LPVOID lpBuffer,
1492 LPDWORD lpcbBufferSize) {
1493 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", this, guidTag, lpBuffer, lpcbBufferSize);
1495 return DD_OK;
1498 static HRESULT WINAPI IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4 this,
1499 REFGUID guidTag) {
1500 FIXME(ddraw, "(%p)->(%p)\n", this, guidTag);
1502 return DD_OK;
1505 static HRESULT WINAPI IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4 this,
1506 LPDWORD lpValue) {
1507 FIXME(ddraw, "(%p)->(%p)\n", this, lpValue);
1509 return DD_OK;
1512 static HRESULT WINAPI IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 this) {
1513 FIXME(ddraw, "(%p)\n", this);
1515 return DD_OK;
1518 static struct IDirectDrawSurface4_VTable dga_dds4vt = {
1519 IDirectDrawSurface4_QueryInterface,
1520 IDirectDrawSurface4_AddRef,
1521 DGA_IDirectDrawSurface4_Release,
1522 IDirectDrawSurface4_AddAttachedSurface,
1523 IDirectDrawSurface4_AddOverlayDirtyRect,
1524 IDirectDrawSurface4_Blt,
1525 IDirectDrawSurface4_BltBatch,
1526 IDirectDrawSurface4_BltFast,
1527 IDirectDrawSurface4_DeleteAttachedSurface,
1528 IDirectDrawSurface4_EnumAttachedSurfaces,
1529 IDirectDrawSurface4_EnumOverlayZOrders,
1530 DGA_IDirectDrawSurface4_Flip,
1531 IDirectDrawSurface4_GetAttachedSurface,
1532 IDirectDrawSurface4_GetBltStatus,
1533 IDirectDrawSurface4_GetCaps,
1534 IDirectDrawSurface4_GetClipper,
1535 IDirectDrawSurface4_GetColorKey,
1536 IDirectDrawSurface4_GetDC,
1537 IDirectDrawSurface4_GetFlipStatus,
1538 IDirectDrawSurface4_GetOverlayPosition,
1539 IDirectDrawSurface4_GetPalette,
1540 IDirectDrawSurface4_GetPixelFormat,
1541 IDirectDrawSurface4_GetSurfaceDesc,
1542 IDirectDrawSurface4_Initialize,
1543 IDirectDrawSurface4_IsLost,
1544 IDirectDrawSurface4_Lock,
1545 IDirectDrawSurface4_ReleaseDC,
1546 IDirectDrawSurface4_Restore,
1547 IDirectDrawSurface4_SetClipper,
1548 IDirectDrawSurface4_SetColorKey,
1549 IDirectDrawSurface4_SetOverlayPosition,
1550 DGA_IDirectDrawSurface4_SetPalette,
1551 DGA_IDirectDrawSurface4_Unlock,
1552 IDirectDrawSurface4_UpdateOverlay,
1553 IDirectDrawSurface4_UpdateOverlayDisplay,
1554 IDirectDrawSurface4_UpdateOverlayZOrder,
1555 IDirectDrawSurface4_GetDDInterface,
1556 IDirectDrawSurface4_PageLock,
1557 IDirectDrawSurface4_PageUnlock,
1558 IDirectDrawSurface4_SetSurfaceDesc,
1559 IDirectDrawSurface4_SetPrivateData,
1560 IDirectDrawSurface4_GetPrivateData,
1561 IDirectDrawSurface4_FreePrivateData,
1562 IDirectDrawSurface4_GetUniquenessValue,
1563 IDirectDrawSurface4_ChangeUniquenessValue
1566 static struct IDirectDrawSurface4_VTable xlib_dds4vt = {
1567 IDirectDrawSurface4_QueryInterface,
1568 IDirectDrawSurface4_AddRef,
1569 Xlib_IDirectDrawSurface4_Release,
1570 IDirectDrawSurface4_AddAttachedSurface,
1571 IDirectDrawSurface4_AddOverlayDirtyRect,
1572 IDirectDrawSurface4_Blt,
1573 IDirectDrawSurface4_BltBatch,
1574 IDirectDrawSurface4_BltFast,
1575 IDirectDrawSurface4_DeleteAttachedSurface,
1576 IDirectDrawSurface4_EnumAttachedSurfaces,
1577 IDirectDrawSurface4_EnumOverlayZOrders,
1578 Xlib_IDirectDrawSurface4_Flip,
1579 IDirectDrawSurface4_GetAttachedSurface,
1580 IDirectDrawSurface4_GetBltStatus,
1581 IDirectDrawSurface4_GetCaps,
1582 IDirectDrawSurface4_GetClipper,
1583 IDirectDrawSurface4_GetColorKey,
1584 IDirectDrawSurface4_GetDC,
1585 IDirectDrawSurface4_GetFlipStatus,
1586 IDirectDrawSurface4_GetOverlayPosition,
1587 IDirectDrawSurface4_GetPalette,
1588 IDirectDrawSurface4_GetPixelFormat,
1589 IDirectDrawSurface4_GetSurfaceDesc,
1590 IDirectDrawSurface4_Initialize,
1591 IDirectDrawSurface4_IsLost,
1592 IDirectDrawSurface4_Lock,
1593 IDirectDrawSurface4_ReleaseDC,
1594 IDirectDrawSurface4_Restore,
1595 IDirectDrawSurface4_SetClipper,
1596 IDirectDrawSurface4_SetColorKey,
1597 IDirectDrawSurface4_SetOverlayPosition,
1598 Xlib_IDirectDrawSurface4_SetPalette,
1599 Xlib_IDirectDrawSurface4_Unlock,
1600 IDirectDrawSurface4_UpdateOverlay,
1601 IDirectDrawSurface4_UpdateOverlayDisplay,
1602 IDirectDrawSurface4_UpdateOverlayZOrder,
1603 IDirectDrawSurface4_GetDDInterface,
1604 IDirectDrawSurface4_PageLock,
1605 IDirectDrawSurface4_PageUnlock,
1606 IDirectDrawSurface4_SetSurfaceDesc,
1607 IDirectDrawSurface4_SetPrivateData,
1608 IDirectDrawSurface4_GetPrivateData,
1609 IDirectDrawSurface4_FreePrivateData,
1610 IDirectDrawSurface4_GetUniquenessValue,
1611 IDirectDrawSurface4_ChangeUniquenessValue
1614 /******************************************************************************
1615 * DirectDrawCreateClipper (DDRAW.7)
1617 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1618 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1619 LPUNKNOWN pUnkOuter)
1621 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1623 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1624 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1625 (*lplpDDClipper)->ref = 1;
1627 return DD_OK;
1630 /******************************************************************************
1631 * IDirectDrawClipper
1633 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1634 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1636 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1637 return DD_OK;
1640 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1641 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1643 this->ref--;
1644 if (this->ref)
1645 return this->ref;
1646 HeapFree(GetProcessHeap(),0,this);
1647 return 0;
1650 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1651 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1653 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1654 if (hmm) *hmm=0;
1655 return DD_OK;
1658 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1659 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1661 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1662 return DD_OK;
1665 static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
1666 LPDIRECTDRAWCLIPPER this,
1667 REFIID riid,
1668 LPVOID* ppvObj )
1670 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
1671 return OLE_E_ENUM_NOMORE;
1674 static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
1676 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1677 return ++(this->ref);
1680 static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
1681 LPDIRECTDRAWCLIPPER this,
1682 HWND32* HWndPtr )
1684 FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
1685 return DD_OK;
1688 static HRESULT WINAPI IDirectDrawClipper_Initialize(
1689 LPDIRECTDRAWCLIPPER this,
1690 LPDIRECTDRAW lpDD,
1691 DWORD dwFlags )
1693 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
1694 return DD_OK;
1697 static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
1698 LPDIRECTDRAWCLIPPER this,
1699 BOOL32* lpbChanged )
1701 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
1702 return DD_OK;
1705 static struct IDirectDrawClipper_VTable ddclipvt = {
1706 IDirectDrawClipper_QueryInterface,
1707 IDirectDrawClipper_AddRef,
1708 IDirectDrawClipper_Release,
1709 IDirectDrawClipper_GetClipList,
1710 IDirectDrawClipper_GetHWnd,
1711 IDirectDrawClipper_Initialize,
1712 IDirectDrawClipper_IsClipListChanged,
1713 IDirectDrawClipper_SetClipList,
1714 IDirectDrawClipper_SetHwnd
1718 /******************************************************************************
1719 * IDirectDrawPalette
1721 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1722 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1724 int i;
1726 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1727 this,x,start,count,palent);
1729 if (!this->cm) /* should not happen */ {
1730 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1731 return DDERR_GENERIC;
1733 for (i=0;i<count;i++) {
1734 palent[i].peRed = this->palents[start+i].peRed;
1735 palent[i].peBlue = this->palents[start+i].peBlue;
1736 palent[i].peGreen = this->palents[start+i].peGreen;
1737 palent[i].peFlags = this->palents[start+i].peFlags;
1740 return DD_OK;
1743 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1744 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1746 XColor xc;
1747 int i;
1749 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1750 this,x,start,count,palent
1752 for (i=0;i<count;i++) {
1753 xc.red = palent[i].peRed<<8;
1754 xc.blue = palent[i].peBlue<<8;
1755 xc.green = palent[i].peGreen<<8;
1756 xc.flags = DoRed|DoBlue|DoGreen;
1757 xc.pixel = start+i;
1759 if (this->cm)
1760 TSXStoreColor(display,this->cm,&xc);
1762 this->palents[start+i].peRed = palent[i].peRed;
1763 this->palents[start+i].peBlue = palent[i].peBlue;
1764 this->palents[start+i].peGreen = palent[i].peGreen;
1765 this->palents[start+i].peFlags = palent[i].peFlags;
1768 /* Now, if we are in 'depth conversion mode', update the screen palette */
1769 if (this->ddraw->d.depth != this->ddraw->d.screen_depth) {
1770 int i;
1772 switch (this->ddraw->d.screen_depth) {
1773 case 16: {
1774 unsigned short *screen_palette = (unsigned short *) this->screen_palents;
1776 for (i = 0; i < count; i++) {
1777 screen_palette[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
1778 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
1779 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
1781 } break;
1783 default:
1784 ERR(ddraw, "Memory corruption !\n");
1785 break;
1789 if (!this->cm) /* should not happen */ {
1791 return DD_OK;
1794 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1795 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1797 #ifdef HAVE_LIBXXF86DGA
1798 XColor xc;
1799 Colormap cm;
1800 int i;
1802 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1803 this,x,start,count,palent
1805 if (!this->cm) /* should not happen */ {
1806 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1807 return DDERR_GENERIC;
1809 /* FIXME: free colorcells instead of freeing whole map */
1810 cm = this->cm;
1811 this->cm = TSXCopyColormapAndFree(display,this->cm);
1812 TSXFreeColormap(display,cm);
1814 for (i=0;i<count;i++) {
1815 xc.red = palent[i].peRed<<8;
1816 xc.blue = palent[i].peBlue<<8;
1817 xc.green = palent[i].peGreen<<8;
1818 xc.flags = DoRed|DoBlue|DoGreen;
1819 xc.pixel = i+start;
1821 TSXStoreColor(display,this->cm,&xc);
1823 this->palents[start+i].peRed = palent[i].peRed;
1824 this->palents[start+i].peBlue = palent[i].peBlue;
1825 this->palents[start+i].peGreen = palent[i].peGreen;
1826 this->palents[start+i].peFlags = palent[i].peFlags;
1828 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1829 return DD_OK;
1830 #else /* defined(HAVE_LIBXXF86DGA) */
1831 return E_UNEXPECTED;
1832 #endif /* defined(HAVE_LIBXXF86DGA) */
1835 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1836 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1837 if (!--(this->ref)) {
1838 if (this->cm) {
1839 TSXFreeColormap(display,this->cm);
1840 this->cm = 0;
1842 HeapFree(GetProcessHeap(),0,this);
1843 return 0;
1845 return this->ref;
1848 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1850 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1851 return ++(this->ref);
1854 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1855 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1857 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1859 return DDERR_ALREADYINITIALIZED;
1862 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1863 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1865 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1866 return DD_OK;
1869 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1870 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1872 char xrefiid[50];
1874 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1875 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1877 return S_OK;
1880 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1881 IDirectDrawPalette_QueryInterface,
1882 IDirectDrawPalette_AddRef,
1883 IDirectDrawPalette_Release,
1884 IDirectDrawPalette_GetCaps,
1885 IDirectDrawPalette_GetEntries,
1886 IDirectDrawPalette_Initialize,
1887 DGA_IDirectDrawPalette_SetEntries
1890 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1891 IDirectDrawPalette_QueryInterface,
1892 IDirectDrawPalette_AddRef,
1893 IDirectDrawPalette_Release,
1894 IDirectDrawPalette_GetCaps,
1895 IDirectDrawPalette_GetEntries,
1896 IDirectDrawPalette_Initialize,
1897 Xlib_IDirectDrawPalette_SetEntries
1900 /*******************************************************************************
1901 * IDirect3D
1903 static HRESULT WINAPI IDirect3D_QueryInterface(
1904 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1906 /* FIXME: Not sure if this is correct */
1907 char xrefiid[50];
1909 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1910 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1911 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1912 *obj = this;
1913 this->lpvtbl->fnAddRef(this);
1915 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
1917 return S_OK;
1919 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1920 LPDIRECT3D d3d;
1922 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1923 d3d->ref = 1;
1924 d3d->ddraw = (LPDIRECTDRAW)this;
1925 this->lpvtbl->fnAddRef(this);
1926 d3d->lpvtbl = &d3dvt;
1927 *obj = d3d;
1929 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
1931 return S_OK;
1933 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
1934 LPDIRECT3D2 d3d;
1936 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1937 d3d->ref = 1;
1938 d3d->ddraw = (LPDIRECTDRAW)this;
1939 this->lpvtbl->fnAddRef(this);
1940 d3d->lpvtbl = &d3d2vt;
1941 *obj = d3d;
1943 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
1945 return S_OK;
1947 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1948 return OLE_E_ENUM_NOMORE;
1951 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1952 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1954 return ++(this->ref);
1957 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1959 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1961 if (!--(this->ref)) {
1962 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1963 HeapFree(GetProcessHeap(),0,this);
1964 return 0;
1966 return this->ref;
1969 static HRESULT WINAPI IDirect3D_Initialize(
1970 LPDIRECT3D this, REFIID refiid )
1972 /* FIXME: Not sure if this is correct */
1973 char xrefiid[50];
1975 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1976 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1978 return DDERR_ALREADYINITIALIZED;
1981 static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this,
1982 LPD3DENUMDEVICESCALLBACK cb,
1983 LPVOID context) {
1984 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1986 /* Call functions defined in d3ddevices.c */
1987 if (d3d_OpenGL_dx3(cb, context))
1988 return DD_OK;
1990 return DD_OK;
1993 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,
1994 LPDIRECT3DLIGHT *lplight,
1995 IUnknown *lpunk)
1997 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
1999 /* Call the creation function that is located in d3dlight.c */
2000 *lplight = d3dlight_create_dx3(this);
2002 return DD_OK;
2005 static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this,
2006 LPDIRECT3DMATERIAL *lpmaterial,
2007 IUnknown *lpunk)
2009 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2011 /* Call the creation function that is located in d3dviewport.c */
2012 *lpmaterial = d3dmaterial_create(this);
2014 return DD_OK;
2017 static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this,
2018 LPDIRECT3DVIEWPORT *lpviewport,
2019 IUnknown *lpunk)
2021 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2023 /* Call the creation function that is located in d3dviewport.c */
2024 *lpviewport = d3dviewport_create(this);
2026 return DD_OK;
2029 static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this,
2030 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2031 LPD3DFINDDEVICERESULT lpfinddevrst)
2033 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2035 return DD_OK;
2038 static struct IDirect3D_VTable d3dvt = {
2039 IDirect3D_QueryInterface,
2040 IDirect3D_AddRef,
2041 IDirect3D_Release,
2042 IDirect3D_Initialize,
2043 IDirect3D_EnumDevices,
2044 IDirect3D_CreateLight,
2045 IDirect3D_CreateMaterial,
2046 IDirect3D_CreateViewport,
2047 IDirect3D_FindDevice
2050 /*******************************************************************************
2051 * IDirect3D2
2053 static HRESULT WINAPI IDirect3D2_QueryInterface(
2054 LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) {
2055 /* For the moment, we use the same function as in IDirect3D */
2056 TRACE(ddraw, "Calling IDirect3D enumerating function.\n");
2058 return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj);
2061 static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) {
2062 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2064 return ++(this->ref);
2067 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
2068 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2070 if (!--(this->ref)) {
2071 this->ddraw->lpvtbl->fnRelease(this->ddraw);
2072 HeapFree(GetProcessHeap(),0,this);
2073 return 0;
2075 return this->ref;
2078 static HRESULT WINAPI IDirect3D2_EnumDevices(
2079 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2081 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
2083 /* Call functions defined in d3ddevices.c */
2084 if (d3d_OpenGL(cb, context))
2085 return DD_OK;
2087 return DD_OK;
2090 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,
2091 LPDIRECT3DLIGHT *lplight,
2092 IUnknown *lpunk)
2094 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
2096 /* Call the creation function that is located in d3dlight.c */
2097 *lplight = d3dlight_create(this);
2099 return DD_OK;
2102 static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this,
2103 LPDIRECT3DMATERIAL2 *lpmaterial,
2104 IUnknown *lpunk)
2106 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2108 /* Call the creation function that is located in d3dviewport.c */
2109 *lpmaterial = d3dmaterial2_create(this);
2111 return DD_OK;
2114 static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this,
2115 LPDIRECT3DVIEWPORT2 *lpviewport,
2116 IUnknown *lpunk)
2118 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2120 /* Call the creation function that is located in d3dviewport.c */
2121 *lpviewport = d3dviewport2_create(this);
2123 return DD_OK;
2126 static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this,
2127 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2128 LPD3DFINDDEVICERESULT lpfinddevrst)
2130 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2132 return DD_OK;
2135 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,
2136 REFCLSID rguid,
2137 LPDIRECTDRAWSURFACE surface,
2138 LPDIRECT3DDEVICE2 *device)
2140 char xbuf[50];
2142 WINE_StringFromCLSID(rguid,xbuf);
2143 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device);
2145 if (is_OpenGL(rguid, surface, device, this)) {
2146 this->lpvtbl->fnAddRef(this);
2147 return DD_OK;
2150 return DDERR_INVALIDPARAMS;
2153 static struct IDirect3D2_VTable d3d2vt = {
2154 IDirect3D2_QueryInterface,
2155 IDirect3D2_AddRef,
2156 IDirect3D2_Release,
2157 IDirect3D2_EnumDevices,
2158 IDirect3D2_CreateLight,
2159 IDirect3D2_CreateMaterial,
2160 IDirect3D2_CreateViewport,
2161 IDirect3D2_FindDevice,
2162 IDirect3D2_CreateDevice
2165 /*******************************************************************************
2166 * IDirectDraw
2169 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2170 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2172 static INT32 ddrawXlibThisOffset = 0;
2174 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
2175 LPDDSURFACEDESC lpddsd,
2176 LPDIRECTDRAWSURFACE lpdsf)
2178 int bpp;
2180 /* The surface was already allocated when entering in this function */
2181 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2183 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2184 /* This is a Z Buffer */
2185 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2186 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2187 } else {
2188 /* This is a standard image */
2189 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2190 /* No pixel format => use DirectDraw's format */
2191 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
2192 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2193 } else {
2194 /* To check what the program wants */
2195 if (TRACE_ON(ddraw)) {
2196 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2200 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2201 bpp = 1;
2202 } else {
2203 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2207 /* Copy the surface description */
2208 lpdsf->s.surface_desc = *lpddsd;
2210 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2211 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2212 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2214 return DD_OK;
2217 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
2218 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2220 #ifdef HAVE_LIBXXF86DGA
2221 int i;
2223 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
2224 if (TRACE_ON(ddraw)) {
2225 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2226 _dump_DDSD(lpddsd->dwFlags);
2227 fprintf(stderr,"caps ");
2228 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2229 fprintf(stderr,"]\n");
2232 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2233 this->lpvtbl->fnAddRef(this);
2235 (*lpdsf)->ref = 1;
2236 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds4vt;
2237 (*lpdsf)->s.ddraw = this;
2238 (*lpdsf)->s.palette = NULL;
2239 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2241 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2242 lpddsd->dwWidth = this->d.width;
2243 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2244 lpddsd->dwHeight = this->d.height;
2246 /* Check if this a 'primary surface' or not */
2247 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2248 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2250 /* This is THE primary surface => there is DGA-specific code */
2251 /* First, store the surface description */
2252 (*lpdsf)->s.surface_desc = *lpddsd;
2254 /* Find a viewport */
2255 for (i=0;i<32;i++)
2256 if (!(this->e.dga.vpmask & (1<<i)))
2257 break;
2258 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2259 /* if i == 32 or maximum ... return error */
2260 this->e.dga.vpmask|=(1<<i);
2261 (*lpdsf)->s.surface_desc.y.lpSurface =
2262 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
2263 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
2264 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
2265 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
2267 /* Add flags if there were not present */
2268 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2269 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2270 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2271 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d.width,this->d.height,lpddsd->lPitch);
2272 /* We put our surface always in video memory */
2273 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2274 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2275 (*lpdsf)->s.backbuffer = NULL;
2277 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2278 LPDIRECTDRAWSURFACE4 back;
2280 if (lpddsd->dwBackBufferCount>1)
2281 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2283 (*lpdsf)->s.backbuffer = back =
2284 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2285 this->lpvtbl->fnAddRef(this);
2286 back->ref = 1;
2287 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&dga_dds4vt;
2288 for (i=0;i<32;i++)
2289 if (!(this->e.dga.vpmask & (1<<i)))
2290 break;
2291 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2292 /* if i == 32 or maximum ... return error */
2293 this->e.dga.vpmask|=(1<<i);
2294 back->t.dga.fb_height = i*this->e.dga.fb_height;
2296 /* Copy the surface description from the front buffer */
2297 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2298 /* Change the parameters that are not the same */
2299 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
2300 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
2301 back->s.ddraw = this;
2302 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2303 * one! */
2305 /* Add relevant info to front and back buffers */
2306 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2307 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2308 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2309 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2310 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2312 } else {
2313 /* There is no DGA-specific code here...
2314 Go to the common surface creation function */
2315 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2318 return DD_OK;
2319 #else /* defined(HAVE_LIBXXF86DGA) */
2320 return E_UNEXPECTED;
2321 #endif /* defined(HAVE_LIBXXF86DGA) */
2324 #ifdef HAVE_LIBXXSHM
2325 /* Error handlers for Image creation */
2326 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2327 XShmErrorFlag = 1;
2328 return 0;
2331 static XImage *create_xshmimage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2332 XImage *img;
2333 int (*WineXHandler)(Display *, XErrorEvent *);
2335 img = TSXShmCreateImage(display,
2336 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2337 this->d.screen_depth,
2338 ZPixmap,
2339 NULL,
2340 &(lpdsf->t.xlib.shminfo),
2341 lpdsf->s.surface_desc.dwWidth,
2342 lpdsf->s.surface_desc.dwHeight);
2344 if (img == NULL) {
2345 ERR(ddraw, "Error creating XShm image. Reverting to standard X images !\n");
2346 this->e.xlib.xshm_active = 0;
2347 return NULL;
2350 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2351 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2352 ERR(ddraw, "Error creating shared memory segment. Reverting to standard X images !\n");
2353 this->e.xlib.xshm_active = 0;
2354 TSXDestroyImage(img);
2355 return NULL;
2358 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2360 if (img->data == (char *) -1) {
2361 ERR(ddraw, "Error attaching shared memory segment. Reverting to standard X images !\n");
2362 this->e.xlib.xshm_active = 0;
2363 TSXDestroyImage(img);
2364 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2365 return NULL;
2367 lpdsf->t.xlib.shminfo.readOnly = False;
2369 /* This is where things start to get trickier....
2370 First, we flush the current X connections to be sure to catch all non-XShm related
2371 errors */
2372 TSXSync(display, False);
2373 /* Then we enter in the non-thread safe part of the tests */
2374 EnterCriticalSection( &X11DRV_CritSection );
2376 /* Reset the error flag, sets our new error handler and try to attach the surface */
2377 XShmErrorFlag = 0;
2378 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2379 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2380 XSync(display, False);
2382 /* Check the error flag */
2383 if (XShmErrorFlag) {
2384 /* An error occured */
2385 XFlush(display);
2386 XShmErrorFlag = 0;
2387 XDestroyImage(img);
2388 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2389 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2390 XSetErrorHandler(WineXHandler);
2392 ERR(ddraw, "Error attaching shared memory segment to X server. Reverting to standard X images !\n");
2393 this->e.xlib.xshm_active = 0;
2395 /* Leave the critical section */
2396 LeaveCriticalSection( &X11DRV_CritSection );
2398 return NULL;
2401 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2402 but it may be a bit overkill.... */
2403 XSetErrorHandler(WineXHandler);
2404 LeaveCriticalSection( &X11DRV_CritSection );
2406 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2408 if (this->d.depth != this->d.screen_depth) {
2409 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2410 lpdsf->s.surface_desc.dwWidth *
2411 lpdsf->s.surface_desc.dwHeight *
2412 (this->d.depth / 8));
2413 } else {
2414 lpdsf->s.surface_desc.y.lpSurface = img->data;
2417 return img;
2419 #endif /* HAVE_LIBXXSHM */
2421 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2422 XImage *img = NULL;
2423 void *img_data;
2425 #ifdef HAVE_LIBXXSHM
2426 if (this->e.xlib.xshm_active) {
2427 img = create_xshmimage(this, lpdsf);
2430 if (img == NULL) {
2431 #endif
2432 /* Allocate surface memory */
2433 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2434 lpdsf->s.surface_desc.dwWidth *
2435 lpdsf->s.surface_desc.dwHeight *
2436 (this->d.depth / 8));
2438 if (this->d.depth != this->d.screen_depth) {
2439 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2440 lpdsf->s.surface_desc.dwWidth *
2441 lpdsf->s.surface_desc.dwHeight *
2442 (this->d.screen_depth / 8));
2443 } else {
2444 img_data = lpdsf->s.surface_desc.y.lpSurface;
2447 /* In this case, create an XImage */
2448 img =
2449 TSXCreateImage(display,
2450 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2451 this->d.screen_depth,
2452 ZPixmap,
2454 img_data,
2455 lpdsf->s.surface_desc.dwWidth,
2456 lpdsf->s.surface_desc.dwHeight,
2458 lpdsf->s.surface_desc.dwWidth * (this->d.screen_depth / 8)
2461 #ifdef HAVE_LIBXXSHM
2463 #endif
2464 if (this->d.depth != this->d.screen_depth) {
2465 lpdsf->s.surface_desc.lPitch = (this->d.depth / 8) * lpdsf->s.surface_desc.dwWidth;
2466 } else {
2467 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2470 return img;
2473 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
2474 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2476 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2477 this,lpddsd,lpdsf,lpunk);
2479 if (TRACE_ON(ddraw)) {
2480 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2481 _dump_DDSD(lpddsd->dwFlags);
2482 fprintf(stderr,"caps ");
2483 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2484 fprintf(stderr,"]\n");
2487 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2489 this->lpvtbl->fnAddRef(this);
2490 (*lpdsf)->s.ddraw = this;
2491 (*lpdsf)->ref = 1;
2492 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds4vt;
2493 (*lpdsf)->s.palette = NULL;
2494 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2496 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2497 lpddsd->dwWidth = this->d.width;
2498 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2499 lpddsd->dwHeight = this->d.height;
2501 /* Check if this a 'primary surface' or not */
2502 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2503 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2504 XImage *img;
2506 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
2508 /* First, store the surface description */
2509 (*lpdsf)->s.surface_desc = *lpddsd;
2511 /* Create the XImage */
2512 img = create_ximage(this, (LPDIRECTDRAWSURFACE4) *lpdsf);
2513 if (img == NULL)
2514 return DDERR_OUTOFMEMORY;
2515 (*lpdsf)->t.xlib.image = img;
2517 /* Add flags if there were not present */
2518 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2519 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2520 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2521 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2522 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
2523 (*lpdsf)->s.backbuffer = NULL;
2525 /* Check for backbuffers */
2526 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2527 LPDIRECTDRAWSURFACE4 back;
2528 XImage *img;
2530 if (lpddsd->dwBackBufferCount>1)
2531 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2533 (*lpdsf)->s.backbuffer = back =
2534 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2536 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2538 this->lpvtbl->fnAddRef(this);
2539 back->s.ddraw = this;
2541 back->ref = 1;
2542 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&xlib_dds4vt;
2543 /* Copy the surface description from the front buffer */
2544 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2546 /* Create the XImage */
2547 img = create_ximage(this, back);
2548 if (img == NULL)
2549 return DDERR_OUTOFMEMORY;
2550 back->t.xlib.image = img;
2552 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2553 * one! */
2555 /* Add relevant info to front and back buffers */
2556 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2557 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2558 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2559 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2560 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2562 } else {
2563 /* There is no Xlib-specific code here...
2564 Go to the common surface creation function */
2565 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2568 return DD_OK;
2571 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
2572 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2574 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
2575 *dst = src; /* FIXME */
2576 return DD_OK;
2580 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2581 * even when the approbiate bitmasks are not specified.
2583 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
2584 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
2586 int i;
2587 const struct {
2588 int mask;
2589 char *name;
2590 } flagmap[] = {
2591 FE(DDSCL_FULLSCREEN)
2592 FE(DDSCL_ALLOWREBOOT)
2593 FE(DDSCL_NOWINDOWCHANGES)
2594 FE(DDSCL_NORMAL)
2595 FE(DDSCL_ALLOWMODEX)
2596 FE(DDSCL_EXCLUSIVE)
2597 FE(DDSCL_SETFOCUSWINDOW)
2598 FE(DDSCL_SETDEVICEWINDOW)
2599 FE(DDSCL_CREATEDEVICEWINDOW)
2602 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
2603 if(TRACE_ON(ddraw)){
2604 dbg_decl_str(ddraw, 512);
2605 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2606 if (flagmap[i].mask & cooplevel)
2607 dsprintf(ddraw, "%s ", flagmap[i].name);
2608 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2610 this->d.mainWindow = hwnd;
2612 /* This will be overwritten in the case of Full Screen mode.
2613 Windowed games could work with that :-) */
2614 if (hwnd)
2615 this->d.drawable = X11DRV_WND_GetXWindow(WIN_FindWndPtr(hwnd));
2617 return DD_OK;
2620 /* Small helper to either use the cooperative window or create a new
2621 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2623 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
2624 RECT32 rect;
2626 /* Do not destroy the application supplied cooperative window */
2627 if (this->d.window && this->d.window != this->d.mainWindow) {
2628 DestroyWindow32(this->d.window);
2629 this->d.window = 0;
2631 /* Sanity check cooperative window before assigning it to drawing. */
2632 if ( IsWindow32(this->d.mainWindow) &&
2633 IsWindowVisible32(this->d.mainWindow)
2635 GetWindowRect32(this->d.mainWindow,&rect);
2636 if (((rect.right-rect.left) >= this->d.width) &&
2637 ((rect.bottom-rect.top) >= this->d.height)
2639 this->d.window = this->d.mainWindow;
2641 /* ... failed, create new one. */
2642 if (!this->d.window) {
2643 this->d.window = CreateWindowEx32A(
2645 "WINE_DirectDraw",
2646 "WINE_DirectDraw",
2647 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2648 0,0,
2649 this->d.width,
2650 this->d.height,
2654 NULL
2656 /*Store THIS with the window. We'll use it in the window procedure*/
2657 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
2658 ShowWindow32(this->d.window,TRUE);
2659 UpdateWindow32(this->d.window);
2661 SetFocus32(this->d.window);
2664 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
2665 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2667 #ifdef HAVE_LIBXXF86DGA
2668 int i,*depths,depcount,mode_count;
2670 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2672 /* We hope getting the asked for depth */
2673 this->d.screen_depth = depth;
2675 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2677 for (i=0;i<depcount;i++)
2678 if (depths[i]==depth)
2679 break;
2680 TSXFree(depths);
2681 if (i==depcount) {/* not found */
2682 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2683 return DDERR_UNSUPPORTEDMODE;
2685 if (this->d.width < width) {
2686 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2687 return DDERR_UNSUPPORTEDMODE;
2689 this->d.width = width;
2690 this->d.height = height;
2691 this->d.depth = depth;
2693 /* adjust fb_height, so we don't overlap */
2694 if (this->e.dga.fb_height < height)
2695 this->e.dga.fb_height = height;
2696 _common_IDirectDraw_SetDisplayMode(this);
2698 #ifdef HAVE_LIBXXF86VM
2700 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2701 XF86VidModeModeLine mod_tmp;
2702 /* int dotclock_tmp; */
2704 /* save original video mode and set fullscreen if available*/
2705 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2706 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2707 orig_mode->hdisplay = mod_tmp.hdisplay;
2708 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2709 orig_mode->hsyncend = mod_tmp.hsyncend;
2710 orig_mode->htotal = mod_tmp.htotal;
2711 orig_mode->vdisplay = mod_tmp.vdisplay;
2712 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2713 orig_mode->vsyncend = mod_tmp.vsyncend;
2714 orig_mode->vtotal = mod_tmp.vtotal;
2715 orig_mode->flags = mod_tmp.flags;
2716 orig_mode->private = mod_tmp.private;
2718 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2719 for (i=0;i<mode_count;i++)
2721 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2723 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2724 *vidmode = *(all_modes[i]);
2725 break;
2726 } else
2727 TSXFree(all_modes[i]->private);
2729 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
2730 TSXFree(all_modes);
2732 if (!vidmode)
2733 WARN(ddraw, "Fullscreen mode not available!\n");
2735 if (vidmode)
2737 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
2738 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2739 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
2740 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2741 #endif
2744 #endif
2746 /* FIXME: this function OVERWRITES several signal handlers.
2747 * can we save them? and restore them later? In a way that
2748 * it works for the library too?
2750 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2751 #ifdef DIABLO_HACK
2752 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2753 #else
2754 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2755 #endif
2757 #ifdef RESTORE_SIGNALS
2758 SIGNAL_InitHandlers();
2759 #endif
2760 return DD_OK;
2761 #else /* defined(HAVE_LIBXXF86DGA) */
2762 return E_UNEXPECTED;
2763 #endif /* defined(HAVE_LIBXXF86DGA) */
2766 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2767 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2769 int i,*depths,depcount;
2770 char buf[200];
2772 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2773 this, width, height, depth);
2775 /* We hope getting the asked for depth */
2776 this->d.screen_depth = depth;
2778 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2780 for (i=0;i<depcount;i++)
2781 if (depths[i]==depth)
2782 break;
2783 if (i==depcount) {/* not found */
2784 for (i=0;i<depcount;i++)
2785 if (depths[i]==16)
2786 break;
2788 if (i==depcount) {
2789 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2790 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2791 TSXFree(depths);
2792 return DDERR_UNSUPPORTEDMODE;
2793 } else {
2794 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
2795 this->d.screen_depth = 16;
2798 TSXFree(depths);
2800 this->d.width = width;
2801 this->d.height = height;
2802 this->d.depth = depth;
2804 _common_IDirectDraw_SetDisplayMode(this);
2806 this->d.paintable = 1;
2807 this->d.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window;
2808 /* We don't have a context for this window. Host off the desktop */
2809 if( !this->d.drawable )
2810 this->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
2811 return DD_OK;
2814 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2815 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2817 #ifdef HAVE_LIBXXF86DGA
2818 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2819 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2820 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2821 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2822 if (caps2) {
2823 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2824 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2825 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2827 return DD_OK;
2828 #else /* defined(HAVE_LIBXXF86DGA) */
2829 return E_UNEXPECTED;
2830 #endif /* defined(HAVE_LIBXXF86DGA) */
2833 static void fill_caps(LPDDCAPS caps) {
2834 /* This function tries to fill the capabilities of Wine's DDraw implementation.
2835 Need to be fixed, though.. */
2836 if (caps == NULL)
2837 return;
2839 caps->dwSize = sizeof(*caps);
2840 caps->dwCaps = DDCAPS_3D | DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
2841 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_ZBLTS;
2842 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NO2DDURING3DSCENE | DDCAPS2_NOPAGELOCKREQUIRED |
2843 DDCAPS2_WIDESURFACES;
2844 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
2845 caps->dwFXCaps = 0;
2846 caps->dwFXAlphaCaps = 0;
2847 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
2848 caps->dwSVCaps = 0;
2849 caps->dwZBufferBitDepths = DDBD_16;
2850 /* I put here 8 Mo so that D3D applications will believe they have enough memory
2851 to put textures in video memory.
2852 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
2853 for example) ? */
2854 caps->dwVidMemTotal = 8192 * 1024;
2855 caps->dwVidMemFree = 8192 * 1024;
2856 /* These are all the supported capabilities of the surfaces */
2857 caps->ddsCaps.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
2858 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
2859 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE |
2860 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE | DDSCAPS_ZBUFFER;
2863 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2864 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2866 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2868 /* Put the same caps for the two capabilities */
2869 fill_caps(caps1);
2870 fill_caps(caps2);
2872 return DD_OK;
2875 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2876 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2878 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2879 this,x,lpddclip,lpunk
2881 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2882 (*lpddclip)->ref = 1;
2883 (*lpddclip)->lpvtbl = &ddclipvt;
2884 return DD_OK;
2887 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2888 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk,int *psize
2890 int size = 0;
2892 if (TRACE_ON(ddraw))
2893 _dump_paletteformat(dwFlags);
2895 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2896 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2897 (*lpddpal)->ref = 1;
2898 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2899 (*lpddpal)->installed = 0;
2901 if (dwFlags & DDPCAPS_1BIT)
2902 size = 2;
2903 else if (dwFlags & DDPCAPS_2BIT)
2904 size = 4;
2905 else if (dwFlags & DDPCAPS_4BIT)
2906 size = 16;
2907 else if (dwFlags & DDPCAPS_8BIT)
2908 size = 256;
2909 else
2910 ERR(ddraw, "unhandled palette format\n");
2911 *psize = size;
2913 if (palent)
2915 /* Now, if we are in 'depth conversion mode', create the screen palette */
2916 if (this->d.depth != this->d.screen_depth) {
2917 int i;
2919 switch (this->d.screen_depth) {
2920 case 16: {
2921 unsigned short *screen_palette = (unsigned short *) (*lpddpal)->screen_palents;
2923 for (i = 0; i < size; i++) {
2924 screen_palette[i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
2925 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
2926 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
2928 } break;
2930 default:
2931 ERR(ddraw, "Memory corruption ! (depth=%ld, screen_depth=%ld)\n",this->d.depth,this->d.screen_depth);
2932 break;
2936 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
2937 } else if (this->d.depth != this->d.screen_depth) {
2938 int i;
2940 switch (this->d.screen_depth) {
2941 case 16: {
2942 unsigned short *screen_palette = (unsigned short *) (*lpddpal)->screen_palents;
2944 for (i = 0; i < size; i++) {
2945 screen_palette[i] = 0xFFFF;
2947 } break;
2949 default:
2950 ERR(ddraw, "Memory corruption !\n");
2951 break;
2955 return DD_OK;
2958 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2959 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2961 HRESULT res;
2962 int xsize = 0,i;
2964 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
2965 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
2966 if (res != 0) return res;
2967 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2968 if (this->d.depth<=8) {
2969 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
2970 } else {
2971 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
2972 (*lpddpal)->cm = 0;
2974 if (((*lpddpal)->cm)&&xsize) {
2975 for (i=0;i<xsize;i++) {
2976 XColor xc;
2978 xc.red = (*lpddpal)->palents[i].peRed<<8;
2979 xc.blue = (*lpddpal)->palents[i].peBlue<<8;
2980 xc.green = (*lpddpal)->palents[i].peGreen<<8;
2981 xc.flags = DoRed|DoBlue|DoGreen;
2982 xc.pixel = i;
2983 TSXStoreColor(display,(*lpddpal)->cm,&xc);
2986 return DD_OK;
2989 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2990 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2992 int xsize;
2993 HRESULT res;
2995 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
2996 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
2997 if (res != 0) return res;
2998 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2999 return DD_OK;
3002 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3003 #ifdef HAVE_LIBXXF86DGA
3004 TRACE(ddraw, "(%p)->()\n",this);
3005 Sleep(1000);
3006 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3007 #ifdef RESTORE_SIGNALS
3008 SIGNAL_InitHandlers();
3009 #endif
3010 return DD_OK;
3011 #else /* defined(HAVE_LIBXXF86DGA) */
3012 return E_UNEXPECTED;
3013 #endif
3016 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3017 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
3018 Sleep(1000);
3019 return DD_OK;
3022 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
3023 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
3025 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
3026 return DD_OK;
3029 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
3030 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
3032 return ++(this->ref);
3035 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3036 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3038 #ifdef HAVE_LIBXXF86DGA
3039 if (!--(this->ref)) {
3040 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3041 if (this->d.window && (this->d.mainWindow != this->d.window))
3042 DestroyWindow32(this->d.window);
3043 #ifdef HAVE_LIBXXF86VM
3044 if (orig_mode) {
3045 TSXF86VidModeSwitchToMode(
3046 display,
3047 DefaultScreen(display),
3048 orig_mode);
3049 if (orig_mode->privsize)
3050 TSXFree(orig_mode->private);
3051 free(orig_mode);
3052 orig_mode = NULL;
3054 #endif
3056 #ifdef RESTORE_SIGNALS
3057 SIGNAL_InitHandlers();
3058 #endif
3059 HeapFree(GetProcessHeap(),0,this);
3060 return 0;
3062 #endif /* defined(HAVE_LIBXXF86DGA) */
3063 return this->ref;
3066 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3067 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3069 if (!--(this->ref)) {
3070 if (this->d.window && (this->d.mainWindow != this->d.window))
3071 DestroyWindow32(this->d.window);
3072 HeapFree(GetProcessHeap(),0,this);
3073 return 0;
3075 /* FIXME: destroy window ... */
3076 return this->ref;
3079 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
3080 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3082 char xrefiid[50];
3084 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3085 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3086 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3087 *obj = this;
3088 this->lpvtbl->fnAddRef(this);
3090 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3092 return S_OK;
3094 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3095 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
3096 this->lpvtbl->fnAddRef(this);
3097 *obj = this;
3099 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3101 return S_OK;
3103 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3104 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
3105 this->lpvtbl->fnAddRef(this);
3106 *obj = this;
3108 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3110 return S_OK;
3112 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3113 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd4vt;
3114 this->lpvtbl->fnAddRef(this);
3115 *obj = this;
3117 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3119 return S_OK;
3121 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3122 LPDIRECT3D d3d;
3124 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3125 d3d->ref = 1;
3126 d3d->ddraw = (LPDIRECTDRAW)this;
3127 this->lpvtbl->fnAddRef(this);
3128 d3d->lpvtbl = &d3dvt;
3129 *obj = d3d;
3131 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3133 return S_OK;
3135 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3136 LPDIRECT3D2 d3d;
3138 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3139 d3d->ref = 1;
3140 d3d->ddraw = (LPDIRECTDRAW)this;
3141 this->lpvtbl->fnAddRef(this);
3142 d3d->lpvtbl = &d3d2vt;
3143 *obj = d3d;
3145 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3147 return S_OK;
3149 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3150 return OLE_E_ENUM_NOMORE;
3153 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
3154 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3156 char xrefiid[50];
3158 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3159 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3160 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3161 *obj = this;
3162 this->lpvtbl->fnAddRef(this);
3164 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3166 return S_OK;
3168 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3169 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
3170 this->lpvtbl->fnAddRef(this);
3171 *obj = this;
3173 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3175 return S_OK;
3177 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3178 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
3179 this->lpvtbl->fnAddRef(this);
3180 *obj = this;
3182 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3184 return S_OK;
3186 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3187 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd4vt;
3188 this->lpvtbl->fnAddRef(this);
3189 *obj = this;
3191 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3193 return S_OK;
3195 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3196 LPDIRECT3D d3d;
3198 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3199 d3d->ref = 1;
3200 d3d->ddraw = (LPDIRECTDRAW)this;
3201 this->lpvtbl->fnAddRef(this);
3202 d3d->lpvtbl = &d3dvt;
3203 *obj = d3d;
3205 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3207 return S_OK;
3209 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3210 LPDIRECT3D2 d3d;
3212 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3213 d3d->ref = 1;
3214 d3d->ddraw = (LPDIRECTDRAW)this;
3215 this->lpvtbl->fnAddRef(this);
3216 d3d->lpvtbl = &d3d2vt;
3217 *obj = d3d;
3219 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3221 return S_OK;
3223 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3224 return OLE_E_ENUM_NOMORE;
3227 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
3228 LPDIRECTDRAW2 this,BOOL32 *status
3230 TRACE(ddraw,"(%p)->(%p)\n",this,status);
3231 *status = TRUE;
3232 return DD_OK;
3235 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
3236 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3238 DDSURFACEDESC ddsfd;
3239 static struct {
3240 int w,h;
3241 } modes[5] = { /* some of the usual modes */
3242 {512,384},
3243 {640,400},
3244 {640,480},
3245 {800,600},
3246 {1024,768},
3248 static int depths[4] = {8,16,24,32};
3249 int i,j;
3251 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
3252 ddsfd.dwSize = sizeof(ddsfd);
3253 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3254 if (dwFlags & DDEDM_REFRESHRATES) {
3255 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3256 ddsfd.x.dwRefreshRate = 60;
3259 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3260 ddsfd.dwBackBufferCount = 1;
3261 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3262 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3263 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3264 /* FIXME: those masks would have to be set in depth > 8 */
3265 if (depths[i]==8) {
3266 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3267 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3268 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3269 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3270 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3271 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3272 } else {
3273 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3275 /* FIXME: We should query those from X itself */
3276 switch (depths[i]) {
3277 case 16:
3278 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3279 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3280 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3281 break;
3282 case 24:
3283 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3284 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3285 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3286 break;
3287 case 32:
3288 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3289 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3290 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3291 break;
3295 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3296 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3297 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3298 if (!modescb(&ddsfd,context)) return DD_OK;
3300 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3301 ddsfd.dwWidth = modes[j].w;
3302 ddsfd.dwHeight = modes[j].h;
3303 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3304 if (!modescb(&ddsfd,context)) return DD_OK;
3307 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3308 /* modeX is not standard VGA */
3310 ddsfd.dwHeight = 200;
3311 ddsfd.dwWidth = 320;
3312 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3313 if (!modescb(&ddsfd,context)) return DD_OK;
3316 return DD_OK;
3319 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
3320 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3322 #ifdef HAVE_LIBXXF86DGA
3323 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
3324 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3325 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3326 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3327 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
3328 lpddsfd->dwBackBufferCount = 1;
3329 lpddsfd->x.dwRefreshRate = 60;
3330 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3331 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
3332 return DD_OK;
3333 #else /* defined(HAVE_LIBXXF86DGA) */
3334 return E_UNEXPECTED;
3335 #endif /* defined(HAVE_LIBXXF86DGA) */
3338 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
3339 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3341 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
3342 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3343 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3344 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3345 /* POOLE FIXME: Xlib */
3346 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
3347 /* END FIXME: Xlib */
3348 lpddsfd->dwBackBufferCount = 1;
3349 lpddsfd->x.dwRefreshRate = 60;
3350 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3351 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
3352 return DD_OK;
3355 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
3356 TRACE(ddraw,"(%p)->()\n",this);
3357 return DD_OK;
3360 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
3361 LPDIRECTDRAW2 this,LPDWORD freq
3363 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
3364 *freq = 60*100; /* 60 Hz */
3365 return DD_OK;
3368 /* what can we directly decompress? */
3369 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
3370 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
3372 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
3373 return DD_OK;
3376 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
3377 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
3379 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
3380 return DD_OK;
3383 static HRESULT WINAPI IDirectDraw2_Compact(
3384 LPDIRECTDRAW2 this )
3386 FIXME(ddraw,"(%p)->()\n", this );
3388 return DD_OK;
3391 static HRESULT WINAPI IDirectDraw2_GetGDISurface(LPDIRECTDRAW2 this,
3392 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
3393 FIXME(ddraw,"(%p)->(%p)\n", this, lplpGDIDDSSurface);
3395 return DD_OK;
3398 static HRESULT WINAPI IDirectDraw2_GetScanLine(LPDIRECTDRAW2 this,
3399 LPDWORD lpdwScanLine) {
3400 FIXME(ddraw,"(%p)->(%p)\n", this, lpdwScanLine);
3402 return DD_OK;
3405 static HRESULT WINAPI IDirectDraw2_Initialize(LPDIRECTDRAW2 this,
3406 GUID *lpGUID) {
3407 FIXME(ddraw,"(%p)->(%p)\n", this, lpGUID);
3409 return DD_OK;
3412 /* Note: Hack so we can reuse the old functions without compiler warnings */
3413 #ifdef __GNUC__
3414 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
3415 #else
3416 # define XCAST(fun) (void*)
3417 #endif
3419 static struct IDirectDraw_VTable dga_ddvt = {
3420 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3421 XCAST(AddRef)IDirectDraw2_AddRef,
3422 XCAST(Release)DGA_IDirectDraw2_Release,
3423 XCAST(Compact)IDirectDraw2_Compact,
3424 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3425 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3426 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3427 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3428 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3429 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3430 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3431 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3432 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3433 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3434 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3435 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3436 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3437 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3438 XCAST(Initialize)IDirectDraw2_Initialize,
3439 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3440 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3441 DGA_IDirectDraw_SetDisplayMode,
3442 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3445 static struct IDirectDraw_VTable xlib_ddvt = {
3446 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3447 XCAST(AddRef)IDirectDraw2_AddRef,
3448 XCAST(Release)Xlib_IDirectDraw2_Release,
3449 XCAST(Compact)IDirectDraw2_Compact,
3450 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3451 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3452 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3453 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3454 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3455 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3456 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3457 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3458 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3459 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3460 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3461 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3462 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3463 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3464 XCAST(Initialize)IDirectDraw2_Initialize,
3465 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3466 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3467 Xlib_IDirectDraw_SetDisplayMode,
3468 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3471 #undef XCAST
3473 /*****************************************************************************
3474 * IDirectDraw2
3479 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
3480 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3482 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3485 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
3486 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3488 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3491 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
3492 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3494 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3495 this,ddscaps,total,free
3497 if (total) *total = this->e.dga.fb_memsize * 1024;
3498 if (free) *free = this->e.dga.fb_memsize * 1024;
3499 return DD_OK;
3502 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
3503 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3505 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3506 this,ddscaps,total,free
3508 if (total) *total = 2048 * 1024;
3509 if (free) *free = 2048 * 1024;
3510 return DD_OK;
3513 static IDirectDraw2_VTable dga_dd2vt = {
3514 DGA_IDirectDraw2_QueryInterface,
3515 IDirectDraw2_AddRef,
3516 DGA_IDirectDraw2_Release,
3517 IDirectDraw2_Compact,
3518 IDirectDraw2_CreateClipper,
3519 DGA_IDirectDraw2_CreatePalette,
3520 DGA_IDirectDraw2_CreateSurface,
3521 IDirectDraw2_DuplicateSurface,
3522 IDirectDraw2_EnumDisplayModes,
3523 IDirectDraw2_EnumSurfaces,
3524 IDirectDraw2_FlipToGDISurface,
3525 DGA_IDirectDraw2_GetCaps,
3526 DGA_IDirectDraw2_GetDisplayMode,
3527 IDirectDraw2_GetFourCCCodes,
3528 IDirectDraw2_GetGDISurface,
3529 IDirectDraw2_GetMonitorFrequency,
3530 IDirectDraw2_GetScanLine,
3531 IDirectDraw2_GetVerticalBlankStatus,
3532 IDirectDraw2_Initialize,
3533 DGA_IDirectDraw2_RestoreDisplayMode,
3534 IDirectDraw2_SetCooperativeLevel,
3535 DGA_IDirectDraw2_SetDisplayMode,
3536 IDirectDraw2_WaitForVerticalBlank,
3537 DGA_IDirectDraw2_GetAvailableVidMem
3540 static struct IDirectDraw2_VTable xlib_dd2vt = {
3541 Xlib_IDirectDraw2_QueryInterface,
3542 IDirectDraw2_AddRef,
3543 Xlib_IDirectDraw2_Release,
3544 IDirectDraw2_Compact,
3545 IDirectDraw2_CreateClipper,
3546 Xlib_IDirectDraw2_CreatePalette,
3547 Xlib_IDirectDraw2_CreateSurface,
3548 IDirectDraw2_DuplicateSurface,
3549 IDirectDraw2_EnumDisplayModes,
3550 IDirectDraw2_EnumSurfaces,
3551 IDirectDraw2_FlipToGDISurface,
3552 Xlib_IDirectDraw2_GetCaps,
3553 Xlib_IDirectDraw2_GetDisplayMode,
3554 IDirectDraw2_GetFourCCCodes,
3555 IDirectDraw2_GetGDISurface,
3556 IDirectDraw2_GetMonitorFrequency,
3557 IDirectDraw2_GetScanLine,
3558 IDirectDraw2_GetVerticalBlankStatus,
3559 IDirectDraw2_Initialize,
3560 Xlib_IDirectDraw2_RestoreDisplayMode,
3561 IDirectDraw2_SetCooperativeLevel,
3562 Xlib_IDirectDraw2_SetDisplayMode,
3563 IDirectDraw2_WaitForVerticalBlank,
3564 Xlib_IDirectDraw2_GetAvailableVidMem
3567 /*****************************************************************************
3568 * IDirectDraw4
3572 static HRESULT WINAPI IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4 this,
3573 HDC32 hdc,
3574 LPDIRECTDRAWSURFACE *lpDDS) {
3575 FIXME(ddraw, "(%p)->(%08ld,%p)\n", this, (DWORD) hdc, lpDDS);
3577 return DD_OK;
3580 static HRESULT WINAPI IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4 this) {
3581 FIXME(ddraw, "(%p)->()\n", this);
3583 return DD_OK;
3586 static HRESULT WINAPI IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4 this) {
3587 FIXME(ddraw, "(%p)->()\n", this);
3589 return DD_OK;
3592 static HRESULT WINAPI IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4 this,
3593 LPDDDEVICEIDENTIFIER lpdddi,
3594 DWORD dwFlags) {
3595 FIXME(ddraw, "(%p)->(%p,%08lx)\n", this, lpdddi, dwFlags);
3597 return DD_OK;
3600 #ifdef __GNUC__
3601 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
3602 #else
3603 # define XCAST(fun) (void*)
3604 #endif
3607 static struct IDirectDraw4_VTable dga_dd4vt = {
3608 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3609 XCAST(AddRef)IDirectDraw2_AddRef,
3610 XCAST(Release)DGA_IDirectDraw2_Release,
3611 XCAST(Compact)IDirectDraw2_Compact,
3612 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3613 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3614 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3615 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3616 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3617 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3618 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3619 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3620 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3621 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3622 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3623 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3624 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3625 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3626 XCAST(Initialize)IDirectDraw2_Initialize,
3627 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3628 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3629 XCAST(SetDisplayMode)DGA_IDirectDraw_SetDisplayMode,
3630 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3631 XCAST(GetAvailableVidMem)DGA_IDirectDraw2_GetAvailableVidMem,
3632 IDirectDraw4_GetSurfaceFromDC,
3633 IDirectDraw4_RestoreAllSurfaces,
3634 IDirectDraw4_TestCooperativeLevel,
3635 IDirectDraw4_GetDeviceIdentifier
3638 static struct IDirectDraw4_VTable xlib_dd4vt = {
3639 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3640 XCAST(AddRef)IDirectDraw2_AddRef,
3641 XCAST(Release)Xlib_IDirectDraw2_Release,
3642 XCAST(Compact)IDirectDraw2_Compact,
3643 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3644 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3645 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3646 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3647 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
3648 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3649 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3650 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3651 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3652 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3653 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3654 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3655 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3656 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3657 XCAST(Initialize)IDirectDraw2_Initialize,
3658 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3659 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3660 XCAST(SetDisplayMode)Xlib_IDirectDraw_SetDisplayMode,
3661 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3662 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2_GetAvailableVidMem,
3663 IDirectDraw4_GetSurfaceFromDC,
3664 IDirectDraw4_RestoreAllSurfaces,
3665 IDirectDraw4_TestCooperativeLevel,
3666 IDirectDraw4_GetDeviceIdentifier
3669 #undef XCAST
3671 /******************************************************************************
3672 * DirectDrawCreate
3675 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
3677 LRESULT ret;
3678 LPDIRECTDRAW ddraw = NULL;
3679 DWORD lastError;
3681 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
3683 SetLastError( ERROR_SUCCESS );
3684 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
3685 if( (!ddraw) &&
3686 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
3689 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
3692 if( ddraw )
3694 /* Perform any special direct draw functions */
3695 if (msg==WM_PAINT)
3696 ddraw->d.paintable = 1;
3698 /* Now let the application deal with the rest of this */
3699 if( ddraw->d.mainWindow )
3702 /* Don't think that we actually need to call this but...
3703 might as well be on the safe side of things... */
3705 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
3706 it should be the procedures of our fake window that gets called
3707 instead of those of the window provided by the application.
3708 And with this patch, mouse clicks work with Monkey Island III
3709 - Lionel */
3710 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
3712 if( !ret )
3714 /* We didn't handle the message - give it to the application */
3715 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
3716 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
3717 ddraw->d.mainWindow, msg, wParam, lParam );
3721 } else {
3722 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
3726 else
3728 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
3731 return ret;
3734 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
3735 #ifdef HAVE_LIBXXF86DGA
3736 int memsize,banksize,width,major,minor,flags,height;
3737 char *addr;
3738 int fd;
3740 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
3741 if ((fd = open("/dev/mem", O_RDWR)) != -1)
3742 close(fd);
3744 if (fd == -1) {
3745 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
3746 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
3747 return E_UNEXPECTED;
3749 if (!DDRAW_DGA_Available()) {
3750 TRACE(ddraw,"No XF86DGA detected.\n");
3751 return DDERR_GENERIC;
3753 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3754 (*lplpDD)->lpvtbl = &dga_ddvt;
3755 (*lplpDD)->ref = 1;
3756 TSXF86DGAQueryVersion(display,&major,&minor);
3757 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
3758 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
3759 if (!(flags & XF86DGADirectPresent))
3760 MSG("direct video is NOT PRESENT.\n");
3761 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
3762 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
3763 addr,width,banksize,memsize
3765 (*lplpDD)->e.dga.fb_width = width;
3766 (*lplpDD)->d.width = width;
3767 (*lplpDD)->e.dga.fb_addr = addr;
3768 (*lplpDD)->e.dga.fb_memsize = memsize;
3769 (*lplpDD)->e.dga.fb_banksize = banksize;
3771 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
3772 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3773 (*lplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3774 #ifdef DIABLO_HACK
3775 (*lplpDD)->e.dga.vpmask = 1;
3776 #else
3777 (*lplpDD)->e.dga.vpmask = 0;
3778 #endif
3780 /* just assume the default depth is the DGA depth too */
3781 (*lplpDD)->d.screen_depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3782 (*lplpDD)->d.depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3783 #ifdef RESTORE_SIGNALS
3784 SIGNAL_InitHandlers();
3785 #endif
3787 return DD_OK;
3788 #else /* defined(HAVE_LIBXXF86DGA) */
3789 return DDERR_INVALIDDIRECTDRAWGUID;
3790 #endif /* defined(HAVE_LIBXXF86DGA) */
3793 BOOL32
3794 DDRAW_XSHM_Available(void)
3796 #ifdef HAVE_LIBXXSHM
3797 if (TSXShmQueryExtension(display))
3799 int major, minor;
3800 Bool shpix;
3802 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
3803 return 1;
3804 else
3805 return 0;
3807 else
3808 return 0;
3809 #else
3810 return 0;
3811 #endif
3814 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
3816 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
3817 (*lplpDD)->lpvtbl = &xlib_ddvt;
3818 (*lplpDD)->ref = 1;
3819 (*lplpDD)->d.drawable = 0; /* in SetDisplayMode */
3821 /* At DirectDraw creation, the depth is the default depth */
3822 (*lplpDD)->d.depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3823 (*lplpDD)->d.screen_depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
3824 (*lplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3825 (*lplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3827 #ifdef HAVE_LIBXXSHM
3828 /* Test if XShm is available. */
3829 if (((*lplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
3830 TRACE(ddraw, "Using XShm extension.\n");
3831 #endif
3833 return DD_OK;
3836 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
3837 char xclsid[50];
3838 WNDCLASS32A wc;
3839 WND* pParentWindow;
3840 HRESULT ret;
3842 if (HIWORD(lpGUID))
3843 WINE_StringFromCLSID(lpGUID,xclsid);
3844 else {
3845 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
3846 lpGUID = NULL;
3849 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
3851 if (!lpGUID) {
3852 /* if they didn't request a particular interface, use the best
3853 * supported one */
3854 if (DDRAW_DGA_Available())
3855 lpGUID = &DGA_DirectDraw_GUID;
3856 else
3857 lpGUID = &XLIB_DirectDraw_GUID;
3860 wc.style = CS_GLOBALCLASS;
3861 wc.lpfnWndProc = Xlib_DDWndProc;
3862 wc.cbClsExtra = 0;
3863 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
3864 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
3866 /* We can be a child of the desktop since we're really important */
3867 pParentWindow = WIN_GetDesktop();
3868 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
3869 wc.hInstance = 0;
3871 wc.hIcon = 0;
3872 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
3873 wc.hbrBackground= NULL_BRUSH;
3874 wc.lpszMenuName = 0;
3875 wc.lpszClassName= "WINE_DirectDraw";
3876 RegisterClass32A(&wc);
3878 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
3879 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
3880 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
3881 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
3882 else
3883 goto err;
3886 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
3887 return ret;
3889 err:
3890 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
3891 return DDERR_INVALIDDIRECTDRAWGUID;