- some clean up in handling of depth
[wine/multimedia.git] / graphics / ddraw.c
blob54d5627d548217ec1b0ce3c3b21fbdc18380124a
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 typedef int INT32;
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 BOOL
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 DirectDrawEnumerateA(LPDDENUMCALLBACKA ddenumproc,LPVOID data) {
132 TRACE(ddraw, "(%p,%p)\n", ddenumproc, data);
134 if (DDRAW_DGA_Available()) {
135 TRACE(ddraw, "Enumerating DGA interface\n");
136 if (!ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data))
137 return DD_OK;
140 TRACE(ddraw, "Enumerating Xlib interface\n");
141 if (!ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data))
142 return DD_OK;
144 TRACE(ddraw, "Enumerating Default interface\n");
145 if (!ddenumproc(NULL,"WINE (default)","display",data))
146 return DD_OK;
148 return DD_OK;
151 HRESULT WINAPI
152 DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA ddenumproc,LPVOID data, DWORD dwFlags) {
153 TRACE(ddraw, "(%p,%p, %08lx)\n", ddenumproc, data, dwFlags);
155 if (TRACE_ON(ddraw)) {
156 DUMP(" Flags : ");
157 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
158 DUMP("DDENUM_ATTACHEDSECONDARYDEVICES ");
159 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
160 DUMP("DDENUM_DETACHEDSECONDARYDEVICES ");
161 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
162 DUMP("DDENUM_NONDISPLAYDEVICES ");
163 DUMP("\n");
166 if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
167 /* For the moment, Wine does not support any 3D only accelerators */
168 return DD_OK;
171 if (DDRAW_DGA_Available()) {
172 TRACE(ddraw, "Enumerating DGA interface\n");
173 if (!ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data, NULL))
174 return DD_OK;
177 TRACE(ddraw, "Enumerating Xlib interface\n");
178 if (!ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data, NULL))
179 return DD_OK;
181 TRACE(ddraw, "Enumerating Default interface\n");
182 if (!ddenumproc(NULL,"WINE (default)","display",data, NULL))
183 return DD_OK;
185 return DD_OK;
188 /* What is this doing here? */
189 HRESULT WINAPI
190 DSoundHelp(DWORD x,DWORD y,DWORD z) {
191 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
192 return 0;
196 /******************************************************************************
197 * internal helper functions
199 static void _dump_DDBLTFX(DWORD flagmask) {
200 int i;
201 const struct {
202 DWORD mask;
203 char *name;
204 } flags[] = {
205 #define FE(x) { x, #x},
206 FE(DDBLTFX_ARITHSTRETCHY)
207 FE(DDBLTFX_MIRRORLEFTRIGHT)
208 FE(DDBLTFX_MIRRORUPDOWN)
209 FE(DDBLTFX_NOTEARING)
210 FE(DDBLTFX_ROTATE180)
211 FE(DDBLTFX_ROTATE270)
212 FE(DDBLTFX_ROTATE90)
213 FE(DDBLTFX_ZBUFFERRANGE)
214 FE(DDBLTFX_ZBUFFERBASEDEST)
216 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
217 if (flags[i].mask & flagmask) {
218 DUMP("%s ",flags[i].name);
221 DUMP("\n");
225 static void _dump_DDBLTFAST(DWORD flagmask) {
226 int i;
227 const struct {
228 DWORD mask;
229 char *name;
230 } flags[] = {
231 #define FE(x) { x, #x},
232 FE(DDBLTFAST_NOCOLORKEY)
233 FE(DDBLTFAST_SRCCOLORKEY)
234 FE(DDBLTFAST_DESTCOLORKEY)
235 FE(DDBLTFAST_WAIT)
237 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
238 if (flags[i].mask & flagmask)
239 DUMP("%s ",flags[i].name);
240 DUMP("\n");
243 static void _dump_DDBLT(DWORD flagmask) {
244 int i;
245 const struct {
246 DWORD mask;
247 char *name;
248 } flags[] = {
249 #define FE(x) { x, #x},
250 FE(DDBLT_ALPHADEST)
251 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
252 FE(DDBLT_ALPHADESTNEG)
253 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
254 FE(DDBLT_ALPHAEDGEBLEND)
255 FE(DDBLT_ALPHASRC)
256 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
257 FE(DDBLT_ALPHASRCNEG)
258 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
259 FE(DDBLT_ASYNC)
260 FE(DDBLT_COLORFILL)
261 FE(DDBLT_DDFX)
262 FE(DDBLT_DDROPS)
263 FE(DDBLT_KEYDEST)
264 FE(DDBLT_KEYDESTOVERRIDE)
265 FE(DDBLT_KEYSRC)
266 FE(DDBLT_KEYSRCOVERRIDE)
267 FE(DDBLT_ROP)
268 FE(DDBLT_ROTATIONANGLE)
269 FE(DDBLT_ZBUFFER)
270 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
271 FE(DDBLT_ZBUFFERDESTOVERRIDE)
272 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
273 FE(DDBLT_ZBUFFERSRCOVERRIDE)
274 FE(DDBLT_WAIT)
275 FE(DDBLT_DEPTHFILL)
277 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
278 if (flags[i].mask & flagmask)
279 DUMP("%s ",flags[i].name);
280 DUMP("\n");
283 static void _dump_DDSCAPS(DWORD flagmask) {
284 int i;
285 const struct {
286 DWORD mask;
287 char *name;
288 } flags[] = {
289 #define FE(x) { x, #x},
290 FE(DDSCAPS_RESERVED1)
291 FE(DDSCAPS_ALPHA)
292 FE(DDSCAPS_BACKBUFFER)
293 FE(DDSCAPS_COMPLEX)
294 FE(DDSCAPS_FLIP)
295 FE(DDSCAPS_FRONTBUFFER)
296 FE(DDSCAPS_OFFSCREENPLAIN)
297 FE(DDSCAPS_OVERLAY)
298 FE(DDSCAPS_PALETTE)
299 FE(DDSCAPS_PRIMARYSURFACE)
300 FE(DDSCAPS_PRIMARYSURFACELEFT)
301 FE(DDSCAPS_SYSTEMMEMORY)
302 FE(DDSCAPS_TEXTURE)
303 FE(DDSCAPS_3DDEVICE)
304 FE(DDSCAPS_VIDEOMEMORY)
305 FE(DDSCAPS_VISIBLE)
306 FE(DDSCAPS_WRITEONLY)
307 FE(DDSCAPS_ZBUFFER)
308 FE(DDSCAPS_OWNDC)
309 FE(DDSCAPS_LIVEVIDEO)
310 FE(DDSCAPS_HWCODEC)
311 FE(DDSCAPS_MODEX)
312 FE(DDSCAPS_MIPMAP)
313 FE(DDSCAPS_RESERVED2)
314 FE(DDSCAPS_ALLOCONLOAD)
315 FE(DDSCAPS_VIDEOPORT)
316 FE(DDSCAPS_LOCALVIDMEM)
317 FE(DDSCAPS_NONLOCALVIDMEM)
318 FE(DDSCAPS_STANDARDVGAMODE)
319 FE(DDSCAPS_OPTIMIZED)
321 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
322 if (flags[i].mask & flagmask)
323 DUMP("%s ",flags[i].name);
324 DUMP("\n");
327 static void _dump_DDSD(DWORD flagmask) {
328 int i;
329 const struct {
330 DWORD mask;
331 char *name;
332 } flags[] = {
333 FE(DDSD_CAPS)
334 FE(DDSD_HEIGHT)
335 FE(DDSD_WIDTH)
336 FE(DDSD_PITCH)
337 FE(DDSD_BACKBUFFERCOUNT)
338 FE(DDSD_ZBUFFERBITDEPTH)
339 FE(DDSD_ALPHABITDEPTH)
340 FE(DDSD_PIXELFORMAT)
341 FE(DDSD_CKDESTOVERLAY)
342 FE(DDSD_CKDESTBLT)
343 FE(DDSD_CKSRCOVERLAY)
344 FE(DDSD_CKSRCBLT)
345 FE(DDSD_MIPMAPCOUNT)
346 FE(DDSD_REFRESHRATE)
347 FE(DDSD_LINEARSIZE)
348 FE(DDSD_LPSURFACE)
350 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
351 if (flags[i].mask & flagmask)
352 DUMP("%s ",flags[i].name);
353 DUMP("\n");
356 static void _dump_DDCOLORKEY(DWORD flagmask) {
357 int i;
358 const struct {
359 DWORD mask;
360 char *name;
361 } flags[] = {
362 #define FE(x) { x, #x},
363 FE(DDPF_ALPHAPIXELS)
364 FE(DDPF_ALPHA)
365 FE(DDPF_FOURCC)
366 FE(DDPF_PALETTEINDEXED4)
367 FE(DDPF_PALETTEINDEXEDTO8)
368 FE(DDPF_PALETTEINDEXED8)
369 FE(DDPF_RGB)
370 FE(DDPF_COMPRESSED)
371 FE(DDPF_RGBTOYUV)
372 FE(DDPF_YUV)
373 FE(DDPF_ZBUFFER)
374 FE(DDPF_PALETTEINDEXED1)
375 FE(DDPF_PALETTEINDEXED2)
376 FE(DDPF_ZPIXELS)
378 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
379 if (flags[i].mask & flagmask)
380 DUMP("%s ",flags[i].name);
381 DUMP("\n");
384 static void _dump_paletteformat(DWORD dwFlags) {
385 int i;
386 const struct {
387 DWORD mask;
388 char *name;
389 } flags[] = {
390 #define FE(x) { x, #x},
391 FE(DDPCAPS_4BIT)
392 FE(DDPCAPS_8BITENTRIES)
393 FE(DDPCAPS_8BIT)
394 FE(DDPCAPS_INITIALIZE)
395 FE(DDPCAPS_PRIMARYSURFACE)
396 FE(DDPCAPS_PRIMARYSURFACELEFT)
397 FE(DDPCAPS_ALLOW256)
398 FE(DDPCAPS_VSYNC)
399 FE(DDPCAPS_1BIT)
400 FE(DDPCAPS_2BIT)
401 FE(DDPCAPS_ALPHA)
403 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
404 if (flags[i].mask & dwFlags)
405 DUMP("%s ",flags[i].name);
406 DUMP("\n");
409 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
410 DUMP("Size : %ld\n", pf->dwSize);
411 if (pf->dwFlags)
412 _dump_DDCOLORKEY(pf->dwFlags);
413 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
414 DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
415 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
416 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
419 /******************************************************************************
420 * IDirectDrawSurface methods
422 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
423 * DDS and DDS2 use those functions. (Function calls did not change (except
424 * using different DirectDrawSurfaceX version), just added flags and functions)
426 static HRESULT WINAPI IDirectDrawSurface4_Lock(
427 LPDIRECTDRAWSURFACE4 this,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
429 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
430 this,lprect,lpddsd,flags,(DWORD)hnd);
431 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
432 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
433 this,lprect,lpddsd,flags,(DWORD)hnd);
435 /* First, copy the Surface description */
436 *lpddsd = this->s.surface_desc;
437 TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
438 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
440 /* If asked only for a part, change the surface pointer */
441 if (lprect) {
442 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
443 lprect->top,lprect->left,lprect->bottom,lprect->right
445 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
446 (lprect->top*this->s.surface_desc.lPitch) +
447 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
448 } else {
449 assert(this->s.surface_desc.y.lpSurface);
451 return DD_OK;
454 static HRESULT WINAPI DGA_IDirectDrawSurface4_Unlock(
455 LPDIRECTDRAWSURFACE4 this,LPVOID surface
457 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
458 return DD_OK;
461 static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4 this) {
462 if (this->s.ddraw->d.pixel_convert != NULL)
463 this->s.ddraw->d.pixel_convert(this->s.surface_desc.y.lpSurface,
464 this->t.xlib.image->data,
465 this->s.surface_desc.dwWidth,
466 this->s.surface_desc.dwHeight,
467 this->s.surface_desc.lPitch,
468 this->s.palette);
470 #ifdef HAVE_LIBXXSHM
471 if (this->s.ddraw->e.xlib.xshm_active)
472 TSXShmPutImage(display,
473 this->s.ddraw->d.drawable,
474 DefaultGCOfScreen(X11DRV_GetXScreen()),
475 this->t.xlib.image,
476 0, 0, 0, 0,
477 this->t.xlib.image->width,
478 this->t.xlib.image->height,
479 False);
480 else
481 #endif
482 TSXPutImage( display,
483 this->s.ddraw->d.drawable,
484 DefaultGCOfScreen(X11DRV_GetXScreen()),
485 this->t.xlib.image,
486 0, 0, 0, 0,
487 this->t.xlib.image->width,
488 this->t.xlib.image->height);
491 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Unlock(
492 LPDIRECTDRAWSURFACE4 this,LPVOID surface)
494 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
496 if (!this->s.ddraw->d.paintable)
497 return DD_OK;
499 /* Only redraw the screen when unlocking the buffer that is on screen */
500 if ((this->t.xlib.image != NULL) &&
501 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
502 Xlib_copy_surface_on_screen(this);
504 if (this->s.palette && this->s.palette->cm)
505 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
508 return DD_OK;
511 static HRESULT WINAPI DGA_IDirectDrawSurface4_Flip(
512 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
514 #ifdef HAVE_LIBXXF86DGA
515 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
516 if (!flipto) {
517 if (this->s.backbuffer)
518 flipto = this->s.backbuffer;
519 else
520 flipto = this;
522 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
524 if (flipto->s.palette && flipto->s.palette->cm) {
525 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
527 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
529 if (flipto!=this) {
530 int tmp;
531 LPVOID ptmp;
533 tmp = this->t.dga.fb_height;
534 this->t.dga.fb_height = flipto->t.dga.fb_height;
535 flipto->t.dga.fb_height = tmp;
537 ptmp = this->s.surface_desc.y.lpSurface;
538 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
539 flipto->s.surface_desc.y.lpSurface = ptmp;
541 return DD_OK;
542 #else /* defined(HAVE_LIBXXF86DGA) */
543 return E_UNEXPECTED;
544 #endif /* defined(HAVE_LIBXXF86DGA) */
547 static HRESULT WINAPI Xlib_IDirectDrawSurface4_Flip(
548 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
550 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
551 if (!this->s.ddraw->d.paintable)
552 return DD_OK;
554 if (!flipto) {
555 if (this->s.backbuffer)
556 flipto = this->s.backbuffer;
557 else
558 flipto = this;
561 Xlib_copy_surface_on_screen(this);
563 if (flipto->s.palette && flipto->s.palette->cm) {
564 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,flipto->s.palette->cm);
566 if (flipto!=this) {
567 XImage *tmp;
568 LPVOID *surf;
569 tmp = this->t.xlib.image;
570 this->t.xlib.image = flipto->t.xlib.image;
571 flipto->t.xlib.image = tmp;
572 surf = this->s.surface_desc.y.lpSurface;
573 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
574 flipto->s.surface_desc.y.lpSurface = surf;
576 return DD_OK;
580 /* The IDirectDrawSurface4::SetPalette method attaches the specified
581 * DirectDrawPalette object to a surface. The surface uses this palette for all
582 * subsequent operations. The palette change takes place immediately.
584 static HRESULT WINAPI Xlib_IDirectDrawSurface4_SetPalette(
585 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
587 int i;
588 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
590 if (pal == NULL) {
591 if( this->s.palette != NULL )
592 this->s.palette->lpvtbl->fnRelease( this->s.palette );
593 this->s.palette = pal;
595 return DD_OK;
598 if( !(pal->cm) && (this->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
600 pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable,
601 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
603 if (!Options.managed)
604 TSXInstallColormap(display,pal->cm);
606 for (i=0;i<256;i++) {
607 XColor xc;
609 xc.red = pal->palents[i].peRed<<8;
610 xc.blue = pal->palents[i].peBlue<<8;
611 xc.green = pal->palents[i].peGreen<<8;
612 xc.flags = DoRed|DoBlue|DoGreen;
613 xc.pixel = i;
614 TSXStoreColor(display,pal->cm,&xc);
616 TSXInstallColormap(display,pal->cm);
619 /* According to spec, we are only supposed to
620 * AddRef if this is not the same palette.
622 if( this->s.palette != pal )
624 if( pal != NULL )
625 pal->lpvtbl->fnAddRef( pal );
626 if( this->s.palette != NULL )
627 this->s.palette->lpvtbl->fnRelease( this->s.palette );
628 this->s.palette = pal;
630 /* I think that we need to attach it to all backbuffers...*/
631 if( this->s.backbuffer ) {
632 if( this->s.backbuffer->s.palette )
633 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
634 this->s.backbuffer->s.palette );
635 this->s.backbuffer->s.palette = pal;
636 if( pal )
637 pal->lpvtbl->fnAddRef( pal );
639 /* Perform the refresh */
640 TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm);
642 return DD_OK;
645 static HRESULT WINAPI DGA_IDirectDrawSurface4_SetPalette(
646 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal
648 TRACE(ddraw,"(%p)->(%p)\n",this,pal);
649 #ifdef HAVE_LIBXXF86DGA
650 /* According to spec, we are only supposed to
651 * AddRef if this is not the same palette.
653 if( this->s.palette != pal )
655 if( pal != NULL )
656 pal->lpvtbl->fnAddRef( pal );
657 if( this->s.palette != NULL )
658 this->s.palette->lpvtbl->fnRelease( this->s.palette );
659 this->s.palette = pal;
661 /* I think that we need to attach it to all backbuffers...*/
662 if( this->s.backbuffer ) {
663 if( this->s.backbuffer->s.palette )
664 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
665 this->s.backbuffer->s.palette = pal;
666 if( pal ) pal->lpvtbl->fnAddRef( pal );
668 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
670 return DD_OK;
671 #else /* defined(HAVE_LIBXXF86DGA) */
672 return E_UNEXPECTED;
673 #endif /* defined(HAVE_LIBXXF86DGA) */
678 static HRESULT WINAPI IDirectDrawSurface4_Blt(
679 LPDIRECTDRAWSURFACE4 this,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
681 RECT xdst,xsrc;
682 DDSURFACEDESC ddesc,sdesc;
683 int i,j;
685 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
686 this,rdst,src,rsrc,dwFlags,lpbltfx);
688 if (src != NULL)
689 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
690 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
692 if (TRACE_ON(ddraw)) {
693 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
694 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
695 TRACE(ddraw,"\tflags: "); _dump_DDBLT(dwFlags);
696 if (dwFlags & DDBLT_DDFX) {
697 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
701 if (rdst) {
702 memcpy(&xdst,rdst,sizeof(xdst));
703 } else {
704 xdst.top = 0;
705 xdst.bottom = ddesc.dwHeight;
706 xdst.left = 0;
707 xdst.right = ddesc.dwWidth;
710 if (rsrc) {
711 memcpy(&xsrc,rsrc,sizeof(xsrc));
712 } else {
713 if (src) {
714 xsrc.top = 0;
715 xsrc.bottom = sdesc.dwHeight;
716 xsrc.left = 0;
717 xsrc.right = sdesc.dwWidth;
718 } else {
719 memset(&xsrc,0,sizeof(xsrc));
723 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
725 /* First, all the 'source-less' blits */
726 if (dwFlags & DDBLT_COLORFILL) {
727 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
728 LPBYTE xline,xpixel;
730 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
731 for (i=xdst.top;i<xdst.bottom;i++) {
732 xpixel = xline+bpp*xdst.left;
734 for (j=xdst.left;j<xdst.right;j++) {
735 /* FIXME: this only works on little endian
736 * architectures, where DWORD starts with low
737 * byte first!
739 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
740 xpixel += bpp;
742 xline += ddesc.lPitch;
744 dwFlags &= ~(DDBLT_COLORFILL);
747 if (dwFlags & DDBLT_DEPTHFILL) {
748 #ifdef HAVE_MESAGL
749 GLboolean ztest;
751 /* Clears the screen */
752 TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
753 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
754 glGetBooleanv(GL_DEPTH_TEST, &ztest);
755 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
756 glClear(GL_DEPTH_BUFFER_BIT);
757 glDepthMask(ztest);
759 dwFlags &= ~(DDBLT_DEPTHFILL);
760 #endif HAVE_MESAGL
763 if (!src) {
764 if (dwFlags) {
765 TRACE(ddraw,"\t(src=NULL):Unsupported flags: "); _dump_DDBLT(dwFlags);
767 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
768 return DD_OK;
771 /* Now the 'with source' blits */
773 /* Standard 'full-surface' blit without special effects */
774 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
775 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
776 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
777 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
778 !dwFlags
780 memcpy(ddesc.y.lpSurface,
781 sdesc.y.lpSurface,
782 ddesc.dwHeight * ddesc.lPitch);
783 } else {
784 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
785 int srcheight = xsrc.bottom - xsrc.top;
786 int srcwidth = xsrc.right - xsrc.left;
787 int dstheight = xdst.bottom - xdst.top;
788 int dstwidth = xdst.right - xdst.left;
789 int width = (xsrc.right - xsrc.left) * bpp;
790 int h;
792 /* Sanity check for rectangle sizes */
793 if ((srcheight != dstheight) || (srcwidth != dstwidth)) {
794 int x, y;
796 /* I think we should do a Blit with 'stretching' here....
797 Tomb Raider II uses this to display the background during the menu selection
798 when the screen resolution is != than 640x480 */
799 TRACE(ddraw, "Blt with stretching\n");
801 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
802 if (bpp == 1) {
803 /* In this case, we cannot do any anti-aliasing */
804 if(dwFlags & DDBLT_KEYSRC) {
805 for (y = xdst.top; y < xdst.bottom; y++) {
806 for (x = xdst.left; x < xdst.right; x++) {
807 double sx, sy;
808 unsigned char tmp;
809 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
810 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
812 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
813 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
815 tmp = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
817 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
818 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
819 dbuf[(y * ddesc.lPitch) + x] = tmp;
822 } else {
823 for (y = xdst.top; y < xdst.bottom; y++) {
824 for (x = xdst.left; x < xdst.right; x++) {
825 double sx, sy;
826 unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface;
827 unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface;
829 sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left;
830 sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top;
832 dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)];
836 } else {
837 FIXME(ddraw, "Not done yet for depth != 8\n");
839 } else {
840 /* Same size => fast blit */
841 if (dwFlags & DDBLT_KEYSRC) {
842 switch (bpp) {
843 case 1: {
844 unsigned char tmp,*psrc,*pdst;
845 int h,i;
847 for (h = 0; h < srcheight; h++) {
848 psrc=sdesc.y.lpSurface +
849 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
850 pdst=ddesc.y.lpSurface +
851 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
852 for(i=0;i<srcwidth;i++) {
853 tmp=*(psrc + i);
854 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
855 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
856 *(pdst + i)=tmp;
859 dwFlags&=~(DDBLT_KEYSRC);
860 } break;
862 case 2: {
863 unsigned short tmp,*psrc,*pdst;
864 int h,i;
866 for (h = 0; h < srcheight; h++) {
867 psrc=sdesc.y.lpSurface +
868 ((h + xsrc.top) * sdesc.lPitch) + xsrc.left;
869 pdst=ddesc.y.lpSurface +
870 ((h + xdst.top) * ddesc.lPitch) + xdst.left;
871 for(i=0;i<srcwidth;i++) {
872 tmp=*(psrc + i);
873 if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) ||
874 (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue))
875 *(pdst + i)=tmp;
878 dwFlags&=~(DDBLT_KEYSRC);
879 } break;
881 default:
882 FIXME(ddraw, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
884 } else {
885 /* Non-stretching Blt without color keying */
886 for (h = 0; h < srcheight; h++) {
887 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
888 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
889 width);
895 if (dwFlags && FIXME_ON(ddraw)) {
896 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
899 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
900 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
902 return DD_OK;
905 static HRESULT WINAPI IDirectDrawSurface4_BltFast(
906 LPDIRECTDRAWSURFACE4 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
908 int i,bpp,w,h;
909 DDSURFACEDESC ddesc,sdesc;
911 if (1 || TRACE_ON(ddraw)) {
912 FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
913 this,dstx,dsty,src,rsrc,trans
915 FIXME(ddraw," trans:");
916 if (FIXME_ON(ddraw))
917 _dump_DDBLTFAST(trans);
918 FIXME(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
920 /* We need to lock the surfaces, or we won't get refreshes when done. */
921 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
922 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
923 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
924 h=rsrc->bottom-rsrc->top;
925 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
926 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
927 if (h<0) h=0;
928 w=rsrc->right-rsrc->left;
929 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
930 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
931 if (w<0) w=0;
933 for (i=0;i<h;i++) {
934 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
935 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
936 w*bpp
939 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
940 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
941 return DD_OK;
944 static HRESULT WINAPI IDirectDrawSurface4_BltBatch(
945 LPDIRECTDRAWSURFACE4 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
947 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
948 this,ddbltbatch,x,y
950 return DD_OK;
953 static HRESULT WINAPI IDirectDrawSurface4_GetCaps(
954 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS caps
956 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
957 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
958 return DD_OK;
961 static HRESULT WINAPI IDirectDrawSurface4_GetSurfaceDesc(
962 LPDIRECTDRAWSURFACE4 this,LPDDSURFACEDESC ddsd
963 ) {
964 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
965 this,ddsd);
967 /* Simply copy the surface description stored in the object */
968 *ddsd = this->s.surface_desc;
970 if (TRACE_ON(ddraw)) {
971 DUMP(" flags: ");
972 _dump_DDSD(ddsd->dwFlags);
973 if (ddsd->dwFlags & DDSD_CAPS) {
974 DUMP(" caps: ");
975 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
977 if (ddsd->dwFlags & DDSD_PIXELFORMAT) {
978 DUMP(" pixel format : \n");
979 _dump_pixelformat(&(ddsd->ddpfPixelFormat));
983 return DD_OK;
986 static ULONG WINAPI IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4 this) {
987 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
989 return ++(this->ref);
992 static ULONG WINAPI DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
993 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
995 #ifdef HAVE_LIBXXF86DGA
996 if (!--(this->ref)) {
997 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
998 /* clear out of surface list */
999 if (this->t.dga.fb_height == -1) {
1000 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1001 } else {
1002 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
1005 /* Free the backbuffer */
1006 if (this->s.backbuffer)
1007 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1009 HeapFree(GetProcessHeap(),0,this);
1010 return 0;
1012 #endif /* defined(HAVE_LIBXXF86DGA) */
1013 return this->ref;
1016 static ULONG WINAPI Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 this) {
1017 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1019 if (!--(this->ref)) {
1020 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
1022 if( this->s.backbuffer )
1023 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
1025 if (this->t.xlib.image != NULL) {
1026 if (this->s.ddraw->d.pixel_convert != NULL) {
1027 /* In pixel conversion mode, there are two buffers to release... */
1028 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1030 #ifdef HAVE_LIBXXSHM
1031 if (this->s.ddraw->e.xlib.xshm_active) {
1032 TSXShmDetach(display, &(this->t.xlib.shminfo));
1033 TSXDestroyImage(this->t.xlib.image);
1034 shmdt(this->t.xlib.shminfo.shmaddr);
1035 } else {
1036 #endif
1037 HeapFree(GetProcessHeap(),0,this->t.xlib.image->data);
1038 this->t.xlib.image->data = NULL;
1039 TSXDestroyImage(this->t.xlib.image);
1040 #ifdef HAVE_LIBXXSHM
1042 #endif
1044 } else {
1045 this->t.xlib.image->data = NULL;
1047 #ifdef HAVE_LIBXXSHM
1048 if (this->s.ddraw->e.xlib.xshm_active) {
1049 TSXShmDetach(display, &(this->t.xlib.shminfo));
1050 TSXDestroyImage(this->t.xlib.image);
1051 shmdt(this->t.xlib.shminfo.shmaddr);
1052 } else {
1053 #endif
1054 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1055 TSXDestroyImage(this->t.xlib.image);
1056 #ifdef HAVE_LIBXXSHM
1058 #endif
1061 this->t.xlib.image = 0;
1062 } else {
1063 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
1066 if (this->s.palette)
1067 this->s.palette->lpvtbl->fnRelease(this->s.palette);
1069 HeapFree(GetProcessHeap(),0,this);
1070 return 0;
1073 return this->ref;
1076 static HRESULT WINAPI IDirectDrawSurface4_GetAttachedSurface(
1077 LPDIRECTDRAWSURFACE4 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1079 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1080 this, lpddsd, lpdsf);
1082 if (TRACE_ON(ddraw)) {
1083 TRACE(ddraw," caps ");
1084 _dump_DDSCAPS(lpddsd->dwCaps);
1087 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1088 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1089 return E_FAIL;
1092 /* FIXME: should handle more than one backbuffer */
1093 *lpdsf = this->s.backbuffer;
1095 if( this->s.backbuffer )
1096 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
1098 return DD_OK;
1101 static HRESULT WINAPI IDirectDrawSurface4_Initialize(
1102 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1104 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
1106 return DDERR_ALREADYINITIALIZED;
1109 static HRESULT WINAPI IDirectDrawSurface4_GetPixelFormat(
1110 LPDIRECTDRAWSURFACE4 this,LPDDPIXELFORMAT pf
1112 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
1114 *pf = this->s.surface_desc.ddpfPixelFormat;
1116 return DD_OK;
1119 static HRESULT WINAPI IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4 this,DWORD dwFlags) {
1120 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
1121 return DD_OK;
1124 static HRESULT WINAPI IDirectDrawSurface4_GetOverlayPosition(
1125 LPDIRECTDRAWSURFACE4 this,LPLONG x1,LPLONG x2
1127 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
1128 return DD_OK;
1131 static HRESULT WINAPI IDirectDrawSurface4_SetClipper(
1132 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWCLIPPER clipper
1134 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
1135 return DD_OK;
1138 static HRESULT WINAPI IDirectDrawSurface4_AddAttachedSurface(
1139 LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 surf
1141 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
1143 this->lpvtbl->fnAddRef(this);
1145 /* This hack will be enough for the moment */
1146 if (this->s.backbuffer == NULL)
1147 this->s.backbuffer = surf;
1148 return DD_OK;
1151 static HRESULT WINAPI IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4 this,HDC* lphdc) {
1152 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
1153 *lphdc = BeginPaint(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1154 return DD_OK;
1157 static HRESULT WINAPI IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4 this,HDC hdc) {
1158 DDSURFACEDESC desc;
1159 DWORD x, y;
1161 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
1162 EndPaint(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
1164 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1165 I fill it with 'dummy' values to have something on the screen */
1166 this->lpvtbl->fnLock(this,NULL,&desc,0,0);
1167 for (y = 0; y < desc.dwHeight; y++) {
1168 for (x = 0; x < desc.dwWidth; x++) {
1169 ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) this + x + y;
1172 this->lpvtbl->fnUnlock(this,NULL);
1174 return DD_OK;
1178 static HRESULT WINAPI IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4 this,REFIID refiid,LPVOID *obj) {
1179 char xrefiid[50];
1181 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1182 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1184 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1185 * the same interface. And IUnknown does that too of course.
1187 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1188 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1189 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1190 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1191 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1193 *obj = this;
1194 this->lpvtbl->fnAddRef(this);
1196 TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj);
1198 return S_OK;
1200 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1202 /* Texture interface */
1203 *obj = d3dtexture2_create(this);
1204 this->lpvtbl->fnAddRef(this);
1206 TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj);
1208 return S_OK;
1210 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1212 /* Texture interface */
1213 *obj = d3dtexture_create(this);
1214 this->lpvtbl->fnAddRef(this);
1216 TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj);
1218 return S_OK;
1220 else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj))
1222 /* It is the OpenGL Direct3D Device */
1223 this->lpvtbl->fnAddRef(this);
1225 TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj);
1227 return S_OK;
1230 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1231 return OLE_E_ENUM_NOMORE;
1234 static HRESULT WINAPI IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4 this) {
1235 TRACE(ddraw,"(%p)->(), stub!\n",this);
1236 return DD_OK; /* hmm */
1239 static HRESULT WINAPI IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1240 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
1241 return DD_OK;
1244 static HRESULT WINAPI IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4 this) {
1245 FIXME(ddraw,"(%p)->(),stub!\n",this);
1246 return DD_OK;
1249 static HRESULT WINAPI IDirectDrawSurface4_SetColorKey(
1250 LPDIRECTDRAWSURFACE4 this, DWORD dwFlags, LPDDCOLORKEY ckey )
1252 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey);
1254 if( dwFlags & DDCKEY_SRCBLT )
1256 dwFlags &= ~DDCKEY_SRCBLT;
1257 this->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1258 memcpy( &(this->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1261 if( dwFlags & DDCKEY_DESTBLT )
1263 dwFlags &= ~DDCKEY_DESTBLT;
1264 this->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1265 memcpy( &(this->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1268 if( dwFlags & DDCKEY_SRCOVERLAY )
1270 dwFlags &= ~DDCKEY_SRCOVERLAY;
1271 this->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1272 memcpy( &(this->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1275 if( dwFlags & DDCKEY_DESTOVERLAY )
1277 dwFlags &= ~DDCKEY_DESTOVERLAY;
1278 this->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1279 memcpy( &(this->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1282 if( dwFlags )
1284 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1287 return DD_OK;
1291 static HRESULT WINAPI IDirectDrawSurface4_AddOverlayDirtyRect(
1292 LPDIRECTDRAWSURFACE4 this,
1293 LPRECT lpRect )
1295 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
1297 return DD_OK;
1300 static HRESULT WINAPI IDirectDrawSurface4_DeleteAttachedSurface(
1301 LPDIRECTDRAWSURFACE4 this,
1302 DWORD dwFlags,
1303 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1305 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1307 return DD_OK;
1310 static HRESULT WINAPI IDirectDrawSurface4_EnumOverlayZOrders(
1311 LPDIRECTDRAWSURFACE4 this,
1312 DWORD dwFlags,
1313 LPVOID lpContext,
1314 LPDDENUMSURFACESCALLBACK lpfnCallback )
1316 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1317 lpContext, lpfnCallback );
1319 return DD_OK;
1322 static HRESULT WINAPI IDirectDrawSurface4_GetClipper(
1323 LPDIRECTDRAWSURFACE4 this,
1324 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1326 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1328 return DD_OK;
1331 static HRESULT WINAPI IDirectDrawSurface4_GetColorKey(
1332 LPDIRECTDRAWSURFACE4 this,
1333 DWORD dwFlags,
1334 LPDDCOLORKEY lpDDColorKey )
1336 TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey);
1338 if( dwFlags & DDCKEY_SRCBLT ) {
1339 dwFlags &= ~DDCKEY_SRCBLT;
1340 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1343 if( dwFlags & DDCKEY_DESTBLT )
1345 dwFlags &= ~DDCKEY_DESTBLT;
1346 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1349 if( dwFlags & DDCKEY_SRCOVERLAY )
1351 dwFlags &= ~DDCKEY_SRCOVERLAY;
1352 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1355 if( dwFlags & DDCKEY_DESTOVERLAY )
1357 dwFlags &= ~DDCKEY_DESTOVERLAY;
1358 memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1361 if( dwFlags )
1363 FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1366 return DD_OK;
1369 static HRESULT WINAPI IDirectDrawSurface4_GetFlipStatus(
1370 LPDIRECTDRAWSURFACE4 this,
1371 DWORD dwFlags )
1373 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1375 return DD_OK;
1378 static HRESULT WINAPI IDirectDrawSurface4_GetPalette(
1379 LPDIRECTDRAWSURFACE4 this,
1380 LPDIRECTDRAWPALETTE* lplpDDPalette )
1382 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1384 return DD_OK;
1387 static HRESULT WINAPI IDirectDrawSurface4_SetOverlayPosition(
1388 LPDIRECTDRAWSURFACE4 this,
1389 LONG lX,
1390 LONG lY)
1392 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1394 return DD_OK;
1397 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlay(
1398 LPDIRECTDRAWSURFACE4 this,
1399 LPRECT lpSrcRect,
1400 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1401 LPRECT lpDestRect,
1402 DWORD dwFlags,
1403 LPDDOVERLAYFX lpDDOverlayFx )
1405 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1406 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1408 return DD_OK;
1411 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayDisplay(
1412 LPDIRECTDRAWSURFACE4 this,
1413 DWORD dwFlags )
1415 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1417 return DD_OK;
1420 static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayZOrder(
1421 LPDIRECTDRAWSURFACE4 this,
1422 DWORD dwFlags,
1423 LPDIRECTDRAWSURFACE4 lpDDSReference )
1425 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1427 return DD_OK;
1430 static HRESULT WINAPI IDirectDrawSurface4_GetDDInterface(
1431 LPDIRECTDRAWSURFACE4 this,
1432 LPVOID* lplpDD )
1434 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1436 /* Not sure about that... */
1437 *lplpDD = (void *) this->s.ddraw;
1439 return DD_OK;
1442 static HRESULT WINAPI IDirectDrawSurface4_PageLock(
1443 LPDIRECTDRAWSURFACE4 this,
1444 DWORD dwFlags )
1446 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1448 return DD_OK;
1451 static HRESULT WINAPI IDirectDrawSurface4_PageUnlock(
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_SetSurfaceDesc(
1461 LPDIRECTDRAWSURFACE4 this,
1462 LPDDSURFACEDESC lpDDSD,
1463 DWORD dwFlags )
1465 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1467 return DD_OK;
1470 static HRESULT WINAPI IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4 this,
1471 REFGUID guidTag,
1472 LPVOID lpData,
1473 DWORD cbSize,
1474 DWORD dwFlags) {
1475 FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag, lpData, cbSize, dwFlags);
1477 return DD_OK;
1480 static HRESULT WINAPI IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4 this,
1481 REFGUID guidTag,
1482 LPVOID lpBuffer,
1483 LPDWORD lpcbBufferSize) {
1484 FIXME(ddraw, "(%p)->(%p,%p,%p)\n", this, guidTag, lpBuffer, lpcbBufferSize);
1486 return DD_OK;
1489 static HRESULT WINAPI IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4 this,
1490 REFGUID guidTag) {
1491 FIXME(ddraw, "(%p)->(%p)\n", this, guidTag);
1493 return DD_OK;
1496 static HRESULT WINAPI IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4 this,
1497 LPDWORD lpValue) {
1498 FIXME(ddraw, "(%p)->(%p)\n", this, lpValue);
1500 return DD_OK;
1503 static HRESULT WINAPI IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 this) {
1504 FIXME(ddraw, "(%p)\n", this);
1506 return DD_OK;
1509 static struct IDirectDrawSurface4_VTable dga_dds4vt = {
1510 IDirectDrawSurface4_QueryInterface,
1511 IDirectDrawSurface4_AddRef,
1512 DGA_IDirectDrawSurface4_Release,
1513 IDirectDrawSurface4_AddAttachedSurface,
1514 IDirectDrawSurface4_AddOverlayDirtyRect,
1515 IDirectDrawSurface4_Blt,
1516 IDirectDrawSurface4_BltBatch,
1517 IDirectDrawSurface4_BltFast,
1518 IDirectDrawSurface4_DeleteAttachedSurface,
1519 IDirectDrawSurface4_EnumAttachedSurfaces,
1520 IDirectDrawSurface4_EnumOverlayZOrders,
1521 DGA_IDirectDrawSurface4_Flip,
1522 IDirectDrawSurface4_GetAttachedSurface,
1523 IDirectDrawSurface4_GetBltStatus,
1524 IDirectDrawSurface4_GetCaps,
1525 IDirectDrawSurface4_GetClipper,
1526 IDirectDrawSurface4_GetColorKey,
1527 IDirectDrawSurface4_GetDC,
1528 IDirectDrawSurface4_GetFlipStatus,
1529 IDirectDrawSurface4_GetOverlayPosition,
1530 IDirectDrawSurface4_GetPalette,
1531 IDirectDrawSurface4_GetPixelFormat,
1532 IDirectDrawSurface4_GetSurfaceDesc,
1533 IDirectDrawSurface4_Initialize,
1534 IDirectDrawSurface4_IsLost,
1535 IDirectDrawSurface4_Lock,
1536 IDirectDrawSurface4_ReleaseDC,
1537 IDirectDrawSurface4_Restore,
1538 IDirectDrawSurface4_SetClipper,
1539 IDirectDrawSurface4_SetColorKey,
1540 IDirectDrawSurface4_SetOverlayPosition,
1541 DGA_IDirectDrawSurface4_SetPalette,
1542 DGA_IDirectDrawSurface4_Unlock,
1543 IDirectDrawSurface4_UpdateOverlay,
1544 IDirectDrawSurface4_UpdateOverlayDisplay,
1545 IDirectDrawSurface4_UpdateOverlayZOrder,
1546 IDirectDrawSurface4_GetDDInterface,
1547 IDirectDrawSurface4_PageLock,
1548 IDirectDrawSurface4_PageUnlock,
1549 IDirectDrawSurface4_SetSurfaceDesc,
1550 IDirectDrawSurface4_SetPrivateData,
1551 IDirectDrawSurface4_GetPrivateData,
1552 IDirectDrawSurface4_FreePrivateData,
1553 IDirectDrawSurface4_GetUniquenessValue,
1554 IDirectDrawSurface4_ChangeUniquenessValue
1557 static struct IDirectDrawSurface4_VTable xlib_dds4vt = {
1558 IDirectDrawSurface4_QueryInterface,
1559 IDirectDrawSurface4_AddRef,
1560 Xlib_IDirectDrawSurface4_Release,
1561 IDirectDrawSurface4_AddAttachedSurface,
1562 IDirectDrawSurface4_AddOverlayDirtyRect,
1563 IDirectDrawSurface4_Blt,
1564 IDirectDrawSurface4_BltBatch,
1565 IDirectDrawSurface4_BltFast,
1566 IDirectDrawSurface4_DeleteAttachedSurface,
1567 IDirectDrawSurface4_EnumAttachedSurfaces,
1568 IDirectDrawSurface4_EnumOverlayZOrders,
1569 Xlib_IDirectDrawSurface4_Flip,
1570 IDirectDrawSurface4_GetAttachedSurface,
1571 IDirectDrawSurface4_GetBltStatus,
1572 IDirectDrawSurface4_GetCaps,
1573 IDirectDrawSurface4_GetClipper,
1574 IDirectDrawSurface4_GetColorKey,
1575 IDirectDrawSurface4_GetDC,
1576 IDirectDrawSurface4_GetFlipStatus,
1577 IDirectDrawSurface4_GetOverlayPosition,
1578 IDirectDrawSurface4_GetPalette,
1579 IDirectDrawSurface4_GetPixelFormat,
1580 IDirectDrawSurface4_GetSurfaceDesc,
1581 IDirectDrawSurface4_Initialize,
1582 IDirectDrawSurface4_IsLost,
1583 IDirectDrawSurface4_Lock,
1584 IDirectDrawSurface4_ReleaseDC,
1585 IDirectDrawSurface4_Restore,
1586 IDirectDrawSurface4_SetClipper,
1587 IDirectDrawSurface4_SetColorKey,
1588 IDirectDrawSurface4_SetOverlayPosition,
1589 Xlib_IDirectDrawSurface4_SetPalette,
1590 Xlib_IDirectDrawSurface4_Unlock,
1591 IDirectDrawSurface4_UpdateOverlay,
1592 IDirectDrawSurface4_UpdateOverlayDisplay,
1593 IDirectDrawSurface4_UpdateOverlayZOrder,
1594 IDirectDrawSurface4_GetDDInterface,
1595 IDirectDrawSurface4_PageLock,
1596 IDirectDrawSurface4_PageUnlock,
1597 IDirectDrawSurface4_SetSurfaceDesc,
1598 IDirectDrawSurface4_SetPrivateData,
1599 IDirectDrawSurface4_GetPrivateData,
1600 IDirectDrawSurface4_FreePrivateData,
1601 IDirectDrawSurface4_GetUniquenessValue,
1602 IDirectDrawSurface4_ChangeUniquenessValue
1605 /******************************************************************************
1606 * DirectDrawCreateClipper (DDRAW.7)
1608 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1609 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1610 LPUNKNOWN pUnkOuter)
1612 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1614 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1615 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1616 (*lplpDDClipper)->ref = 1;
1618 return DD_OK;
1621 /******************************************************************************
1622 * IDirectDrawClipper
1624 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1625 LPDIRECTDRAWCLIPPER this,DWORD x,HWND hwnd
1627 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1628 return DD_OK;
1631 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1632 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1634 this->ref--;
1635 if (this->ref)
1636 return this->ref;
1637 HeapFree(GetProcessHeap(),0,this);
1638 return 0;
1641 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1642 LPDIRECTDRAWCLIPPER this,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
1644 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1645 if (hmm) *hmm=0;
1646 return DD_OK;
1649 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1650 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1652 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1653 return DD_OK;
1656 static HRESULT WINAPI IDirectDrawClipper_QueryInterface(
1657 LPDIRECTDRAWCLIPPER this,
1658 REFIID riid,
1659 LPVOID* ppvObj )
1661 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj);
1662 return OLE_E_ENUM_NOMORE;
1665 static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this )
1667 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1668 return ++(this->ref);
1671 static HRESULT WINAPI IDirectDrawClipper_GetHWnd(
1672 LPDIRECTDRAWCLIPPER this,
1673 HWND* HWndPtr )
1675 FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr);
1676 return DD_OK;
1679 static HRESULT WINAPI IDirectDrawClipper_Initialize(
1680 LPDIRECTDRAWCLIPPER this,
1681 LPDIRECTDRAW lpDD,
1682 DWORD dwFlags )
1684 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags);
1685 return DD_OK;
1688 static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged(
1689 LPDIRECTDRAWCLIPPER this,
1690 BOOL* lpbChanged )
1692 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged);
1693 return DD_OK;
1696 static struct IDirectDrawClipper_VTable ddclipvt = {
1697 IDirectDrawClipper_QueryInterface,
1698 IDirectDrawClipper_AddRef,
1699 IDirectDrawClipper_Release,
1700 IDirectDrawClipper_GetClipList,
1701 IDirectDrawClipper_GetHWnd,
1702 IDirectDrawClipper_Initialize,
1703 IDirectDrawClipper_IsClipListChanged,
1704 IDirectDrawClipper_SetClipList,
1705 IDirectDrawClipper_SetHwnd
1709 /******************************************************************************
1710 * IDirectDrawPalette
1712 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1713 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1715 int i;
1717 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1718 this,x,start,count,palent);
1720 if (!this->cm) /* should not happen */ {
1721 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1722 return DDERR_GENERIC;
1724 for (i=0;i<count;i++) {
1725 palent[i].peRed = this->palents[start+i].peRed;
1726 palent[i].peBlue = this->palents[start+i].peBlue;
1727 palent[i].peGreen = this->palents[start+i].peGreen;
1728 palent[i].peFlags = this->palents[start+i].peFlags;
1731 return DD_OK;
1734 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1735 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1737 XColor xc;
1738 int i;
1740 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1741 this,x,start,count,palent
1743 for (i=0;i<count;i++) {
1744 xc.red = palent[i].peRed<<8;
1745 xc.blue = palent[i].peBlue<<8;
1746 xc.green = palent[i].peGreen<<8;
1747 xc.flags = DoRed|DoBlue|DoGreen;
1748 xc.pixel = start+i;
1750 if (this->cm)
1751 TSXStoreColor(display,this->cm,&xc);
1753 this->palents[start+i].peRed = palent[i].peRed;
1754 this->palents[start+i].peBlue = palent[i].peBlue;
1755 this->palents[start+i].peGreen = palent[i].peGreen;
1756 this->palents[start+i].peFlags = palent[i].peFlags;
1759 /* Now, if we are in 'depth conversion mode', update the screen palette */
1760 if (this->ddraw->d.palette_convert != NULL)
1761 this->ddraw->d.palette_convert(palent, this->screen_palents, start, count);
1763 return DD_OK;
1766 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1767 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1769 #ifdef HAVE_LIBXXF86DGA
1770 XColor xc;
1771 Colormap cm;
1772 int i;
1774 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1775 this,x,start,count,palent
1777 if (!this->cm) /* should not happen */ {
1778 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1779 return DDERR_GENERIC;
1781 /* FIXME: free colorcells instead of freeing whole map */
1782 cm = this->cm;
1783 this->cm = TSXCopyColormapAndFree(display,this->cm);
1784 TSXFreeColormap(display,cm);
1786 for (i=0;i<count;i++) {
1787 xc.red = palent[i].peRed<<8;
1788 xc.blue = palent[i].peBlue<<8;
1789 xc.green = palent[i].peGreen<<8;
1790 xc.flags = DoRed|DoBlue|DoGreen;
1791 xc.pixel = i+start;
1793 TSXStoreColor(display,this->cm,&xc);
1795 this->palents[start+i].peRed = palent[i].peRed;
1796 this->palents[start+i].peBlue = palent[i].peBlue;
1797 this->palents[start+i].peGreen = palent[i].peGreen;
1798 this->palents[start+i].peFlags = palent[i].peFlags;
1800 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1801 return DD_OK;
1802 #else /* defined(HAVE_LIBXXF86DGA) */
1803 return E_UNEXPECTED;
1804 #endif /* defined(HAVE_LIBXXF86DGA) */
1807 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1808 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1809 if (!--(this->ref)) {
1810 if (this->cm) {
1811 TSXFreeColormap(display,this->cm);
1812 this->cm = 0;
1814 HeapFree(GetProcessHeap(),0,this);
1815 return 0;
1817 return this->ref;
1820 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1822 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1823 return ++(this->ref);
1826 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1827 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1829 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1831 return DDERR_ALREADYINITIALIZED;
1834 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1835 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1837 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1838 return DD_OK;
1841 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1842 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1844 char xrefiid[50];
1846 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1847 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1849 return S_OK;
1852 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1853 IDirectDrawPalette_QueryInterface,
1854 IDirectDrawPalette_AddRef,
1855 IDirectDrawPalette_Release,
1856 IDirectDrawPalette_GetCaps,
1857 IDirectDrawPalette_GetEntries,
1858 IDirectDrawPalette_Initialize,
1859 DGA_IDirectDrawPalette_SetEntries
1862 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1863 IDirectDrawPalette_QueryInterface,
1864 IDirectDrawPalette_AddRef,
1865 IDirectDrawPalette_Release,
1866 IDirectDrawPalette_GetCaps,
1867 IDirectDrawPalette_GetEntries,
1868 IDirectDrawPalette_Initialize,
1869 Xlib_IDirectDrawPalette_SetEntries
1872 /*******************************************************************************
1873 * IDirect3D
1875 static HRESULT WINAPI IDirect3D_QueryInterface(
1876 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1878 /* FIXME: Not sure if this is correct */
1879 char xrefiid[50];
1881 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1882 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1883 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1884 *obj = this;
1885 this->lpvtbl->fnAddRef(this);
1887 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
1889 return S_OK;
1891 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1892 LPDIRECT3D d3d;
1894 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1895 d3d->ref = 1;
1896 d3d->ddraw = (LPDIRECTDRAW)this;
1897 this->lpvtbl->fnAddRef(this);
1898 d3d->lpvtbl = &d3dvt;
1899 *obj = d3d;
1901 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
1903 return S_OK;
1905 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
1906 LPDIRECT3D2 d3d;
1908 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1909 d3d->ref = 1;
1910 d3d->ddraw = (LPDIRECTDRAW)this;
1911 this->lpvtbl->fnAddRef(this);
1912 d3d->lpvtbl = &d3d2vt;
1913 *obj = d3d;
1915 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
1917 return S_OK;
1919 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1920 return OLE_E_ENUM_NOMORE;
1923 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1924 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1926 return ++(this->ref);
1929 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1931 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1933 if (!--(this->ref)) {
1934 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1935 HeapFree(GetProcessHeap(),0,this);
1936 return 0;
1938 return this->ref;
1941 static HRESULT WINAPI IDirect3D_Initialize(
1942 LPDIRECT3D this, REFIID refiid )
1944 /* FIXME: Not sure if this is correct */
1945 char xrefiid[50];
1947 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1948 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1950 return DDERR_ALREADYINITIALIZED;
1953 static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this,
1954 LPD3DENUMDEVICESCALLBACK cb,
1955 LPVOID context) {
1956 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1958 /* Call functions defined in d3ddevices.c */
1959 if (!d3d_OpenGL_dx3(cb, context))
1960 return DD_OK;
1962 return DD_OK;
1965 static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this,
1966 LPDIRECT3DLIGHT *lplight,
1967 IUnknown *lpunk)
1969 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
1971 /* Call the creation function that is located in d3dlight.c */
1972 *lplight = d3dlight_create_dx3(this);
1974 return DD_OK;
1977 static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this,
1978 LPDIRECT3DMATERIAL *lpmaterial,
1979 IUnknown *lpunk)
1981 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
1983 /* Call the creation function that is located in d3dviewport.c */
1984 *lpmaterial = d3dmaterial_create(this);
1986 return DD_OK;
1989 static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this,
1990 LPDIRECT3DVIEWPORT *lpviewport,
1991 IUnknown *lpunk)
1993 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
1995 /* Call the creation function that is located in d3dviewport.c */
1996 *lpviewport = d3dviewport_create(this);
1998 return DD_OK;
2001 static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this,
2002 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2003 LPD3DFINDDEVICERESULT lpfinddevrst)
2005 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2007 return DD_OK;
2010 static struct IDirect3D_VTable d3dvt = {
2011 IDirect3D_QueryInterface,
2012 IDirect3D_AddRef,
2013 IDirect3D_Release,
2014 IDirect3D_Initialize,
2015 IDirect3D_EnumDevices,
2016 IDirect3D_CreateLight,
2017 IDirect3D_CreateMaterial,
2018 IDirect3D_CreateViewport,
2019 IDirect3D_FindDevice
2022 /*******************************************************************************
2023 * IDirect3D2
2025 static HRESULT WINAPI IDirect3D2_QueryInterface(
2026 LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) {
2027 /* For the moment, we use the same function as in IDirect3D */
2028 TRACE(ddraw, "Calling IDirect3D enumerating function.\n");
2030 return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj);
2033 static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) {
2034 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2036 return ++(this->ref);
2039 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
2040 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2042 if (!--(this->ref)) {
2043 this->ddraw->lpvtbl->fnRelease(this->ddraw);
2044 HeapFree(GetProcessHeap(),0,this);
2045 return 0;
2047 return this->ref;
2050 static HRESULT WINAPI IDirect3D2_EnumDevices(
2051 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2053 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
2055 /* Call functions defined in d3ddevices.c */
2056 if (!d3d_OpenGL(cb, context))
2057 return DD_OK;
2059 return DD_OK;
2062 static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this,
2063 LPDIRECT3DLIGHT *lplight,
2064 IUnknown *lpunk)
2066 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk);
2068 /* Call the creation function that is located in d3dlight.c */
2069 *lplight = d3dlight_create(this);
2071 return DD_OK;
2074 static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this,
2075 LPDIRECT3DMATERIAL2 *lpmaterial,
2076 IUnknown *lpunk)
2078 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk);
2080 /* Call the creation function that is located in d3dviewport.c */
2081 *lpmaterial = d3dmaterial2_create(this);
2083 return DD_OK;
2086 static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this,
2087 LPDIRECT3DVIEWPORT2 *lpviewport,
2088 IUnknown *lpunk)
2090 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk);
2092 /* Call the creation function that is located in d3dviewport.c */
2093 *lpviewport = d3dviewport2_create(this);
2095 return DD_OK;
2098 static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this,
2099 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2100 LPD3DFINDDEVICERESULT lpfinddevrst)
2102 TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst);
2104 return DD_OK;
2107 static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this,
2108 REFCLSID rguid,
2109 LPDIRECTDRAWSURFACE surface,
2110 LPDIRECT3DDEVICE2 *device)
2112 char xbuf[50];
2114 WINE_StringFromCLSID(rguid,xbuf);
2115 FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device);
2117 if (is_OpenGL(rguid, surface, device, this)) {
2118 this->lpvtbl->fnAddRef(this);
2119 return DD_OK;
2122 return DDERR_INVALIDPARAMS;
2125 static struct IDirect3D2_VTable d3d2vt = {
2126 IDirect3D2_QueryInterface,
2127 IDirect3D2_AddRef,
2128 IDirect3D2_Release,
2129 IDirect3D2_EnumDevices,
2130 IDirect3D2_CreateLight,
2131 IDirect3D2_CreateMaterial,
2132 IDirect3D2_CreateViewport,
2133 IDirect3D2_FindDevice,
2134 IDirect3D2_CreateDevice
2137 /*******************************************************************************
2138 * IDirectDraw
2141 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2142 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2144 static INT ddrawXlibThisOffset = 0;
2146 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
2147 LPDDSURFACEDESC lpddsd,
2148 LPDIRECTDRAWSURFACE lpdsf)
2150 int bpp;
2152 /* The surface was already allocated when entering in this function */
2153 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2155 if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2156 /* This is a Z Buffer */
2157 TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2158 bpp = lpddsd->x.dwZBufferBitDepth / 8;
2159 } else {
2160 /* This is a standard image */
2161 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2162 /* No pixel format => use DirectDraw's format */
2163 lpddsd->ddpfPixelFormat = this->d.directdraw_pixelformat;
2164 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2165 } else {
2166 /* To check what the program wants */
2167 if (TRACE_ON(ddraw)) {
2168 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2172 if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2173 bpp = 1;
2174 } else {
2175 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2179 /* Copy the surface description */
2180 lpdsf->s.surface_desc = *lpddsd;
2182 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2183 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2184 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2186 return DD_OK;
2189 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
2190 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2192 #ifdef HAVE_LIBXXF86DGA
2193 int i;
2195 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
2196 if (TRACE_ON(ddraw)) {
2197 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2198 _dump_DDSD(lpddsd->dwFlags);
2199 DUMP(" caps ");
2200 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2203 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2204 this->lpvtbl->fnAddRef(this);
2206 (*lpdsf)->ref = 1;
2207 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds4vt;
2208 (*lpdsf)->s.ddraw = this;
2209 (*lpdsf)->s.palette = NULL;
2210 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2212 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2213 lpddsd->dwWidth = this->d.width;
2214 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2215 lpddsd->dwHeight = this->d.height;
2217 /* Check if this a 'primary surface' or not */
2218 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2219 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2221 /* This is THE primary surface => there is DGA-specific code */
2222 /* First, store the surface description */
2223 (*lpdsf)->s.surface_desc = *lpddsd;
2225 /* Find a viewport */
2226 for (i=0;i<32;i++)
2227 if (!(this->e.dga.vpmask & (1<<i)))
2228 break;
2229 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2230 /* if i == 32 or maximum ... return error */
2231 this->e.dga.vpmask|=(1<<i);
2232 (*lpdsf)->s.surface_desc.y.lpSurface =
2233 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2234 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
2235 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
2236 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
2238 /* Add flags if there were not present */
2239 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2240 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2241 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2242 TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d.width,this->d.height,lpddsd->lPitch);
2243 /* We put our surface always in video memory */
2244 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2245 (*lpdsf)->s.surface_desc.ddpfPixelFormat = this->d.directdraw_pixelformat;
2246 (*lpdsf)->s.backbuffer = NULL;
2248 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2249 LPDIRECTDRAWSURFACE4 back;
2251 if (lpddsd->dwBackBufferCount>1)
2252 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2254 (*lpdsf)->s.backbuffer = back =
2255 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2256 this->lpvtbl->fnAddRef(this);
2257 back->ref = 1;
2258 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&dga_dds4vt;
2259 for (i=0;i<32;i++)
2260 if (!(this->e.dga.vpmask & (1<<i)))
2261 break;
2262 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2263 /* if i == 32 or maximum ... return error */
2264 this->e.dga.vpmask|=(1<<i);
2265 back->t.dga.fb_height = i*this->e.dga.fb_height;
2267 /* Copy the surface description from the front buffer */
2268 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2269 /* Change the parameters that are not the same */
2270 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
2271 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2272 back->s.ddraw = this;
2273 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2274 * one! */
2276 /* Add relevant info to front and back buffers */
2277 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2278 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2279 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2280 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2281 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2283 } else {
2284 /* There is no DGA-specific code here...
2285 Go to the common surface creation function */
2286 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2289 return DD_OK;
2290 #else /* defined(HAVE_LIBXXF86DGA) */
2291 return E_UNEXPECTED;
2292 #endif /* defined(HAVE_LIBXXF86DGA) */
2295 #ifdef HAVE_LIBXXSHM
2296 /* Error handlers for Image creation */
2297 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2298 XShmErrorFlag = 1;
2299 return 0;
2302 static XImage *create_xshmimage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2303 XImage *img;
2304 int (*WineXHandler)(Display *, XErrorEvent *);
2306 img = TSXShmCreateImage(display,
2307 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2308 this->d.pixmap_depth,
2309 ZPixmap,
2310 NULL,
2311 &(lpdsf->t.xlib.shminfo),
2312 lpdsf->s.surface_desc.dwWidth,
2313 lpdsf->s.surface_desc.dwHeight);
2315 if (img == NULL) {
2316 ERR(ddraw, "Error creating XShm image. Reverting to standard X images !\n");
2317 this->e.xlib.xshm_active = 0;
2318 return NULL;
2321 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2322 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2323 ERR(ddraw, "Error creating shared memory segment. Reverting to standard X images !\n");
2324 this->e.xlib.xshm_active = 0;
2325 TSXDestroyImage(img);
2326 return NULL;
2329 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2331 if (img->data == (char *) -1) {
2332 ERR(ddraw, "Error attaching shared memory segment. Reverting to standard X images !\n");
2333 this->e.xlib.xshm_active = 0;
2334 TSXDestroyImage(img);
2335 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2336 return NULL;
2338 lpdsf->t.xlib.shminfo.readOnly = False;
2340 /* This is where things start to get trickier....
2341 First, we flush the current X connections to be sure to catch all non-XShm related
2342 errors */
2343 TSXSync(display, False);
2344 /* Then we enter in the non-thread safe part of the tests */
2345 EnterCriticalSection( &X11DRV_CritSection );
2347 /* Reset the error flag, sets our new error handler and try to attach the surface */
2348 XShmErrorFlag = 0;
2349 WineXHandler = XSetErrorHandler(XShmErrorHandler);
2350 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2351 XSync(display, False);
2353 /* Check the error flag */
2354 if (XShmErrorFlag) {
2355 /* An error occured */
2356 XFlush(display);
2357 XShmErrorFlag = 0;
2358 XDestroyImage(img);
2359 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2360 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2361 XSetErrorHandler(WineXHandler);
2363 ERR(ddraw, "Error attaching shared memory segment to X server. Reverting to standard X images !\n");
2364 this->e.xlib.xshm_active = 0;
2366 /* Leave the critical section */
2367 LeaveCriticalSection( &X11DRV_CritSection );
2369 return NULL;
2372 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2373 but it may be a bit overkill.... */
2374 XSetErrorHandler(WineXHandler);
2375 LeaveCriticalSection( &X11DRV_CritSection );
2377 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2379 if (this->d.pixel_convert != NULL) {
2380 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2381 lpdsf->s.surface_desc.dwWidth *
2382 lpdsf->s.surface_desc.dwHeight *
2383 (this->d.directdraw_pixelformat.x.dwRGBBitCount));
2384 } else {
2385 lpdsf->s.surface_desc.y.lpSurface = img->data;
2388 return img;
2390 #endif /* HAVE_LIBXXSHM */
2392 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
2393 XImage *img = NULL;
2394 void *img_data;
2396 #ifdef HAVE_LIBXXSHM
2397 if (this->e.xlib.xshm_active) {
2398 img = create_xshmimage(this, lpdsf);
2401 if (img == NULL) {
2402 #endif
2403 /* Allocate surface memory */
2404 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2405 lpdsf->s.surface_desc.dwWidth *
2406 lpdsf->s.surface_desc.dwHeight *
2407 (this->d.directdraw_pixelformat.x.dwRGBBitCount / 8));
2409 if (this->d.pixel_convert != NULL) {
2410 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2411 lpdsf->s.surface_desc.dwWidth *
2412 lpdsf->s.surface_desc.dwHeight *
2413 (this->d.screen_pixelformat.x.dwRGBBitCount / 8));
2414 } else {
2415 img_data = lpdsf->s.surface_desc.y.lpSurface;
2418 /* In this case, create an XImage */
2419 img =
2420 TSXCreateImage(display,
2421 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2422 this->d.pixmap_depth,
2423 ZPixmap,
2425 img_data,
2426 lpdsf->s.surface_desc.dwWidth,
2427 lpdsf->s.surface_desc.dwHeight,
2429 lpdsf->s.surface_desc.dwWidth * (this->d.screen_pixelformat.x.dwRGBBitCount / 8)
2432 #ifdef HAVE_LIBXXSHM
2434 #endif
2435 if (this->d.pixel_convert != NULL) {
2436 lpdsf->s.surface_desc.lPitch = (this->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
2437 } else {
2438 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2441 return img;
2444 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
2445 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2447 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2448 this,lpddsd,lpdsf,lpunk);
2450 if (TRACE_ON(ddraw)) {
2451 DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2452 _dump_DDSD(lpddsd->dwFlags);
2453 DUMP(" caps ");
2454 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2457 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
2459 this->lpvtbl->fnAddRef(this);
2460 (*lpdsf)->s.ddraw = this;
2461 (*lpdsf)->ref = 1;
2462 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds4vt;
2463 (*lpdsf)->s.palette = NULL;
2464 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2466 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2467 lpddsd->dwWidth = this->d.width;
2468 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2469 lpddsd->dwHeight = this->d.height;
2471 /* Check if this a 'primary surface' or not */
2472 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2473 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2474 XImage *img;
2476 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
2478 /* First, store the surface description */
2479 (*lpdsf)->s.surface_desc = *lpddsd;
2481 /* Create the XImage */
2482 img = create_ximage(this, (LPDIRECTDRAWSURFACE4) *lpdsf);
2483 if (img == NULL)
2484 return DDERR_OUTOFMEMORY;
2485 (*lpdsf)->t.xlib.image = img;
2487 /* Add flags if there were not present */
2488 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2489 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
2490 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
2491 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2492 (*lpdsf)->s.surface_desc.ddpfPixelFormat = this->d.directdraw_pixelformat;
2493 (*lpdsf)->s.backbuffer = NULL;
2495 /* Check for backbuffers */
2496 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2497 LPDIRECTDRAWSURFACE4 back;
2498 XImage *img;
2500 if (lpddsd->dwBackBufferCount>1)
2501 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2503 (*lpdsf)->s.backbuffer = back =
2504 (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4));
2506 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2508 this->lpvtbl->fnAddRef(this);
2509 back->s.ddraw = this;
2511 back->ref = 1;
2512 back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&xlib_dds4vt;
2513 /* Copy the surface description from the front buffer */
2514 back->s.surface_desc = (*lpdsf)->s.surface_desc;
2516 /* Create the XImage */
2517 img = create_ximage(this, back);
2518 if (img == NULL)
2519 return DDERR_OUTOFMEMORY;
2520 back->t.xlib.image = img;
2522 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2523 * one! */
2525 /* Add relevant info to front and back buffers */
2526 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2527 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2528 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2529 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2530 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2532 } else {
2533 /* There is no Xlib-specific code here...
2534 Go to the common surface creation function */
2535 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
2538 return DD_OK;
2541 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
2542 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2544 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
2545 *dst = src; /* FIXME */
2546 return DD_OK;
2550 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2551 * even when the approbiate bitmasks are not specified.
2553 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
2554 LPDIRECTDRAW2 this,HWND hwnd,DWORD cooplevel
2556 int i;
2557 const struct {
2558 int mask;
2559 char *name;
2560 } flagmap[] = {
2561 FE(DDSCL_FULLSCREEN)
2562 FE(DDSCL_ALLOWREBOOT)
2563 FE(DDSCL_NOWINDOWCHANGES)
2564 FE(DDSCL_NORMAL)
2565 FE(DDSCL_ALLOWMODEX)
2566 FE(DDSCL_EXCLUSIVE)
2567 FE(DDSCL_SETFOCUSWINDOW)
2568 FE(DDSCL_SETDEVICEWINDOW)
2569 FE(DDSCL_CREATEDEVICEWINDOW)
2572 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
2573 if(TRACE_ON(ddraw)){
2574 dbg_decl_str(ddraw, 512);
2575 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2576 if (flagmap[i].mask & cooplevel)
2577 dsprintf(ddraw, "%s ", flagmap[i].name);
2578 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2580 this->d.mainWindow = hwnd;
2582 /* This will be overwritten in the case of Full Screen mode.
2583 Windowed games could work with that :-) */
2584 if (hwnd)
2585 this->d.drawable = X11DRV_WND_GetXWindow(WIN_FindWndPtr(hwnd));
2587 return DD_OK;
2590 /* Small helper to either use the cooperative window or create a new
2591 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2593 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
2594 RECT rect;
2596 /* Do not destroy the application supplied cooperative window */
2597 if (this->d.window && this->d.window != this->d.mainWindow) {
2598 DestroyWindow(this->d.window);
2599 this->d.window = 0;
2601 /* Sanity check cooperative window before assigning it to drawing. */
2602 if ( IsWindow(this->d.mainWindow) &&
2603 IsWindowVisible(this->d.mainWindow)
2605 GetWindowRect(this->d.mainWindow,&rect);
2606 if (((rect.right-rect.left) >= this->d.width) &&
2607 ((rect.bottom-rect.top) >= this->d.height)
2609 this->d.window = this->d.mainWindow;
2611 /* ... failed, create new one. */
2612 if (!this->d.window) {
2613 this->d.window = CreateWindowExA(
2615 "WINE_DirectDraw",
2616 "WINE_DirectDraw",
2617 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2618 0,0,
2619 this->d.width,
2620 this->d.height,
2624 NULL
2626 /*Store THIS with the window. We'll use it in the window procedure*/
2627 SetWindowLongA(this->d.window,ddrawXlibThisOffset,(LONG)this);
2628 ShowWindow(this->d.window,TRUE);
2629 UpdateWindow(this->d.window);
2631 SetFocus(this->d.window);
2634 static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
2635 XVisualInfo *vi;
2636 XPixmapFormatValues *pf;
2637 XVisualInfo vt;
2638 int nvisuals, npixmap, i;
2639 int match = 0;
2641 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
2642 pf = XListPixmapFormats(display, &npixmap);
2644 for (i = 0; i < npixmap; i++) {
2645 if (pf[i].bits_per_pixel == depth) {
2646 int j;
2648 for (j = 0; j < nvisuals; j++) {
2649 if (vi[j].depth == pf[i].depth) {
2650 pixelformat->dwSize = sizeof(*pixelformat);
2651 if (depth == 8) {
2652 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
2653 pixelformat->y.dwRBitMask = 0;
2654 pixelformat->z.dwGBitMask = 0;
2655 pixelformat->xx.dwBBitMask = 0;
2656 } else {
2657 pixelformat->dwFlags = DDPF_RGB;
2658 pixelformat->y.dwRBitMask = vi[j].red_mask;
2659 pixelformat->z.dwGBitMask = vi[j].green_mask;
2660 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
2662 pixelformat->dwFourCC = 0;
2663 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
2664 pixelformat->xy.dwRGBAlphaBitMask= 0;
2666 *screen_pixelformat = *pixelformat;
2668 if (pix_depth != NULL)
2669 *pix_depth = vi[j].depth;
2671 match = 1;
2673 break;
2677 if (j == nvisuals)
2678 ERR(ddraw, "No visual corresponding to pixmap format !\n");
2682 if ((match == 0) && (depth == 8)) {
2683 pixelformat->dwSize = sizeof(*pixelformat);
2684 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
2685 pixelformat->dwFourCC = 0;
2686 pixelformat->x.dwRGBBitCount = 8;
2687 pixelformat->y.dwRBitMask = 0;
2688 pixelformat->z.dwGBitMask = 0;
2689 pixelformat->xx.dwBBitMask = 0;
2690 pixelformat->xy.dwRGBAlphaBitMask= 0;
2692 /* In that case, find a visual to emulate the 8 bpp format */
2693 for (i = 0; i < npixmap; i++) {
2694 if (pf[i].bits_per_pixel >= depth) {
2695 int j;
2697 for (j = 0; j < nvisuals; j++) {
2698 if (vi[j].depth == pf[i].depth) {
2699 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
2700 screen_pixelformat->dwFlags = DDPF_RGB;
2701 screen_pixelformat->dwFourCC = 0;
2702 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
2703 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
2704 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
2705 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
2706 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
2708 if (pix_depth != NULL)
2709 *pix_depth = vi[j].depth;
2711 match = 2;
2713 break;
2717 if (j == nvisuals)
2718 ERR(ddraw, "No visual corresponding to pixmap format !\n");
2723 TSXFree(vi);
2724 TSXFree(pf);
2726 return match;
2729 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
2730 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2732 #ifdef HAVE_LIBXXF86DGA
2733 int i,mode_count;
2735 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
2737 /* We hope getting the asked for depth */
2738 if (_common_depth_to_pixelformat(depth, &(this->d.directdraw_pixelformat), &(this->d.screen_pixelformat), NULL) != 1) {
2739 /* I.e. no visual found or emulated */
2740 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
2741 return DDERR_UNSUPPORTEDMODE;
2744 if (this->d.width < width) {
2745 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
2746 return DDERR_UNSUPPORTEDMODE;
2748 this->d.width = width;
2749 this->d.height = height;
2751 /* adjust fb_height, so we don't overlap */
2752 if (this->e.dga.fb_height < height)
2753 this->e.dga.fb_height = height;
2754 _common_IDirectDraw_SetDisplayMode(this);
2756 #ifdef HAVE_LIBXXF86VM
2758 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
2759 XF86VidModeModeLine mod_tmp;
2760 /* int dotclock_tmp; */
2762 /* save original video mode and set fullscreen if available*/
2763 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
2764 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
2765 orig_mode->hdisplay = mod_tmp.hdisplay;
2766 orig_mode->hsyncstart = mod_tmp.hsyncstart;
2767 orig_mode->hsyncend = mod_tmp.hsyncend;
2768 orig_mode->htotal = mod_tmp.htotal;
2769 orig_mode->vdisplay = mod_tmp.vdisplay;
2770 orig_mode->vsyncstart = mod_tmp.vsyncstart;
2771 orig_mode->vsyncend = mod_tmp.vsyncend;
2772 orig_mode->vtotal = mod_tmp.vtotal;
2773 orig_mode->flags = mod_tmp.flags;
2774 orig_mode->private = mod_tmp.private;
2776 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2777 for (i=0;i<mode_count;i++)
2779 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2781 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2782 *vidmode = *(all_modes[i]);
2783 break;
2784 } else
2785 TSXFree(all_modes[i]->private);
2787 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
2788 TSXFree(all_modes);
2790 if (!vidmode)
2791 WARN(ddraw, "Fullscreen mode not available!\n");
2793 if (vidmode)
2795 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
2796 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2797 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
2798 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
2799 #endif
2802 #endif
2804 /* FIXME: this function OVERWRITES several signal handlers.
2805 * can we save them? and restore them later? In a way that
2806 * it works for the library too?
2808 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2809 #ifdef DIABLO_HACK
2810 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2811 #else
2812 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2813 #endif
2815 #ifdef RESTORE_SIGNALS
2816 SIGNAL_InitHandlers();
2817 #endif
2818 return DD_OK;
2819 #else /* defined(HAVE_LIBXXF86DGA) */
2820 return E_UNEXPECTED;
2821 #endif /* defined(HAVE_LIBXXF86DGA) */
2824 /* *************************************
2825 16 / 15 bpp to palettized 8 bpp
2826 ************************************* */
2827 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, LPDIRECTDRAWPALETTE palette) {
2828 unsigned char *c_src = (unsigned char *) src;
2829 unsigned short *c_dst = (unsigned short *) dst;
2830 int x, y;
2832 if (palette != NULL) {
2833 unsigned short *pal = (unsigned short *) palette->screen_palents;
2835 for (y = 0; y < height; y++) {
2836 for (x = 0; x < width; x++) {
2837 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
2840 } else {
2841 WARN(ddraw, "No palette set...\n");
2842 memset(dst, 0, width * height * 2);
2845 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
2846 int i;
2847 unsigned short *pal = (unsigned short *) screen_palette;
2849 for (i = 0; i < count; i++)
2850 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
2851 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
2852 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
2854 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
2855 int i;
2856 unsigned short *pal = (unsigned short *) screen_palette;
2858 for (i = 0; i < count; i++)
2859 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
2860 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
2861 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
2864 /* *************************************
2865 24 / 32 bpp to palettized 8 bpp
2866 ************************************* */
2867 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, LPDIRECTDRAWPALETTE palette) {
2868 unsigned char *c_src = (unsigned char *) src;
2869 unsigned int *c_dst = (unsigned int *) dst;
2870 int x, y;
2872 if (palette != NULL) {
2873 unsigned int *pal = (unsigned int *) palette->screen_palents;
2875 for (y = 0; y < height; y++) {
2876 for (x = 0; x < width; x++) {
2877 c_dst[x + y * width] = pal[c_src[x + y * pitch]];
2880 } else {
2881 WARN(ddraw, "No palette set...\n");
2882 memset(dst, 0, width * height * 4);
2885 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
2886 int i;
2887 unsigned int *pal = (unsigned int *) screen_palette;
2889 for (i = 0; i < count; i++)
2890 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
2891 (((unsigned int) palent[i].peGreen) << 8) |
2892 ((unsigned int) palent[i].peBlue));
2895 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2896 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2898 char buf[200];
2900 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2901 this, width, height, depth);
2903 switch (_common_depth_to_pixelformat(depth,
2904 &(this->d.directdraw_pixelformat),
2905 &(this->d.screen_pixelformat),
2906 &(this->d.pixmap_depth))) {
2907 case 0:
2908 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2909 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2910 return DDERR_UNSUPPORTEDMODE;
2912 case 1:
2913 /* No convertion */
2914 this->d.pixel_convert = NULL;
2915 this->d.palette_convert = NULL;
2916 break;
2918 case 2: {
2919 int found = 0;
2921 WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
2923 /* Set the depth convertion routines */
2924 switch (this->d.screen_pixelformat.x.dwRGBBitCount) {
2925 case 16:
2926 if ((this->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
2927 (this->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
2928 (this->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
2929 /* 16 bpp */
2930 found = 1;
2932 this->d.pixel_convert = pixel_convert_16_to_8;
2933 this->d.palette_convert = palette_convert_16_to_8;
2934 } else if ((this->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
2935 (this->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
2936 (this->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
2937 /* 15 bpp */
2938 found = 1;
2940 this->d.pixel_convert = pixel_convert_16_to_8;
2941 this->d.palette_convert = palette_convert_15_to_8;
2943 break;
2945 case 24:
2946 /* Not handled yet :/ */
2947 found = 0;
2948 break;
2950 case 32:
2951 if ((this->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) &&
2952 (this->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) &&
2953 (this->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
2954 /* 24 bpp */
2955 found = 1;
2957 this->d.pixel_convert = pixel_convert_32_to_8;
2958 this->d.palette_convert = palette_convert_24_to_8;
2960 break;
2963 if (!found) {
2964 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2965 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2966 return DDERR_UNSUPPORTEDMODE;
2968 } break;
2971 this->d.width = width;
2972 this->d.height = height;
2974 _common_IDirectDraw_SetDisplayMode(this);
2976 this->d.paintable = 1;
2977 this->d.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window;
2978 /* We don't have a context for this window. Host off the desktop */
2979 if( !this->d.drawable )
2980 this->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
2981 return DD_OK;
2984 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2985 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2987 #ifdef HAVE_LIBXXF86DGA
2988 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2989 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2990 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2991 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2992 if (caps2) {
2993 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2994 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2995 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2997 return DD_OK;
2998 #else /* defined(HAVE_LIBXXF86DGA) */
2999 return E_UNEXPECTED;
3000 #endif /* defined(HAVE_LIBXXF86DGA) */
3003 static void fill_caps(LPDDCAPS caps) {
3004 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3005 Need to be fixed, though.. */
3006 if (caps == NULL)
3007 return;
3009 caps->dwSize = sizeof(*caps);
3010 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3011 DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE;
3012 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3013 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3014 caps->dwFXCaps = 0;
3015 caps->dwFXAlphaCaps = 0;
3016 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3017 caps->dwSVCaps = 0;
3018 caps->dwZBufferBitDepths = DDBD_16;
3019 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3020 to put textures in video memory.
3021 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3022 for example) ? */
3023 caps->dwVidMemTotal = 8192 * 1024;
3024 caps->dwVidMemFree = 8192 * 1024;
3025 /* These are all the supported capabilities of the surfaces */
3026 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3027 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3028 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3029 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3030 #ifdef HAVE_MESAGL
3031 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3032 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3033 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3034 #endif
3037 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
3038 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
3040 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
3042 /* Put the same caps for the two capabilities */
3043 fill_caps(caps1);
3044 fill_caps(caps2);
3046 return DD_OK;
3049 static HRESULT WINAPI IDirectDraw2_CreateClipper(
3050 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3052 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3053 this,x,lpddclip,lpunk
3055 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
3056 (*lpddclip)->ref = 1;
3057 (*lpddclip)->lpvtbl = &ddclipvt;
3058 return DD_OK;
3061 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
3062 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk,int *psize
3064 int size = 0;
3066 if (TRACE_ON(ddraw))
3067 _dump_paletteformat(dwFlags);
3069 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
3070 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3071 (*lpddpal)->ref = 1;
3072 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
3073 (*lpddpal)->installed = 0;
3075 if (dwFlags & DDPCAPS_1BIT)
3076 size = 2;
3077 else if (dwFlags & DDPCAPS_2BIT)
3078 size = 4;
3079 else if (dwFlags & DDPCAPS_4BIT)
3080 size = 16;
3081 else if (dwFlags & DDPCAPS_8BIT)
3082 size = 256;
3083 else
3084 ERR(ddraw, "unhandled palette format\n");
3085 *psize = size;
3087 if (palent)
3089 /* Now, if we are in 'depth conversion mode', create the screen palette */
3090 if (this->d.palette_convert != NULL)
3091 this->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3093 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3094 } else if (this->d.palette_convert != NULL) {
3095 /* In that case, put all 0xFF */
3096 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3099 return DD_OK;
3102 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
3103 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3105 HRESULT res;
3106 int xsize = 0,i;
3108 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
3109 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
3110 if (res != 0) return res;
3111 (*lpddpal)->lpvtbl = &dga_ddpalvt;
3112 if (this->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3113 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3114 } else {
3115 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3116 (*lpddpal)->cm = 0;
3118 if (((*lpddpal)->cm)&&xsize) {
3119 for (i=0;i<xsize;i++) {
3120 XColor xc;
3122 xc.red = (*lpddpal)->palents[i].peRed<<8;
3123 xc.blue = (*lpddpal)->palents[i].peBlue<<8;
3124 xc.green = (*lpddpal)->palents[i].peGreen<<8;
3125 xc.flags = DoRed|DoBlue|DoGreen;
3126 xc.pixel = i;
3127 TSXStoreColor(display,(*lpddpal)->cm,&xc);
3130 return DD_OK;
3133 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
3134 LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3136 int xsize;
3137 HRESULT res;
3139 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk);
3140 res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize);
3141 if (res != 0) return res;
3142 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
3143 return DD_OK;
3146 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3147 #ifdef HAVE_LIBXXF86DGA
3148 TRACE(ddraw, "(%p)->()\n",this);
3149 Sleep(1000);
3150 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3151 #ifdef RESTORE_SIGNALS
3152 SIGNAL_InitHandlers();
3153 #endif
3154 return DD_OK;
3155 #else /* defined(HAVE_LIBXXF86DGA) */
3156 return E_UNEXPECTED;
3157 #endif
3160 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
3161 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
3162 Sleep(1000);
3163 return DD_OK;
3166 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
3167 LPDIRECTDRAW2 this,DWORD x,HANDLE h
3169 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
3170 return DD_OK;
3173 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
3174 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
3176 return ++(this->ref);
3179 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3180 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3182 #ifdef HAVE_LIBXXF86DGA
3183 if (!--(this->ref)) {
3184 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3185 if (this->d.window && (this->d.mainWindow != this->d.window))
3186 DestroyWindow(this->d.window);
3187 #ifdef HAVE_LIBXXF86VM
3188 if (orig_mode) {
3189 TSXF86VidModeSwitchToMode(
3190 display,
3191 DefaultScreen(display),
3192 orig_mode);
3193 if (orig_mode->privsize)
3194 TSXFree(orig_mode->private);
3195 free(orig_mode);
3196 orig_mode = NULL;
3198 #endif
3200 #ifdef RESTORE_SIGNALS
3201 SIGNAL_InitHandlers();
3202 #endif
3203 HeapFree(GetProcessHeap(),0,this);
3204 return 0;
3206 #endif /* defined(HAVE_LIBXXF86DGA) */
3207 return this->ref;
3210 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
3211 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
3213 if (!--(this->ref)) {
3214 if (this->d.window && (this->d.mainWindow != this->d.window))
3215 DestroyWindow(this->d.window);
3216 HeapFree(GetProcessHeap(),0,this);
3217 return 0;
3219 /* FIXME: destroy window ... */
3220 return this->ref;
3223 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
3224 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3226 char xrefiid[50];
3228 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3229 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3230 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3231 *obj = this;
3232 this->lpvtbl->fnAddRef(this);
3234 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3236 return S_OK;
3238 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3239 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
3240 this->lpvtbl->fnAddRef(this);
3241 *obj = this;
3243 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3245 return S_OK;
3247 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3248 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
3249 this->lpvtbl->fnAddRef(this);
3250 *obj = this;
3252 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3254 return S_OK;
3256 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3257 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd4vt;
3258 this->lpvtbl->fnAddRef(this);
3259 *obj = this;
3261 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3263 return S_OK;
3265 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3266 LPDIRECT3D d3d;
3268 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3269 d3d->ref = 1;
3270 d3d->ddraw = (LPDIRECTDRAW)this;
3271 this->lpvtbl->fnAddRef(this);
3272 d3d->lpvtbl = &d3dvt;
3273 *obj = d3d;
3275 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3277 return S_OK;
3279 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3280 LPDIRECT3D2 d3d;
3282 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3283 d3d->ref = 1;
3284 d3d->ddraw = (LPDIRECTDRAW)this;
3285 this->lpvtbl->fnAddRef(this);
3286 d3d->lpvtbl = &d3d2vt;
3287 *obj = d3d;
3289 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3291 return S_OK;
3293 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3294 return OLE_E_ENUM_NOMORE;
3297 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
3298 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
3300 char xrefiid[50];
3302 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3303 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
3304 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3305 *obj = this;
3306 this->lpvtbl->fnAddRef(this);
3308 TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj);
3310 return S_OK;
3312 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3313 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
3314 this->lpvtbl->fnAddRef(this);
3315 *obj = this;
3317 TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj);
3319 return S_OK;
3321 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3322 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
3323 this->lpvtbl->fnAddRef(this);
3324 *obj = this;
3326 TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj);
3328 return S_OK;
3330 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3331 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd4vt;
3332 this->lpvtbl->fnAddRef(this);
3333 *obj = this;
3335 TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj);
3337 return S_OK;
3339 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3340 LPDIRECT3D d3d;
3342 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3343 d3d->ref = 1;
3344 d3d->ddraw = (LPDIRECTDRAW)this;
3345 this->lpvtbl->fnAddRef(this);
3346 d3d->lpvtbl = &d3dvt;
3347 *obj = d3d;
3349 TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj);
3351 return S_OK;
3353 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3354 LPDIRECT3D2 d3d;
3356 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3357 d3d->ref = 1;
3358 d3d->ddraw = (LPDIRECTDRAW)this;
3359 this->lpvtbl->fnAddRef(this);
3360 d3d->lpvtbl = &d3d2vt;
3361 *obj = d3d;
3363 TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj);
3365 return S_OK;
3367 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
3368 return OLE_E_ENUM_NOMORE;
3371 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
3372 LPDIRECTDRAW2 this,BOOL *status
3374 TRACE(ddraw,"(%p)->(%p)\n",this,status);
3375 *status = TRUE;
3376 return DD_OK;
3379 static HRESULT WINAPI DGA_IDirectDraw2_EnumDisplayModes(
3380 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3382 DDSURFACEDESC ddsfd;
3383 static struct {
3384 int w,h;
3385 } modes[5] = { /* some of the usual modes */
3386 {512,384},
3387 {640,400},
3388 {640,480},
3389 {800,600},
3390 {1024,768},
3392 static int depths[4] = {8,16,24,32};
3393 int i,j;
3395 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
3396 ddsfd.dwSize = sizeof(ddsfd);
3397 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3398 if (dwFlags & DDEDM_REFRESHRATES) {
3399 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3400 ddsfd.x.dwRefreshRate = 60;
3403 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3404 ddsfd.dwBackBufferCount = 1;
3405 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3406 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3407 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
3408 /* FIXME: those masks would have to be set in depth > 8 */
3409 if (depths[i]==8) {
3410 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3411 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3412 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3413 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3414 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3415 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3416 } else {
3417 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3419 /* FIXME: We should query those from X itself */
3420 switch (depths[i]) {
3421 case 16:
3422 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3423 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3424 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3425 break;
3426 case 24:
3427 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3428 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3429 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3430 break;
3431 case 32:
3432 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3433 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3434 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3435 break;
3439 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3440 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3441 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3442 if (!modescb(&ddsfd,context)) return DD_OK;
3444 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3445 ddsfd.dwWidth = modes[j].w;
3446 ddsfd.dwHeight = modes[j].h;
3447 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3448 if (!modescb(&ddsfd,context)) return DD_OK;
3451 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3452 /* modeX is not standard VGA */
3454 ddsfd.dwHeight = 200;
3455 ddsfd.dwWidth = 320;
3456 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3457 if (!modescb(&ddsfd,context)) return DD_OK;
3460 return DD_OK;
3463 static HRESULT WINAPI Xlib_IDirectDraw2_EnumDisplayModes(
3464 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3466 XVisualInfo *vi;
3467 XPixmapFormatValues *pf;
3468 XVisualInfo vt;
3469 int nvisuals, npixmap, i;
3470 int send_mode;
3471 int has_8bpp = 0;
3472 DDSURFACEDESC ddsfd;
3473 static struct {
3474 int w,h;
3475 } modes[] = { /* some of the usual modes */
3476 {512,384},
3477 {640,400},
3478 {640,480},
3479 {800,600},
3480 {1024,768},
3481 {1280,1024}
3483 DWORD maxWidth, maxHeight;
3485 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
3486 ddsfd.dwSize = sizeof(ddsfd);
3487 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
3488 if (dwFlags & DDEDM_REFRESHRATES) {
3489 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3490 ddsfd.x.dwRefreshRate = 60;
3492 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3493 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3495 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3496 pf = XListPixmapFormats(display, &npixmap);
3498 i = 0;
3499 send_mode = 0;
3500 while (i < npixmap) {
3501 if ((has_8bpp == 0) && (pf[i].depth == 8)) {
3502 /* Special case of a 8bpp depth */
3503 has_8bpp = 1;
3504 send_mode = 1;
3506 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
3507 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3508 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
3509 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3510 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
3511 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3512 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3513 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3514 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3515 } else if (pf[i].depth > 8) {
3516 int j;
3518 /* All the 'true color' depths (15, 16 and 24)
3519 First, find the corresponding visual to extract the bit masks */
3520 for (j = 0; j < nvisuals; j++) {
3521 if (vi[j].depth == pf[i].depth) {
3522 ddsfd.ddsCaps.dwCaps = 0;
3523 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3524 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3525 ddsfd.ddpfPixelFormat.dwFourCC = 0;
3526 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
3527 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
3528 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
3529 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
3530 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3532 send_mode = 1;
3533 break;
3537 if (j == nvisuals)
3538 ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
3539 } else {
3540 send_mode = 0;
3543 if (send_mode) {
3544 int mode;
3546 if (TRACE_ON(ddraw)) {
3547 TRACE(ddraw, "Enumerating with pixel format : \n");
3548 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
3551 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
3552 /* Do not enumerate modes we cannot handle anyway */
3553 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
3554 break;
3556 ddsfd.dwWidth = modes[mode].w;
3557 ddsfd.dwHeight = modes[mode].h;
3559 /* Now, send the mode description to the application */
3560 TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
3561 if (!modescb(&ddsfd, context))
3562 goto exit_enum;
3565 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3566 /* modeX is not standard VGA */
3567 ddsfd.dwWidth = 320;
3568 ddsfd.dwHeight = 200;
3569 if (!modescb(&ddsfd, context))
3570 goto exit_enum;
3574 /* Hack to always enumerate a 8bpp depth */
3575 i++;
3576 if ((i == npixmap) && (has_8bpp == 0)) {
3577 i--;
3578 pf[i].depth = 8;
3582 exit_enum:
3583 TSXFree(vi);
3584 TSXFree(pf);
3586 return DD_OK;
3589 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
3590 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3592 #ifdef HAVE_LIBXXF86DGA
3593 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
3594 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3595 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3596 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3597 lpddsfd->lPitch = this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3598 lpddsfd->dwBackBufferCount = 1;
3599 lpddsfd->x.dwRefreshRate = 60;
3600 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3601 lpddsfd->ddpfPixelFormat = this->d.directdraw_pixelformat;
3602 return DD_OK;
3603 #else /* defined(HAVE_LIBXXF86DGA) */
3604 return E_UNEXPECTED;
3605 #endif /* defined(HAVE_LIBXXF86DGA) */
3608 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
3609 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
3611 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
3612 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3613 lpddsfd->dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3614 lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3615 lpddsfd->lPitch = lpddsfd->dwWidth * this->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3616 lpddsfd->dwBackBufferCount = 1;
3617 lpddsfd->x.dwRefreshRate = 60;
3618 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3619 lpddsfd->ddpfPixelFormat = this->d.directdraw_pixelformat;
3620 return DD_OK;
3623 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
3624 TRACE(ddraw,"(%p)->()\n",this);
3625 return DD_OK;
3628 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
3629 LPDIRECTDRAW2 this,LPDWORD freq
3631 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
3632 *freq = 60*100; /* 60 Hz */
3633 return DD_OK;
3636 /* what can we directly decompress? */
3637 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
3638 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
3640 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
3641 return DD_OK;
3644 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
3645 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
3647 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
3648 return DD_OK;
3651 static HRESULT WINAPI IDirectDraw2_Compact(
3652 LPDIRECTDRAW2 this )
3654 FIXME(ddraw,"(%p)->()\n", this );
3656 return DD_OK;
3659 static HRESULT WINAPI IDirectDraw2_GetGDISurface(LPDIRECTDRAW2 this,
3660 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
3661 FIXME(ddraw,"(%p)->(%p)\n", this, lplpGDIDDSSurface);
3663 return DD_OK;
3666 static HRESULT WINAPI IDirectDraw2_GetScanLine(LPDIRECTDRAW2 this,
3667 LPDWORD lpdwScanLine) {
3668 FIXME(ddraw,"(%p)->(%p)\n", this, lpdwScanLine);
3670 return DD_OK;
3673 static HRESULT WINAPI IDirectDraw2_Initialize(LPDIRECTDRAW2 this,
3674 GUID *lpGUID) {
3675 FIXME(ddraw,"(%p)->(%p)\n", this, lpGUID);
3677 return DD_OK;
3680 /* Note: Hack so we can reuse the old functions without compiler warnings */
3681 #ifdef __GNUC__
3682 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
3683 #else
3684 # define XCAST(fun) (void*)
3685 #endif
3687 static struct IDirectDraw_VTable dga_ddvt = {
3688 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3689 XCAST(AddRef)IDirectDraw2_AddRef,
3690 XCAST(Release)DGA_IDirectDraw2_Release,
3691 XCAST(Compact)IDirectDraw2_Compact,
3692 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3693 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3694 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3695 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3696 XCAST(EnumDisplayModes)DGA_IDirectDraw2_EnumDisplayModes,
3697 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3698 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3699 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3700 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3701 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3702 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3703 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3704 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3705 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3706 XCAST(Initialize)IDirectDraw2_Initialize,
3707 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3708 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3709 DGA_IDirectDraw_SetDisplayMode,
3710 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3713 static struct IDirectDraw_VTable xlib_ddvt = {
3714 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3715 XCAST(AddRef)IDirectDraw2_AddRef,
3716 XCAST(Release)Xlib_IDirectDraw2_Release,
3717 XCAST(Compact)IDirectDraw2_Compact,
3718 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3719 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3720 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3721 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3722 XCAST(EnumDisplayModes)Xlib_IDirectDraw2_EnumDisplayModes,
3723 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3724 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3725 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3726 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3727 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3728 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3729 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3730 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3731 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3732 XCAST(Initialize)IDirectDraw2_Initialize,
3733 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3734 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3735 Xlib_IDirectDraw_SetDisplayMode,
3736 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3739 #undef XCAST
3741 /*****************************************************************************
3742 * IDirectDraw2
3747 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
3748 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3750 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3753 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
3754 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
3756 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
3759 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
3760 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3762 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3763 this,ddscaps,total,free
3765 if (total) *total = this->e.dga.fb_memsize * 1024;
3766 if (free) *free = this->e.dga.fb_memsize * 1024;
3767 return DD_OK;
3770 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
3771 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
3773 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
3774 this,ddscaps,total,free
3776 if (total) *total = 2048 * 1024;
3777 if (free) *free = 2048 * 1024;
3778 return DD_OK;
3781 static IDirectDraw2_VTable dga_dd2vt = {
3782 DGA_IDirectDraw2_QueryInterface,
3783 IDirectDraw2_AddRef,
3784 DGA_IDirectDraw2_Release,
3785 IDirectDraw2_Compact,
3786 IDirectDraw2_CreateClipper,
3787 DGA_IDirectDraw2_CreatePalette,
3788 DGA_IDirectDraw2_CreateSurface,
3789 IDirectDraw2_DuplicateSurface,
3790 DGA_IDirectDraw2_EnumDisplayModes,
3791 IDirectDraw2_EnumSurfaces,
3792 IDirectDraw2_FlipToGDISurface,
3793 DGA_IDirectDraw2_GetCaps,
3794 DGA_IDirectDraw2_GetDisplayMode,
3795 IDirectDraw2_GetFourCCCodes,
3796 IDirectDraw2_GetGDISurface,
3797 IDirectDraw2_GetMonitorFrequency,
3798 IDirectDraw2_GetScanLine,
3799 IDirectDraw2_GetVerticalBlankStatus,
3800 IDirectDraw2_Initialize,
3801 DGA_IDirectDraw2_RestoreDisplayMode,
3802 IDirectDraw2_SetCooperativeLevel,
3803 DGA_IDirectDraw2_SetDisplayMode,
3804 IDirectDraw2_WaitForVerticalBlank,
3805 DGA_IDirectDraw2_GetAvailableVidMem
3808 static struct IDirectDraw2_VTable xlib_dd2vt = {
3809 Xlib_IDirectDraw2_QueryInterface,
3810 IDirectDraw2_AddRef,
3811 Xlib_IDirectDraw2_Release,
3812 IDirectDraw2_Compact,
3813 IDirectDraw2_CreateClipper,
3814 Xlib_IDirectDraw2_CreatePalette,
3815 Xlib_IDirectDraw2_CreateSurface,
3816 IDirectDraw2_DuplicateSurface,
3817 Xlib_IDirectDraw2_EnumDisplayModes,
3818 IDirectDraw2_EnumSurfaces,
3819 IDirectDraw2_FlipToGDISurface,
3820 Xlib_IDirectDraw2_GetCaps,
3821 Xlib_IDirectDraw2_GetDisplayMode,
3822 IDirectDraw2_GetFourCCCodes,
3823 IDirectDraw2_GetGDISurface,
3824 IDirectDraw2_GetMonitorFrequency,
3825 IDirectDraw2_GetScanLine,
3826 IDirectDraw2_GetVerticalBlankStatus,
3827 IDirectDraw2_Initialize,
3828 Xlib_IDirectDraw2_RestoreDisplayMode,
3829 IDirectDraw2_SetCooperativeLevel,
3830 Xlib_IDirectDraw2_SetDisplayMode,
3831 IDirectDraw2_WaitForVerticalBlank,
3832 Xlib_IDirectDraw2_GetAvailableVidMem
3835 /*****************************************************************************
3836 * IDirectDraw4
3840 static HRESULT WINAPI IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4 this,
3841 HDC hdc,
3842 LPDIRECTDRAWSURFACE *lpDDS) {
3843 FIXME(ddraw, "(%p)->(%08ld,%p)\n", this, (DWORD) hdc, lpDDS);
3845 return DD_OK;
3848 static HRESULT WINAPI IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4 this) {
3849 FIXME(ddraw, "(%p)->()\n", this);
3851 return DD_OK;
3854 static HRESULT WINAPI IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4 this) {
3855 FIXME(ddraw, "(%p)->()\n", this);
3857 return DD_OK;
3860 static HRESULT WINAPI IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4 this,
3861 LPDDDEVICEIDENTIFIER lpdddi,
3862 DWORD dwFlags) {
3863 FIXME(ddraw, "(%p)->(%p,%08lx)\n", this, lpdddi, dwFlags);
3865 return DD_OK;
3868 #ifdef __GNUC__
3869 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
3870 #else
3871 # define XCAST(fun) (void*)
3872 #endif
3875 static struct IDirectDraw4_VTable dga_dd4vt = {
3876 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
3877 XCAST(AddRef)IDirectDraw2_AddRef,
3878 XCAST(Release)DGA_IDirectDraw2_Release,
3879 XCAST(Compact)IDirectDraw2_Compact,
3880 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3881 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
3882 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
3883 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3884 XCAST(EnumDisplayModes)DGA_IDirectDraw2_EnumDisplayModes,
3885 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3886 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3887 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
3888 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
3889 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3890 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3891 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3892 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3893 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3894 XCAST(Initialize)IDirectDraw2_Initialize,
3895 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
3896 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3897 XCAST(SetDisplayMode)DGA_IDirectDraw_SetDisplayMode,
3898 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3899 XCAST(GetAvailableVidMem)DGA_IDirectDraw2_GetAvailableVidMem,
3900 IDirectDraw4_GetSurfaceFromDC,
3901 IDirectDraw4_RestoreAllSurfaces,
3902 IDirectDraw4_TestCooperativeLevel,
3903 IDirectDraw4_GetDeviceIdentifier
3906 static struct IDirectDraw4_VTable xlib_dd4vt = {
3907 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
3908 XCAST(AddRef)IDirectDraw2_AddRef,
3909 XCAST(Release)Xlib_IDirectDraw2_Release,
3910 XCAST(Compact)IDirectDraw2_Compact,
3911 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
3912 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
3913 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
3914 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
3915 XCAST(EnumDisplayModes)Xlib_IDirectDraw2_EnumDisplayModes,
3916 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
3917 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
3918 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
3919 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
3920 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
3921 XCAST(GetGDISurface)IDirectDraw2_GetGDISurface,
3922 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
3923 XCAST(GetScanLine)IDirectDraw2_GetScanLine,
3924 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
3925 XCAST(Initialize)IDirectDraw2_Initialize,
3926 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
3927 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
3928 XCAST(SetDisplayMode)Xlib_IDirectDraw_SetDisplayMode,
3929 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
3930 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2_GetAvailableVidMem,
3931 IDirectDraw4_GetSurfaceFromDC,
3932 IDirectDraw4_RestoreAllSurfaces,
3933 IDirectDraw4_TestCooperativeLevel,
3934 IDirectDraw4_GetDeviceIdentifier
3937 #undef XCAST
3939 /******************************************************************************
3940 * DirectDrawCreate
3943 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
3945 LRESULT ret;
3946 LPDIRECTDRAW ddraw = NULL;
3947 DWORD lastError;
3949 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
3951 SetLastError( ERROR_SUCCESS );
3952 ddraw = (LPDIRECTDRAW)GetWindowLongA( hwnd, ddrawXlibThisOffset );
3953 if( (!ddraw) &&
3954 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
3957 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
3960 if( ddraw )
3962 /* Perform any special direct draw functions */
3963 if (msg==WM_PAINT)
3964 ddraw->d.paintable = 1;
3966 /* Now let the application deal with the rest of this */
3967 if( ddraw->d.mainWindow )
3970 /* Don't think that we actually need to call this but...
3971 might as well be on the safe side of things... */
3973 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
3974 it should be the procedures of our fake window that gets called
3975 instead of those of the window provided by the application.
3976 And with this patch, mouse clicks work with Monkey Island III
3977 - Lionel */
3978 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
3980 if( !ret )
3982 /* We didn't handle the message - give it to the application */
3983 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
3984 ret = CallWindowProcA( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
3985 ddraw->d.mainWindow, msg, wParam, lParam );
3989 } else {
3990 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
3994 else
3996 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
3999 return ret;
4002 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4003 #ifdef HAVE_LIBXXF86DGA
4004 int memsize,banksize,width,major,minor,flags,height;
4005 char *addr;
4006 int fd;
4007 int depth;
4009 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4010 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4011 close(fd);
4013 if (fd == -1) {
4014 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4015 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4016 return E_UNEXPECTED;
4018 if (!DDRAW_DGA_Available()) {
4019 TRACE(ddraw,"No XF86DGA detected.\n");
4020 return DDERR_GENERIC;
4022 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
4023 (*lplpDD)->lpvtbl = &dga_ddvt;
4024 (*lplpDD)->ref = 1;
4025 TSXF86DGAQueryVersion(display,&major,&minor);
4026 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4027 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4028 if (!(flags & XF86DGADirectPresent))
4029 MSG("direct video is NOT PRESENT.\n");
4030 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4031 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4032 addr,width,banksize,memsize
4034 (*lplpDD)->e.dga.fb_width = width;
4035 (*lplpDD)->d.width = width;
4036 (*lplpDD)->e.dga.fb_addr = addr;
4037 (*lplpDD)->e.dga.fb_memsize = memsize;
4038 (*lplpDD)->e.dga.fb_banksize = banksize;
4040 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4041 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4042 (*lplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4043 #ifdef DIABLO_HACK
4044 (*lplpDD)->e.dga.vpmask = 1;
4045 #else
4046 (*lplpDD)->e.dga.vpmask = 0;
4047 #endif
4049 /* just assume the default depth is the DGA depth too */
4050 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4051 _common_depth_to_pixelformat(depth, &((*lplpDD)->d.directdraw_pixelformat), &((*lplpDD)->d.screen_pixelformat), NULL);
4052 #ifdef RESTORE_SIGNALS
4053 SIGNAL_InitHandlers();
4054 #endif
4056 return DD_OK;
4057 #else /* defined(HAVE_LIBXXF86DGA) */
4058 return DDERR_INVALIDDIRECTDRAWGUID;
4059 #endif /* defined(HAVE_LIBXXF86DGA) */
4062 BOOL
4063 DDRAW_XSHM_Available(void)
4065 #ifdef HAVE_LIBXXSHM
4066 if (TSXShmQueryExtension(display))
4068 int major, minor;
4069 Bool shpix;
4071 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4072 return 1;
4073 else
4074 return 0;
4076 else
4077 return 0;
4078 #else
4079 return 0;
4080 #endif
4083 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4084 int depth;
4086 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
4087 (*lplpDD)->lpvtbl = &xlib_ddvt;
4088 (*lplpDD)->ref = 1;
4089 (*lplpDD)->d.drawable = 0; /* in SetDisplayMode */
4091 /* At DirectDraw creation, the depth is the default depth */
4092 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4093 _common_depth_to_pixelformat(depth, &((*lplpDD)->d.directdraw_pixelformat), &((*lplpDD)->d.screen_pixelformat), NULL);
4094 (*lplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4095 (*lplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4097 #ifdef HAVE_LIBXXSHM
4098 /* Test if XShm is available. */
4099 if (((*lplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4100 TRACE(ddraw, "Using XShm extension.\n");
4101 #endif
4103 return DD_OK;
4106 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4107 char xclsid[50];
4108 WNDCLASSA wc;
4109 WND* pParentWindow;
4110 HRESULT ret;
4112 if (HIWORD(lpGUID))
4113 WINE_StringFromCLSID(lpGUID,xclsid);
4114 else {
4115 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4116 lpGUID = NULL;
4119 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
4121 if (!lpGUID) {
4122 /* if they didn't request a particular interface, use the best
4123 * supported one */
4124 if (DDRAW_DGA_Available())
4125 lpGUID = &DGA_DirectDraw_GUID;
4126 else
4127 lpGUID = &XLIB_DirectDraw_GUID;
4130 wc.style = CS_GLOBALCLASS;
4131 wc.lpfnWndProc = Xlib_DDWndProc;
4132 wc.cbClsExtra = 0;
4133 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
4134 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
4136 /* We can be a child of the desktop since we're really important */
4137 pParentWindow = WIN_GetDesktop();
4138 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
4139 wc.hInstance = 0;
4141 wc.hIcon = 0;
4142 wc.hCursor = (HCURSOR)IDC_ARROWA;
4143 wc.hbrBackground= NULL_BRUSH;
4144 wc.lpszMenuName = 0;
4145 wc.lpszClassName= "WINE_DirectDraw";
4146 RegisterClassA(&wc);
4148 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4149 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4150 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4151 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4152 else
4153 goto err;
4156 (*lplpDD)->d.winclass = RegisterClassA(&wc);
4157 return ret;
4159 err:
4160 ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4161 return DDERR_INVALIDDIRECTDRAWGUID;