1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
6 * When DirectVideo mode is enabled you can no longer use 'normal' X
7 * applications nor can you switch to a virtual console. Also, enabling
8 * only works, if you have switched to the screen where the application
10 * Some ways to debug this stuff are:
11 * - A terminal connected to the serial port. Can be bought used for cheap.
12 * (This is the method I am using.)
13 * - Another machine connected over some kind of network.
20 #include <sys/signal.h>
26 #ifdef HAVE_LIBXXF86VM
27 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
28 this is a crude hack to get around it */
30 #include "ts_xf86vmode.h"
34 #include "interfaces.h"
50 #ifdef HAVE_LIBXXF86DGA
51 #include "ts_xf86dga.h"
55 #include <sys/types.h>
61 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
64 /* Restore signal handlers overwritten by XF86DGA
65 * this is a define, for it will only work in emulator mode
67 #undef RESTORE_SIGNALS
69 /* Where do these GUIDs come from? mkuuid.
70 * They exist solely to distinguish between the targets Wine support,
71 * and should be different than any other GUIDs in existence.
73 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
77 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
80 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
84 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
87 static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt;
88 static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt;
89 static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt;
90 static struct IDirectDrawClipper_VTable ddclipvt;
91 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
92 static struct IDirect3D_VTable d3dvt;
93 static struct IDirect3D2_VTable d3d2vt;
98 #ifdef HAVE_LIBXXF86DGA
99 int evbase, evret, fd;
104 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
105 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
106 /* others. --stephenc */
107 if ((fd = open("/dev/mem", O_RDWR)) != -1)
110 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
111 #else /* defined(HAVE_LIBXXF86DGA) */
113 #endif /* defined(HAVE_LIBXXF86DGA) */
117 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
118 if (DDRAW_DGA_Available()) {
119 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
121 ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
122 ddenumproc(NULL,"WINE","display",data);
126 /* What is this doing here? */
128 DSoundHelp(DWORD x,DWORD y,DWORD z) {
129 FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
134 /******************************************************************************
135 * internal helper functions
137 static void _dump_DDBLTFX(DWORD flagmask) {
143 #define FE(x) { x, #x},
144 FE(DDBLTFX_ARITHSTRETCHY)
145 FE(DDBLTFX_MIRRORLEFTRIGHT)
146 FE(DDBLTFX_MIRRORUPDOWN)
147 FE(DDBLTFX_NOTEARING)
148 FE(DDBLTFX_ROTATE180)
149 FE(DDBLTFX_ROTATE270)
151 FE(DDBLTFX_ZBUFFERRANGE)
152 FE(DDBLTFX_ZBUFFERBASEDEST)
154 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
155 if (flags[i].mask & flagmask) {
156 DUMP("%s ",flags[i].name);
163 static void _dump_DDBLTFAST(DWORD flagmask) {
169 #define FE(x) { x, #x},
170 FE(DDBLTFAST_NOCOLORKEY)
171 FE(DDBLTFAST_SRCCOLORKEY)
172 FE(DDBLTFAST_DESTCOLORKEY)
175 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
176 if (flags[i].mask & flagmask)
177 DUMP("%s ",flags[i].name);
181 static void _dump_DDBLT(DWORD flagmask) {
187 #define FE(x) { x, #x},
189 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
190 FE(DDBLT_ALPHADESTNEG)
191 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
192 FE(DDBLT_ALPHAEDGEBLEND)
194 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
195 FE(DDBLT_ALPHASRCNEG)
196 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
202 FE(DDBLT_KEYDESTOVERRIDE)
204 FE(DDBLT_KEYSRCOVERRIDE)
206 FE(DDBLT_ROTATIONANGLE)
208 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
209 FE(DDBLT_ZBUFFERDESTOVERRIDE)
210 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
211 FE(DDBLT_ZBUFFERSRCOVERRIDE)
215 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
216 if (flags[i].mask & flagmask)
217 DUMP("%s ",flags[i].name);
220 static void _dump_DDSCAPS(DWORD flagmask) {
226 #define FE(x) { x, #x},
227 FE(DDSCAPS_RESERVED1)
229 FE(DDSCAPS_BACKBUFFER)
232 FE(DDSCAPS_FRONTBUFFER)
233 FE(DDSCAPS_OFFSCREENPLAIN)
236 FE(DDSCAPS_PRIMARYSURFACE)
237 FE(DDSCAPS_PRIMARYSURFACELEFT)
238 FE(DDSCAPS_SYSTEMMEMORY)
241 FE(DDSCAPS_VIDEOMEMORY)
243 FE(DDSCAPS_WRITEONLY)
246 FE(DDSCAPS_LIVEVIDEO)
250 FE(DDSCAPS_RESERVED2)
251 FE(DDSCAPS_ALLOCONLOAD)
252 FE(DDSCAPS_VIDEOPORT)
253 FE(DDSCAPS_LOCALVIDMEM)
254 FE(DDSCAPS_NONLOCALVIDMEM)
255 FE(DDSCAPS_STANDARDVGAMODE)
256 FE(DDSCAPS_OPTIMIZED)
258 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
259 if (flags[i].mask & flagmask)
260 DUMP("%s ",flags[i].name);
264 static void _dump_DDSD(DWORD flagmask) {
274 FE(DDSD_BACKBUFFERCOUNT)
275 FE(DDSD_ZBUFFERBITDEPTH)
276 FE(DDSD_ALPHABITDEPTH)
278 FE(DDSD_CKDESTOVERLAY)
280 FE(DDSD_CKSRCOVERLAY)
287 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
288 if (flags[i].mask & flagmask)
289 DUMP("%s ",flags[i].name);
293 static void _dump_DDCOLORKEY(DWORD flagmask) {
299 #define FE(x) { x, #x},
303 FE(DDPF_PALETTEINDEXED4)
304 FE(DDPF_PALETTEINDEXEDTO8)
305 FE(DDPF_PALETTEINDEXED8)
311 FE(DDPF_PALETTEINDEXED1)
312 FE(DDPF_PALETTEINDEXED2)
315 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
316 if (flags[i].mask & flagmask)
317 DUMP("%s ",flags[i].name);
321 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
322 _dump_DDCOLORKEY(pf->dwFlags);
323 DUMP("dwFourCC : %ld\n", pf->dwFourCC);
324 DUMP("RBG bit cbout : %ld\n", pf->x.dwRGBBitCount);
325 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
326 pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
329 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
330 static XVisualInfo *vi;
335 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
338 if (ddraw->d.depth==8) {
339 pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
340 pf->x.dwRGBBitCount = 8;
341 pf->y.dwRBitMask = 0;
342 pf->z.dwGBitMask = 0;
343 pf->xx.dwBBitMask = 0;
344 pf->xy.dwRGBAlphaBitMask= 0;
347 if (ddraw->d.depth==16) {
348 pf->dwFlags = DDPF_RGB;
349 pf->x.dwRGBBitCount = 16;
350 pf->y.dwRBitMask = vi[0].red_mask;
351 pf->z.dwGBitMask = vi[0].green_mask;
352 pf->xx.dwBBitMask = vi[0].blue_mask;
353 pf->xy.dwRGBAlphaBitMask= 0;
356 FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
357 return DDERR_GENERIC;
360 /******************************************************************************
361 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
363 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
364 * DDS and DDS2 use those functions. (Function calls did not change (except
365 * using different DirectDrawSurfaceX version), just added flags and functions)
367 static HRESULT WINAPI IDirectDrawSurface3_Lock(
368 LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
370 TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
371 this,lprect,lpddsd,flags,(DWORD)hnd);
372 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
373 WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
374 this,lprect,lpddsd,flags,(DWORD)hnd);
376 /* First, copy the Surface description */
377 *lpddsd = this->s.surface_desc;
379 /* If asked only for a part, change the surface pointer */
381 FIXME(ddraw," lprect: %dx%d-%dx%d\n",
382 lprect->top,lprect->left,lprect->bottom,lprect->right
384 lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface +
385 (lprect->top*this->s.surface_desc.lPitch) +
386 (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
388 assert(this->s.surface_desc.y.lpSurface);
393 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
394 LPDIRECTDRAWSURFACE3 this,LPVOID surface
396 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
400 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
401 LPDIRECTDRAWSURFACE3 this,LPVOID surface)
403 TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
405 if (!this->s.ddraw->e.xlib.paintable)
408 /* Only redraw the screen when unlocking the buffer that is on screen */
409 if ((this->t.xlib.image != NULL) &&
410 (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
412 if (this->s.ddraw->e.xlib.xshm_active)
413 TSXShmPutImage(display,
414 this->s.ddraw->e.xlib.drawable,
415 DefaultGCOfScreen(screen),
418 this->t.xlib.image->width,
419 this->t.xlib.image->height,
423 TSXPutImage( display,
424 this->s.ddraw->e.xlib.drawable,
425 DefaultGCOfScreen(screen),
428 this->t.xlib.image->width,
429 this->t.xlib.image->height);
431 if (this->s.palette && this->s.palette->cm)
432 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
438 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
439 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
441 #ifdef HAVE_LIBXXF86DGA
442 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
444 if (this->s.backbuffer)
445 flipto = this->s.backbuffer;
449 TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
451 if (flipto->s.palette && flipto->s.palette->cm) {
452 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
454 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
460 tmp = this->t.dga.fb_height;
461 this->t.dga.fb_height = flipto->t.dga.fb_height;
462 flipto->t.dga.fb_height = tmp;
464 ptmp = this->s.surface_desc.y.lpSurface;
465 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
466 flipto->s.surface_desc.y.lpSurface = ptmp;
469 #else /* defined(HAVE_LIBXXF86DGA) */
471 #endif /* defined(HAVE_LIBXXF86DGA) */
474 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
475 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
477 TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
478 if (!this->s.ddraw->e.xlib.paintable)
482 if (this->s.backbuffer)
483 flipto = this->s.backbuffer;
489 if (this->s.ddraw->e.xlib.xshm_active) {
490 TSXShmPutImage(display,
491 this->s.ddraw->e.xlib.drawable,
492 DefaultGCOfScreen(screen),
493 flipto->t.xlib.image,
495 flipto->t.xlib.image->width,
496 flipto->t.xlib.image->height,
501 this->s.ddraw->e.xlib.drawable,
502 DefaultGCOfScreen(screen),
503 flipto->t.xlib.image,
505 flipto->t.xlib.image->width,
506 flipto->t.xlib.image->height);
508 if (flipto->s.palette && flipto->s.palette->cm) {
509 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,flipto->s.palette->cm);
514 tmp = this->t.xlib.image;
515 this->t.xlib.image = flipto->t.xlib.image;
516 flipto->t.xlib.image = tmp;
517 surf = this->s.surface_desc.y.lpSurface;
518 this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface;
519 flipto->s.surface_desc.y.lpSurface = surf;
525 /* The IDirectDrawSurface3::SetPalette method attaches the specified
526 * DirectDrawPalette object to a surface. The surface uses this palette for all
527 * subsequent operations. The palette change takes place immediately.
529 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
530 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
533 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
535 if (!(pal->cm) && (this->s.ddraw->d.depth<=8)) {
536 pal->cm = TSXCreateColormap(display,this->s.ddraw->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
537 /* FIXME: this is not correct, when using -managed */
538 TSXInstallColormap(display,pal->cm);
539 for (i=0;i<256;i++) {
542 xc.red = pal->palents[i].peRed<<8;
543 xc.blue = pal->palents[i].peBlue<<8;
544 xc.green = pal->palents[i].peGreen<<8;
545 xc.flags = DoRed|DoBlue|DoGreen;
547 TSXStoreColor(display,pal->cm,&xc);
550 /* According to spec, we are only supposed to
551 * AddRef if this is not the same palette.
553 if( this->s.palette != pal )
556 pal->lpvtbl->fnAddRef( pal );
557 if( this->s.palette != NULL )
558 this->s.palette->lpvtbl->fnRelease( this->s.palette );
559 this->s.palette = pal;
561 /* I think that we need to attach it to all backbuffers...*/
562 if( this->s.backbuffer ) {
563 if( this->s.backbuffer->s.palette )
564 this->s.backbuffer->s.palette->lpvtbl->fnRelease(
565 this->s.backbuffer->s.palette );
566 this->s.backbuffer->s.palette = pal;
568 pal->lpvtbl->fnAddRef( pal );
570 /* Perform the refresh */
571 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
576 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
577 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
579 TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
580 #ifdef HAVE_LIBXXF86DGA
581 /* According to spec, we are only supposed to
582 * AddRef if this is not the same palette.
584 if( this->s.palette != pal )
587 pal->lpvtbl->fnAddRef( pal );
588 if( this->s.palette != NULL )
589 this->s.palette->lpvtbl->fnRelease( this->s.palette );
590 this->s.palette = pal;
592 /* I think that we need to attach it to all backbuffers...*/
593 if( this->s.backbuffer ) {
594 if( this->s.backbuffer->s.palette )
595 this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
596 this->s.backbuffer->s.palette = pal;
597 if( pal ) pal->lpvtbl->fnAddRef( pal );
599 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
602 #else /* defined(HAVE_LIBXXF86DGA) */
604 #endif /* defined(HAVE_LIBXXF86DGA) */
609 static HRESULT WINAPI IDirectDrawSurface3_Blt(
610 LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
613 DDSURFACEDESC ddesc,sdesc;
616 TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n",
617 this,rdst,src,rsrc,dwFlags,lpbltfx);
620 src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0);
621 this->lpvtbl->fnLock(this,NULL,&ddesc,0,0);
623 if (TRACE_ON(ddraw)) {
624 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
625 if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
626 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
627 if (dwFlags & DDBLT_DDFX) {
628 TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
633 memcpy(&xdst,rdst,sizeof(xdst));
636 xdst.bottom = ddesc.dwHeight;
638 xdst.right = ddesc.dwWidth;
642 memcpy(&xsrc,rsrc,sizeof(xsrc));
646 xsrc.bottom = sdesc.dwHeight;
648 xsrc.right = sdesc.dwWidth;
650 memset(&xsrc,0,sizeof(xsrc));
654 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
656 if (dwFlags & DDBLT_COLORFILL) {
657 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
660 xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch;
661 for (i=xdst.top;i<xdst.bottom;i++) {
662 xpixel = xline+bpp*xdst.left;
664 for (j=xdst.left;j<xdst.right;j++) {
665 /* FIXME: this only works on little endian
666 * architectures, where DWORD starts with low
669 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
672 xline += ddesc.lPitch;
674 dwFlags &= ~(DDBLT_COLORFILL);
679 TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
684 if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) &&
685 (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) &&
686 (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) &&
687 (xdst.left==0) && (xdst.right ==ddesc.dwWidth) &&
690 memcpy(ddesc.y.lpSurface,
692 ddesc.dwHeight * ddesc.lPitch);
694 int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
695 int height = xsrc.bottom - xsrc.top;
696 int width = (xsrc.right - xsrc.left) * bpp;
699 for (h = 0; h < height; h++) {
700 memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp,
701 sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp,
706 if (dwFlags && FIXME_ON(ddraw)) {
707 FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags);
710 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
711 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
716 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
717 LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
720 DDSURFACEDESC ddesc,sdesc;
722 if (TRACE_ON(ddraw)) {
723 TRACE(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
724 this,dstx,dsty,src,rsrc,trans
726 TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
727 TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
729 /* We need to lock the surfaces, or we won't get refreshes when done. */
730 src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
731 this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0);
732 bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
733 for (i=0;i<rsrc->bottom-rsrc->top;i++) {
734 memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp,
735 sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp,
736 (rsrc->right-rsrc->left)*bpp
739 this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface);
740 src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface);
744 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
745 LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
747 FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
753 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
754 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
756 TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
757 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
761 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
762 LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
764 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
767 /* Simply copy the surface description stored in the object */
768 *ddsd = this->s.surface_desc;
770 if (TRACE_ON(ddraw)) {
771 fprintf(stderr," flags: ");
772 _dump_DDSD(ddsd->dwFlags);
773 if (ddsd->dwFlags & DDSD_CAPS) {
774 fprintf(stderr, " caps: ");
775 _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
777 fprintf(stderr,"\n");
783 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
784 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
786 return ++(this->ref);
789 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
790 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
792 #ifdef HAVE_LIBXXF86DGA
793 if (!--(this->ref)) {
794 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
795 /* clear out of surface list */
796 if (this->t.dga.fb_height == -1) {
797 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
799 this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
801 HeapFree(GetProcessHeap(),0,this);
804 #endif /* defined(HAVE_LIBXXF86DGA) */
808 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
809 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
811 if (!--(this->ref)) {
812 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
814 if( this->s.backbuffer )
815 this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
817 if (this->t.xlib.image != NULL) {
818 this->t.xlib.image->data = NULL;
821 if (this->s.ddraw->e.xlib.xshm_active) {
822 TSXShmDetach(display, &(this->t.xlib.shminfo));
823 TSXDestroyImage(this->t.xlib.image);
824 shmdt(this->t.xlib.shminfo.shmaddr);
827 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
828 TSXDestroyImage(this->t.xlib.image);
833 this->t.xlib.image = 0;
835 HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface);
839 this->s.palette->lpvtbl->fnRelease(this->s.palette);
841 HeapFree(GetProcessHeap(),0,this);
848 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
849 LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
851 TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
852 this, lpddsd, lpdsf);
854 if (TRACE_ON(ddraw)) {
855 TRACE(ddraw," caps ");
856 _dump_DDSCAPS(lpddsd->dwCaps);
859 if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
860 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
864 /* FIXME: should handle more than one backbuffer */
865 *lpdsf = this->s.backbuffer;
867 if( this->s.backbuffer )
868 this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
873 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
874 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
876 TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd);
878 return DDERR_ALREADYINITIALIZED;
881 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
882 LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
884 TRACE(ddraw,"(%p)->(%p)\n",this,pf);
886 *pf = this->s.surface_desc.ddpfPixelFormat;
891 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
892 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
896 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
897 LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
899 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
903 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
904 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
906 FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
910 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
911 LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
913 FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
915 /* This hack will be enough for the moment */
916 if (this->s.backbuffer == NULL)
917 this->s.backbuffer = surf;
921 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
922 FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
923 *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
927 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
928 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
929 EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps);
934 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
937 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
938 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
940 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
941 * the same interface. And IUnknown does that too of course.
943 if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
944 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
945 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
946 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
949 this->lpvtbl->fnAddRef(this);
952 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
953 return OLE_E_ENUM_NOMORE;
956 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
957 TRACE(ddraw,"(%p)->(), stub!\n",this);
961 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
962 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
966 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
967 FIXME(ddraw,"(%p)->(),stub!\n",this);
971 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
972 LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
974 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
976 if( dwFlags & DDCKEY_SRCBLT )
977 dwFlags &= ~DDCKEY_SRCBLT;
979 TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
983 static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect(
984 LPDIRECTDRAWSURFACE3 this,
987 FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect);
992 static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface(
993 LPDIRECTDRAWSURFACE3 this,
995 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface )
997 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface);
1002 static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders(
1003 LPDIRECTDRAWSURFACE3 this,
1006 LPDDENUMSURFACESCALLBACK lpfnCallback )
1008 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags,
1009 lpContext, lpfnCallback );
1014 static HRESULT WINAPI IDirectDrawSurface3_GetClipper(
1015 LPDIRECTDRAWSURFACE3 this,
1016 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1018 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper);
1023 static HRESULT WINAPI IDirectDrawSurface3_GetColorKey(
1024 LPDIRECTDRAWSURFACE3 this,
1026 LPDDCOLORKEY lpDDColorKey )
1028 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDColorKey);
1033 static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus(
1034 LPDIRECTDRAWSURFACE3 this,
1037 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1042 static HRESULT WINAPI IDirectDrawSurface3_GetPalette(
1043 LPDIRECTDRAWSURFACE3 this,
1044 LPDIRECTDRAWPALETTE* lplpDDPalette )
1046 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette);
1051 static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition(
1052 LPDIRECTDRAWSURFACE3 this,
1056 FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY);
1061 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay(
1062 LPDIRECTDRAWSURFACE3 this,
1064 LPDIRECTDRAWSURFACE3 lpDDDestSurface,
1065 LPRECT32 lpDestRect,
1067 LPDDOVERLAYFX lpDDOverlayFx )
1069 FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1070 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1075 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay(
1076 LPDIRECTDRAWSURFACE3 this,
1079 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1084 static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder(
1085 LPDIRECTDRAWSURFACE3 this,
1087 LPDIRECTDRAWSURFACE3 lpDDSReference )
1089 FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference);
1094 static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface(
1095 LPDIRECTDRAWSURFACE3 this,
1098 FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD);
1103 static HRESULT WINAPI IDirectDrawSurface3_PageLock(
1104 LPDIRECTDRAWSURFACE3 this,
1107 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1112 static HRESULT WINAPI IDirectDrawSurface3_PageUnlock(
1113 LPDIRECTDRAWSURFACE3 this,
1116 FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags);
1121 static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc(
1122 LPDIRECTDRAWSURFACE3 this,
1123 LPDDSURFACEDESC lpDDSD,
1126 FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags);
1131 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
1132 IDirectDrawSurface3_QueryInterface,
1133 IDirectDrawSurface3_AddRef,
1134 DGA_IDirectDrawSurface3_Release,
1135 IDirectDrawSurface3_AddAttachedSurface,
1136 IDirectDrawSurface3_AddOverlayDirtyRect,
1137 IDirectDrawSurface3_Blt,
1138 IDirectDrawSurface3_BltBatch,
1139 IDirectDrawSurface3_BltFast,
1140 IDirectDrawSurface3_DeleteAttachedSurface,
1141 IDirectDrawSurface3_EnumAttachedSurfaces,
1142 IDirectDrawSurface3_EnumOverlayZOrders,
1143 DGA_IDirectDrawSurface3_Flip,
1144 IDirectDrawSurface3_GetAttachedSurface,
1145 IDirectDrawSurface3_GetBltStatus,
1146 IDirectDrawSurface3_GetCaps,
1147 IDirectDrawSurface3_GetClipper,
1148 IDirectDrawSurface3_GetColorKey,
1149 IDirectDrawSurface3_GetDC,
1150 IDirectDrawSurface3_GetFlipStatus,
1151 IDirectDrawSurface3_GetOverlayPosition,
1152 IDirectDrawSurface3_GetPalette,
1153 IDirectDrawSurface3_GetPixelFormat,
1154 IDirectDrawSurface3_GetSurfaceDesc,
1155 IDirectDrawSurface3_Initialize,
1156 IDirectDrawSurface3_IsLost,
1157 IDirectDrawSurface3_Lock,
1158 IDirectDrawSurface3_ReleaseDC,
1159 IDirectDrawSurface3_Restore,
1160 IDirectDrawSurface3_SetClipper,
1161 IDirectDrawSurface3_SetColorKey,
1162 IDirectDrawSurface3_SetOverlayPosition,
1163 DGA_IDirectDrawSurface3_SetPalette,
1164 DGA_IDirectDrawSurface3_Unlock,
1165 IDirectDrawSurface3_UpdateOverlay,
1166 IDirectDrawSurface3_UpdateOverlayDisplay,
1167 IDirectDrawSurface3_UpdateOverlayZOrder,
1168 IDirectDrawSurface3_GetDDInterface,
1169 IDirectDrawSurface3_PageLock,
1170 IDirectDrawSurface3_PageUnlock,
1171 IDirectDrawSurface3_SetSurfaceDesc,
1174 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
1175 IDirectDrawSurface3_QueryInterface,
1176 IDirectDrawSurface3_AddRef,
1177 Xlib_IDirectDrawSurface3_Release,
1178 IDirectDrawSurface3_AddAttachedSurface,
1179 IDirectDrawSurface3_AddOverlayDirtyRect,
1180 IDirectDrawSurface3_Blt,
1181 IDirectDrawSurface3_BltBatch,
1182 IDirectDrawSurface3_BltFast,
1183 IDirectDrawSurface3_DeleteAttachedSurface,
1184 IDirectDrawSurface3_EnumAttachedSurfaces,
1185 IDirectDrawSurface3_EnumOverlayZOrders,
1186 Xlib_IDirectDrawSurface3_Flip,
1187 IDirectDrawSurface3_GetAttachedSurface,
1188 IDirectDrawSurface3_GetBltStatus,
1189 IDirectDrawSurface3_GetCaps,
1190 IDirectDrawSurface3_GetClipper,
1191 IDirectDrawSurface3_GetColorKey,
1192 IDirectDrawSurface3_GetDC,
1193 IDirectDrawSurface3_GetFlipStatus,
1194 IDirectDrawSurface3_GetOverlayPosition,
1195 IDirectDrawSurface3_GetPalette,
1196 IDirectDrawSurface3_GetPixelFormat,
1197 IDirectDrawSurface3_GetSurfaceDesc,
1198 IDirectDrawSurface3_Initialize,
1199 IDirectDrawSurface3_IsLost,
1200 IDirectDrawSurface3_Lock,
1201 IDirectDrawSurface3_ReleaseDC,
1202 IDirectDrawSurface3_Restore,
1203 IDirectDrawSurface3_SetClipper,
1204 IDirectDrawSurface3_SetColorKey,
1205 IDirectDrawSurface3_SetOverlayPosition,
1206 Xlib_IDirectDrawSurface3_SetPalette,
1207 Xlib_IDirectDrawSurface3_Unlock,
1208 IDirectDrawSurface3_UpdateOverlay,
1209 IDirectDrawSurface3_UpdateOverlayDisplay,
1210 IDirectDrawSurface3_UpdateOverlayZOrder,
1211 IDirectDrawSurface3_GetDDInterface,
1212 IDirectDrawSurface3_PageLock,
1213 IDirectDrawSurface3_PageUnlock,
1214 IDirectDrawSurface3_SetSurfaceDesc,
1217 /******************************************************************************
1218 * DirectDrawCreateClipper (DDRAW.7)
1220 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1221 LPDIRECTDRAWCLIPPER *lplpDDClipper,
1222 LPUNKNOWN pUnkOuter)
1224 TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
1226 *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1227 (*lplpDDClipper)->lpvtbl = &ddclipvt;
1228 (*lplpDDClipper)->ref = 1;
1233 /******************************************************************************
1234 * IDirectDrawClipper
1236 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
1237 LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
1239 FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
1243 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
1244 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1249 HeapFree(GetProcessHeap(),0,this);
1253 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
1254 LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
1256 FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
1261 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
1262 LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
1264 FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
1268 static struct IDirectDrawClipper_VTable ddclipvt = {
1271 IDirectDrawClipper_Release,
1272 IDirectDrawClipper_GetClipList,
1276 IDirectDrawClipper_SetClipList,
1277 IDirectDrawClipper_SetHwnd
1280 /******************************************************************************
1281 * IDirectDrawPalette
1283 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
1284 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1288 TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1289 this,x,start,count,palent);
1291 if (!this->cm) /* should not happen */ {
1292 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
1293 return DDERR_GENERIC;
1295 for (i=0;i<count;i++) {
1296 palent[i].peRed = this->palents[start+i].peRed;
1297 palent[i].peBlue = this->palents[start+i].peBlue;
1298 palent[i].peGreen = this->palents[start+i].peGreen;
1299 palent[i].peFlags = this->palents[start+i].peFlags;
1305 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
1306 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1311 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1312 this,x,start,count,palent
1314 for (i=0;i<count;i++) {
1315 xc.red = palent[i].peRed<<8;
1316 xc.blue = palent[i].peBlue<<8;
1317 xc.green = palent[i].peGreen<<8;
1318 xc.flags = DoRed|DoBlue|DoGreen;
1322 TSXStoreColor(display,this->cm,&xc);
1324 this->palents[start+i].peRed = palent[i].peRed;
1325 this->palents[start+i].peBlue = palent[i].peBlue;
1326 this->palents[start+i].peGreen = palent[i].peGreen;
1327 this->palents[start+i].peFlags = palent[i].peFlags;
1329 if (!this->cm) /* should not happen */ {
1334 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1335 LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1337 #ifdef HAVE_LIBXXF86DGA
1342 TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1343 this,x,start,count,palent
1345 if (!this->cm) /* should not happen */ {
1346 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1347 return DDERR_GENERIC;
1349 /* FIXME: free colorcells instead of freeing whole map */
1351 this->cm = TSXCopyColormapAndFree(display,this->cm);
1352 TSXFreeColormap(display,cm);
1354 for (i=0;i<count;i++) {
1355 xc.red = palent[i].peRed<<8;
1356 xc.blue = palent[i].peBlue<<8;
1357 xc.green = palent[i].peGreen<<8;
1358 xc.flags = DoRed|DoBlue|DoGreen;
1361 TSXStoreColor(display,this->cm,&xc);
1363 this->palents[start+i].peRed = palent[i].peRed;
1364 this->palents[start+i].peBlue = palent[i].peBlue;
1365 this->palents[start+i].peGreen = palent[i].peGreen;
1366 this->palents[start+i].peFlags = palent[i].peFlags;
1368 TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1370 #else /* defined(HAVE_LIBXXF86DGA) */
1371 return E_UNEXPECTED;
1372 #endif /* defined(HAVE_LIBXXF86DGA) */
1375 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1376 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1377 if (!--(this->ref)) {
1379 TSXFreeColormap(display,this->cm);
1382 HeapFree(GetProcessHeap(),0,this);
1388 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1390 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1391 return ++(this->ref);
1394 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1395 LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1397 TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent);
1399 return DDERR_ALREADYINITIALIZED;
1402 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1403 LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1405 FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1409 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1410 LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj )
1414 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1415 FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1420 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1421 IDirectDrawPalette_QueryInterface,
1422 IDirectDrawPalette_AddRef,
1423 IDirectDrawPalette_Release,
1424 IDirectDrawPalette_GetCaps,
1425 IDirectDrawPalette_GetEntries,
1426 IDirectDrawPalette_Initialize,
1427 DGA_IDirectDrawPalette_SetEntries
1430 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1431 IDirectDrawPalette_QueryInterface,
1432 IDirectDrawPalette_AddRef,
1433 IDirectDrawPalette_Release,
1434 IDirectDrawPalette_GetCaps,
1435 IDirectDrawPalette_GetEntries,
1436 IDirectDrawPalette_Initialize,
1437 Xlib_IDirectDrawPalette_SetEntries
1440 /*******************************************************************************
1443 static HRESULT WINAPI IDirect3D_QueryInterface(
1444 LPDIRECT3D this,REFIID refiid,LPVOID *obj
1446 /* FIXME: Not sure if this is correct */
1449 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1450 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1451 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1453 this->lpvtbl->fnAddRef(this);
1456 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1459 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1461 d3d->ddraw = (LPDIRECTDRAW)this;
1462 this->lpvtbl->fnAddRef(this);
1463 d3d->lpvtbl = &d3dvt;
1467 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1470 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1472 d3d->ddraw = (LPDIRECTDRAW)this;
1473 this->lpvtbl->fnAddRef(this);
1474 d3d->lpvtbl = &d3d2vt;
1478 FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1479 return OLE_E_ENUM_NOMORE;
1482 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1483 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1485 return ++(this->ref);
1488 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1490 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1492 if (!--(this->ref)) {
1493 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1494 HeapFree(GetProcessHeap(),0,this);
1500 static HRESULT WINAPI IDirect3D_Initialize(
1501 LPDIRECT3D this, REFIID refiid )
1503 /* FIXME: Not sure if this is correct */
1506 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1507 FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1509 return DDERR_ALREADYINITIALIZED;
1512 /*******************************************************************************
1515 static struct IDirect3D_VTable d3dvt = {
1516 (void*)IDirect3D_QueryInterface,
1517 (void*)IDirect3D_AddRef,
1518 (void*)IDirect3D_Release,
1519 IDirect3D_Initialize,
1527 /*******************************************************************************
1530 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1531 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1533 if (!--(this->ref)) {
1534 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1535 HeapFree(GetProcessHeap(),0,this);
1541 static HRESULT WINAPI IDirect3D2_EnumDevices(
1542 LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1544 D3DDEVICEDESC d1,d2;
1546 FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1548 d1.dwSize = sizeof(d1);
1551 d2.dwSize = sizeof(d2);
1553 cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1558 static struct IDirect3D2_VTable d3d2vt = {
1562 IDirect3D2_EnumDevices,
1570 /*******************************************************************************
1574 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1575 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1577 static INT32 ddrawXlibThisOffset = 0;
1579 static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this,
1580 LPDDSURFACEDESC lpddsd,
1581 LPDIRECTDRAWSURFACE lpdsf)
1585 /* The surface was already allocated when entering in this function */
1586 if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
1587 /* No pixel format => use DirectDraw's format */
1588 _getpixelformat(this,&(lpddsd->ddpfPixelFormat));
1589 lpddsd->dwFlags |= DDSD_PIXELFORMAT;
1591 /* To check what the program wants */
1592 if (TRACE_ON(ddraw)) {
1593 _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
1597 bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
1599 /* Copy the surface description */
1600 lpdsf->s.surface_desc = *lpddsd;
1602 lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1603 lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
1604 lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
1606 TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
1611 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1612 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1614 #ifdef HAVE_LIBXXF86DGA
1617 TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1618 if (TRACE_ON(ddraw)) {
1619 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1620 _dump_DDSD(lpddsd->dwFlags);
1621 fprintf(stderr,"caps ");
1622 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1623 fprintf(stderr,"]\n");
1626 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1627 this->lpvtbl->fnAddRef(this);
1629 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1630 (*lpdsf)->s.ddraw = this;
1631 (*lpdsf)->s.palette = NULL;
1632 (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
1634 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1635 lpddsd->dwWidth = this->d.width;
1636 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1637 lpddsd->dwHeight = this->d.height;
1639 /* Check if this a 'primary surface' or not */
1640 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1641 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1643 /* This is THE primary surface => there is DGA-specific code */
1644 /* First, store the surface description */
1645 (*lpdsf)->s.surface_desc = *lpddsd;
1647 /* Find a viewport */
1649 if (!(this->e.dga.vpmask & (1<<i)))
1651 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1652 /* if i == 32 or maximum ... return error */
1653 this->e.dga.vpmask|=(1<<i);
1654 (*lpdsf)->s.surface_desc.y.lpSurface =
1655 this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1656 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1657 (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8;
1658 lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch;
1660 /* Add flags if there were not present */
1661 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1662 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1663 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1664 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1665 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1666 (*lpdsf)->s.backbuffer = NULL;
1668 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1669 LPDIRECTDRAWSURFACE3 back;
1671 if (lpddsd->dwBackBufferCount>1)
1672 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1674 (*lpdsf)->s.backbuffer = back =
1675 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1676 this->lpvtbl->fnAddRef(this);
1678 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1680 if (!(this->e.dga.vpmask & (1<<i)))
1682 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1683 /* if i == 32 or maximum ... return error */
1684 this->e.dga.vpmask|=(1<<i);
1685 back->t.dga.fb_height = i*this->e.dga.fb_height;
1687 /* Copy the surface description from the front buffer */
1688 back->s.surface_desc = (*lpdsf)->s.surface_desc;
1689 /* Change the parameters that are not the same */
1690 back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+
1691 ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1692 back->s.ddraw = this;
1693 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1696 /* Add relevant info to front and back buffers */
1697 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1698 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
1699 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1700 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
1703 /* There is no DGA-specific code here...
1704 Go to the common surface creation function */
1705 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
1709 #else /* defined(HAVE_LIBXXF86DGA) */
1710 return E_UNEXPECTED;
1711 #endif /* defined(HAVE_LIBXXF86DGA) */
1714 static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) {
1717 #ifdef HAVE_LIBXXSHM
1718 if (this->e.xlib.xshm_active) {
1719 img = TSXShmCreateImage(display,
1720 DefaultVisualOfScreen(screen),
1724 &(lpdsf->t.xlib.shminfo),
1725 lpdsf->s.surface_desc.dwWidth,
1726 lpdsf->s.surface_desc.dwHeight);
1731 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
1732 if (lpdsf->t.xlib.shminfo.shmid < 0) {
1733 TSXDestroyImage(img);
1737 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
1739 if (img->data == (char *) -1) {
1740 TSXDestroyImage(img);
1741 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1744 lpdsf->t.xlib.shminfo.readOnly = False;
1746 TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
1747 TSXSync(display, False);
1749 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
1751 lpdsf->s.surface_desc.y.lpSurface = img->data;
1754 /* Allocate surface memory */
1755 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1756 lpdsf->s.surface_desc.dwWidth *
1757 lpdsf->s.surface_desc.dwHeight *
1758 (this->d.depth / 8));
1760 /* In this case, create an XImage */
1762 TSXCreateImage(display,
1763 DefaultVisualOfScreen(screen),
1767 lpdsf->s.surface_desc.y.lpSurface,
1768 lpdsf->s.surface_desc.dwWidth,
1769 lpdsf->s.surface_desc.dwHeight,
1771 lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8)
1774 #ifdef HAVE_LIBXXSHM
1777 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
1782 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1783 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1785 TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1786 this,lpddsd,lpdsf,lpunk);
1788 if (TRACE_ON(ddraw)) {
1789 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1790 _dump_DDSD(lpddsd->dwFlags);
1791 fprintf(stderr,"caps ");
1792 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1793 fprintf(stderr,"]\n");
1796 *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1798 this->lpvtbl->fnAddRef(this);
1799 (*lpdsf)->s.ddraw = this;
1801 (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1802 (*lpdsf)->s.palette = NULL;
1803 (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
1805 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1806 lpddsd->dwWidth = this->d.width;
1807 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1808 lpddsd->dwHeight = this->d.height;
1810 /* Check if this a 'primary surface' or not */
1811 if ((lpddsd->dwFlags & DDSD_CAPS) &&
1812 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
1815 TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf);
1817 /* First, store the surface description */
1818 (*lpdsf)->s.surface_desc = *lpddsd;
1820 /* Create the XImage */
1821 img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf);
1823 return DDERR_OUTOFMEMORY;
1824 (*lpdsf)->t.xlib.image = img;
1826 /* Add flags if there were not present */
1827 (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
1828 (*lpdsf)->s.surface_desc.dwWidth = this->d.width;
1829 (*lpdsf)->s.surface_desc.dwHeight = this->d.height;
1830 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE;
1831 _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat));
1832 (*lpdsf)->s.backbuffer = NULL;
1834 /* Check for backbuffers */
1835 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1836 LPDIRECTDRAWSURFACE3 back;
1839 if (lpddsd->dwBackBufferCount>1)
1840 FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1842 (*lpdsf)->s.backbuffer = back =
1843 (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1845 TRACE(ddraw,"allocated back-buffer (%p)\n", back);
1847 this->lpvtbl->fnAddRef(this);
1848 back->s.ddraw = this;
1851 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
1852 /* Copy the surface description from the front buffer */
1853 back->s.surface_desc = (*lpdsf)->s.surface_desc;
1855 /* Create the XImage */
1856 img = create_ximage(this, back);
1858 return DDERR_OUTOFMEMORY;
1859 back->t.xlib.image = img;
1861 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1864 /* Add relevant info to front and back buffers */
1865 (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
1866 back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
1867 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
1868 back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
1871 /* There is no Xlib-specific code here...
1872 Go to the common surface creation function */
1873 return common_off_screen_CreateSurface(this, lpddsd, *lpdsf);
1879 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
1880 LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1882 FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1883 *dst = src; /* FIXME */
1888 * The Xlib Implementation tries to use the passed hwnd as drawing window,
1889 * even when the approbiate bitmasks are not specified.
1891 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1892 LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
1899 FE(DDSCL_FULLSCREEN)
1900 FE(DDSCL_ALLOWREBOOT)
1901 FE(DDSCL_NOWINDOWCHANGES)
1903 FE(DDSCL_ALLOWMODEX)
1905 FE(DDSCL_SETFOCUSWINDOW)
1906 FE(DDSCL_SETDEVICEWINDOW)
1907 FE(DDSCL_CREATEDEVICEWINDOW)
1910 FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
1911 if(TRACE_ON(ddraw)){
1912 dbg_decl_str(ddraw, 512);
1913 for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1914 if (flagmap[i].mask & cooplevel)
1915 dsprintf(ddraw, "%s ", flagmap[i].name);
1916 TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1918 this->d.mainWindow = hwnd;
1922 /* Small helper to either use the cooperative window or create a new
1923 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
1925 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) {
1928 /* Do not destroy the application supplied cooperative window */
1929 if (this->d.window && this->d.window != this->d.mainWindow) {
1930 DestroyWindow32(this->d.window);
1933 /* Sanity check cooperative window before assigning it to drawing. */
1934 if ( IsWindow32(this->d.mainWindow) &&
1935 IsWindowVisible32(this->d.mainWindow)
1937 GetWindowRect32(this->d.mainWindow,&rect);
1938 if (((rect.right-rect.left) >= this->d.width) &&
1939 ((rect.bottom-rect.top) >= this->d.height)
1941 this->d.window = this->d.mainWindow;
1943 /* ... failed, create new one. */
1944 if (!this->d.window) {
1945 this->d.window = CreateWindowEx32A(
1949 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1958 /*Store THIS with the window. We'll use it in the window procedure*/
1959 SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this);
1960 ShowWindow32(this->d.window,TRUE);
1961 UpdateWindow32(this->d.window);
1965 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
1966 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1968 #ifdef HAVE_LIBXXF86DGA
1969 int i,*depths,depcount,mode_count;
1971 TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
1973 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1974 for (i=0;i<depcount;i++)
1975 if (depths[i]==depth)
1978 if (i==depcount) {/* not found */
1979 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1980 return DDERR_UNSUPPORTEDMODE;
1982 if (this->d.width < width) {
1983 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
1984 return DDERR_UNSUPPORTEDMODE;
1986 this->d.width = width;
1987 this->d.height = height;
1988 this->d.depth = depth;
1990 /* adjust fb_height, so we don't overlap */
1991 if (this->e.dga.fb_height < height)
1992 this->e.dga.fb_height = height;
1993 _common_IDirectDraw_SetDisplayMode(this);
1995 #ifdef HAVE_LIBXXF86VM
1997 XF86VidModeModeInfo **all_modes, *vidmode;
1998 /* set fullscreen mode */
1999 /* do we need to save the old video mode and restore it when we exit? */
2001 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
2002 for (i=0;i<mode_count;i++)
2004 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
2006 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
2007 *vidmode = *(all_modes[i]);
2010 TSXFree(all_modes[i]->private);
2015 WARN(ddraw, "Fullscreen mode not available!\n");
2018 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
2022 /* FIXME: this function OVERWRITES several signal handlers.
2023 * can we save them? and restore them later? In a way that
2024 * it works for the library too?
2026 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
2028 TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
2031 #ifdef RESTORE_SIGNALS
2032 SIGNAL_InitEmulator();
2035 #else /* defined(HAVE_LIBXXF86DGA) */
2036 return E_UNEXPECTED;
2037 #endif /* defined(HAVE_LIBXXF86DGA) */
2040 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
2041 LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
2043 int i,*depths,depcount;
2046 TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2047 this, width, height, depth);
2049 depths = TSXListDepths(display,DefaultScreen(display),&depcount);
2050 for (i=0;i<depcount;i++)
2051 if (depths[i]==depth)
2054 if (i==depcount) {/* not found */
2055 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
2056 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
2057 return DDERR_UNSUPPORTEDMODE;
2059 this->d.width = width;
2060 this->d.height = height;
2061 this->d.depth = depth;
2063 _common_IDirectDraw_SetDisplayMode(this);
2065 this->e.xlib.paintable = 1;
2066 this->e.xlib.drawable = WIN_FindWndPtr(this->d.window)->window;
2067 /* We don't have a context for this window. Host off the desktop */
2068 if( !this->e.xlib.drawable )
2069 this->e.xlib.drawable = WIN_GetDesktop()->window;
2073 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
2074 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2076 #ifdef HAVE_LIBXXF86DGA
2077 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2078 caps1->dwVidMemTotal = this->e.dga.fb_memsize;
2079 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2080 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2082 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
2083 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
2084 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2087 #else /* defined(HAVE_LIBXXF86DGA) */
2088 return E_UNEXPECTED;
2089 #endif /* defined(HAVE_LIBXXF86DGA) */
2092 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
2093 LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
2095 TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
2097 caps1->dwVidMemTotal = 2048*1024;
2098 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2099 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2101 caps2->dwVidMemTotal = 2048*1024;
2102 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI);
2103 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
2105 /* END FIXME: Xlib */
2109 static HRESULT WINAPI IDirectDraw2_CreateClipper(
2110 LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
2112 FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
2113 this,x,lpddclip,lpunk
2115 *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
2116 (*lpddclip)->ref = 1;
2117 (*lpddclip)->lpvtbl = &ddclipvt;
2121 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
2122 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2124 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2125 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2126 (*lpddpal)->ref = 1;
2127 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2128 (*lpddpal)->installed = 0;
2129 if (this->d.depth<=8) {
2130 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
2132 /* we don't want palettes in hicolor or truecolor */
2138 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
2139 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2142 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2143 res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
2144 if (res != 0) return res;
2145 (*lpddpal)->lpvtbl = &dga_ddpalvt;
2149 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
2150 LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
2152 TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
2153 *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
2154 if (*lpddpal == NULL) return E_OUTOFMEMORY;
2155 (*lpddpal)->ref = 1;
2156 (*lpddpal)->installed = 0;
2158 FIXME(ddraw,"needs to handle palent (%p)\n",palent);
2160 (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
2161 this->lpvtbl->fnAddRef(this);
2164 (*lpddpal)->lpvtbl = &xlib_ddpalvt;
2168 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2169 #ifdef HAVE_LIBXXF86DGA
2170 TRACE(ddraw, "(%p)->()\n",this);
2172 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2173 #ifdef RESTORE_SIGNALS
2174 SIGNAL_InitEmulator();
2177 #else /* defined(HAVE_LIBXXF86DGA) */
2178 return E_UNEXPECTED;
2182 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
2183 TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
2188 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
2189 LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
2191 TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
2195 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
2196 TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
2198 return ++(this->ref);
2201 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2202 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2204 #ifdef HAVE_LIBXXF86DGA
2205 if (!--(this->ref)) {
2206 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
2207 #ifdef RESTORE_SIGNALS
2208 SIGNAL_InitEmulator();
2210 HeapFree(GetProcessHeap(),0,this);
2213 #endif /* defined(HAVE_LIBXXF86DGA) */
2217 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
2218 TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
2220 if (!--(this->ref)) {
2221 HeapFree(GetProcessHeap(),0,this);
2224 /* FIXME: destroy window ... */
2228 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
2229 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2233 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2234 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2235 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2237 this->lpvtbl->fnAddRef(this);
2240 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2241 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
2242 this->lpvtbl->fnAddRef(this);
2246 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2247 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
2248 this->lpvtbl->fnAddRef(this);
2252 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2255 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2257 d3d->ddraw = (LPDIRECTDRAW)this;
2258 this->lpvtbl->fnAddRef(this);
2259 d3d->lpvtbl = &d3dvt;
2263 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2266 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2268 d3d->ddraw = (LPDIRECTDRAW)this;
2269 this->lpvtbl->fnAddRef(this);
2270 d3d->lpvtbl = &d3d2vt;
2274 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2275 return OLE_E_ENUM_NOMORE;
2278 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
2279 LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
2283 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2284 TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
2285 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
2287 this->lpvtbl->fnAddRef(this);
2290 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
2291 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
2292 this->lpvtbl->fnAddRef(this);
2296 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
2297 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
2298 this->lpvtbl->fnAddRef(this);
2302 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2305 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2307 d3d->ddraw = (LPDIRECTDRAW)this;
2308 this->lpvtbl->fnAddRef(this);
2309 d3d->lpvtbl = &d3dvt;
2313 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
2316 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2318 d3d->ddraw = (LPDIRECTDRAW)this;
2319 this->lpvtbl->fnAddRef(this);
2320 d3d->lpvtbl = &d3d2vt;
2324 WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
2325 return OLE_E_ENUM_NOMORE;
2328 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
2329 LPDIRECTDRAW2 this,BOOL32 *status
2331 TRACE(ddraw,"(%p)->(%p)\n",this,status);
2336 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
2337 LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
2339 DDSURFACEDESC ddsfd;
2342 } modes[5] = { /* some of the usual modes */
2349 static int depths[4] = {8,16,24,32};
2352 TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
2353 ddsfd.dwSize = sizeof(ddsfd);
2354 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2355 if (dwFlags & DDEDM_REFRESHRATES) {
2356 ddsfd.dwFlags |= DDSD_REFRESHRATE;
2357 ddsfd.x.dwRefreshRate = 60;
2360 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
2361 ddsfd.dwBackBufferCount = 1;
2362 ddsfd.ddpfPixelFormat.dwFourCC = 0;
2363 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2364 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
2365 /* FIXME: those masks would have to be set in depth > 8 */
2367 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
2368 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
2369 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
2370 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2371 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
2372 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
2374 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
2376 /* FIXME: We should query those from X itself */
2377 switch (depths[i]) {
2379 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f;
2380 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0;
2381 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00;
2384 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2385 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2386 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2389 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff;
2390 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00;
2391 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000;
2396 ddsfd.dwWidth = screenWidth;
2397 ddsfd.dwHeight = screenHeight;
2398 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2399 if (!modescb(&ddsfd,context)) return 0;
2401 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
2402 ddsfd.dwWidth = modes[j].w;
2403 ddsfd.dwHeight = modes[j].h;
2404 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
2405 if (!modescb(&ddsfd,context)) return 0;
2408 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
2409 /* modeX is not standard VGA */
2411 ddsfd.dwHeight = 200;
2412 ddsfd.dwWidth = 320;
2413 TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
2414 if (!modescb(&ddsfd,context)) return 0;
2420 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
2421 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2423 #ifdef HAVE_LIBXXF86DGA
2424 TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
2425 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2426 lpddsfd->dwHeight = screenHeight;
2427 lpddsfd->dwWidth = screenWidth;
2428 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2429 lpddsfd->dwBackBufferCount = 1;
2430 lpddsfd->x.dwRefreshRate = 60;
2431 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2432 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2434 #else /* defined(HAVE_LIBXXF86DGA) */
2435 return E_UNEXPECTED;
2436 #endif /* defined(HAVE_LIBXXF86DGA) */
2439 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
2440 LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
2442 TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
2443 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
2444 lpddsfd->dwHeight = screenHeight;
2445 lpddsfd->dwWidth = screenWidth;
2446 /* POOLE FIXME: Xlib */
2447 lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
2448 /* END FIXME: Xlib */
2449 lpddsfd->dwBackBufferCount = 1;
2450 lpddsfd->x.dwRefreshRate = 60;
2451 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
2452 _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
2456 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
2457 TRACE(ddraw,"(%p)->()\n",this);
2461 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
2462 LPDIRECTDRAW2 this,LPDWORD freq
2464 FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
2465 *freq = 60*100; /* 60 Hz */
2469 /* what can we directly decompress? */
2470 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
2471 LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
2473 FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
2477 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
2478 LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
2480 FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
2484 static HRESULT WINAPI IDirectDraw2_Compact(
2485 LPDIRECTDRAW2 this )
2487 FIXME(ddraw,"(%p)->()\n", this );
2493 /* Note: Hack so we can reuse the old functions without compiler warnings */
2495 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2497 # define XCAST(fun) (void*)
2500 static struct IDirectDraw_VTable dga_ddvt = {
2501 XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
2502 XCAST(AddRef)IDirectDraw2_AddRef,
2503 XCAST(Release)DGA_IDirectDraw2_Release,
2504 XCAST(Compact)IDirectDraw2_Compact,
2505 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2506 XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
2507 XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
2508 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2509 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2510 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2511 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2512 XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2513 XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2514 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2515 XCAST(GetGDISurface)15,
2516 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2517 XCAST(GetScanLine)17,
2518 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2519 XCAST(Initialize)19,
2520 XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2521 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2522 DGA_IDirectDraw_SetDisplayMode,
2523 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2526 static struct IDirectDraw_VTable xlib_ddvt = {
2527 XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2528 XCAST(AddRef)IDirectDraw2_AddRef,
2529 XCAST(Release)Xlib_IDirectDraw2_Release,
2530 XCAST(Compact)IDirectDraw2_Compact,
2531 XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2532 XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2533 XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2534 XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2535 XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2536 XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2537 XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2538 XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2539 XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2540 XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2541 XCAST(GetGDISurface)15,
2542 XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2543 XCAST(GetScanLine)17,
2544 XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2545 XCAST(Initialize)19,
2546 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2547 XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2548 Xlib_IDirectDraw_SetDisplayMode,
2549 XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2552 /*****************************************************************************
2558 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2559 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2561 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2564 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2565 LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2567 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2570 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2571 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2573 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2574 this,ddscaps,total,free
2576 if (total) *total = this->e.dga.fb_memsize * 1024;
2577 if (free) *free = this->e.dga.fb_memsize * 1024;
2581 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2582 LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2584 TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2585 this,ddscaps,total,free
2587 if (total) *total = 2048 * 1024;
2588 if (free) *free = 2048 * 1024;
2592 static IDirectDraw2_VTable dga_dd2vt = {
2593 DGA_IDirectDraw2_QueryInterface,
2594 IDirectDraw2_AddRef,
2595 DGA_IDirectDraw2_Release,
2596 IDirectDraw2_Compact,
2597 IDirectDraw2_CreateClipper,
2598 DGA_IDirectDraw2_CreatePalette,
2599 DGA_IDirectDraw2_CreateSurface,
2601 IDirectDraw2_EnumDisplayModes,
2602 IDirectDraw2_EnumSurfaces,
2603 IDirectDraw2_FlipToGDISurface,
2604 DGA_IDirectDraw2_GetCaps,
2605 DGA_IDirectDraw2_GetDisplayMode,
2606 IDirectDraw2_GetFourCCCodes,
2608 IDirectDraw2_GetMonitorFrequency,
2610 IDirectDraw2_GetVerticalBlankStatus,
2612 DGA_IDirectDraw2_RestoreDisplayMode,
2613 IDirectDraw2_SetCooperativeLevel,
2614 DGA_IDirectDraw2_SetDisplayMode,
2615 IDirectDraw2_WaitForVerticalBlank,
2616 DGA_IDirectDraw2_GetAvailableVidMem
2619 static struct IDirectDraw2_VTable xlib_dd2vt = {
2620 Xlib_IDirectDraw2_QueryInterface,
2621 IDirectDraw2_AddRef,
2622 Xlib_IDirectDraw2_Release,
2623 IDirectDraw2_Compact,
2624 IDirectDraw2_CreateClipper,
2625 Xlib_IDirectDraw2_CreatePalette,
2626 Xlib_IDirectDraw2_CreateSurface,
2628 IDirectDraw2_EnumDisplayModes,
2629 IDirectDraw2_EnumSurfaces,
2630 IDirectDraw2_FlipToGDISurface,
2631 Xlib_IDirectDraw2_GetCaps,
2632 Xlib_IDirectDraw2_GetDisplayMode,
2633 IDirectDraw2_GetFourCCCodes,
2635 IDirectDraw2_GetMonitorFrequency,
2637 IDirectDraw2_GetVerticalBlankStatus,
2639 Xlib_IDirectDraw2_RestoreDisplayMode,
2640 IDirectDraw2_SetCooperativeLevel,
2641 Xlib_IDirectDraw2_SetDisplayMode,
2642 IDirectDraw2_WaitForVerticalBlank,
2643 Xlib_IDirectDraw2_GetAvailableVidMem
2646 /******************************************************************************
2650 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2653 LPDIRECTDRAW ddraw = NULL;
2656 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2658 SetLastError( ERROR_SUCCESS );
2659 ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2661 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2664 ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2669 /* Perform any special direct draw functions */
2671 ddraw->e.xlib.paintable = 1;
2673 /* Now let the application deal with the rest of this */
2674 if( ddraw->d.mainWindow )
2677 /* Don't think that we actually need to call this but...
2678 might as well be on the safe side of things... */
2680 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
2681 it should be the procedures of our fake window that gets called
2682 instead of those of the window provided by the application.
2683 And with this patch, mouse clicks work with Monkey Island III
2685 ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2689 /* We didn't handle the message - give it to the application */
2690 if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) {
2691 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2692 ddraw->d.mainWindow, msg, wParam, lParam );
2697 ret = DefWindowProc32A(hwnd, msg, wParam, lParam );
2703 ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2709 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2710 #ifdef HAVE_LIBXXF86DGA
2711 int memsize,banksize,width,major,minor,flags,height;
2715 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
2716 if ((fd = open("/dev/mem", O_RDWR)) != -1)
2720 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
2721 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2722 return E_UNEXPECTED;
2724 if (!DDRAW_DGA_Available()) {
2725 TRACE(ddraw,"No XF86DGA detected.\n");
2726 return DDERR_GENERIC;
2728 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2729 (*lplpDD)->lpvtbl = &dga_ddvt;
2731 TSXF86DGAQueryVersion(display,&major,&minor);
2732 TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2733 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2734 if (!(flags & XF86DGADirectPresent))
2735 MSG("direct video is NOT PRESENT.\n");
2736 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2737 TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2738 addr,width,banksize,memsize
2740 (*lplpDD)->e.dga.fb_width = width;
2741 (*lplpDD)->d.width = width;
2742 (*lplpDD)->e.dga.fb_addr = addr;
2743 (*lplpDD)->e.dga.fb_memsize = memsize;
2744 (*lplpDD)->e.dga.fb_banksize = banksize;
2746 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2747 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2748 (*lplpDD)->e.dga.fb_height = screenHeight;
2750 (*lplpDD)->e.dga.vpmask = 1;
2752 (*lplpDD)->e.dga.vpmask = 0;
2755 /* just assume the default depth is the DGA depth too */
2756 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2757 #ifdef RESTORE_SIGNALS
2758 SIGNAL_InitEmulator();
2762 #else /* defined(HAVE_LIBXXF86DGA) */
2763 return DDERR_INVALIDDIRECTDRAWGUID;
2764 #endif /* defined(HAVE_LIBXXF86DGA) */
2768 DDRAW_XSHM_Available()
2770 #ifdef HAVE_LIBXXSHM
2771 if (TSXShmQueryExtension(display))
2776 if (TSXShmQueryVersion(display, &major, &minor, &shpix))
2788 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2790 *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2791 (*lplpDD)->lpvtbl = &xlib_ddvt;
2793 (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
2795 (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2796 (*lplpDD)->d.height = screenHeight;
2797 (*lplpDD)->d.width = screenWidth;
2799 #ifdef HAVE_LIBXXSHM
2800 /* Test if XShm is available.
2801 As XShm is not ready yet for 'prime-time', it is disabled for now */
2802 if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */))
2803 TRACE(ddraw, "Using XShm extesion.\n");
2809 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
2816 WINE_StringFromCLSID(lpGUID,xclsid);
2818 sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID);
2822 TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
2825 /* if they didn't request a particular interface, use the best
2827 if (DDRAW_DGA_Available())
2828 lpGUID = &DGA_DirectDraw_GUID;
2830 lpGUID = &XLIB_DirectDraw_GUID;
2833 wc.style = CS_GLOBALCLASS;
2834 wc.lpfnWndProc = Xlib_DDWndProc;
2836 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
2837 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
2839 /* We can be a child of the desktop since we're really important */
2840 pParentWindow = WIN_GetDesktop();
2841 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
2845 wc.hCursor = (HCURSOR32)IDC_ARROW32A;
2846 wc.hbrBackground= NULL_BRUSH;
2847 wc.lpszMenuName = 0;
2848 wc.lpszClassName= "WINE_DirectDraw";
2849 RegisterClass32A(&wc);
2851 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
2852 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
2853 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
2854 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
2858 (*lplpDD)->d.winclass = RegisterClass32A(&wc);
2862 fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
2863 return DDERR_INVALIDDIRECTDRAWGUID;