| /* DirectDraw using DGA or Xlib(XSHM) | |
| * | |
| * Copyright 1997-1999 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" | |
| #include "winerror.h" | |
| #ifndef X_DISPLAY_MISSING | |
| #include "ts_xlib.h" | |
| #include "ts_xutil.h" | |
| #ifdef HAVE_LIBXXSHM | |
| # include <sys/types.h> | |
| # ifdef HAVE_SYS_IPC_H | |
| # include <sys/ipc.h> | |
| # endif | |
| # ifdef HAVE_SYS_SHM_H | |
| # include <sys/shm.h> | |
| # endif | |
| # include "ts_xshm.h" | |
| #endif /* defined(HAVE_LIBXXSHM) */ | |
| #ifdef HAVE_LIBXXF86DGA | |
| #include "ts_xf86dga.h" | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| #include "ts_xf86dga2.h" | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| #ifdef HAVE_LIBXXF86VM | |
| #include "ts_xf86vmode.h" | |
| #endif /* defined(HAVE_LIBXXF86VM) */ | |
| #include "x11drv.h" | |
| #include <unistd.h> | |
| #include <assert.h> | |
| #ifdef HAVE_SYS_SIGNAL_H | |
| # include <sys/signal.h> | |
| #endif | |
| #include <fcntl.h> | |
| #include <string.h> | |
| #include <stdlib.h> | |
| #include "gdi.h" | |
| #include "heap.h" | |
| #include "dc.h" | |
| #include "win.h" | |
| #include "wine/exception.h" | |
| #include "ddraw.h" | |
| #include "d3d.h" | |
| #include "debugtools.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 "ddraw_private.h" | |
| #include "d3d_private.h" | |
| DEFAULT_DEBUG_CHANNEL(ddraw) | |
| /* Restore signal handlers overwritten by XF86DGA | |
| */ | |
| #define RESTORE_SIGNALS | |
| /* Get DDSCAPS of surface (shortcutmacro) */ | |
| #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps) | |
| /* Get the number of bytes per pixel for a given surface */ | |
| #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8)) | |
| #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat) | |
| /* 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} | |
| }; | |
| #ifdef HAVE_LIBXXF86DGA | |
| static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt; | |
| static struct ICOM_VTABLE(IDirectDraw) dga_ddvt; | |
| static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt; | |
| static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt; | |
| static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| static struct ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt; | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| static struct ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt; | |
| static struct ICOM_VTABLE(IDirectDraw) xlib_ddvt; | |
| static struct ICOM_VTABLE(IDirectDraw2) xlib_dd2vt; | |
| static struct ICOM_VTABLE(IDirectDraw4) xlib_dd4vt; | |
| static struct ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt; | |
| static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt; | |
| static struct ICOM_VTABLE(IDirect3D) d3dvt; | |
| static struct ICOM_VTABLE(IDirect3D2) d3d2vt; | |
| /* This is for mode-emulation */ | |
| static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ; | |
| static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ; | |
| static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ; | |
| static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ; | |
| static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ; | |
| static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ; | |
| static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ; | |
| typedef struct { | |
| unsigned short bpp; | |
| unsigned short depth; | |
| unsigned int rmask; | |
| unsigned int gmask; | |
| unsigned int bmask; | |
| } ConvertMode; | |
| typedef struct { | |
| void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette); | |
| void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count); | |
| } ConvertFuncs; | |
| typedef struct { | |
| ConvertMode screen, dest; | |
| ConvertFuncs funcs; | |
| } Convert; | |
| static Convert ModeEmulations[] = { | |
| { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } }, | |
| { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } }, | |
| { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } }, | |
| { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } }, | |
| { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } }, | |
| }; | |
| #ifdef HAVE_LIBXXF86VM | |
| static XF86VidModeModeInfo *orig_mode = NULL; | |
| #endif | |
| #ifdef HAVE_LIBXXSHM | |
| static int XShmErrorFlag = 0; | |
| #endif | |
| static BYTE | |
| DDRAW_DGA_Available(void) | |
| { | |
| #ifdef HAVE_LIBXXF86DGA | |
| int fd, evbase, evret, majver, minver; | |
| static BYTE return_value = 0xFF; | |
| /* This prevents from probing X times for DGA */ | |
| if (return_value != 0xFF) | |
| return return_value; | |
| if (Options.noDGA) { | |
| return_value = 0; | |
| return 0; | |
| } | |
| /* First, query the extenstion and its version */ | |
| if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) { | |
| return_value = 0; | |
| return 0; | |
| } | |
| if (!TSXF86DGAQueryVersion(display,&majver,&minver)) { | |
| return_value = 0; | |
| return 0; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| if (majver >= 2) { | |
| /* We have DGA 2.0 available ! */ | |
| if (TSXDGAOpenFramebuffer(display, DefaultScreen(display))) { | |
| TSXDGACloseFramebuffer(display, DefaultScreen(display)); | |
| return_value = 2; | |
| } else { | |
| return_value = 0; | |
| } | |
| return return_value; | |
| } else { | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| /* 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); | |
| if (fd != -1) | |
| return_value = 1; | |
| else | |
| return_value = 0; | |
| return return_value; | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| #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("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags); | |
| if (TRACE_ON(ddraw)) { | |
| DPRINTF(" Flags : "); | |
| if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES) | |
| DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES "); | |
| if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES) | |
| DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES "); | |
| if (dwFlags & DDENUM_NONDISPLAYDEVICES) | |
| DPRINTF("DDENUM_NONDISPLAYDEVICES "); | |
| DPRINTF("\n"); | |
| } | |
| if (dwFlags == DDENUM_NONDISPLAYDEVICES) { | |
| /* For the moment, Wine does not support any 3D only accelerators */ | |
| return DD_OK; | |
| } | |
| if (dwFlags == DDENUM_NONDISPLAYDEVICES) { | |
| /* For the moment, Wine does not support any attached secondary devices */ | |
| return DD_OK; | |
| } | |
| if (DDRAW_DGA_Available()) { | |
| TRACE("Enumerating DGA interface\n"); | |
| if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0)) | |
| return DD_OK; | |
| } | |
| TRACE("Enumerating Xlib interface\n"); | |
| if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0)) | |
| return DD_OK; | |
| TRACE("Enumerating Default interface\n"); | |
| if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0)) | |
| return DD_OK; | |
| return DD_OK; | |
| } | |
| /*********************************************************************** | |
| * DirectDrawEnumerateExW (DDRAW.*) | |
| */ | |
| static BOOL CALLBACK 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 = (LPVOID) lpCallback; | |
| epd.lpContext = lpContext; | |
| return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW, | |
| (LPVOID) &epd, 0); | |
| } | |
| /*********************************************************************** | |
| * DirectDrawEnumerateA (DDRAW.*) | |
| */ | |
| static BOOL CALLBACK 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 = (LPVOID) lpCallback; | |
| epd.lpContext = lpContext; | |
| return DirectDrawEnumerateExA(DirectDrawEnumerateProcA, | |
| (LPVOID) &epd, 0); | |
| } | |
| /*********************************************************************** | |
| * DirectDrawEnumerateW (DDRAW.*) | |
| */ | |
| static BOOL WINAPI 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 = (LPVOID) 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("(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) | |
| #undef FE | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) { | |
| DPRINTF("%s ",flags[i].name); | |
| }; | |
| DPRINTF("\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) | |
| #undef FE | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) | |
| DPRINTF("%s ",flags[i].name); | |
| DPRINTF("\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) | |
| #undef FE | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) | |
| DPRINTF("%s ",flags[i].name); | |
| DPRINTF("\n"); | |
| } | |
| static void _dump_DDSCAPS(void *in) { | |
| 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) | |
| #undef FE | |
| }; | |
| DWORD flagmask = *((DWORD *) in); | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) | |
| DPRINTF("%s ",flags[i].name); | |
| } | |
| static void _dump_pixelformat_flag(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) | |
| #undef FE | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & flagmask) | |
| DPRINTF("%s ",flags[i].name); | |
| } | |
| 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) | |
| #undef FE | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & dwFlags) | |
| DPRINTF("%s ",flags[i].name); | |
| DPRINTF("\n"); | |
| } | |
| static void _dump_pixelformat(void *in) { | |
| LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in; | |
| char *cmd; | |
| DPRINTF("( "); | |
| _dump_pixelformat_flag(pf->dwFlags); | |
| if (pf->dwFlags & DDPF_FOURCC) { | |
| DPRINTF(", dwFourCC : %ld", pf->dwFourCC); | |
| } | |
| if (pf->dwFlags & DDPF_RGB) { | |
| DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount); | |
| switch (pf->u.dwRGBBitCount) { | |
| case 4: | |
| cmd = "%1lx"; | |
| break; | |
| case 8: | |
| cmd = "%02lx"; | |
| break; | |
| case 16: | |
| cmd = "%04lx"; | |
| break; | |
| case 24: | |
| cmd = "%06lx"; | |
| break; | |
| case 32: | |
| cmd = "%08lx"; | |
| break; | |
| default: | |
| ERR("Unexpected bit depth !\n"); | |
| cmd = "%d"; | |
| } | |
| DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask); | |
| DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask); | |
| DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask); | |
| if (pf->dwFlags & DDPF_ALPHAPIXELS) { | |
| DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask); | |
| } | |
| if (pf->dwFlags & DDPF_ZPIXELS) { | |
| DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask); | |
| } | |
| } | |
| if (pf->dwFlags & DDPF_ZBUFFER) { | |
| DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth); | |
| } | |
| if (pf->dwFlags & DDPF_ALPHA) { | |
| DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth); | |
| } | |
| DPRINTF(")"); | |
| } | |
| static void _dump_colorkeyflag(DWORD ck) { | |
| int i; | |
| const struct { | |
| DWORD mask; | |
| char *name; | |
| } flags[] = { | |
| #define FE(x) { x, #x}, | |
| FE(DDCKEY_COLORSPACE) | |
| FE(DDCKEY_DESTBLT) | |
| FE(DDCKEY_DESTOVERLAY) | |
| FE(DDCKEY_SRCBLT) | |
| FE(DDCKEY_SRCOVERLAY) | |
| #undef FE | |
| }; | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & ck) | |
| DPRINTF("%s ",flags[i].name); | |
| } | |
| static void _dump_DWORD(void *in) { | |
| DPRINTF("%ld", *((DWORD *) in)); | |
| } | |
| static void _dump_PTR(void *in) { | |
| DPRINTF("%p", *((void **) in)); | |
| } | |
| static void _dump_DDCOLORKEY(void *in) { | |
| DDCOLORKEY *ddck = (DDCOLORKEY *) in; | |
| DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue); | |
| } | |
| static void _dump_surface_desc(DDSURFACEDESC *lpddsd) { | |
| int i; | |
| struct { | |
| DWORD mask; | |
| char *name; | |
| void (*func)(void *); | |
| void *elt; | |
| } flags[16], *fe = flags; | |
| #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0) | |
| FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps); | |
| FE(DDSD_HEIGHT, _dump_DWORD, dwHeight); | |
| FE(DDSD_WIDTH, _dump_DWORD, dwWidth); | |
| FE(DDSD_PITCH, _dump_DWORD, lPitch); | |
| FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount); | |
| FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth); | |
| FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth); | |
| FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat); | |
| FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay); | |
| FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt); | |
| FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay); | |
| FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt); | |
| FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount); | |
| FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate); | |
| FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize); | |
| FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface); | |
| #undef FE | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) | |
| if (flags[i].mask & lpddsd->dwFlags) { | |
| DPRINTF(" - %s : ",flags[i].name); | |
| flags[i].func(flags[i].elt); | |
| DPRINTF("\n"); | |
| } | |
| } | |
| /****************************************************************************** | |
| * 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 IDirectDrawSurface4Impl_Lock( | |
| LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n", | |
| This,lprect,lpddsd,flags,(DWORD)hnd); | |
| if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY)) | |
| WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n", | |
| This,lprect,lpddsd,flags,(DWORD)hnd); | |
| /* First, copy the Surface description */ | |
| *lpddsd = This->s.surface_desc; | |
| TRACE("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) { | |
| TRACE(" lprect: %dx%d-%dx%d\n", | |
| lprect->top,lprect->left,lprect->bottom,lprect->right | |
| ); | |
| if ((lprect->top < 0) || | |
| (lprect->left < 0) || | |
| (lprect->bottom < 0) || | |
| (lprect->right < 0)) { | |
| ERR(" Negative values in LPRECT !!!\n"); | |
| return DDERR_INVALIDPARAMS; | |
| } | |
| lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface + | |
| (lprect->top*This->s.surface_desc.lPitch) + | |
| lprect->left*GET_BPP(This->s.surface_desc)); | |
| } else { | |
| assert(This->s.surface_desc.u1.lpSurface); | |
| } | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock( | |
| LPDIRECTDRAWSURFACE4 iface,LPVOID surface | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->Unlock(%p)\n",This,surface); | |
| return DD_OK; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) { | |
| if (This->s.ddraw->d.pixel_convert != NULL) | |
| This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.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) { | |
| int compl = This->s.ddraw->e.xlib.xshm_compl; | |
| if (compl) | |
| X11DRV_EVENT_WaitShmCompletion( compl ); | |
| This->s.ddraw->e.xlib.xshm_compl = X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable ); | |
| 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, | |
| True); | |
| } | |
| 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_IDirectDrawSurface4Impl_Unlock( | |
| LPDIRECTDRAWSURFACE4 iface,LPVOID surface) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%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 && (SDDSCAPS(This) & 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 IDirectDrawSurface4Impl* _common_find_flipto( | |
| IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto | |
| ) { | |
| int i,j,flipable=0; | |
| struct _surface_chain *chain = This->s.chain; | |
| /* if there was no override flipto, look for current backbuffer */ | |
| if (!flipto) { | |
| /* walk the flip chain looking for backbuffer */ | |
| for (i=0;i<chain->nrofsurfaces;i++) { | |
| if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) | |
| flipable++; | |
| if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER) | |
| flipto = chain->surfaces[i]; | |
| } | |
| /* sanity checks ... */ | |
| if (!flipto) { | |
| if (flipable>1) { | |
| for (i=0;i<chain->nrofsurfaces;i++) | |
| if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER) | |
| break; | |
| if (i==chain->nrofsurfaces) { | |
| /* we do not have a frontbuffer either */ | |
| for (i=0;i<chain->nrofsurfaces;i++) | |
| if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) { | |
| SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER; | |
| break; | |
| } | |
| for (j=i+1;j<i+chain->nrofsurfaces+1;j++) { | |
| int k = j % chain->nrofsurfaces; | |
| if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) { | |
| SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER; | |
| flipto = chain->surfaces[k]; | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| if (!flipto) | |
| flipto = This; | |
| } | |
| TRACE("flipping to %p\n",flipto); | |
| } | |
| return flipto; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip( | |
| LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto; | |
| DWORD xheight; | |
| LPBYTE surf; | |
| TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags); | |
| iflipto = _common_find_flipto(This,iflipto); | |
| /* and flip! */ | |
| TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height); | |
| if (iflipto->s.palette && iflipto->s.palette->cm) | |
| TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm); | |
| while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) { | |
| } | |
| /* We need to switch the lowlevel surfaces, for DGA this is: */ | |
| /* The height within the framebuffer */ | |
| xheight = This->t.dga.fb_height; | |
| This->t.dga.fb_height = iflipto->t.dga.fb_height; | |
| iflipto->t.dga.fb_height = xheight; | |
| /* And the assciated surface pointer */ | |
| surf = This->s.surface_desc.u1.lpSurface; | |
| This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface; | |
| iflipto->s.surface_desc.u1.lpSurface = surf; | |
| return DD_OK; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| static HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip( | |
| LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto; | |
| DWORD xheight; | |
| LPBYTE surf; | |
| TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags); | |
| iflipto = _common_find_flipto(This,iflipto); | |
| /* and flip! */ | |
| TSXDGASetViewport(display,DefaultScreen(display),0,iflipto->t.dga.fb_height, XDGAFlipRetrace); | |
| TSXDGASync(display,DefaultScreen(display)); | |
| TSXFlush(display); | |
| if (iflipto->s.palette && iflipto->s.palette->cm) | |
| TSXDGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm); | |
| /* We need to switch the lowlevel surfaces, for DGA this is: */ | |
| /* The height within the framebuffer */ | |
| xheight = This->t.dga.fb_height; | |
| This->t.dga.fb_height = iflipto->t.dga.fb_height; | |
| iflipto->t.dga.fb_height = xheight; | |
| /* And the assciated surface pointer */ | |
| surf = This->s.surface_desc.u1.lpSurface; | |
| This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface; | |
| iflipto->s.surface_desc.u1.lpSurface = surf; | |
| return DD_OK; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip( | |
| LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| XImage *image; | |
| LPBYTE surf; | |
| IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto; | |
| TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags); | |
| iflipto = _common_find_flipto(This,iflipto); | |
| #if defined(HAVE_MESAGL) && 0 /* does not work */ | |
| if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) { | |
| TRACE(" - OpenGL flip\n"); | |
| ENTER_GL(); | |
| glXSwapBuffers(display, This->s.ddraw->d.drawable); | |
| LEAVE_GL(); | |
| return DD_OK; | |
| } | |
| #endif /* defined(HAVE_MESAGL) */ | |
| if (!This->s.ddraw->d.paintable) | |
| return DD_OK; | |
| /* We need to switch the lowlevel surfaces, for xlib this is: */ | |
| /* The surface pointer */ | |
| surf = This->s.surface_desc.u1.lpSurface; | |
| This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface; | |
| iflipto->s.surface_desc.u1.lpSurface = surf; | |
| /* the associated ximage */ | |
| image = This->t.xlib.image; | |
| This->t.xlib.image = iflipto->t.xlib.image; | |
| iflipto->t.xlib.image = image; | |
| Xlib_copy_surface_on_screen(This); | |
| if (iflipto->s.palette && iflipto->s.palette->cm) | |
| TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm); | |
| 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_IDirectDrawSurface4Impl_SetPalette( | |
| LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal; | |
| int i; | |
| TRACE("(%p)->(%p)\n",This,ipal); | |
| if (ipal == NULL) { | |
| if( This->s.palette != NULL ) | |
| IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette); | |
| This->s.palette = ipal; | |
| return DD_OK; | |
| } | |
| if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8)) | |
| { | |
| ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable, | |
| DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll); | |
| if (!Options.managed) | |
| TSXInstallColormap(display,ipal->cm); | |
| for (i=0;i<256;i++) { | |
| XColor xc; | |
| xc.red = ipal->palents[i].peRed<<8; | |
| xc.blue = ipal->palents[i].peBlue<<8; | |
| xc.green = ipal->palents[i].peGreen<<8; | |
| xc.flags = DoRed|DoBlue|DoGreen; | |
| xc.pixel = i; | |
| TSXStoreColor(display,ipal->cm,&xc); | |
| } | |
| TSXInstallColormap(display,ipal->cm); | |
| } | |
| /* According to spec, we are only supposed to | |
| * AddRef if this is not the same palette. | |
| */ | |
| if( This->s.palette != ipal ) | |
| { | |
| if( ipal != NULL ) | |
| IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal ); | |
| if( This->s.palette != NULL ) | |
| IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette ); | |
| This->s.palette = ipal; | |
| /* Perform the refresh */ | |
| TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm); | |
| } | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette( | |
| LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal; | |
| TRACE("(%p)->(%p)\n",This,ipal); | |
| /* According to spec, we are only supposed to | |
| * AddRef if this is not the same palette. | |
| */ | |
| if( This->s.palette != ipal ) | |
| { | |
| if( ipal != NULL ) | |
| IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal ); | |
| if( This->s.palette != NULL ) | |
| IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette ); | |
| This->s.palette = ipal; | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| if (This->s.ddraw->e.dga.version == 2) | |
| TSXDGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm); | |
| else | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm); | |
| } | |
| return DD_OK; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color) | |
| { | |
| int x, y; | |
| LPBYTE first; | |
| /* Do first row */ | |
| #define COLORFILL_ROW(type) { \ | |
| type *d = (type *) buf; \ | |
| for (x = 0; x < width; x++) \ | |
| d[x] = (type) color; \ | |
| break; \ | |
| } | |
| switch(bpp) { | |
| case 1: COLORFILL_ROW(BYTE) | |
| case 2: COLORFILL_ROW(WORD) | |
| case 4: COLORFILL_ROW(DWORD) | |
| default: | |
| FIXME("Color fill not implemented for bpp %d!\n", bpp*8); | |
| return DDERR_UNSUPPORTED; | |
| } | |
| #undef COLORFILL_ROW | |
| /* Now copy first row */ | |
| first = buf; | |
| for (y = 1; y < height; y++) { | |
| buf += lPitch; | |
| memcpy(buf, first, width * bpp); | |
| } | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_Blt( | |
| LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| RECT xdst,xsrc; | |
| DDSURFACEDESC ddesc,sdesc; | |
| HRESULT ret = DD_OK; | |
| int bpp, srcheight, srcwidth, dstheight, dstwidth, width; | |
| int x, y; | |
| LPBYTE dbuf, sbuf; | |
| TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx); | |
| if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0); | |
| IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0); | |
| if (TRACE_ON(ddraw)) { | |
| if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom); | |
| if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom); | |
| TRACE("\tflags: "); | |
| _dump_DDBLT(dwFlags); | |
| if (dwFlags & DDBLT_DDFX) { | |
| TRACE("\tblitfx: "); | |
| _dump_DDBLTFX(lpbltfx->dwDDFX); | |
| } | |
| } | |
| if (rdst) { | |
| if ((rdst->top < 0) || | |
| (rdst->left < 0) || | |
| (rdst->bottom < 0) || | |
| (rdst->right < 0)) { | |
| ERR(" Negative values in LPRECT !!!\n"); | |
| goto release; | |
| } | |
| memcpy(&xdst,rdst,sizeof(xdst)); | |
| } else { | |
| xdst.top = 0; | |
| xdst.bottom = ddesc.dwHeight; | |
| xdst.left = 0; | |
| xdst.right = ddesc.dwWidth; | |
| } | |
| if (rsrc) { | |
| if ((rsrc->top < 0) || | |
| (rsrc->left < 0) || | |
| (rsrc->bottom < 0) || | |
| (rsrc->right < 0)) { | |
| ERR(" Negative values in LPRECT !!!\n"); | |
| goto release; | |
| } | |
| 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)); | |
| } | |
| } | |
| bpp = GET_BPP(ddesc); | |
| srcheight = xsrc.bottom - xsrc.top; | |
| srcwidth = xsrc.right - xsrc.left; | |
| dstheight = xdst.bottom - xdst.top; | |
| dstwidth = xdst.right - xdst.left; | |
| width = (xdst.right - xdst.left) * bpp; | |
| dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp); | |
| dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */ | |
| /* First, all the 'source-less' blits */ | |
| if (dwFlags & DDBLT_COLORFILL) { | |
| ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, | |
| ddesc.lPitch, lpbltfx->u4.dwFillColor); | |
| dwFlags &= ~DDBLT_COLORFILL; | |
| } | |
| if (dwFlags & DDBLT_DEPTHFILL) { | |
| #ifdef HAVE_MESAGL | |
| GLboolean ztest; | |
| /* Clears the screen */ | |
| TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth); | |
| glClearDepth(lpbltfx->u4.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 /* defined(HAVE_MESAGL) */ | |
| } | |
| if (dwFlags & DDBLT_ROP) { | |
| /* Catch some degenerate cases here */ | |
| switch(lpbltfx->dwROP) { | |
| case BLACKNESS: | |
| ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0); | |
| break; | |
| case 0xAA0029: /* No-op */ | |
| break; | |
| case WHITENESS: | |
| ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0); | |
| break; | |
| default: | |
| FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern); | |
| goto error; | |
| } | |
| dwFlags &= ~DDBLT_ROP; | |
| } | |
| if (dwFlags & DDBLT_DDROPS) { | |
| FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern); | |
| } | |
| /* Now the 'with source' blits */ | |
| if (src) { | |
| LPBYTE sbase; | |
| int sx, xinc, sy, yinc; | |
| sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp; | |
| xinc = (srcwidth << 16) / dstwidth; | |
| yinc = (srcheight << 16) / dstheight; | |
| if (!dwFlags) { | |
| /* No effects, we can cheat here */ | |
| if (dstwidth == srcwidth) { | |
| if (dstheight == srcheight) { | |
| /* No stretching in either direction. This needs to be as fast as possible */ | |
| sbuf = sbase; | |
| for (y = 0; y < dstheight; y++) { | |
| memcpy(dbuf, sbuf, width); | |
| sbuf += sdesc.lPitch; | |
| dbuf += ddesc.lPitch; | |
| } | |
| } else { | |
| /* Stretching in Y direction only */ | |
| for (y = sy = 0; y < dstheight; y++, sy += yinc) { | |
| sbuf = sbase + (sy >> 16) * sdesc.lPitch; | |
| memcpy(dbuf, sbuf, width); | |
| dbuf += ddesc.lPitch; | |
| } | |
| } | |
| } else { | |
| /* Stretching in X direction */ | |
| int last_sy = -1; | |
| for (y = sy = 0; y < dstheight; y++, sy += yinc) { | |
| sbuf = sbase + (sy >> 16) * sdesc.lPitch; | |
| if ((sy >> 16) == (last_sy >> 16)) { | |
| /* Same as last row - copy already stretched row */ | |
| memcpy(dbuf, dbuf - ddesc.lPitch, width); | |
| } else { | |
| #define STRETCH_ROW(type) { \ | |
| type *s = (type *) sbuf, *d = (type *) dbuf; \ | |
| for (x = sx = 0; x < dstwidth; x++, sx += xinc) \ | |
| d[x] = s[sx >> 16]; \ | |
| break; } | |
| switch(bpp) { | |
| case 1: STRETCH_ROW(BYTE) | |
| case 2: STRETCH_ROW(WORD) | |
| case 4: STRETCH_ROW(DWORD) | |
| default: | |
| FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8); | |
| ret = DDERR_UNSUPPORTED; | |
| goto error; | |
| } | |
| #undef STRETCH_ROW | |
| } | |
| last_sy = sy; | |
| dbuf += ddesc.lPitch; | |
| } | |
| } | |
| } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) { | |
| DWORD keylow, keyhigh; | |
| if (dwFlags & DDBLT_KEYSRC) { | |
| keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue; | |
| keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue; | |
| } else { | |
| /* I'm not sure if this is correct */ | |
| FIXME("DDBLT_KEYDEST not fully supported yet.\n"); | |
| keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue; | |
| keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue; | |
| } | |
| for (y = sy = 0; y < dstheight; y++, sy += yinc) { | |
| sbuf = sbase + (sy >> 16) * sdesc.lPitch; | |
| #define COPYROW_COLORKEY(type) { \ | |
| type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \ | |
| for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \ | |
| tmp = s[sx >> 16]; \ | |
| if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \ | |
| } \ | |
| break; } | |
| switch (bpp) { | |
| case 1: COPYROW_COLORKEY(BYTE) | |
| case 2: COPYROW_COLORKEY(WORD) | |
| case 4: COPYROW_COLORKEY(DWORD) | |
| default: | |
| FIXME("%s color-keyed blit not implemented for bpp %d!\n", | |
| (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8); | |
| ret = DDERR_UNSUPPORTED; | |
| goto error; | |
| } | |
| dbuf += ddesc.lPitch; | |
| } | |
| #undef COPYROW_COLORKEY | |
| dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST); | |
| } | |
| } | |
| error: | |
| if (dwFlags && FIXME_ON(ddraw)) { | |
| FIXME("\tUnsupported flags: "); | |
| _dump_DDBLT(dwFlags); | |
| } | |
| release: | |
| IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface); | |
| if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast( | |
| LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| int bpp, w, h, x, y; | |
| DDSURFACEDESC ddesc,sdesc; | |
| HRESULT ret = DD_OK; | |
| LPBYTE sbuf, dbuf; | |
| RECT rsrc2; | |
| if (TRACE_ON(ddraw)) { | |
| FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n", | |
| This,dstx,dsty,src,rsrc,trans | |
| ); | |
| FIXME(" trans:"); | |
| if (FIXME_ON(ddraw)) | |
| _dump_DDBLTFAST(trans); | |
| if (rsrc) | |
| FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom); | |
| else | |
| FIXME(" srcrect: NULL\n"); | |
| } | |
| /* We need to lock the surfaces, or we won't get refreshes when done. */ | |
| IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0); | |
| IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0); | |
| if (!rsrc) { | |
| WARN("rsrc is NULL!\n"); | |
| rsrc = &rsrc2; | |
| rsrc->left = rsrc->top = 0; | |
| rsrc->right = sdesc.dwWidth; | |
| rsrc->bottom = sdesc.dwHeight; | |
| } | |
| bpp = GET_BPP(This->s.surface_desc); | |
| sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp; | |
| dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp; | |
| 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; | |
| if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) { | |
| DWORD keylow, keyhigh; | |
| if (trans & DDBLTFAST_SRCCOLORKEY) { | |
| keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue; | |
| keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue; | |
| } else { | |
| /* I'm not sure if this is correct */ | |
| FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n"); | |
| keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue; | |
| keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue; | |
| } | |
| #define COPYBOX_COLORKEY(type) { \ | |
| type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \ | |
| s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \ | |
| d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \ | |
| for (y = 0; y < h; y++) { \ | |
| for (x = 0; x < w; x++) { \ | |
| tmp = s[x]; \ | |
| if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \ | |
| } \ | |
| (LPBYTE)s += sdesc.lPitch; \ | |
| (LPBYTE)d += ddesc.lPitch; \ | |
| } \ | |
| break; \ | |
| } | |
| switch (bpp) { | |
| case 1: COPYBOX_COLORKEY(BYTE) | |
| case 2: COPYBOX_COLORKEY(WORD) | |
| case 4: COPYBOX_COLORKEY(DWORD) | |
| default: | |
| FIXME("Source color key blitting not supported for bpp %d\n", bpp*8); | |
| ret = DDERR_UNSUPPORTED; | |
| goto error; | |
| } | |
| #undef COPYBOX_COLORKEY | |
| } else { | |
| int width = w * bpp; | |
| for (y = 0; y < h; y++) { | |
| memcpy(dbuf, sbuf, width); | |
| sbuf += sdesc.lPitch; | |
| dbuf += ddesc.lPitch; | |
| } | |
| } | |
| error: | |
| IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface); | |
| IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface); | |
| return ret; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch( | |
| LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n", | |
| This,ddbltbatch,x,y | |
| ); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps( | |
| LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->GetCaps(%p)\n",This,caps); | |
| caps->dwCaps = DDSCAPS_PALETTE; /* probably more */ | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc( | |
| LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%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_surface_desc(ddsd); } | |
| return DD_OK; | |
| } | |
| static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->() incrementing from %lu.\n", This, This->ref ); | |
| return ++(This->ref); | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->() decrementing from %lu.\n", This, This->ref ); | |
| if (--(This->ref)) | |
| return This->ref; | |
| IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw); | |
| /* clear out of surface list */ | |
| if (This->t.dga.fb_height == -1) | |
| HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface); | |
| else | |
| This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height)); | |
| /* Free the DIBSection (if any) */ | |
| if (This->s.hdc != 0) { | |
| SelectObject(This->s.hdc, This->s.holdbitmap); | |
| DeleteDC(This->s.hdc); | |
| DeleteObject(This->s.DIBsection); | |
| } | |
| /* Free the clipper if attached to this surface */ | |
| if( This->s.lpClipper ) | |
| IDirectDrawClipper_Release(This->s.lpClipper); | |
| HeapFree(GetProcessHeap(),0,This); | |
| return S_OK; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref ); | |
| if (--(This->ref)) | |
| return This->ref; | |
| IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw); | |
| if (This->t.xlib.image != NULL) { | |
| if (This->s.ddraw->d.pixel_convert != NULL) { | |
| /* In pixel conversion mode, there are 2 buffers to release. */ | |
| HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.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.u1.lpSurface); | |
| TSXDestroyImage(This->t.xlib.image); | |
| #ifdef HAVE_LIBXXSHM | |
| } | |
| #endif | |
| } | |
| This->t.xlib.image = 0; | |
| } else { | |
| HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface); | |
| } | |
| if (This->s.palette) | |
| IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette); | |
| /* Free the DIBSection (if any) */ | |
| if (This->s.hdc != 0) { | |
| SelectObject(This->s.hdc, This->s.holdbitmap); | |
| DeleteDC(This->s.hdc); | |
| DeleteObject(This->s.DIBsection); | |
| } | |
| /* Free the clipper if present */ | |
| if( This->s.lpClipper ) | |
| IDirectDrawClipper_Release(This->s.lpClipper); | |
| HeapFree(GetProcessHeap(),0,This); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface( | |
| LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| int i,found = 0,xstart; | |
| struct _surface_chain *chain; | |
| TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf); | |
| if (TRACE_ON(ddraw)) { | |
| TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps)); | |
| DPRINTF("\n"); | |
| } | |
| chain = This->s.chain; | |
| if (!chain) | |
| return DDERR_NOTFOUND; | |
| for (i=0;i<chain->nrofsurfaces;i++) | |
| if (chain->surfaces[i] == This) | |
| break; | |
| xstart = i; | |
| for (i=0;i<chain->nrofsurfaces;i++) { | |
| if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) { | |
| #if 0 | |
| if (found) /* may not find the same caps twice, (doc) */ | |
| return DDERR_INVALIDPARAMS;/*FIXME: correct? */ | |
| #endif | |
| found = (i+1)+xstart; | |
| } | |
| } | |
| if (!found) | |
| return DDERR_NOTFOUND; | |
| *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart]; | |
| /* FIXME: AddRef? */ | |
| TRACE("found %p\n",*lpdsf); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize( | |
| LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd); | |
| return DDERR_ALREADYINITIALIZED; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat( | |
| LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->(%p)\n",This,pf); | |
| *pf = This->s.surface_desc.ddpfPixelFormat; | |
| if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); } | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition( | |
| LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2 | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper( | |
| LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->(%p)!\n",This,lpClipper); | |
| if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper ); | |
| This->s.lpClipper = lpClipper; | |
| if (lpClipper) IDirectDrawClipper_AddRef( lpClipper ); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface( | |
| LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf | |
| ) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf; | |
| int i; | |
| struct _surface_chain *chain; | |
| FIXME("(%p)->(%p)\n",This,surf); | |
| chain = This->s.chain; | |
| /* IDirectDrawSurface4_AddRef(surf); */ | |
| if (chain) { | |
| for (i=0;i<chain->nrofsurfaces;i++) | |
| if (chain->surfaces[i] == isurf) | |
| FIXME("attaching already attached surface %p to %p!\n",iface,isurf); | |
| } else { | |
| chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain)); | |
| chain->nrofsurfaces = 1; | |
| chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0])); | |
| chain->surfaces[0] = This; | |
| This->s.chain = chain; | |
| } | |
| if (chain->surfaces) | |
| chain->surfaces = HeapReAlloc( | |
| GetProcessHeap(), | |
| 0, | |
| chain->surfaces, | |
| sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1) | |
| ); | |
| else | |
| chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0])); | |
| isurf->s.chain = chain; | |
| chain->surfaces[chain->nrofsurfaces++] = isurf; | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| DDSURFACEDESC desc; | |
| BITMAPINFO *b_info; | |
| UINT usage; | |
| FIXME("(%p)->GetDC(%p)\n",This,lphdc); | |
| /* Creates a DIB Section of the same size / format as the surface */ | |
| IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0); | |
| if (This->s.hdc == 0) { | |
| switch (desc.ddpfPixelFormat.u.dwRGBBitCount) { | |
| case 16: | |
| case 32: | |
| #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */ | |
| b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD)); | |
| break; | |
| #endif | |
| case 24: | |
| b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER)); | |
| break; | |
| default: | |
| b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, | |
| sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount)); | |
| break; | |
| } | |
| b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
| b_info->bmiHeader.biWidth = desc.dwWidth; | |
| b_info->bmiHeader.biHeight = desc.dwHeight; | |
| b_info->bmiHeader.biPlanes = 1; | |
| b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount; | |
| #if 0 | |
| if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) && | |
| (desc.ddpfPixelFormat.u.dwRGBBitCount != 32)) | |
| #endif | |
| b_info->bmiHeader.biCompression = BI_RGB; | |
| #if 0 | |
| else | |
| b_info->bmiHeader.biCompression = BI_BITFIELDS; | |
| #endif | |
| b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight; | |
| b_info->bmiHeader.biXPelsPerMeter = 0; | |
| b_info->bmiHeader.biYPelsPerMeter = 0; | |
| b_info->bmiHeader.biClrUsed = 0; | |
| b_info->bmiHeader.biClrImportant = 0; | |
| switch (desc.ddpfPixelFormat.u.dwRGBBitCount) { | |
| case 16: | |
| case 32: | |
| #if 0 | |
| { | |
| DWORD *masks = (DWORD *) &(b_info->bmiColors); | |
| usage = 0; | |
| masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask; | |
| masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask; | |
| masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask; | |
| } | |
| break; | |
| #endif | |
| case 24: | |
| /* Nothing to do */ | |
| usage = DIB_RGB_COLORS; | |
| break; | |
| default: { | |
| int i; | |
| /* Fill the palette */ | |
| usage = DIB_RGB_COLORS; | |
| if (This->s.palette == NULL) { | |
| ERR("Bad palette !!!\n"); | |
| } else { | |
| RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors); | |
| PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents); | |
| for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) { | |
| rgb[i].rgbBlue = pent[i].peBlue; | |
| rgb[i].rgbRed = pent[i].peRed; | |
| rgb[i].rgbGreen = pent[i].peGreen; | |
| } | |
| } | |
| } | |
| break; | |
| } | |
| This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps), | |
| b_info, | |
| usage, | |
| &(This->s.bitmap_data), | |
| 0, | |
| 0 | |
| ); | |
| EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps); | |
| TRACE("DIBSection at : %p\n", This->s.bitmap_data); | |
| /* b_info is not useful anymore */ | |
| HeapFree(GetProcessHeap(), 0, b_info); | |
| /* Create the DC */ | |
| This->s.hdc = CreateCompatibleDC(0); | |
| This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection); | |
| } | |
| /* Copy our surface in the DIB section */ | |
| if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch) | |
| memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight); | |
| else | |
| /* TODO */ | |
| FIXME("This case has to be done :/\n"); | |
| TRACE("HDC : %08lx\n", (DWORD) This->s.hdc); | |
| *lphdc = This->s.hdc; | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc); | |
| TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data); | |
| /* Copy the DIB section to our surface */ | |
| if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) { | |
| memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight); | |
| } else { | |
| /* TODO */ | |
| FIXME("This case has to be done :/\n"); | |
| } | |
| /* Unlock the surface */ | |
| IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| TRACE("(%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 ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) || | |
| IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) || | |
| IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) || | |
| IsEqualGUID( &IID_IDirectDrawSurface, refiid ) || | |
| IsEqualGUID( &IID_IUnknown, refiid ) | |
| ) { | |
| *obj = This; | |
| IDirectDrawSurface4_AddRef(iface); | |
| TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) ) | |
| { | |
| /* Texture interface */ | |
| *obj = d3dtexture2_create(This); | |
| IDirectDrawSurface4_AddRef(iface); | |
| TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) ) | |
| { | |
| /* Texture interface */ | |
| *obj = d3dtexture_create(This); | |
| IDirectDrawSurface4_AddRef(iface); | |
| TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) { | |
| /* It is the OpenGL Direct3D Device */ | |
| IDirectDrawSurface4_AddRef(iface); | |
| TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid); | |
| return OLE_E_ENUM_NOMORE; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->(), stub!\n",This); | |
| return DD_OK; /* hmm */ | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| int i; | |
| struct _surface_chain *chain = This->s.chain; | |
| TRACE("(%p)->(%p,%p)\n",This,context,esfcb); | |
| for (i=0;i<chain->nrofsurfaces;i++) { | |
| TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]); | |
| if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL) | |
| return DD_OK; /* FIXME: return value correct? */ | |
| } | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(),stub!\n",This); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey( | |
| LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey); | |
| if (TRACE_ON(ddraw)) { | |
| _dump_colorkeyflag(dwFlags); | |
| DPRINTF(" : "); | |
| _dump_DDCOLORKEY((void *) ckey); | |
| DPRINTF("\n"); | |
| } | |
| /* If this surface was loaded as a texture, call also the texture | |
| SetColorKey callback */ | |
| if (This->s.texture) { | |
| This->s.SetColorKey_cb(This->s.texture, 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("unhandled dwFlags: 0x%08lx\n", dwFlags ); | |
| } | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| LPRECT lpRect ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%p),stub!\n",This,lpRect); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| DWORD dwFlags, | |
| LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| int i; | |
| struct _surface_chain *chain; | |
| TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface); | |
| chain = This->s.chain; | |
| for (i=0;i<chain->nrofsurfaces;i++) { | |
| if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){ | |
| IDirectDrawSurface4_Release(lpDDSAttachedSurface); | |
| chain->surfaces[i]->s.chain = NULL; | |
| memcpy( chain->surfaces+i, | |
| chain->surfaces+(i+1), | |
| (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i]) | |
| ); | |
| chain->surfaces = HeapReAlloc( | |
| GetProcessHeap(), | |
| 0, | |
| chain->surfaces, | |
| sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1) | |
| ); | |
| chain->nrofsurfaces--; | |
| return DD_OK; | |
| } | |
| } | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| DWORD dwFlags, | |
| LPVOID lpContext, | |
| LPDDENUMSURFACESCALLBACK lpfnCallback ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags, | |
| lpContext, lpfnCallback ); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| LPDIRECTDRAWCLIPPER* lplpDDClipper ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| DWORD dwFlags, | |
| LPDDCOLORKEY lpDDColorKey ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%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("unhandled dwFlags: 0x%08lx\n", dwFlags ); | |
| } | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| DWORD dwFlags ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| LPDIRECTDRAWPALETTE* lplpDDPalette ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette); | |
| if (This->s.palette != NULL) { | |
| IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette ); | |
| *lplpDDPalette = (IDirectDrawPalette*) This->s.palette; | |
| return DD_OK; | |
| } else { | |
| return DDERR_NOPALETTEATTACHED; | |
| } | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| LONG lX, | |
| LONG lY) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| LPRECT lpSrcRect, | |
| LPDIRECTDRAWSURFACE4 lpDDDestSurface, | |
| LPRECT lpDestRect, | |
| DWORD dwFlags, | |
| LPDDOVERLAYFX lpDDOverlayFx ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This, | |
| lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx ); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| DWORD dwFlags ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| DWORD dwFlags, | |
| LPDIRECTDRAWSURFACE4 lpDDSReference ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| LPVOID* lplpDD ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%p),stub!\n", This, lplpDD); | |
| /* Not sure about that... */ | |
| *lplpDD = (void *) This->s.ddraw; | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| DWORD dwFlags ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| DWORD dwFlags ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc( | |
| LPDIRECTDRAWSURFACE4 iface, | |
| LPDDSURFACEDESC lpDDSD, | |
| DWORD dwFlags ) | |
| { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface, | |
| REFGUID guidTag, | |
| LPVOID lpData, | |
| DWORD cbSize, | |
| DWORD dwFlags) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface, | |
| REFGUID guidTag, | |
| LPVOID lpBuffer, | |
| LPDWORD lpcbBufferSize) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface, | |
| REFGUID guidTag) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%p)\n", This, guidTag); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface, | |
| LPDWORD lpValue) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)->(%p)\n", This, lpValue); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) { | |
| ICOM_THIS(IDirectDrawSurface4Impl,iface); | |
| FIXME("(%p)\n", This); | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| IDirectDrawSurface4Impl_QueryInterface, | |
| IDirectDrawSurface4Impl_AddRef, | |
| DGA_IDirectDrawSurface4Impl_Release, | |
| IDirectDrawSurface4Impl_AddAttachedSurface, | |
| IDirectDrawSurface4Impl_AddOverlayDirtyRect, | |
| IDirectDrawSurface4Impl_Blt, | |
| IDirectDrawSurface4Impl_BltBatch, | |
| IDirectDrawSurface4Impl_BltFast, | |
| IDirectDrawSurface4Impl_DeleteAttachedSurface, | |
| IDirectDrawSurface4Impl_EnumAttachedSurfaces, | |
| IDirectDrawSurface4Impl_EnumOverlayZOrders, | |
| DGA_IDirectDrawSurface4Impl_Flip, | |
| IDirectDrawSurface4Impl_GetAttachedSurface, | |
| IDirectDrawSurface4Impl_GetBltStatus, | |
| IDirectDrawSurface4Impl_GetCaps, | |
| IDirectDrawSurface4Impl_GetClipper, | |
| IDirectDrawSurface4Impl_GetColorKey, | |
| IDirectDrawSurface4Impl_GetDC, | |
| IDirectDrawSurface4Impl_GetFlipStatus, | |
| IDirectDrawSurface4Impl_GetOverlayPosition, | |
| IDirectDrawSurface4Impl_GetPalette, | |
| IDirectDrawSurface4Impl_GetPixelFormat, | |
| IDirectDrawSurface4Impl_GetSurfaceDesc, | |
| IDirectDrawSurface4Impl_Initialize, | |
| IDirectDrawSurface4Impl_IsLost, | |
| IDirectDrawSurface4Impl_Lock, | |
| IDirectDrawSurface4Impl_ReleaseDC, | |
| IDirectDrawSurface4Impl_Restore, | |
| IDirectDrawSurface4Impl_SetClipper, | |
| IDirectDrawSurface4Impl_SetColorKey, | |
| IDirectDrawSurface4Impl_SetOverlayPosition, | |
| DGA_IDirectDrawSurface4Impl_SetPalette, | |
| DGA_IDirectDrawSurface4Impl_Unlock, | |
| IDirectDrawSurface4Impl_UpdateOverlay, | |
| IDirectDrawSurface4Impl_UpdateOverlayDisplay, | |
| IDirectDrawSurface4Impl_UpdateOverlayZOrder, | |
| IDirectDrawSurface4Impl_GetDDInterface, | |
| IDirectDrawSurface4Impl_PageLock, | |
| IDirectDrawSurface4Impl_PageUnlock, | |
| IDirectDrawSurface4Impl_SetSurfaceDesc, | |
| IDirectDrawSurface4Impl_SetPrivateData, | |
| IDirectDrawSurface4Impl_GetPrivateData, | |
| IDirectDrawSurface4Impl_FreePrivateData, | |
| IDirectDrawSurface4Impl_GetUniquenessValue, | |
| IDirectDrawSurface4Impl_ChangeUniquenessValue | |
| }; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| IDirectDrawSurface4Impl_QueryInterface, | |
| IDirectDrawSurface4Impl_AddRef, | |
| DGA_IDirectDrawSurface4Impl_Release, | |
| IDirectDrawSurface4Impl_AddAttachedSurface, | |
| IDirectDrawSurface4Impl_AddOverlayDirtyRect, | |
| IDirectDrawSurface4Impl_Blt, | |
| IDirectDrawSurface4Impl_BltBatch, | |
| IDirectDrawSurface4Impl_BltFast, | |
| IDirectDrawSurface4Impl_DeleteAttachedSurface, | |
| IDirectDrawSurface4Impl_EnumAttachedSurfaces, | |
| IDirectDrawSurface4Impl_EnumOverlayZOrders, | |
| DGA2_IDirectDrawSurface4Impl_Flip, | |
| IDirectDrawSurface4Impl_GetAttachedSurface, | |
| IDirectDrawSurface4Impl_GetBltStatus, | |
| IDirectDrawSurface4Impl_GetCaps, | |
| IDirectDrawSurface4Impl_GetClipper, | |
| IDirectDrawSurface4Impl_GetColorKey, | |
| IDirectDrawSurface4Impl_GetDC, | |
| IDirectDrawSurface4Impl_GetFlipStatus, | |
| IDirectDrawSurface4Impl_GetOverlayPosition, | |
| IDirectDrawSurface4Impl_GetPalette, | |
| IDirectDrawSurface4Impl_GetPixelFormat, | |
| IDirectDrawSurface4Impl_GetSurfaceDesc, | |
| IDirectDrawSurface4Impl_Initialize, | |
| IDirectDrawSurface4Impl_IsLost, | |
| IDirectDrawSurface4Impl_Lock, | |
| IDirectDrawSurface4Impl_ReleaseDC, | |
| IDirectDrawSurface4Impl_Restore, | |
| IDirectDrawSurface4Impl_SetClipper, | |
| IDirectDrawSurface4Impl_SetColorKey, | |
| IDirectDrawSurface4Impl_SetOverlayPosition, | |
| DGA_IDirectDrawSurface4Impl_SetPalette, | |
| DGA_IDirectDrawSurface4Impl_Unlock, | |
| IDirectDrawSurface4Impl_UpdateOverlay, | |
| IDirectDrawSurface4Impl_UpdateOverlayDisplay, | |
| IDirectDrawSurface4Impl_UpdateOverlayZOrder, | |
| IDirectDrawSurface4Impl_GetDDInterface, | |
| IDirectDrawSurface4Impl_PageLock, | |
| IDirectDrawSurface4Impl_PageUnlock, | |
| IDirectDrawSurface4Impl_SetSurfaceDesc, | |
| IDirectDrawSurface4Impl_SetPrivateData, | |
| IDirectDrawSurface4Impl_GetPrivateData, | |
| IDirectDrawSurface4Impl_FreePrivateData, | |
| IDirectDrawSurface4Impl_GetUniquenessValue, | |
| IDirectDrawSurface4Impl_ChangeUniquenessValue | |
| }; | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| IDirectDrawSurface4Impl_QueryInterface, | |
| IDirectDrawSurface4Impl_AddRef, | |
| Xlib_IDirectDrawSurface4Impl_Release, | |
| IDirectDrawSurface4Impl_AddAttachedSurface, | |
| IDirectDrawSurface4Impl_AddOverlayDirtyRect, | |
| IDirectDrawSurface4Impl_Blt, | |
| IDirectDrawSurface4Impl_BltBatch, | |
| IDirectDrawSurface4Impl_BltFast, | |
| IDirectDrawSurface4Impl_DeleteAttachedSurface, | |
| IDirectDrawSurface4Impl_EnumAttachedSurfaces, | |
| IDirectDrawSurface4Impl_EnumOverlayZOrders, | |
| Xlib_IDirectDrawSurface4Impl_Flip, | |
| IDirectDrawSurface4Impl_GetAttachedSurface, | |
| IDirectDrawSurface4Impl_GetBltStatus, | |
| IDirectDrawSurface4Impl_GetCaps, | |
| IDirectDrawSurface4Impl_GetClipper, | |
| IDirectDrawSurface4Impl_GetColorKey, | |
| IDirectDrawSurface4Impl_GetDC, | |
| IDirectDrawSurface4Impl_GetFlipStatus, | |
| IDirectDrawSurface4Impl_GetOverlayPosition, | |
| IDirectDrawSurface4Impl_GetPalette, | |
| IDirectDrawSurface4Impl_GetPixelFormat, | |
| IDirectDrawSurface4Impl_GetSurfaceDesc, | |
| IDirectDrawSurface4Impl_Initialize, | |
| IDirectDrawSurface4Impl_IsLost, | |
| IDirectDrawSurface4Impl_Lock, | |
| IDirectDrawSurface4Impl_ReleaseDC, | |
| IDirectDrawSurface4Impl_Restore, | |
| IDirectDrawSurface4Impl_SetClipper, | |
| IDirectDrawSurface4Impl_SetColorKey, | |
| IDirectDrawSurface4Impl_SetOverlayPosition, | |
| Xlib_IDirectDrawSurface4Impl_SetPalette, | |
| Xlib_IDirectDrawSurface4Impl_Unlock, | |
| IDirectDrawSurface4Impl_UpdateOverlay, | |
| IDirectDrawSurface4Impl_UpdateOverlayDisplay, | |
| IDirectDrawSurface4Impl_UpdateOverlayZOrder, | |
| IDirectDrawSurface4Impl_GetDDInterface, | |
| IDirectDrawSurface4Impl_PageLock, | |
| IDirectDrawSurface4Impl_PageUnlock, | |
| IDirectDrawSurface4Impl_SetSurfaceDesc, | |
| IDirectDrawSurface4Impl_SetPrivateData, | |
| IDirectDrawSurface4Impl_GetPrivateData, | |
| IDirectDrawSurface4Impl_FreePrivateData, | |
| IDirectDrawSurface4Impl_GetUniquenessValue, | |
| IDirectDrawSurface4Impl_ChangeUniquenessValue | |
| }; | |
| /****************************************************************************** | |
| * DirectDrawCreateClipper (DDRAW.7) | |
| */ | |
| HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags, | |
| LPDIRECTDRAWCLIPPER *lplpDDClipper, | |
| LPUNKNOWN pUnkOuter) | |
| { | |
| IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper; | |
| TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter); | |
| *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl)); | |
| ICOM_VTBL(*ilplpDDClipper) = &ddclipvt; | |
| (*ilplpDDClipper)->ref = 1; | |
| (*ilplpDDClipper)->hWnd = 0; | |
| return DD_OK; | |
| } | |
| /****************************************************************************** | |
| * IDirectDrawClipper | |
| */ | |
| static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd( | |
| LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd | |
| ) { | |
| ICOM_THIS(IDirectDrawClipperImpl,iface); | |
| TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd); | |
| if( dwFlags ) { | |
| FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags); | |
| return DDERR_INVALIDPARAMS; | |
| } | |
| This->hWnd = hWnd; | |
| return DD_OK; | |
| } | |
| static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) { | |
| ICOM_THIS(IDirectDrawClipperImpl,iface); | |
| TRACE("(%p)->() decrementing from %lu.\n", This, This->ref ); | |
| This->ref--; | |
| if (This->ref) | |
| return This->ref; | |
| HeapFree(GetProcessHeap(),0,This); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList( | |
| LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm | |
| ) { | |
| ICOM_THIS(IDirectDrawClipperImpl,iface); | |
| FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm); | |
| if (hmm) *hmm=0; | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList( | |
| LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm | |
| ) { | |
| ICOM_THIS(IDirectDrawClipperImpl,iface); | |
| FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface( | |
| LPDIRECTDRAWCLIPPER iface, | |
| REFIID riid, | |
| LPVOID* ppvObj ) | |
| { | |
| ICOM_THIS(IDirectDrawClipperImpl,iface); | |
| FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj); | |
| return OLE_E_ENUM_NOMORE; | |
| } | |
| static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface ) | |
| { | |
| ICOM_THIS(IDirectDrawClipperImpl,iface); | |
| TRACE("(%p)->() incrementing from %lu.\n", This, This->ref ); | |
| return ++(This->ref); | |
| } | |
| static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd( | |
| LPDIRECTDRAWCLIPPER iface, | |
| HWND* hWndPtr ) | |
| { | |
| ICOM_THIS(IDirectDrawClipperImpl,iface); | |
| FIXME("(%p)->(%p),stub!\n",This,hWndPtr); | |
| *hWndPtr = This->hWnd; | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawClipperImpl_Initialize( | |
| LPDIRECTDRAWCLIPPER iface, | |
| LPDIRECTDRAW lpDD, | |
| DWORD dwFlags ) | |
| { | |
| ICOM_THIS(IDirectDrawClipperImpl,iface); | |
| FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged( | |
| LPDIRECTDRAWCLIPPER iface, | |
| BOOL* lpbChanged ) | |
| { | |
| ICOM_THIS(IDirectDrawClipperImpl,iface); | |
| FIXME("(%p)->(%p),stub!\n",This,lpbChanged); | |
| return DD_OK; | |
| } | |
| static ICOM_VTABLE(IDirectDrawClipper) ddclipvt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| IDirectDrawClipperImpl_QueryInterface, | |
| IDirectDrawClipperImpl_AddRef, | |
| IDirectDrawClipperImpl_Release, | |
| IDirectDrawClipperImpl_GetClipList, | |
| IDirectDrawClipperImpl_GetHWnd, | |
| IDirectDrawClipperImpl_Initialize, | |
| IDirectDrawClipperImpl_IsClipListChanged, | |
| IDirectDrawClipperImpl_SetClipList, | |
| IDirectDrawClipperImpl_SetHwnd | |
| }; | |
| /****************************************************************************** | |
| * IDirectDrawPalette | |
| */ | |
| static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries( | |
| LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent | |
| ) { | |
| ICOM_THIS(IDirectDrawPaletteImpl,iface); | |
| int i; | |
| TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n", | |
| This,x,start,count,palent); | |
| /* No palette created and not in depth-convertion mode -> BUG ! */ | |
| if ((This->cm == None) && | |
| (This->ddraw->d.palette_convert == NULL)) | |
| { | |
| FIXME("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_IDirectDrawPaletteImpl_SetEntries( | |
| LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent | |
| ) { | |
| ICOM_THIS(IDirectDrawPaletteImpl,iface); | |
| XColor xc; | |
| int i; | |
| TRACE("(%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 */ | |
| /* FIXME: we need to update the image or we won't get palette fading. */ | |
| if (This->ddraw->d.palette_convert != NULL) | |
| This->ddraw->d.palette_convert(palent, This->screen_palents, start, count); | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries( | |
| LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent | |
| ) { | |
| ICOM_THIS(IDirectDrawPaletteImpl,iface); | |
| XColor xc; | |
| Colormap cm; | |
| int i; | |
| TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n", | |
| This,x,start,count,palent | |
| ); | |
| if (!This->cm) /* should not happen */ { | |
| FIXME("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; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| if (This->ddraw->e.dga.version == 2) | |
| TSXDGAInstallColormap(display,DefaultScreen(display),This->cm); | |
| else | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm); | |
| return DD_OK; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) { | |
| ICOM_THIS(IDirectDrawPaletteImpl,iface); | |
| TRACE("(%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 S_OK; | |
| } | |
| return This->ref; | |
| } | |
| static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) { | |
| ICOM_THIS(IDirectDrawPaletteImpl,iface); | |
| TRACE("(%p)->() incrementing from %lu.\n", This, This->ref ); | |
| return ++(This->ref); | |
| } | |
| static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize( | |
| LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent | |
| ) { | |
| ICOM_THIS(IDirectDrawPaletteImpl,iface); | |
| TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent); | |
| return DDERR_ALREADYINITIALIZED; | |
| } | |
| static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps( | |
| LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps ) | |
| { | |
| ICOM_THIS(IDirectDrawPaletteImpl,iface); | |
| FIXME("(%p)->(%p) stub.\n", This, lpdwCaps ); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface( | |
| LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj ) | |
| { | |
| ICOM_THIS(IDirectDrawPaletteImpl,iface); | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| FIXME("(%p)->(%s,%p) stub.\n",This,xrefiid,obj); | |
| return S_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| IDirectDrawPaletteImpl_QueryInterface, | |
| IDirectDrawPaletteImpl_AddRef, | |
| IDirectDrawPaletteImpl_Release, | |
| IDirectDrawPaletteImpl_GetCaps, | |
| IDirectDrawPaletteImpl_GetEntries, | |
| IDirectDrawPaletteImpl_Initialize, | |
| DGA_IDirectDrawPaletteImpl_SetEntries | |
| }; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| IDirectDrawPaletteImpl_QueryInterface, | |
| IDirectDrawPaletteImpl_AddRef, | |
| IDirectDrawPaletteImpl_Release, | |
| IDirectDrawPaletteImpl_GetCaps, | |
| IDirectDrawPaletteImpl_GetEntries, | |
| IDirectDrawPaletteImpl_Initialize, | |
| Xlib_IDirectDrawPaletteImpl_SetEntries | |
| }; | |
| /******************************************************************************* | |
| * IDirect3D | |
| */ | |
| static HRESULT WINAPI IDirect3DImpl_QueryInterface( | |
| LPDIRECT3D iface,REFIID refiid,LPVOID *obj | |
| ) { | |
| ICOM_THIS(IDirect3DImpl,iface); | |
| /* FIXME: Not sure if this is correct */ | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj); | |
| if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) || | |
| ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) || | |
| ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) { | |
| *obj = This->ddraw; | |
| IDirect3D_AddRef(iface); | |
| TRACE(" Creating IDirectDrawX interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) || | |
| ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) { | |
| *obj = This; | |
| IDirect3D_AddRef(iface); | |
| TRACE(" Creating IDirect3D interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) { | |
| IDirect3D2Impl* d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = This->ddraw; | |
| IDirect3D_AddRef(iface); | |
| ICOM_VTBL(d3d) = &d3d2vt; | |
| *obj = d3d; | |
| TRACE(" Creating IDirect3D2 interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid); | |
| return OLE_E_ENUM_NOMORE; | |
| } | |
| static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) { | |
| ICOM_THIS(IDirect3DImpl,iface); | |
| TRACE("(%p)->() incrementing from %lu.\n", This, This->ref ); | |
| return ++(This->ref); | |
| } | |
| static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface) | |
| { | |
| ICOM_THIS(IDirect3DImpl,iface); | |
| TRACE("(%p)->() decrementing from %lu.\n", This, This->ref ); | |
| if (!--(This->ref)) { | |
| IDirectDraw2_Release((IDirectDraw2*)This->ddraw); | |
| HeapFree(GetProcessHeap(),0,This); | |
| return S_OK; | |
| } | |
| return This->ref; | |
| } | |
| static HRESULT WINAPI IDirect3DImpl_Initialize( | |
| LPDIRECT3D iface, REFIID refiid ) | |
| { | |
| ICOM_THIS(IDirect3DImpl,iface); | |
| /* FIXME: Not sure if this is correct */ | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| FIXME("(%p)->(%s):stub.\n",This,xrefiid); | |
| return DDERR_ALREADYINITIALIZED; | |
| } | |
| static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface, | |
| LPD3DENUMDEVICESCALLBACK cb, | |
| LPVOID context) { | |
| ICOM_THIS(IDirect3DImpl,iface); | |
| FIXME("(%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 IDirect3DImpl_CreateLight(LPDIRECT3D iface, | |
| LPDIRECT3DLIGHT *lplight, | |
| IUnknown *lpunk) | |
| { | |
| ICOM_THIS(IDirect3DImpl,iface); | |
| TRACE("(%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 IDirect3DImpl_CreateMaterial(LPDIRECT3D iface, | |
| LPDIRECT3DMATERIAL *lpmaterial, | |
| IUnknown *lpunk) | |
| { | |
| ICOM_THIS(IDirect3DImpl,iface); | |
| TRACE("(%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 IDirect3DImpl_CreateViewport(LPDIRECT3D iface, | |
| LPDIRECT3DVIEWPORT *lpviewport, | |
| IUnknown *lpunk) | |
| { | |
| ICOM_THIS(IDirect3DImpl,iface); | |
| TRACE("(%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 IDirect3DImpl_FindDevice(LPDIRECT3D iface, | |
| LPD3DFINDDEVICESEARCH lpfinddevsrc, | |
| LPD3DFINDDEVICERESULT lpfinddevrst) | |
| { | |
| ICOM_THIS(IDirect3DImpl,iface); | |
| TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst); | |
| return DD_OK; | |
| } | |
| static ICOM_VTABLE(IDirect3D) d3dvt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| IDirect3DImpl_QueryInterface, | |
| IDirect3DImpl_AddRef, | |
| IDirect3DImpl_Release, | |
| IDirect3DImpl_Initialize, | |
| IDirect3DImpl_EnumDevices, | |
| IDirect3DImpl_CreateLight, | |
| IDirect3DImpl_CreateMaterial, | |
| IDirect3DImpl_CreateViewport, | |
| IDirect3DImpl_FindDevice | |
| }; | |
| /******************************************************************************* | |
| * IDirect3D2 | |
| */ | |
| static HRESULT WINAPI IDirect3D2Impl_QueryInterface( | |
| LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) { | |
| ICOM_THIS(IDirect3D2Impl,iface); | |
| /* FIXME: Not sure if this is correct */ | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj); | |
| if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) || | |
| ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) || | |
| ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) { | |
| *obj = This->ddraw; | |
| IDirect3D2_AddRef(iface); | |
| TRACE(" Creating IDirectDrawX interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) || | |
| ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) { | |
| *obj = This; | |
| IDirect3D2_AddRef(iface); | |
| TRACE(" Creating IDirect3D2 interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) { | |
| IDirect3DImpl* d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = This->ddraw; | |
| IDirect3D2_AddRef(iface); | |
| ICOM_VTBL(d3d) = &d3dvt; | |
| *obj = d3d; | |
| TRACE(" Creating IDirect3D interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid); | |
| return OLE_E_ENUM_NOMORE; | |
| } | |
| static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) { | |
| ICOM_THIS(IDirect3D2Impl,iface); | |
| TRACE("(%p)->() incrementing from %lu.\n", This, This->ref ); | |
| return ++(This->ref); | |
| } | |
| static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) { | |
| ICOM_THIS(IDirect3D2Impl,iface); | |
| TRACE("(%p)->() decrementing from %lu.\n", This, This->ref ); | |
| if (!--(This->ref)) { | |
| IDirectDraw2_Release((IDirectDraw2*)This->ddraw); | |
| HeapFree(GetProcessHeap(),0,This); | |
| return S_OK; | |
| } | |
| return This->ref; | |
| } | |
| static HRESULT WINAPI IDirect3D2Impl_EnumDevices( | |
| LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context | |
| ) { | |
| ICOM_THIS(IDirect3D2Impl,iface); | |
| FIXME("(%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 IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface, | |
| LPDIRECT3DLIGHT *lplight, | |
| IUnknown *lpunk) | |
| { | |
| ICOM_THIS(IDirect3D2Impl,iface); | |
| TRACE("(%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 IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface, | |
| LPDIRECT3DMATERIAL2 *lpmaterial, | |
| IUnknown *lpunk) | |
| { | |
| ICOM_THIS(IDirect3D2Impl,iface); | |
| TRACE("(%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 IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface, | |
| LPDIRECT3DVIEWPORT2 *lpviewport, | |
| IUnknown *lpunk) | |
| { | |
| ICOM_THIS(IDirect3D2Impl,iface); | |
| TRACE("(%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 IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface, | |
| LPD3DFINDDEVICESEARCH lpfinddevsrc, | |
| LPD3DFINDDEVICERESULT lpfinddevrst) | |
| { | |
| ICOM_THIS(IDirect3D2Impl,iface); | |
| TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface, | |
| REFCLSID rguid, | |
| LPDIRECTDRAWSURFACE surface, | |
| LPDIRECT3DDEVICE2 *device) | |
| { | |
| ICOM_THIS(IDirect3D2Impl,iface); | |
| char xbuf[50]; | |
| WINE_StringFromCLSID(rguid,xbuf); | |
| FIXME("(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device); | |
| if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) { | |
| IDirect3D2_AddRef(iface); | |
| return DD_OK; | |
| } | |
| return DDERR_INVALIDPARAMS; | |
| } | |
| static ICOM_VTABLE(IDirect3D2) d3d2vt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| IDirect3D2Impl_QueryInterface, | |
| IDirect3D2Impl_AddRef, | |
| IDirect3D2Impl_Release, | |
| IDirect3D2Impl_EnumDevices, | |
| IDirect3D2Impl_CreateLight, | |
| IDirect3D2Impl_CreateMaterial, | |
| IDirect3D2Impl_CreateViewport, | |
| IDirect3D2Impl_FindDevice, | |
| IDirect3D2Impl_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(IDirectDraw2Impl* This, | |
| IDirectDrawSurfaceImpl* lpdsf) | |
| { | |
| int bpp; | |
| /* The surface was already allocated when entering in this function */ | |
| TRACE("using system memory for a surface (%p) \n", lpdsf); | |
| if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) { | |
| /* This is a Z Buffer */ | |
| TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth); | |
| bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8; | |
| } else { | |
| /* This is a standard image */ | |
| if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) { | |
| /* No pixel format => use DirectDraw's format */ | |
| lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat; | |
| lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT; | |
| } | |
| bpp = GET_BPP(lpdsf->s.surface_desc); | |
| } | |
| if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) { | |
| /* The surface was preallocated : seems that we have nothing to do :-) */ | |
| ERR("Creates a surface that is already allocated : assuming this is an application bug !\n"); | |
| } | |
| assert(bpp); | |
| FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf->s.surface_desc.dwWidth,lpdsf->s.surface_desc.dwHeight,bpp); | |
| lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE; | |
| lpdsf->s.surface_desc.u1.lpSurface = | |
| (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp); | |
| lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp; | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface( | |
| LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf; | |
| int i, fbheight = This->e.dga.fb_height; | |
| TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk); | |
| if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); } | |
| *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc( | |
| GetProcessHeap(), | |
| HEAP_ZERO_MEMORY, | |
| sizeof(IDirectDrawSurfaceImpl) | |
| ); | |
| IDirectDraw2_AddRef(iface); | |
| (*ilpdsf)->ref = 1; | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| if (This->e.dga.version == 2) | |
| ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt; | |
| else | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt; | |
| (*ilpdsf)->s.ddraw = This; | |
| (*ilpdsf)->s.palette = NULL; | |
| (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */ | |
| (*ilpdsf)->s.lpClipper = NULL; | |
| /* Copy the surface description */ | |
| (*ilpdsf)->s.surface_desc = *lpddsd; | |
| if (!(lpddsd->dwFlags & DDSD_WIDTH)) | |
| (*ilpdsf)->s.surface_desc.dwWidth = This->d.width; | |
| if (!(lpddsd->dwFlags & DDSD_HEIGHT)) | |
| (*ilpdsf)->s.surface_desc.dwHeight = This->d.height; | |
| (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_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 */ | |
| (*ilpdsf)->s.surface_desc = *lpddsd; | |
| /* Find a viewport */ | |
| for (i=0;i<32;i++) | |
| if (!(This->e.dga.vpmask & (1<<i))) | |
| break; | |
| TRACE("using viewport %d for a primary surface\n",i); | |
| /* if i == 32 or maximum ... return error */ | |
| This->e.dga.vpmask|=(1<<i); | |
| lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch = | |
| This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat); | |
| (*ilpdsf)->s.surface_desc.u1.lpSurface = | |
| This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch; | |
| (*ilpdsf)->t.dga.fb_height = i*fbheight; | |
| /* Add flags if there were not present */ | |
| (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT; | |
| (*ilpdsf)->s.surface_desc.dwWidth = This->d.width; | |
| (*ilpdsf)->s.surface_desc.dwHeight = This->d.height; | |
| TRACE("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 */ | |
| SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY; | |
| (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat; | |
| (*ilpdsf)->s.chain = NULL; | |
| if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) { | |
| IDirectDrawSurface4Impl* back; | |
| int bbc; | |
| for (bbc=lpddsd->dwBackBufferCount;bbc--;) { | |
| int i; | |
| back = (IDirectDrawSurface4Impl*)HeapAlloc( | |
| GetProcessHeap(), | |
| HEAP_ZERO_MEMORY, | |
| sizeof(IDirectDrawSurface4Impl) | |
| ); | |
| IDirectDraw2_AddRef(iface); | |
| back->ref = 1; | |
| ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt; | |
| for (i=0;i<32;i++) | |
| if (!(This->e.dga.vpmask & (1<<i))) | |
| break; | |
| TRACE("using viewport %d for backbuffer %d\n",i, bbc); | |
| /* if i == 32 or maximum ... return error */ | |
| This->e.dga.vpmask|=(1<<i); | |
| back->t.dga.fb_height = i*fbheight; | |
| /* Copy the surface description from the front buffer */ | |
| back->s.surface_desc = (*ilpdsf)->s.surface_desc; | |
| /* Change the parameters that are not the same */ | |
| back->s.surface_desc.u1.lpSurface = | |
| This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch; | |
| back->s.ddraw = This; | |
| /* Add relevant info to front and back buffers */ | |
| /* FIXME: backbuffer/frontbuffer handling broken here, but | |
| * will be fixed up in _Flip(). | |
| */ | |
| SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER; | |
| SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY; | |
| back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; | |
| SDDSCAPS(back) &= ~DDSCAPS_VISIBLE; | |
| IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back); | |
| } | |
| } | |
| } else { | |
| /* There is no DGA-specific code here... | |
| Go to the common surface creation function */ | |
| return common_off_screen_CreateSurface(This, *ilpdsf); | |
| } | |
| return DD_OK; | |
| } | |
| #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(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* 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) { | |
| FIXME("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) { | |
| FIXME("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) { | |
| FIXME("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); | |
| FIXME("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.u1.lpSurface = HeapAlloc( | |
| GetProcessHeap(), | |
| HEAP_ZERO_MEMORY, | |
| lpdsf->s.surface_desc.dwWidth * | |
| lpdsf->s.surface_desc.dwHeight * | |
| PFGET_BPP(This->d.directdraw_pixelformat) | |
| ); | |
| } else { | |
| lpdsf->s.surface_desc.u1.lpSurface = img->data; | |
| } | |
| return img; | |
| } | |
| #endif /* HAVE_LIBXXSHM */ | |
| static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* 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.u1.lpSurface = HeapAlloc( | |
| GetProcessHeap(),HEAP_ZERO_MEMORY, | |
| lpdsf->s.surface_desc.dwWidth * | |
| lpdsf->s.surface_desc.dwHeight * | |
| PFGET_BPP(This->d.directdraw_pixelformat) | |
| ); | |
| if (This->d.pixel_convert != NULL) { | |
| img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, | |
| lpdsf->s.surface_desc.dwWidth * | |
| lpdsf->s.surface_desc.dwHeight * | |
| PFGET_BPP(This->d.screen_pixelformat) | |
| ); | |
| } else { | |
| img_data = lpdsf->s.surface_desc.u1.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* PFGET_BPP(This->d.screen_pixelformat) | |
| ); | |
| #ifdef HAVE_LIBXXSHM | |
| } | |
| #endif | |
| if (This->d.pixel_convert != NULL) | |
| lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth; | |
| else | |
| lpdsf->s.surface_desc.lPitch = img->bytes_per_line; | |
| return img; | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface( | |
| LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf; | |
| TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk); | |
| if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); } | |
| *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc( | |
| GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl) | |
| ); | |
| IDirectDraw2_AddRef(iface); | |
| (*ilpdsf)->s.ddraw = This; | |
| (*ilpdsf)->ref = 1; | |
| ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt; | |
| (*ilpdsf)->s.palette = NULL; | |
| (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */ | |
| (*ilpdsf)->s.lpClipper = NULL; | |
| /* Copy the surface description */ | |
| (*ilpdsf)->s.surface_desc = *lpddsd; | |
| if (!(lpddsd->dwFlags & DDSD_WIDTH)) | |
| (*ilpdsf)->s.surface_desc.dwWidth = This->d.width; | |
| if (!(lpddsd->dwFlags & DDSD_HEIGHT)) | |
| (*ilpdsf)->s.surface_desc.dwHeight = This->d.height; | |
| (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT; | |
| /* Check if this a 'primary surface' or not */ | |
| if ((lpddsd->dwFlags & DDSD_CAPS) && | |
| (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) { | |
| XImage *img; | |
| TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf); | |
| /* Create the XImage */ | |
| img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf); | |
| if (img == NULL) | |
| return DDERR_OUTOFMEMORY; | |
| (*ilpdsf)->t.xlib.image = img; | |
| /* Add flags if there were not present */ | |
| (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT; | |
| (*ilpdsf)->s.surface_desc.dwWidth = This->d.width; | |
| (*ilpdsf)->s.surface_desc.dwHeight = This->d.height; | |
| (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY; | |
| (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat; | |
| /* Check for backbuffers */ | |
| if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) { | |
| IDirectDrawSurface4Impl* back; | |
| XImage *img; | |
| int i; | |
| for (i=lpddsd->dwBackBufferCount;i--;) { | |
| back = (IDirectDrawSurface4Impl*)HeapAlloc( | |
| GetProcessHeap(),HEAP_ZERO_MEMORY, | |
| sizeof(IDirectDrawSurface4Impl) | |
| ); | |
| TRACE("allocated back-buffer (%p)\n", back); | |
| IDirectDraw2_AddRef(iface); | |
| back->s.ddraw = This; | |
| back->ref = 1; | |
| ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt; | |
| /* Copy the surface description from the front buffer */ | |
| back->s.surface_desc = (*ilpdsf)->s.surface_desc; | |
| /* Create the XImage */ | |
| img = create_ximage(This, back); | |
| if (img == NULL) | |
| return DDERR_OUTOFMEMORY; | |
| back->t.xlib.image = img; | |
| /* Add relevant info to front and back buffers */ | |
| /* FIXME: backbuffer/frontbuffer handling broken here, but | |
| * will be fixed up in _Flip(). | |
| */ | |
| SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER; | |
| SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP; | |
| back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT; | |
| SDDSCAPS(back) &= ~DDSCAPS_VISIBLE; | |
| IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back); | |
| } | |
| } | |
| } else { | |
| /* There is no Xlib-specific code here... | |
| Go to the common surface creation function */ | |
| return common_off_screen_CreateSurface(This, *ilpdsf); | |
| } | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface( | |
| LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| FIXME("(%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 IDirectDraw2Impl_SetCooperativeLevel( | |
| LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| int i; | |
| const struct { | |
| int mask; | |
| char *name; | |
| } flags[] = { | |
| #define FE(x) { x, #x}, | |
| 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) | |
| #undef FE | |
| }; | |
| FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel); | |
| if (TRACE_ON(ddraw)) { | |
| DPRINTF(" - "); | |
| for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) { | |
| if (flags[i].mask & cooplevel) { | |
| DPRINTF("%s ",flags[i].name); | |
| } | |
| } | |
| DPRINTF("\n"); | |
| } | |
| This->d.mainWindow = hwnd; | |
| /* This will be overwritten in the case of Full Screen mode. | |
| Windowed games could work with that :-) */ | |
| if (hwnd) | |
| { | |
| WND *tmpWnd = WIN_FindWndPtr(hwnd); | |
| This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd); | |
| WIN_ReleaseWndPtr(tmpWnd); | |
| if( !This->d.drawable ) { | |
| This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window; | |
| WIN_ReleaseDesktop(); | |
| } | |
| TRACE("Setting drawable to %ld\n", This->d.drawable); | |
| } | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel( | |
| LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| HRESULT ret; | |
| int evbase, erbase; | |
| ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel); | |
| if (This->e.dga.version != 2) { | |
| return ret; | |
| } else { | |
| if (ret != DD_OK) | |
| return ret; | |
| TSXDGAQueryExtension(display, &evbase, &erbase); | |
| /* Now, start handling of DGA events giving the handle to the DDraw window | |
| as the window for which the event will be reported */ | |
| TSXDGASelectInput(display, DefaultScreen(display), | |
| KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask ); | |
| X11DRV_EVENT_SetDGAStatus(hwnd, evbase); | |
| return DD_OK; | |
| } | |
| } | |
| #endif | |
| /* 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_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* 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) | |
| ) { | |
| /* if it does not fit, resize the cooperative window. | |
| * and hope the app likes it | |
| */ | |
| 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; | |
| /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/ | |
| } | |
| /* ... 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; | |
| int index = -2; | |
| vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals); | |
| pf = XListPixmapFormats(display, &npixmap); | |
| for (i = 0; i < npixmap; i++) { | |
| if (pf[i].depth == 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->u1.dwRBitMask = 0; | |
| pixelformat->u2.dwGBitMask = 0; | |
| pixelformat->u3.dwBBitMask = 0; | |
| } else { | |
| pixelformat->dwFlags = DDPF_RGB; | |
| pixelformat->u1.dwRBitMask = vi[j].red_mask; | |
| pixelformat->u2.dwGBitMask = vi[j].green_mask; | |
| pixelformat->u3.dwBBitMask = vi[j].blue_mask; | |
| } | |
| pixelformat->dwFourCC = 0; | |
| pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel; | |
| pixelformat->u4.dwRGBAlphaBitMask= 0; | |
| *screen_pixelformat = *pixelformat; | |
| if (pix_depth != NULL) | |
| *pix_depth = vi[j].depth; | |
| match = 1; | |
| index = -1; | |
| goto clean_up_and_exit; | |
| } | |
| } | |
| ERR("No visual corresponding to pixmap format !\n"); | |
| } | |
| } | |
| if (match == 0) { | |
| /* We try now to find an emulated mode */ | |
| int c; | |
| for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) { | |
| if (ModeEmulations[c].dest.depth == depth) { | |
| /* Found an emulation function, now tries to find a matching visual / pixel format pair */ | |
| for (i = 0; i < npixmap; i++) { | |
| if ((pf[i].depth == ModeEmulations[c].screen.depth) && | |
| (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) { | |
| 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->u.dwRGBBitCount = pf[i].bits_per_pixel; | |
| screen_pixelformat->u1.dwRBitMask = vi[j].red_mask; | |
| screen_pixelformat->u2.dwGBitMask = vi[j].green_mask; | |
| screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask; | |
| screen_pixelformat->u4.dwRGBAlphaBitMask= 0; | |
| pixelformat->dwSize = sizeof(*pixelformat); | |
| pixelformat->dwFourCC = 0; | |
| if (depth == 8) { | |
| pixelformat->dwFlags = DDPF_PALETTEINDEXED8; | |
| pixelformat->u.dwRGBBitCount = 8; | |
| pixelformat->u1.dwRBitMask = 0; | |
| pixelformat->u2.dwGBitMask = 0; | |
| pixelformat->u3.dwBBitMask = 0; | |
| } else { | |
| pixelformat->dwFlags = DDPF_RGB; | |
| pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp; | |
| pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask; | |
| pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask; | |
| pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask; | |
| } | |
| pixelformat->u4.dwRGBAlphaBitMask= 0; | |
| if (pix_depth != NULL) | |
| *pix_depth = vi[j].depth; | |
| match = 2; | |
| index = c; | |
| goto clean_up_and_exit; | |
| } | |
| ERR("No visual corresponding to pixmap format !\n"); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| clean_up_and_exit: | |
| TSXFree(vi); | |
| TSXFree(pf); | |
| return index; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode( | |
| LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth | |
| ) { | |
| ICOM_THIS(IDirectDrawImpl,iface); | |
| int i,mode_count; | |
| TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth); | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| if (This->e.dga.version == 2) | |
| /* For the moment, we suppose we have the correct display settings when in DGA 2.0 mode */ | |
| return DD_OK; | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| /* 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("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth); | |
| return DDERR_UNSUPPORTEDMODE; | |
| } | |
| if (This->d.width < width) { | |
| ERR("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_IDirectDrawImpl_SetDisplayMode(This); | |
| #ifdef HAVE_LIBXXF86VM | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */ | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| { | |
| 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("Fullscreen mode not available!\n"); | |
| if (vidmode) | |
| { | |
| TRACE("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); | |
| TSXF86DGASetViewPort(display,DefaultScreen(display),0,0); | |
| #ifdef RESTORE_SIGNALS | |
| SIGNAL_Init(); | |
| #endif | |
| return DD_OK; | |
| } | |
| #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, IDirectDrawPaletteImpl* palette) { | |
| unsigned char *c_src = (unsigned char *) src; | |
| unsigned short *c_dst = (unsigned short *) dst; | |
| int y; | |
| if (palette != NULL) { | |
| const unsigned short * pal = (unsigned short *) palette->screen_palents; | |
| for (y = height; y--; ) { | |
| #if defined(__i386__) && defined(__GNUC__) | |
| /* gcc generates slightly inefficient code for the the copy / lookup, | |
| * it generates one excess memory access (to pal) per pixel. Since | |
| * we know that pal is not modified by the memory write we can | |
| * put it into a register and reduce the number of memory accesses | |
| * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls. | |
| * (This is not guaranteed to be the fastest method.) | |
| */ | |
| __asm__ __volatile__( | |
| "xor %%eax,%%eax\n" | |
| "1:\n" | |
| " lodsb\n" | |
| " movw (%%edx,%%eax,2),%%ax\n" | |
| " stosw\n" | |
| " xor %%eax,%%eax\n" | |
| " loop 1b\n" | |
| : "=S" (c_src), "=D" (c_dst) | |
| : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal) | |
| : "eax", "cc", "memory" | |
| ); | |
| c_src+=(pitch-width); | |
| #else | |
| unsigned char * srclineend = c_src+width; | |
| while (c_src < srclineend) | |
| *c_dst++ = pal[*c_src++]; | |
| c_src+=(pitch-width); | |
| #endif | |
| } | |
| } else { | |
| WARN("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 to palettized 8 bpp | |
| ************************************* */ | |
| static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) { | |
| unsigned char *c_src = (unsigned char *) src; | |
| unsigned char *c_dst = (unsigned char *) dst; | |
| int y; | |
| if (palette != NULL) { | |
| const unsigned int *pal = (unsigned int *) palette->screen_palents; | |
| for (y = height; y--; ) { | |
| unsigned char * srclineend = c_src+width; | |
| while (c_src < srclineend ) { | |
| register long pixel = pal[*c_src++]; | |
| *c_dst++ = pixel; | |
| *c_dst++ = pixel>>8; | |
| *c_dst++ = pixel>>16; | |
| } | |
| c_src+=(pitch-width); | |
| } | |
| } else { | |
| WARN("No palette set...\n"); | |
| memset(dst, 0, width * height * 4); | |
| } | |
| } | |
| /* ************************************* | |
| 32 bpp to palettized 8 bpp | |
| ************************************* */ | |
| static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) { | |
| unsigned char *c_src = (unsigned char *) src; | |
| unsigned int *c_dst = (unsigned int *) dst; | |
| int y; | |
| if (palette != NULL) { | |
| const unsigned int *pal = (unsigned int *) palette->screen_palents; | |
| for (y = height; y--; ) { | |
| #if defined(__i386__) && defined(__GNUC__) | |
| /* See comment in pixel_convert_16_to_8 */ | |
| __asm__ __volatile__( | |
| "xor %%eax,%%eax\n" | |
| "1:\n" | |
| " lodsb\n" | |
| " movl (%%edx,%%eax,4),%%eax\n" | |
| " stosl\n" | |
| " xor %%eax,%%eax\n" | |
| " loop 1b\n" | |
| : "=S" (c_src), "=D" (c_dst) | |
| : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal) | |
| : "eax", "cc", "memory" | |
| ); | |
| c_src+=(pitch-width); | |
| #else | |
| unsigned char * srclineend = c_src+width; | |
| while (c_src < srclineend ) | |
| *c_dst++ = pal[*c_src++]; | |
| c_src+=(pitch-width); | |
| #endif | |
| } | |
| } else { | |
| WARN("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)); | |
| } | |
| /* ************************************* | |
| 32 bpp to 16 bpp | |
| ************************************* */ | |
| static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) { | |
| unsigned short *c_src = (unsigned short *) src; | |
| unsigned int *c_dst = (unsigned int *) dst; | |
| int y; | |
| for (y = height; y--; ) { | |
| unsigned short * srclineend = c_src+width; | |
| while (c_src < srclineend ) { | |
| *c_dst++ = (((*c_src & 0xF800) << 8) | | |
| ((*c_src & 0x07E0) << 5) | | |
| ((*c_src & 0x001F) << 3)); | |
| c_src++; | |
| } | |
| c_src+=((pitch/2)-width); | |
| } | |
| } | |
| static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode( | |
| LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth | |
| ) { | |
| ICOM_THIS(IDirectDrawImpl,iface); | |
| char buf[200]; | |
| WND *tmpWnd; | |
| int c; | |
| TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n", | |
| This, width, height, depth); | |
| switch ((c = _common_depth_to_pixelformat(depth, | |
| &(This->d.directdraw_pixelformat), | |
| &(This->d.screen_pixelformat), | |
| &(This->d.pixmap_depth)))) { | |
| case -2: | |
| 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; | |
| default: | |
| WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth); | |
| /* Set the depth convertion routines */ | |
| This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert; | |
| This->d.palette_convert = ModeEmulations[c].funcs.palette_convert; | |
| } | |
| This->d.width = width; | |
| This->d.height = height; | |
| _common_IDirectDrawImpl_SetDisplayMode(This); | |
| tmpWnd = WIN_FindWndPtr(This->d.window); | |
| This->d.paintable = 1; | |
| This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window; | |
| WIN_ReleaseWndPtr(tmpWnd); | |
| /* 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; | |
| WIN_ReleaseDesktop(); | |
| } | |
| TRACE("Setting drawable to %ld\n", This->d.drawable); | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps( | |
| LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2 | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2); | |
| if (!caps1 && !caps2) | |
| return DDERR_INVALIDPARAMS; | |
| if (caps1) { | |
| 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; | |
| } | |
| #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 | DDCAPS_NOHARDWARE; | |
| 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_IDirectDraw2Impl_GetCaps( | |
| LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2 | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%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 IDirectDraw2Impl_CreateClipper( | |
| LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip; | |
| FIXME("(%p)->(%08lx,%p,%p),stub!\n", | |
| This,x,ilpddclip,lpunk | |
| ); | |
| *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl)); | |
| (*ilpddclip)->ref = 1; | |
| ICOM_VTBL(*ilpddclip) = &ddclipvt; | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette( | |
| IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize | |
| ) { | |
| int size = 0; | |
| if (TRACE_ON(ddraw)) | |
| _dump_paletteformat(dwFlags); | |
| *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl)); | |
| if (*lpddpal == NULL) return E_OUTOFMEMORY; | |
| (*lpddpal)->ref = 1; | |
| (*lpddpal)->ddraw = (IDirectDrawImpl*)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("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; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette( | |
| LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal; | |
| HRESULT res; | |
| int xsize = 0,i; | |
| TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk); | |
| res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize); | |
| if (res != 0) return res; | |
| ICOM_VTBL(*ilpddpal) = &dga_ddpalvt; | |
| if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) { | |
| (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll); | |
| } else { | |
| FIXME("why are we doing CreatePalette in hi/truecolor?\n"); | |
| (*ilpddpal)->cm = 0; | |
| } | |
| if (((*ilpddpal)->cm)&&xsize) { | |
| for (i=0;i<xsize;i++) { | |
| XColor xc; | |
| xc.red = (*ilpddpal)->palents[i].peRed<<8; | |
| xc.blue = (*ilpddpal)->palents[i].peBlue<<8; | |
| xc.green = (*ilpddpal)->palents[i].peGreen<<8; | |
| xc.flags = DoRed|DoBlue|DoGreen; | |
| xc.pixel = i; | |
| TSXStoreColor(display,(*ilpddpal)->cm,&xc); | |
| } | |
| } | |
| return DD_OK; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette( | |
| LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal; | |
| int xsize; | |
| HRESULT res; | |
| TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk); | |
| res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize); | |
| if (res != 0) return res; | |
| ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt; | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->()\n",This); | |
| Sleep(1000); | |
| TSXF86DGADirectVideo(display,DefaultScreen(display),0); | |
| #ifdef RESTORE_SIGNALS | |
| SIGNAL_Init(); | |
| #endif | |
| return DD_OK; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->RestoreDisplayMode()\n", This); | |
| Sleep(1000); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank( | |
| LPDIRECTDRAW2 iface,DWORD x,HANDLE h | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h); | |
| return DD_OK; | |
| } | |
| static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->() incrementing from %lu.\n", This, This->ref ); | |
| return ++(This->ref); | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->() decrementing from %lu.\n", This, This->ref ); | |
| if (!--(This->ref)) { | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| if (This->e.dga.version == 2) { | |
| TRACE("Closing access to the FrameBuffer\n"); | |
| TSXDGACloseFramebuffer(display, DefaultScreen(display)); | |
| TRACE("Going back to normal X mode of operation\n"); | |
| TSXDGASetMode(display, DefaultScreen(display), 0); | |
| /* Set the input handling back to absolute */ | |
| X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE); | |
| /* Remove the handling of DGA2 events */ | |
| X11DRV_EVENT_SetDGAStatus(0, -1); | |
| } else | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| 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_Init(); | |
| #endif | |
| HeapFree(GetProcessHeap(),0,This); | |
| return S_OK; | |
| } | |
| return This->ref; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%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 S_OK; | |
| } | |
| /* FIXME: destroy window ... */ | |
| return This->ref; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface( | |
| LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj); | |
| if ( IsEqualGUID( &IID_IUnknown, refiid ) ) { | |
| *obj = This; | |
| IDirectDraw2_AddRef(iface); | |
| TRACE(" Creating IUnknown interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) { | |
| ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt; | |
| IDirectDraw2_AddRef(iface); | |
| *obj = This; | |
| TRACE(" Creating IDirectDraw interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) { | |
| ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt; | |
| IDirectDraw2_AddRef(iface); | |
| *obj = This; | |
| TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) { | |
| ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt; | |
| IDirectDraw2_AddRef(iface); | |
| *obj = This; | |
| TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) { | |
| IDirect3DImpl* d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = (IDirectDrawImpl*)This; | |
| IDirectDraw2_AddRef(iface); | |
| ICOM_VTBL(d3d) = &d3dvt; | |
| *obj = d3d; | |
| TRACE(" Creating IDirect3D interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) { | |
| IDirect3D2Impl* d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = (IDirectDrawImpl*)This; | |
| IDirectDraw2_AddRef(iface); | |
| ICOM_VTBL(d3d) = &d3d2vt; | |
| *obj = d3d; | |
| TRACE(" Creating IDirect3D2 interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid); | |
| return OLE_E_ENUM_NOMORE; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface( | |
| LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| char xrefiid[50]; | |
| WINE_StringFromCLSID((LPCLSID)refiid,xrefiid); | |
| TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj); | |
| if ( IsEqualGUID( &IID_IUnknown, refiid ) ) { | |
| *obj = This; | |
| IDirectDraw2_AddRef(iface); | |
| TRACE(" Creating IUnknown interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) { | |
| ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt; | |
| IDirectDraw2_AddRef(iface); | |
| *obj = This; | |
| TRACE(" Creating IDirectDraw interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) { | |
| ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt; | |
| IDirectDraw2_AddRef(iface); | |
| *obj = This; | |
| TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) { | |
| ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt; | |
| IDirectDraw2_AddRef(iface); | |
| *obj = This; | |
| TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) { | |
| IDirect3DImpl* d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = (IDirectDrawImpl*)This; | |
| IDirectDraw2_AddRef(iface); | |
| ICOM_VTBL(d3d) = &d3dvt; | |
| *obj = d3d; | |
| TRACE(" Creating IDirect3D interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) { | |
| IDirect3D2Impl* d3d; | |
| d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d)); | |
| d3d->ref = 1; | |
| d3d->ddraw = (IDirectDrawImpl*)This; | |
| IDirectDraw2_AddRef(iface); | |
| ICOM_VTBL(d3d) = &d3d2vt; | |
| *obj = d3d; | |
| TRACE(" Creating IDirect3D2 interface (%p)\n", *obj); | |
| return S_OK; | |
| } | |
| WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid); | |
| return OLE_E_ENUM_NOMORE; | |
| } | |
| static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus( | |
| LPDIRECTDRAW2 iface,BOOL *status | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->(%p)\n",This,status); | |
| *status = TRUE; | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes( | |
| LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| 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("(%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.u.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.u.dwRGBBitCount = depths[i]; | |
| /* FIXME: those masks would have to be set in depth > 8 */ | |
| if (depths[i]==8) { | |
| ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0; | |
| ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0; | |
| ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0; | |
| ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0; | |
| ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE; | |
| ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8; | |
| } else { | |
| ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0; | |
| /* FIXME: We should query those from X itself */ | |
| switch (depths[i]) { | |
| case 16: | |
| ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800; | |
| ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0; | |
| ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F; | |
| break; | |
| case 24: | |
| ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000; | |
| ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00; | |
| ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF; | |
| break; | |
| case 32: | |
| ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000; | |
| ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00; | |
| ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF; | |
| break; | |
| } | |
| } | |
| ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor); | |
| ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); | |
| TRACE(" 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(" 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(" enumerating (320x200x%d)\n",depths[i]); | |
| if (!modescb(&ddsfd,context)) return DD_OK; | |
| } | |
| } | |
| return DD_OK; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes( | |
| LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| XVisualInfo *vi; | |
| XPixmapFormatValues *pf; | |
| XVisualInfo vt; | |
| int nvisuals, npixmap, i, emu; | |
| int has_mode[] = { 0, 0, 0, 0 }; | |
| int has_depth[] = { 8, 15, 16, 24 }; | |
| 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("(%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.u.dwRefreshRate = 60; | |
| } | |
| maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor); | |
| maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); | |
| vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals); | |
| pf = XListPixmapFormats(display, &npixmap); | |
| i = 0; | |
| emu = 0; | |
| while ((i < npixmap) || | |
| (emu != 4)) { | |
| int mode_index = 0; | |
| int send_mode = 0; | |
| int j; | |
| if (i < npixmap) { | |
| for (j = 0; j < 4; j++) { | |
| if (has_depth[j] == pf[i].depth) { | |
| mode_index = j; | |
| break; | |
| } | |
| } | |
| if (j == 4) { | |
| i++; | |
| continue; | |
| } | |
| if (has_mode[mode_index] == 0) { | |
| if (mode_index == 0) { | |
| 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.u.dwRGBBitCount = 8; | |
| ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0; | |
| ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0; | |
| ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0; | |
| ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0; | |
| has_mode[mode_index] = 1; | |
| } else { | |
| /* 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.u.dwRGBBitCount = pf[i].bits_per_pixel; | |
| ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask; | |
| ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask; | |
| ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask; | |
| ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0; | |
| send_mode = 1; | |
| has_mode[mode_index] = 1; | |
| break; | |
| } | |
| } | |
| if (j == nvisuals) | |
| ERR("Did not find visual corresponding the the pixmap format !\n"); | |
| } | |
| } | |
| i++; | |
| } else { | |
| /* Now to emulated modes */ | |
| if (has_mode[emu] == 0) { | |
| int c; | |
| int l; | |
| int depth = has_depth[emu]; | |
| for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) { | |
| if (ModeEmulations[c].dest.depth == depth) { | |
| /* Found an emulation function, now tries to find a matching visual / pixel format pair */ | |
| for (l = 0; (l < npixmap) && (send_mode == 0); l++) { | |
| if ((pf[l].depth == ModeEmulations[c].screen.depth) && | |
| (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) { | |
| int j; | |
| for (j = 0; (j < nvisuals) && (send_mode == 0); j++) { | |
| if ((vi[j].depth == pf[l].depth) && | |
| (vi[j].red_mask == ModeEmulations[c].screen.rmask) && | |
| (vi[j].green_mask == ModeEmulations[c].screen.gmask) && | |
| (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) { | |
| ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat); | |
| ddsfd.ddpfPixelFormat.dwFourCC = 0; | |
| if (depth == 8) { | |
| ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8; | |
| ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8; | |
| ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0; | |
| ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0; | |
| ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0; | |
| } else { | |
| ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB; | |
| ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp; | |
| ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask; | |
| ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask; | |
| ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask; | |
| } | |
| ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0; | |
| send_mode = 1; | |
| } | |
| if (send_mode == 0) | |
| ERR("No visual corresponding to pixmap format !\n"); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| emu++; | |
| } | |
| if (send_mode) { | |
| int mode; | |
| if (TRACE_ON(ddraw)) { | |
| TRACE("Enumerating with pixel format : \n"); | |
| _dump_pixelformat(&(ddsfd.ddpfPixelFormat)); | |
| DPRINTF("\n"); | |
| } | |
| 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(" - 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; | |
| } | |
| } | |
| } | |
| exit_enum: | |
| TSXFree(vi); | |
| TSXFree(pf); | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode( | |
| LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->(%p)\n",This,lpddsfd); | |
| lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS; | |
| lpddsfd->dwHeight = This->d.height; | |
| lpddsfd->dwWidth = This->d.width; | |
| lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat); | |
| lpddsfd->dwBackBufferCount = 1; | |
| lpddsfd->u.dwRefreshRate = 60; | |
| lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE; | |
| lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat; | |
| if (TRACE_ON(ddraw)) { | |
| _dump_surface_desc(lpddsfd); | |
| } | |
| return DD_OK; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode( | |
| LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd); | |
| lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS; | |
| lpddsfd->dwHeight = This->d.height; | |
| lpddsfd->dwWidth = This->d.width; | |
| lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat); | |
| lpddsfd->dwBackBufferCount = 1; | |
| lpddsfd->u.dwRefreshRate = 60; | |
| lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE; | |
| lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat; | |
| if (TRACE_ON(ddraw)) { | |
| _dump_surface_desc(lpddsfd); | |
| } | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->()\n",This); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency( | |
| LPDIRECTDRAW2 iface,LPDWORD freq | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| FIXME("(%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 IDirectDraw2Impl_GetFourCCCodes( | |
| LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| FIXME("(%p,%p,%p), stub\n",This,x,y); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces( | |
| LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2Impl_Compact( | |
| LPDIRECTDRAW2 iface ) | |
| { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| FIXME("(%p)->()\n", This ); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface, | |
| LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface, | |
| LPDWORD lpdwScanLine) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| FIXME("(%p)->(%p)\n", This, lpdwScanLine); | |
| if (lpdwScanLine) | |
| *lpdwScanLine = 0; | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface, | |
| GUID *lpGUID) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| FIXME("(%p)->(%p)\n", This, lpGUID); | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| /* Note: Hack so we can reuse the old functions without compiler warnings */ | |
| #if !defined(__STRICT_ANSI__) && defined(__GNUC__) | |
| # define XCAST(fun) (typeof(dga_ddvt.fn##fun)) | |
| #else | |
| # define XCAST(fun) (void *) | |
| #endif | |
| static ICOM_VTABLE(IDirectDraw) dga_ddvt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface, | |
| XCAST(AddRef)IDirectDraw2Impl_AddRef, | |
| XCAST(Release)DGA_IDirectDraw2Impl_Release, | |
| XCAST(Compact)IDirectDraw2Impl_Compact, | |
| XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper, | |
| XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette, | |
| XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface, | |
| XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface, | |
| XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes, | |
| XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces, | |
| XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface, | |
| XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps, | |
| XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode, | |
| XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes, | |
| XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface, | |
| XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency, | |
| XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine, | |
| XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus, | |
| XCAST(Initialize)IDirectDraw2Impl_Initialize, | |
| XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode, | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel, | |
| #else | |
| XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel, | |
| #endif | |
| DGA_IDirectDrawImpl_SetDisplayMode, | |
| XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank, | |
| }; | |
| #undef XCAST | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| /* Note: Hack so we can reuse the old functions without compiler warnings */ | |
| #if !defined(__STRICT_ANSI__) && defined(__GNUC__) | |
| # define XCAST(fun) (typeof(xlib_ddvt.fn##fun)) | |
| #else | |
| # define XCAST(fun) (void *) | |
| #endif | |
| static ICOM_VTABLE(IDirectDraw) xlib_ddvt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface, | |
| XCAST(AddRef)IDirectDraw2Impl_AddRef, | |
| XCAST(Release)Xlib_IDirectDraw2Impl_Release, | |
| XCAST(Compact)IDirectDraw2Impl_Compact, | |
| XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper, | |
| XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette, | |
| XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface, | |
| XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface, | |
| XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes, | |
| XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces, | |
| XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface, | |
| XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps, | |
| XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode, | |
| XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes, | |
| XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface, | |
| XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency, | |
| XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine, | |
| XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus, | |
| XCAST(Initialize)IDirectDraw2Impl_Initialize, | |
| XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode, | |
| XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel, | |
| Xlib_IDirectDrawImpl_SetDisplayMode, | |
| XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank, | |
| }; | |
| #undef XCAST | |
| /***************************************************************************** | |
| * IDirectDraw2 | |
| * | |
| */ | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode( | |
| LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags | |
| ) { | |
| FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags ); | |
| return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth); | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode( | |
| LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags | |
| ) { | |
| FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags ); | |
| return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth); | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem( | |
| LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%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; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem( | |
| LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free | |
| ) { | |
| ICOM_THIS(IDirectDraw2Impl,iface); | |
| TRACE("(%p)->(%p,%p,%p)\n", | |
| This,ddscaps,total,free | |
| ); | |
| if (total) *total = 2048 * 1024; | |
| if (free) *free = 2048 * 1024; | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| static ICOM_VTABLE(IDirectDraw2) dga_dd2vt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| DGA_IDirectDraw2Impl_QueryInterface, | |
| IDirectDraw2Impl_AddRef, | |
| DGA_IDirectDraw2Impl_Release, | |
| IDirectDraw2Impl_Compact, | |
| IDirectDraw2Impl_CreateClipper, | |
| DGA_IDirectDraw2Impl_CreatePalette, | |
| DGA_IDirectDraw2Impl_CreateSurface, | |
| IDirectDraw2Impl_DuplicateSurface, | |
| DGA_IDirectDraw2Impl_EnumDisplayModes, | |
| IDirectDraw2Impl_EnumSurfaces, | |
| IDirectDraw2Impl_FlipToGDISurface, | |
| DGA_IDirectDraw2Impl_GetCaps, | |
| DGA_IDirectDraw2Impl_GetDisplayMode, | |
| IDirectDraw2Impl_GetFourCCCodes, | |
| IDirectDraw2Impl_GetGDISurface, | |
| IDirectDraw2Impl_GetMonitorFrequency, | |
| IDirectDraw2Impl_GetScanLine, | |
| IDirectDraw2Impl_GetVerticalBlankStatus, | |
| IDirectDraw2Impl_Initialize, | |
| DGA_IDirectDraw2Impl_RestoreDisplayMode, | |
| IDirectDraw2Impl_SetCooperativeLevel, | |
| DGA_IDirectDraw2Impl_SetDisplayMode, | |
| IDirectDraw2Impl_WaitForVerticalBlank, | |
| DGA_IDirectDraw2Impl_GetAvailableVidMem | |
| }; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| Xlib_IDirectDraw2Impl_QueryInterface, | |
| IDirectDraw2Impl_AddRef, | |
| Xlib_IDirectDraw2Impl_Release, | |
| IDirectDraw2Impl_Compact, | |
| IDirectDraw2Impl_CreateClipper, | |
| Xlib_IDirectDraw2Impl_CreatePalette, | |
| Xlib_IDirectDraw2Impl_CreateSurface, | |
| IDirectDraw2Impl_DuplicateSurface, | |
| Xlib_IDirectDraw2Impl_EnumDisplayModes, | |
| IDirectDraw2Impl_EnumSurfaces, | |
| IDirectDraw2Impl_FlipToGDISurface, | |
| Xlib_IDirectDraw2Impl_GetCaps, | |
| Xlib_IDirectDraw2Impl_GetDisplayMode, | |
| IDirectDraw2Impl_GetFourCCCodes, | |
| IDirectDraw2Impl_GetGDISurface, | |
| IDirectDraw2Impl_GetMonitorFrequency, | |
| IDirectDraw2Impl_GetScanLine, | |
| IDirectDraw2Impl_GetVerticalBlankStatus, | |
| IDirectDraw2Impl_Initialize, | |
| Xlib_IDirectDraw2Impl_RestoreDisplayMode, | |
| IDirectDraw2Impl_SetCooperativeLevel, | |
| Xlib_IDirectDraw2Impl_SetDisplayMode, | |
| IDirectDraw2Impl_WaitForVerticalBlank, | |
| Xlib_IDirectDraw2Impl_GetAvailableVidMem | |
| }; | |
| /***************************************************************************** | |
| * IDirectDraw4 | |
| * | |
| */ | |
| static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface, | |
| HDC hdc, | |
| LPDIRECTDRAWSURFACE *lpDDS) { | |
| ICOM_THIS(IDirectDraw4Impl,iface); | |
| FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) { | |
| ICOM_THIS(IDirectDraw4Impl,iface); | |
| FIXME("(%p)->()\n", This); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) { | |
| ICOM_THIS(IDirectDraw4Impl,iface); | |
| FIXME("(%p)->()\n", This); | |
| return DD_OK; | |
| } | |
| static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface, | |
| LPDDDEVICEIDENTIFIER lpdddi, | |
| DWORD dwFlags) { | |
| ICOM_THIS(IDirectDraw4Impl,iface); | |
| FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags); | |
| return DD_OK; | |
| } | |
| #ifdef HAVE_LIBXXF86DGA | |
| #if !defined(__STRICT_ANSI__) && defined(__GNUC__) | |
| # define XCAST(fun) (typeof(dga_dd4vt.fn##fun)) | |
| #else | |
| # define XCAST(fun) (void*) | |
| #endif | |
| static ICOM_VTABLE(IDirectDraw4) dga_dd4vt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface, | |
| XCAST(AddRef)IDirectDraw2Impl_AddRef, | |
| XCAST(Release)DGA_IDirectDraw2Impl_Release, | |
| XCAST(Compact)IDirectDraw2Impl_Compact, | |
| XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper, | |
| XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette, | |
| XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface, | |
| XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface, | |
| XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes, | |
| XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces, | |
| XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface, | |
| XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps, | |
| XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode, | |
| XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes, | |
| XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface, | |
| XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency, | |
| XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine, | |
| XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus, | |
| XCAST(Initialize)IDirectDraw2Impl_Initialize, | |
| XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode, | |
| XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel, | |
| XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode, | |
| XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank, | |
| XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem, | |
| IDirectDraw4Impl_GetSurfaceFromDC, | |
| IDirectDraw4Impl_RestoreAllSurfaces, | |
| IDirectDraw4Impl_TestCooperativeLevel, | |
| IDirectDraw4Impl_GetDeviceIdentifier | |
| }; | |
| #undef XCAST | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| #if !defined(__STRICT_ANSI__) && defined(__GNUC__) | |
| # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun)) | |
| #else | |
| # define XCAST(fun) (void*) | |
| #endif | |
| static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface, | |
| XCAST(AddRef)IDirectDraw2Impl_AddRef, | |
| XCAST(Release)Xlib_IDirectDraw2Impl_Release, | |
| XCAST(Compact)IDirectDraw2Impl_Compact, | |
| XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper, | |
| XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette, | |
| XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface, | |
| XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface, | |
| XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes, | |
| XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces, | |
| XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface, | |
| XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps, | |
| XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode, | |
| XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes, | |
| XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface, | |
| XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency, | |
| XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine, | |
| XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus, | |
| XCAST(Initialize)IDirectDraw2Impl_Initialize, | |
| XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode, | |
| XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel, | |
| XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode, | |
| XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank, | |
| XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem, | |
| IDirectDraw4Impl_GetSurfaceFromDC, | |
| IDirectDraw4Impl_RestoreAllSurfaces, | |
| IDirectDraw4Impl_TestCooperativeLevel, | |
| IDirectDraw4Impl_GetDeviceIdentifier | |
| }; | |
| #undef XCAST | |
| /****************************************************************************** | |
| * DirectDrawCreate | |
| */ | |
| static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) | |
| { | |
| LRESULT ret; | |
| IDirectDrawImpl* 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 = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset ); | |
| if( (!ddraw) && | |
| ( ( lastError = GetLastError() ) != ERROR_SUCCESS ) | |
| ) | |
| { | |
| ERR("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 ) | |
| { | |
| WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow); | |
| /* We didn't handle the message - give it to the application */ | |
| if (ddraw && ddraw->d.mainWindow && tmpWnd) | |
| { | |
| ret = CallWindowProcA(tmpWnd->winproc, | |
| ddraw->d.mainWindow, msg, wParam, lParam ); | |
| } | |
| WIN_ReleaseWndPtr(tmpWnd); | |
| } | |
| } else { | |
| ret = DefWindowProcA(hwnd, msg, wParam, lParam ); | |
| } | |
| } | |
| else | |
| { | |
| ret = DefWindowProcA(hwnd,msg,wParam,lParam); | |
| } | |
| return ret; | |
| } | |
| static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) { | |
| #ifdef HAVE_LIBXXF86DGA | |
| IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD; | |
| int memsize,banksize,major,minor,flags; | |
| char *addr; | |
| int depth; | |
| int dga_version; | |
| int width, height; | |
| /* Get DGA availability / version */ | |
| dga_version = DDRAW_DGA_Available(); | |
| if (dga_version == 0) { | |
| MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP); | |
| return DDERR_GENERIC; | |
| } | |
| *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl)); | |
| (*ilplpDD)->ref = 1; | |
| ICOM_VTBL(*ilplpDD) = &dga_ddvt; | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| if (dga_version == 1) { | |
| (*ilplpDD)->e.dga.version = 1; | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| TSXF86DGAQueryVersion(display,&major,&minor); | |
| TRACE("XF86DGA is version %d.%d\n",major,minor); | |
| TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags); | |
| if (!(flags & XF86DGADirectPresent)) | |
| MESSAGE("direct video is NOT PRESENT.\n"); | |
| TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize); | |
| (*ilplpDD)->e.dga.fb_width = width; | |
| TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height); | |
| TSXF86DGASetViewPort(display,DefaultScreen(display),0,0); | |
| (*ilplpDD)->e.dga.fb_height = height; | |
| TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n", | |
| addr,width,banksize,memsize | |
| ); | |
| TRACE("viewport height: %d\n",height); | |
| /* Get the screen dimensions as seen by Wine. | |
| In that case, it may be better to ignore the -desktop mode and return the | |
| real screen size => print a warning */ | |
| (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); | |
| (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor); | |
| if (((*ilplpDD)->d.height != height) || | |
| ((*ilplpDD)->d.width != width)) | |
| WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n"); | |
| (*ilplpDD)->e.dga.fb_addr = addr; | |
| (*ilplpDD)->e.dga.fb_memsize = memsize; | |
| (*ilplpDD)->e.dga.vpmask = 0; | |
| /* just assume the default depth is the DGA depth too */ | |
| depth = DefaultDepthOfScreen(X11DRV_GetXScreen()); | |
| _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL); | |
| #ifdef RESTORE_SIGNALS | |
| SIGNAL_Init(); | |
| #endif | |
| #ifdef HAVE_LIBXXF86DGA2 | |
| } else { | |
| DDPIXELFORMAT *pf = &((*ilplpDD)->d.directdraw_pixelformat); | |
| XDGAMode *modes; | |
| int i, num_modes; | |
| int mode_to_use = 0; | |
| (*ilplpDD)->e.dga.version = 2; | |
| TSXDGAQueryVersion(display,&major,&minor); | |
| TRACE("XDGA is version %d.%d\n",major,minor); | |
| TRACE("Opening the frame buffer.\n"); | |
| if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) { | |
| ERR("Error opening the frame buffer !!!\n"); | |
| return DDERR_GENERIC; | |
| } | |
| /* List all available modes */ | |
| modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes); | |
| if (TRACE_ON(ddraw)) { | |
| TRACE("Available modes :\n"); | |
| for (i = 0; i < num_modes; i++) { | |
| DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -", | |
| modes[i].num, | |
| modes[i].name, modes[i].imageWidth, modes[i].imageHeight, | |
| modes[i].viewportWidth, modes[i].viewportHeight, | |
| modes[i].depth); | |
| if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess "); | |
| if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect "); | |
| if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect "); | |
| if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect "); | |
| if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap "); | |
| DPRINTF("\n"); | |
| if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) && | |
| (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) && | |
| (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) { | |
| mode_to_use = modes[i].num; | |
| } | |
| } | |
| } | |
| if (mode_to_use == 0) { | |
| ERR("Could not find mode !\n"); | |
| mode_to_use = 1; | |
| } else { | |
| DPRINTF("Using mode number %d\n", mode_to_use); | |
| } | |
| /* Now, get the device / mode description */ | |
| (*ilplpDD)->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode_to_use); | |
| /* Set the input handling for relative mouse movements */ | |
| X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE); | |
| (*ilplpDD)->e.dga.fb_width = (*ilplpDD)->e.dga.dev->mode.imageWidth; | |
| TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate); | |
| (*ilplpDD)->e.dga.fb_height = (*ilplpDD)->e.dga.dev->mode.viewportHeight; | |
| TRACE("video framebuffer: begin %p, width %d, memsize %d\n", | |
| (*ilplpDD)->e.dga.dev->data, | |
| (*ilplpDD)->e.dga.dev->mode.imageWidth, | |
| ((*ilplpDD)->e.dga.dev->mode.imageWidth * | |
| (*ilplpDD)->e.dga.dev->mode.imageHeight * | |
| ((*ilplpDD)->e.dga.dev->mode.bitsPerPixel / 8)) | |
| ); | |
| TRACE("viewport height: %d\n", (*ilplpDD)->e.dga.dev->mode.viewportHeight); | |
| /* Get the screen dimensions as seen by Wine. | |
| In that case, it may be better to ignore the -desktop mode and return the | |
| real screen size => print a warning */ | |
| (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); | |
| (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor); | |
| (*ilplpDD)->e.dga.fb_addr = (*ilplpDD)->e.dga.dev->data; | |
| (*ilplpDD)->e.dga.fb_memsize = ((*ilplpDD)->e.dga.dev->mode.imageWidth * | |
| (*ilplpDD)->e.dga.dev->mode.imageHeight * | |
| ((*ilplpDD)->e.dga.dev->mode.bitsPerPixel / 8)); | |
| (*ilplpDD)->e.dga.vpmask = 0; | |
| /* Fill the screen pixelformat */ | |
| if ((*ilplpDD)->e.dga.dev->mode.depth == 8) { | |
| pf->dwFlags = DDPF_PALETTEINDEXED8; | |
| pf->u1.dwRBitMask = 0; | |
| pf->u2.dwGBitMask = 0; | |
| pf->u3.dwBBitMask = 0; | |
| } else { | |
| pf->dwFlags = DDPF_RGB; | |
| pf->u1.dwRBitMask = (*ilplpDD)->e.dga.dev->mode.redMask; | |
| pf->u2.dwGBitMask = (*ilplpDD)->e.dga.dev->mode.greenMask; | |
| pf->u3.dwBBitMask = (*ilplpDD)->e.dga.dev->mode.blueMask; | |
| } | |
| pf->dwFourCC = 0; | |
| pf->u.dwRGBBitCount = (*ilplpDD)->e.dga.dev->mode.bitsPerPixel; | |
| pf->u4.dwRGBAlphaBitMask= 0; | |
| (*ilplpDD)->d.screen_pixelformat = *pf; | |
| } | |
| #endif /* defined(HAVE_LIBXXF86DGA2) */ | |
| return DD_OK; | |
| #else /* defined(HAVE_LIBXXF86DGA) */ | |
| return DDERR_INVALIDDIRECTDRAWGUID; | |
| #endif /* defined(HAVE_LIBXXF86DGA) */ | |
| } | |
| static BOOL | |
| DDRAW_XSHM_Available(void) | |
| { | |
| #ifdef HAVE_LIBXXSHM | |
| if (TSXShmQueryExtension(display)) | |
| { | |
| int major, minor; | |
| Bool shpix; | |
| if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) && | |
| (Options.noXSHM != 1)) | |
| return 1; | |
| else | |
| return 0; | |
| } | |
| else | |
| return 0; | |
| #else | |
| return 0; | |
| #endif | |
| } | |
| static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) { | |
| IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD; | |
| int depth; | |
| *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl)); | |
| ICOM_VTBL(*ilplpDD) = &xlib_ddvt; | |
| (*ilplpDD)->ref = 1; | |
| (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */ | |
| /* At DirectDraw creation, the depth is the default depth */ | |
| depth = DefaultDepthOfScreen(X11DRV_GetXScreen()); | |
| _common_depth_to_pixelformat(depth, | |
| &((*ilplpDD)->d.directdraw_pixelformat), | |
| &((*ilplpDD)->d.screen_pixelformat), | |
| &((*ilplpDD)->d.pixmap_depth)); | |
| (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor); | |
| (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor); | |
| #ifdef HAVE_LIBXXSHM | |
| /* Test if XShm is available. */ | |
| if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) { | |
| (*ilplpDD)->e.xlib.xshm_compl = 0; | |
| TRACE("Using XShm extension.\n"); | |
| } | |
| #endif | |
| return DD_OK; | |
| } | |
| HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) { | |
| IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD; | |
| 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("(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter); | |
| if ( ( !lpGUID ) || | |
| ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) || | |
| ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) || | |
| ( IsEqualGUID( &IID_IDirectDraw4, 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 */ | |
| /* | |
| This code is not useful since hInstance is forced to 0 afterward | |
| 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 ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) { | |
| ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter); | |
| } | |
| else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) { | |
| ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter); | |
| } | |
| else { | |
| goto err; | |
| } | |
| (*ilplpDD)->d.winclass = RegisterClassA(&wc); | |
| return ret; | |
| err: | |
| ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter); | |
| return DDERR_INVALIDDIRECTDRAWGUID; | |
| } | |
| /******************************************************************************* | |
| * DirectDraw ClassFactory | |
| * | |
| * Heavily inspired (well, can you say completely copied :-) ) from DirectSound | |
| * | |
| */ | |
| typedef struct | |
| { | |
| /* IUnknown fields */ | |
| ICOM_VFIELD(IClassFactory); | |
| DWORD ref; | |
| } IClassFactoryImpl; | |
| static HRESULT WINAPI | |
| DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { | |
| ICOM_THIS(IClassFactoryImpl,iface); | |
| char buf[80]; | |
| if (HIWORD(riid)) | |
| WINE_StringFromCLSID(riid,buf); | |
| else | |
| sprintf(buf,"<guid-0x%04x>",LOWORD(riid)); | |
| FIXME("(%p)->(%s,%p),stub!\n",This,buf,ppobj); | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI | |
| DDCF_AddRef(LPCLASSFACTORY iface) { | |
| ICOM_THIS(IClassFactoryImpl,iface); | |
| return ++(This->ref); | |
| } | |
| static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) { | |
| ICOM_THIS(IClassFactoryImpl,iface); | |
| /* static class, won't be freed */ | |
| return --(This->ref); | |
| } | |
| static HRESULT WINAPI DDCF_CreateInstance( | |
| LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj | |
| ) { | |
| ICOM_THIS(IClassFactoryImpl,iface); | |
| char buf[80]; | |
| WINE_StringFromCLSID(riid,buf); | |
| TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj); | |
| if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) || | |
| ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) || | |
| ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) { | |
| /* FIXME: reuse already created DirectDraw if present? */ | |
| return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter); | |
| } | |
| return CLASS_E_CLASSNOTAVAILABLE; | |
| } | |
| static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { | |
| ICOM_THIS(IClassFactoryImpl,iface); | |
| FIXME("(%p)->(%d),stub!\n",This,dolock); | |
| return S_OK; | |
| } | |
| static ICOM_VTABLE(IClassFactory) DDCF_Vtbl = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| DDCF_QueryInterface, | |
| DDCF_AddRef, | |
| DDCF_Release, | |
| DDCF_CreateInstance, | |
| DDCF_LockServer | |
| }; | |
| static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 }; | |
| /******************************************************************************* | |
| * DllGetClassObject [DDRAW.13] | |
| * Retrieves class object from a DLL object | |
| * | |
| * NOTES | |
| * Docs say returns STDAPI | |
| * | |
| * PARAMS | |
| * rclsid [I] CLSID for the class object | |
| * riid [I] Reference to identifier of interface for class object | |
| * ppv [O] Address of variable to receive interface pointer for riid | |
| * | |
| * RETURNS | |
| * Success: S_OK | |
| * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG, | |
| * E_UNEXPECTED | |
| */ | |
| DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv) | |
| { | |
| char buf[80],xbuf[80]; | |
| if (HIWORD(rclsid)) | |
| WINE_StringFromCLSID(rclsid,xbuf); | |
| else | |
| sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid)); | |
| if (HIWORD(riid)) | |
| WINE_StringFromCLSID(riid,buf); | |
| else | |
| sprintf(buf,"<guid-0x%04x>",LOWORD(riid)); | |
| WINE_StringFromCLSID(riid,xbuf); | |
| TRACE("(%p,%p,%p)\n", xbuf, buf, ppv); | |
| if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) { | |
| *ppv = (LPVOID)&DDRAW_CF; | |
| IClassFactory_AddRef((IClassFactory*)*ppv); | |
| return S_OK; | |
| } | |
| FIXME("(%p,%p,%p): no interface found.\n", xbuf, buf, ppv); | |
| return CLASS_E_CLASSNOTAVAILABLE; | |
| } | |
| /******************************************************************************* | |
| * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use. | |
| * | |
| * RETURNS | |
| * Success: S_OK | |
| * Failure: S_FALSE | |
| */ | |
| DWORD WINAPI DDRAW_DllCanUnloadNow(void) | |
| { | |
| FIXME("(void): stub\n"); | |
| return S_FALSE; | |
| } | |
| #else /* !defined(X_DISPLAY_MISSING) */ | |
| #include "windef.h" | |
| #include "wtypes.h" | |
| #define DD_OK 0 | |
| 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; | |
| } | |
| DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) | |
| { | |
| return CLASS_E_CLASSNOTAVAILABLE; | |
| } | |
| DWORD WINAPI DDRAW_DllCanUnloadNow(void) | |
| { | |
| return DD_OK; | |
| } | |
| #endif /* !defined(X_DISPLAY_MISSING) */ | |