| /* DirectDraw using DGA or Xlib(XSHM) |
| * |
| * Copyright 1997,1998 Marcus Meissner |
| * Copyright 1998 Lionel Ulmer (most of Direct3D stuff) |
| */ |
| /* 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" |
| |
| #ifndef X_DISPLAY_MISSING |
| |
| #include "ts_xlib.h" |
| #include "ts_xutil.h" |
| |
| #ifdef HAVE_LIBXXSHM |
| #include <sys/types.h> |
| #include <sys/ipc.h> |
| #include <sys/shm.h> |
| #include "ts_xshm.h" |
| #endif /* defined(HAVE_LIBXXSHM) */ |
| |
| #ifdef HAVE_LIBXXF86DGA |
| #include "ts_xf86dga.h" |
| #endif /* defined(HAVE_LIBXXF86DGA) */ |
| |
| #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 |
| typedef int INT32; |
| #include "ts_xf86vmode.h" |
| #endif /* defined(HAVE_LIBXXF86VM) */ |
| |
| #include "x11drv.h" |
| |
| #include <unistd.h> |
| #include <assert.h> |
| #include <sys/signal.h> |
| #include <fcntl.h> |
| #include <string.h> |
| #include <stdlib.h> |
| |
| #include "winerror.h" |
| #include "gdi.h" |
| #include "heap.h" |
| #include "dc.h" |
| #include "win.h" |
| #include "miscemu.h" |
| #include "ddraw.h" |
| #include "d3d.h" |
| #include "debug.h" |
| #include "spy.h" |
| #include "message.h" |
| #include "options.h" |
| #include "monitor.h" |
| |
| /* This for all the enumeration and creation of D3D-related objects */ |
| #include "d3d_private.h" |
| |
| /* define this if you want to play Diablo using XF86DGA. (bug workaround) */ |
| #undef DIABLO_HACK |
| |
| /* Restore signal handlers overwritten by XF86DGA |
| */ |
| #define 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 IDirectDrawSurface4_VTable dga_dds4vt, xlib_dds4vt; |
| static struct IDirectDraw_VTable dga_ddvt, xlib_ddvt; |
| static struct IDirectDraw2_VTable dga_dd2vt, xlib_dd2vt; |
| static struct IDirectDraw4_VTable dga_dd4vt, xlib_dd4vt; |
| static struct IDirectDrawClipper_VTable ddclipvt; |
| static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt; |
| static struct IDirect3D_VTable d3dvt; |
| static struct IDirect3D2_VTable d3d2vt; |
| |
| #ifdef HAVE_LIBXXF86VM |
| static XF86VidModeModeInfo *orig_mode = NULL; |
| #endif |
| |
| #ifdef HAVE_LIBXXSHM |
| static int XShmErrorFlag = 0; |
| #endif |
| |
| BOOL |
| DDRAW_DGA_Available(void) |
| { |
| #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) */ |
| } |
| |
| /**********************************************************************/ |
| |
| typedef struct { |
| LPVOID lpCallback; |
| LPVOID lpContext; |
| } DirectDrawEnumerateProcData; |
| |
| /*********************************************************************** |
| * DirectDrawEnumerateExA (DDRAW.*) |
| */ |
| HRESULT WINAPI DirectDrawEnumerateExA( |
| LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags) |
| { |
| TRACE(ddraw, "(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags); |
| |
| if (TRACE_ON(ddraw)) { |
| DUMP(" Flags : "); |
| if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES) |
| DUMP("DDENUM_ATTACHEDSECONDARYDEVICES "); |
| if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES) |
| DUMP("DDENUM_DETACHEDSECONDARYDEVICES "); |
| if (dwFlags & DDENUM_NONDISPLAYDEVICES) |
| DUMP("DDENUM_NONDISPLAYDEVICES "); |
| DUMP("\n"); |
| } |
| |
| if (dwFlags & DDENUM_NONDISPLAYDEVICES) { |
| /* For the moment, Wine does not support any 3D only accelerators */ |
| return DD_OK; |
| } |
| |
| if (DDRAW_DGA_Available()) { |
| TRACE(ddraw, "Enumerating DGA interface\n"); |
| if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, NULL)) |
| return DD_OK; |
| } |
| |
| TRACE(ddraw, "Enumerating Xlib interface\n"); |
| if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, NULL)) |
| return DD_OK; |
| |
| TRACE(ddraw, "Enumerating Default interface\n"); |
| if (!lpCallback(NULL,"WINE (default)", "display", lpContext, NULL)) |
| return DD_OK; |
| |
| return DD_OK; |
| } |
| |
| /*********************************************************************** |
| * DirectDrawEnumerateExW (DDRAW.*) |
| */ |
| |
| static BOOL DirectDrawEnumerateExProcW( |
| GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, |
| LPVOID lpContext, HMONITOR hm) |
| { |
| DirectDrawEnumerateProcData *pEPD = |
| (DirectDrawEnumerateProcData *) lpContext; |
| LPWSTR lpDriverDescriptionW = |
| HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription); |
| LPWSTR lpDriverNameW = |
| HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName); |
| |
| BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)( |
| lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm); |
| |
| HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW); |
| HeapFree(GetProcessHeap(), 0, lpDriverNameW); |
| |
| return bResult; |
| } |
| |
| /**********************************************************************/ |
| |
| HRESULT WINAPI DirectDrawEnumerateExW( |
| LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags) |
| { |
| DirectDrawEnumerateProcData epd; |
| epd.lpCallback = lpCallback; |
| epd.lpContext = lpContext; |
| |
| return DirectDrawEnumerateExA(&DirectDrawEnumerateExProcW, |
| (LPVOID) &epd, 0); |
| } |
| |
| /*********************************************************************** |
| * DirectDrawEnumerateA (DDRAW.*) |
| */ |
| |
| static BOOL DirectDrawEnumerateProcA( |
| GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, |
| LPVOID lpContext, HMONITOR hm) |
| { |
| DirectDrawEnumerateProcData *pEPD = |
| (DirectDrawEnumerateProcData *) lpContext; |
| |
| return (*(LPDDENUMCALLBACKA *) pEPD->lpCallback)( |
| lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext); |
| } |
| |
| /**********************************************************************/ |
| |
| HRESULT WINAPI DirectDrawEnumerateA( |
| LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) |
| { |
| DirectDrawEnumerateProcData epd; |
| epd.lpCallback = lpCallback; |
| epd.lpContext = lpContext; |
| |
| return DirectDrawEnumerateExA(&DirectDrawEnumerateProcA, |
| (LPVOID) &epd, 0); |
| } |
| |
| /*********************************************************************** |
| * DirectDrawEnumerateW (DDRAW.*) |
| */ |
| |
| static BOOL DirectDrawEnumerateProcW( |
| GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName, |
| LPVOID lpContext, HMONITOR hm) |
| { |
| DirectDrawEnumerateProcData *pEPD = |
| (DirectDrawEnumerateProcData *) lpContext; |
| |
| return (*(LPDDENUMCALLBACKW *) pEPD->lpCallback)( |
| lpGUID, lpDriverDescription, lpDriverName, |
| pEPD->lpContext); |
| } |
| |
| /**********************************************************************/ |
| |
| HRESULT WINAPI DirectDrawEnumerateW( |
| LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) |
| { |
| DirectDrawEnumerateProcData epd; |
| epd.lpCallback = lpCallback; |
| epd.lpContext = lpContext; |
| |
| return DirectDrawEnumerateExW(&DirectDrawEnumerateProcW, |
| (LPVOID) &epd, 0); |
| } |
| |
| /*********************************************************************** |
| * DSoundHelp (DDRAW.?) |
| */ |
| |
| /* 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); |
| DUMP("\n"); |
| } |
| |
| 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_paletteformat(DWORD dwFlags) { |
| int i; |
| const struct { |
| DWORD mask; |
| char *name; |
| } flags[] = { |
| #define FE(x) { x, #x}, |
| FE(DDPCAPS_4BIT) |
| FE(DDPCAPS_8BITENTRIES) |
| FE(DDPCAPS_8BIT) |
| FE(DDPCAPS_INITIALIZE) |
| FE(DDPCAPS_PRIMARYSURFACE) |
| FE(DDPCAPS_PRIMARYSURFACELEFT) |
| FE(DDPCAPS_ALLOW256) |
| FE(DDPCAPS_VSYNC) |
| FE(DDPCAPS_1BIT) |
| FE(DDPCAPS_2BIT) |
| FE(DDPCAPS_ALPHA) |
| }; |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) |
| if (flags[i].mask & dwFlags) |
| DUMP("%s ",flags[i].name); |
| DUMP("\n"); |
| } |
| |
| static void _dump_pixelformat(LPDDPIXELFORMAT pf) { |
| DUMP("Size : %ld\n", pf->dwSize); |
| if (pf->dwFlags) |
| _dump_DDCOLORKEY(pf->dwFlags); |
| DUMP("dwFourCC : %ld\n", pf->dwFourCC); |
| DUMP("RGB bit count : %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); |
| } |
| |
| /****************************************************************************** |
| * IDirectDrawSurface methods |
| * |
| * 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 IDirectDrawSurface4_Lock( |
| LPDIRECTDRAWSURFACE4 this,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE 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; |
| TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n", |
| lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch); |
| |
| /* 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 DD_OK; |
| } |
| |
| static HRESULT WINAPI DGA_IDirectDrawSurface4_Unlock( |
| LPDIRECTDRAWSURFACE4 this,LPVOID surface |
| ) { |
| TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface); |
| return DD_OK; |
| } |
| |
| static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4 this) { |
| if (this->s.ddraw->d.pixel_convert != NULL) |
| this->s.ddraw->d.pixel_convert(this->s.surface_desc.y.lpSurface, |
| this->t.xlib.image->data, |
| this->s.surface_desc.dwWidth, |
| this->s.surface_desc.dwHeight, |
| this->s.surface_desc.lPitch, |
| this->s.palette); |
| |
| #ifdef HAVE_LIBXXSHM |
| if (this->s.ddraw->e.xlib.xshm_active) |
| TSXShmPutImage(display, |
| this->s.ddraw->d.drawable, |
| DefaultGCOfScreen(X11DRV_GetXScreen()), |
| 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->d.drawable, |
| DefaultGCOfScreen(X11DRV_GetXScreen()), |
| this->t.xlib.image, |
| 0, 0, 0, 0, |
| this->t.xlib.image->width, |
| this->t.xlib.image->height); |
| } |
| |
| static HRESULT WINAPI Xlib_IDirectDrawSurface4_Unlock( |
| LPDIRECTDRAWSURFACE4 this,LPVOID surface) |
| { |
| TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface); |
| |
| if (!this->s.ddraw->d.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)) { |
| Xlib_copy_surface_on_screen(this); |
| |
| if (this->s.palette && this->s.palette->cm) |
| TSXSetWindowColormap(display,this->s.ddraw->d.drawable,this->s.palette->cm); |
| } |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI DGA_IDirectDrawSurface4_Flip( |
| LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 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 DD_OK; |
| #else /* defined(HAVE_LIBXXF86DGA) */ |
| return E_UNEXPECTED; |
| #endif /* defined(HAVE_LIBXXF86DGA) */ |
| } |
| |
| static HRESULT WINAPI Xlib_IDirectDrawSurface4_Flip( |
| LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags |
| ) { |
| TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags); |
| if (!this->s.ddraw->d.paintable) |
| return DD_OK; |
| |
| if (!flipto) { |
| if (this->s.backbuffer) |
| flipto = this->s.backbuffer; |
| else |
| flipto = this; |
| } |
| |
| Xlib_copy_surface_on_screen(this); |
| |
| if (flipto->s.palette && flipto->s.palette->cm) { |
| TSXSetWindowColormap(display,this->s.ddraw->d.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 DD_OK; |
| } |
| |
| |
| /* The IDirectDrawSurface4::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_IDirectDrawSurface4_SetPalette( |
| LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal |
| ) { |
| int i; |
| TRACE(ddraw,"(%p)->(%p)\n",this,pal); |
| |
| if (pal == NULL) { |
| if( this->s.palette != NULL ) |
| this->s.palette->lpvtbl->fnRelease( this->s.palette ); |
| this->s.palette = pal; |
| |
| return DD_OK; |
| } |
| |
| if( !(pal->cm) && (this->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8)) |
| { |
| pal->cm = TSXCreateColormap(display,this->s.ddraw->d.drawable, |
| DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll); |
| |
| if (!Options.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); |
| } |
| TSXInstallColormap(display,pal->cm); |
| } |
| |
| /* 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->d.drawable,this->s.palette->cm); |
| } |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI DGA_IDirectDrawSurface4_SetPalette( |
| LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWPALETTE pal |
| ) { |
| TRACE(ddraw,"(%p)->(%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 DD_OK; |
| #else /* defined(HAVE_LIBXXF86DGA) */ |
| return E_UNEXPECTED; |
| #endif /* defined(HAVE_LIBXXF86DGA) */ |
| |
| |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_Blt( |
| LPDIRECTDRAWSURFACE4 this,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx |
| ) { |
| RECT 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); |
| 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 */ |
| |
| /* First, all the 'source-less' blits */ |
| 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 (dwFlags & DDBLT_DEPTHFILL) { |
| #ifdef HAVE_MESAGL |
| GLboolean ztest; |
| |
| /* Clears the screen */ |
| TRACE(ddraw, " Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth); |
| glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */ |
| glGetBooleanv(GL_DEPTH_TEST, &ztest); |
| glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */ |
| glClear(GL_DEPTH_BUFFER_BIT); |
| glDepthMask(ztest); |
| |
| dwFlags &= ~(DDBLT_DEPTHFILL); |
| #endif HAVE_MESAGL |
| } |
| |
| if (!src) { |
| if (dwFlags) { |
| TRACE(ddraw,"\t(src=NULL):Unsupported flags: "); _dump_DDBLT(dwFlags); |
| } |
| this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface); |
| return DD_OK; |
| } |
| |
| /* Now the 'with source' blits */ |
| |
| /* Standard 'full-surface' blit without special effects */ |
| 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 srcheight = xsrc.bottom - xsrc.top; |
| int srcwidth = xsrc.right - xsrc.left; |
| int dstheight = xdst.bottom - xdst.top; |
| int dstwidth = xdst.right - xdst.left; |
| int width = (xsrc.right - xsrc.left) * bpp; |
| int h; |
| |
| /* Sanity check for rectangle sizes */ |
| if ((srcheight != dstheight) || (srcwidth != dstwidth)) { |
| int x, y; |
| |
| /* I think we should do a Blit with 'stretching' here.... |
| Tomb Raider II uses this to display the background during the menu selection |
| when the screen resolution is != than 640x480 */ |
| TRACE(ddraw, "Blt with stretching\n"); |
| |
| /* This is a basic stretch implementation. It is painfully slow and quite ugly. */ |
| if (bpp == 1) { |
| /* In this case, we cannot do any anti-aliasing */ |
| if(dwFlags & DDBLT_KEYSRC) { |
| for (y = xdst.top; y < xdst.bottom; y++) { |
| for (x = xdst.left; x < xdst.right; x++) { |
| double sx, sy; |
| unsigned char tmp; |
| unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface; |
| unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface; |
| |
| sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left; |
| sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top; |
| |
| tmp = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)]; |
| |
| if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) || |
| (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue)) |
| dbuf[(y * ddesc.lPitch) + x] = tmp; |
| } |
| } |
| } else { |
| for (y = xdst.top; y < xdst.bottom; y++) { |
| for (x = xdst.left; x < xdst.right; x++) { |
| double sx, sy; |
| unsigned char *dbuf = (unsigned char *) ddesc.y.lpSurface; |
| unsigned char *sbuf = (unsigned char *) sdesc.y.lpSurface; |
| |
| sx = (((double) (x - xdst.left) / dstwidth) * srcwidth) + xsrc.left; |
| sy = (((double) (y - xdst.top) / dstheight) * srcheight) + xsrc.top; |
| |
| dbuf[(y * ddesc.lPitch) + x] = sbuf[(((int) sy) * sdesc.lPitch) + ((int) sx)]; |
| } |
| } |
| } |
| } else { |
| FIXME(ddraw, "Not done yet for depth != 8\n"); |
| } |
| } else { |
| /* Same size => fast blit */ |
| if (dwFlags & DDBLT_KEYSRC) { |
| switch (bpp) { |
| case 1: { |
| unsigned char tmp,*psrc,*pdst; |
| int h,i; |
| |
| for (h = 0; h < srcheight; h++) { |
| psrc=sdesc.y.lpSurface + |
| ((h + xsrc.top) * sdesc.lPitch) + xsrc.left; |
| pdst=ddesc.y.lpSurface + |
| ((h + xdst.top) * ddesc.lPitch) + xdst.left; |
| for(i=0;i<srcwidth;i++) { |
| tmp=*(psrc + i); |
| if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) || |
| (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue)) |
| *(pdst + i)=tmp; |
| } |
| } |
| dwFlags&=~(DDBLT_KEYSRC); |
| } break; |
| |
| case 2: { |
| unsigned short tmp,*psrc,*pdst; |
| int h,i; |
| |
| for (h = 0; h < srcheight; h++) { |
| psrc=sdesc.y.lpSurface + |
| ((h + xsrc.top) * sdesc.lPitch) + xsrc.left; |
| pdst=ddesc.y.lpSurface + |
| ((h + xdst.top) * ddesc.lPitch) + xdst.left; |
| for(i=0;i<srcwidth;i++) { |
| tmp=*(psrc + i); |
| if ((tmp < src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue) || |
| (tmp > src->s.surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue)) |
| *(pdst + i)=tmp; |
| } |
| } |
| dwFlags&=~(DDBLT_KEYSRC); |
| } break; |
| |
| default: |
| FIXME(ddraw, "Bitblt, KEYSRC: Not done yet for depth > 16\n"); |
| } |
| } else { |
| /* Non-stretching Blt without color keying */ |
| for (h = 0; h < srcheight; 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 DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_BltFast( |
| LPDIRECTDRAWSURFACE4 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans |
| ) { |
| int i,bpp,w,h; |
| DDSURFACEDESC ddesc,sdesc; |
| |
| if (1 || TRACE_ON(ddraw)) { |
| FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n", |
| this,dstx,dsty,src,rsrc,trans |
| ); |
| FIXME(ddraw," trans:"); |
| if (FIXME_ON(ddraw)) |
| _dump_DDBLTFAST(trans); |
| FIXME(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; |
| h=rsrc->bottom-rsrc->top; |
| if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty; |
| if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top; |
| if (h<0) h=0; |
| w=rsrc->right-rsrc->left; |
| if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx; |
| if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left; |
| if (w<0) w=0; |
| |
| for (i=0;i<h;i++) { |
| memcpy( ddesc.y.lpSurface+(dsty +i)*ddesc.lPitch+dstx*bpp, |
| sdesc.y.lpSurface+(rsrc->top+i)*sdesc.lPitch+rsrc->left*bpp, |
| w*bpp |
| ); |
| } |
| this->lpvtbl->fnUnlock(this,ddesc.y.lpSurface); |
| src ->lpvtbl->fnUnlock(src,sdesc.y.lpSurface); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_BltBatch( |
| LPDIRECTDRAWSURFACE4 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y |
| ) { |
| FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n", |
| this,ddbltbatch,x,y |
| ); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetCaps( |
| LPDIRECTDRAWSURFACE4 this,LPDDSCAPS caps |
| ) { |
| TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps); |
| caps->dwCaps = DDSCAPS_PALETTE; /* probably more */ |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetSurfaceDesc( |
| LPDIRECTDRAWSURFACE4 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)) { |
| DUMP(" flags: "); |
| _dump_DDSD(ddsd->dwFlags); |
| if (ddsd->dwFlags & DDSD_CAPS) { |
| DUMP(" caps: "); |
| _dump_DDSCAPS(ddsd->ddsCaps.dwCaps); |
| } |
| if (ddsd->dwFlags & DDSD_PIXELFORMAT) { |
| DUMP(" pixel format : \n"); |
| _dump_pixelformat(&(ddsd->ddpfPixelFormat)); |
| } |
| } |
| |
| return DD_OK; |
| } |
| |
| static ULONG WINAPI IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4 this) { |
| TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref ); |
| |
| return ++(this->ref); |
| } |
| |
| static ULONG WINAPI DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 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)); |
| } |
| |
| /* Free the backbuffer */ |
| if (this->s.backbuffer) |
| this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer); |
| |
| HeapFree(GetProcessHeap(),0,this); |
| return 0; |
| } |
| #endif /* defined(HAVE_LIBXXF86DGA) */ |
| return this->ref; |
| } |
| |
| static ULONG WINAPI Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4 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) { |
| if (this->s.ddraw->d.pixel_convert != NULL) { |
| /* In pixel conversion mode, there are two buffers to release... */ |
| HeapFree(GetProcessHeap(),0,this->s.surface_desc.y.lpSurface); |
| |
| #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->t.xlib.image->data); |
| this->t.xlib.image->data = NULL; |
| TSXDestroyImage(this->t.xlib.image); |
| #ifdef HAVE_LIBXXSHM |
| } |
| #endif |
| |
| } else { |
| 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 IDirectDrawSurface4_GetAttachedSurface( |
| LPDIRECTDRAWSURFACE4 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *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 DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_Initialize( |
| LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd |
| ) { |
| TRACE(ddraw,"(%p)->(%p, %p)\n",this,ddraw,lpdsfd); |
| |
| return DDERR_ALREADYINITIALIZED; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetPixelFormat( |
| LPDIRECTDRAWSURFACE4 this,LPDDPIXELFORMAT pf |
| ) { |
| TRACE(ddraw,"(%p)->(%p)\n",this,pf); |
| |
| *pf = this->s.surface_desc.ddpfPixelFormat; |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4 this,DWORD dwFlags) { |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetOverlayPosition( |
| LPDIRECTDRAWSURFACE4 this,LPLONG x1,LPLONG x2 |
| ) { |
| FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_SetClipper( |
| LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWCLIPPER clipper |
| ) { |
| FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_AddAttachedSurface( |
| LPDIRECTDRAWSURFACE4 this,LPDIRECTDRAWSURFACE4 surf |
| ) { |
| FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf); |
| |
| this->lpvtbl->fnAddRef(this); |
| |
| /* This hack will be enough for the moment */ |
| if (this->s.backbuffer == NULL) |
| this->s.backbuffer = surf; |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4 this,HDC* lphdc) { |
| FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc); |
| *lphdc = BeginPaint(this->s.ddraw->d.window,&this->s.ddraw->d.ps); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4 this,HDC hdc) { |
| DDSURFACEDESC desc; |
| DWORD x, y; |
| |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc); |
| EndPaint(this->s.ddraw->d.window,&this->s.ddraw->d.ps); |
| |
| /* Well, as what the application did paint in this DC is NOT saved in the surface, |
| I fill it with 'dummy' values to have something on the screen */ |
| this->lpvtbl->fnLock(this,NULL,&desc,0,0); |
| for (y = 0; y < desc.dwHeight; y++) { |
| for (x = 0; x < desc.dwWidth; x++) { |
| ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) this + x + y; |
| } |
| } |
| this->lpvtbl->fnUnlock(this,NULL); |
| |
| return DD_OK; |
| } |
| |
| |
| static HRESULT WINAPI IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4 this,REFIID refiid,LPVOID *obj) { |
| char xrefiid[50]; |
| |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); |
| TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj); |
| |
| /* All DirectDrawSurface versions (1, 2, 3 and 4) use |
| * the same interface. And IUnknown does that too of course. |
| */ |
| if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) || |
| !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); |
| |
| TRACE(ddraw, " Creating IDirectDrawSurface interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID))) |
| { |
| /* Texture interface */ |
| *obj = d3dtexture2_create(this); |
| this->lpvtbl->fnAddRef(this); |
| |
| TRACE(ddraw, " Creating IDirect3DTexture2 interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID))) |
| { |
| /* Texture interface */ |
| *obj = d3dtexture_create(this); |
| this->lpvtbl->fnAddRef(this); |
| |
| TRACE(ddraw, " Creating IDirect3DTexture interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| else if (is_OpenGL_dx3(refiid, (LPDIRECTDRAWSURFACE) this, (LPDIRECT3DDEVICE *) obj)) |
| { |
| /* It is the OpenGL Direct3D Device */ |
| this->lpvtbl->fnAddRef(this); |
| |
| TRACE(ddraw, " Creating IDirect3DDevice interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| |
| FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid); |
| return OLE_E_ENUM_NOMORE; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4 this) { |
| TRACE(ddraw,"(%p)->(), stub!\n",this); |
| return DD_OK; /* hmm */ |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) { |
| FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4 this) { |
| FIXME(ddraw,"(%p)->(),stub!\n",this); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_SetColorKey( |
| LPDIRECTDRAWSURFACE4 this, DWORD dwFlags, LPDDCOLORKEY ckey ) |
| { |
| TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",this,dwFlags,ckey); |
| |
| if( dwFlags & DDCKEY_SRCBLT ) |
| { |
| dwFlags &= ~DDCKEY_SRCBLT; |
| this->s.surface_desc.dwFlags |= DDSD_CKSRCBLT; |
| memcpy( &(this->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) ); |
| } |
| |
| if( dwFlags & DDCKEY_DESTBLT ) |
| { |
| dwFlags &= ~DDCKEY_DESTBLT; |
| this->s.surface_desc.dwFlags |= DDSD_CKDESTBLT; |
| memcpy( &(this->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) ); |
| } |
| |
| if( dwFlags & DDCKEY_SRCOVERLAY ) |
| { |
| dwFlags &= ~DDCKEY_SRCOVERLAY; |
| this->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY; |
| memcpy( &(this->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) ); |
| } |
| |
| if( dwFlags & DDCKEY_DESTOVERLAY ) |
| { |
| dwFlags &= ~DDCKEY_DESTOVERLAY; |
| this->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY; |
| memcpy( &(this->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) ); |
| } |
| |
| if( dwFlags ) |
| { |
| FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags ); |
| } |
| |
| return DD_OK; |
| |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_AddOverlayDirtyRect( |
| LPDIRECTDRAWSURFACE4 this, |
| LPRECT lpRect ) |
| { |
| FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpRect); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_DeleteAttachedSurface( |
| LPDIRECTDRAWSURFACE4 this, |
| DWORD dwFlags, |
| LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface ) |
| { |
| FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,lpDDSAttachedSurface); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_EnumOverlayZOrders( |
| LPDIRECTDRAWSURFACE4 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 IDirectDrawSurface4_GetClipper( |
| LPDIRECTDRAWSURFACE4 this, |
| LPDIRECTDRAWCLIPPER* lplpDDClipper ) |
| { |
| FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDClipper); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetColorKey( |
| LPDIRECTDRAWSURFACE4 this, |
| DWORD dwFlags, |
| LPDDCOLORKEY lpDDColorKey ) |
| { |
| TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", this, dwFlags, lpDDColorKey); |
| |
| if( dwFlags & DDCKEY_SRCBLT ) { |
| dwFlags &= ~DDCKEY_SRCBLT; |
| memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) ); |
| } |
| |
| if( dwFlags & DDCKEY_DESTBLT ) |
| { |
| dwFlags &= ~DDCKEY_DESTBLT; |
| memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) ); |
| } |
| |
| if( dwFlags & DDCKEY_SRCOVERLAY ) |
| { |
| dwFlags &= ~DDCKEY_SRCOVERLAY; |
| memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) ); |
| } |
| |
| if( dwFlags & DDCKEY_DESTOVERLAY ) |
| { |
| dwFlags &= ~DDCKEY_DESTOVERLAY; |
| memcpy( lpDDColorKey, &(this->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) ); |
| } |
| |
| if( dwFlags ) |
| { |
| FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags ); |
| } |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetFlipStatus( |
| LPDIRECTDRAWSURFACE4 this, |
| DWORD dwFlags ) |
| { |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetPalette( |
| LPDIRECTDRAWSURFACE4 this, |
| LPDIRECTDRAWPALETTE* lplpDDPalette ) |
| { |
| FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDDPalette); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_SetOverlayPosition( |
| LPDIRECTDRAWSURFACE4 this, |
| LONG lX, |
| LONG lY) |
| { |
| FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", this, lX, lY); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlay( |
| LPDIRECTDRAWSURFACE4 this, |
| LPRECT lpSrcRect, |
| LPDIRECTDRAWSURFACE4 lpDDDestSurface, |
| LPRECT 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 IDirectDrawSurface4_UpdateOverlayDisplay( |
| LPDIRECTDRAWSURFACE4 this, |
| DWORD dwFlags ) |
| { |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_UpdateOverlayZOrder( |
| LPDIRECTDRAWSURFACE4 this, |
| DWORD dwFlags, |
| LPDIRECTDRAWSURFACE4 lpDDSReference ) |
| { |
| FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags, lpDDSReference); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetDDInterface( |
| LPDIRECTDRAWSURFACE4 this, |
| LPVOID* lplpDD ) |
| { |
| FIXME(ddraw,"(%p)->(%p),stub!\n", this, lplpDD); |
| |
| /* Not sure about that... */ |
| *lplpDD = (void *) this->s.ddraw; |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_PageLock( |
| LPDIRECTDRAWSURFACE4 this, |
| DWORD dwFlags ) |
| { |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_PageUnlock( |
| LPDIRECTDRAWSURFACE4 this, |
| DWORD dwFlags ) |
| { |
| FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", this, dwFlags); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_SetSurfaceDesc( |
| LPDIRECTDRAWSURFACE4 this, |
| LPDDSURFACEDESC lpDDSD, |
| DWORD dwFlags ) |
| { |
| FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD, dwFlags); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4 this, |
| REFGUID guidTag, |
| LPVOID lpData, |
| DWORD cbSize, |
| DWORD dwFlags) { |
| FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag, lpData, cbSize, dwFlags); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4 this, |
| REFGUID guidTag, |
| LPVOID lpBuffer, |
| LPDWORD lpcbBufferSize) { |
| FIXME(ddraw, "(%p)->(%p,%p,%p)\n", this, guidTag, lpBuffer, lpcbBufferSize); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4 this, |
| REFGUID guidTag) { |
| FIXME(ddraw, "(%p)->(%p)\n", this, guidTag); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4 this, |
| LPDWORD lpValue) { |
| FIXME(ddraw, "(%p)->(%p)\n", this, lpValue); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 this) { |
| FIXME(ddraw, "(%p)\n", this); |
| |
| return DD_OK; |
| } |
| |
| static struct IDirectDrawSurface4_VTable dga_dds4vt = { |
| IDirectDrawSurface4_QueryInterface, |
| IDirectDrawSurface4_AddRef, |
| DGA_IDirectDrawSurface4_Release, |
| IDirectDrawSurface4_AddAttachedSurface, |
| IDirectDrawSurface4_AddOverlayDirtyRect, |
| IDirectDrawSurface4_Blt, |
| IDirectDrawSurface4_BltBatch, |
| IDirectDrawSurface4_BltFast, |
| IDirectDrawSurface4_DeleteAttachedSurface, |
| IDirectDrawSurface4_EnumAttachedSurfaces, |
| IDirectDrawSurface4_EnumOverlayZOrders, |
| DGA_IDirectDrawSurface4_Flip, |
| IDirectDrawSurface4_GetAttachedSurface, |
| IDirectDrawSurface4_GetBltStatus, |
| IDirectDrawSurface4_GetCaps, |
| IDirectDrawSurface4_GetClipper, |
| IDirectDrawSurface4_GetColorKey, |
| IDirectDrawSurface4_GetDC, |
| IDirectDrawSurface4_GetFlipStatus, |
| IDirectDrawSurface4_GetOverlayPosition, |
| IDirectDrawSurface4_GetPalette, |
| IDirectDrawSurface4_GetPixelFormat, |
| IDirectDrawSurface4_GetSurfaceDesc, |
| IDirectDrawSurface4_Initialize, |
| IDirectDrawSurface4_IsLost, |
| IDirectDrawSurface4_Lock, |
| IDirectDrawSurface4_ReleaseDC, |
| IDirectDrawSurface4_Restore, |
| IDirectDrawSurface4_SetClipper, |
| IDirectDrawSurface4_SetColorKey, |
| IDirectDrawSurface4_SetOverlayPosition, |
| DGA_IDirectDrawSurface4_SetPalette, |
| DGA_IDirectDrawSurface4_Unlock, |
| IDirectDrawSurface4_UpdateOverlay, |
| IDirectDrawSurface4_UpdateOverlayDisplay, |
| IDirectDrawSurface4_UpdateOverlayZOrder, |
| IDirectDrawSurface4_GetDDInterface, |
| IDirectDrawSurface4_PageLock, |
| IDirectDrawSurface4_PageUnlock, |
| IDirectDrawSurface4_SetSurfaceDesc, |
| IDirectDrawSurface4_SetPrivateData, |
| IDirectDrawSurface4_GetPrivateData, |
| IDirectDrawSurface4_FreePrivateData, |
| IDirectDrawSurface4_GetUniquenessValue, |
| IDirectDrawSurface4_ChangeUniquenessValue |
| }; |
| |
| static struct IDirectDrawSurface4_VTable xlib_dds4vt = { |
| IDirectDrawSurface4_QueryInterface, |
| IDirectDrawSurface4_AddRef, |
| Xlib_IDirectDrawSurface4_Release, |
| IDirectDrawSurface4_AddAttachedSurface, |
| IDirectDrawSurface4_AddOverlayDirtyRect, |
| IDirectDrawSurface4_Blt, |
| IDirectDrawSurface4_BltBatch, |
| IDirectDrawSurface4_BltFast, |
| IDirectDrawSurface4_DeleteAttachedSurface, |
| IDirectDrawSurface4_EnumAttachedSurfaces, |
| IDirectDrawSurface4_EnumOverlayZOrders, |
| Xlib_IDirectDrawSurface4_Flip, |
| IDirectDrawSurface4_GetAttachedSurface, |
| IDirectDrawSurface4_GetBltStatus, |
| IDirectDrawSurface4_GetCaps, |
| IDirectDrawSurface4_GetClipper, |
| IDirectDrawSurface4_GetColorKey, |
| IDirectDrawSurface4_GetDC, |
| IDirectDrawSurface4_GetFlipStatus, |
| IDirectDrawSurface4_GetOverlayPosition, |
| IDirectDrawSurface4_GetPalette, |
| IDirectDrawSurface4_GetPixelFormat, |
| IDirectDrawSurface4_GetSurfaceDesc, |
| IDirectDrawSurface4_Initialize, |
| IDirectDrawSurface4_IsLost, |
| IDirectDrawSurface4_Lock, |
| IDirectDrawSurface4_ReleaseDC, |
| IDirectDrawSurface4_Restore, |
| IDirectDrawSurface4_SetClipper, |
| IDirectDrawSurface4_SetColorKey, |
| IDirectDrawSurface4_SetOverlayPosition, |
| Xlib_IDirectDrawSurface4_SetPalette, |
| Xlib_IDirectDrawSurface4_Unlock, |
| IDirectDrawSurface4_UpdateOverlay, |
| IDirectDrawSurface4_UpdateOverlayDisplay, |
| IDirectDrawSurface4_UpdateOverlayZOrder, |
| IDirectDrawSurface4_GetDDInterface, |
| IDirectDrawSurface4_PageLock, |
| IDirectDrawSurface4_PageUnlock, |
| IDirectDrawSurface4_SetSurfaceDesc, |
| IDirectDrawSurface4_SetPrivateData, |
| IDirectDrawSurface4_GetPrivateData, |
| IDirectDrawSurface4_FreePrivateData, |
| IDirectDrawSurface4_GetUniquenessValue, |
| IDirectDrawSurface4_ChangeUniquenessValue |
| }; |
| |
| /****************************************************************************** |
| * 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 DD_OK; |
| } |
| |
| /****************************************************************************** |
| * IDirectDrawClipper |
| */ |
| static HRESULT WINAPI IDirectDrawClipper_SetHwnd( |
| LPDIRECTDRAWCLIPPER this,DWORD x,HWND hwnd |
| ) { |
| FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd); |
| return DD_OK; |
| } |
| |
| 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,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm |
| ) { |
| FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm); |
| if (hmm) *hmm=0; |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawClipper_SetClipList( |
| LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm |
| ) { |
| FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawClipper_QueryInterface( |
| LPDIRECTDRAWCLIPPER this, |
| REFIID riid, |
| LPVOID* ppvObj ) |
| { |
| FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,riid,ppvObj); |
| return OLE_E_ENUM_NOMORE; |
| } |
| |
| static ULONG WINAPI IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER this ) |
| { |
| TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref ); |
| return ++(this->ref); |
| } |
| |
| static HRESULT WINAPI IDirectDrawClipper_GetHWnd( |
| LPDIRECTDRAWCLIPPER this, |
| HWND* HWndPtr ) |
| { |
| FIXME(ddraw,"(%p)->(%p),stub!\n",this,HWndPtr); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawClipper_Initialize( |
| LPDIRECTDRAWCLIPPER this, |
| LPDIRECTDRAW lpDD, |
| DWORD dwFlags ) |
| { |
| FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD,dwFlags); |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDrawClipper_IsClipListChanged( |
| LPDIRECTDRAWCLIPPER this, |
| BOOL* lpbChanged ) |
| { |
| FIXME(ddraw,"(%p)->(%p),stub!\n",this,lpbChanged); |
| return DD_OK; |
| } |
| |
| static struct IDirectDrawClipper_VTable ddclipvt = { |
| IDirectDrawClipper_QueryInterface, |
| IDirectDrawClipper_AddRef, |
| IDirectDrawClipper_Release, |
| IDirectDrawClipper_GetClipList, |
| IDirectDrawClipper_GetHWnd, |
| IDirectDrawClipper_Initialize, |
| IDirectDrawClipper_IsClipListChanged, |
| 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 DD_OK; |
| } |
| |
| 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; |
| } |
| |
| /* Now, if we are in 'depth conversion mode', update the screen palette */ |
| if (this->ddraw->d.palette_convert != NULL) |
| this->ddraw->d.palette_convert(palent, this->screen_palents, start, count); |
| |
| return DD_OK; |
| } |
| |
| 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 DD_OK; |
| #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); |
| |
| TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| 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; |
| |
| TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) { |
| LPDIRECT3D2 d3d; |
| |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); |
| d3d->ref = 1; |
| d3d->ddraw = (LPDIRECTDRAW)this; |
| this->lpvtbl->fnAddRef(this); |
| d3d->lpvtbl = &d3d2vt; |
| *obj = d3d; |
| |
| TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| 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; |
| } |
| |
| static HRESULT WINAPI IDirect3D_EnumDevices(LPDIRECT3D this, |
| LPD3DENUMDEVICESCALLBACK cb, |
| LPVOID context) { |
| FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context); |
| |
| /* Call functions defined in d3ddevices.c */ |
| if (!d3d_OpenGL_dx3(cb, context)) |
| return DD_OK; |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirect3D_CreateLight(LPDIRECT3D this, |
| LPDIRECT3DLIGHT *lplight, |
| IUnknown *lpunk) |
| { |
| TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk); |
| |
| /* Call the creation function that is located in d3dlight.c */ |
| *lplight = d3dlight_create_dx3(this); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirect3D_CreateMaterial(LPDIRECT3D this, |
| LPDIRECT3DMATERIAL *lpmaterial, |
| IUnknown *lpunk) |
| { |
| TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk); |
| |
| /* Call the creation function that is located in d3dviewport.c */ |
| *lpmaterial = d3dmaterial_create(this); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirect3D_CreateViewport(LPDIRECT3D this, |
| LPDIRECT3DVIEWPORT *lpviewport, |
| IUnknown *lpunk) |
| { |
| TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk); |
| |
| /* Call the creation function that is located in d3dviewport.c */ |
| *lpviewport = d3dviewport_create(this); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirect3D_FindDevice(LPDIRECT3D this, |
| LPD3DFINDDEVICESEARCH lpfinddevsrc, |
| LPD3DFINDDEVICERESULT lpfinddevrst) |
| { |
| TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst); |
| |
| return DD_OK; |
| } |
| |
| static struct IDirect3D_VTable d3dvt = { |
| IDirect3D_QueryInterface, |
| IDirect3D_AddRef, |
| IDirect3D_Release, |
| IDirect3D_Initialize, |
| IDirect3D_EnumDevices, |
| IDirect3D_CreateLight, |
| IDirect3D_CreateMaterial, |
| IDirect3D_CreateViewport, |
| IDirect3D_FindDevice |
| }; |
| |
| /******************************************************************************* |
| * IDirect3D2 |
| */ |
| static HRESULT WINAPI IDirect3D2_QueryInterface( |
| LPDIRECT3D2 this,REFIID refiid,LPVOID *obj) { |
| /* For the moment, we use the same function as in IDirect3D */ |
| TRACE(ddraw, "Calling IDirect3D enumerating function.\n"); |
| |
| return IDirect3D_QueryInterface((LPDIRECT3D) this, refiid, obj); |
| } |
| |
| static ULONG WINAPI IDirect3D2_AddRef(LPDIRECT3D2 this) { |
| TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref ); |
| |
| return ++(this->ref); |
| } |
| |
| 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 |
| ) { |
| FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context); |
| |
| /* Call functions defined in d3ddevices.c */ |
| if (!d3d_OpenGL(cb, context)) |
| return DD_OK; |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirect3D2_CreateLight(LPDIRECT3D2 this, |
| LPDIRECT3DLIGHT *lplight, |
| IUnknown *lpunk) |
| { |
| TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lplight, lpunk); |
| |
| /* Call the creation function that is located in d3dlight.c */ |
| *lplight = d3dlight_create(this); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirect3D2_CreateMaterial(LPDIRECT3D2 this, |
| LPDIRECT3DMATERIAL2 *lpmaterial, |
| IUnknown *lpunk) |
| { |
| TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpmaterial, lpunk); |
| |
| /* Call the creation function that is located in d3dviewport.c */ |
| *lpmaterial = d3dmaterial2_create(this); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirect3D2_CreateViewport(LPDIRECT3D2 this, |
| LPDIRECT3DVIEWPORT2 *lpviewport, |
| IUnknown *lpunk) |
| { |
| TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpviewport, lpunk); |
| |
| /* Call the creation function that is located in d3dviewport.c */ |
| *lpviewport = d3dviewport2_create(this); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirect3D2_FindDevice(LPDIRECT3D2 this, |
| LPD3DFINDDEVICESEARCH lpfinddevsrc, |
| LPD3DFINDDEVICERESULT lpfinddevrst) |
| { |
| TRACE(ddraw, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc, lpfinddevrst); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirect3D2_CreateDevice(LPDIRECT3D2 this, |
| REFCLSID rguid, |
| LPDIRECTDRAWSURFACE surface, |
| LPDIRECT3DDEVICE2 *device) |
| { |
| char xbuf[50]; |
| |
| WINE_StringFromCLSID(rguid,xbuf); |
| FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",this,xbuf,surface,device); |
| |
| if (is_OpenGL(rguid, surface, device, this)) { |
| this->lpvtbl->fnAddRef(this); |
| return DD_OK; |
| } |
| |
| return DDERR_INVALIDPARAMS; |
| } |
| |
| static struct IDirect3D2_VTable d3d2vt = { |
| IDirect3D2_QueryInterface, |
| IDirect3D2_AddRef, |
| IDirect3D2_Release, |
| IDirect3D2_EnumDevices, |
| IDirect3D2_CreateLight, |
| IDirect3D2_CreateMaterial, |
| IDirect3D2_CreateViewport, |
| IDirect3D2_FindDevice, |
| IDirect3D2_CreateDevice |
| }; |
| |
| /******************************************************************************* |
| * 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 INT 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 */ |
| TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf); |
| |
| if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) { |
| /* This is a Z Buffer */ |
| TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth); |
| bpp = lpddsd->x.dwZBufferBitDepth / 8; |
| } else { |
| /* This is a standard image */ |
| if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) { |
| /* No pixel format => use DirectDraw's format */ |
| lpddsd->ddpfPixelFormat = this->d.directdraw_pixelformat; |
| lpddsd->dwFlags |= DDSD_PIXELFORMAT; |
| } else { |
| /* To check what the program wants */ |
| if (TRACE_ON(ddraw)) { |
| _dump_pixelformat(&(lpddsd->ddpfPixelFormat)); |
| } |
| } |
| |
| if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { |
| bpp = 1; |
| } else { |
| 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; |
| |
| return DD_OK; |
| } |
| |
| 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); |
| DUMP(" caps "); |
| _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps); |
| } |
| |
| *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface)); |
| this->lpvtbl->fnAddRef(this); |
| |
| (*lpdsf)->ref = 1; |
| (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds4vt; |
| (*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.directdraw_pixelformat.x.dwRGBBitCount/8); |
| (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height; |
| (*lpdsf)->s.surface_desc.lPitch = this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/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|DDSD_PIXELFORMAT; |
| (*lpdsf)->s.surface_desc.dwWidth = this->d.width; |
| (*lpdsf)->s.surface_desc.dwHeight = this->d.height; |
| TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d.width,this->d.height,lpddsd->lPitch); |
| /* We put our surface always in video memory */ |
| (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY; |
| (*lpdsf)->s.surface_desc.ddpfPixelFormat = this->d.directdraw_pixelformat; |
| (*lpdsf)->s.backbuffer = NULL; |
| |
| if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) { |
| LPDIRECTDRAWSURFACE4 back; |
| |
| if (lpddsd->dwBackBufferCount>1) |
| FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount); |
| |
| (*lpdsf)->s.backbuffer = back = |
| (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4)); |
| this->lpvtbl->fnAddRef(this); |
| back->ref = 1; |
| back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&dga_dds4vt; |
| 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.directdraw_pixelformat.x.dwRGBBitCount/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; |
| back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; |
| } |
| } else { |
| /* There is no DGA-specific code here... |
| Go to the common surface creation function */ |
| return common_off_screen_CreateSurface(this, lpddsd, *lpdsf); |
| } |
| |
| return DD_OK; |
| #else /* defined(HAVE_LIBXXF86DGA) */ |
| return E_UNEXPECTED; |
| #endif /* defined(HAVE_LIBXXF86DGA) */ |
| } |
| |
| #ifdef HAVE_LIBXXSHM |
| /* Error handlers for Image creation */ |
| static int XShmErrorHandler(Display *dpy, XErrorEvent *event) { |
| XShmErrorFlag = 1; |
| return 0; |
| } |
| |
| static XImage *create_xshmimage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) { |
| XImage *img; |
| int (*WineXHandler)(Display *, XErrorEvent *); |
| |
| img = TSXShmCreateImage(display, |
| DefaultVisualOfScreen(X11DRV_GetXScreen()), |
| this->d.pixmap_depth, |
| ZPixmap, |
| NULL, |
| &(lpdsf->t.xlib.shminfo), |
| lpdsf->s.surface_desc.dwWidth, |
| lpdsf->s.surface_desc.dwHeight); |
| |
| if (img == NULL) { |
| MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n"); |
| this->e.xlib.xshm_active = 0; |
| 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) { |
| MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n"); |
| this->e.xlib.xshm_active = 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) { |
| MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n"); |
| this->e.xlib.xshm_active = 0; |
| TSXDestroyImage(img); |
| shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0); |
| return NULL; |
| } |
| lpdsf->t.xlib.shminfo.readOnly = False; |
| |
| /* This is where things start to get trickier.... |
| First, we flush the current X connections to be sure to catch all non-XShm related |
| errors */ |
| TSXSync(display, False); |
| /* Then we enter in the non-thread safe part of the tests */ |
| EnterCriticalSection( &X11DRV_CritSection ); |
| |
| /* Reset the error flag, sets our new error handler and try to attach the surface */ |
| XShmErrorFlag = 0; |
| WineXHandler = XSetErrorHandler(XShmErrorHandler); |
| XShmAttach(display, &(lpdsf->t.xlib.shminfo)); |
| XSync(display, False); |
| |
| /* Check the error flag */ |
| if (XShmErrorFlag) { |
| /* An error occured */ |
| XFlush(display); |
| XShmErrorFlag = 0; |
| XDestroyImage(img); |
| shmdt(lpdsf->t.xlib.shminfo.shmaddr); |
| shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0); |
| XSetErrorHandler(WineXHandler); |
| |
| MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n"); |
| this->e.xlib.xshm_active = 0; |
| |
| /* Leave the critical section */ |
| LeaveCriticalSection( &X11DRV_CritSection ); |
| |
| return NULL; |
| } |
| |
| /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works, |
| but it may be a bit overkill.... */ |
| XSetErrorHandler(WineXHandler); |
| LeaveCriticalSection( &X11DRV_CritSection ); |
| |
| shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0); |
| |
| if (this->d.pixel_convert != NULL) { |
| lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, |
| lpdsf->s.surface_desc.dwWidth * |
| lpdsf->s.surface_desc.dwHeight * |
| (this->d.directdraw_pixelformat.x.dwRGBBitCount)); |
| } else { |
| lpdsf->s.surface_desc.y.lpSurface = img->data; |
| } |
| |
| return img; |
| } |
| #endif /* HAVE_LIBXXSHM */ |
| |
| static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) { |
| XImage *img = NULL; |
| void *img_data; |
| |
| #ifdef HAVE_LIBXXSHM |
| if (this->e.xlib.xshm_active) { |
| img = create_xshmimage(this, lpdsf); |
| } |
| |
| if (img == NULL) { |
| #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.directdraw_pixelformat.x.dwRGBBitCount / 8)); |
| |
| if (this->d.pixel_convert != NULL) { |
| img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, |
| lpdsf->s.surface_desc.dwWidth * |
| lpdsf->s.surface_desc.dwHeight * |
| (this->d.screen_pixelformat.x.dwRGBBitCount / 8)); |
| } else { |
| img_data = lpdsf->s.surface_desc.y.lpSurface; |
| } |
| |
| /* In this case, create an XImage */ |
| img = |
| TSXCreateImage(display, |
| DefaultVisualOfScreen(X11DRV_GetXScreen()), |
| this->d.pixmap_depth, |
| ZPixmap, |
| 0, |
| img_data, |
| lpdsf->s.surface_desc.dwWidth, |
| lpdsf->s.surface_desc.dwHeight, |
| 32, |
| lpdsf->s.surface_desc.dwWidth * (this->d.screen_pixelformat.x.dwRGBBitCount / 8) |
| ); |
| |
| #ifdef HAVE_LIBXXSHM |
| } |
| #endif |
| if (this->d.pixel_convert != NULL) { |
| lpdsf->s.surface_desc.lPitch = (this->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth; |
| } else { |
| 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)) { |
| DUMP(" w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight); |
| _dump_DDSD(lpddsd->dwFlags); |
| DUMP(" caps "); |
| _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps); |
| } |
| |
| *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_dds4vt; |
| (*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, (LPDIRECTDRAWSURFACE4) *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|DDSD_PIXELFORMAT; |
| (*lpdsf)->s.surface_desc.dwWidth = this->d.width; |
| (*lpdsf)->s.surface_desc.dwHeight = this->d.height; |
| (*lpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY; |
| (*lpdsf)->s.surface_desc.ddpfPixelFormat = this->d.directdraw_pixelformat; |
| (*lpdsf)->s.backbuffer = NULL; |
| |
| /* Check for backbuffers */ |
| if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) { |
| LPDIRECTDRAWSURFACE4 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 = |
| (LPDIRECTDRAWSURFACE4)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4)); |
| |
| TRACE(ddraw,"allocated back-buffer (%p)\n", back); |
| |
| this->lpvtbl->fnAddRef(this); |
| back->s.ddraw = this; |
| |
| back->ref = 1; |
| back->lpvtbl = (LPDIRECTDRAWSURFACE4_VTABLE)&xlib_dds4vt; |
| /* 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; |
| back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; |
| } |
| } else { |
| /* There is no Xlib-specific code here... |
| Go to the common surface creation function */ |
| return common_off_screen_CreateSurface(this, lpddsd, *lpdsf); |
| } |
| |
| return DD_OK; |
| } |
| |
| 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 DD_OK; |
| } |
| |
| /* |
| * 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,HWND 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; |
| |
| /* This will be overwritten in the case of Full Screen mode. |
| Windowed games could work with that :-) */ |
| if (hwnd) |
| this->d.drawable = X11DRV_WND_GetXWindow(WIN_FindWndPtr(hwnd)); |
| |
| return DD_OK; |
| } |
| |
| /* 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) { |
| RECT rect; |
| |
| /* Do not destroy the application supplied cooperative window */ |
| if (this->d.window && this->d.window != this->d.mainWindow) { |
| DestroyWindow(this->d.window); |
| this->d.window = 0; |
| } |
| /* Sanity check cooperative window before assigning it to drawing. */ |
| if ( IsWindow(this->d.mainWindow) && |
| IsWindowVisible(this->d.mainWindow) |
| ) { |
| GetWindowRect(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 = CreateWindowExA( |
| 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*/ |
| SetWindowLongA(this->d.window,ddrawXlibThisOffset,(LONG)this); |
| ShowWindow(this->d.window,TRUE); |
| UpdateWindow(this->d.window); |
| } |
| SetFocus(this->d.window); |
| } |
| |
| static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) { |
| XVisualInfo *vi; |
| XPixmapFormatValues *pf; |
| XVisualInfo vt; |
| int nvisuals, npixmap, i; |
| int match = 0; |
| |
| vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals); |
| pf = XListPixmapFormats(display, &npixmap); |
| |
| for (i = 0; i < npixmap; i++) { |
| if (pf[i].bits_per_pixel == depth) { |
| int j; |
| |
| for (j = 0; j < nvisuals; j++) { |
| if (vi[j].depth == pf[i].depth) { |
| pixelformat->dwSize = sizeof(*pixelformat); |
| if (depth == 8) { |
| pixelformat->dwFlags = DDPF_PALETTEINDEXED8; |
| pixelformat->y.dwRBitMask = 0; |
| pixelformat->z.dwGBitMask = 0; |
| pixelformat->xx.dwBBitMask = 0; |
| } else { |
| pixelformat->dwFlags = DDPF_RGB; |
| pixelformat->y.dwRBitMask = vi[j].red_mask; |
| pixelformat->z.dwGBitMask = vi[j].green_mask; |
| pixelformat->xx.dwBBitMask = vi[j].blue_mask; |
| } |
| pixelformat->dwFourCC = 0; |
| pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel; |
| pixelformat->xy.dwRGBAlphaBitMask= 0; |
| |
| *screen_pixelformat = *pixelformat; |
| |
| if (pix_depth != NULL) |
| *pix_depth = vi[j].depth; |
| |
| match = 1; |
| |
| break; |
| } |
| } |
| |
| if (j == nvisuals) |
| ERR(ddraw, "No visual corresponding to pixmap format !\n"); |
| } |
| } |
| |
| if ((match == 0) && (depth == 8)) { |
| pixelformat->dwSize = sizeof(*pixelformat); |
| pixelformat->dwFlags = DDPF_PALETTEINDEXED8; |
| pixelformat->dwFourCC = 0; |
| pixelformat->x.dwRGBBitCount = 8; |
| pixelformat->y.dwRBitMask = 0; |
| pixelformat->z.dwGBitMask = 0; |
| pixelformat->xx.dwBBitMask = 0; |
| pixelformat->xy.dwRGBAlphaBitMask= 0; |
| |
| /* In that case, find a visual to emulate the 8 bpp format */ |
| for (i = 0; i < npixmap; i++) { |
| if (pf[i].bits_per_pixel >= depth) { |
| int j; |
| |
| for (j = 0; j < nvisuals; j++) { |
| if (vi[j].depth == pf[i].depth) { |
| screen_pixelformat->dwSize = sizeof(*screen_pixelformat); |
| screen_pixelformat->dwFlags = DDPF_RGB; |
| screen_pixelformat->dwFourCC = 0; |
| screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel; |
| screen_pixelformat->y.dwRBitMask = vi[j].red_mask; |
| screen_pixelformat->z.dwGBitMask = vi[j].green_mask; |
| screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask; |
| screen_pixelformat->xy.dwRGBAlphaBitMask= 0; |
| |
| if (pix_depth != NULL) |
| *pix_depth = vi[j].depth; |
| |
| match = 2; |
| |
| break; |
| } |
| } |
| |
| if (j == nvisuals) |
| ERR(ddraw, "No visual corresponding to pixmap format !\n"); |
| } |
| } |
| } |
| |
| TSXFree(vi); |
| TSXFree(pf); |
| |
| return match; |
| } |
| |
| static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode( |
| LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth |
| ) { |
| #ifdef HAVE_LIBXXF86DGA |
| int i,mode_count; |
| |
| TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth); |
| |
| /* We hope getting the asked for depth */ |
| if (_common_depth_to_pixelformat(depth, &(this->d.directdraw_pixelformat), &(this->d.screen_pixelformat), NULL) != 1) { |
| /* I.e. no visual found or emulated */ |
| 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; |
| |
| /* 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; |
| XF86VidModeModeLine mod_tmp; |
| /* int dotclock_tmp; */ |
| |
| /* save original video mode and set fullscreen if available*/ |
| orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo)); |
| TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp); |
| orig_mode->hdisplay = mod_tmp.hdisplay; |
| orig_mode->hsyncstart = mod_tmp.hsyncstart; |
| orig_mode->hsyncend = mod_tmp.hsyncend; |
| orig_mode->htotal = mod_tmp.htotal; |
| orig_mode->vdisplay = mod_tmp.vdisplay; |
| orig_mode->vsyncstart = mod_tmp.vsyncstart; |
| orig_mode->vsyncend = mod_tmp.vsyncend; |
| orig_mode->vtotal = mod_tmp.vtotal; |
| orig_mode->flags = mod_tmp.flags; |
| orig_mode->private = mod_tmp.private; |
| |
| 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); |
| } |
| for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private); |
| TSXFree(all_modes); |
| |
| if (!vidmode) |
| WARN(ddraw, "Fullscreen mode not available!\n"); |
| |
| if (vidmode) |
| { |
| TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay); |
| TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode); |
| #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */ |
| TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0); |
| #endif |
| } |
| } |
| #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); |
| #else |
| TSXF86DGASetViewPort(display,DefaultScreen(display),0,0); |
| #endif |
| |
| #ifdef RESTORE_SIGNALS |
| SIGNAL_InitHandlers(); |
| #endif |
| return DD_OK; |
| #else /* defined(HAVE_LIBXXF86DGA) */ |
| return E_UNEXPECTED; |
| #endif /* defined(HAVE_LIBXXF86DGA) */ |
| } |
| |
| /* ************************************* |
| 16 / 15 bpp to palettized 8 bpp |
| ************************************* */ |
| static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, LPDIRECTDRAWPALETTE palette) { |
| unsigned char *c_src = (unsigned char *) src; |
| unsigned short *c_dst = (unsigned short *) dst; |
| int x, y; |
| |
| if (palette != NULL) { |
| unsigned short *pal = (unsigned short *) palette->screen_palents; |
| |
| for (y = 0; y < height; y++) { |
| for (x = 0; x < width; x++) { |
| c_dst[x + y * width] = pal[c_src[x + y * pitch]]; |
| } |
| } |
| } else { |
| WARN(ddraw, "No palette set...\n"); |
| memset(dst, 0, width * height * 2); |
| } |
| } |
| static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) { |
| int i; |
| unsigned short *pal = (unsigned short *) screen_palette; |
| |
| for (i = 0; i < count; i++) |
| pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) | |
| ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) | |
| ((((unsigned short) palent[i].peGreen) & 0xFC) << 3)); |
| } |
| static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) { |
| int i; |
| unsigned short *pal = (unsigned short *) screen_palette; |
| |
| for (i = 0; i < count; i++) |
| pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) | |
| ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) | |
| ((((unsigned short) palent[i].peGreen) & 0xF8) << 2)); |
| } |
| |
| /* ************************************* |
| 24 / 32 bpp to palettized 8 bpp |
| ************************************* */ |
| static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, LPDIRECTDRAWPALETTE palette) { |
| unsigned char *c_src = (unsigned char *) src; |
| unsigned int *c_dst = (unsigned int *) dst; |
| int x, y; |
| |
| if (palette != NULL) { |
| unsigned int *pal = (unsigned int *) palette->screen_palents; |
| |
| for (y = 0; y < height; y++) { |
| for (x = 0; x < width; x++) { |
| c_dst[x + y * width] = pal[c_src[x + y * pitch]]; |
| } |
| } |
| } else { |
| WARN(ddraw, "No palette set...\n"); |
| memset(dst, 0, width * height * 4); |
| } |
| } |
| static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) { |
| int i; |
| unsigned int *pal = (unsigned int *) screen_palette; |
| |
| for (i = 0; i < count; i++) |
| pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) | |
| (((unsigned int) palent[i].peGreen) << 8) | |
| ((unsigned int) palent[i].peBlue)); |
| } |
| |
| static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode( |
| LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth |
| ) { |
| char buf[200]; |
| |
| TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n", |
| this, width, height, depth); |
| |
| switch (_common_depth_to_pixelformat(depth, |
| &(this->d.directdraw_pixelformat), |
| &(this->d.screen_pixelformat), |
| &(this->d.pixmap_depth))) { |
| case 0: |
| sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth); |
| MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP); |
| return DDERR_UNSUPPORTEDMODE; |
| |
| case 1: |
| /* No convertion */ |
| this->d.pixel_convert = NULL; |
| this->d.palette_convert = NULL; |
| break; |
| |
| case 2: { |
| int found = 0; |
| |
| WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth); |
| |
| /* Set the depth convertion routines */ |
| switch (this->d.screen_pixelformat.x.dwRGBBitCount) { |
| case 16: |
| if ((this->d.screen_pixelformat.y.dwRBitMask == 0xF800) && |
| (this->d.screen_pixelformat.z.dwGBitMask == 0x07E0) && |
| (this->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) { |
| /* 16 bpp */ |
| found = 1; |
| |
| this->d.pixel_convert = pixel_convert_16_to_8; |
| this->d.palette_convert = palette_convert_16_to_8; |
| } else if ((this->d.screen_pixelformat.y.dwRBitMask == 0x7C00) && |
| (this->d.screen_pixelformat.z.dwGBitMask == 0x03E0) && |
| (this->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) { |
| /* 15 bpp */ |
| found = 1; |
| |
| this->d.pixel_convert = pixel_convert_16_to_8; |
| this->d.palette_convert = palette_convert_15_to_8; |
| } |
| break; |
| |
| case 24: |
| /* Not handled yet :/ */ |
| found = 0; |
| break; |
| |
| case 32: |
| if ((this->d.screen_pixelformat.y.dwRBitMask == 0xFF0000) && |
| (this->d.screen_pixelformat.z.dwGBitMask == 0x00FF00) && |
| (this->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) { |
| /* 24 bpp */ |
| found = 1; |
| |
| this->d.pixel_convert = pixel_convert_32_to_8; |
| this->d.palette_convert = palette_convert_24_to_8; |
| } |
| break; |
| } |
| |
| if (!found) { |
| sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth); |
| MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP); |
| return DDERR_UNSUPPORTEDMODE; |
| } |
| } break; |
| } |
| |
| this->d.width = width; |
| this->d.height = height; |
| |
| _common_IDirectDraw_SetDisplayMode(this); |
| |
| this->d.paintable = 1; |
| this->d.drawable = ((X11DRV_WND_DATA *) WIN_FindWndPtr(this->d.window)->pDriverData)->window; |
| /* We don't have a context for this window. Host off the desktop */ |
| if( !this->d.drawable ) |
| this->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window; |
| return DD_OK; |
| } |
| |
| 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 DD_OK; |
| #else /* defined(HAVE_LIBXXF86DGA) */ |
| return E_UNEXPECTED; |
| #endif /* defined(HAVE_LIBXXF86DGA) */ |
| } |
| |
| static void fill_caps(LPDDCAPS caps) { |
| /* This function tries to fill the capabilities of Wine's DDraw implementation. |
| Need to be fixed, though.. */ |
| if (caps == NULL) |
| return; |
| |
| caps->dwSize = sizeof(*caps); |
| caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | |
| DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE; |
| caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES; |
| caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */ |
| caps->dwFXCaps = 0; |
| caps->dwFXAlphaCaps = 0; |
| caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256; |
| caps->dwSVCaps = 0; |
| caps->dwZBufferBitDepths = DDBD_16; |
| /* I put here 8 Mo so that D3D applications will believe they have enough memory |
| to put textures in video memory. |
| BTW, is this only frame buffer memory or also texture memory (for Voodoo boards |
| for example) ? */ |
| caps->dwVidMemTotal = 8192 * 1024; |
| caps->dwVidMemFree = 8192 * 1024; |
| /* These are all the supported capabilities of the surfaces */ |
| caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP | |
| DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN | |
| DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | |
| DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE; |
| #ifdef HAVE_MESAGL |
| caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS; |
| caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE; |
| caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER; |
| #endif |
| } |
| |
| static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps( |
| LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2 |
| ) { |
| TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2); |
| |
| /* Put the same caps for the two capabilities */ |
| fill_caps(caps1); |
| fill_caps(caps2); |
| |
| return DD_OK; |
| } |
| |
| 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 DD_OK; |
| } |
| |
| static HRESULT WINAPI common_IDirectDraw2_CreatePalette( |
| LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk,int *psize |
| ) { |
| int size = 0; |
| |
| if (TRACE_ON(ddraw)) |
| _dump_paletteformat(dwFlags); |
| |
| *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 (dwFlags & DDPCAPS_1BIT) |
| size = 2; |
| else if (dwFlags & DDPCAPS_2BIT) |
| size = 4; |
| else if (dwFlags & DDPCAPS_4BIT) |
| size = 16; |
| else if (dwFlags & DDPCAPS_8BIT) |
| size = 256; |
| else |
| ERR(ddraw, "unhandled palette format\n"); |
| *psize = size; |
| |
| if (palent) |
| { |
| /* Now, if we are in 'depth conversion mode', create the screen palette */ |
| if (this->d.palette_convert != NULL) |
| this->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size); |
| |
| memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY)); |
| } else if (this->d.palette_convert != NULL) { |
| /* In that case, put all 0xFF */ |
| memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int)); |
| } |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette( |
| LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk |
| ) { |
| HRESULT res; |
| int xsize = 0,i; |
| |
| TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk); |
| res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize); |
| if (res != 0) return res; |
| (*lpddpal)->lpvtbl = &dga_ddpalvt; |
| if (this->d.directdraw_pixelformat.x.dwRGBBitCount<=8) { |
| (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll); |
| } else { |
| FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n"); |
| (*lpddpal)->cm = 0; |
| } |
| if (((*lpddpal)->cm)&&xsize) { |
| for (i=0;i<xsize;i++) { |
| XColor xc; |
| |
| xc.red = (*lpddpal)->palents[i].peRed<<8; |
| xc.blue = (*lpddpal)->palents[i].peBlue<<8; |
| xc.green = (*lpddpal)->palents[i].peGreen<<8; |
| xc.flags = DoRed|DoBlue|DoGreen; |
| xc.pixel = i; |
| TSXStoreColor(display,(*lpddpal)->cm,&xc); |
| } |
| } |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette( |
| LPDIRECTDRAW2 this,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk |
| ) { |
| int xsize; |
| HRESULT res; |
| |
| TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags,palent,lpddpal,lpunk); |
| res = common_IDirectDraw2_CreatePalette(this,dwFlags,palent,lpddpal,lpunk,&xsize); |
| if (res != 0) return res; |
| (*lpddpal)->lpvtbl = &xlib_ddpalvt; |
| return DD_OK; |
| } |
| |
| 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_InitHandlers(); |
| #endif |
| return DD_OK; |
| #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 DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank( |
| LPDIRECTDRAW2 this,DWORD x,HANDLE h |
| ) { |
| TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h); |
| return DD_OK; |
| } |
| |
| 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); |
| if (this->d.window && (this->d.mainWindow != this->d.window)) |
| DestroyWindow(this->d.window); |
| #ifdef HAVE_LIBXXF86VM |
| if (orig_mode) { |
| TSXF86VidModeSwitchToMode( |
| display, |
| DefaultScreen(display), |
| orig_mode); |
| if (orig_mode->privsize) |
| TSXFree(orig_mode->private); |
| free(orig_mode); |
| orig_mode = NULL; |
| } |
| #endif |
| |
| #ifdef RESTORE_SIGNALS |
| SIGNAL_InitHandlers(); |
| #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)) { |
| if (this->d.window && (this->d.mainWindow != this->d.window)) |
| DestroyWindow(this->d.window); |
| 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); |
| |
| TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) { |
| this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt; |
| this->lpvtbl->fnAddRef(this); |
| *obj = this; |
| |
| TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) { |
| this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt; |
| this->lpvtbl->fnAddRef(this); |
| *obj = this; |
| |
| TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) { |
| this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd4vt; |
| this->lpvtbl->fnAddRef(this); |
| *obj = this; |
| |
| TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| 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; |
| |
| TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) { |
| LPDIRECT3D2 d3d; |
| |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); |
| d3d->ref = 1; |
| d3d->ddraw = (LPDIRECTDRAW)this; |
| this->lpvtbl->fnAddRef(this); |
| d3d->lpvtbl = &d3d2vt; |
| *obj = d3d; |
| |
| TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| 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); |
| |
| TRACE(ddraw, " Creating IUnknown interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) { |
| this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt; |
| this->lpvtbl->fnAddRef(this); |
| *obj = this; |
| |
| TRACE(ddraw, " Creating IDirectDraw interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) { |
| this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt; |
| this->lpvtbl->fnAddRef(this); |
| *obj = this; |
| |
| TRACE(ddraw, " Creating IDirectDraw2 interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) { |
| this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd4vt; |
| this->lpvtbl->fnAddRef(this); |
| *obj = this; |
| |
| TRACE(ddraw, " Creating IDirectDraw4 interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| 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; |
| |
| TRACE(ddraw, " Creating IDirect3D interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| 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; |
| |
| TRACE(ddraw, " Creating IDirect3D2 interface (%p)\n", *obj); |
| |
| return S_OK; |
| } |
| WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid); |
| return OLE_E_ENUM_NOMORE; |
| } |
| |
| static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus( |
| LPDIRECTDRAW2 this,BOOL *status |
| ) { |
| TRACE(ddraw,"(%p)->(%p)\n",this,status); |
| *status = TRUE; |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI DGA_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 = 0xF800; |
| ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0; |
| ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F; |
| break; |
| case 24: |
| ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000; |
| ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00; |
| ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF; |
| break; |
| case 32: |
| ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000; |
| ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00; |
| ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF; |
| break; |
| } |
| } |
| |
| ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor); |
| ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); |
| TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]); |
| if (!modescb(&ddsfd,context)) return DD_OK; |
| |
| 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 DD_OK; |
| } |
| |
| 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 DD_OK; |
| } |
| } |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI Xlib_IDirectDraw2_EnumDisplayModes( |
| LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb |
| ) { |
| XVisualInfo *vi; |
| XPixmapFormatValues *pf; |
| XVisualInfo vt; |
| int nvisuals, npixmap, i; |
| int send_mode; |
| int has_8bpp = 0; |
| DDSURFACEDESC ddsfd; |
| static struct { |
| int w,h; |
| } modes[] = { /* some of the usual modes */ |
| {512,384}, |
| {640,400}, |
| {640,480}, |
| {800,600}, |
| {1024,768}, |
| {1280,1024} |
| }; |
| DWORD maxWidth, maxHeight; |
| |
| 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_PIXELFORMAT|DDSD_CAPS; |
| if (dwFlags & DDEDM_REFRESHRATES) { |
| ddsfd.dwFlags |= DDSD_REFRESHRATE; |
| ddsfd.x.dwRefreshRate = 60; |
| } |
| maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor); |
| maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); |
| |
| vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals); |
| pf = XListPixmapFormats(display, &npixmap); |
| |
| i = 0; |
| send_mode = 0; |
| while (i < npixmap) { |
| if ((has_8bpp == 0) && (pf[i].depth == 8)) { |
| /* Special case of a 8bpp depth */ |
| has_8bpp = 1; |
| send_mode = 1; |
| |
| ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE; |
| ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat); |
| ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8; |
| ddsfd.ddpfPixelFormat.dwFourCC = 0; |
| ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8; |
| ddsfd.ddpfPixelFormat.y.dwRBitMask = 0; |
| ddsfd.ddpfPixelFormat.z.dwGBitMask = 0; |
| ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0; |
| ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0; |
| } else if (pf[i].depth > 8) { |
| int j; |
| |
| /* All the 'true color' depths (15, 16 and 24) |
| First, find the corresponding visual to extract the bit masks */ |
| for (j = 0; j < nvisuals; j++) { |
| if (vi[j].depth == pf[i].depth) { |
| ddsfd.ddsCaps.dwCaps = 0; |
| ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat); |
| ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB; |
| ddsfd.ddpfPixelFormat.dwFourCC = 0; |
| ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel; |
| ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask; |
| ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask; |
| ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask; |
| ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0; |
| |
| send_mode = 1; |
| break; |
| } |
| } |
| |
| if (j == nvisuals) |
| ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n"); |
| } else { |
| send_mode = 0; |
| } |
| |
| if (send_mode) { |
| int mode; |
| |
| if (TRACE_ON(ddraw)) { |
| TRACE(ddraw, "Enumerating with pixel format : \n"); |
| _dump_pixelformat(&(ddsfd.ddpfPixelFormat)); |
| } |
| |
| for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) { |
| /* Do not enumerate modes we cannot handle anyway */ |
| if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight)) |
| break; |
| |
| ddsfd.dwWidth = modes[mode].w; |
| ddsfd.dwHeight = modes[mode].h; |
| |
| /* Now, send the mode description to the application */ |
| TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight); |
| if (!modescb(&ddsfd, context)) |
| goto exit_enum; |
| } |
| |
| if (!(dwFlags & DDEDM_STANDARDVGAMODES)) { |
| /* modeX is not standard VGA */ |
| ddsfd.dwWidth = 320; |
| ddsfd.dwHeight = 200; |
| if (!modescb(&ddsfd, context)) |
| goto exit_enum; |
| } |
| } |
| |
| /* Hack to always enumerate a 8bpp depth */ |
| i++; |
| if ((i == npixmap) && (has_8bpp == 0)) { |
| i--; |
| pf[i].depth = 8; |
| } |
| } |
| |
| exit_enum: |
| TSXFree(vi); |
| TSXFree(pf); |
| |
| 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 = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); |
| lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor); |
| lpddsfd->lPitch = this->e.dga.fb_width*this->d.directdraw_pixelformat.x.dwRGBBitCount/8; |
| lpddsfd->dwBackBufferCount = 1; |
| lpddsfd->x.dwRefreshRate = 60; |
| lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE; |
| lpddsfd->ddpfPixelFormat = this->d.directdraw_pixelformat; |
| 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 = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); |
| lpddsfd->dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor); |
| lpddsfd->lPitch = lpddsfd->dwWidth * this->d.directdraw_pixelformat.x.dwRGBBitCount/8; |
| lpddsfd->dwBackBufferCount = 1; |
| lpddsfd->x.dwRefreshRate = 60; |
| lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE; |
| lpddsfd->ddpfPixelFormat = this->d.directdraw_pixelformat; |
| 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 DD_OK; |
| } |
| |
| /* 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 DD_OK; |
| } |
| |
| 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 DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDraw2_Compact( |
| LPDIRECTDRAW2 this ) |
| { |
| FIXME(ddraw,"(%p)->()\n", this ); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDraw2_GetGDISurface(LPDIRECTDRAW2 this, |
| LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) { |
| FIXME(ddraw,"(%p)->(%p)\n", this, lplpGDIDDSSurface); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDraw2_GetScanLine(LPDIRECTDRAW2 this, |
| LPDWORD lpdwScanLine) { |
| FIXME(ddraw,"(%p)->(%p)\n", this, lpdwScanLine); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDraw2_Initialize(LPDIRECTDRAW2 this, |
| GUID *lpGUID) { |
| FIXME(ddraw,"(%p)->(%p)\n", this, lpGUID); |
| |
| 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)DGA_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)IDirectDraw2_GetGDISurface, |
| XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency, |
| XCAST(GetScanLine)IDirectDraw2_GetScanLine, |
| XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus, |
| XCAST(Initialize)IDirectDraw2_Initialize, |
| 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)Xlib_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)IDirectDraw2_GetGDISurface, |
| XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency, |
| XCAST(GetScanLine)IDirectDraw2_GetScanLine, |
| XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus, |
| XCAST(Initialize)IDirectDraw2_Initialize, |
| XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode, |
| XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel, |
| Xlib_IDirectDraw_SetDisplayMode, |
| XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank, |
| }; |
| |
| #undef XCAST |
| |
| /***************************************************************************** |
| * 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 DD_OK; |
| } |
| |
| 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 DD_OK; |
| } |
| |
| static IDirectDraw2_VTable dga_dd2vt = { |
| DGA_IDirectDraw2_QueryInterface, |
| IDirectDraw2_AddRef, |
| DGA_IDirectDraw2_Release, |
| IDirectDraw2_Compact, |
| IDirectDraw2_CreateClipper, |
| DGA_IDirectDraw2_CreatePalette, |
| DGA_IDirectDraw2_CreateSurface, |
| IDirectDraw2_DuplicateSurface, |
| DGA_IDirectDraw2_EnumDisplayModes, |
| IDirectDraw2_EnumSurfaces, |
| IDirectDraw2_FlipToGDISurface, |
| DGA_IDirectDraw2_GetCaps, |
| DGA_IDirectDraw2_GetDisplayMode, |
| IDirectDraw2_GetFourCCCodes, |
| IDirectDraw2_GetGDISurface, |
| IDirectDraw2_GetMonitorFrequency, |
| IDirectDraw2_GetScanLine, |
| IDirectDraw2_GetVerticalBlankStatus, |
| IDirectDraw2_Initialize, |
| 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, |
| IDirectDraw2_DuplicateSurface, |
| Xlib_IDirectDraw2_EnumDisplayModes, |
| IDirectDraw2_EnumSurfaces, |
| IDirectDraw2_FlipToGDISurface, |
| Xlib_IDirectDraw2_GetCaps, |
| Xlib_IDirectDraw2_GetDisplayMode, |
| IDirectDraw2_GetFourCCCodes, |
| IDirectDraw2_GetGDISurface, |
| IDirectDraw2_GetMonitorFrequency, |
| IDirectDraw2_GetScanLine, |
| IDirectDraw2_GetVerticalBlankStatus, |
| IDirectDraw2_Initialize, |
| Xlib_IDirectDraw2_RestoreDisplayMode, |
| IDirectDraw2_SetCooperativeLevel, |
| Xlib_IDirectDraw2_SetDisplayMode, |
| IDirectDraw2_WaitForVerticalBlank, |
| Xlib_IDirectDraw2_GetAvailableVidMem |
| }; |
| |
| /***************************************************************************** |
| * IDirectDraw4 |
| * |
| */ |
| |
| static HRESULT WINAPI IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4 this, |
| HDC hdc, |
| LPDIRECTDRAWSURFACE *lpDDS) { |
| FIXME(ddraw, "(%p)->(%08ld,%p)\n", this, (DWORD) hdc, lpDDS); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4 this) { |
| FIXME(ddraw, "(%p)->()\n", this); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4 this) { |
| FIXME(ddraw, "(%p)->()\n", this); |
| |
| return DD_OK; |
| } |
| |
| static HRESULT WINAPI IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4 this, |
| LPDDDEVICEIDENTIFIER lpdddi, |
| DWORD dwFlags) { |
| FIXME(ddraw, "(%p)->(%p,%08lx)\n", this, lpdddi, dwFlags); |
| |
| return DD_OK; |
| } |
| |
| #ifdef __GNUC__ |
| # define XCAST(fun) (typeof(dga_dd4vt.fn##fun)) |
| #else |
| # define XCAST(fun) (void*) |
| #endif |
| |
| |
| static struct IDirectDraw4_VTable dga_dd4vt = { |
| 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)DGA_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)IDirectDraw2_GetGDISurface, |
| XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency, |
| XCAST(GetScanLine)IDirectDraw2_GetScanLine, |
| XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus, |
| XCAST(Initialize)IDirectDraw2_Initialize, |
| XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode, |
| XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel, |
| XCAST(SetDisplayMode)DGA_IDirectDraw_SetDisplayMode, |
| XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank, |
| XCAST(GetAvailableVidMem)DGA_IDirectDraw2_GetAvailableVidMem, |
| IDirectDraw4_GetSurfaceFromDC, |
| IDirectDraw4_RestoreAllSurfaces, |
| IDirectDraw4_TestCooperativeLevel, |
| IDirectDraw4_GetDeviceIdentifier |
| }; |
| |
| static struct IDirectDraw4_VTable xlib_dd4vt = { |
| 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)Xlib_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)IDirectDraw2_GetGDISurface, |
| XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency, |
| XCAST(GetScanLine)IDirectDraw2_GetScanLine, |
| XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus, |
| XCAST(Initialize)IDirectDraw2_Initialize, |
| XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode, |
| XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel, |
| XCAST(SetDisplayMode)Xlib_IDirectDraw_SetDisplayMode, |
| XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank, |
| XCAST(GetAvailableVidMem)Xlib_IDirectDraw2_GetAvailableVidMem, |
| IDirectDraw4_GetSurfaceFromDC, |
| IDirectDraw4_RestoreAllSurfaces, |
| IDirectDraw4_TestCooperativeLevel, |
| IDirectDraw4_GetDeviceIdentifier |
| }; |
| |
| #undef XCAST |
| |
| /****************************************************************************** |
| * DirectDrawCreate |
| */ |
| |
| LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM 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)GetWindowLongA( 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->d.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 = DefWindowProcA( 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 = CallWindowProcA( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc, |
| ddraw->d.mainWindow, msg, wParam, lParam ); |
| } |
| } |
| |
| } else { |
| ret = DefWindowProcA(hwnd, msg, wParam, lParam ); |
| } |
| |
| } |
| else |
| { |
| ret = DefWindowProcA(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; |
| int depth; |
| |
| /* 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"); |
| MessageBoxA(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 = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); |
| #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 */ |
| depth = DefaultDepthOfScreen(X11DRV_GetXScreen()); |
| _common_depth_to_pixelformat(depth, &((*lplpDD)->d.directdraw_pixelformat), &((*lplpDD)->d.screen_pixelformat), NULL); |
| #ifdef RESTORE_SIGNALS |
| SIGNAL_InitHandlers(); |
| #endif |
| |
| return DD_OK; |
| #else /* defined(HAVE_LIBXXF86DGA) */ |
| return DDERR_INVALIDDIRECTDRAWGUID; |
| #endif /* defined(HAVE_LIBXXF86DGA) */ |
| } |
| |
| BOOL |
| DDRAW_XSHM_Available(void) |
| { |
| #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) { |
| int depth; |
| |
| *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw)); |
| (*lplpDD)->lpvtbl = &xlib_ddvt; |
| (*lplpDD)->ref = 1; |
| (*lplpDD)->d.drawable = 0; /* in SetDisplayMode */ |
| |
| /* At DirectDraw creation, the depth is the default depth */ |
| depth = DefaultDepthOfScreen(X11DRV_GetXScreen()); |
| _common_depth_to_pixelformat(depth, &((*lplpDD)->d.directdraw_pixelformat), &((*lplpDD)->d.screen_pixelformat), NULL); |
| (*lplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); |
| (*lplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor); |
| |
| #ifdef HAVE_LIBXXSHM |
| /* Test if XShm is available. */ |
| if (((*lplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) |
| TRACE(ddraw, "Using XShm extension.\n"); |
| #endif |
| |
| return DD_OK; |
| } |
| |
| HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) { |
| char xclsid[50]; |
| WNDCLASSA wc; |
| WND* pParentWindow; |
| HRESULT ret; |
| |
| if (HIWORD(lpGUID)) |
| WINE_StringFromCLSID(lpGUID,xclsid); |
| else { |
| sprintf(xclsid,"<guid-0x%08x>",(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 = (HCURSOR)IDC_ARROWA; |
| wc.hbrBackground= NULL_BRUSH; |
| wc.lpszMenuName = 0; |
| wc.lpszClassName= "WINE_DirectDraw"; |
| RegisterClassA(&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 = RegisterClassA(&wc); |
| return ret; |
| |
| err: |
| ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter); |
| return DDERR_INVALIDDIRECTDRAWGUID; |
| } |
| |
| |
| #else /* !defined(X_DISPLAY_MISSING) */ |
| |
| #include "windef.h" |
| |
| #define DD_OK 0 |
| |
| typedef void *LPGUID; |
| typedef void *LPUNKNOWN; |
| typedef void *LPDIRECTDRAW; |
| typedef void *LPDIRECTDRAWCLIPPER; |
| typedef void *LPDDENUMCALLBACKA; |
| typedef void *LPDDENUMCALLBACKEXA; |
| typedef void *LPDDENUMCALLBACKEXW; |
| typedef void *LPDDENUMCALLBACKW; |
| |
| HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z) |
| { |
| return DD_OK; |
| } |
| |
| HRESULT WINAPI DirectDrawCreate( |
| LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) |
| { |
| return DD_OK; |
| } |
| |
| HRESULT WINAPI DirectDrawCreateClipper( |
| DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter) |
| { |
| return DD_OK; |
| } |
| |
| HRESULT WINAPI DirectDrawEnumerateA( |
| LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) |
| { |
| return DD_OK; |
| } |
| |
| HRESULT WINAPI DirectDrawEnumerateExA( |
| LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags) |
| { |
| return DD_OK; |
| } |
| |
| HRESULT WINAPI DirectDrawEnumerateExW( |
| LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags) |
| { |
| return DD_OK; |
| } |
| |
| HRESULT WINAPI DirectDrawEnumerateW( |
| LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) |
| { |
| return DD_OK; |
| } |
| |
| #endif /* !defined(X_DISPLAY_MISSING) */ |