| /* DirectDraw using DGA or Xlib(XSHM) | |
| * | |
| * Copyright 1997,1998 Marcus Meissner | |
| */ | |
| /* XF86DGA: | |
| * When DirectVideo mode is enabled you can no longer use 'normal' X | |
| * applications nor can you switch to a virtual console. Also, enabling | |
| * only works, if you have switched to the screen where the application | |
| * is running. | |
| * Some ways to debug this stuff are: | |
| * - A terminal connected to the serial port. Can be bought used for cheap. | |
| * (This is the method I am using.) | |
| * - Another machine connected over some kind of network. | |
| */ | |
| #include "config.h" | |
| #include <unistd.h> | |
| #include <assert.h> | |
| #include "ts_xlib.h" | |
| #include <sys/signal.h> | |
| #include <fcntl.h> | |
| #include <string.h> | |
| #include <stdlib.h> | |
| #include "windows.h" | |
| #ifdef HAVE_LIBXXF86VM | |
| /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h, | |
| this is a crude hack to get around it */ | |
| #define XMD_H | |
| #include "ts_xf86vmode.h" | |
| #endif | |
| #include "winerror.h" | |
| #include "interfaces.h" | |
| #include "gdi.h" | |
| #include "heap.h" | |
| #include "ldt.h" | |
| #include "dc.h" | |
| #include "win.h" | |
| #include "miscemu.h" | |
| #include "ddraw.h" | |
| #include "d3d.h" | |
| #include "debug.h" | |
| #include "compobj.h" | |
| #include "spy.h" | |
| #include "message.h" | |
| #include "x11drv.h" | |
| #include "options.h" | |
| #ifdef HAVE_LIBXXF86DGA | |
| #include "ts_xf86dga.h" | |
| #endif | |
| #ifdef HAVE_LIBXXSHM | |
| #include <sys/types.h> | |
| #include <sys/ipc.h> | |
| #include <sys/shm.h> | |
| #include "ts_xshm.h" | |
| #endif | |
| /* define this if you want to play Diablo using XF86DGA. (bug workaround) */ | |
| #undef DIABLO_HACK | |
| /* Restore signal handlers overwritten by XF86DGA | |
| * this is a define, for it will only work in emulator mode | |
| */ | |
| #undef RESTORE_SIGNALS | |
| /* Where do these GUIDs come from? mkuuid. | |
| * They exist solely to distinguish between the targets Wine support, | |
| * and should be different than any other GUIDs in existence. | |
| */ | |
| static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */ | |
| 0xe2dcb020, | |
| 0xdc60, | |
| 0x11d1, | |
| {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02} | |
| }; | |
| static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */ | |
| 0x1574a740, | |
| 0xdc61, | |
| 0x11d1, | |
| {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79} | |
| }; | |
| static struct IDirectDrawSurface3_VTable dga_dds3vt, xlib_dds3vt; | |
| static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt; | |
| static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt; | |
| static struct IDirectDrawClipper_VTable ddclipvt; | |
| static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt; | |
| static struct IDirect3D_VTable d3dvt; | |
| static struct IDirect3D2_VTable d3d2vt; | |
| BOOL32 | |
| DDRAW_DGA_Available() | |
| { | |
| #ifdef HAVE_LIBXXF86DGA | |
| int evbase, evret, fd; | |
| if (Options.noDGA) | |
| return 0; | |
| /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */ | |
| /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */ | |
| /* others. --stephenc */ | |
| if ((fd = open("/dev/mem", O_RDWR)) != -1) | |
| close(fd); | |
| return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret); | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return 0; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| } | |
| HRESULT WINAPI | |
| DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) { | |
| if (DDRAW_DGA_Available()) { | |
| ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data); | |
| } | |
| ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data); | |
| ddenumproc(NULL,"WINE","display",data); | |
| return 0; | |
| } | |
| /* What is this doing here? */ | |
| HRESULT WINAPI | |
| DSoundHelp(DWORD x,DWORD y,DWORD z) { | |
| FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z); | |
| return 0; | |
| } | |
| /****************************************************************************** | |
| * internal helper functions | |
| */ | |
| static void _dump_DDBLTFX(DWORD flagmask) { | |
| int i; | |
| const struct { | |
| DWORD mask; | |
| char *name; | |
| } flags[] = { | |
| #define FE(x) { x, #x}, | |
| FE(DDBLTFX_ARITHSTRETCHY) | |
| FE(DDBLTFX_MIRRORLEFTRIGHT) | |
| FE(DDBLTFX_MIRRORUPDOWN) | |
| FE(DDBLTFX_NOTEARING) | |
| FE(DDBLTFX_ROTATE180) | |
| FE(DDBLTFX_ROTATE270) | |
| FE(DDBLTFX_ROTATE90) | |
| FE(DDBLTFX_ZBUFFERRANGE) | |
| FE(DDBLTFX_ZBUFFERBASEDEST) | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) { | |
| DUMP("%s ",flags[i].name); | |
| }; | |
| DUMP("\n"); | |
| } | |
| static void _dump_DDBLTFAST(DWORD flagmask) { | |
| int i; | |
| const struct { | |
| DWORD mask; | |
| char *name; | |
| } flags[] = { | |
| #define FE(x) { x, #x}, | |
| FE(DDBLTFAST_NOCOLORKEY) | |
| FE(DDBLTFAST_SRCCOLORKEY) | |
| FE(DDBLTFAST_DESTCOLORKEY) | |
| FE(DDBLTFAST_WAIT) | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) | |
| DUMP("%s ",flags[i].name); | |
| DUMP("\n"); | |
| } | |
| static void _dump_DDBLT(DWORD flagmask) { | |
| int i; | |
| const struct { | |
| DWORD mask; | |
| char *name; | |
| } flags[] = { | |
| #define FE(x) { x, #x}, | |
| FE(DDBLT_ALPHADEST) | |
| FE(DDBLT_ALPHADESTCONSTOVERRIDE) | |
| FE(DDBLT_ALPHADESTNEG) | |
| FE(DDBLT_ALPHADESTSURFACEOVERRIDE) | |
| FE(DDBLT_ALPHAEDGEBLEND) | |
| FE(DDBLT_ALPHASRC) | |
| FE(DDBLT_ALPHASRCCONSTOVERRIDE) | |
| FE(DDBLT_ALPHASRCNEG) | |
| FE(DDBLT_ALPHASRCSURFACEOVERRIDE) | |
| FE(DDBLT_ASYNC) | |
| FE(DDBLT_COLORFILL) | |
| FE(DDBLT_DDFX) | |
| FE(DDBLT_DDROPS) | |
| FE(DDBLT_KEYDEST) | |
| FE(DDBLT_KEYDESTOVERRIDE) | |
| FE(DDBLT_KEYSRC) | |
| FE(DDBLT_KEYSRCOVERRIDE) | |
| FE(DDBLT_ROP) | |
| FE(DDBLT_ROTATIONANGLE) | |
| FE(DDBLT_ZBUFFER) | |
| FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE) | |
| FE(DDBLT_ZBUFFERDESTOVERRIDE) | |
| FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE) | |
| FE(DDBLT_ZBUFFERSRCOVERRIDE) | |
| FE(DDBLT_WAIT) | |
| FE(DDBLT_DEPTHFILL) | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) | |
| DUMP("%s ",flags[i].name); | |
| } | |
| static void _dump_DDSCAPS(DWORD flagmask) { | |
| int i; | |
| const struct { | |
| DWORD mask; | |
| char *name; | |
| } flags[] = { | |
| #define FE(x) { x, #x}, | |
| FE(DDSCAPS_RESERVED1) | |
| FE(DDSCAPS_ALPHA) | |
| FE(DDSCAPS_BACKBUFFER) | |
| FE(DDSCAPS_COMPLEX) | |
| FE(DDSCAPS_FLIP) | |
| FE(DDSCAPS_FRONTBUFFER) | |
| FE(DDSCAPS_OFFSCREENPLAIN) | |
| FE(DDSCAPS_OVERLAY) | |
| FE(DDSCAPS_PALETTE) | |
| FE(DDSCAPS_PRIMARYSURFACE) | |
| FE(DDSCAPS_PRIMARYSURFACELEFT) | |
| FE(DDSCAPS_SYSTEMMEMORY) | |
| FE(DDSCAPS_TEXTURE) | |
| FE(DDSCAPS_3DDEVICE) | |
| FE(DDSCAPS_VIDEOMEMORY) | |
| FE(DDSCAPS_VISIBLE) | |
| FE(DDSCAPS_WRITEONLY) | |
| FE(DDSCAPS_ZBUFFER) | |
| FE(DDSCAPS_OWNDC) | |
| FE(DDSCAPS_LIVEVIDEO) | |
| FE(DDSCAPS_HWCODEC) | |
| FE(DDSCAPS_MODEX) | |
| FE(DDSCAPS_MIPMAP) | |
| FE(DDSCAPS_RESERVED2) | |
| FE(DDSCAPS_ALLOCONLOAD) | |
| FE(DDSCAPS_VIDEOPORT) | |
| FE(DDSCAPS_LOCALVIDMEM) | |
| FE(DDSCAPS_NONLOCALVIDMEM) | |
| FE(DDSCAPS_STANDARDVGAMODE) | |
| FE(DDSCAPS_OPTIMIZED) | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) | |
| DUMP("%s ",flags[i].name); | |
| DUMP("\n"); | |
| } | |
| static void _dump_DDSD(DWORD flagmask) { | |
| int i; | |
| const struct { | |
| DWORD mask; | |
| char *name; | |
| } flags[] = { | |
| FE(DDSD_CAPS) | |
| FE(DDSD_HEIGHT) | |
| FE(DDSD_WIDTH) | |
| FE(DDSD_PITCH) | |
| FE(DDSD_BACKBUFFERCOUNT) | |
| FE(DDSD_ZBUFFERBITDEPTH) | |
| FE(DDSD_ALPHABITDEPTH) | |
| FE(DDSD_PIXELFORMAT) | |
| FE(DDSD_CKDESTOVERLAY) | |
| FE(DDSD_CKDESTBLT) | |
| FE(DDSD_CKSRCOVERLAY) | |
| FE(DDSD_CKSRCBLT) | |
| FE(DDSD_MIPMAPCOUNT) | |
| FE(DDSD_REFRESHRATE) | |
| FE(DDSD_LINEARSIZE) | |
| FE(DDSD_LPSURFACE) | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) | |
| DUMP("%s ",flags[i].name); | |
| DUMP("\n"); | |
| } | |
| static void _dump_DDCOLORKEY(DWORD flagmask) { | |
| int i; | |
| const struct { | |
| DWORD mask; | |
| char *name; | |
| } flags[] = { | |
| #define FE(x) { x, #x}, | |
| FE(DDPF_ALPHAPIXELS) | |
| FE(DDPF_ALPHA) | |
| FE(DDPF_FOURCC) | |
| FE(DDPF_PALETTEINDEXED4) | |
| FE(DDPF_PALETTEINDEXEDTO8) | |
| FE(DDPF_PALETTEINDEXED8) | |
| FE(DDPF_RGB) | |
| FE(DDPF_COMPRESSED) | |
| FE(DDPF_RGBTOYUV) | |
| FE(DDPF_YUV) | |
| FE(DDPF_ZBUFFER) | |
| FE(DDPF_PALETTEINDEXED1) | |
| FE(DDPF_PALETTEINDEXED2) | |
| FE(DDPF_ZPIXELS) | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) | |
| DUMP("%s ",flags[i].name); | |
| DUMP("\n"); | |
| } | |
| static void _dump_pixelformat(LPDDPIXELFORMAT pf) { | |
| _dump_DDCOLORKEY(pf->dwFlags); | |
| DUMP("dwFourCC : %ld\n", pf->dwFourCC); | |
| DUMP("RBG bit cbout : %ld\n", pf->x.dwRGBBitCount); | |
| DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n", | |
| pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask); | |
| } | |
| static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) { | |
| static XVisualInfo *vi; | |
| XVisualInfo vt; | |
| int nitems; | |
| if (!vi) | |
| vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems); | |
| pf->dwFourCC = 0; | |
| if (ddraw->d.depth==8) { | |
| pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8; | |
| pf->x.dwRGBBitCount = 8; | |
| pf->y.dwRBitMask = 0; | |
| pf->z.dwGBitMask = 0; | |
| pf->xx.dwBBitMask = 0; | |
| pf->xy.dwRGBAlphaBitMask= 0; | |
| return 0; | |
| } | |
| if (ddraw->d.depth==16) { | |
| pf->dwFlags = DDPF_RGB; | |
| pf->x.dwRGBBitCount = 16; | |
| pf->y.dwRBitMask = vi[0].red_mask; | |
| pf->z.dwGBitMask = vi[0].green_mask; | |
| pf->xx.dwBBitMask = vi[0].blue_mask; | |
| pf->xy.dwRGBAlphaBitMask= 0; | |
| return 0; | |
| } | |
| FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth); | |
| return DDERR_GENERIC; | |
| } | |
| /****************************************************************************** | |
| * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3 | |
| * | |
| * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let | |
| * DDS and DDS2 use those functions. (Function calls did not change (except | |
| * using different DirectDrawSurfaceX version), just added flags and functions) | |
| */ | |
| static HRESULT WINAPI IDirectDrawSurface3_Lock( | |
| LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd | |
| ) { | |
| TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n", | |
| this,lprect,lpddsd,flags,(DWORD)hnd); | |
| if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY)) | |
| WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n", | |
| this,lprect,lpddsd,flags,(DWORD)hnd); | |
| /* First, copy the Surface description */ | |
| *lpddsd = this->s.surface_desc; | |
| /* If asked only for a part, change the surface pointer */ | |
| if (lprect) { | |
| FIXME(ddraw," lprect: %dx%d-%dx%d\n", | |
| lprect->top,lprect->left,lprect->bottom,lprect->right | |
| ); | |
| lpddsd->y.lpSurface = this->s.surface_desc.y.lpSurface + | |
| (lprect->top*this->s.surface_desc.lPitch) + | |
| (lprect->left*(this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8)); | |
| } else { | |
| assert(this->s.surface_desc.y.lpSurface); | |
| } | |
| return 0; | |
| } | |
| static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock( | |
| LPDIRECTDRAWSURFACE3 this,LPVOID surface | |
| ) { | |
| TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface); | |
| return 0; | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock( | |
| LPDIRECTDRAWSURFACE3 this,LPVOID surface) | |
| { | |
| TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface); | |
| if (!this->s.ddraw->e.xlib.paintable) | |
| return DD_OK; | |
| /* Only redraw the screen when unlocking the buffer that is on screen */ | |
| if ((this->t.xlib.image != NULL) && | |
| (this->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) { | |
| #ifdef HAVE_LIBXXSHM | |
| if (this->s.ddraw->e.xlib.xshm_active) | |
| TSXShmPutImage(display, | |
| this->s.ddraw->e.xlib.drawable, | |
| DefaultGCOfScreen(screen), | |
| this->t.xlib.image, | |
| 0, 0, 0, 0, | |
| this->t.xlib.image->width, | |
| this->t.xlib.image->height, | |
| False); | |
| else | |
| #endif | |
| TSXPutImage( display, | |
| this->s.ddraw->e.xlib.drawable, | |
| DefaultGCOfScreen(screen), | |
| this->t.xlib.image, | |
| 0, 0, 0, 0, | |
| this->t.xlib.image->width, | |
| this->t.xlib.image->height); | |
| if (this->s.palette && this->s.palette->cm) | |
| TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm); | |
| } | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip( | |
| LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags | |
| ) { | |
| #ifdef HAVE_LIBXXF86DGA | |
| TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags); | |
| if (!flipto) { | |
| if (this->s.backbuffer) | |
| flipto = this->s.backbuffer; | |
| else | |
| flipto = this; | |
| } | |
| TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height); | |
| if (flipto->s.palette && flipto->s.palette->cm) { | |
| TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm); | |
| } | |
| while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) { | |
| } | |
| if (flipto!=this) { | |
| int tmp; | |
| LPVOID ptmp; | |
| tmp = this->t.dga.fb_height; | |
| this->t.dga.fb_height = flipto->t.dga.fb_height; | |
| flipto->t.dga.fb_height = tmp; | |
| ptmp = this->s.surface_desc.y.lpSurface; | |
| this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface; | |
| flipto->s.surface_desc.y.lpSurface = ptmp; | |
| } | |
| return 0; | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return E_UNEXPECTED; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip( | |
| LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags | |
| ) { | |
| TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags); | |
| if (!this->s.ddraw->e.xlib.paintable) | |
| return 0; | |
| if (!flipto) { | |
| if (this->s.backbuffer) | |
| flipto = this->s.backbuffer; | |
| else | |
| flipto = this; | |
| } | |
| #ifdef HAVE_LIBXXSHM | |
| if (this->s.ddraw->e.xlib.xshm_active) { | |
| TSXShmPutImage(display, | |
| this->s.ddraw->e.xlib.drawable, | |
| DefaultGCOfScreen(screen), | |
| flipto->t.xlib.image, | |
| 0, 0, 0, 0, | |
| flipto->t.xlib.image->width, | |
| flipto->t.xlib.image->height, | |
| False); | |
| } else | |
| #endif | |
| TSXPutImage(display, | |
| this->s.ddraw->e.xlib.drawable, | |
| DefaultGCOfScreen(screen), | |
| flipto->t.xlib.image, | |
| 0, 0, 0, 0, | |
| flipto->t.xlib.image->width, | |
| flipto->t.xlib.image->height); | |
| if (flipto->s.palette && flipto->s.palette->cm) { | |
| TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,flipto->s.palette->cm); | |
| } | |
| if (flipto!=this) { | |
| XImage *tmp; | |
| LPVOID *surf; | |
| tmp = this->t.xlib.image; | |
| this->t.xlib.image = flipto->t.xlib.image; | |
| flipto->t.xlib.image = tmp; | |
| surf = this->s.surface_desc.y.lpSurface; | |
| this->s.surface_desc.y.lpSurface = flipto->s.surface_desc.y.lpSurface; | |
| flipto->s.surface_desc.y.lpSurface = surf; | |
| } | |
| return 0; | |
| } | |
| /* The IDirectDrawSurface3::SetPalette method attaches the specified | |
| * DirectDrawPalette object to a surface. The surface uses this palette for all | |
| * subsequent operations. The palette change takes place immediately. | |
| */ | |
| static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette( | |
| LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal | |
| ) { | |
| int i; | |
| TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal); | |
| if (!(pal->cm) && (this->s.ddraw->d.depth<=8)) { | |
| pal->cm = TSXCreateColormap(display,this->s.ddraw->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll); | |
| /* FIXME: this is not correct, when using -managed */ | |
| TSXInstallColormap(display,pal->cm); | |
| for (i=0;i<256;i++) { | |
| XColor xc; | |
| xc.red = pal->palents[i].peRed<<8; | |
| xc.blue = pal->palents[i].peBlue<<8; | |
| xc.green = pal->palents[i].peGreen<<8; | |
| xc.flags = DoRed|DoBlue|DoGreen; | |
| xc.pixel = i; | |
| TSXStoreColor(display,pal->cm,&xc); | |
| } | |
| } | |
| /* According to spec, we are only supposed to | |
| * AddRef if this is not the same palette. | |
| */ | |
| if( this->s.palette != pal ) | |
| { | |
| if( pal != NULL ) | |
| pal->lpvtbl->fnAddRef( pal ); | |
| if( this->s.palette != NULL ) | |
| this->s.palette->lpvtbl->fnRelease( this->s.palette ); | |
| this->s.palette = pal; | |
| /* I think that we need to attach it to all backbuffers...*/ | |
| if( this->s.backbuffer ) { | |
| if( this->s.backbuffer->s.palette ) | |
| this->s.backbuffer->s.palette->lpvtbl->fnRelease( | |
| this->s.backbuffer->s.palette ); | |
| this->s.backbuffer->s.palette = pal; | |
| if( pal ) | |
| pal->lpvtbl->fnAddRef( pal ); | |
| } | |
| /* Perform the refresh */ | |
| TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm); | |
| } | |
| return 0; | |
| } | |
| static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette( | |
| LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal | |
| ) { | |
| TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal); | |
| #ifdef HAVE_LIBXXF86DGA | |
| /* According to spec, we are only supposed to | |
| * AddRef if this is not the same palette. | |
| */ | |
| if( this->s.palette != pal ) | |
| { | |
| if( pal != NULL ) | |
| pal->lpvtbl->fnAddRef( pal ); | |
| if( this->s.palette != NULL ) | |
| this->s.palette->lpvtbl->fnRelease( this->s.palette ); | |
| this->s.palette = pal; | |
| /* I think that we need to attach it to all backbuffers...*/ | |
| if( this->s.backbuffer ) { | |
| if( this->s.backbuffer->s.palette ) | |
| this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette ); | |
| this->s.backbuffer->s.palette = pal; | |
| if( pal ) pal->lpvtbl->fnAddRef( pal ); | |
| } | |
| TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm); | |
| } | |
| return 0; | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return E_UNEXPECTED; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_Blt( | |
| LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx | |
| ) { | |
| RECT32 xdst,xsrc; | |
| DDSURFACEDESC ddesc,sdesc; | |
| int i,j; | |
| TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n", | |
| this,rdst,src,rsrc,dwFlags,lpbltfx); | |
| if (src != NULL) | |
| src ->lpvtbl->fnLock(src, NULL,&sdesc,0,0); | |
| this->lpvtbl->fnLock(this,NULL,&ddesc,0,0); | |
| if (TRACE_ON(ddraw)) { | |
| if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom); | |
| if (rsrc) TRACE(ddraw," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom); | |
| TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n"); | |
| if (dwFlags & DDBLT_DDFX) { | |
| TRACE(ddraw," blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX); | |
| } | |
| } | |
| if (rdst) { | |
| memcpy(&xdst,rdst,sizeof(xdst)); | |
| } else { | |
| xdst.top = 0; | |
| xdst.bottom = ddesc.dwHeight; | |
| xdst.left = 0; | |
| xdst.right = ddesc.dwWidth; | |
| } | |
| if (rsrc) { | |
| memcpy(&xsrc,rsrc,sizeof(xsrc)); | |
| } else { | |
| if (src) { | |
| xsrc.top = 0; | |
| xsrc.bottom = sdesc.dwHeight; | |
| xsrc.left = 0; | |
| xsrc.right = sdesc.dwWidth; | |
| } else { | |
| memset(&xsrc,0,sizeof(xsrc)); | |
| } | |
| } | |
| dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */ | |
| if (dwFlags & DDBLT_COLORFILL) { | |
| int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8; | |
| LPBYTE xline,xpixel; | |
| xline = (LPBYTE) ddesc.y.lpSurface + xdst.top * ddesc.lPitch; | |
| for (i=xdst.top;i<xdst.bottom;i++) { | |
| xpixel = xline+bpp*xdst.left; | |
| for (j=xdst.left;j<xdst.right;j++) { | |
| /* FIXME: this only works on little endian | |
| * architectures, where DWORD starts with low | |
| * byte first! | |
| */ | |
| memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp); | |
| xpixel += bpp; | |
| } | |
| xline += ddesc.lPitch; | |
| } | |
| dwFlags &= ~(DDBLT_COLORFILL); | |
| } | |
| if (!src) { | |
| if (dwFlags) { | |
| TRACE(ddraw,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n"); | |
| } | |
| return 0; | |
| } | |
| if ( (xsrc.top ==0) && (xsrc.bottom ==ddesc.dwHeight) && | |
| (xsrc.left==0) && (xsrc.right ==ddesc.dwWidth) && | |
| (xdst.top ==0) && (xdst.bottom ==ddesc.dwHeight) && | |
| (xdst.left==0) && (xdst.right ==ddesc.dwWidth) && | |
| !dwFlags | |
| ) { | |
| memcpy(ddesc.y.lpSurface, | |
| sdesc.y.lpSurface, | |
| ddesc.dwHeight * ddesc.lPitch); | |
| } else { | |
| int bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8; | |
| int height = xsrc.bottom - xsrc.top; | |
| int width = (xsrc.right - xsrc.left) * bpp; | |
| int h; | |
| for (h = 0; h < height; h++) { | |
| memcpy(ddesc.y.lpSurface + ((h + xdst.top) * ddesc.lPitch) + xdst.left * bpp, | |
| sdesc.y.lpSurface + ((h + xsrc.top) * sdesc.lPitch) + xsrc.left * bpp, | |
| width); | |
| } | |
| } | |
| if (dwFlags && FIXME_ON(ddraw)) { | |
| FIXME(ddraw,"\tUnsupported flags: ");_dump_DDBLT(dwFlags); | |
| } | |
| this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface); | |
| src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_BltFast( | |
| LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans | |
| ) { | |
| int i,bpp; | |
| DDSURFACEDESC ddesc,sdesc; | |
| if (TRACE_ON(ddraw)) { | |
| TRACE(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n", | |
| this,dstx,dsty,src,rsrc,trans | |
| ); | |
| TRACE(ddraw," trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n"); | |
| TRACE(ddraw," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom); | |
| } | |
| /* We need to lock the surfaces, or we won't get refreshes when done. */ | |
| src ->lpvtbl->fnLock(src, NULL,&sdesc,DDLOCK_READONLY, 0); | |
| this->lpvtbl->fnLock(this,NULL,&ddesc,DDLOCK_WRITEONLY,0); | |
| bpp = this->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8; | |
| for (i=0;i<rsrc->bottom-rsrc->top;i++) { | |
| memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp, | |
| sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp, | |
| (rsrc->right-rsrc->left)*bpp | |
| ); | |
| } | |
| this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface); | |
| src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_BltBatch( | |
| LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y | |
| ) { | |
| FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n", | |
| this,ddbltbatch,x,y | |
| ); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetCaps( | |
| LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps | |
| ) { | |
| TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps); | |
| caps->dwCaps = DDSCAPS_PALETTE; /* probably more */ | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc( | |
| LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd | |
| ) { | |
| TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n", | |
| this,ddsd); | |
| /* Simply copy the surface description stored in the object */ | |
| *ddsd = this->s.surface_desc; | |
| if (TRACE_ON(ddraw)) { | |
| fprintf(stderr," flags: "); | |
| _dump_DDSD(ddsd->dwFlags); | |
| if (ddsd->dwFlags & DDSD_CAPS) { | |
| fprintf(stderr, " caps: "); | |
| _dump_DDSCAPS(ddsd->ddsCaps.dwCaps); | |
| } | |
| fprintf(stderr,"\n"); | |
| } | |
| return 0; | |
| } | |
| static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) { | |
| TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref ); | |
| return ++(this->ref); | |
| } | |
| static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) { | |
| TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); | |
| #ifdef HAVE_LIBXXF86DGA | |
| if (!--(this->ref)) { | |
| this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw); | |
| /* clear out of surface list */ | |
| if (this->t.dga.fb_height == -1) { | |
| HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface); | |
| } else { | |
| this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height)); | |
| } | |
| HeapFree(GetProcessHeap(),0,this); | |
| return 0; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| return this->ref; | |
| } | |
| static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) { | |
| TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); | |
| if (!--(this->ref)) { | |
| this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw); | |
| if( this->s.backbuffer ) | |
| this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer); | |
| if (this->t.xlib.image != NULL) { | |
| this->t.xlib.image->data = NULL; | |
| #ifdef HAVE_LIBXXSHM | |
| if (this->s.ddraw->e.xlib.xshm_active) { | |
| TSXShmDetach(display, &(this->t.xlib.shminfo)); | |
| TSXDestroyImage(this->t.xlib.image); | |
| shmdt(this->t.xlib.shminfo.shmaddr); | |
| } else { | |
| #endif | |
| HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface); | |
| TSXDestroyImage(this->t.xlib.image); | |
| #ifdef HAVE_LIBXXSHM | |
| } | |
| #endif | |
| this->t.xlib.image = 0; | |
| } else { | |
| HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface); | |
| } | |
| if (this->s.palette) | |
| this->s.palette->lpvtbl->fnRelease(this->s.palette); | |
| HeapFree(GetProcessHeap(),0,this); | |
| return 0; | |
| } | |
| return this->ref; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface( | |
| LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf | |
| ) { | |
| TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n", | |
| this, lpddsd, lpdsf); | |
| if (TRACE_ON(ddraw)) { | |
| TRACE(ddraw," caps "); | |
| _dump_DDSCAPS(lpddsd->dwCaps); | |
| } | |
| if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) { | |
| FIXME(ddraw,"whoops, can only handle backbuffers for now\n"); | |
| return E_FAIL; | |
| } | |
| /* FIXME: should handle more than one backbuffer */ | |
| *lpdsf = this->s.backbuffer; | |
| if( this->s.backbuffer ) | |
| this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer ); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_Initialize( | |
| LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd | |
| ) { | |
| TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd); | |
| return DDERR_ALREADYINITIALIZED; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat( | |
| LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf | |
| ) { | |
| TRACE(ddraw,"(%p)->(%p)\n",this,pf); | |
| *pf = this->s.surface_desc.ddpfPixelFormat; | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) { | |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition( | |
| LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2 | |
| ) { | |
| FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_SetClipper( | |
| LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper | |
| ) { | |
| FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface( | |
| LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf | |
| ) { | |
| FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf); | |
| /* This hack will be enough for the moment */ | |
| if (this->s.backbuffer == NULL) | |
| this->s.backbuffer = surf; | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) { | |
| FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc); | |
| *lphdc = BeginPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) { | |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc); | |
| EndPaint32(this->s.ddraw->d.window,&this->s.ddraw->d.ps); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) { | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj); | |
| /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use | |
| * the same interface. And IUnknown does that too of course. | |
| */ | |
| if ( !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) || | |
| !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) || | |
| !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) || | |
| !memcmp(&IID_IUnknown,refiid,sizeof(IID)) | |
| ) { | |
| *obj = this; | |
| this->lpvtbl->fnAddRef(this); | |
| return 0; | |
| } | |
| FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid); | |
| return OLE_E_ENUM_NOMORE; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) { | |
| TRACE(ddraw,"(%p)->(), stub!\n",this); | |
| return 0; /* hmm */ | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) { | |
| FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) { | |
| FIXME(ddraw,"(%p)->(),stub!\n",this); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_SetColorKey( | |
| LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey | |
| ) { | |
| FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey); | |
| if( dwFlags & DDCKEY_SRCBLT ) | |
| dwFlags &= ~DDCKEY_SRCBLT; | |
| if( dwFlags ) | |
| TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags ); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_AddOverlayDirtyRect( | |
| LPDIRECTDRAWSURFACE3 this, | |
| LPRECT32 lpRect ) | |
| { | |
| FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_DeleteAttachedSurface( | |
| LPDIRECTDRAWSURFACE3 this, | |
| DWORD dwFlags, | |
| LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface ) | |
| { | |
| FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_EnumOverlayZOrders( | |
| LPDIRECTDRAWSURFACE3 this, | |
| DWORD dwFlags, | |
| LPVOID lpContext, | |
| LPDDENUMSURFACESCALLBACK lpfnCallback ) | |
| { | |
| FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags, | |
| lpContext, lpfnCallback ); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetClipper( | |
| LPDIRECTDRAWSURFACE3 this, | |
| LPDIRECTDRAWCLIPPER* lplpDDClipper ) | |
| { | |
| FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetColorKey( | |
| LPDIRECTDRAWSURFACE3 this, | |
| DWORD dwFlags, | |
| LPDDCOLORKEY lpDDColorKey ) | |
| { | |
| FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDColorKey); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetFlipStatus( | |
| LPDIRECTDRAWSURFACE3 this, | |
| DWORD dwFlags ) | |
| { | |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetPalette( | |
| LPDIRECTDRAWSURFACE3 this, | |
| LPDIRECTDRAWPALETTE* lplpDDPalette ) | |
| { | |
| FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_SetOverlayPosition( | |
| LPDIRECTDRAWSURFACE3 this, | |
| LONG lX, | |
| LONG lY) | |
| { | |
| FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlay( | |
| LPDIRECTDRAWSURFACE3 this, | |
| LPRECT32 lpSrcRect, | |
| LPDIRECTDRAWSURFACE3 lpDDDestSurface, | |
| LPRECT32 lpDestRect, | |
| DWORD dwFlags, | |
| LPDDOVERLAYFX lpDDOverlayFx ) | |
| { | |
| FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this, | |
| lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx ); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayDisplay( | |
| LPDIRECTDRAWSURFACE3 this, | |
| DWORD dwFlags ) | |
| { | |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_UpdateOverlayZOrder( | |
| LPDIRECTDRAWSURFACE3 this, | |
| DWORD dwFlags, | |
| LPDIRECTDRAWSURFACE3 lpDDSReference ) | |
| { | |
| FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_GetDDInterface( | |
| LPDIRECTDRAWSURFACE3 this, | |
| LPVOID* lplpDD ) | |
| { | |
| FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_PageLock( | |
| LPDIRECTDRAWSURFACE3 this, | |
| DWORD dwFlags ) | |
| { | |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_PageUnlock( | |
| LPDIRECTDRAWSURFACE3 this, | |
| DWORD dwFlags ) | |
| { | |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface3_SetSurfaceDesc( | |
| LPDIRECTDRAWSURFACE3 this, | |
| LPDDSURFACEDESC lpDDSD, | |
| DWORD dwFlags ) | |
| { | |
| FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags); | |
| return DD_OK; | |
| } | |
| static struct IDirectDrawSurface3_VTable dga_dds3vt = { | |
| IDirectDrawSurface3_QueryInterface, | |
| IDirectDrawSurface3_AddRef, | |
| DGA_IDirectDrawSurface3_Release, | |
| IDirectDrawSurface3_AddAttachedSurface, | |
| IDirectDrawSurface3_AddOverlayDirtyRect, | |
| IDirectDrawSurface3_Blt, | |
| IDirectDrawSurface3_BltBatch, | |
| IDirectDrawSurface3_BltFast, | |
| IDirectDrawSurface3_DeleteAttachedSurface, | |
| IDirectDrawSurface3_EnumAttachedSurfaces, | |
| IDirectDrawSurface3_EnumOverlayZOrders, | |
| DGA_IDirectDrawSurface3_Flip, | |
| IDirectDrawSurface3_GetAttachedSurface, | |
| IDirectDrawSurface3_GetBltStatus, | |
| IDirectDrawSurface3_GetCaps, | |
| IDirectDrawSurface3_GetClipper, | |
| IDirectDrawSurface3_GetColorKey, | |
| IDirectDrawSurface3_GetDC, | |
| IDirectDrawSurface3_GetFlipStatus, | |
| IDirectDrawSurface3_GetOverlayPosition, | |
| IDirectDrawSurface3_GetPalette, | |
| IDirectDrawSurface3_GetPixelFormat, | |
| IDirectDrawSurface3_GetSurfaceDesc, | |
| IDirectDrawSurface3_Initialize, | |
| IDirectDrawSurface3_IsLost, | |
| IDirectDrawSurface3_Lock, | |
| IDirectDrawSurface3_ReleaseDC, | |
| IDirectDrawSurface3_Restore, | |
| IDirectDrawSurface3_SetClipper, | |
| IDirectDrawSurface3_SetColorKey, | |
| IDirectDrawSurface3_SetOverlayPosition, | |
| DGA_IDirectDrawSurface3_SetPalette, | |
| DGA_IDirectDrawSurface3_Unlock, | |
| IDirectDrawSurface3_UpdateOverlay, | |
| IDirectDrawSurface3_UpdateOverlayDisplay, | |
| IDirectDrawSurface3_UpdateOverlayZOrder, | |
| IDirectDrawSurface3_GetDDInterface, | |
| IDirectDrawSurface3_PageLock, | |
| IDirectDrawSurface3_PageUnlock, | |
| IDirectDrawSurface3_SetSurfaceDesc, | |
| }; | |
| static struct IDirectDrawSurface3_VTable xlib_dds3vt = { | |
| IDirectDrawSurface3_QueryInterface, | |
| IDirectDrawSurface3_AddRef, | |
| Xlib_IDirectDrawSurface3_Release, | |
| IDirectDrawSurface3_AddAttachedSurface, | |
| IDirectDrawSurface3_AddOverlayDirtyRect, | |
| IDirectDrawSurface3_Blt, | |
| IDirectDrawSurface3_BltBatch, | |
| IDirectDrawSurface3_BltFast, | |
| IDirectDrawSurface3_DeleteAttachedSurface, | |
| IDirectDrawSurface3_EnumAttachedSurfaces, | |
| IDirectDrawSurface3_EnumOverlayZOrders, | |
| Xlib_IDirectDrawSurface3_Flip, | |
| IDirectDrawSurface3_GetAttachedSurface, | |
| IDirectDrawSurface3_GetBltStatus, | |
| IDirectDrawSurface3_GetCaps, | |
| IDirectDrawSurface3_GetClipper, | |
| IDirectDrawSurface3_GetColorKey, | |
| IDirectDrawSurface3_GetDC, | |
| IDirectDrawSurface3_GetFlipStatus, | |
| IDirectDrawSurface3_GetOverlayPosition, | |
| IDirectDrawSurface3_GetPalette, | |
| IDirectDrawSurface3_GetPixelFormat, | |
| IDirectDrawSurface3_GetSurfaceDesc, | |
| IDirectDrawSurface3_Initialize, | |
| IDirectDrawSurface3_IsLost, | |
| IDirectDrawSurface3_Lock, | |
| IDirectDrawSurface3_ReleaseDC, | |
| IDirectDrawSurface3_Restore, | |
| IDirectDrawSurface3_SetClipper, | |
| IDirectDrawSurface3_SetColorKey, | |
| IDirectDrawSurface3_SetOverlayPosition, | |
| Xlib_IDirectDrawSurface3_SetPalette, | |
| Xlib_IDirectDrawSurface3_Unlock, | |
| IDirectDrawSurface3_UpdateOverlay, | |
| IDirectDrawSurface3_UpdateOverlayDisplay, | |
| IDirectDrawSurface3_UpdateOverlayZOrder, | |
| IDirectDrawSurface3_GetDDInterface, | |
| IDirectDrawSurface3_PageLock, | |
| IDirectDrawSurface3_PageUnlock, | |
| IDirectDrawSurface3_SetSurfaceDesc, | |
| }; | |
| /****************************************************************************** | |
| * DirectDrawCreateClipper (DDRAW.7) | |
| */ | |
| HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags, | |
| LPDIRECTDRAWCLIPPER *lplpDDClipper, | |
| LPUNKNOWN pUnkOuter) | |
| { | |
| TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter); | |
| *lplpDDClipper = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper)); | |
| (*lplpDDClipper)->lpvtbl = &ddclipvt; | |
| (*lplpDDClipper)->ref = 1; | |
| return 0; | |
| } | |
| /****************************************************************************** | |
| * IDirectDrawClipper | |
| */ | |
| static HRESULT WINAPI IDirectDrawClipper_SetHwnd( | |
| LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd | |
| ) { | |
| FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd); | |
| return 0; | |
| } | |
| static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) { | |
| TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); | |
| this->ref--; | |
| if (this->ref) | |
| return this->ref; | |
| HeapFree(GetProcessHeap(),0,this); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawClipper_GetClipList( | |
| LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm | |
| ) { | |
| FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm); | |
| if (hmm) *hmm=0; | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDrawClipper_SetClipList( | |
| LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm | |
| ) { | |
| FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm); | |
| return 0; | |
| } | |
| static struct IDirectDrawClipper_VTable ddclipvt = { | |
| (void*)1, | |
| (void*)2, | |
| IDirectDrawClipper_Release, | |
| IDirectDrawClipper_GetClipList, | |
| (void*)5, | |
| (void*)6, | |
| (void*)7, | |
| IDirectDrawClipper_SetClipList, | |
| IDirectDrawClipper_SetHwnd | |
| }; | |
| /****************************************************************************** | |
| * IDirectDrawPalette | |
| */ | |
| static HRESULT WINAPI IDirectDrawPalette_GetEntries( | |
| LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent | |
| ) { | |
| int i; | |
| TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n", | |
| this,x,start,count,palent); | |
| if (!this->cm) /* should not happen */ { | |
| FIXME(ddraw,"app tried to read colormap for non-palettized mode\n"); | |
| return DDERR_GENERIC; | |
| } | |
| for (i=0;i<count;i++) { | |
| palent[i].peRed = this->palents[start+i].peRed; | |
| palent[i].peBlue = this->palents[start+i].peBlue; | |
| palent[i].peGreen = this->palents[start+i].peGreen; | |
| palent[i].peFlags = this->palents[start+i].peFlags; | |
| } | |
| return 0; | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries( | |
| LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent | |
| ) { | |
| XColor xc; | |
| int i; | |
| TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n", | |
| this,x,start,count,palent | |
| ); | |
| for (i=0;i<count;i++) { | |
| xc.red = palent[i].peRed<<8; | |
| xc.blue = palent[i].peBlue<<8; | |
| xc.green = palent[i].peGreen<<8; | |
| xc.flags = DoRed|DoBlue|DoGreen; | |
| xc.pixel = start+i; | |
| if (this->cm) | |
| TSXStoreColor(display,this->cm,&xc); | |
| this->palents[start+i].peRed = palent[i].peRed; | |
| this->palents[start+i].peBlue = palent[i].peBlue; | |
| this->palents[start+i].peGreen = palent[i].peGreen; | |
| this->palents[start+i].peFlags = palent[i].peFlags; | |
| } | |
| if (!this->cm) /* should not happen */ { | |
| } | |
| return 0; | |
| } | |
| static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries( | |
| LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent | |
| ) { | |
| #ifdef HAVE_LIBXXF86DGA | |
| XColor xc; | |
| Colormap cm; | |
| int i; | |
| TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n", | |
| this,x,start,count,palent | |
| ); | |
| if (!this->cm) /* should not happen */ { | |
| FIXME(ddraw,"app tried to set colormap in non-palettized mode\n"); | |
| return DDERR_GENERIC; | |
| } | |
| /* FIXME: free colorcells instead of freeing whole map */ | |
| cm = this->cm; | |
| this->cm = TSXCopyColormapAndFree(display,this->cm); | |
| TSXFreeColormap(display,cm); | |
| for (i=0;i<count;i++) { | |
| xc.red = palent[i].peRed<<8; | |
| xc.blue = palent[i].peBlue<<8; | |
| xc.green = palent[i].peGreen<<8; | |
| xc.flags = DoRed|DoBlue|DoGreen; | |
| xc.pixel = i+start; | |
| TSXStoreColor(display,this->cm,&xc); | |
| this->palents[start+i].peRed = palent[i].peRed; | |
| this->palents[start+i].peBlue = palent[i].peBlue; | |
| this->palents[start+i].peGreen = palent[i].peGreen; | |
| this->palents[start+i].peFlags = palent[i].peFlags; | |
| } | |
| TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm); | |
| return 0; | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return E_UNEXPECTED; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| } | |
| static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) { | |
| TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); | |
| if (!--(this->ref)) { | |
| if (this->cm) { | |
| TSXFreeColormap(display,this->cm); | |
| this->cm = 0; | |
| } | |
| HeapFree(GetProcessHeap(),0,this); | |
| return 0; | |
| } | |
| return this->ref; | |
| } | |
| static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) { | |
| TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref ); | |
| return ++(this->ref); | |
| } | |
| static HRESULT WINAPI IDirectDrawPalette_Initialize( | |
| LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent | |
| ) { | |
| TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", this, ddraw, x, palent); | |
| return DDERR_ALREADYINITIALIZED; | |
| } | |
| static HRESULT WINAPI IDirectDrawPalette_GetCaps( | |
| LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps ) | |
| { | |
| FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps ); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawPalette_QueryInterface( | |
| LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj ) | |
| { | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj); | |
| return S_OK; | |
| } | |
| static struct IDirectDrawPalette_VTable dga_ddpalvt = { | |
| IDirectDrawPalette_QueryInterface, | |
| IDirectDrawPalette_AddRef, | |
| IDirectDrawPalette_Release, | |
| IDirectDrawPalette_GetCaps, | |
| IDirectDrawPalette_GetEntries, | |
| IDirectDrawPalette_Initialize, | |
| DGA_IDirectDrawPalette_SetEntries | |
| }; | |
| static struct IDirectDrawPalette_VTable xlib_ddpalvt = { | |
| IDirectDrawPalette_QueryInterface, | |
| IDirectDrawPalette_AddRef, | |
| IDirectDrawPalette_Release, | |
| IDirectDrawPalette_GetCaps, | |
| IDirectDrawPalette_GetEntries, | |
| IDirectDrawPalette_Initialize, | |
| Xlib_IDirectDrawPalette_SetEntries | |
| }; | |
| /******************************************************************************* | |
| * IDirect3D | |
| */ | |
| static HRESULT WINAPI IDirect3D_QueryInterface( | |
| LPDIRECT3D this,REFIID refiid,LPVOID *obj | |
| ) { | |
| /* FIXME: Not sure if this is correct */ | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj); | |
| if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) { | |
| *obj = this; | |
| this->lpvtbl->fnAddRef(this); | |
| return 0; | |
| } | |
| if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) { | |
| LPDIRECT3D d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = (LPDIRECTDRAW)this; | |
| this->lpvtbl->fnAddRef(this); | |
| d3d->lpvtbl = &d3dvt; | |
| *obj = d3d; | |
| return 0; | |
| } | |
| if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) { | |
| LPDIRECT3D2 d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = (LPDIRECTDRAW)this; | |
| this->lpvtbl->fnAddRef(this); | |
| d3d->lpvtbl = &d3d2vt; | |
| *obj = d3d; | |
| return 0; | |
| } | |
| FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid); | |
| return OLE_E_ENUM_NOMORE; | |
| } | |
| static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) { | |
| TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref ); | |
| return ++(this->ref); | |
| } | |
| static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this) | |
| { | |
| TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); | |
| if (!--(this->ref)) { | |
| this->ddraw->lpvtbl->fnRelease(this->ddraw); | |
| HeapFree(GetProcessHeap(),0,this); | |
| return 0; | |
| } | |
| return this->ref; | |
| } | |
| static HRESULT WINAPI IDirect3D_Initialize( | |
| LPDIRECT3D this, REFIID refiid ) | |
| { | |
| /* FIXME: Not sure if this is correct */ | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid); | |
| return DDERR_ALREADYINITIALIZED; | |
| } | |
| /******************************************************************************* | |
| * IDirect3D | |
| */ | |
| static struct IDirect3D_VTable d3dvt = { | |
| (void*)IDirect3D_QueryInterface, | |
| (void*)IDirect3D_AddRef, | |
| (void*)IDirect3D_Release, | |
| IDirect3D_Initialize, | |
| (void*)5, | |
| (void*)6, | |
| (void*)7, | |
| (void*)8, | |
| (void*)9, | |
| }; | |
| /******************************************************************************* | |
| * IDirect3D2 | |
| */ | |
| static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) { | |
| TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); | |
| if (!--(this->ref)) { | |
| this->ddraw->lpvtbl->fnRelease(this->ddraw); | |
| HeapFree(GetProcessHeap(),0,this); | |
| return 0; | |
| } | |
| return this->ref; | |
| } | |
| static HRESULT WINAPI IDirect3D2_EnumDevices( | |
| LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context | |
| ) { | |
| D3DDEVICEDESC d1,d2; | |
| FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context); | |
| #if 0 | |
| d1.dwSize = sizeof(d1); | |
| d1.dwFlags = 0; | |
| d2.dwSize = sizeof(d2); | |
| d2.dwFlags = 0; | |
| cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context); | |
| #endif | |
| return 0; | |
| } | |
| static struct IDirect3D2_VTable d3d2vt = { | |
| (void*)1, | |
| (void*)2, | |
| IDirect3D2_Release, | |
| IDirect3D2_EnumDevices, | |
| (void*)5, | |
| (void*)6, | |
| (void*)7, | |
| (void*)8, | |
| (void*)9, | |
| }; | |
| /******************************************************************************* | |
| * IDirectDraw | |
| */ | |
| /* Used in conjunction with cbWndExtra for storage of the this ptr for the window. | |
| * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here. | |
| */ | |
| static INT32 ddrawXlibThisOffset = 0; | |
| static HRESULT common_off_screen_CreateSurface(LPDIRECTDRAW2 this, | |
| LPDDSURFACEDESC lpddsd, | |
| LPDIRECTDRAWSURFACE lpdsf) | |
| { | |
| int bpp; | |
| /* The surface was already allocated when entering in this function */ | |
| if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) { | |
| /* No pixel format => use DirectDraw's format */ | |
| _getpixelformat(this,&(lpddsd->ddpfPixelFormat)); | |
| lpddsd->dwFlags |= DDSD_PIXELFORMAT; | |
| } else { | |
| /* To check what the program wants */ | |
| if (TRACE_ON(ddraw)) { | |
| _dump_pixelformat(&(lpddsd->ddpfPixelFormat)); | |
| } | |
| } | |
| bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8; | |
| /* Copy the surface description */ | |
| lpdsf->s.surface_desc = *lpddsd; | |
| lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE; | |
| lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp); | |
| lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp; | |
| TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf); | |
| return 0; | |
| } | |
| static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface( | |
| LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk | |
| ) { | |
| #ifdef HAVE_LIBXXF86DGA | |
| int i; | |
| TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk); | |
| if (TRACE_ON(ddraw)) { | |
| DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight); | |
| _dump_DDSD(lpddsd->dwFlags); | |
| fprintf(stderr,"caps "); | |
| _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps); | |
| fprintf(stderr,"]\n"); | |
| } | |
| *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface)); | |
| this->lpvtbl->fnAddRef(this); | |
| (*lpdsf)->ref = 1; | |
| (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt; | |
| (*lpdsf)->s.ddraw = this; | |
| (*lpdsf)->s.palette = NULL; | |
| (*lpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */ | |
| if (!(lpddsd->dwFlags & DDSD_WIDTH)) | |
| lpddsd->dwWidth = this->d.width; | |
| if (!(lpddsd->dwFlags & DDSD_HEIGHT)) | |
| lpddsd->dwHeight = this->d.height; | |
| /* Check if this a 'primary surface' or not */ | |
| if ((lpddsd->dwFlags & DDSD_CAPS) && | |
| (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) { | |
| /* This is THE primary surface => there is DGA-specific code */ | |
| /* First, store the surface description */ | |
| (*lpdsf)->s.surface_desc = *lpddsd; | |
| /* Find a viewport */ | |
| for (i=0;i<32;i++) | |
| if (!(this->e.dga.vpmask & (1<<i))) | |
| break; | |
| TRACE(ddraw,"using viewport %d for a primary surface\n",i); | |
| /* if i == 32 or maximum ... return error */ | |
| this->e.dga.vpmask|=(1<<i); | |
| (*lpdsf)->s.surface_desc.y.lpSurface = | |
| this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8); | |
| (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height; | |
| (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.depth/8; | |
| lpddsd->lPitch = (*lpdsf)->s.surface_desc.lPitch; | |
| /* Add flags if there were not present */ | |
| (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE; | |
| (*lpdsf)->s.surface_desc.dwWidth = this->d.width; | |
| (*lpdsf)->s.surface_desc.dwHeight = this->d.height; | |
| (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE; | |
| _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat)); | |
| (*lpdsf)->s.backbuffer = NULL; | |
| if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) { | |
| LPDIRECTDRAWSURFACE3 back; | |
| if (lpddsd->dwBackBufferCount>1) | |
| FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount); | |
| (*lpdsf)->s.backbuffer = back = | |
| (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3)); | |
| this->lpvtbl->fnAddRef(this); | |
| back->ref = 1; | |
| back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt; | |
| for (i=0;i<32;i++) | |
| if (!(this->e.dga.vpmask & (1<<i))) | |
| break; | |
| TRACE(ddraw,"using viewport %d for backbuffer\n",i); | |
| /* if i == 32 or maximum ... return error */ | |
| this->e.dga.vpmask|=(1<<i); | |
| back->t.dga.fb_height = i*this->e.dga.fb_height; | |
| /* Copy the surface description from the front buffer */ | |
| back->s.surface_desc = (*lpdsf)->s.surface_desc; | |
| /* Change the parameters that are not the same */ | |
| back->s.surface_desc.y.lpSurface = this->e.dga.fb_addr+ | |
| ((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8); | |
| back->s.ddraw = this; | |
| back->s.backbuffer = NULL; /* does not have a backbuffer, it is | |
| * one! */ | |
| /* Add relevant info to front and back buffers */ | |
| (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; | |
| back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; | |
| back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; | |
| back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE; | |
| } | |
| } else { | |
| /* There is no DGA-specific code here... | |
| Go to the common surface creation function */ | |
| return common_off_screen_CreateSurface(this, lpddsd, *lpdsf); | |
| } | |
| return 0; | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return E_UNEXPECTED; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| } | |
| static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE3 lpdsf) { | |
| XImage *img; | |
| #ifdef HAVE_LIBXXSHM | |
| if (this->e.xlib.xshm_active) { | |
| img = TSXShmCreateImage(display, | |
| DefaultVisualOfScreen(screen), | |
| this->d.depth, | |
| ZPixmap, | |
| NULL, | |
| &(lpdsf->t.xlib.shminfo), | |
| lpdsf->s.surface_desc.dwWidth, | |
| lpdsf->s.surface_desc.dwHeight); | |
| if (img == NULL) | |
| return NULL; | |
| lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 ); | |
| if (lpdsf->t.xlib.shminfo.shmid < 0) { | |
| TSXDestroyImage(img); | |
| return NULL; | |
| } | |
| lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0); | |
| if (img->data == (char *) -1) { | |
| TSXDestroyImage(img); | |
| shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0); | |
| return NULL; | |
| } | |
| lpdsf->t.xlib.shminfo.readOnly = False; | |
| TSXShmAttach(display, &(lpdsf->t.xlib.shminfo)); | |
| TSXSync(display, False); | |
| shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0); | |
| lpdsf->s.surface_desc.y.lpSurface = img->data; | |
| } else { | |
| #endif | |
| /* Allocate surface memory */ | |
| lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, | |
| lpdsf->s.surface_desc.dwWidth * | |
| lpdsf->s.surface_desc.dwHeight * | |
| (this->d.depth / 8)); | |
| /* In this case, create an XImage */ | |
| img = | |
| TSXCreateImage(display, | |
| DefaultVisualOfScreen(screen), | |
| this->d.depth, | |
| ZPixmap, | |
| 0, | |
| lpdsf->s.surface_desc.y.lpSurface, | |
| lpdsf->s.surface_desc.dwWidth, | |
| lpdsf->s.surface_desc.dwHeight, | |
| 32, | |
| lpdsf->s.surface_desc.dwWidth * (this->d.depth / 8) | |
| ); | |
| #ifdef HAVE_LIBXXSHM | |
| } | |
| #endif | |
| lpdsf->s.surface_desc.lPitch = img->bytes_per_line; | |
| return img; | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface( | |
| LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk | |
| ) { | |
| TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n", | |
| this,lpddsd,lpdsf,lpunk); | |
| if (TRACE_ON(ddraw)) { | |
| fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight); | |
| _dump_DDSD(lpddsd->dwFlags); | |
| fprintf(stderr,"caps "); | |
| _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps); | |
| fprintf(stderr,"]\n"); | |
| } | |
| *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface)); | |
| this->lpvtbl->fnAddRef(this); | |
| (*lpdsf)->s.ddraw = this; | |
| (*lpdsf)->ref = 1; | |
| (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt; | |
| (*lpdsf)->s.palette = NULL; | |
| (*lpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */ | |
| if (!(lpddsd->dwFlags & DDSD_WIDTH)) | |
| lpddsd->dwWidth = this->d.width; | |
| if (!(lpddsd->dwFlags & DDSD_HEIGHT)) | |
| lpddsd->dwHeight = this->d.height; | |
| /* Check if this a 'primary surface' or not */ | |
| if ((lpddsd->dwFlags & DDSD_CAPS) && | |
| (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) { | |
| XImage *img; | |
| TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *lpdsf); | |
| /* First, store the surface description */ | |
| (*lpdsf)->s.surface_desc = *lpddsd; | |
| /* Create the XImage */ | |
| img = create_ximage(this, (LPDIRECTDRAWSURFACE3) *lpdsf); | |
| if (img == NULL) | |
| return DDERR_OUTOFMEMORY; | |
| (*lpdsf)->t.xlib.image = img; | |
| /* Add flags if there were not present */ | |
| (*lpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE; | |
| (*lpdsf)->s.surface_desc.dwWidth = this->d.width; | |
| (*lpdsf)->s.surface_desc.dwHeight = this->d.height; | |
| (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE; | |
| _getpixelformat(this,&((*lpdsf)->s.surface_desc.ddpfPixelFormat)); | |
| (*lpdsf)->s.backbuffer = NULL; | |
| /* Check for backbuffers */ | |
| if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) { | |
| LPDIRECTDRAWSURFACE3 back; | |
| XImage *img; | |
| if (lpddsd->dwBackBufferCount>1) | |
| FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount); | |
| (*lpdsf)->s.backbuffer = back = | |
| (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3)); | |
| TRACE(ddraw,"allocated back-buffer (%p)\n", back); | |
| this->lpvtbl->fnAddRef(this); | |
| back->s.ddraw = this; | |
| back->ref = 1; | |
| back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt; | |
| /* Copy the surface description from the front buffer */ | |
| back->s.surface_desc = (*lpdsf)->s.surface_desc; | |
| /* Create the XImage */ | |
| img = create_ximage(this, back); | |
| if (img == NULL) | |
| return DDERR_OUTOFMEMORY; | |
| back->t.xlib.image = img; | |
| back->s.backbuffer = NULL; /* does not have a backbuffer, it is | |
| * one! */ | |
| /* Add relevant info to front and back buffers */ | |
| (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; | |
| back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; | |
| back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; | |
| back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE; | |
| } | |
| } else { | |
| /* There is no Xlib-specific code here... | |
| Go to the common surface creation function */ | |
| return common_off_screen_CreateSurface(this, lpddsd, *lpdsf); | |
| } | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDraw2_DuplicateSurface( | |
| LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst | |
| ) { | |
| FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst); | |
| *dst = src; /* FIXME */ | |
| return 0; | |
| } | |
| /* | |
| * The Xlib Implementation tries to use the passed hwnd as drawing window, | |
| * even when the approbiate bitmasks are not specified. | |
| */ | |
| static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel( | |
| LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel | |
| ) { | |
| int i; | |
| const struct { | |
| int mask; | |
| char *name; | |
| } flagmap[] = { | |
| FE(DDSCL_FULLSCREEN) | |
| FE(DDSCL_ALLOWREBOOT) | |
| FE(DDSCL_NOWINDOWCHANGES) | |
| FE(DDSCL_NORMAL) | |
| FE(DDSCL_ALLOWMODEX) | |
| FE(DDSCL_EXCLUSIVE) | |
| FE(DDSCL_SETFOCUSWINDOW) | |
| FE(DDSCL_SETDEVICEWINDOW) | |
| FE(DDSCL_CREATEDEVICEWINDOW) | |
| }; | |
| FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel); | |
| if(TRACE_ON(ddraw)){ | |
| dbg_decl_str(ddraw, 512); | |
| for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++) | |
| if (flagmap[i].mask & cooplevel) | |
| dsprintf(ddraw, "%s ", flagmap[i].name); | |
| TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw)); | |
| } | |
| this->d.mainWindow = hwnd; | |
| return 0; | |
| } | |
| /* Small helper to either use the cooperative window or create a new | |
| * one (for mouse and keyboard input) and drawing in the Xlib implementation. | |
| */ | |
| static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW this) { | |
| RECT32 rect; | |
| /* Do not destroy the application supplied cooperative window */ | |
| if (this->d.window && this->d.window != this->d.mainWindow) { | |
| DestroyWindow32(this->d.window); | |
| this->d.window = 0; | |
| } | |
| /* Sanity check cooperative window before assigning it to drawing. */ | |
| if ( IsWindow32(this->d.mainWindow) && | |
| IsWindowVisible32(this->d.mainWindow) | |
| ) { | |
| GetWindowRect32(this->d.mainWindow,&rect); | |
| if (((rect.right-rect.left) >= this->d.width) && | |
| ((rect.bottom-rect.top) >= this->d.height) | |
| ) | |
| this->d.window = this->d.mainWindow; | |
| } | |
| /* ... failed, create new one. */ | |
| if (!this->d.window) { | |
| this->d.window = CreateWindowEx32A( | |
| 0, | |
| "WINE_DirectDraw", | |
| "WINE_DirectDraw", | |
| WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME, | |
| 0,0, | |
| this->d.width, | |
| this->d.height, | |
| 0, | |
| 0, | |
| 0, | |
| NULL | |
| ); | |
| /*Store THIS with the window. We'll use it in the window procedure*/ | |
| SetWindowLong32A(this->d.window,ddrawXlibThisOffset,(LONG)this); | |
| ShowWindow32(this->d.window,TRUE); | |
| UpdateWindow32(this->d.window); | |
| } | |
| SetFocus32(this->d.window); | |
| } | |
| static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode( | |
| LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth | |
| ) { | |
| #ifdef HAVE_LIBXXF86DGA | |
| int i,*depths,depcount,mode_count; | |
| TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth); | |
| depths = TSXListDepths(display,DefaultScreen(display),&depcount); | |
| for (i=0;i<depcount;i++) | |
| if (depths[i]==depth) | |
| break; | |
| TSXFree(depths); | |
| if (i==depcount) {/* not found */ | |
| ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth); | |
| return DDERR_UNSUPPORTEDMODE; | |
| } | |
| if (this->d.width < width) { | |
| ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width); | |
| return DDERR_UNSUPPORTEDMODE; | |
| } | |
| this->d.width = width; | |
| this->d.height = height; | |
| this->d.depth = depth; | |
| /* adjust fb_height, so we don't overlap */ | |
| if (this->e.dga.fb_height < height) | |
| this->e.dga.fb_height = height; | |
| _common_IDirectDraw_SetDisplayMode(this); | |
| #ifdef HAVE_LIBXXF86VM | |
| { | |
| XF86VidModeModeInfo **all_modes, *vidmode = NULL; | |
| /* set fullscreen mode */ | |
| /* do we need to save the old video mode and restore it when we exit? */ | |
| TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes); | |
| for (i=0;i<mode_count;i++) | |
| { | |
| if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height) | |
| { | |
| vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo)); | |
| *vidmode = *(all_modes[i]); | |
| break; | |
| } else | |
| TSXFree(all_modes[i]->private); | |
| } | |
| TSXFree(all_modes); | |
| if (!vidmode) | |
| WARN(ddraw, "Fullscreen mode not available!\n"); | |
| if (vidmode) | |
| TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode); | |
| } | |
| #endif | |
| /* FIXME: this function OVERWRITES several signal handlers. | |
| * can we save them? and restore them later? In a way that | |
| * it works for the library too? | |
| */ | |
| TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics); | |
| #ifdef DIABLO_HACK | |
| TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height); | |
| #endif | |
| #ifdef RESTORE_SIGNALS | |
| SIGNAL_InitEmulator(); | |
| #endif | |
| return 0; | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return E_UNEXPECTED; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode( | |
| LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth | |
| ) { | |
| int i,*depths,depcount; | |
| char buf[200]; | |
| TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n", | |
| this, width, height, depth); | |
| depths = TSXListDepths(display,DefaultScreen(display),&depcount); | |
| for (i=0;i<depcount;i++) | |
| if (depths[i]==depth) | |
| break; | |
| TSXFree(depths); | |
| if (i==depcount) {/* not found */ | |
| sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth); | |
| MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP); | |
| return DDERR_UNSUPPORTEDMODE; | |
| } | |
| this->d.width = width; | |
| this->d.height = height; | |
| this->d.depth = depth; | |
| _common_IDirectDraw_SetDisplayMode(this); | |
| this->e.xlib.paintable = 1; | |
| this->e.xlib.drawable = WIN_FindWndPtr(this->d.window)->window; | |
| /* We don't have a context for this window. Host off the desktop */ | |
| if( !this->e.xlib.drawable ) | |
| this->e.xlib.drawable = WIN_GetDesktop()->window; | |
| return 0; | |
| } | |
| static HRESULT WINAPI DGA_IDirectDraw2_GetCaps( | |
| LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2 | |
| ) { | |
| #ifdef HAVE_LIBXXF86DGA | |
| TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2); | |
| caps1->dwVidMemTotal = this->e.dga.fb_memsize; | |
| caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */ | |
| caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */ | |
| if (caps2) { | |
| caps2->dwVidMemTotal = this->e.dga.fb_memsize; | |
| caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */ | |
| caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */ | |
| } | |
| return 0; | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return E_UNEXPECTED; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps( | |
| LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2 | |
| ) { | |
| TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2); | |
| /* FIXME: Xlib */ | |
| caps1->dwVidMemTotal = 2048*1024; | |
| caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI); | |
| caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */ | |
| if (caps2) { | |
| caps2->dwVidMemTotal = 2048*1024; | |
| caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED|DDCAPS_GDI); | |
| caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */ | |
| } | |
| /* END FIXME: Xlib */ | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDraw2_CreateClipper( | |
| LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk | |
| ) { | |
| FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n", | |
| this,x,lpddclip,lpunk | |
| ); | |
| *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper)); | |
| (*lpddclip)->ref = 1; | |
| (*lpddclip)->lpvtbl = &ddclipvt; | |
| return 0; | |
| } | |
| static HRESULT WINAPI common_IDirectDraw2_CreatePalette( | |
| LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk | |
| ) { | |
| *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette)); | |
| if (*lpddpal == NULL) return E_OUTOFMEMORY; | |
| (*lpddpal)->ref = 1; | |
| (*lpddpal)->ddraw = (LPDIRECTDRAW)this; | |
| (*lpddpal)->installed = 0; | |
| if (this->d.depth<=8) { | |
| (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll); | |
| } else { | |
| /* we don't want palettes in hicolor or truecolor */ | |
| (*lpddpal)->cm = 0; | |
| } | |
| return 0; | |
| } | |
| static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette( | |
| LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk | |
| ) { | |
| HRESULT res; | |
| TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk); | |
| res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk); | |
| if (res != 0) return res; | |
| (*lpddpal)->lpvtbl = &dga_ddpalvt; | |
| return 0; | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette( | |
| LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk | |
| ) { | |
| TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk); | |
| *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette)); | |
| if (*lpddpal == NULL) return E_OUTOFMEMORY; | |
| (*lpddpal)->ref = 1; | |
| (*lpddpal)->installed = 0; | |
| if (palent) | |
| FIXME(ddraw,"needs to handle palent (%p)\n",palent); | |
| (*lpddpal)->ddraw = (LPDIRECTDRAW)this; | |
| this->lpvtbl->fnAddRef(this); | |
| (*lpddpal)->cm = 0; | |
| (*lpddpal)->lpvtbl = &xlib_ddpalvt; | |
| return 0; | |
| } | |
| static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) { | |
| #ifdef HAVE_LIBXXF86DGA | |
| TRACE(ddraw, "(%p)->()\n",this); | |
| Sleep(1000); | |
| TSXF86DGADirectVideo(display,DefaultScreen(display),0); | |
| #ifdef RESTORE_SIGNALS | |
| SIGNAL_InitEmulator(); | |
| #endif | |
| return 0; | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return E_UNEXPECTED; | |
| #endif | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) { | |
| TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this); | |
| Sleep(1000); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank( | |
| LPDIRECTDRAW2 this,DWORD x,HANDLE32 h | |
| ) { | |
| TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h); | |
| return 0; | |
| } | |
| static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) { | |
| TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref ); | |
| return ++(this->ref); | |
| } | |
| static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) { | |
| TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); | |
| #ifdef HAVE_LIBXXF86DGA | |
| if (!--(this->ref)) { | |
| TSXF86DGADirectVideo(display,DefaultScreen(display),0); | |
| #ifdef RESTORE_SIGNALS | |
| SIGNAL_InitEmulator(); | |
| #endif | |
| HeapFree(GetProcessHeap(),0,this); | |
| return 0; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| return this->ref; | |
| } | |
| static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) { | |
| TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref ); | |
| if (!--(this->ref)) { | |
| HeapFree(GetProcessHeap(),0,this); | |
| return 0; | |
| } | |
| /* FIXME: destroy window ... */ | |
| return this->ref; | |
| } | |
| static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface( | |
| LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj | |
| ) { | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj); | |
| if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) { | |
| *obj = this; | |
| this->lpvtbl->fnAddRef(this); | |
| return 0; | |
| } | |
| if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) { | |
| this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt; | |
| this->lpvtbl->fnAddRef(this); | |
| *obj = this; | |
| return 0; | |
| } | |
| if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) { | |
| this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt; | |
| this->lpvtbl->fnAddRef(this); | |
| *obj = this; | |
| return 0; | |
| } | |
| if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) { | |
| LPDIRECT3D d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = (LPDIRECTDRAW)this; | |
| this->lpvtbl->fnAddRef(this); | |
| d3d->lpvtbl = &d3dvt; | |
| *obj = d3d; | |
| return 0; | |
| } | |
| if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) { | |
| LPDIRECT3D2 d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = (LPDIRECTDRAW)this; | |
| this->lpvtbl->fnAddRef(this); | |
| d3d->lpvtbl = &d3d2vt; | |
| *obj = d3d; | |
| return 0; | |
| } | |
| WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid); | |
| return OLE_E_ENUM_NOMORE; | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface( | |
| LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj | |
| ) { | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj); | |
| if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) { | |
| *obj = this; | |
| this->lpvtbl->fnAddRef(this); | |
| return 0; | |
| } | |
| if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) { | |
| this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt; | |
| this->lpvtbl->fnAddRef(this); | |
| *obj = this; | |
| return 0; | |
| } | |
| if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) { | |
| this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt; | |
| this->lpvtbl->fnAddRef(this); | |
| *obj = this; | |
| return 0; | |
| } | |
| if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) { | |
| LPDIRECT3D d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = (LPDIRECTDRAW)this; | |
| this->lpvtbl->fnAddRef(this); | |
| d3d->lpvtbl = &d3dvt; | |
| *obj = d3d; | |
| return 0; | |
| } | |
| if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) { | |
| LPDIRECT3D2 d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = (LPDIRECTDRAW)this; | |
| this->lpvtbl->fnAddRef(this); | |
| d3d->lpvtbl = &d3d2vt; | |
| *obj = d3d; | |
| return 0; | |
| } | |
| WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid); | |
| return OLE_E_ENUM_NOMORE; | |
| } | |
| static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus( | |
| LPDIRECTDRAW2 this,BOOL32 *status | |
| ) { | |
| TRACE(ddraw,"(%p)->(%p)\n",this,status); | |
| *status = TRUE; | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDraw2_EnumDisplayModes( | |
| LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb | |
| ) { | |
| DDSURFACEDESC ddsfd; | |
| static struct { | |
| int w,h; | |
| } modes[5] = { /* some of the usual modes */ | |
| {512,384}, | |
| {640,400}, | |
| {640,480}, | |
| {800,600}, | |
| {1024,768}, | |
| }; | |
| static int depths[4] = {8,16,24,32}; | |
| int i,j; | |
| TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb); | |
| ddsfd.dwSize = sizeof(ddsfd); | |
| ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS; | |
| if (dwFlags & DDEDM_REFRESHRATES) { | |
| ddsfd.dwFlags |= DDSD_REFRESHRATE; | |
| ddsfd.x.dwRefreshRate = 60; | |
| } | |
| for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) { | |
| ddsfd.dwBackBufferCount = 1; | |
| ddsfd.ddpfPixelFormat.dwFourCC = 0; | |
| ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB; | |
| ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i]; | |
| /* FIXME: those masks would have to be set in depth > 8 */ | |
| if (depths[i]==8) { | |
| ddsfd.ddpfPixelFormat.y.dwRBitMask = 0; | |
| ddsfd.ddpfPixelFormat.z.dwGBitMask = 0; | |
| ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0; | |
| ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0; | |
| ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE; | |
| ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8; | |
| } else { | |
| ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0; | |
| /* FIXME: We should query those from X itself */ | |
| switch (depths[i]) { | |
| case 16: | |
| ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000f; | |
| ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x00f0; | |
| ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x0f00; | |
| break; | |
| case 24: | |
| ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff; | |
| ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00; | |
| ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000; | |
| break; | |
| case 32: | |
| ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x000000ff; | |
| ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000ff00; | |
| ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x00ff0000; | |
| break; | |
| } | |
| } | |
| ddsfd.dwWidth = screenWidth; | |
| ddsfd.dwHeight = screenHeight; | |
| TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]); | |
| if (!modescb(&ddsfd,context)) return 0; | |
| for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) { | |
| ddsfd.dwWidth = modes[j].w; | |
| ddsfd.dwHeight = modes[j].h; | |
| TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]); | |
| if (!modescb(&ddsfd,context)) return 0; | |
| } | |
| if (!(dwFlags & DDEDM_STANDARDVGAMODES)) { | |
| /* modeX is not standard VGA */ | |
| ddsfd.dwHeight = 200; | |
| ddsfd.dwWidth = 320; | |
| TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]); | |
| if (!modescb(&ddsfd,context)) return 0; | |
| } | |
| } | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode( | |
| LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd | |
| ) { | |
| #ifdef HAVE_LIBXXF86DGA | |
| TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd); | |
| lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS; | |
| lpddsfd->dwHeight = screenHeight; | |
| lpddsfd->dwWidth = screenWidth; | |
| lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8; | |
| lpddsfd->dwBackBufferCount = 1; | |
| lpddsfd->x.dwRefreshRate = 60; | |
| lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE; | |
| _getpixelformat(this,&(lpddsfd->ddpfPixelFormat)); | |
| return DD_OK; | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return E_UNEXPECTED; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode( | |
| LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd | |
| ) { | |
| TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd); | |
| lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS; | |
| lpddsfd->dwHeight = screenHeight; | |
| lpddsfd->dwWidth = screenWidth; | |
| /* POOLE FIXME: Xlib */ | |
| lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8; | |
| /* END FIXME: Xlib */ | |
| lpddsfd->dwBackBufferCount = 1; | |
| lpddsfd->x.dwRefreshRate = 60; | |
| lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE; | |
| _getpixelformat(this,&(lpddsfd->ddpfPixelFormat)); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) { | |
| TRACE(ddraw,"(%p)->()\n",this); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency( | |
| LPDIRECTDRAW2 this,LPDWORD freq | |
| ) { | |
| FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq); | |
| *freq = 60*100; /* 60 Hz */ | |
| return 0; | |
| } | |
| /* what can we directly decompress? */ | |
| static HRESULT WINAPI IDirectDraw2_GetFourCCCodes( | |
| LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y | |
| ) { | |
| FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDraw2_EnumSurfaces( | |
| LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb | |
| ) { | |
| FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb); | |
| return 0; | |
| } | |
| static HRESULT WINAPI IDirectDraw2_Compact( | |
| LPDIRECTDRAW2 this ) | |
| { | |
| FIXME(ddraw,"(%p)->()\n", this ); | |
| return DD_OK; | |
| } | |
| /* Note: Hack so we can reuse the old functions without compiler warnings */ | |
| #ifdef __GNUC__ | |
| # define XCAST(fun) (typeof(dga_ddvt.fn##fun)) | |
| #else | |
| # define XCAST(fun) (void*) | |
| #endif | |
| static struct IDirectDraw_VTable dga_ddvt = { | |
| XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface, | |
| XCAST(AddRef)IDirectDraw2_AddRef, | |
| XCAST(Release)DGA_IDirectDraw2_Release, | |
| XCAST(Compact)IDirectDraw2_Compact, | |
| XCAST(CreateClipper)IDirectDraw2_CreateClipper, | |
| XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette, | |
| XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface, | |
| XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface, | |
| XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes, | |
| XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces, | |
| XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface, | |
| XCAST(GetCaps)DGA_IDirectDraw2_GetCaps, | |
| XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode, | |
| XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes, | |
| XCAST(GetGDISurface)15, | |
| XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency, | |
| XCAST(GetScanLine)17, | |
| XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus, | |
| XCAST(Initialize)19, | |
| XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode, | |
| XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel, | |
| DGA_IDirectDraw_SetDisplayMode, | |
| XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank, | |
| }; | |
| static struct IDirectDraw_VTable xlib_ddvt = { | |
| XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface, | |
| XCAST(AddRef)IDirectDraw2_AddRef, | |
| XCAST(Release)Xlib_IDirectDraw2_Release, | |
| XCAST(Compact)IDirectDraw2_Compact, | |
| XCAST(CreateClipper)IDirectDraw2_CreateClipper, | |
| XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette, | |
| XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface, | |
| XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface, | |
| XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes, | |
| XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces, | |
| XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface, | |
| XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps, | |
| XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode, | |
| XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes, | |
| XCAST(GetGDISurface)15, | |
| XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency, | |
| XCAST(GetScanLine)17, | |
| XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus, | |
| XCAST(Initialize)19, | |
| XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode, | |
| XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel, | |
| Xlib_IDirectDraw_SetDisplayMode, | |
| XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank, | |
| }; | |
| /***************************************************************************** | |
| * IDirectDraw2 | |
| * | |
| */ | |
| static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode( | |
| LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy | |
| ) { | |
| return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth); | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode( | |
| LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy | |
| ) { | |
| return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth); | |
| } | |
| static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem( | |
| LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free | |
| ) { | |
| TRACE(ddraw,"(%p)->(%p,%p,%p)\n", | |
| this,ddscaps,total,free | |
| ); | |
| if (total) *total = this->e.dga.fb_memsize * 1024; | |
| if (free) *free = this->e.dga.fb_memsize * 1024; | |
| return 0; | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem( | |
| LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free | |
| ) { | |
| TRACE(ddraw,"(%p)->(%p,%p,%p)\n", | |
| this,ddscaps,total,free | |
| ); | |
| if (total) *total = 2048 * 1024; | |
| if (free) *free = 2048 * 1024; | |
| return 0; | |
| } | |
| static IDirectDraw2_VTable dga_dd2vt = { | |
| DGA_IDirectDraw2_QueryInterface, | |
| IDirectDraw2_AddRef, | |
| DGA_IDirectDraw2_Release, | |
| IDirectDraw2_Compact, | |
| IDirectDraw2_CreateClipper, | |
| DGA_IDirectDraw2_CreatePalette, | |
| DGA_IDirectDraw2_CreateSurface, | |
| (void*)8, | |
| IDirectDraw2_EnumDisplayModes, | |
| IDirectDraw2_EnumSurfaces, | |
| IDirectDraw2_FlipToGDISurface, | |
| DGA_IDirectDraw2_GetCaps, | |
| DGA_IDirectDraw2_GetDisplayMode, | |
| IDirectDraw2_GetFourCCCodes, | |
| (void*)15, | |
| IDirectDraw2_GetMonitorFrequency, | |
| (void*)17, | |
| IDirectDraw2_GetVerticalBlankStatus, | |
| (void*)19, | |
| DGA_IDirectDraw2_RestoreDisplayMode, | |
| IDirectDraw2_SetCooperativeLevel, | |
| DGA_IDirectDraw2_SetDisplayMode, | |
| IDirectDraw2_WaitForVerticalBlank, | |
| DGA_IDirectDraw2_GetAvailableVidMem | |
| }; | |
| static struct IDirectDraw2_VTable xlib_dd2vt = { | |
| Xlib_IDirectDraw2_QueryInterface, | |
| IDirectDraw2_AddRef, | |
| Xlib_IDirectDraw2_Release, | |
| IDirectDraw2_Compact, | |
| IDirectDraw2_CreateClipper, | |
| Xlib_IDirectDraw2_CreatePalette, | |
| Xlib_IDirectDraw2_CreateSurface, | |
| (void*)8, | |
| IDirectDraw2_EnumDisplayModes, | |
| IDirectDraw2_EnumSurfaces, | |
| IDirectDraw2_FlipToGDISurface, | |
| Xlib_IDirectDraw2_GetCaps, | |
| Xlib_IDirectDraw2_GetDisplayMode, | |
| IDirectDraw2_GetFourCCCodes, | |
| (void*)15, | |
| IDirectDraw2_GetMonitorFrequency, | |
| (void*)17, | |
| IDirectDraw2_GetVerticalBlankStatus, | |
| (void*)19, | |
| Xlib_IDirectDraw2_RestoreDisplayMode, | |
| IDirectDraw2_SetCooperativeLevel, | |
| Xlib_IDirectDraw2_SetDisplayMode, | |
| IDirectDraw2_WaitForVerticalBlank, | |
| Xlib_IDirectDraw2_GetAvailableVidMem | |
| }; | |
| /****************************************************************************** | |
| * DirectDrawCreate | |
| */ | |
| LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam) | |
| { | |
| LRESULT ret; | |
| LPDIRECTDRAW ddraw = NULL; | |
| DWORD lastError; | |
| /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */ | |
| SetLastError( ERROR_SUCCESS ); | |
| ddraw = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset ); | |
| if( (!ddraw) && | |
| ( ( lastError = GetLastError() ) != ERROR_SUCCESS ) | |
| ) | |
| { | |
| ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError ); | |
| } | |
| if( ddraw ) | |
| { | |
| /* Perform any special direct draw functions */ | |
| if (msg==WM_PAINT) | |
| ddraw->e.xlib.paintable = 1; | |
| /* Now let the application deal with the rest of this */ | |
| if( ddraw->d.mainWindow ) | |
| { | |
| /* Don't think that we actually need to call this but... | |
| might as well be on the safe side of things... */ | |
| /* I changed hwnd to ddraw->d.mainWindow as I did not see why | |
| it should be the procedures of our fake window that gets called | |
| instead of those of the window provided by the application. | |
| And with this patch, mouse clicks work with Monkey Island III | |
| - Lionel */ | |
| ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam ); | |
| if( !ret ) | |
| { | |
| /* We didn't handle the message - give it to the application */ | |
| if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow)) { | |
| ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc, | |
| ddraw->d.mainWindow, msg, wParam, lParam ); | |
| } | |
| } | |
| } else { | |
| ret = DefWindowProc32A(hwnd, msg, wParam, lParam ); | |
| } | |
| } | |
| else | |
| { | |
| ret = DefWindowProc32A(hwnd,msg,wParam,lParam); | |
| } | |
| return ret; | |
| } | |
| HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) { | |
| #ifdef HAVE_LIBXXF86DGA | |
| int memsize,banksize,width,major,minor,flags,height; | |
| char *addr; | |
| int fd; | |
| /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */ | |
| if ((fd = open("/dev/mem", O_RDWR)) != -1) | |
| close(fd); | |
| if (fd == -1) { | |
| MSG("Must be able to access /dev/mem to use XF86DGA!\n"); | |
| MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP); | |
| return E_UNEXPECTED; | |
| } | |
| if (!DDRAW_DGA_Available()) { | |
| TRACE(ddraw,"No XF86DGA detected.\n"); | |
| return DDERR_GENERIC; | |
| } | |
| *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw)); | |
| (*lplpDD)->lpvtbl = &dga_ddvt; | |
| (*lplpDD)->ref = 1; | |
| TSXF86DGAQueryVersion(display,&major,&minor); | |
| TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor); | |
| TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags); | |
| if (!(flags & XF86DGADirectPresent)) | |
| MSG("direct video is NOT PRESENT.\n"); | |
| TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize); | |
| TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n", | |
| addr,width,banksize,memsize | |
| ); | |
| (*lplpDD)->e.dga.fb_width = width; | |
| (*lplpDD)->d.width = width; | |
| (*lplpDD)->e.dga.fb_addr = addr; | |
| (*lplpDD)->e.dga.fb_memsize = memsize; | |
| (*lplpDD)->e.dga.fb_banksize = banksize; | |
| TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height); | |
| TSXF86DGASetViewPort(display,DefaultScreen(display),0,0); | |
| (*lplpDD)->e.dga.fb_height = screenHeight; | |
| #ifdef DIABLO_HACK | |
| (*lplpDD)->e.dga.vpmask = 1; | |
| #else | |
| (*lplpDD)->e.dga.vpmask = 0; | |
| #endif | |
| /* just assume the default depth is the DGA depth too */ | |
| (*lplpDD)->d.depth = DefaultDepthOfScreen(screen); | |
| #ifdef RESTORE_SIGNALS | |
| SIGNAL_InitEmulator(); | |
| #endif | |
| return 0; | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return DDERR_INVALIDDIRECTDRAWGUID; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| } | |
| BOOL32 | |
| DDRAW_XSHM_Available() | |
| { | |
| #ifdef HAVE_LIBXXSHM | |
| if (TSXShmQueryExtension(display)) | |
| { | |
| int major, minor; | |
| Bool shpix; | |
| if (TSXShmQueryVersion(display, &major, &minor, &shpix)) | |
| return 1; | |
| else | |
| return 0; | |
| } | |
| else | |
| return 0; | |
| #else | |
| return 0; | |
| #endif | |
| } | |
| HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) { | |
| *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw)); | |
| (*lplpDD)->lpvtbl = &xlib_ddvt; | |
| (*lplpDD)->ref = 1; | |
| (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */ | |
| (*lplpDD)->d.depth = DefaultDepthOfScreen(screen); | |
| (*lplpDD)->d.height = screenHeight; | |
| (*lplpDD)->d.width = screenWidth; | |
| #ifdef HAVE_LIBXXSHM | |
| /* Test if XShm is available. | |
| As XShm is not ready yet for 'prime-time', it is disabled for now */ | |
| if (((*lplpDD)->e.xlib.xshm_active = 0 /* DDRAW_XSHM_Available() */)) | |
| TRACE(ddraw, "Using XShm extesion.\n"); | |
| #endif | |
| return 0; | |
| } | |
| HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) { | |
| char xclsid[50]; | |
| WNDCLASS32A wc; | |
| WND* pParentWindow; | |
| HRESULT ret; | |
| if (HIWORD(lpGUID)) | |
| WINE_StringFromCLSID(lpGUID,xclsid); | |
| else { | |
| sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID); | |
| lpGUID = NULL; | |
| } | |
| TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter); | |
| if (!lpGUID) { | |
| /* if they didn't request a particular interface, use the best | |
| * supported one */ | |
| if (DDRAW_DGA_Available()) | |
| lpGUID = &DGA_DirectDraw_GUID; | |
| else | |
| lpGUID = &XLIB_DirectDraw_GUID; | |
| } | |
| wc.style = CS_GLOBALCLASS; | |
| wc.lpfnWndProc = Xlib_DDWndProc; | |
| wc.cbClsExtra = 0; | |
| wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */ | |
| sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */ | |
| /* We can be a child of the desktop since we're really important */ | |
| pParentWindow = WIN_GetDesktop(); | |
| wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0; | |
| wc.hInstance = 0; | |
| wc.hIcon = 0; | |
| wc.hCursor = (HCURSOR32)IDC_ARROW32A; | |
| wc.hbrBackground= NULL_BRUSH; | |
| wc.lpszMenuName = 0; | |
| wc.lpszClassName= "WINE_DirectDraw"; | |
| RegisterClass32A(&wc); | |
| if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID))) | |
| ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter); | |
| else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID))) | |
| ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter); | |
| else | |
| goto err; | |
| (*lplpDD)->d.winclass = RegisterClass32A(&wc); | |
| return ret; | |
| err: | |
| fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter); | |
| return DDERR_INVALIDDIRECTDRAWGUID; | |
| } |