diff --git a/abi_used_libs b/abi_used_libs --- a/abi_used_libs +++ b/abi_used_libs @@ -1,7 +1,5 @@ -libEGL.so.1 -libGL.so.1 +libFAudio.so.0 libOpenCL.so.1 -libX11-xcb.so.1 libX11.so.6 libXext.so.6 libasound.so.2 @@ -22,9 +20,5 @@ libresolv.so.2 libudev.so.1 libvkd3d.so.1 -libxcb-dri3.so.0 -libxcb-present.so.0 -libxcb-xfixes.so.0 -libxcb.so.1 libxml2.so.2 libz.so.1 diff --git a/abi_used_libs32 b/abi_used_libs32 --- a/abi_used_libs32 +++ b/abi_used_libs32 @@ -1,7 +1,5 @@ -libEGL.so.1 -libGL.so.1 +libFAudio.so.0 libOpenCL.so.1 -libX11-xcb.so.1 libX11.so.6 libXext.so.6 libasound.so.2 @@ -21,9 +19,5 @@ libresolv.so.2 libudev.so.1 libvkd3d.so.1 -libxcb-dri3.so.0 -libxcb-present.so.0 -libxcb-xfixes.so.0 -libxcb.so.1 libxml2.so.2 libz.so.1 diff --git a/files/d3d9-helper.patch b/files/d3d9-helper.patch deleted file mode 100644 --- a/files/d3d9-helper.patch +++ /dev/null @@ -1,1029 +0,0 @@ -From 6c098bfed3f441e9b3a15ca82d52a3327fd2eb77 Mon Sep 17 00:00:00 2001 -From: Nick Sarnie -Date: Wed, 23 Jan 2019 21:23:56 -0500 -Subject: [PATCH] D3D9 Helper - -Signed-off-by: Nick Sarnie ---- - dlls/ntdll/loader.c | 205 ++++++++++++++++++++---- - dlls/ntdll/loadorder.c | 298 ++++++++++++++++++++++++++--------- - dlls/ntdll/ntdll_misc.h | 1 + - programs/winecfg/Makefile.in | 1 + - programs/winecfg/main.c | 12 +- - programs/winecfg/resource.h | 5 + - programs/winecfg/staging.c | 93 +++++++++++ - programs/winecfg/winecfg.h | 1 + - programs/winecfg/winecfg.rc | 10 ++ - 9 files changed, 522 insertions(+), 104 deletions(-) - create mode 100644 programs/winecfg/staging.c - -diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c -index 631e8bd998..72c0dd4b2a 100644 ---- a/dlls/ntdll/loader.c -+++ b/dlls/ntdll/loader.c -@@ -110,6 +110,7 @@ struct builtin_load_info - { - const WCHAR *load_path; - const WCHAR *filename; -+ const WCHAR *fakemodule; - NTSTATUS status; - WINE_MODREF *wm; - }; -@@ -134,7 +135,8 @@ static WINE_MODREF *cached_modref; - static WINE_MODREF *current_modref; - static WINE_MODREF *last_failed_modref; - --static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_MODREF** pwm ); -+static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, LPCWSTR fakemodule, -+ DWORD flags, WINE_MODREF** pwm ); - static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved ); - static FARPROC find_ordinal_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports, - DWORD exp_size, DWORD ordinal, LPCWSTR load_path ); -@@ -510,7 +512,7 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS - if (!(wm = find_basename_module( mod_name ))) - { - TRACE( "delay loading %s for '%s'\n", debugstr_w(mod_name), forward ); -- if (load_dll( load_path, mod_name, 0, &wm ) == STATUS_SUCCESS && -+ if (load_dll( load_path, mod_name, NULL, 0, &wm ) == STATUS_SUCCESS && - !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) - { - if (!imports_fixup_done && current_modref) -@@ -681,7 +683,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP - { - ascii_to_unicode( buffer, name, len ); - buffer[len] = 0; -- status = load_dll( load_path, buffer, 0, &wmImp ); -+ status = load_dll( load_path, buffer, NULL, 0, &wmImp ); - } - else /* need to allocate a larger buffer */ - { -@@ -689,7 +691,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP - if (!ptr) return FALSE; - ascii_to_unicode( ptr, name, len ); - ptr[len] = 0; -- status = load_dll( load_path, ptr, 0, &wmImp ); -+ status = load_dll( load_path, ptr, NULL, 0, &wmImp ); - RtlFreeHeap( GetProcessHeap(), 0, ptr ); - } - -@@ -975,7 +977,7 @@ static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void * - - prev = current_modref; - current_modref = wm; -- if (!(status = load_dll( load_path, mscoreeW, 0, &imp ))) wm->deps[0] = imp; -+ if (!(status = load_dll( load_path, mscoreeW, NULL, 0, &imp ))) wm->deps[0] = imp; - current_modref = prev; - if (status) - { -@@ -1063,7 +1065,7 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path ) - * Allocate a WINE_MODREF structure and add it to the process list - * The loader_section must be locked while calling this function. - */ --static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename ) -+static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename, LPCWSTR fakemodule ) - { - WINE_MODREF *wm; - const WCHAR *p; -@@ -1077,7 +1079,7 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename ) - wm->ldr.TlsIndex = -1; - wm->ldr.LoadCount = 1; - -- RtlCreateUnicodeString( &wm->ldr.FullDllName, filename ); -+ RtlCreateUnicodeString( &wm->ldr.FullDllName, fakemodule ? fakemodule : filename ); - if ((p = strrchrW( wm->ldr.FullDllName.Buffer, '\\' ))) p++; - else p = wm->ldr.FullDllName.Buffer; - RtlInitUnicodeString( &wm->ldr.BaseDllName, p ); -@@ -1744,7 +1746,7 @@ static void load_builtin_callback( void *module, const char *filename ) - return; - } - -- wm = alloc_module( module, fullname ); -+ wm = alloc_module( module, fullname, builtin_load_info->fakemodule ); - RtlFreeHeap( GetProcessHeap(), 0, fullname ); - if (!wm) - { -@@ -1995,8 +1997,8 @@ static BOOL is_valid_binary( HMODULE module, const pe_image_info_t *info ) - /****************************************************************************** - * load_native_dll (internal) - */ --static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file, -- DWORD flags, WINE_MODREF** pwm, struct stat *st ) -+static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, LPCWSTR fakemodule, -+ HANDLE file, DWORD flags, WINE_MODREF** pwm, struct stat *st ) - { - void *module; - HANDLE mapping; -@@ -2039,7 +2041,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file, - - /* create the MODREF */ - -- if (!(wm = alloc_module( module, name ))) -+ if (!(wm = alloc_module( module, name, fakemodule ))) - { - if (module) NtUnmapViewOfSection( NtCurrentProcess(), module ); - return STATUS_NO_MEMORY; -@@ -2107,8 +2109,8 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, LPCWSTR name, HANDLE file, - /*********************************************************************** - * load_builtin_dll - */ --static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, HANDLE file, -- DWORD flags, WINE_MODREF** pwm ) -+static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, LPCWSTR fakemodule, -+ HANDLE file, DWORD flags, WINE_MODREF** pwm ) - { - char error[256], dllname[MAX_PATH]; - const WCHAR *name, *p; -@@ -2128,6 +2130,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, HANDLE file, - */ - info.load_path = load_path; - info.filename = NULL; -+ info.fakemodule = fakemodule; - info.status = STATUS_SUCCESS; - info.wm = NULL; - -@@ -2326,6 +2329,108 @@ done: - return status; - } - -+#if defined(__i386__) -+#define CURRENT_ARCH IMAGE_FILE_MACHINE_I386 -+#elif defined(__x86_64__) -+#define CURRENT_ARCH IMAGE_FILE_MACHINE_AMD64 -+#elif defined(__arm__) -+#define CURRENT_ARCH IMAGE_FILE_MACHINE_ARM -+#elif defined(__aarch64__) -+#define CURRENT_ARCH IMAGE_FILE_MACHINE_ARM64 -+#endif -+ -+/*********************************************************************** -+ * get_machine_type (internal) -+ * -+ * Determines the machine type of a module. Based on the code in -+ * dlls/kernel32/module.c. -+ */ -+static WORD get_machine_type( HANDLE hfile ) -+{ -+ union -+ { -+ struct -+ { -+ unsigned char magic[4]; -+ unsigned char class; -+ unsigned char data; -+ unsigned char version; -+ unsigned char ignored[9]; -+ unsigned short type; -+ unsigned short machine; -+ } elf; -+ struct -+ { -+ unsigned int magic; -+ unsigned int cputype; -+ unsigned int cpusubtype; -+ unsigned int filetype; -+ } macho; -+ IMAGE_DOS_HEADER mz; -+ } header; -+ -+ IO_STATUS_BLOCK io; -+ LARGE_INTEGER offset; -+ -+ /* Seek to the start of the file and read the header information. */ -+ offset.QuadPart = 0; -+ if (NtReadFile( hfile, 0, NULL, 0, &io, &header, sizeof(header), &offset, NULL )) return 0; -+ if (io.Information < sizeof(header)) return 0; -+ -+ if (!memcmp( header.elf.magic, "\177ELF", 4 )) -+ { -+#ifdef WORDS_BIGENDIAN -+ if (header.elf.data == 1) -+#else -+ if (header.elf.data == 2) -+#endif -+ { -+ header.elf.machine = RtlUshortByteSwap( header.elf.machine ); -+ } -+ -+ switch(header.elf.machine) -+ { -+ case 3: return IMAGE_FILE_MACHINE_I386; -+ case 20: return IMAGE_FILE_MACHINE_POWERPC; -+ case 40: return IMAGE_FILE_MACHINE_ARMNT; -+ case 50: return IMAGE_FILE_MACHINE_IA64; -+ case 62: return IMAGE_FILE_MACHINE_AMD64; -+ case 183: return IMAGE_FILE_MACHINE_ARM64; -+ default: return 0; -+ } -+ } -+ /* Mach-o File with Endian set to Big Endian or Little Endian */ -+ else if (header.macho.magic == 0xfeedface || header.macho.magic == 0xcefaedfe || -+ header.macho.magic == 0xfeedfacf || header.macho.magic == 0xcffaedfe) -+ { -+ if (header.macho.magic == 0xcefaedfe || header.macho.magic == 0xcffaedfe) -+ header.macho.cputype = RtlUlongByteSwap( header.macho.cputype ); -+ -+ switch(header.macho.cputype) -+ { -+ case 0x00000007: return IMAGE_FILE_MACHINE_I386; -+ case 0x01000007: return IMAGE_FILE_MACHINE_AMD64; -+ case 0x0000000c: return IMAGE_FILE_MACHINE_ARMNT; -+ case 0x0100000c: return IMAGE_FILE_MACHINE_ARM64; -+ case 0x00000012: return IMAGE_FILE_MACHINE_POWERPC; -+ default: return 0; -+ } -+ } -+ /* Not ELF, try DOS */ -+ else if (header.mz.e_magic == IMAGE_DOS_SIGNATURE) -+ { -+ IMAGE_NT_HEADERS32 ext_header; -+ -+ offset.QuadPart = header.mz.e_lfanew; -+ if (NtReadFile( hfile, 0, NULL, 0, &io, &ext_header, sizeof(ext_header), &offset, NULL )) return 0; -+ if (io.Information < sizeof(ext_header)) return 0; -+ -+ if (!memcmp( &ext_header.Signature, "PE\0\0", 4 )) -+ return ext_header.FileHeader.Machine; -+ } -+ -+ return 0; -+} - - /*********************************************************************** - * open_dll_file -@@ -2372,7 +2477,7 @@ static HANDLE open_dll_file( UNICODE_STRING *nt_name, WINE_MODREF **pwm, struct - */ - static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, - WCHAR *filename, ULONG *size, WINE_MODREF **pwm, -- HANDLE *handle, struct stat *st ) -+ HANDLE *handle, struct stat *st, BOOL check_arch ) - { - UNICODE_STRING nt_name; - WCHAR *file_part, *ext, *dllname; -@@ -2417,20 +2522,41 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, - - if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH) - { -- /* we need to search for it */ -- len = RtlDosSearchPath_U( load_path, libname, NULL, *size, filename, &file_part ); -- if (len) -+ while (load_path) - { -+ /* we need to search for it */ -+ len = RtlDosSearchPath_U( load_path, libname, NULL, *size, filename, &file_part ); -+ if (!len) break; -+ - if (len >= *size) goto overflow; - if ((*pwm = find_fullname_module( filename ))) goto found; -+ if (!handle) goto next; - - if (!RtlDosPathNameToNtPathName_U( filename, &nt_name, NULL, NULL )) - { - RtlFreeHeap( GetProcessHeap(), 0, dllname ); - return STATUS_NO_MEMORY; - } -+ - *handle = open_dll_file( &nt_name, pwm, st ); -- goto found; -+ -+ #ifdef CURRENT_ARCH -+ if (*handle && check_arch) -+ { -+ WORD machine_type = get_machine_type( *handle ); -+ if (machine_type && machine_type != CURRENT_ARCH) -+ { -+ FIXME( "skipping %s because of wrong architecture\n", debugstr_w(filename) ); -+ NtClose( *handle ); -+ *handle = 0; -+ } -+ } -+ #endif -+ if (*handle) goto found; -+ -+ next: -+ load_path = strchrW(load_path, ';'); -+ if (load_path) load_path++; - } - - /* not found */ -@@ -2478,8 +2604,10 @@ overflow: - * Load a PE style module according to the load order. - * The loader_section must be locked while calling this function. - */ --static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_MODREF** pwm ) -+static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, LPCWSTR fakemodule, -+ DWORD flags, WINE_MODREF** pwm ) - { -+ BOOL data = flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE); - enum loadorder loadorder; - WCHAR buffer[64]; - WCHAR *filename; -@@ -2496,7 +2624,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_ - size = sizeof(buffer); - for (;;) - { -- nts = find_dll_file( load_path, libname, filename, &size, pwm, &handle, &st ); -+ nts = find_dll_file( load_path, libname, filename, &size, pwm, &handle, &st, !data ); - if (nts == STATUS_SUCCESS) break; - if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename ); - if (nts != STATUS_BUFFER_TOO_SMALL) return nts; -@@ -2516,6 +2644,25 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_ - } - - main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress ); -+ -+ /* handle dll redirection */ -+ if (!fakemodule) -+ { -+ BYTE buffer2[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + MAX_PATH * sizeof(WCHAR)]; -+ WCHAR *redirect = get_redirect( main_exe ? main_exe->ldr.BaseDllName.Buffer : NULL, -+ filename, buffer2, sizeof(buffer2) ); -+ if (redirect) -+ { -+ FIXME("Loader redirect from %s to %s\n", debugstr_w(libname), debugstr_w(redirect)); -+ -+ nts = load_dll( load_path, redirect, filename, flags, pwm ); -+ -+ if (handle) NtClose( handle ); -+ if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename ); -+ return nts; -+ } -+ } -+ - loadorder = get_load_order( main_exe ? main_exe->ldr.BaseDllName.Buffer : NULL, filename ); - - if (handle && is_fake_dll( handle )) -@@ -2538,22 +2685,22 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_ - if (!handle) nts = STATUS_DLL_NOT_FOUND; - else - { -- nts = load_native_dll( load_path, filename, handle, flags, pwm, &st ); -+ nts = load_native_dll( load_path, filename, fakemodule, handle, flags, pwm, &st ); - if (nts == STATUS_INVALID_IMAGE_NOT_MZ) - /* not in PE format, maybe it's a builtin */ -- nts = load_builtin_dll( load_path, filename, handle, flags, pwm ); -+ nts = load_builtin_dll( load_path, filename, fakemodule, handle, flags, pwm ); - } - if (nts == STATUS_DLL_NOT_FOUND && loadorder == LO_NATIVE_BUILTIN) -- nts = load_builtin_dll( load_path, filename, 0, flags, pwm ); -+ nts = load_builtin_dll( load_path, filename, fakemodule, 0, flags, pwm ); - break; - case LO_BUILTIN: - case LO_BUILTIN_NATIVE: - case LO_DEFAULT: /* default is builtin,native */ -- nts = load_builtin_dll( load_path, filename, handle, flags, pwm ); -+ nts = load_builtin_dll( load_path, filename, fakemodule, handle, flags, pwm ); - if (!handle) break; /* nothing else we can try */ - /* file is not a builtin library, try without using the specified file */ - if (nts != STATUS_SUCCESS) -- nts = load_builtin_dll( load_path, filename, 0, flags, pwm ); -+ nts = load_builtin_dll( load_path, filename, fakemodule, 0, flags, pwm ); - if (nts == STATUS_SUCCESS && loadorder == LO_DEFAULT && - (MODULE_InitDLL( *pwm, DLL_WINE_PREATTACH, NULL ) != STATUS_SUCCESS)) - { -@@ -2563,7 +2710,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_ - nts = STATUS_DLL_NOT_FOUND; - } - if (nts == STATUS_DLL_NOT_FOUND && loadorder != LO_BUILTIN) -- nts = load_native_dll( load_path, filename, handle, flags, pwm, &st ); -+ nts = load_native_dll( load_path, filename, fakemodule, handle, flags, pwm, &st ); - break; - } - -@@ -2596,7 +2743,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags, - RtlEnterCriticalSection( &loader_section ); - - if (!path_name) path_name = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer; -- nts = load_dll( path_name, libname->Buffer, flags, &wm ); -+ nts = load_dll( path_name, libname->Buffer, NULL, flags, &wm ); - - if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) - { -@@ -2635,7 +2782,7 @@ NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_S - size = sizeof(buffer); - for (;;) - { -- status = find_dll_file( load_path, name->Buffer, filename, &size, &wm, &handle, &st ); -+ status = find_dll_file( load_path, name->Buffer, filename, &size, &wm, &handle, &st, TRUE ); - if (handle) NtClose( handle ); - if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename ); - if (status != STATUS_BUFFER_TOO_SMALL) break; -@@ -3570,7 +3717,7 @@ void __wine_process_init(void) - /* setup the load callback and create ntdll modref */ - wine_dll_set_callback( load_builtin_callback ); - -- if ((status = load_builtin_dll( NULL, kernel32W, 0, 0, &wm )) != STATUS_SUCCESS) -+ if ((status = load_builtin_dll( NULL, kernel32W, NULL, 0, 0, &wm )) != STATUS_SUCCESS) - { - MESSAGE( "wine: could not load kernel32.dll, status %x\n", status ); - exit(1); -diff --git a/dlls/ntdll/loadorder.c b/dlls/ntdll/loadorder.c -index c6c0245931..c247a50380 100644 ---- a/dlls/ntdll/loadorder.c -+++ b/dlls/ntdll/loadorder.c -@@ -290,102 +290,165 @@ static inline enum loadorder get_env_load_order( const WCHAR *module ) - - - /*************************************************************************** -- * get_standard_key -+ * open_user_reg_key -+ * -+ * Return a handle to a registry key under HKCU. -+ */ -+static HANDLE open_user_reg_key(const WCHAR *key_name) -+{ -+ HANDLE hkey, root; -+ OBJECT_ATTRIBUTES attr; -+ UNICODE_STRING nameW; -+ -+ RtlOpenCurrentUser( KEY_ALL_ACCESS, &root ); -+ attr.Length = sizeof(attr); -+ attr.RootDirectory = root; -+ attr.ObjectName = &nameW; -+ attr.Attributes = 0; -+ attr.SecurityDescriptor = NULL; -+ attr.SecurityQualityOfService = NULL; -+ RtlInitUnicodeString( &nameW, key_name ); -+ -+ if (NtOpenKey( &hkey, KEY_WOW64_64KEY | KEY_ALL_ACCESS, &attr )) hkey = 0; -+ NtClose( root ); -+ -+ return hkey; -+} -+ -+ -+/*************************************************************************** -+ * open_app_reg_key -+ * -+ * Return a handle to an app-specific registry key. -+ */ -+static HANDLE open_app_reg_key( const WCHAR *sub_key, const WCHAR *app_name ) -+{ -+ static const WCHAR AppDefaultsW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\', -+ 'A','p','p','D','e','f','a','u','l','t','s','\\',0}; -+ WCHAR *str; -+ HANDLE hkey; -+ -+ str = RtlAllocateHeap( GetProcessHeap(), 0, -+ sizeof(AppDefaultsW) + -+ strlenW(sub_key) * sizeof(WCHAR) + -+ strlenW(app_name) * sizeof(WCHAR) ); -+ if (!str) return 0; -+ strcpyW( str, AppDefaultsW ); -+ strcatW( str, app_name ); -+ strcatW( str, sub_key ); -+ -+ hkey = open_user_reg_key( str ); -+ RtlFreeHeap( GetProcessHeap(), 0, str ); -+ return hkey; -+} -+ -+ -+/*************************************************************************** -+ * get_override_standard_key - * - * Return a handle to the standard DllOverrides registry section. - */ --static HANDLE get_standard_key(void) -+static HANDLE get_override_standard_key(void) - { - static const WCHAR DllOverridesW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\', - 'D','l','l','O','v','e','r','r','i','d','e','s',0}; - static HANDLE std_key = (HANDLE)-1; - - if (std_key == (HANDLE)-1) -- { -- OBJECT_ATTRIBUTES attr; -- UNICODE_STRING nameW; -- HANDLE root; -- -- RtlOpenCurrentUser( KEY_ALL_ACCESS, &root ); -- attr.Length = sizeof(attr); -- attr.RootDirectory = root; -- attr.ObjectName = &nameW; -- attr.Attributes = 0; -- attr.SecurityDescriptor = NULL; -- attr.SecurityQualityOfService = NULL; -- RtlInitUnicodeString( &nameW, DllOverridesW ); -- -- /* @@ Wine registry key: HKCU\Software\Wine\DllOverrides */ -- if (NtOpenKey( &std_key, KEY_ALL_ACCESS, &attr )) std_key = 0; -- NtClose( root ); -- } -+ std_key = open_user_reg_key( DllOverridesW ); -+ - return std_key; - } - - - /*************************************************************************** -- * get_app_key -+ * get_override_app_key - * - * Get the registry key for the app-specific DllOverrides list. - */ --static HANDLE get_app_key( const WCHAR *app_name ) -+static HANDLE get_override_app_key( const WCHAR *app_name ) - { -- OBJECT_ATTRIBUTES attr; -- UNICODE_STRING nameW; -- HANDLE root; -- WCHAR *str; -- static const WCHAR AppDefaultsW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\', -- 'A','p','p','D','e','f','a','u','l','t','s','\\',0}; - static const WCHAR DllOverridesW[] = {'\\','D','l','l','O','v','e','r','r','i','d','e','s',0}; - static HANDLE app_key = (HANDLE)-1; - -- if (app_key != (HANDLE)-1) return app_key; -+ if (app_key == (HANDLE)-1) -+ app_key = open_app_reg_key( DllOverridesW, app_name ); - -- str = RtlAllocateHeap( GetProcessHeap(), 0, -- sizeof(AppDefaultsW) + sizeof(DllOverridesW) + -- strlenW(app_name) * sizeof(WCHAR) ); -- if (!str) return 0; -- strcpyW( str, AppDefaultsW ); -- strcatW( str, app_name ); -- strcatW( str, DllOverridesW ); -+ return app_key; -+} - -- RtlOpenCurrentUser( KEY_ALL_ACCESS, &root ); -- attr.Length = sizeof(attr); -- attr.RootDirectory = root; -- attr.ObjectName = &nameW; -- attr.Attributes = 0; -- attr.SecurityDescriptor = NULL; -- attr.SecurityQualityOfService = NULL; -- RtlInitUnicodeString( &nameW, str ); - -- /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\DllOverrides */ -- if (NtOpenKey( &app_key, KEY_ALL_ACCESS, &attr )) app_key = 0; -- NtClose( root ); -- RtlFreeHeap( GetProcessHeap(), 0, str ); -+/*************************************************************************** -+ * get_redirect_standard_key -+ * -+ * Return a handle to the standard DllRedirects registry section. -+ */ -+static HANDLE get_redirect_standard_key(void) -+{ -+ static const WCHAR DllRedirectsW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\', -+ 'D','l','l','R','e','d','i','r','e','c','t','s',0}; -+ static HANDLE std_key = (HANDLE)-1; -+ -+ if (std_key == (HANDLE)-1) -+ std_key = open_user_reg_key( DllRedirectsW ); -+ -+ return std_key; -+} -+ -+ -+/*************************************************************************** -+ * get_redirect_app_key -+ * -+ * Get the registry key for the app-specific DllRedirects list. -+ */ -+static HANDLE get_redirect_app_key( const WCHAR *app_name ) -+{ -+ static const WCHAR DllRedirectsW[] = {'\\','D','l','l','R','e','d','i','r','e','c','t','s',0}; -+ static HANDLE app_key = (HANDLE)-1; -+ -+ if (app_key == (HANDLE)-1) -+ app_key = open_app_reg_key( DllRedirectsW, app_name ); -+ - return app_key; - } - - - /*************************************************************************** -- * get_registry_value -+ * get_registry_string - * -- * Load the registry loadorder value for a given module. -+ * Load a registry string for a given module. - */ --static enum loadorder get_registry_value( HANDLE hkey, const WCHAR *module ) -+static WCHAR* get_registry_string( HANDLE hkey, const WCHAR *module, BYTE *buffer, -+ ULONG size ) - { - UNICODE_STRING valueW; -- char buffer[80]; - DWORD count; -+ WCHAR *ret = NULL; - - RtlInitUnicodeString( &valueW, module ); -- -- if (!NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, -- buffer, sizeof(buffer), &count )) -+ if (size >= sizeof(WCHAR) && -+ !NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, -+ buffer, size - sizeof(WCHAR), &count )) - { -- WCHAR *str = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)buffer)->Data; -- return parse_load_order( str ); -+ KEY_VALUE_PARTIAL_INFORMATION *info = (void *)buffer; -+ ret = (WCHAR *)info->Data; -+ ret[info->DataLength / sizeof(WCHAR)] = 0; - } -- return LO_INVALID; -+ -+ return ret; -+} -+ -+ -+/*************************************************************************** -+ * get_registry_load_order -+ * -+ * Load the registry loadorder value for a given module. -+ */ -+static enum loadorder get_registry_load_order( HANDLE hkey, const WCHAR *module ) -+{ -+ BYTE buffer[81]; -+ WCHAR *str = get_registry_string( hkey, module, buffer, sizeof(buffer) ); -+ return str ? parse_load_order( str ) : LO_INVALID; - } - - -@@ -407,13 +470,13 @@ static enum loadorder get_load_order_value( HANDLE std_key, HANDLE app_key, cons - return ret; - } - -- if (app_key && ((ret = get_registry_value( app_key, module )) != LO_INVALID)) -+ if (app_key && ((ret = get_registry_load_order( app_key, module )) != LO_INVALID)) - { - TRACE( "got app defaults %s for %s\n", debugstr_loadorder(ret), debugstr_w(module) ); - return ret; - } - -- if (std_key && ((ret = get_registry_value( std_key, module )) != LO_INVALID)) -+ if (std_key && ((ret = get_registry_load_order( std_key, module )) != LO_INVALID)) - { - TRACE( "got standard key %s for %s\n", debugstr_loadorder(ret), debugstr_w(module) ); - return ret; -@@ -422,25 +485,43 @@ static enum loadorder get_load_order_value( HANDLE std_key, HANDLE app_key, cons - return ret; - } - -+ /*************************************************************************** -+ * get_redirect_value -+ * -+ * Get the redirect value for the exact specified module string, looking in: -+ * 1. The per-application DllRedirects key -+ * 2. The standard DllRedirects key -+ */ -+static WCHAR* get_redirect_value( HANDLE std_key, HANDLE app_key, const WCHAR *module, -+ BYTE *buffer, ULONG size ) -+{ -+ WCHAR *ret = NULL; -+ -+ if (app_key && (ret = get_registry_string( app_key, module, buffer, size ))) -+ { -+ TRACE( "got app defaults %s for %s\n", debugstr_w(ret), debugstr_w(module) ); -+ return ret; -+ } -+ -+ if (std_key && (ret = get_registry_string( std_key, module, buffer, size ))) -+ { -+ TRACE( "got standard key %s for %s\n", debugstr_w(ret), debugstr_w(module) ); -+ return ret; -+ } -+ -+ return ret; -+} - - /*************************************************************************** -- * get_load_order (internal) -+ * get_module_basename (internal) - * - * Return the loadorder of a module. - * The system directory and '.dll' extension is stripped from the path. - */ --enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path ) -+static WCHAR* get_module_basename( const WCHAR *path, WCHAR **basename ) - { -- enum loadorder ret = LO_INVALID; -- HANDLE std_key, app_key = 0; -- WCHAR *module, *basename; - int len; -- -- if (!init_done) init_load_order(); -- std_key = get_standard_key(); -- if (app_name) app_key = get_app_key( app_name ); -- -- TRACE("looking for %s\n", debugstr_w(path)); -+ WCHAR *module; - - /* Strip path information if the module resides in the system directory - */ -@@ -451,12 +532,36 @@ enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path ) - if (!strchrW( p, '\\' ) && !strchrW( p, '/' )) path = p; - } - -- if (!(len = strlenW(path))) return ret; -- if (!(module = RtlAllocateHeap( GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR) ))) return ret; -+ if (!(len = strlenW(path))) return NULL; -+ if (!(module = RtlAllocateHeap( GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR) ))) return NULL; - strcpyW( module+1, path ); /* reserve module[0] for the wildcard char */ -- basename = (WCHAR *)get_basename( module+1 ); -+ *basename = (WCHAR *)get_basename( module+1 ); - - if (len >= 4) remove_dll_ext( module + 1 + len - 4 ); -+ return module; -+} -+ -+ -+/*************************************************************************** -+ * get_load_order (internal) -+ * -+ * Return the loadorder of a module. -+ * The system directory and '.dll' extension is stripped from the path. -+ */ -+enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path ) -+{ -+ enum loadorder ret = LO_INVALID; -+ HANDLE std_key, app_key = 0; -+ WCHAR *module, *basename; -+ -+ if (!init_done) init_load_order(); -+ std_key = get_override_standard_key(); -+ if (app_name) app_key = get_override_app_key( app_name ); -+ -+ TRACE("looking up loadorder for %s\n", debugstr_w(path)); -+ -+ if (!(module = get_module_basename(path, &basename))) -+ return ret; - - /* first explicit module name */ - if ((ret = get_load_order_value( std_key, app_key, module+1 )) != LO_INVALID) -@@ -487,3 +592,48 @@ enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path ) - RtlFreeHeap( GetProcessHeap(), 0, module ); - return ret; - } -+ -+ -+/*************************************************************************** -+ * get_redirect (internal) -+ * -+ * Return the redirect value of a module. -+ * The system directory and '.dll' extension is stripped from the path. -+ */ -+WCHAR* get_redirect( const WCHAR *app_name, const WCHAR *path, BYTE *buffer, ULONG size ) -+{ -+ WCHAR *ret = NULL; -+ HANDLE std_key, app_key = 0; -+ WCHAR *module, *basename; -+ -+ std_key = get_redirect_standard_key(); -+ if (app_name) app_key = get_redirect_app_key( app_name ); -+ -+ TRACE("looking up redirection for %s\n", debugstr_w(path)); -+ -+ if (!(module = get_module_basename(path, &basename))) -+ return ret; -+ -+ /* first explicit module name */ -+ if ((ret = get_redirect_value( std_key, app_key, module+1, buffer, size ))) -+ goto done; -+ -+ /* then module basename preceded by '*' */ -+ basename[-1] = '*'; -+ if ((ret = get_redirect_value( std_key, app_key, basename-1, buffer, size ))) -+ goto done; -+ -+ /* then module basename without '*' (only if explicit path) */ -+ /* -+ if (basename != module+1 && (ret = get_redirect_value( std_key, app_key, basename, buffer, size ))) -+ goto done; -+ */ -+ -+ /* and last the hard-coded default */ -+ ret = NULL; -+ TRACE( "no redirection found for %s\n", debugstr_w(path) ); -+ -+ done: -+ RtlFreeHeap( GetProcessHeap(), 0, module ); -+ return ret; -+} -diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h -index 1630978f0a..b24b39a8b3 100644 ---- a/dlls/ntdll/ntdll_misc.h -+++ b/dlls/ntdll/ntdll_misc.h -@@ -217,6 +217,7 @@ enum loadorder - }; - - extern enum loadorder get_load_order( const WCHAR *app_name, const WCHAR *path ) DECLSPEC_HIDDEN; -+extern WCHAR* get_redirect( const WCHAR *app_name, const WCHAR *path, BYTE *buffer, ULONG size ) DECLSPEC_HIDDEN; - - struct debug_info - { -diff --git a/programs/winecfg/Makefile.in b/programs/winecfg/Makefile.in -index 4e66e04e31..1cf70310d5 100644 ---- a/programs/winecfg/Makefile.in -+++ b/programs/winecfg/Makefile.in -@@ -11,6 +11,7 @@ C_SRCS = \ - driveui.c \ - libraries.c \ - main.c \ -+ staging.c \ - theme.c \ - winecfg.c \ - x11drvdlg.c -diff --git a/programs/winecfg/main.c b/programs/winecfg/main.c -index b8a85fe717..de209a925c 100644 ---- a/programs/winecfg/main.c -+++ b/programs/winecfg/main.c -@@ -58,7 +58,7 @@ PropSheetCallback (HWND hWnd, UINT uMsg, LPARAM lParam) - return 0; - } - --#define NUM_PROPERTY_PAGES 7 -+#define NUM_PROPERTY_PAGES 8 - - static INT_PTR - doPropertySheet (HINSTANCE hInstance, HWND hOwner) -@@ -139,6 +139,16 @@ doPropertySheet (HINSTANCE hInstance, HWND hOwner) - psp[pg].lParam = 0; - pg++; - -+ psp[pg].dwSize = sizeof (PROPSHEETPAGEW); -+ psp[pg].dwFlags = PSP_USETITLE; -+ psp[pg].hInstance = hInstance; -+ psp[pg].u.pszTemplate = MAKEINTRESOURCEW (IDD_STAGING); -+ psp[pg].u2.pszIcon = NULL; -+ psp[pg].pfnDlgProc = StagingDlgProc; -+ psp[pg].pszTitle = load_string (IDS_TAB_STAGING); -+ psp[pg].lParam = 0; -+ pg++; -+ - /* - * Fill out the (General) PROPSHEETPAGE data structure - * for the property sheet -diff --git a/programs/winecfg/resource.h b/programs/winecfg/resource.h -index 2760e92c00..0584422ab5 100644 ---- a/programs/winecfg/resource.h -+++ b/programs/winecfg/resource.h -@@ -45,6 +45,7 @@ - #define IDS_SHELL_FOLDER 16 - #define IDS_LINKS_TO 17 - #define IDS_WINECFG_TITLE_APP 18 /* App specific title */ -+#define IDS_TAB_STAGING 19 - #define IDI_WINECFG 100 - #define IDI_LOGO 102 - #define IDD_ABOUTCFG 107 -@@ -54,6 +55,7 @@ - #define IDD_DLLCFG 111 - #define IDD_DRIVECFG 112 - #define IDD_DESKTOP_INTEGRATION 115 -+#define IDD_STAGING 116 - #define IDC_WINVER 1012 - #define IDC_DESKTOP_WIDTH 1023 - #define IDC_DESKTOP_HEIGHT 1024 -@@ -219,3 +221,6 @@ - #define IDC_ABT_TITLE_TEXT 8436 - #define IDC_ABT_WEB_LINK 8437 - #define IDC_ABT_LICENSE_TEXT 8438 -+ -+/* Staging tab */ -+#define IDC_ENABLE_NATIVE_D3D9 9001 -diff --git a/programs/winecfg/staging.c b/programs/winecfg/staging.c -new file mode 100644 -index 0000000000..ddad850bf0 ---- /dev/null -+++ b/programs/winecfg/staging.c -@@ -0,0 +1,93 @@ -+/* -+ * WineCfg Staging panel -+ * -+ * Copyright 2014 Michael Müller -+ * Copyright 2015 Sebastian Lackner -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ * -+ */ -+ -+#define COBJMACROS -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include "resource.h" -+#include "winecfg.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(winecfg); -+ -+/* -+ * Gallium nine -+ */ -+static BOOL nine_get(void) -+{ -+ BOOL ret; -+ char *value = get_reg_key(config_key, keypath("DllRedirects"), "d3d9", NULL); -+ ret = (value && !strcmp(value, "d3d9-nine.dll")); -+ HeapFree(GetProcessHeap(), 0, value); -+ return ret; -+} -+ -+static void nine_set(BOOL status) -+{ -+ set_reg_key(config_key, keypath("DllRedirects"), "d3d9", status ? "d3d9-nine.dll" : NULL); -+} -+ -+ -+static void load_staging_settings(HWND dialog) -+{ -+ CheckDlgButton(dialog, IDC_ENABLE_NATIVE_D3D9, nine_get() ? BST_CHECKED : BST_UNCHECKED); -+#if !defined(HAVE_D3D9NINE) -+ disable(IDC_ENABLE_NATIVE_D3D9); -+#endif -+} -+ -+INT_PTR CALLBACK StagingDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -+{ -+ switch (uMsg) -+ { -+ case WM_INITDIALOG: -+ break; -+ -+ case WM_NOTIFY: -+ if (((LPNMHDR)lParam)->code == PSN_SETACTIVE) -+ load_staging_settings(hDlg); -+ break; -+ -+ case WM_SHOWWINDOW: -+ set_window_title(hDlg); -+ break; -+ -+ case WM_DESTROY: -+ break; -+ -+ case WM_COMMAND: -+ if (HIWORD(wParam) != BN_CLICKED) break; -+ switch (LOWORD(wParam)) -+ { -+ case IDC_ENABLE_NATIVE_D3D9: -+ nine_set(IsDlgButtonChecked(hDlg, IDC_ENABLE_NATIVE_D3D9) == BST_CHECKED); -+ SendMessageW(GetParent(hDlg), PSM_CHANGED, 0, 0); -+ return TRUE; -+ } -+ break; -+ } -+ return FALSE; -+} -diff --git a/programs/winecfg/winecfg.h b/programs/winecfg/winecfg.h -index 110856a536..a94947439c 100644 ---- a/programs/winecfg/winecfg.h -+++ b/programs/winecfg/winecfg.h -@@ -87,6 +87,7 @@ INT_PTR CALLBACK AppDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) - INT_PTR CALLBACK LibrariesDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - INT_PTR CALLBACK AudioDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - INT_PTR CALLBACK ThemeDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -+INT_PTR CALLBACK StagingDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - INT_PTR CALLBACK AboutDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - - /* Drive management */ -diff --git a/programs/winecfg/winecfg.rc b/programs/winecfg/winecfg.rc -index 33f54d43b2..d12522e758 100644 ---- a/programs/winecfg/winecfg.rc -+++ b/programs/winecfg/winecfg.rc -@@ -39,6 +39,7 @@ BEGIN - IDS_TAB_GRAPHICS "Graphics" - IDS_TAB_DESKTOP_INTEGRATION "Desktop Integration" - IDS_TAB_AUDIO "Audio" -+ IDS_TAB_STAGING "Staging" - IDS_TAB_ABOUT "About" - IDS_WINECFG_TITLE "Wine configuration" - IDS_WINECFG_TITLE_APP "Wine configuration for %s" -@@ -312,6 +313,15 @@ BEGIN - PUSHBUTTON "B&rowse...",IDC_BROWSE_SFPATH,195,195,50,13,WS_DISABLED - END - -+IDD_STAGING DIALOG 0, 0, 260, 220 -+STYLE WS_CHILD | WS_DISABLED -+FONT 8, "MS Shell Dlg" -+BEGIN -+ GROUPBOX "Staging settings",IDC_STATIC,8,4,244,210 -+ LTEXT "The following settings are experimental and may break stuff!\nMake sure to reset them again in case of a problem.\nGallium Nine requires MESA graphic drivers and AMD/Nvidia GPU.\n",IDC_STATIC,16,16,230,24 -+ CONTROL "Enable &Gallium Nine for better D3D9 graphic performance.",IDC_ENABLE_NATIVE_D3D9,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,40,230,8 -+END -+ - LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL - - /* @makedep: winecfg.ico */ --- -2.20.1 - diff --git a/files/wine-d3d9.patch b/files/wine-d3d9.patch deleted file mode 100644 --- a/files/wine-d3d9.patch +++ /dev/null @@ -1,5785 +0,0 @@ -From dfe9f5d81dc24995568d4e6edb63d007032e2bec Mon Sep 17 00:00:00 2001 -From: Nick Sarnie -Date: Wed, 23 Jan 2019 21:23:04 -0500 -Subject: [PATCH] Wine D3D9 - -Signed-off-by: Nick Sarnie ---- - configure.ac | 188 ++++ - dlls/d3d9-nine/Makefile.in | 15 + - dlls/d3d9-nine/d3d9-nine.spec | 14 + - dlls/d3d9-nine/d3d9_main.c | 173 +++ - dlls/d3d9-nine/d3dadapter9.c | 898 +++++++++++++++ - dlls/d3d9-nine/d3dadapter9.h | 32 + - dlls/d3d9-nine/device_wrap.c | 500 +++++++++ - dlls/d3d9-nine/device_wrap.h | 26 + - dlls/d3d9-nine/dri3.c | 1426 +++++++++++++++++++++++ - dlls/d3d9-nine/dri3.h | 91 ++ - dlls/d3d9-nine/present.c | 1748 +++++++++++++++++++++++++++++ - dlls/d3d9-nine/present.h | 40 + - dlls/d3d9-nine/shader_validator.c | 88 ++ - dlls/d3d9-nine/shader_validator.h | 29 + - dlls/d3d9-nine/version.rc | 26 + - dlls/d3d9-nine/wndproc.c | 277 +++++ - dlls/d3d9-nine/wndproc.h | 41 + - 17 files changed, 5612 insertions(+) - create mode 100644 dlls/d3d9-nine/Makefile.in - create mode 100644 dlls/d3d9-nine/d3d9-nine.spec - create mode 100644 dlls/d3d9-nine/d3d9_main.c - create mode 100644 dlls/d3d9-nine/d3dadapter9.c - create mode 100644 dlls/d3d9-nine/d3dadapter9.h - create mode 100644 dlls/d3d9-nine/device_wrap.c - create mode 100644 dlls/d3d9-nine/device_wrap.h - create mode 100644 dlls/d3d9-nine/dri3.c - create mode 100644 dlls/d3d9-nine/dri3.h - create mode 100644 dlls/d3d9-nine/present.c - create mode 100644 dlls/d3d9-nine/present.h - create mode 100644 dlls/d3d9-nine/shader_validator.c - create mode 100644 dlls/d3d9-nine/shader_validator.h - create mode 100644 dlls/d3d9-nine/version.rc - create mode 100644 dlls/d3d9-nine/wndproc.c - create mode 100644 dlls/d3d9-nine/wndproc.h - -diff --git a/configure.ac b/configure.ac -index 972d44eb86..5f668d44c9 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -70,6 +70,14 @@ AC_ARG_WITH(openal, AS_HELP_STRING([--without-openal],[do not use OpenAL]), - AC_ARG_WITH(opencl, AS_HELP_STRING([--without-opencl],[do not use OpenCL]), - [if test "x$withval" = "xno"; then ac_cv_header_CL_cl_h=no; ac_cv_header_OpenCL_opencl_h=no; fi]) - AC_ARG_WITH(opengl, AS_HELP_STRING([--without-opengl],[do not use OpenGL])) -+AC_ARG_WITH(d3d9-nine, AS_HELP_STRING([--without-d3d9-nine],[do not build d3d9-nine.dll (Gallium Nine support)]), -+ [], [with_d3d9_nine=auto]) -+AC_ARG_WITH(d3d9-nine-module, AS_HELP_STRING([--with-d3d9-nine-module], -+ [Gallium Nine module location. Can be 'manual' (path to be filled in a register), 'auto' (default. use pkgconfig to detect the location) or a path]), -+ [], [with_d3d9_nine_module=auto]) -+AC_ARG_WITH(d3d9-nine-headers-path, AS_HELP_STRING([--with-d3d9-nine-headers-path], -+ [Gallium Nine headers location. Can be 'auto' (default. use pkgconfig to detect the location) or a path]), -+ [], [with_d3d9_nine_headers_path=auto]) - AC_ARG_WITH(osmesa, AS_HELP_STRING([--without-osmesa],[do not use the OSMesa library])) - AC_ARG_WITH(oss, AS_HELP_STRING([--without-oss],[do not use the OSS sound support])) - AC_ARG_WITH(pcap, AS_HELP_STRING([--without-pcap],[do not use the Packet Capture library]), -@@ -413,6 +421,8 @@ AC_CHECK_LIB(ossaudio,_oss_ioctl) - - AC_SUBST(OPENGL_LIBS,"") - -+AC_SUBST(D3D9NINE_LIBS,"") -+ - dnl **** Check for header files **** - - AC_SYS_LARGEFILE() -@@ -1280,6 +1290,183 @@ OpenGL and Direct3D won't be supported.]) - WINE_NOTICE_WITH(va,[test "x$ac_cv_lib_soname_va" = "x" -o "x$ac_cv_lib_soname_va_x11" = "x" -o "x$ac_cv_lib_soname_va_drm" = "x"], - [libva ${notice_platform}development files not found, GPU video acceleration won't be supported.]) - -+ dnl Check for d3d9-nine support -+ if test "x$with_d3d9_nine" = "xauto" && (test "x$with_d3d9_nine_module" = "xauto" || test "x$with_d3d9_nine_headers_path" = "xauto") -+ then -+ AC_MSG_CHECKING([whether d3dadapter9 package (Gallium Nine) is present]) -+ D3DADAPTER9_MODULEDIR=`$PKG_CONFIG --variable=moduledir d3dadapter9 2>/dev/null` -+ D3DADAPTER9_LEGACY_MODULEDIR=`$PKG_CONFIG --variable=moduledir d3d 2>/dev/null` -+ if test "x$D3DADAPTER9_MODULEDIR" = "x" -a "x$D3DADAPTER9_LEGACY_MODULEDIR" = "x" -+ then -+ AC_MSG_RESULT([no, disabling support]) -+ with_d3d9_nine=no -+ else -+ AC_MSG_RESULT([yes]) -+ fi -+ fi -+ -+ if test "x$with_d3d9_nine" != "xno" -+ then -+ AC_MSG_NOTICE([Checking for d3dadapter9 library dependencies]) -+ D3D9NINE_LIBS="" -+ D3D9NINE_MISSING_LIBS="" -+ AC_CHECK_LIB(xcb,xcb_request_check,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lxcb"])]) -+ test "x$ac_cv_lib_xcb_xcb_request_check" != xyes && D3D9NINE_MISSING_LIBS="libxcb " -+ AC_CHECK_LIB(xcb-dri3,xcb_dri3_open,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lxcb-dri3"])]) -+ test "x$ac_cv_lib_xcb_dri3_xcb_dri3_open" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libxcb-dri3 " -+ AC_CHECK_LIB(xcb-present,xcb_present_notify_msc,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lxcb-present"])]) -+ test "x$ac_cv_lib_xcb_present_xcb_present_notify_msc" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libxcb-present " -+ AC_CHECK_LIB(xcb-xfixes,xcb_xfixes_create_region,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lxcb-xfixes"])]) -+ test "x$ac_cv_lib_xcb_xfixes_xcb_xfixes_create_region" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libxcb-xfixes " -+ AC_CHECK_LIB(X11-xcb,XGetXCBConnection,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lX11-xcb"])]) -+ test "x$ac_cv_lib_X11_xcb_XGetXCBConnection" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libX11-xcb " -+ AC_CHECK_LIB(X11,XOpenDisplay,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lX11"])]) -+ test "x$ac_cv_lib_X11_XOpenDisplay" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libX11 " -+ AC_CHECK_LIB(Xext,XextRemoveDisplay,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lXext"])]) -+ test "x$ac_cv_lib_Xext_XextRemoveDisplay" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libXext " -+ # libs for the dri2 fallback -+ AC_CHECK_LIB(GL,glGenFramebuffers,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lGL"])]) -+ test "x$ac_cv_lib_GL_glGenFramebuffers" != xyes && D3D9NINE_MISSING_LIBS="libGL " -+ AC_CHECK_LIB(EGL,eglCreateContext,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lEGL"])]) -+ test "x$ac_cv_lib_EGL_eglCreateContext" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libEGL" -+ -+ if test "x$D3D9NINE_MISSING_LIBS" != x -+ then -+ if test "x$with_d3d9_nine" = "xyes" -+ then -+ AC_MSG_ERROR([Missing libraries to build d3d9-nine.dll: $D3D9NINE_MISSING_LIBS]) -+ else -+ AC_MSG_NOTICE([Missing libraries to build d3d9-nine.dll: $D3D9NINE_MISSING_LIBS . disabling support]) -+ with_d3d9_nine=no -+ fi -+ fi -+ fi -+ -+ if test "x$with_d3d9_nine" != "xno" -+ then -+ AC_MSG_NOTICE([Checking d3dadapter9 header dependencies]) -+ D3D9NINE_MISSING_HEADERS="" -+ AC_CHECK_HEADERS([X11/Xlib-xcb.h xcb/dri3.h xcb/present.h X11/Xutil.h X11/Xlib.h pthread.h]) -+ test "x$ac_cv_header_X11_Xlib_xcb_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/Xlib-xcb.h " -+ test "x$ac_cv_header_xcb_dri3_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}xcb/dri3.h " -+ test "x$ac_cv_header_xcb_present_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}xcb/present.h " -+ test "x$ac_cv_header_X11_Xutil_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/Xutil.h " -+ test "x$ac_cv_header_X11_Xlib_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/Xlib.h " -+ test "x$ac_cv_header_pthread_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}pthread.h " -+ # headers for the dri2 fallback -+ AC_CHECK_HEADERS([X11/Xmd.h X11/Xlibint.h X11/extensions/dri2tokens.h X11/extensions/dri2proto.h X11/extensions/extutil.h GL/gl.h GL/glext.h EGL/egl.h EGL/eglext.h libdrm/drm_fourcc.h libdrm/drm.h], -+ [],[],[[ -+#include -+#include -+#include -+#include -+]]) -+ test "x$ac_cv_header_X11_Xmd_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/Xmd.h " -+ test "x$ac_cv_header_X11_Xlibint_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/Xlibint.h " -+ test "x$ac_cv_header_X11_extensions_dri2tokens_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/extensions/dri2tokens.h " -+ test "x$ac_cv_header_X11_extensions_dri2proto_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/extensions/dri2proto.h " -+ test "x$ac_cv_header_X11_extensions_extutil_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/extensions/extutil.h " -+ test "x$ac_cv_header_GL_gl_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}GL/gl.h " -+ test "x$ac_cv_header_GL_glext_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}GL/glext.h " -+ test "x$ac_cv_header_EGL_egl_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}EGL/egl.h " -+ test "x$ac_cv_header_EGL_eglext_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}EGL/eglext.h " -+ test "x$ac_cv_header_libdrm_drm_fourcc_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}libdrm/drm_fourcc.h " -+ test "x$ac_cv_header_libdrm_drm_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}libdrm/drm.h " -+ if test "x$D3D9NINE_MISSING_HEADERS" != x -+ then -+ if test "x$with_d3d9_nine" = "xyes" -+ then -+ AC_MSG_ERROR([Missing headers to build d3d9-nine.dll: $D3D9NINE_MISSING_HEADERS]) -+ else -+ AC_MSG_NOTICE([Missing headers to build d3d9-nine.dll: $D3D9NINE_MISSING_HEADERS . disabling support]) -+ with_d3d9_nine=no -+ fi -+ fi -+ fi -+ -+ if test "x$with_d3d9_nine" != "xno" -+ then -+ # d3d9-nine.dll will be built and an option to use it -+ # added. The module path can always be overriden by -+ # a wine registry setting. If the module isn't found -+ # at execution time, the dll will refuse to load and -+ # print an error message to the user. -+ AC_DEFINE(HAVE_D3D9NINE, 1, [Whether d3d9-nine.dll is built]) -+ # default: use pkgconfig to find the gallium nine module. -+ # Check the module is there. -+ if test "x$with_d3d9_nine_module" = "xauto" -+ then -+ D3DADAPTER9_MODULEDIR=`$PKG_CONFIG --variable=moduledir d3dadapter9 2>/dev/null` -+ if test "x$D3DADAPTER9_MODULEDIR" = x -+ then -+ # legacy path -+ D3DADAPTER9_MODULEDIR=`$PKG_CONFIG --variable=moduledir d3d 2>/dev/null` -+ if test "x$D3DADAPTER9_MODULEDIR" = x -+ then -+ AC_MSG_ERROR([pkg-config couldn't find Gallium Nine module]) -+ fi -+ fi -+ AC_DEFINE_UNQUOTED(D3D9NINE_MODULEPATH, ["`echo ${D3DADAPTER9_MODULEDIR}/d3dadapter9.so.1`"], [Gallium Nine module path]) -+ # Check module -+ CPPFLAGSBAK=$CPPFLAGS -+ # link against libdl -+ CPPFLAGS="$CPPFLAGS -Wl,--no-as-needed -ldl" -+ -+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include -+#include ]],[[void *handle = dlopen("${D3DADAPTER9_MODULEDIR}/d3dadapter9.so.1", RTLD_GLOBAL | RTLD_NOW); -+exit((handle && dlsym(handle, "D3DAdapter9GetProc")) ? 0 : 1)]])], -+ [echo "d3dadapter9.so.1 found at '${D3DADAPTER9_MODULEDIR}/d3dadapter9.so.1'"], -+ [AC_MSG_ERROR([Couldn't load Gallium nine module at '${D3DADAPTER9_MODULEDIR}/d3dadapter9.so.1' (found by pkg-config)])]) -+ CPPFLAGS=$CPPFLAGSBAK -+ else -+ # Manual : do not feed any path, the wine registry will have -+ # to be used to pass a path. Useful for wine builds -+ # that are distributed and will run on different -+ # distros. -+ # Else feed a path directly. Useful for distro maintainers who -+ # know where the package would be installed, but don't have -+ # it installed on their build. -+ # Don't check if the module is there. -+ if test "x$with_d3d9_nine_module" != "xmanual" -+ then -+ AC_DEFINE_UNQUOTED(D3D9NINE_MODULEPATH, ["`echo ${with_d3d9_nine_module}`"], [Gallium Nine module path]) -+ fi -+ fi -+ -+ # by default the headers are found with pkgconfig, -+ # but it is possible to pass a path to a specific directory. -+ # that directory must contain a d3dadapter directory -+ # with d3dadapter9.h, drm.h and present.h -+ if test "x$with_d3d9_nine_headers_path" = "xauto" -+ then -+ AC_PROG_SED -+ D3DADAPTER9_INCLUDEDIR=`$PKG_CONFIG --variable=includedir d3dadapter9 2>/dev/null` -+ D3DADAPTER9_MAJOR=`$PKG_CONFIG --modversion d3dadapter9 2>/dev/null | $SED -n 's/\([[^\.]]*\)\..*$/\1/p'` -+ if test "x$D3DADAPTER9_INCLUDEDIR" = x -+ then -+ # legacy path -+ D3DADAPTER9_INCLUDEDIR=`$PKG_CONFIG --variable=includedir d3d 2>/dev/null` -+ D3DADAPTER9_MAJOR=`$PKG_CONFIG --modversion d3d 2>/dev/null | $SED -n 's/\([[^\.]]*\)\..*$/\1/p'` -+ if test "x$D3DADAPTER9_INCLUDEDIR" = x -+ then -+ AC_MSG_ERROR([pkg-config couldn't find Gallium Nine headers]) -+ fi -+ fi -+ # check major version of package. The major version number guarantees header compatibility. -+ if test "x$D3DADAPTER9_MAJOR" != x1 -+ then -+ AC_MSG_ERROR([pkg-config found Gallium Nine Module and Headers, but version is incompatible]) -+ fi -+ else -+ D3DADAPTER9_INCLUDEDIR=`echo ${with_d3d9_nine_headers_path}` -+ fi -+ AC_DEFINE_UNQUOTED(D3D9NINE_HEADERS_CFLAGS, ["`echo -I${D3DADAPTER9_INCLUDEDIR}`"], [Gallium Nine headers cflags]) -+ -+ AC_DEFINE(D3D9NINE_DRI2, 1, [Whether d3d9-nine DRI2 fallback is compiled]) -+ else -+ enable_d3d9_nine=${enable_d3d9_nine:-no} -+ fi -+ - CPPFLAGS="$ac_save_CPPFLAGS" - else - X_CFLAGS="" -@@ -3262,6 +3449,7 @@ WINE_CONFIG_MAKEFILE(dlls/d3d8) - WINE_CONFIG_MAKEFILE(dlls/d3d8/tests) - WINE_CONFIG_MAKEFILE(dlls/d3d9) - WINE_CONFIG_MAKEFILE(dlls/d3d9/tests) -+WINE_CONFIG_MAKEFILE(dlls/d3d9-nine) - WINE_CONFIG_MAKEFILE(dlls/d3dcompiler_33) - WINE_CONFIG_MAKEFILE(dlls/d3dcompiler_34) - WINE_CONFIG_MAKEFILE(dlls/d3dcompiler_35) -diff --git a/dlls/d3d9-nine/Makefile.in b/dlls/d3d9-nine/Makefile.in -new file mode 100644 -index 0000000000..c6df8d7dbe ---- /dev/null -+++ b/dlls/d3d9-nine/Makefile.in -@@ -0,0 +1,15 @@ -+MODULE = d3d9-nine.dll -+IMPORTS = dxguid uuid advapi32 gdi32 user32 -+EXTRAINCL = $(X_CFLAGS) $(D3D9NINE_HEADERS_CFLAGS) -+EXTRALIBS = $(D3D9NINE_LIBS) -+ -+C_SRCS = \ -+ d3d9_main.c \ -+ d3dadapter9.c \ -+ device_wrap.c \ -+ present.c \ -+ dri3.c \ -+ wndproc.c \ -+ shader_validator.c -+ -+RC_SRCS = version.rc -diff --git a/dlls/d3d9-nine/d3d9-nine.spec b/dlls/d3d9-nine/d3d9-nine.spec -new file mode 100644 -index 0000000000..a33cba51e7 ---- /dev/null -+++ b/dlls/d3d9-nine/d3d9-nine.spec -@@ -0,0 +1,14 @@ -+@ stdcall Direct3DShaderValidatorCreate9() -+@ stub PSGPError -+@ stub PSGPSampleTexture -+@ stdcall D3DPERF_BeginEvent(long wstr) -+@ stdcall D3DPERF_EndEvent() -+@ stdcall D3DPERF_GetStatus() -+@ stdcall D3DPERF_QueryRepeatFrame() -+@ stdcall D3DPERF_SetMarker(long wstr) -+@ stdcall D3DPERF_SetOptions(long) -+@ stdcall D3DPERF_SetRegion(long wstr) -+@ stub DebugSetLevel -+@ stdcall DebugSetMute() -+@ stdcall Direct3DCreate9(long) -+@ stdcall Direct3DCreate9Ex(long ptr) -diff --git a/dlls/d3d9-nine/d3d9_main.c b/dlls/d3d9-nine/d3d9_main.c -new file mode 100644 -index 0000000000..d1efdf4a71 ---- /dev/null -+++ b/dlls/d3d9-nine/d3d9_main.c -@@ -0,0 +1,173 @@ -+/* -+ * Direct3D 9 -+ * -+ * Copyright 2002-2003 Jason Edmeades -+ * Copyright 2002-2003 Raphael Junqueira -+ * Copyright 2005 Oliver Stieber -+ * Copyright 2015 Patrick Rudolph -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ * -+ */ -+ -+#include "config.h" -+#include "wine/debug.h" -+ -+#include -+#include -+ -+#include "d3dadapter9.h" -+#include "wndproc.h" -+#include "shader_validator.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(d3d9nine); -+ -+static int D3DPERF_event_level = 0; -+static Display *gdi_display; -+ -+void WINAPI DebugSetMute(void) -+{ -+ /* nothing to do */ -+} -+ -+IDirect3D9 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate9(UINT sdk_version) -+{ -+ IDirect3D9 *native; -+ TRACE("sdk_version %#x.\n", sdk_version); -+ -+ if (SUCCEEDED(d3dadapter9_new(gdi_display, FALSE, (IDirect3D9Ex **)&native))) -+ return native; -+ -+ return NULL; -+} -+ -+HRESULT WINAPI DECLSPEC_HOTPATCH Direct3DCreate9Ex(UINT sdk_version, IDirect3D9Ex **d3d9ex) -+{ -+ TRACE("sdk_version %#x, d3d9ex %p.\n", sdk_version, d3d9ex); -+ -+ return d3dadapter9_new(gdi_display, TRUE, d3d9ex); -+} -+ -+/******************************************************************* -+ * Direct3DShaderValidatorCreate9 (D3D9.@) -+ * -+ * No documentation available for this function. -+ * SDK only says it is internal and shouldn't be used. -+ */ -+ -+void* WINAPI Direct3DShaderValidatorCreate9(void) -+{ -+ IDirect3DShaderValidator9Impl* object = -+ HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(IDirect3DShaderValidator9Impl)); -+ -+ object->lpVtbl = &IDirect3DShaderValidator9Vtbl; -+ object->ref = 1; -+ -+ FIXME("Returning interface %p\n", object); -+ return (void*) object; -+} -+ -+/******************************************************************* -+ * DllMain -+ */ -+BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) -+{ -+ switch (reason) -+ { -+ case DLL_PROCESS_ATTACH: -+ if (!(gdi_display = XOpenDisplay( NULL ))) -+ { -+ ERR("Failed to open display\n"); -+ return FALSE; -+ } -+ -+ fcntl( ConnectionNumber(gdi_display), F_SETFD, 1 ); /* set close on exec flag */ -+ -+ nine_dll_init(inst); -+ break; -+ case DLL_PROCESS_DETACH: -+ if (!reserved) -+ return nine_dll_destroy(inst); -+ break; -+ } -+ -+ return TRUE; -+} -+ -+/*********************************************************************** -+ * D3DPERF_BeginEvent (D3D9.@) -+ */ -+int WINAPI D3DPERF_BeginEvent(D3DCOLOR color, const WCHAR *name) -+{ -+ TRACE("color 0x%08x, name %s.\n", color, debugstr_w(name)); -+ -+ return D3DPERF_event_level++; -+} -+ -+/*********************************************************************** -+ * D3DPERF_EndEvent (D3D9.@) -+ */ -+int WINAPI D3DPERF_EndEvent(void) -+{ -+ TRACE("(void) : stub\n"); -+ -+ return --D3DPERF_event_level; -+} -+ -+/*********************************************************************** -+ * D3DPERF_GetStatus (D3D9.@) -+ */ -+DWORD WINAPI D3DPERF_GetStatus(void) -+{ -+ FIXME("(void) : stub\n"); -+ -+ return 0; -+} -+ -+/*********************************************************************** -+ * D3DPERF_SetOptions (D3D9.@) -+ * -+ */ -+void WINAPI D3DPERF_SetOptions(DWORD options) -+{ -+ FIXME("(%#x) : stub\n", options); -+} -+ -+/*********************************************************************** -+ * D3DPERF_QueryRepeatFrame (D3D9.@) -+ */ -+BOOL WINAPI D3DPERF_QueryRepeatFrame(void) -+{ -+ FIXME("(void) : stub\n"); -+ -+ return FALSE; -+} -+ -+/*********************************************************************** -+ * D3DPERF_SetMarker (D3D9.@) -+ */ -+void WINAPI D3DPERF_SetMarker(D3DCOLOR color, const WCHAR *name) -+{ -+ FIXME("color 0x%08x, name %s stub!\n", color, debugstr_w(name)); -+} -+ -+/*********************************************************************** -+ * D3DPERF_SetRegion (D3D9.@) -+ */ -+void WINAPI D3DPERF_SetRegion(D3DCOLOR color, const WCHAR *name) -+{ -+ FIXME("color 0x%08x, name %s stub!\n", color, debugstr_w(name)); -+} -diff --git a/dlls/d3d9-nine/d3dadapter9.c b/dlls/d3d9-nine/d3dadapter9.c -new file mode 100644 -index 0000000000..188eebf763 ---- /dev/null -+++ b/dlls/d3d9-nine/d3dadapter9.c -@@ -0,0 +1,898 @@ -+/* -+ * Wine IDirect3D9 interface using ID3DAdapter9 -+ * -+ * Copyright 2013 Joakim Sindholt -+ * Christoph Bumiller -+ * Copyright 2014 David Heidelberger -+ * Copyright 2014-2015 Axel Davy -+ * Copyright 2015 Nick Sarnie -+ * Patrick Rudolph -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "config.h" -+#include "wine/debug.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(d3d9nine); -+ -+#include -+#include "present.h" -+#include "device_wrap.h" -+ -+/* this represents a snapshot taken at the moment of creation */ -+struct output -+{ -+ D3DDISPLAYROTATION rotation; /* current rotation */ -+ D3DDISPLAYMODEEX *modes; -+ unsigned nmodes; -+ unsigned nmodesalloc; -+ unsigned current; /* current mode num */ -+ -+ HMONITOR monitor; -+}; -+ -+struct adapter_group -+{ -+ struct output *outputs; -+ unsigned noutputs; -+ unsigned noutputsalloc; -+ -+ /* override driver provided DeviceName with this to homogenize device names -+ * with wine */ -+ WCHAR devname[32]; -+ -+ /* driver stuff */ -+ ID3DAdapter9 *adapter; -+}; -+ -+struct adapter_map -+{ -+ unsigned group; -+ unsigned master; -+}; -+ -+struct d3dadapter9 -+{ -+ /* COM vtable */ -+ void *vtable; -+ /* IUnknown reference count */ -+ LONG refs; -+ -+ /* adapter groups and mappings */ -+ struct adapter_group *groups; -+ struct adapter_map *map; -+ unsigned nadapters; -+ unsigned ngroups; -+ unsigned ngroupsalloc; -+ -+ /* true if it implements IDirect3D9Ex */ -+ boolean ex; -+ Display *gdi_display; -+}; -+ -+/* convenience wrapper for calls into ID3D9Adapter */ -+#define ADAPTER_GROUP \ -+ This->groups[This->map[Adapter].group] -+ -+#define ADAPTER_PROC(name, ...) \ -+ ID3DAdapter9_##name(ADAPTER_GROUP.adapter, ## __VA_ARGS__) -+ -+#define ADAPTER_OUTPUT \ -+ ADAPTER_GROUP.outputs[Adapter-This->map[Adapter].master] -+ -+static HRESULT WINAPI d3dadapter9_CheckDeviceFormat(struct d3dadapter9 *This, -+ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, -+ DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat); -+ -+static ULONG WINAPI d3dadapter9_AddRef(struct d3dadapter9 *This) -+{ -+ ULONG refs = InterlockedIncrement(&This->refs); -+ TRACE("%p increasing refcount to %u.\n", This, refs); -+ return refs; -+} -+ -+static ULONG WINAPI d3dadapter9_Release(struct d3dadapter9 *This) -+{ -+ ULONG refs = InterlockedDecrement(&This->refs); -+ TRACE("%p decreasing refcount to %u.\n", This, refs); -+ if (refs == 0) -+ { -+ /* dtor */ -+ if (This->map) -+ { -+ HeapFree(GetProcessHeap(), 0, This->map); -+ } -+ -+ if (This->groups) -+ { -+ int i, j; -+ for (i = 0; i < This->ngroups; ++i) -+ { -+ if (This->groups[i].outputs) -+ { -+ for (j = 0; j < This->groups[i].noutputs; ++j) -+ { -+ if (This->groups[i].outputs[j].modes) -+ { -+ HeapFree(GetProcessHeap(), 0, -+ This->groups[i].outputs[j].modes); -+ } -+ } -+ HeapFree(GetProcessHeap(), 0, This->groups[i].outputs); -+ } -+ -+ if (This->groups[i].adapter) -+ ID3DAdapter9_Release(This->groups[i].adapter); -+ } -+ HeapFree(GetProcessHeap(), 0, This->groups); -+ } -+ -+ HeapFree(GetProcessHeap(), 0, This); -+ } -+ return refs; -+} -+ -+static HRESULT WINAPI d3dadapter9_QueryInterface(struct d3dadapter9 *This, -+ REFIID riid, void **ppvObject) -+{ -+ if (!ppvObject) -+ return E_POINTER; -+ -+ if ((IsEqualGUID(&IID_IDirect3D9Ex, riid) && This->ex) || -+ IsEqualGUID(&IID_IDirect3D9, riid) || -+ IsEqualGUID(&IID_IUnknown, riid)) -+ { -+ *ppvObject = This; -+ d3dadapter9_AddRef(This); -+ return S_OK; -+ } -+ -+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); -+ *ppvObject = NULL; -+ -+ return E_NOINTERFACE; -+} -+ -+static HRESULT WINAPI d3dadapter9_RegisterSoftwareDevice(struct d3dadapter9 *This, -+ void *pInitializeFunction) -+{ -+ FIXME("(%p, %p), stub!\n", This, pInitializeFunction); -+ return D3DERR_INVALIDCALL; -+} -+ -+static UINT WINAPI d3dadapter9_GetAdapterCount(struct d3dadapter9 *This) -+{ -+ return This->nadapters; -+} -+ -+static HRESULT WINAPI d3dadapter9_GetAdapterIdentifier(struct d3dadapter9 *This, -+ UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9 *pIdentifier) -+{ -+ HRESULT hr; -+ HKEY regkey; -+ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ hr = ADAPTER_PROC(GetAdapterIdentifier, Flags, pIdentifier); -+ if (SUCCEEDED(hr)) -+ { -+ /* Override the driver provided DeviceName with what Wine provided */ -+ ZeroMemory(pIdentifier->DeviceName, sizeof(pIdentifier->DeviceName)); -+ if (!WideCharToMultiByte(CP_ACP, 0, ADAPTER_GROUP.devname, -1, -+ pIdentifier->DeviceName, sizeof(pIdentifier->DeviceName), NULL, NULL)) -+ return D3DERR_INVALIDCALL; -+ -+ TRACE("DeviceName overriden: %s\n", pIdentifier->DeviceName); -+ -+ /* Override PCI IDs when wined3d registry keys are set */ -+ if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Direct3DNine", ®key)) -+ { -+ DWORD type, data; -+ DWORD size = sizeof(DWORD); -+ -+ if (!RegQueryValueExA(regkey, "VideoPciDeviceID", 0, &type, (BYTE *)&data, &size) && -+ (type == REG_DWORD) && (size == sizeof(DWORD))) -+ pIdentifier->DeviceId = data; -+ if (size != sizeof(DWORD)) -+ { -+ ERR("VideoPciDeviceID is not a DWORD\n"); -+ size = sizeof(DWORD); -+ } -+ if (!RegQueryValueExA(regkey, "VideoPciVendorID", 0, &type, (BYTE *)&data, &size) && -+ (type == REG_DWORD) && (size == sizeof(DWORD))) -+ pIdentifier->VendorId = data; -+ if (size != sizeof(DWORD)) -+ ERR("VideoPciVendorID is not a DWORD\n"); -+ RegCloseKey(regkey); -+ -+ TRACE("DeviceId:VendorId overridden: %04X:%04X\n", pIdentifier->DeviceId, pIdentifier->VendorId); -+ } -+ } -+ return hr; -+} -+ -+static UINT WINAPI d3dadapter9_GetAdapterModeCount(struct d3dadapter9 *This, -+ UINT Adapter, D3DFORMAT Format) -+{ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ if (FAILED(d3dadapter9_CheckDeviceFormat(This, Adapter, D3DDEVTYPE_HAL, -+ Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, Format))) -+ { -+ WARN("DeviceFormat not available.\n"); -+ return 0; -+ } -+ -+ TRACE("%u modes.\n", ADAPTER_OUTPUT.nmodes); -+ return ADAPTER_OUTPUT.nmodes; -+} -+ -+static HRESULT WINAPI d3dadapter9_EnumAdapterModes(struct d3dadapter9 *This, -+ UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE *pMode) -+{ -+ HRESULT hr; -+ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ hr = d3dadapter9_CheckDeviceFormat(This, Adapter, D3DDEVTYPE_HAL, -+ Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, Format); -+ -+ if (FAILED(hr)) -+ { -+ TRACE("DeviceFormat not available.\n"); -+ return hr; -+ } -+ -+ if (Mode >= ADAPTER_OUTPUT.nmodes) -+ { -+ WARN("Mode %u does not exist.\n", Mode); -+ return D3DERR_INVALIDCALL; -+ } -+ -+ pMode->Width = ADAPTER_OUTPUT.modes[Mode].Width; -+ pMode->Height = ADAPTER_OUTPUT.modes[Mode].Height; -+ pMode->RefreshRate = ADAPTER_OUTPUT.modes[Mode].RefreshRate; -+ pMode->Format = Format; -+ -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI d3dadapter9_GetAdapterDisplayMode(struct d3dadapter9 *This, -+ UINT Adapter, D3DDISPLAYMODE *pMode) -+{ -+ UINT Mode; -+ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ Mode = ADAPTER_OUTPUT.current; -+ pMode->Width = ADAPTER_OUTPUT.modes[Mode].Width; -+ pMode->Height = ADAPTER_OUTPUT.modes[Mode].Height; -+ pMode->RefreshRate = ADAPTER_OUTPUT.modes[Mode].RefreshRate; -+ pMode->Format = ADAPTER_OUTPUT.modes[Mode].Format; -+ -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI d3dadapter9_CheckDeviceType(struct d3dadapter9 *This, -+ UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, -+ D3DFORMAT BackBufferFormat, BOOL bWindowed) -+{ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ return ADAPTER_PROC(CheckDeviceType, -+ DevType, AdapterFormat, BackBufferFormat, bWindowed); -+} -+ -+static HRESULT WINAPI d3dadapter9_CheckDeviceFormat(struct d3dadapter9 *This, -+ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, -+ DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) -+{ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ return ADAPTER_PROC(CheckDeviceFormat, -+ DeviceType, AdapterFormat, Usage, RType, CheckFormat); -+} -+ -+static HRESULT WINAPI d3dadapter9_CheckDeviceMultiSampleType(struct d3dadapter9 *This, -+ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, -+ BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels) -+{ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ return ADAPTER_PROC(CheckDeviceMultiSampleType, DeviceType, SurfaceFormat, -+ Windowed, MultiSampleType, pQualityLevels); -+} -+ -+static HRESULT WINAPI d3dadapter9_CheckDepthStencilMatch(struct d3dadapter9 *This, -+ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, -+ D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) -+{ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ return ADAPTER_PROC(CheckDepthStencilMatch, DeviceType, AdapterFormat, -+ RenderTargetFormat, DepthStencilFormat); -+} -+ -+static HRESULT WINAPI d3dadapter9_CheckDeviceFormatConversion(struct d3dadapter9 *This, -+ UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) -+{ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ return ADAPTER_PROC(CheckDeviceFormatConversion, -+ DeviceType, SourceFormat, TargetFormat); -+} -+ -+static HRESULT WINAPI d3dadapter9_GetDeviceCaps(struct d3dadapter9 *This, -+ UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps) -+{ -+ HRESULT hr; -+ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ hr = ADAPTER_PROC(GetDeviceCaps, DeviceType, pCaps); -+ if (FAILED(hr)) -+ return hr; -+ -+ pCaps->MasterAdapterOrdinal = This->map[Adapter].master; -+ pCaps->AdapterOrdinalInGroup = Adapter-This->map[Adapter].master; -+ pCaps->NumberOfAdaptersInGroup = ADAPTER_GROUP.noutputs; -+ -+ return hr; -+} -+ -+static HMONITOR WINAPI d3dadapter9_GetAdapterMonitor(struct d3dadapter9 *This, -+ UINT Adapter) -+{ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return (HMONITOR)0; -+ -+ return (HMONITOR)ADAPTER_OUTPUT.monitor; -+} -+ -+static HRESULT WINAPI DECLSPEC_HOTPATCH d3dadapter9_CreateDeviceEx(struct d3dadapter9 *This, -+ UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, -+ D3DPRESENT_PARAMETERS *pPresentationParameters, -+ D3DDISPLAYMODEEX *pFullscreenDisplayMode, -+ IDirect3DDevice9Ex **ppReturnedDeviceInterface); -+ -+static HRESULT WINAPI DECLSPEC_HOTPATCH d3dadapter9_CreateDevice(struct d3dadapter9 *This, -+ UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, -+ D3DPRESENT_PARAMETERS *pPresentationParameters, -+ IDirect3DDevice9 **ppReturnedDeviceInterface) -+{ -+ HRESULT hr; -+ hr = d3dadapter9_CreateDeviceEx(This, Adapter, DeviceType, hFocusWindow, -+ BehaviorFlags, pPresentationParameters, NULL, -+ (IDirect3DDevice9Ex **)ppReturnedDeviceInterface); -+ if (FAILED(hr)) -+ return hr; -+ -+ return D3D_OK; -+} -+ -+static UINT WINAPI d3dadapter9_GetAdapterModeCountEx(struct d3dadapter9 *This, -+ UINT Adapter, const D3DDISPLAYMODEFILTER *pFilter) -+{ -+ FIXME("(%p, %u, %p), half stub!\n", This, Adapter, pFilter); -+ return d3dadapter9_GetAdapterModeCount(This, Adapter, pFilter->Format); -+} -+ -+static HRESULT WINAPI d3dadapter9_EnumAdapterModesEx(struct d3dadapter9 *This, -+ UINT Adapter, const D3DDISPLAYMODEFILTER *pFilter, UINT Mode, -+ D3DDISPLAYMODEEX *pMode) -+{ -+ HRESULT hr; -+ -+ FIXME("(%p, %u, %p, %u, %p), half stub!\n", This, Adapter, pFilter, Mode, pMode); -+ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ hr = d3dadapter9_CheckDeviceFormat(This, Adapter, D3DDEVTYPE_HAL, -+ pFilter->Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, pFilter->Format); -+ -+ if (FAILED(hr)) -+ { -+ TRACE("DeviceFormat not available.\n"); -+ return hr; -+ } -+ -+ if (Mode >= ADAPTER_OUTPUT.nmodes) -+ { -+ WARN("Mode %u does not exist.\n", Mode); -+ return D3DERR_INVALIDCALL; -+ } -+ -+ pMode->Size = ADAPTER_OUTPUT.modes[Mode].Size; -+ pMode->Width = ADAPTER_OUTPUT.modes[Mode].Width; -+ pMode->Height = ADAPTER_OUTPUT.modes[Mode].Height; -+ pMode->RefreshRate = ADAPTER_OUTPUT.modes[Mode].RefreshRate; -+ pMode->Format = ADAPTER_OUTPUT.modes[Mode].Format; -+ pMode->ScanLineOrdering = ADAPTER_OUTPUT.modes[Mode].ScanLineOrdering; -+ -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI d3dadapter9_GetAdapterDisplayModeEx(struct d3dadapter9 *This, -+ UINT Adapter, D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation) -+{ -+ UINT Mode; -+ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ if (pMode) -+ { -+ Mode = ADAPTER_OUTPUT.current; -+ pMode->Size = sizeof(D3DDISPLAYMODEEX); -+ pMode->Width = ADAPTER_OUTPUT.modes[Mode].Width; -+ pMode->Height = ADAPTER_OUTPUT.modes[Mode].Height; -+ pMode->RefreshRate = ADAPTER_OUTPUT.modes[Mode].RefreshRate; -+ pMode->Format = ADAPTER_OUTPUT.modes[Mode].Format; -+ pMode->ScanLineOrdering = ADAPTER_OUTPUT.modes[Mode].ScanLineOrdering; -+ } -+ if (pRotation) -+ *pRotation = ADAPTER_OUTPUT.rotation; -+ -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI DECLSPEC_HOTPATCH d3dadapter9_CreateDeviceEx(struct d3dadapter9 *This, -+ UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, -+ D3DPRESENT_PARAMETERS *pPresentationParameters, -+ D3DDISPLAYMODEEX *pFullscreenDisplayMode, -+ IDirect3DDevice9Ex **ppReturnedDeviceInterface) -+{ -+ ID3DPresentGroup *present; -+ HRESULT hr; -+ -+ if (Adapter >= d3dadapter9_GetAdapterCount(This)) -+ return D3DERR_INVALIDCALL; -+ -+ { -+ struct adapter_group *group = &ADAPTER_GROUP; -+ unsigned nparams, ordinal; -+ -+ if (BehaviorFlags & D3DCREATE_ADAPTERGROUP_DEVICE) -+ { -+ nparams = group->noutputs; -+ ordinal = 0; -+ } -+ else -+ { -+ nparams = 1; -+ ordinal = Adapter - This->map[Adapter].master; -+ } -+ hr = present_create_present_group(This->gdi_display, group->devname, ordinal, -+ hFocusWindow, pPresentationParameters, nparams, &present, This->ex, -+ BehaviorFlags); -+ } -+ -+ if (FAILED(hr)) -+ { -+ WARN("Failed to create PresentGroup.\n"); -+ return hr; -+ } -+ -+ if (This->ex) -+ { -+ hr = ADAPTER_PROC(CreateDeviceEx, Adapter, DeviceType, hFocusWindow, -+ BehaviorFlags, pPresentationParameters, pFullscreenDisplayMode, -+ (IDirect3D9Ex *)This, present, ppReturnedDeviceInterface); -+ } -+ else -+ { -+ /* CreateDevice on non-ex */ -+ hr = ADAPTER_PROC(CreateDevice, Adapter, DeviceType, hFocusWindow, -+ BehaviorFlags, pPresentationParameters, (IDirect3D9 *)This, present, -+ (IDirect3DDevice9 **)ppReturnedDeviceInterface); -+ } -+ if (FAILED(hr)) -+ { -+ WARN("ADAPTER_PROC failed.\n"); -+ ID3DPresentGroup_Release(present); -+ return hr; -+ } -+ -+ /* Nine returns different vtables for Ex, non Ex and -+ * if you use the multithread flag or not. This prevents -+ * things like Steam overlay to work, in addition to the problem -+ * that functions nine side are not recognized by wine as -+ * hotpatch-able. If possible, we use our vtable wrapper, -+ * which solves the problem described above. */ -+ if (enable_device_vtable_wrapper()) -+ (*ppReturnedDeviceInterface)->lpVtbl = get_device_vtable(); -+ return hr; -+} -+ -+static HRESULT WINAPI d3dadapter9_GetAdapterLUID(struct d3dadapter9 *This, -+ UINT Adapter, LUID *pLUID) -+{ -+ FIXME("(%p, %u, %p), stub!\n", This, Adapter, pLUID); -+ return D3DERR_INVALIDCALL; -+} -+ -+static struct adapter_group *add_group(struct d3dadapter9 *This) -+{ -+ if (This->ngroups >= This->ngroupsalloc) -+ { -+ void *r; -+ -+ if (This->ngroupsalloc == 0) -+ { -+ This->ngroupsalloc = 2; -+ r = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ This->ngroupsalloc*sizeof(struct adapter_group)); -+ } -+ else -+ { -+ This->ngroupsalloc <<= 1; -+ r = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->groups, -+ This->ngroupsalloc*sizeof(struct adapter_group)); -+ } -+ -+ if (!r) -+ return NULL; -+ This->groups = r; -+ } -+ -+ return &This->groups[This->ngroups++]; -+} -+ -+static void remove_group(struct d3dadapter9 *This) -+{ -+ struct adapter_group *group = &This->groups[This->ngroups-1]; -+ int i; -+ -+ for (i = 0; i < group->noutputs; ++i) -+ { -+ HeapFree(GetProcessHeap(), 0, group->outputs[i].modes); -+ } -+ HeapFree(GetProcessHeap(), 0, group->outputs); -+ -+ ZeroMemory(group, sizeof(struct adapter_group)); -+ This->ngroups--; -+} -+ -+static struct output *add_output(struct d3dadapter9 *This) -+{ -+ struct adapter_group *group = &This->groups[This->ngroups-1]; -+ -+ if (group->noutputs >= group->noutputsalloc) -+ { -+ void *r; -+ -+ if (group->noutputsalloc == 0) -+ { -+ group->noutputsalloc = 2; -+ r = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ group->noutputsalloc*sizeof(struct output)); -+ } -+ else -+ { -+ group->noutputsalloc <<= 1; -+ r = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, group->outputs, -+ group->noutputsalloc*sizeof(struct output)); -+ } -+ -+ if (!r) -+ return NULL; -+ group->outputs = r; -+ } -+ -+ return &group->outputs[group->noutputs++]; -+} -+ -+static void remove_output(struct d3dadapter9 *This) -+{ -+ struct adapter_group *group = &This->groups[This->ngroups-1]; -+ struct output *out = &group->outputs[group->noutputs-1]; -+ -+ HeapFree(GetProcessHeap(), 0, out->modes); -+ -+ ZeroMemory(out, sizeof(struct output)); -+ group->noutputs--; -+} -+ -+static D3DDISPLAYMODEEX *add_mode(struct d3dadapter9 *This) -+{ -+ struct adapter_group *group = &This->groups[This->ngroups-1]; -+ struct output *out = &group->outputs[group->noutputs-1]; -+ -+ if (out->nmodes >= out->nmodesalloc) -+ { -+ void *r; -+ -+ if (out->nmodesalloc == 0) -+ { -+ out->nmodesalloc = 8; -+ r = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ out->nmodesalloc*sizeof(struct D3DDISPLAYMODEEX)); -+ } -+ else -+ { -+ out->nmodesalloc <<= 1; -+ r = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, out->modes, -+ out->nmodesalloc*sizeof(struct D3DDISPLAYMODEEX)); -+ } -+ -+ if (!r) -+ return NULL; -+ out->modes = r; -+ } -+ -+ return &out->modes[out->nmodes++]; -+} -+ -+static void remove_mode(struct d3dadapter9 *This) -+{ -+ struct adapter_group *group = &This->groups[This->ngroups-1]; -+ struct output *out = &group->outputs[group->noutputs-1]; -+ out->nmodes--; -+} -+ -+static HRESULT fill_groups(struct d3dadapter9 *This) -+{ -+ DISPLAY_DEVICEW dd; -+ DEVMODEW dm; -+ POINT pt; -+ HDC hdc; -+ HRESULT hr; -+ int i, j, k; -+ -+ WCHAR wdisp[] = {'D','I','S','P','L','A','Y',0}; -+ -+ ZeroMemory(&dd, sizeof(dd)); -+ ZeroMemory(&dm, sizeof(dm)); -+ dd.cb = sizeof(dd); -+ dm.dmSize = sizeof(dm); -+ -+ for (i = 0; EnumDisplayDevicesW(NULL, i, &dd, 0); ++i) -+ { -+ struct adapter_group *group = add_group(This); -+ if (!group) -+ { -+ ERR("Out of memory.\n"); -+ return E_OUTOFMEMORY; -+ } -+ -+ hdc = CreateDCW(wdisp, dd.DeviceName, NULL, NULL); -+ if (!hdc) -+ { -+ remove_group(This); -+ WARN("Unable to create DC for display %d.\n", i); -+ goto end_group; -+ } -+ -+ hr = present_create_adapter9(This->gdi_display, hdc, &group->adapter); -+ DeleteDC(hdc); -+ if (FAILED(hr)) -+ { -+ remove_group(This); -+ goto end_group; -+ } -+ -+ CopyMemory(group->devname, dd.DeviceName, sizeof(group->devname)); -+ for (j = 0; EnumDisplayDevicesW(group->devname, j, &dd, 0); ++j) -+ { -+ struct output *out = add_output(This); -+ boolean orient = FALSE, monit = FALSE; -+ if (!out) -+ { -+ ERR("Out of memory.\n"); -+ return E_OUTOFMEMORY; -+ } -+ -+ for (k = 0; EnumDisplaySettingsExW(dd.DeviceName, k, &dm, 0); ++k) -+ { -+ D3DDISPLAYMODEEX *mode = add_mode(This); -+ if (!out) -+ { -+ ERR("Out of memory.\n"); -+ return E_OUTOFMEMORY; -+ } -+ -+ mode->Size = sizeof(D3DDISPLAYMODEEX); -+ mode->Width = dm.dmPelsWidth; -+ mode->Height = dm.dmPelsHeight; -+ mode->RefreshRate = dm.dmDisplayFrequency; -+ mode->ScanLineOrdering = -+ (dm.dmDisplayFlags & DM_INTERLACED) ? -+ D3DSCANLINEORDERING_INTERLACED : -+ D3DSCANLINEORDERING_PROGRESSIVE; -+ -+ switch (dm.dmBitsPerPel) -+ { -+ case 32: mode->Format = D3DFMT_X8R8G8B8; break; -+ case 24: mode->Format = D3DFMT_R8G8B8; break; -+ case 16: mode->Format = D3DFMT_R5G6B5; break; -+ case 8: -+ remove_mode(This); -+ goto end_mode; -+ -+ default: -+ remove_mode(This); -+ WARN("Unknown format (%u bpp) in display %d, monitor " -+ "%d, mode %d.\n", dm.dmBitsPerPel, i, j, k); -+ goto end_mode; -+ } -+ -+ if (!orient) -+ { -+ switch (dm.dmDisplayOrientation) -+ { -+ case DMDO_DEFAULT: -+ out->rotation = D3DDISPLAYROTATION_IDENTITY; -+ break; -+ -+ case DMDO_90: -+ out->rotation = D3DDISPLAYROTATION_90; -+ break; -+ -+ case DMDO_180: -+ out->rotation = D3DDISPLAYROTATION_180; -+ break; -+ -+ case DMDO_270: -+ out->rotation = D3DDISPLAYROTATION_270; -+ break; -+ -+ default: -+ remove_output(This); -+ WARN("Unknown display rotation in display %d, " -+ "monitor %d\n", i, j); -+ goto end_output; -+ } -+ orient = TRUE; -+ } -+ -+ if (!monit) -+ { -+ pt.x = dm.dmPosition.x; -+ pt.y = dm.dmPosition.y; -+ out->monitor = MonitorFromPoint(pt, 0); -+ if (!out->monitor) -+ { -+ remove_output(This); -+ WARN("Unable to get monitor handle for display %d, " -+ "monitor %d.\n", i, j); -+ goto end_output; -+ } -+ monit = TRUE; -+ } -+ -+end_mode: -+ ZeroMemory(&dm, sizeof(dm)); -+ dm.dmSize = sizeof(dm); -+ } -+ -+end_output: -+ ZeroMemory(&dd, sizeof(dd)); -+ dd.cb = sizeof(dd); -+ } -+ -+end_group: -+ ZeroMemory(&dd, sizeof(dd)); -+ dd.cb = sizeof(dd); -+ } -+ -+ return D3D_OK; -+} -+ -+static IDirect3D9ExVtbl d3dadapter9_vtable = { -+ (void *)d3dadapter9_QueryInterface, -+ (void *)d3dadapter9_AddRef, -+ (void *)d3dadapter9_Release, -+ (void *)d3dadapter9_RegisterSoftwareDevice, -+ (void *)d3dadapter9_GetAdapterCount, -+ (void *)d3dadapter9_GetAdapterIdentifier, -+ (void *)d3dadapter9_GetAdapterModeCount, -+ (void *)d3dadapter9_EnumAdapterModes, -+ (void *)d3dadapter9_GetAdapterDisplayMode, -+ (void *)d3dadapter9_CheckDeviceType, -+ (void *)d3dadapter9_CheckDeviceFormat, -+ (void *)d3dadapter9_CheckDeviceMultiSampleType, -+ (void *)d3dadapter9_CheckDepthStencilMatch, -+ (void *)d3dadapter9_CheckDeviceFormatConversion, -+ (void *)d3dadapter9_GetDeviceCaps, -+ (void *)d3dadapter9_GetAdapterMonitor, -+ (void *)d3dadapter9_CreateDevice, -+ (void *)d3dadapter9_GetAdapterModeCountEx, -+ (void *)d3dadapter9_EnumAdapterModesEx, -+ (void *)d3dadapter9_GetAdapterDisplayModeEx, -+ (void *)d3dadapter9_CreateDeviceEx, -+ (void *)d3dadapter9_GetAdapterLUID -+}; -+ -+HRESULT d3dadapter9_new(Display *gdi_display, boolean ex, IDirect3D9Ex **ppOut) -+{ -+ struct d3dadapter9 *This; -+ HRESULT hr; -+ unsigned i, j, k; -+ -+ This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct d3dadapter9)); -+ if (!This) -+ { -+ ERR("Out of memory.\n"); -+ return E_OUTOFMEMORY; -+ } -+ -+ This->vtable = &d3dadapter9_vtable; -+ This->refs = 1; -+ This->ex = ex; -+ This->gdi_display = gdi_display; -+ -+ if (!present_has_d3dadapter(gdi_display)) -+ { -+ ERR("Your display driver doesn't support native D3D9 adapters.\n"); -+ d3dadapter9_Release(This); -+ return D3DERR_NOTAVAILABLE; -+ } -+ -+ if (FAILED(hr = fill_groups(This))) -+ { -+ d3dadapter9_Release(This); -+ return hr; -+ } -+ -+ /* map absolute adapter IDs with internal adapters */ -+ for (i = 0; i < This->ngroups; ++i) -+ { -+ for (j = 0; j < This->groups[i].noutputs; ++j) -+ { -+ This->nadapters++; -+ } -+ } -+ if (This->nadapters == 0) -+ { -+ ERR("No available native adapters in system.\n"); -+ d3dadapter9_Release(This); -+ return D3DERR_NOTAVAILABLE; -+ } -+ -+ This->map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ This->nadapters * sizeof(struct adapter_map)); -+ -+ if (!This->map) -+ { -+ d3dadapter9_Release(This); -+ ERR("Out of memory.\n"); -+ return E_OUTOFMEMORY; -+ } -+ for (i = k = 0; i < This->ngroups; ++i) -+ { -+ for (j = 0; j < This->groups[i].noutputs; ++j, ++k) -+ { -+ This->map[k].master = k-j; -+ This->map[k].group = i; -+ } -+ } -+ -+ *ppOut = (IDirect3D9Ex *)This; -+ FIXME("\033[1;32m\nNative Direct3D 9 is active." -+ "\nFor more information visit https://wiki.ixit.cz/d3d9\033[0m\n"); -+ return D3D_OK; -+} -diff --git a/dlls/d3d9-nine/d3dadapter9.h b/dlls/d3d9-nine/d3dadapter9.h -new file mode 100644 -index 0000000000..ad54f67285 ---- /dev/null -+++ b/dlls/d3d9-nine/d3dadapter9.h -@@ -0,0 +1,32 @@ -+/* -+ * D3DAdapter9 interface -+ * -+ * Copyright 2015 Patrick Rudolph -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#ifndef __WINE_D3D9ADAPTER_H -+#define __WINE_D3D9ADAPTER_H -+ -+#include -+ -+void d3dadapter9_init(HINSTANCE hinst); -+ -+void d3dadapter9_destroy(HINSTANCE hinst); -+ -+HRESULT d3dadapter9_new(Display *gdi_display, boolean ex, IDirect3D9Ex **ppOut); -+ -+#endif /* __WINE_D3D9ADAPTER_H */ -diff --git a/dlls/d3d9-nine/device_wrap.c b/dlls/d3d9-nine/device_wrap.c -new file mode 100644 -index 0000000000..e662c6f89a ---- /dev/null -+++ b/dlls/d3d9-nine/device_wrap.c -@@ -0,0 +1,500 @@ -+/* -+ * Copyright 2016 Axel Davy -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "config.h" -+#include "wine/port.h" -+#include "wine/debug.h" -+ -+#include -+ -+#include "device_wrap.h" -+ -+struct IDirect3DDevice9Ex_Minor1 -+{ -+ IDirect3DDevice9ExVtbl *lpVtbl; -+ IDirect3DDevice9ExVtbl *lpVtbl_internal; -+}; -+ -+struct IDirect3DSwapChain9Ex_Minor1 -+{ -+ IDirect3DSwapChain9ExVtbl *lpVtbl; -+ IDirect3DSwapChain9ExVtbl *lpVtbl_internal; -+}; -+ -+typedef struct IDirect3DDevice9Ex_Minor1 IDirect3DDevice9Ex_Minor1; -+typedef struct IDirect3DSwapChain9Ex_Minor1 IDirect3DSwapChain9Ex_Minor1; -+ -+#define SWAPCHAIN_WRAP0(ret, func) \ -+ ret WINAPI WineNineSwapChain9_ ## func(IDirect3DSwapChain9Ex *This) \ -+ { \ -+ return ((IDirect3DSwapChain9Ex_Minor1 *)This)->lpVtbl_internal->func(This); \ -+ } -+ -+#define SWAPCHAIN_WRAP1(ret, func, type1) \ -+ ret WINAPI WineNineSwapChain9_ ## func(IDirect3DSwapChain9Ex *This, type1 arg1) \ -+ { \ -+ return ((IDirect3DSwapChain9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1); \ -+ } -+ -+#define SWAPCHAIN_WRAP2(ret, func, type1, type2) \ -+ ret WINAPI WineNineSwapChain9_ ## func(IDirect3DSwapChain9Ex *This, type1 arg1, type2 arg2) \ -+ { \ -+ return ((IDirect3DSwapChain9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2); \ -+ } -+ -+#define SWAPCHAIN_WRAP3(ret, func, type1, type2, type3) \ -+ ret WINAPI WineNineSwapChain9_ ## func(IDirect3DSwapChain9Ex *This, type1 arg1, type2 arg2, type3 arg3) \ -+ { \ -+ return ((IDirect3DSwapChain9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3); \ -+ } -+ -+#define SWAPCHAIN_H_WRAP5(ret, func, type1, type2, type3, type4, type5) \ -+ ret WINAPI DECLSPEC_HOTPATCH WineNineSwapChain9_ ## func(IDirect3DSwapChain9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -+ { \ -+ return ((IDirect3DSwapChain9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5); \ -+ } -+ -+#define DEVICE_WRAP0(ret, func) \ -+ ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This); \ -+ } -+ -+#define DEVICE_WRAP1(ret, func, type1) \ -+ ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1); \ -+ } -+ -+#define DEVICE_WRAP2(ret, func, type1, type2) \ -+ ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2); \ -+ } -+ -+#define DEVICE_WRAP3(ret, func, type1, type2, type3) \ -+ ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3); \ -+ } -+ -+#define DEVICE_WRAP4(ret, func, type1, type2, type3, type4) \ -+ ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4); \ -+ } -+ -+#define DEVICE_WRAP5(ret, func, type1, type2, type3, type4, type5) \ -+ ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5); \ -+ } -+ -+#define DEVICE_WRAP6(ret, func, type1, type2, type3, type4, type5, type6) \ -+ ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5, arg6); \ -+ } -+ -+#define DEVICE_WRAP7(ret, func, type1, type2, type3, type4, type5, type6, type7) \ -+ ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ -+ } -+ -+#define DEVICE_WRAP8(ret, func, type1, type2, type3, type4, type5, type6, type7, type8) \ -+ ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ -+ } -+ -+#define DEVICE_WRAP9(ret, func, type1, type2, type3, type4, type5, type6, type7, type8, type9) \ -+ ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8, type9 arg9) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ -+ } -+ -+#define DEVICE_H_WRAP0(ret, func) \ -+ ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This); \ -+ } -+ -+#define DEVICE_H_WRAP1(ret, func, type1) \ -+ ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1); \ -+ } -+ -+#define DEVICE_H_WRAP2(ret, func, type1, type2) \ -+ ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2); \ -+ } -+ -+#define DEVICE_H_WRAP3(ret, func, type1, type2, type3) \ -+ ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3); \ -+ } -+ -+#define DEVICE_H_WRAP4(ret, func, type1, type2, type3, type4) \ -+ ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4); \ -+ } -+ -+#define DEVICE_H_WRAP5(ret, func, type1, type2, type3, type4, type5) \ -+ ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -+ { \ -+ return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5); \ -+ } -+ -+SWAPCHAIN_WRAP2(HRESULT, QueryInterface, REFIID, void **) -+SWAPCHAIN_WRAP0(ULONG, AddRef) -+SWAPCHAIN_WRAP0(ULONG, Release) -+SWAPCHAIN_H_WRAP5(HRESULT, Present, const RECT *, const RECT *, HWND, const RGNDATA *, DWORD) -+SWAPCHAIN_WRAP1(HRESULT, GetFrontBufferData, IDirect3DSurface9 *) -+SWAPCHAIN_WRAP3(HRESULT, GetBackBuffer, UINT, D3DBACKBUFFER_TYPE, IDirect3DSurface9 **) -+SWAPCHAIN_WRAP1(HRESULT, GetRasterStatus, D3DRASTER_STATUS *) -+SWAPCHAIN_WRAP1(HRESULT, GetDisplayMode, D3DDISPLAYMODE *) -+SWAPCHAIN_WRAP1(HRESULT, GetDevice, IDirect3DDevice9 **) -+SWAPCHAIN_WRAP1(HRESULT, GetPresentParameters, D3DPRESENT_PARAMETERS *) -+SWAPCHAIN_WRAP1(HRESULT, GetLastPresentCount, UINT *) -+SWAPCHAIN_WRAP1(HRESULT, GetPresentStats, D3DPRESENTSTATS *) -+SWAPCHAIN_WRAP2(HRESULT, GetDisplayModeEx, D3DDISPLAYMODEEX *, D3DDISPLAYROTATION *) -+ -+DEVICE_WRAP2(HRESULT, QueryInterface, REFIID, void **) -+DEVICE_WRAP0(ULONG, AddRef) -+DEVICE_H_WRAP0(ULONG, Release) -+DEVICE_WRAP0(HRESULT, TestCooperativeLevel) -+DEVICE_WRAP0(UINT, GetAvailableTextureMem) -+DEVICE_WRAP0(HRESULT, EvictManagedResources) -+DEVICE_WRAP1(HRESULT, GetDirect3D, IDirect3D9 **) -+DEVICE_WRAP1(HRESULT, GetDeviceCaps, D3DCAPS9 *) -+DEVICE_WRAP2(HRESULT, GetDisplayMode, UINT, D3DDISPLAYMODE*) -+DEVICE_WRAP1(HRESULT, GetCreationParameters, D3DDEVICE_CREATION_PARAMETERS *) -+DEVICE_WRAP3(HRESULT, SetCursorProperties, UINT, UINT, IDirect3DSurface9 *) -+DEVICE_WRAP3(void, SetCursorPosition, int, int, DWORD) -+DEVICE_WRAP1(BOOL, ShowCursor, BOOL) -+/*DEVICE_H_WRAP2(HRESULT, CreateAdditionalSwapChain, D3DPRESENT_PARAMETERS *, IDirect3DSwapChain9 **)*/ -+/*DEVICE_H_WRAP2(HRESULT, GetSwapChain, UINT, IDirect3DSwapChain9 **)*/ -+DEVICE_WRAP0(UINT, GetNumberOfSwapChains) -+DEVICE_H_WRAP1(HRESULT, Reset, D3DPRESENT_PARAMETERS *) -+DEVICE_H_WRAP4(HRESULT, Present, const RECT *, const RECT *, HWND, const RGNDATA *) -+DEVICE_WRAP4(HRESULT, GetBackBuffer, UINT, UINT, D3DBACKBUFFER_TYPE, IDirect3DSurface9 **) -+DEVICE_WRAP2(HRESULT, GetRasterStatus, UINT, D3DRASTER_STATUS *) -+DEVICE_WRAP1(HRESULT, SetDialogBoxMode, BOOL) -+DEVICE_H_WRAP3(void, SetGammaRamp, UINT, DWORD, const D3DGAMMARAMP *) -+DEVICE_WRAP2(void, GetGammaRamp, UINT, D3DGAMMARAMP *) -+DEVICE_WRAP8(HRESULT, CreateTexture, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, IDirect3DTexture9 **, HANDLE *) -+DEVICE_WRAP9(HRESULT, CreateVolumeTexture, UINT, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, IDirect3DVolumeTexture9 **, HANDLE *) -+DEVICE_WRAP7(HRESULT, CreateCubeTexture, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, IDirect3DCubeTexture9 **, HANDLE *) -+DEVICE_WRAP6(HRESULT, CreateVertexBuffer, UINT, DWORD, DWORD, D3DPOOL, IDirect3DVertexBuffer9 **, HANDLE *) -+DEVICE_WRAP6(HRESULT, CreateIndexBuffer, UINT, DWORD, D3DFORMAT, D3DPOOL, IDirect3DIndexBuffer9 **, HANDLE *) -+DEVICE_WRAP8(HRESULT, CreateRenderTarget, UINT, UINT, D3DFORMAT, D3DMULTISAMPLE_TYPE, DWORD, BOOL, IDirect3DSurface9 **, HANDLE *) -+DEVICE_WRAP8(HRESULT, CreateDepthStencilSurface, UINT, UINT, D3DFORMAT, D3DMULTISAMPLE_TYPE, DWORD, BOOL, IDirect3DSurface9 **, HANDLE *) -+DEVICE_WRAP4(HRESULT, UpdateSurface, IDirect3DSurface9 *, const RECT *, IDirect3DSurface9 *, const POINT *) -+DEVICE_WRAP2(HRESULT, UpdateTexture, IDirect3DBaseTexture9 *, IDirect3DBaseTexture9 *) -+DEVICE_WRAP2(HRESULT, GetRenderTargetData, IDirect3DSurface9 *, IDirect3DSurface9 *) -+DEVICE_WRAP2(HRESULT, GetFrontBufferData, UINT, IDirect3DSurface9 *) -+DEVICE_WRAP5(HRESULT, StretchRect, IDirect3DSurface9 *, const RECT *, IDirect3DSurface9 *, const RECT *, D3DTEXTUREFILTERTYPE) -+DEVICE_WRAP3(HRESULT, ColorFill, IDirect3DSurface9 *, const RECT *, D3DCOLOR) -+DEVICE_WRAP6(HRESULT, CreateOffscreenPlainSurface, UINT, UINT, D3DFORMAT, D3DPOOL, IDirect3DSurface9 **, HANDLE *) -+DEVICE_WRAP2(HRESULT, SetRenderTarget, DWORD, IDirect3DSurface9 *) -+DEVICE_WRAP2(HRESULT, GetRenderTarget, DWORD, IDirect3DSurface9 **) -+DEVICE_WRAP1(HRESULT, SetDepthStencilSurface, IDirect3DSurface9 *) -+DEVICE_WRAP1(HRESULT, GetDepthStencilSurface, IDirect3DSurface9 **) -+DEVICE_WRAP0(HRESULT, BeginScene) -+DEVICE_H_WRAP0(HRESULT, EndScene) -+DEVICE_WRAP6(HRESULT, Clear, DWORD, const D3DRECT *, DWORD, D3DCOLOR, float, DWORD) -+DEVICE_WRAP2(HRESULT, SetTransform, D3DTRANSFORMSTATETYPE, const D3DMATRIX *) -+DEVICE_WRAP2(HRESULT, GetTransform, D3DTRANSFORMSTATETYPE, D3DMATRIX *) -+DEVICE_WRAP2(HRESULT, MultiplyTransform, D3DTRANSFORMSTATETYPE, const D3DMATRIX *) -+DEVICE_WRAP1(HRESULT, SetViewport, const D3DVIEWPORT9 *) -+DEVICE_WRAP1(HRESULT, GetViewport, D3DVIEWPORT9 *) -+DEVICE_WRAP1(HRESULT, SetMaterial, const D3DMATERIAL9 *) -+DEVICE_WRAP1(HRESULT, GetMaterial, D3DMATERIAL9 *) -+DEVICE_WRAP2(HRESULT, SetLight, DWORD, const D3DLIGHT9 *) -+DEVICE_WRAP2(HRESULT, GetLight, DWORD, D3DLIGHT9 *) -+DEVICE_WRAP2(HRESULT, LightEnable, DWORD, BOOL) -+DEVICE_WRAP2(HRESULT, GetLightEnable, DWORD, BOOL *) -+DEVICE_WRAP2(HRESULT, SetClipPlane, DWORD, const float *) -+DEVICE_WRAP2(HRESULT, GetClipPlane, DWORD, float *) -+DEVICE_H_WRAP2(HRESULT, SetRenderState, D3DRENDERSTATETYPE, DWORD) -+DEVICE_WRAP2(HRESULT, GetRenderState, D3DRENDERSTATETYPE, DWORD *) -+DEVICE_WRAP2(HRESULT, CreateStateBlock, D3DSTATEBLOCKTYPE, IDirect3DStateBlock9 **) -+DEVICE_WRAP0(HRESULT, BeginStateBlock) -+DEVICE_WRAP1(HRESULT, EndStateBlock, IDirect3DStateBlock9 **) -+DEVICE_WRAP1(HRESULT, SetClipStatus, const D3DCLIPSTATUS9 *) -+DEVICE_WRAP1(HRESULT, GetClipStatus, D3DCLIPSTATUS9 *) -+DEVICE_WRAP2(HRESULT, GetTexture, DWORD, IDirect3DBaseTexture9 **) -+DEVICE_WRAP2(HRESULT, SetTexture, DWORD, IDirect3DBaseTexture9 *) -+DEVICE_WRAP3(HRESULT, GetTextureStageState, DWORD, D3DTEXTURESTAGESTATETYPE, DWORD *) -+DEVICE_WRAP3(HRESULT, SetTextureStageState, DWORD, D3DTEXTURESTAGESTATETYPE, DWORD) -+DEVICE_WRAP3(HRESULT, GetSamplerState, DWORD, D3DSAMPLERSTATETYPE, DWORD *) -+DEVICE_H_WRAP3(HRESULT, SetSamplerState, DWORD, D3DSAMPLERSTATETYPE, DWORD) -+DEVICE_WRAP1(HRESULT, ValidateDevice, DWORD *) -+DEVICE_WRAP2(HRESULT, SetPaletteEntries, UINT, const PALETTEENTRY *) -+DEVICE_WRAP2(HRESULT, GetPaletteEntries, UINT, PALETTEENTRY *) -+DEVICE_WRAP1(HRESULT, SetCurrentTexturePalette, UINT) -+DEVICE_WRAP1(HRESULT, GetCurrentTexturePalette, UINT *) -+DEVICE_WRAP1(HRESULT, SetScissorRect, const RECT *) -+DEVICE_WRAP1(HRESULT, GetScissorRect, RECT *) -+DEVICE_WRAP1(HRESULT, SetSoftwareVertexProcessing, BOOL) -+DEVICE_WRAP0(BOOL, GetSoftwareVertexProcessing) -+DEVICE_WRAP1(HRESULT, SetNPatchMode, float) -+DEVICE_WRAP0(float, GetNPatchMode) -+DEVICE_WRAP3(HRESULT, DrawPrimitive, D3DPRIMITIVETYPE, UINT, UINT) -+DEVICE_WRAP6(HRESULT, DrawIndexedPrimitive, D3DPRIMITIVETYPE, INT, UINT, UINT, UINT, UINT) -+DEVICE_WRAP4(HRESULT, DrawPrimitiveUP, D3DPRIMITIVETYPE, UINT, const void *, UINT) -+DEVICE_WRAP8(HRESULT, DrawIndexedPrimitiveUP, D3DPRIMITIVETYPE, UINT, UINT, UINT, const void *, D3DFORMAT, const void *, UINT) -+DEVICE_WRAP6(HRESULT, ProcessVertices, UINT, UINT, UINT, IDirect3DVertexBuffer9 *, IDirect3DVertexDeclaration9 *, DWORD) -+DEVICE_WRAP2(HRESULT, CreateVertexDeclaration, const D3DVERTEXELEMENT9 *, IDirect3DVertexDeclaration9 **) -+DEVICE_WRAP1(HRESULT, SetVertexDeclaration, IDirect3DVertexDeclaration9 *) -+DEVICE_WRAP1(HRESULT, GetVertexDeclaration, IDirect3DVertexDeclaration9 **) -+DEVICE_WRAP1(HRESULT, SetFVF, DWORD) -+DEVICE_WRAP1(HRESULT, GetFVF, DWORD *) -+DEVICE_WRAP2(HRESULT, CreateVertexShader, const DWORD *, IDirect3DVertexShader9 **) -+DEVICE_WRAP1(HRESULT, SetVertexShader, IDirect3DVertexShader9 *) -+DEVICE_WRAP1(HRESULT, GetVertexShader, IDirect3DVertexShader9 **) -+DEVICE_WRAP3(HRESULT, SetVertexShaderConstantF, UINT, const float *, UINT) -+DEVICE_WRAP3(HRESULT, GetVertexShaderConstantF, UINT, float *, UINT) -+DEVICE_WRAP3(HRESULT, SetVertexShaderConstantI, UINT, const int *, UINT) -+DEVICE_WRAP3(HRESULT, GetVertexShaderConstantI, UINT, int *, UINT) -+DEVICE_WRAP3(HRESULT, SetVertexShaderConstantB, UINT, const BOOL *, UINT) -+DEVICE_WRAP3(HRESULT, GetVertexShaderConstantB, UINT, BOOL *, UINT) -+DEVICE_WRAP4(HRESULT, SetStreamSource, UINT, IDirect3DVertexBuffer9 *, UINT, UINT) -+DEVICE_WRAP4(HRESULT, GetStreamSource, UINT, IDirect3DVertexBuffer9 **, UINT *, UINT *) -+DEVICE_WRAP2(HRESULT, SetStreamSourceFreq, UINT, UINT) -+DEVICE_WRAP2(HRESULT, GetStreamSourceFreq, UINT, UINT *) -+DEVICE_WRAP1(HRESULT, SetIndices, IDirect3DIndexBuffer9 *) -+DEVICE_WRAP1(HRESULT, GetIndices, IDirect3DIndexBuffer9 **) -+DEVICE_WRAP2(HRESULT, CreatePixelShader, const DWORD *, IDirect3DPixelShader9 **) -+DEVICE_WRAP1(HRESULT, SetPixelShader, IDirect3DPixelShader9 *) -+DEVICE_WRAP1(HRESULT, GetPixelShader, IDirect3DPixelShader9 **) -+DEVICE_WRAP3(HRESULT, SetPixelShaderConstantF, UINT, const float *, UINT) -+DEVICE_WRAP3(HRESULT, GetPixelShaderConstantF, UINT, float *, UINT) -+DEVICE_WRAP3(HRESULT, SetPixelShaderConstantI, UINT, const int *, UINT) -+DEVICE_WRAP3(HRESULT, GetPixelShaderConstantI, UINT, int *, UINT) -+DEVICE_WRAP3(HRESULT, SetPixelShaderConstantB, UINT, const BOOL *, UINT) -+DEVICE_WRAP3(HRESULT, GetPixelShaderConstantB, UINT, BOOL *, UINT) -+DEVICE_WRAP3(HRESULT, DrawRectPatch, UINT, const float *, const D3DRECTPATCH_INFO *) -+DEVICE_WRAP3(HRESULT, DrawTriPatch, UINT, const float *, const D3DTRIPATCH_INFO *) -+DEVICE_WRAP1(HRESULT, DeletePatch, UINT) -+DEVICE_WRAP2(HRESULT, CreateQuery, D3DQUERYTYPE, IDirect3DQuery9 **) -+DEVICE_WRAP4(HRESULT, SetConvolutionMonoKernel, UINT, UINT, float *, float *) -+DEVICE_WRAP8(HRESULT, ComposeRects, IDirect3DSurface9 *, IDirect3DSurface9 *, IDirect3DVertexBuffer9 *, UINT, IDirect3DVertexBuffer9 *, D3DCOMPOSERECTSOP, int, int) -+DEVICE_H_WRAP5(HRESULT, PresentEx, const RECT *, const RECT *, HWND, const RGNDATA *, DWORD) -+DEVICE_WRAP1(HRESULT, GetGPUThreadPriority, INT *) -+DEVICE_WRAP1(HRESULT, SetGPUThreadPriority, INT) -+DEVICE_WRAP1(HRESULT, WaitForVBlank, UINT) -+DEVICE_WRAP2(HRESULT, CheckResourceResidency, IDirect3DResource9 **, UINT32) -+DEVICE_WRAP1(HRESULT, SetMaximumFrameLatency, UINT) -+DEVICE_WRAP1(HRESULT, GetMaximumFrameLatency, UINT *) -+DEVICE_WRAP1(HRESULT, CheckDeviceState, HWND) -+DEVICE_WRAP9(HRESULT, CreateRenderTargetEx, UINT, UINT, D3DFORMAT, D3DMULTISAMPLE_TYPE, DWORD, BOOL, IDirect3DSurface9 **, HANDLE *, DWORD) -+DEVICE_WRAP7(HRESULT, CreateOffscreenPlainSurfaceEx, UINT, UINT, D3DFORMAT, D3DPOOL, IDirect3DSurface9 **, HANDLE *, DWORD) -+DEVICE_WRAP9(HRESULT, CreateDepthStencilSurfaceEx, UINT, UINT, D3DFORMAT, D3DMULTISAMPLE_TYPE, DWORD, BOOL, IDirect3DSurface9 **, HANDLE *, DWORD) -+DEVICE_H_WRAP2(HRESULT, ResetEx, D3DPRESENT_PARAMETERS *, D3DDISPLAYMODEEX *) -+DEVICE_WRAP3(HRESULT, GetDisplayModeEx, UINT, D3DDISPLAYMODEEX *, D3DDISPLAYROTATION *) -+ -+IDirect3DSwapChain9ExVtbl WineNineSwapChain9Ex_vtable = { -+ WineNineSwapChain9_QueryInterface, -+ WineNineSwapChain9_AddRef, -+ WineNineSwapChain9_Release, -+ WineNineSwapChain9_Present, -+ WineNineSwapChain9_GetFrontBufferData, -+ WineNineSwapChain9_GetBackBuffer, -+ WineNineSwapChain9_GetRasterStatus, -+ WineNineSwapChain9_GetDisplayMode, -+ WineNineSwapChain9_GetDevice, -+ WineNineSwapChain9_GetPresentParameters, -+ WineNineSwapChain9_GetLastPresentCount, -+ WineNineSwapChain9_GetPresentStats, -+ WineNineSwapChain9_GetDisplayModeEx -+}; -+ -+HRESULT WINAPI DECLSPEC_HOTPATCH WineNineDevice9_CreateAdditionalSwapChain(IDirect3DDevice9Ex *This, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DSwapChain9 **pSwapChain) -+{ -+ HRESULT hr; -+ -+ hr = ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->CreateAdditionalSwapChain(This, pPresentationParameters, pSwapChain); -+ if (FAILED(hr)) -+ return hr; -+ -+ (*pSwapChain)->lpVtbl = (IDirect3DSwapChain9Vtbl *)&WineNineSwapChain9Ex_vtable; -+ -+ return hr; -+} -+ -+HRESULT WINAPI DECLSPEC_HOTPATCH WineNineDevice9_GetSwapChain(IDirect3DDevice9Ex *This, UINT iSwapChain, IDirect3DSwapChain9 **pSwapChain) -+{ -+ HRESULT hr; -+ -+ hr = ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->GetSwapChain(This, iSwapChain, pSwapChain); -+ if (FAILED(hr)) -+ return hr; -+ -+ (*pSwapChain)->lpVtbl = (IDirect3DSwapChain9Vtbl *)&WineNineSwapChain9Ex_vtable; -+ -+ return hr; -+} -+ -+ -+IDirect3DDevice9ExVtbl WineNineDevice9_vtable = { -+ WineNineDevice9_QueryInterface, -+ WineNineDevice9_AddRef, -+ WineNineDevice9_Release, -+ WineNineDevice9_TestCooperativeLevel, -+ WineNineDevice9_GetAvailableTextureMem, -+ WineNineDevice9_EvictManagedResources, -+ WineNineDevice9_GetDirect3D, -+ WineNineDevice9_GetDeviceCaps, -+ WineNineDevice9_GetDisplayMode, -+ WineNineDevice9_GetCreationParameters, -+ WineNineDevice9_SetCursorProperties, -+ WineNineDevice9_SetCursorPosition, -+ WineNineDevice9_ShowCursor, -+ WineNineDevice9_CreateAdditionalSwapChain, -+ WineNineDevice9_GetSwapChain, -+ WineNineDevice9_GetNumberOfSwapChains, -+ WineNineDevice9_Reset, -+ WineNineDevice9_Present, -+ WineNineDevice9_GetBackBuffer, -+ WineNineDevice9_GetRasterStatus, -+ WineNineDevice9_SetDialogBoxMode, -+ WineNineDevice9_SetGammaRamp, -+ WineNineDevice9_GetGammaRamp, -+ WineNineDevice9_CreateTexture, -+ WineNineDevice9_CreateVolumeTexture, -+ WineNineDevice9_CreateCubeTexture, -+ WineNineDevice9_CreateVertexBuffer, -+ WineNineDevice9_CreateIndexBuffer, -+ WineNineDevice9_CreateRenderTarget, -+ WineNineDevice9_CreateDepthStencilSurface, -+ WineNineDevice9_UpdateSurface, -+ WineNineDevice9_UpdateTexture, -+ WineNineDevice9_GetRenderTargetData, -+ WineNineDevice9_GetFrontBufferData, -+ WineNineDevice9_StretchRect, -+ WineNineDevice9_ColorFill, -+ WineNineDevice9_CreateOffscreenPlainSurface, -+ WineNineDevice9_SetRenderTarget, -+ WineNineDevice9_GetRenderTarget, -+ WineNineDevice9_SetDepthStencilSurface, -+ WineNineDevice9_GetDepthStencilSurface, -+ WineNineDevice9_BeginScene, -+ WineNineDevice9_EndScene, -+ WineNineDevice9_Clear, -+ WineNineDevice9_SetTransform, -+ WineNineDevice9_GetTransform, -+ WineNineDevice9_MultiplyTransform, -+ WineNineDevice9_SetViewport, -+ WineNineDevice9_GetViewport, -+ WineNineDevice9_SetMaterial, -+ WineNineDevice9_GetMaterial, -+ WineNineDevice9_SetLight, -+ WineNineDevice9_GetLight, -+ WineNineDevice9_LightEnable, -+ WineNineDevice9_GetLightEnable, -+ WineNineDevice9_SetClipPlane, -+ WineNineDevice9_GetClipPlane, -+ WineNineDevice9_SetRenderState, -+ WineNineDevice9_GetRenderState, -+ WineNineDevice9_CreateStateBlock, -+ WineNineDevice9_BeginStateBlock, -+ WineNineDevice9_EndStateBlock, -+ WineNineDevice9_SetClipStatus, -+ WineNineDevice9_GetClipStatus, -+ WineNineDevice9_GetTexture, -+ WineNineDevice9_SetTexture, -+ WineNineDevice9_GetTextureStageState, -+ WineNineDevice9_SetTextureStageState, -+ WineNineDevice9_GetSamplerState, -+ WineNineDevice9_SetSamplerState, -+ WineNineDevice9_ValidateDevice, -+ WineNineDevice9_SetPaletteEntries, -+ WineNineDevice9_GetPaletteEntries, -+ WineNineDevice9_SetCurrentTexturePalette, -+ WineNineDevice9_GetCurrentTexturePalette, -+ WineNineDevice9_SetScissorRect, -+ WineNineDevice9_GetScissorRect, -+ WineNineDevice9_SetSoftwareVertexProcessing, -+ WineNineDevice9_GetSoftwareVertexProcessing, -+ WineNineDevice9_SetNPatchMode, -+ WineNineDevice9_GetNPatchMode, -+ WineNineDevice9_DrawPrimitive, -+ WineNineDevice9_DrawIndexedPrimitive, -+ WineNineDevice9_DrawPrimitiveUP, -+ WineNineDevice9_DrawIndexedPrimitiveUP, -+ WineNineDevice9_ProcessVertices, -+ WineNineDevice9_CreateVertexDeclaration, -+ WineNineDevice9_SetVertexDeclaration, -+ WineNineDevice9_GetVertexDeclaration, -+ WineNineDevice9_SetFVF, -+ WineNineDevice9_GetFVF, -+ WineNineDevice9_CreateVertexShader, -+ WineNineDevice9_SetVertexShader, -+ WineNineDevice9_GetVertexShader, -+ WineNineDevice9_SetVertexShaderConstantF, -+ WineNineDevice9_GetVertexShaderConstantF, -+ WineNineDevice9_SetVertexShaderConstantI, -+ WineNineDevice9_GetVertexShaderConstantI, -+ WineNineDevice9_SetVertexShaderConstantB, -+ WineNineDevice9_GetVertexShaderConstantB, -+ WineNineDevice9_SetStreamSource, -+ WineNineDevice9_GetStreamSource, -+ WineNineDevice9_SetStreamSourceFreq, -+ WineNineDevice9_GetStreamSourceFreq, -+ WineNineDevice9_SetIndices, -+ WineNineDevice9_GetIndices, -+ WineNineDevice9_CreatePixelShader, -+ WineNineDevice9_SetPixelShader, -+ WineNineDevice9_GetPixelShader, -+ WineNineDevice9_SetPixelShaderConstantF, -+ WineNineDevice9_GetPixelShaderConstantF, -+ WineNineDevice9_SetPixelShaderConstantI, -+ WineNineDevice9_GetPixelShaderConstantI, -+ WineNineDevice9_SetPixelShaderConstantB, -+ WineNineDevice9_GetPixelShaderConstantB, -+ WineNineDevice9_DrawRectPatch, -+ WineNineDevice9_DrawTriPatch, -+ WineNineDevice9_DeletePatch, -+ WineNineDevice9_CreateQuery, -+ WineNineDevice9_SetConvolutionMonoKernel, -+ WineNineDevice9_ComposeRects, -+ WineNineDevice9_PresentEx, -+ WineNineDevice9_GetGPUThreadPriority, -+ WineNineDevice9_SetGPUThreadPriority, -+ WineNineDevice9_WaitForVBlank, -+ WineNineDevice9_CheckResourceResidency, -+ WineNineDevice9_SetMaximumFrameLatency, -+ WineNineDevice9_GetMaximumFrameLatency, -+ WineNineDevice9_CheckDeviceState, -+ WineNineDevice9_CreateRenderTargetEx, -+ WineNineDevice9_CreateOffscreenPlainSurfaceEx, -+ WineNineDevice9_CreateDepthStencilSurfaceEx, -+ WineNineDevice9_ResetEx, -+ WineNineDevice9_GetDisplayModeEx -+}; -+ -+IDirect3DDevice9ExVtbl *get_device_vtable() -+{ -+ return &WineNineDevice9_vtable; -+} -diff --git a/dlls/d3d9-nine/device_wrap.h b/dlls/d3d9-nine/device_wrap.h -new file mode 100644 -index 0000000000..8f5e7206a0 ---- /dev/null -+++ b/dlls/d3d9-nine/device_wrap.h -@@ -0,0 +1,26 @@ -+/* -+ * Copyright 2016 Axel Davy -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#ifndef __NINE_DEVICE_WRAP_H -+#define __NINE_DEVICE_WRAP_H -+ -+#include -+ -+IDirect3DDevice9ExVtbl *get_device_vtable(void); -+ -+#endif /* __NINE_DEVICE_WRAP_H */ -diff --git a/dlls/d3d9-nine/dri3.c b/dlls/d3d9-nine/dri3.c -new file mode 100644 -index 0000000000..3946e7f8bf ---- /dev/null -+++ b/dlls/d3d9-nine/dri3.c -@@ -0,0 +1,1426 @@ -+/* -+ * Wine DRI3 interface -+ * -+ * Copyright 2014-2015 Axel Davy -+ * Copyright 2015 Patrick Rudolph -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+ -+#include "config.h" -+#include "wine/debug.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(d3d9nine); -+ -+#include "dri3.h" -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "winbase.h" -+ -+#ifdef D3D9NINE_DRI2 -+#include -+ -+#define BOOL X_BOOL -+#define BYTE X_BYTE -+#define INT8 X_INT8 -+#define INT16 X_INT16 -+#define INT32 X_INT32 -+#define INT64 X_INT64 -+#include -+#undef BOOL -+#undef BYTE -+#undef INT8 -+#undef INT16 -+#undef INT32 -+#undef INT64 -+#undef LONG64 -+ -+#include -+#include -+#include -+#include -+#define GL_GLEXT_PROTOTYPES 1 -+#define EGL_EGLEXT_PROTOTYPES 1 -+#define GL_GLEXT_LEGACY 1 -+ -+/* workaround for broken ABI on x86_64 due to windef.h */ -+#undef APIENTRY -+#undef APIENTRYP -+#include -+ -+/* workaround gl header bug */ -+#define glBlendColor glBlendColorLEV -+#define glBlendEquation glBlendEquationLEV -+#include -+#include -+#include -+#include -+#include -+ -+static EGLDisplay display = NULL; -+static int display_ref = 0; -+ -+struct DRI2priv { -+ Display *dpy; -+ EGLDisplay display; -+ EGLContext context; -+ PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES_func; -+ PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR_func; -+ PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR_func; -+}; -+#endif -+ -+struct PRESENTPriv { -+ xcb_connection_t *xcb_connection; -+ xcb_connection_t *xcb_connection_bis; /* to avoid libxcb thread bugs, use a different connection to present pixmaps */ -+ XID window; -+ uint64_t last_msc; -+ uint64_t last_target; -+ uint32_t last_serial_given; -+ xcb_special_event_t *special_event; -+ PRESENTPixmapPriv *first_present_priv; -+ int pixmap_present_pending; -+ BOOL idle_notify_since_last_check; -+ BOOL notify_with_serial_pending; -+ CRITICAL_SECTION mutex_present; /* protect readind/writing present_priv things */ -+ CRITICAL_SECTION mutex_xcb_wait; -+ BOOL xcb_wait; -+}; -+ -+struct PRESENTPixmapPriv { -+ PRESENTpriv *present_priv; -+ Pixmap pixmap; -+ BOOL released; -+ unsigned int width; -+ unsigned int height; -+ unsigned int depth; -+ unsigned int present_complete_pending; -+ uint32_t serial; -+#ifdef D3D9NINE_DRI2 -+ struct { -+ BOOL is_dri2; -+ struct DRI2priv *dri2_priv; -+ GLuint fbo_read; -+ GLuint fbo_write; -+ GLuint texture_read; -+ GLuint texture_write; -+ } dri2_info; -+#endif -+ BOOL last_present_was_flip; -+ PRESENTPixmapPriv *next; -+}; -+ -+BOOL DRI3CheckExtension(Display *dpy, int major, int minor) -+{ -+ xcb_connection_t *xcb_connection = XGetXCBConnection(dpy); -+ xcb_dri3_query_version_cookie_t dri3_cookie; -+ xcb_dri3_query_version_reply_t *dri3_reply; -+ xcb_generic_error_t *error; -+ const xcb_query_extension_reply_t *extension; -+ int fd; -+ -+ xcb_prefetch_extension_data(xcb_connection, &xcb_dri3_id); -+ -+ extension = xcb_get_extension_data(xcb_connection, &xcb_dri3_id); -+ if (!(extension && extension->present)) -+ { -+ ERR("DRI3 extension is not present\n"); -+ return FALSE; -+ } -+ -+ dri3_cookie = xcb_dri3_query_version(xcb_connection, major, minor); -+ -+ dri3_reply = xcb_dri3_query_version_reply(xcb_connection, dri3_cookie, &error); -+ if (!dri3_reply) -+ { -+ free(error); -+ ERR("Issue getting requested version of DRI3: %d,%d\n", major, minor); -+ return FALSE; -+ } -+ -+ if (!DRI3Open(dpy, DefaultScreen(dpy), &fd)) -+ { -+ ERR("DRI3 advertised, but not working\n"); -+ return FALSE; -+ } -+ close(fd); -+ -+ TRACE("DRI3 version %d,%d found. %d %d requested\n", major, minor, -+ (int)dri3_reply->major_version, (int)dri3_reply->minor_version); -+ free(dri3_reply); -+ -+ return TRUE; -+} -+ -+#ifdef D3D9NINE_DRI2 -+ -+BOOL DRI2FallbackInit(Display *dpy, struct DRI2priv **priv) -+{ -+ PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES_func; -+ PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR_func; -+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT_func; -+ PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR_func; -+ EGLint major, minor; -+ EGLConfig config; -+ EGLContext context; -+ EGLint i; -+ EGLBoolean b; -+ EGLenum current_api = 0; -+ const char *extensions; -+ EGLint config_attribs[] = { -+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, -+ EGL_NONE -+ }; -+ EGLint context_compatibility_attribs[] = { -+ EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR, -+ EGL_NONE -+ }; -+ -+ current_api = eglQueryAPI(); -+ eglGetPlatformDisplayEXT_func = (PFNEGLGETPLATFORMDISPLAYEXTPROC) -+ eglGetProcAddress("eglGetPlatformDisplayEXT"); -+ -+ if (!eglGetPlatformDisplayEXT_func) -+ return FALSE; -+ if (!display) -+ display = eglGetPlatformDisplayEXT_func(EGL_PLATFORM_X11_EXT, dpy, NULL); -+ if (!display) -+ return FALSE; -+ /* count references on display for multi device setups */ -+ display_ref++; -+ -+ if (eglInitialize(display, &major, &minor) != EGL_TRUE) -+ goto clean_egl_display; -+ -+ extensions = eglQueryString(display, EGL_CLIENT_APIS); -+ if (!extensions || !strstr(extensions, "OpenGL")) -+ goto clean_egl_display; -+ -+ extensions = eglQueryString(display, EGL_EXTENSIONS); -+ if (!extensions || !strstr(extensions, "EGL_EXT_image_dma_buf_import") || -+ !strstr(extensions, "EGL_KHR_create_context") || -+ !strstr(extensions, "EGL_KHR_surfaceless_context") || -+ !strstr(extensions, "EGL_KHR_image_base")) -+ goto clean_egl_display; -+ -+ if (!eglChooseConfig(display, config_attribs, &config, 1, &i)) -+ goto clean_egl_display; -+ -+ b = eglBindAPI(EGL_OPENGL_API); -+ if (b == EGL_FALSE) -+ goto clean_egl_display; -+ context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_compatibility_attribs); -+ if (context == EGL_NO_CONTEXT) -+ goto clean_egl_display; -+ -+ glEGLImageTargetTexture2DOES_func = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) -+ eglGetProcAddress("glEGLImageTargetTexture2DOES"); -+ -+ eglCreateImageKHR_func = (PFNEGLCREATEIMAGEKHRPROC) -+ eglGetProcAddress("eglCreateImageKHR"); -+ -+ eglDestroyImageKHR_func = (PFNEGLDESTROYIMAGEKHRPROC) -+ eglGetProcAddress("eglDestroyImageKHR"); -+ -+ if (!eglCreateImageKHR_func || -+ !glEGLImageTargetTexture2DOES_func || -+ !eglDestroyImageKHR_func) -+ { -+ ERR("eglGetProcAddress failed !"); -+ goto clean_egl; -+ } -+ -+ eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ -+ *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(struct DRI2priv)); -+ if (!*priv) -+ goto clean_egl; -+ (*priv)->dpy = dpy; -+ (*priv)->display = display; -+ (*priv)->context = context; -+ (*priv)->glEGLImageTargetTexture2DOES_func = glEGLImageTargetTexture2DOES_func; -+ (*priv)->eglCreateImageKHR_func = eglCreateImageKHR_func; -+ (*priv)->eglDestroyImageKHR_func = eglDestroyImageKHR_func; -+ eglBindAPI(current_api); -+ return TRUE; -+ -+clean_egl: -+ eglDestroyContext(display, context); -+ -+clean_egl_display: -+ eglTerminate(display); -+ eglBindAPI(current_api); -+ return FALSE; -+} -+ -+/* hypothesis: at this step all textures, etc are destroyed */ -+void DRI2FallbackDestroy(struct DRI2priv *priv) -+{ -+ EGLenum current_api; -+ current_api = eglQueryAPI(); -+ eglBindAPI(EGL_OPENGL_API); -+ eglMakeCurrent(priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ eglDestroyContext(priv->display, priv->context); -+ if (display) -+ { -+ /* destroy display connection with last device */ -+ display_ref--; -+ if (!display_ref) -+ { -+ eglTerminate(display); -+ display = NULL; -+ } -+ } -+ eglBindAPI(current_api); -+ HeapFree(GetProcessHeap(), 0, priv); -+} -+ -+BOOL DRI2FallbackCheckSupport(Display *dpy) -+{ -+ struct DRI2priv *priv; -+ int fd; -+ if (!DRI2FallbackInit(dpy, &priv)) -+ return FALSE; -+ DRI2FallbackDestroy(priv); -+ if (!DRI2FallbackOpen(dpy, DefaultScreen(dpy), &fd)) -+ return FALSE; -+ close(fd); -+ return TRUE; -+} -+ -+#endif -+ -+BOOL PRESENTCheckExtension(Display *dpy, int major, int minor) -+{ -+ xcb_connection_t *xcb_connection = XGetXCBConnection(dpy); -+ xcb_present_query_version_cookie_t present_cookie; -+ xcb_present_query_version_reply_t *present_reply; -+ xcb_generic_error_t *error; -+ const xcb_query_extension_reply_t *extension; -+ -+ xcb_prefetch_extension_data(xcb_connection, &xcb_present_id); -+ -+ extension = xcb_get_extension_data(xcb_connection, &xcb_present_id); -+ if (!(extension && extension->present)) -+ { -+ ERR("PRESENT extension is not present\n"); -+ return FALSE; -+ } -+ -+ present_cookie = xcb_present_query_version(xcb_connection, major, minor); -+ -+ present_reply = xcb_present_query_version_reply(xcb_connection, present_cookie, &error); -+ if (!present_reply) -+ { -+ free(error); -+ ERR("Issue getting requested version of PRESENT: %d,%d\n", major, minor); -+ return FALSE; -+ } -+ -+ TRACE("PRESENT version %d,%d found. %u %u requested\n", major, minor, -+ present_reply->major_version, present_reply->minor_version); -+ -+ free(present_reply); -+ -+ return TRUE; -+} -+ -+BOOL DRI3Open(Display *dpy, int screen, int *device_fd) -+{ -+ xcb_dri3_open_cookie_t cookie; -+ xcb_dri3_open_reply_t *reply; -+ xcb_connection_t *xcb_connection = XGetXCBConnection(dpy); -+ int fd; -+ Window root = RootWindow(dpy, screen); -+ -+ cookie = xcb_dri3_open(xcb_connection, root, 0); -+ -+ reply = xcb_dri3_open_reply(xcb_connection, cookie, NULL); -+ if (!reply) -+ return FALSE; -+ -+ if (reply->nfd != 1) -+ { -+ free(reply); -+ return FALSE; -+ } -+ -+ fd = xcb_dri3_open_reply_fds(xcb_connection, reply)[0]; -+ fcntl(fd, F_SETFD, FD_CLOEXEC); -+ -+ *device_fd = fd; -+ free(reply); -+ -+ return TRUE; -+} -+ -+#ifdef D3D9NINE_DRI2 -+ -+static XExtensionInfo _dri2_info_data; -+static XExtensionInfo *dri2_info = &_dri2_info_data; -+static char dri2_name[] = DRI2_NAME; -+ -+#define DRI2CheckExtension(dpy, i, val) \ -+ XextCheckExtension(dpy, i, dri2_name, val) -+ -+static int close_display(Display *dpy, XExtCodes *codes); -+static Bool wire_to_event(Display *dpy, XEvent *re, xEvent *event); -+static Status event_to_wire(Display *dpy, XEvent *re, xEvent *event); -+static int error( Display *dpy, xError *err, XExtCodes *codes, int *ret_code ); -+ -+static XExtensionHooks dri2_hooks = { -+ NULL, /* create_gc */ -+ NULL, /* copy_gc */ -+ NULL, /* flush_gc */ -+ NULL, /* free_gc */ -+ NULL, /* create_font */ -+ NULL, /* free_font */ -+ close_display, /* close_display */ -+ wire_to_event, /* wire_to_event */ -+ event_to_wire, /* event_to_wire */ -+ error, /* error */ -+ NULL, /* error_string */ -+}; -+static XEXT_GENERATE_CLOSE_DISPLAY(close_display, dri2_info); -+static XEXT_GENERATE_FIND_DISPLAY(find_display, dri2_info, -+ dri2_name, &dri2_hooks, 0, NULL); -+static Bool wire_to_event(Display *dpy, XEvent *re, xEvent *event) -+{ -+ XExtDisplayInfo *info = find_display(dpy); -+ DRI2CheckExtension(dpy, info, False); -+ TRACE("dri2 wire_to_event\n"); -+ return False; -+} -+ -+static Status event_to_wire(Display *dpy, XEvent *re, xEvent *event) -+{ -+ XExtDisplayInfo *info = find_display(dpy); -+ DRI2CheckExtension(dpy, info, False); -+ TRACE("dri2 event_to_wire\n"); -+ return False; -+} -+ -+static int error(Display *dpy, xError *err, XExtCodes *codes, int *ret_code) -+{ -+ TRACE("dri2 error\n"); -+ return False; -+} -+ -+#define XALIGN(x) (((x) + 3) & (~3)) -+ -+static BOOL DRI2Connect(Display *dpy, XID window, unsigned driver_type, char **device) -+{ -+ XExtDisplayInfo *info = find_display(dpy); -+ xDRI2ConnectReply rep; -+ xDRI2ConnectReq *req; -+ int dev_len, driv_len; -+ char *driver; -+ -+ DRI2CheckExtension(dpy, info, False); -+ -+ *device = NULL; -+ -+ LockDisplay(dpy); -+ GetReq(DRI2Connect, req); -+ req->reqType = info->codes->major_opcode; -+ req->dri2ReqType = X_DRI2Connect; -+ req->window = window; -+ req->driverType = driver_type; -+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) -+ { -+ UnlockDisplay(dpy); -+ SyncHandle(); -+ return False; -+ } -+ -+ /* check string lengths */ -+ dev_len = rep.deviceNameLength; -+ driv_len = rep.driverNameLength; -+ if (dev_len == 0 || driv_len == 0) -+ { -+ _XEatData(dpy, XALIGN(dev_len) + XALIGN(driv_len)); -+ UnlockDisplay(dpy); -+ SyncHandle(); -+ return False; -+ } -+ -+ /* read out driver */ -+ driver = HeapAlloc(GetProcessHeap(), 0, driv_len + 1); -+ if (!driver) -+ { -+ _XEatData(dpy, XALIGN(dev_len) + XALIGN(driv_len)); -+ UnlockDisplay(dpy); -+ SyncHandle(); -+ return False; -+ } -+ _XReadPad(dpy, driver, driv_len); -+ HeapFree(GetProcessHeap(), 0, driver); /* we don't need the driver */ -+ -+ /* read out device */ -+ *device = HeapAlloc(GetProcessHeap(), 0, dev_len + 1); -+ if (!*device) -+ { -+ _XEatData(dpy, XALIGN(dev_len)); -+ UnlockDisplay(dpy); -+ SyncHandle(); -+ return False; -+ } -+ _XReadPad(dpy, *device, dev_len); -+ (*device)[dev_len] = '\0'; -+ -+ UnlockDisplay(dpy); -+ SyncHandle(); -+ -+ return True; -+} -+ -+static Bool DRI2Authenticate(Display *dpy, XID window, uint32_t token) -+{ -+ XExtDisplayInfo *info = find_display(dpy); -+ xDRI2AuthenticateReply rep; -+ xDRI2AuthenticateReq *req; -+ -+ DRI2CheckExtension(dpy, info, False); -+ -+ LockDisplay(dpy); -+ GetReq(DRI2Authenticate, req); -+ req->reqType = info->codes->major_opcode; -+ req->dri2ReqType = X_DRI2Authenticate; -+ req->window = window; -+ req->magic = token; -+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) -+ { -+ UnlockDisplay(dpy); -+ SyncHandle(); -+ return False; -+ } -+ UnlockDisplay(dpy); -+ SyncHandle(); -+ -+ return rep.authenticated ? True : False; -+} -+ -+BOOL DRI2FallbackOpen(Display *dpy, int screen, int *device_fd) -+{ -+ char *device; -+ int fd; -+ Window root = RootWindow(dpy, screen); -+ drm_auth_t auth; -+ -+ if (!DRI2Connect(dpy, root, DRI2DriverDRI, &device)) -+ return FALSE; -+ -+ fd = open(device, O_RDWR); -+ HeapFree(GetProcessHeap(), 0, device); -+ if (fd < 0) -+ return FALSE; -+ -+ if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth) != 0) -+ { -+ close(fd); -+ return FALSE; -+ } -+ -+ if (!DRI2Authenticate(dpy, root, auth.magic)) -+ { -+ close(fd); -+ return FALSE; -+ } -+ -+ *device_fd = fd; -+ -+ return TRUE; -+} -+ -+#endif -+ -+ -+BOOL DRI3PixmapFromDmaBuf(Display *dpy, int screen, int fd, int width, int height, -+ int stride, int depth, int bpp, Pixmap *pixmap) -+{ -+ xcb_connection_t *xcb_connection = XGetXCBConnection(dpy); -+ Window root = RootWindow(dpy, screen); -+ xcb_void_cookie_t cookie; -+ xcb_generic_error_t *error; -+ -+ cookie = xcb_dri3_pixmap_from_buffer_checked(xcb_connection, -+ (*pixmap = xcb_generate_id(xcb_connection)), root, 0, -+ width, height, stride, depth, bpp, fd); -+ -+ error = xcb_request_check(xcb_connection, cookie); /* performs a flush */ -+ if (error) -+ { -+ ERR("Error using DRI3 to convert a DmaBufFd to pixmap\n"); -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+BOOL DRI3DmaBufFromPixmap(Display *dpy, Pixmap pixmap, int *fd, int *width, int *height, -+ int *stride, int *depth, int *bpp) -+{ -+ xcb_connection_t *xcb_connection = XGetXCBConnection(dpy); -+ xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie; -+ xcb_dri3_buffer_from_pixmap_reply_t *bp_reply; -+ -+ bp_cookie = xcb_dri3_buffer_from_pixmap(xcb_connection, pixmap); -+ bp_reply = xcb_dri3_buffer_from_pixmap_reply(xcb_connection, bp_cookie, NULL); -+ if (!bp_reply) -+ return FALSE; -+ *fd = xcb_dri3_buffer_from_pixmap_reply_fds(xcb_connection, bp_reply)[0]; -+ *width = bp_reply->width; -+ *height = bp_reply->height; -+ *stride = bp_reply->stride; -+ *depth = bp_reply->depth; -+ *bpp = bp_reply->depth; -+ return TRUE; -+} -+ -+static PRESENTPixmapPriv *PRESENTFindPixmapPriv(PRESENTpriv *present_priv, uint32_t serial) -+{ -+ PRESENTPixmapPriv *current = present_priv->first_present_priv; -+ -+ while (current) -+ { -+ if (current->serial == serial) -+ return current; -+ current = current->next; -+ } -+ return NULL; -+} -+ -+static void PRESENThandle_events(PRESENTpriv *present_priv, xcb_present_generic_event_t *ge) -+{ -+ PRESENTPixmapPriv *present_pixmap_priv = NULL; -+ -+ switch (ge->evtype) -+ { -+ case XCB_PRESENT_COMPLETE_NOTIFY: -+ { -+ xcb_present_complete_notify_event_t *ce = (void *) ge; -+ if (ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC) -+ { -+ if (ce->serial) -+ present_priv->notify_with_serial_pending = FALSE; -+ free(ce); -+ return; -+ } -+ present_pixmap_priv = PRESENTFindPixmapPriv(present_priv, ce->serial); -+ if (!present_pixmap_priv || ce->kind != XCB_PRESENT_COMPLETE_KIND_PIXMAP) -+ { -+ ERR("FATAL ERROR: PRESENT handling failed\n"); -+ free(ce); -+ return; -+ } -+ present_pixmap_priv->present_complete_pending--; -+ switch (ce->mode) -+ { -+ case XCB_PRESENT_COMPLETE_MODE_FLIP: -+ present_pixmap_priv->last_present_was_flip = TRUE; -+ break; -+ case XCB_PRESENT_COMPLETE_MODE_COPY: -+ present_pixmap_priv->last_present_was_flip = FALSE; -+ break; -+ } -+ present_priv->pixmap_present_pending--; -+ present_priv->last_msc = ce->msc; -+ break; -+ } -+ case XCB_PRESENT_EVENT_IDLE_NOTIFY: -+ { -+ xcb_present_idle_notify_event_t *ie = (void *) ge; -+ present_pixmap_priv = PRESENTFindPixmapPriv(present_priv, ie->serial); -+ if (!present_pixmap_priv || present_pixmap_priv->pixmap != ie->pixmap) -+ { -+ ERR("FATAL ERROR: PRESENT handling failed\n"); -+ free(ie); -+ return; -+ } -+ present_pixmap_priv->released = TRUE; -+ present_priv->idle_notify_since_last_check = TRUE; -+ break; -+ } -+ } -+ free(ge); -+} -+ -+static void PRESENTflush_events(PRESENTpriv *present_priv, BOOL assert_no_other_thread_waiting) -+{ -+ xcb_generic_event_t *ev; -+ -+ if ((present_priv->xcb_wait && !assert_no_other_thread_waiting) || /* don't steal events to someone waiting */ -+ !present_priv->special_event) -+ return; -+ -+ while ((ev = xcb_poll_for_special_event(present_priv->xcb_connection, -+ present_priv->special_event)) != NULL) -+ { -+ PRESENThandle_events(present_priv, (void *) ev); -+ } -+} -+ -+static BOOL PRESENTwait_events(PRESENTpriv *present_priv, BOOL allow_other_threads) -+{ -+ xcb_generic_event_t *ev; -+ -+ if (allow_other_threads) -+ { -+ present_priv->xcb_wait = TRUE; -+ EnterCriticalSection(&present_priv->mutex_xcb_wait); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ } -+ ev = xcb_wait_for_special_event(present_priv->xcb_connection, present_priv->special_event); -+ if (allow_other_threads) -+ { -+ LeaveCriticalSection(&present_priv->mutex_xcb_wait); -+ EnterCriticalSection(&present_priv->mutex_present); -+ present_priv->xcb_wait = FALSE; -+ } -+ if (!ev) -+ { -+ ERR("FATAL error: xcb had an error\n"); -+ return FALSE; -+ } -+ -+ PRESENThandle_events(present_priv, (void *) ev); -+ return TRUE; -+} -+ -+static struct xcb_connection_t *create_xcb_connection(Display *dpy) -+{ -+ int screen_num = DefaultScreen(dpy); -+ xcb_connection_t *ret; -+ xcb_xfixes_query_version_cookie_t cookie; -+ xcb_xfixes_query_version_reply_t *rep; -+ -+ ret = xcb_connect(DisplayString(dpy), &screen_num); -+ cookie = xcb_xfixes_query_version_unchecked(ret, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION); -+ rep = xcb_xfixes_query_version_reply(ret, cookie, NULL); -+ if (rep) -+ free(rep); -+ return ret; -+} -+ -+BOOL PRESENTInit(Display *dpy, PRESENTpriv **present_priv) -+{ -+ *present_priv = (PRESENTpriv *) HeapAlloc(GetProcessHeap(), -+ HEAP_ZERO_MEMORY, sizeof(PRESENTpriv)); -+ -+ if (!*present_priv) -+ return FALSE; -+ -+ (*present_priv)->xcb_connection = create_xcb_connection(dpy); -+ (*present_priv)->xcb_connection_bis = create_xcb_connection(dpy); -+ -+ InitializeCriticalSection(&(*present_priv)->mutex_present); -+ InitializeCriticalSection(&(*present_priv)->mutex_xcb_wait); -+ return TRUE; -+} -+ -+static void PRESENTForceReleases(PRESENTpriv *present_priv) -+{ -+ PRESENTPixmapPriv *current = NULL; -+ -+ if (!present_priv->window) -+ return; -+ -+ /* There should be no other thread listening for events here. -+ * This can happen when hDestWindowOverride changes without reset. -+ * This case should never happen, but can happen in theory.*/ -+ if (present_priv->xcb_wait) -+ { -+ xcb_present_notify_msc(present_priv->xcb_connection, present_priv->window, 0, 0, 0, 0); -+ xcb_flush(present_priv->xcb_connection); -+ EnterCriticalSection(&present_priv->mutex_xcb_wait); -+ LeaveCriticalSection(&present_priv->mutex_xcb_wait); -+ /* the problem here is that we don't have access to the event the other thread got. -+ * It is either presented event, idle event or notify event. -+ */ -+ while (present_priv->pixmap_present_pending >= 2) -+ PRESENTwait_events(present_priv, FALSE); -+ PRESENTflush_events(present_priv, TRUE); -+ /* Remaining events to come can be a pair of present/idle, -+ * or an idle, or nothing. To be sure we are after all pixmaps -+ * have been presented, add an event to the queue that can only -+ * be after the present event, then if we receive an event more, -+ * we are sure all pixmaps were presented */ -+ present_priv->notify_with_serial_pending = TRUE; -+ xcb_present_notify_msc(present_priv->xcb_connection, present_priv->window, -+ 1, present_priv->last_target + 5, 0, 0); -+ -+ xcb_flush(present_priv->xcb_connection); -+ while (present_priv->notify_with_serial_pending) -+ PRESENTwait_events(present_priv, FALSE); -+ /* Now we are sure we are not expecting any new event */ -+ } -+ else -+ { -+ while (present_priv->pixmap_present_pending) /* wait all sent pixmaps are presented */ -+ PRESENTwait_events(present_priv, FALSE); -+ PRESENTflush_events(present_priv, TRUE); /* may be remaining idle event */ -+ /* Since idle events are send with the complete events when it is not flips, -+ * we are not expecting any new event here */ -+ } -+ -+ current = present_priv->first_present_priv; -+ while (current) -+ { -+ if (!current->released) -+ { -+ if (!current->last_present_was_flip && !present_priv->xcb_wait) -+ { -+ ERR("ERROR: a pixmap seems not released by PRESENT for no reason. Code bug.\n"); -+ } -+ else -+ { -+ /* Present the same pixmap with a non-valid part to force the copy mode and the releases */ -+ xcb_xfixes_region_t valid, update; -+ xcb_rectangle_t rect_update; -+ rect_update.x = 0; -+ rect_update.y = 0; -+ rect_update.width = 8; -+ rect_update.height = 1; -+ valid = xcb_generate_id(present_priv->xcb_connection); -+ update = xcb_generate_id(present_priv->xcb_connection); -+ xcb_xfixes_create_region(present_priv->xcb_connection, valid, 1, &rect_update); -+ xcb_xfixes_create_region(present_priv->xcb_connection, update, 1, &rect_update); -+ /* here we know the pixmap has been presented. Thus if it is on screen, -+ * the following request can only make it released by the server if it is not */ -+ xcb_present_pixmap(present_priv->xcb_connection, present_priv->window, -+ current->pixmap, 0, valid, update, 0, 0, None, None, -+ None, XCB_PRESENT_OPTION_COPY | XCB_PRESENT_OPTION_ASYNC, 0, 0, 0, 0, NULL); -+ xcb_flush(present_priv->xcb_connection); -+ PRESENTwait_events(present_priv, FALSE); /* by assumption this can only be idle event */ -+ PRESENTflush_events(present_priv, TRUE); /* Shoudln't be needed */ -+ } -+ } -+ current = current->next; -+ } -+ /* Now all pixmaps are released (possibility if xcb_wait is true that one is not aware yet), -+ * and we don't expect any new Present event to come from Xserver */ -+} -+ -+static void PRESENTFreeXcbQueue(PRESENTpriv *present_priv) -+{ -+ if (present_priv->window) -+ { -+ xcb_unregister_for_special_event(present_priv->xcb_connection, present_priv->special_event); -+ present_priv->last_msc = 0; -+ present_priv->last_target = 0; -+ present_priv->special_event = NULL; -+ } -+} -+ -+static BOOL PRESENTPrivChangeWindow(PRESENTpriv *present_priv, XID window) -+{ -+ xcb_void_cookie_t cookie; -+ xcb_generic_error_t *error; -+ xcb_present_event_t eid; -+ -+ PRESENTForceReleases(present_priv); -+ PRESENTFreeXcbQueue(present_priv); -+ present_priv->window = window; -+ -+ if (window) -+ { -+ cookie = xcb_present_select_input_checked(present_priv->xcb_connection, -+ (eid = xcb_generate_id(present_priv->xcb_connection)), window, -+ XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY | XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY); -+ -+ present_priv->special_event = xcb_register_for_special_xge(present_priv->xcb_connection, -+ &xcb_present_id, eid, NULL); -+ -+ error = xcb_request_check(present_priv->xcb_connection, cookie); /* performs a flush */ -+ if (error || !present_priv->special_event) -+ { -+ ERR("FAILED to use the X PRESENT extension. Was the destination a window ?\n"); -+ if (present_priv->special_event) -+ xcb_unregister_for_special_event(present_priv->xcb_connection, present_priv->special_event); -+ present_priv->special_event = NULL; -+ present_priv->window = 0; -+ } -+ } -+ return (present_priv->window != 0); -+} -+ -+/* Destroy the content, except the link and the struct mem */ -+static void PRESENTDestroyPixmapContent(Display *dpy, PRESENTPixmapPriv *present_pixmap) -+{ -+ XFreePixmap(dpy, present_pixmap->pixmap); -+#ifdef D3D9NINE_DRI2 -+ if (present_pixmap->dri2_info.is_dri2) -+ { -+ struct DRI2priv *dri2_priv = present_pixmap->dri2_info.dri2_priv; -+ EGLenum current_api; -+ current_api = eglQueryAPI(); -+ eglBindAPI(EGL_OPENGL_API); -+ if (eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, dri2_priv->context)) -+ { -+ glDeleteFramebuffers(1, &present_pixmap->dri2_info.fbo_read); -+ glDeleteFramebuffers(1, &present_pixmap->dri2_info.fbo_write); -+ glDeleteTextures(1, &present_pixmap->dri2_info.texture_read); -+ glDeleteTextures(1, &present_pixmap->dri2_info.texture_write); -+ } -+ else -+ ERR("eglMakeCurrent failed with 0x%0X\n", eglGetError()); -+ -+ eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ eglBindAPI(current_api); -+ } -+#endif -+} -+ -+void PRESENTDestroy(Display *dpy, PRESENTpriv *present_priv) -+{ -+ PRESENTPixmapPriv *current = NULL; -+ -+ EnterCriticalSection(&present_priv->mutex_present); -+ -+ PRESENTForceReleases(present_priv); -+ -+ current = present_priv->first_present_priv; -+ while (current) -+ { -+ PRESENTPixmapPriv *next = current->next; -+ PRESENTDestroyPixmapContent(dpy, current); -+ HeapFree(GetProcessHeap(), 0, current); -+ current = next; -+ } -+ -+ PRESENTFreeXcbQueue(present_priv); -+ -+ xcb_disconnect(present_priv->xcb_connection); -+ xcb_disconnect(present_priv->xcb_connection_bis); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ DeleteCriticalSection(&present_priv->mutex_present); -+ DeleteCriticalSection(&present_priv->mutex_xcb_wait); -+ -+ HeapFree(GetProcessHeap(), 0, present_priv); -+} -+ -+BOOL PRESENTPixmapInit(PRESENTpriv *present_priv, Pixmap pixmap, PRESENTPixmapPriv **present_pixmap_priv) -+{ -+ xcb_get_geometry_cookie_t cookie; -+ xcb_get_geometry_reply_t *reply; -+ -+ cookie = xcb_get_geometry(present_priv->xcb_connection, pixmap); -+ reply = xcb_get_geometry_reply(present_priv->xcb_connection, cookie, NULL); -+ -+ if (!reply) -+ return FALSE; -+ -+ *present_pixmap_priv = (PRESENTPixmapPriv *) HeapAlloc(GetProcessHeap(), -+ HEAP_ZERO_MEMORY, sizeof(PRESENTPixmapPriv)); -+ -+ if (!*present_pixmap_priv) -+ { -+ free(reply); -+ return FALSE; -+ } -+ EnterCriticalSection(&present_priv->mutex_present); -+ -+ (*present_pixmap_priv)->released = TRUE; -+ (*present_pixmap_priv)->pixmap = pixmap; -+ (*present_pixmap_priv)->present_priv = present_priv; -+ (*present_pixmap_priv)->next = present_priv->first_present_priv; -+ (*present_pixmap_priv)->width = reply->width; -+ (*present_pixmap_priv)->height = reply->height; -+ (*present_pixmap_priv)->depth = reply->depth; -+#ifdef D3D9NINE_DRI2 -+ (*present_pixmap_priv)->dri2_info.is_dri2 = FALSE; -+#endif -+ free(reply); -+ -+ present_priv->last_serial_given++; -+ (*present_pixmap_priv)->serial = present_priv->last_serial_given; -+ present_priv->first_present_priv = *present_pixmap_priv; -+ -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return TRUE; -+} -+ -+#ifdef D3D9NINE_DRI2 -+ -+BOOL DRI2FallbackPRESENTPixmap(PRESENTpriv *present_priv, struct DRI2priv *dri2_priv, -+ int fd, int width, int height, int stride, int depth, -+ int bpp, PRESENTPixmapPriv **present_pixmap_priv) -+{ -+ Window root = RootWindow(dri2_priv->dpy, DefaultScreen(dri2_priv->dpy)); -+ Pixmap pixmap; -+ EGLImageKHR image; -+ GLuint texture_read, texture_write, fbo_read, fbo_write; -+ EGLint attribs[] = { -+ EGL_WIDTH, 0, -+ EGL_HEIGHT, 0, -+ EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888, -+ EGL_DMA_BUF_PLANE0_FD_EXT, 0, -+ EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, -+ EGL_DMA_BUF_PLANE0_PITCH_EXT, 0, -+ EGL_NONE -+ }; -+ EGLenum current_api = 0; -+ int status; -+ -+ EnterCriticalSection(&present_priv->mutex_present); -+ -+ pixmap = XCreatePixmap(dri2_priv->dpy, root, width, height, 24); -+ if (!pixmap) -+ goto fail; -+ -+ attribs[1] = width; -+ attribs[3] = height; -+ attribs[7] = fd; -+ attribs[11] = stride; -+ -+ current_api = eglQueryAPI(); -+ eglBindAPI(EGL_OPENGL_API); -+ -+ /* We bind the dma-buf to a EGLImage, then to a texture, and then to a fbo. -+ * Note that we can delete the EGLImage, but we shouldn't delete the texture, -+ * else the fbo is invalid */ -+ -+ image = dri2_priv->eglCreateImageKHR_func(dri2_priv->display, -+ EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs); -+ -+ if (image == EGL_NO_IMAGE_KHR) -+ goto fail; -+ close(fd); -+ -+ if (eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, dri2_priv->context)) -+ { -+ glGenTextures(1, &texture_read); -+ glBindTexture(GL_TEXTURE_2D, texture_read); -+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); -+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); -+ dri2_priv->glEGLImageTargetTexture2DOES_func(GL_TEXTURE_2D, image); -+ glGenFramebuffers(1, &fbo_read); -+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_read); -+ glFramebufferTexture2D(GL_FRAMEBUFFER, -+ GL_COLOR_ATTACHMENT0, -+ GL_TEXTURE_2D, texture_read, -+ 0); -+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER); -+ if (status != GL_FRAMEBUFFER_COMPLETE) -+ goto fail; -+ glBindTexture(GL_TEXTURE_2D, 0); -+ dri2_priv->eglDestroyImageKHR_func(dri2_priv->display, image); -+ -+ /* We bind a newly created pixmap (to which we want to copy the content) -+ * to an EGLImage, then to a texture, then to a fbo. */ -+ image = dri2_priv->eglCreateImageKHR_func(dri2_priv->display, -+ dri2_priv->context, -+ EGL_NATIVE_PIXMAP_KHR, -+ (void *)pixmap, NULL); -+ if (image == EGL_NO_IMAGE_KHR) -+ goto fail; -+ -+ glGenTextures(1, &texture_write); -+ glBindTexture(GL_TEXTURE_2D, texture_write); -+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); -+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); -+ dri2_priv->glEGLImageTargetTexture2DOES_func(GL_TEXTURE_2D, image); -+ glGenFramebuffers(1, &fbo_write); -+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_write); -+ glFramebufferTexture2D(GL_FRAMEBUFFER, -+ GL_COLOR_ATTACHMENT0, -+ GL_TEXTURE_2D, texture_write, -+ 0); -+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER); -+ if (status != GL_FRAMEBUFFER_COMPLETE) -+ goto fail; -+ glBindTexture(GL_TEXTURE_2D, 0); -+ dri2_priv->eglDestroyImageKHR_func(dri2_priv->display, image); -+ } -+ else -+ ERR("eglMakeCurrent failed with 0x%0X\n", eglGetError()); -+ -+ eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ -+ *present_pixmap_priv = (PRESENTPixmapPriv *) HeapAlloc(GetProcessHeap(), -+ HEAP_ZERO_MEMORY, sizeof(PRESENTPixmapPriv)); -+ -+ if (!*present_pixmap_priv) -+ goto fail; -+ -+ (*present_pixmap_priv)->released = TRUE; -+ (*present_pixmap_priv)->pixmap = pixmap; -+ (*present_pixmap_priv)->present_priv = present_priv; -+ (*present_pixmap_priv)->next = present_priv->first_present_priv; -+ (*present_pixmap_priv)->width = width; -+ (*present_pixmap_priv)->height = height; -+ (*present_pixmap_priv)->depth = depth; -+ (*present_pixmap_priv)->dri2_info.is_dri2 = TRUE; -+ (*present_pixmap_priv)->dri2_info.dri2_priv = dri2_priv; -+ (*present_pixmap_priv)->dri2_info.fbo_read = fbo_read; -+ (*present_pixmap_priv)->dri2_info.fbo_write = fbo_write; -+ (*present_pixmap_priv)->dri2_info.texture_read = texture_read; -+ (*present_pixmap_priv)->dri2_info.texture_write = texture_write; -+ -+ present_priv->last_serial_given++; -+ (*present_pixmap_priv)->serial = present_priv->last_serial_given; -+ present_priv->first_present_priv = *present_pixmap_priv; -+ -+ eglBindAPI(current_api); -+ -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return TRUE; -+fail: -+ eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ eglBindAPI(current_api); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return FALSE; -+} -+ -+#endif -+ -+BOOL PRESENTTryFreePixmap(Display *dpy, PRESENTPixmapPriv *present_pixmap_priv) -+{ -+ PRESENTpriv *present_priv = present_pixmap_priv->present_priv; -+ PRESENTPixmapPriv *current; -+ -+ EnterCriticalSection(&present_priv->mutex_present); -+ -+ if (!present_pixmap_priv->released || present_pixmap_priv->present_complete_pending) -+ { -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return FALSE; -+ } -+ -+ if (present_priv->first_present_priv == present_pixmap_priv) -+ { -+ present_priv->first_present_priv = present_pixmap_priv->next; -+ goto free_priv; -+ } -+ -+ current = present_priv->first_present_priv; -+ while (current->next != present_pixmap_priv) -+ current = current->next; -+ current->next = present_pixmap_priv->next; -+free_priv: -+ PRESENTDestroyPixmapContent(dpy, present_pixmap_priv); -+ HeapFree(GetProcessHeap(), 0, present_pixmap_priv); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return TRUE; -+} -+ -+BOOL PRESENTHelperCopyFront(Display *dpy, PRESENTPixmapPriv *present_pixmap_priv) -+{ -+ PRESENTpriv *present_priv = present_pixmap_priv->present_priv; -+ xcb_void_cookie_t cookie; -+ xcb_generic_error_t *error; -+ uint32_t v = 0; -+ xcb_gcontext_t gc; -+ -+ EnterCriticalSection(&present_priv->mutex_present); -+ -+ if (!present_priv->window) -+ { -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return FALSE; -+ } -+ -+ gc = xcb_generate_id(present_priv->xcb_connection); -+ xcb_create_gc(present_priv->xcb_connection, gc, present_priv->window, -+ XCB_GC_GRAPHICS_EXPOSURES, &v); -+ -+ cookie = xcb_copy_area_checked(present_priv->xcb_connection, -+ present_priv->window, present_pixmap_priv->pixmap, gc, -+ 0, 0, 0, 0, present_pixmap_priv->width, present_pixmap_priv->height); -+ -+ error = xcb_request_check(present_priv->xcb_connection, cookie); -+ xcb_free_gc(present_priv->xcb_connection, gc); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return (error != NULL); -+} -+ -+BOOL PRESENTPixmap(Display *dpy, XID window, PRESENTPixmapPriv *present_pixmap_priv, -+ const UINT PresentationInterval, const BOOL PresentAsync, const BOOL SwapEffectCopy, -+ const RECT *pSourceRect, const RECT *pDestRect, const RGNDATA *pDirtyRegion) -+{ -+ PRESENTpriv *present_priv = present_pixmap_priv->present_priv; -+#ifdef D3D9NINE_DRI2 -+ struct DRI2priv *dri2_priv = present_pixmap_priv->dri2_info.dri2_priv; -+ EGLenum current_api = 0; -+#endif -+ xcb_void_cookie_t cookie; -+ xcb_generic_error_t *error; -+ int64_t target_msc, presentationInterval; -+ xcb_xfixes_region_t valid, update; -+ int16_t x_off, y_off; -+ uint32_t options = XCB_PRESENT_OPTION_NONE; -+ -+ EnterCriticalSection(&present_priv->mutex_present); -+ -+ if (window != present_priv->window) -+ PRESENTPrivChangeWindow(present_priv, window); -+ -+ if (!window) -+ { -+ ERR("ERROR: Try to Present a pixmap on a NULL window\n"); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return FALSE; -+ } -+ -+ PRESENTflush_events(present_priv, FALSE); -+ /* Note: present_pixmap_priv->present_complete_pending may be non-0, because -+ * on some paths the Xserver sends the complete event just after the idle -+ * event. */ -+ if (!present_pixmap_priv->released) -+ { -+ ERR("FATAL ERROR: Trying to Present a pixmap not released\n"); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return FALSE; -+ } -+#ifdef D3D9NINE_DRI2 -+ if (present_pixmap_priv->dri2_info.is_dri2) -+ { -+ current_api = eglQueryAPI(); -+ eglBindAPI(EGL_OPENGL_API); -+ if (eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, dri2_priv->context)) -+ { -+ glBindFramebuffer(GL_READ_FRAMEBUFFER, present_pixmap_priv->dri2_info.fbo_read); -+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, present_pixmap_priv->dri2_info.fbo_write); -+ -+ glBlitFramebuffer(0, 0, present_pixmap_priv->width, present_pixmap_priv->height, -+ 0, 0, present_pixmap_priv->width, present_pixmap_priv->height, -+ GL_COLOR_BUFFER_BIT, GL_NEAREST); -+ glFlush(); /* Perhaps useless */ -+ } -+ else -+ ERR("eglMakeCurrent failed with 0x%0X\n", eglGetError()); -+ -+ eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -+ eglBindAPI(current_api); -+ } -+#endif -+ target_msc = present_priv->last_msc; -+ -+ presentationInterval = PresentationInterval; -+ if (PresentAsync) -+ options |= XCB_PRESENT_OPTION_ASYNC; -+ if (SwapEffectCopy) -+ options |= XCB_PRESENT_OPTION_COPY; -+ -+ target_msc += presentationInterval * (present_priv->pixmap_present_pending + 1); -+ -+ /* Note: PRESENT defines some way to do partial copy: -+ * presentproto: -+ * 'x-off' and 'y-off' define the location in the window where -+ * the 0,0 location of the pixmap will be presented. valid-area -+ * and update-area are relative to the pixmap. -+ */ -+ if (!pSourceRect && !pDestRect && !pDirtyRegion) -+ { -+ valid = 0; -+ update = 0; -+ x_off = 0; -+ y_off = 0; -+ } -+ else -+ { -+ xcb_rectangle_t rect_update; -+ xcb_rectangle_t *rect_updates; -+ int i; -+ -+ rect_update.x = 0; -+ rect_update.y = 0; -+ rect_update.width = present_pixmap_priv->width; -+ rect_update.height = present_pixmap_priv->height; -+ x_off = 0; -+ y_off = 0; -+ if (pSourceRect) -+ { -+ x_off = -pSourceRect->left; -+ y_off = -pSourceRect->top; -+ rect_update.x = pSourceRect->left; -+ rect_update.y = pSourceRect->top; -+ rect_update.width = pSourceRect->right - pSourceRect->left; -+ rect_update.height = pSourceRect->bottom - pSourceRect->top; -+ } -+ if (pDestRect) -+ { -+ x_off += pDestRect->left; -+ y_off += pDestRect->top; -+ rect_update.width = pDestRect->right - pDestRect->left; -+ rect_update.height = pDestRect->bottom - pDestRect->top; -+ /* Note: the size of pDestRect and pSourceRect are supposed to be the same size -+ * because the driver would have done things to assure that. */ -+ } -+ valid = xcb_generate_id(present_priv->xcb_connection_bis); -+ update = xcb_generate_id(present_priv->xcb_connection_bis); -+ xcb_xfixes_create_region(present_priv->xcb_connection_bis, valid, 1, &rect_update); -+ if (pDirtyRegion && pDirtyRegion->rdh.nCount) -+ { -+ rect_updates = (void *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(xcb_rectangle_t) * pDirtyRegion->rdh.nCount); -+ -+ for (i = 0; i < pDirtyRegion->rdh.nCount; i++) -+ { -+ RECT rc; -+ memcpy(&rc, pDirtyRegion->Buffer + i * sizeof(RECT), sizeof(RECT)); -+ rect_update.x = rc.left; -+ rect_update.y = rc.top; -+ rect_update.width = rc.right - rc.left; -+ rect_update.height = rc.bottom - rc.top; -+ memcpy(rect_updates + i * sizeof(xcb_rectangle_t), &rect_update, sizeof(xcb_rectangle_t)); -+ } -+ xcb_xfixes_create_region(present_priv->xcb_connection_bis, update, pDirtyRegion->rdh.nCount, rect_updates); -+ HeapFree(GetProcessHeap(), 0, rect_updates); -+ } else -+ xcb_xfixes_create_region(present_priv->xcb_connection_bis, update, 1, &rect_update); -+ } -+ -+ cookie = xcb_present_pixmap_checked(present_priv->xcb_connection_bis, -+ window, present_pixmap_priv->pixmap, present_pixmap_priv->serial, -+ valid, update, x_off, y_off, None, None, None, options, -+ target_msc, 0, 0, 0, NULL); -+ error = xcb_request_check(present_priv->xcb_connection_bis, cookie); /* performs a flush */ -+ -+ if (update) -+ xcb_xfixes_destroy_region(present_priv->xcb_connection_bis, update); -+ if (valid) -+ xcb_xfixes_destroy_region(present_priv->xcb_connection_bis, valid); -+ -+ if (error) -+ { -+ xcb_get_geometry_cookie_t cookie_geom; -+ xcb_get_geometry_reply_t *reply; -+ -+ cookie_geom = xcb_get_geometry(present_priv->xcb_connection_bis, window); -+ reply = xcb_get_geometry_reply(present_priv->xcb_connection_bis, cookie_geom, NULL); -+ -+ ERR("Error using PRESENT. Here some debug info\n"); -+ if (!reply) -+ { -+ ERR("Error querying window info. Perhaps it doesn't exist anymore\n"); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return FALSE; -+ } -+ ERR("Pixmap: width=%d, height=%d, depth=%d\n", -+ present_pixmap_priv->width, present_pixmap_priv->height, -+ present_pixmap_priv->depth); -+ -+ ERR("Window: width=%d, height=%d, depth=%d, x=%d, y=%d\n", -+ (int) reply->width, (int) reply->height, -+ (int) reply->depth, (int) reply->x, (int) reply->y); -+ -+ ERR("Present parameter: PresentationInterval=%d, Pending presentations=%d\n", -+ PresentationInterval, present_priv->pixmap_present_pending); -+ -+ if (present_pixmap_priv->depth != reply->depth) -+ ERR("Depths are different. PRESENT needs the pixmap and the window have same depth\n"); -+ free(reply); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return FALSE; -+ } -+ present_priv->last_target = target_msc; -+ present_priv->pixmap_present_pending++; -+ present_pixmap_priv->present_complete_pending++; -+ present_pixmap_priv->released = FALSE; -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return TRUE; -+} -+ -+BOOL PRESENTWaitPixmapReleased(PRESENTPixmapPriv *present_pixmap_priv) -+{ -+ PRESENTpriv *present_priv = present_pixmap_priv->present_priv; -+ -+ EnterCriticalSection(&present_priv->mutex_present); -+ -+ PRESENTflush_events(present_priv, FALSE); -+ -+ /* The part with present_pixmap_priv->present_complete_pending is legacy behaviour. -+ * It matters for SwapEffectCopy with swapinterval > 0. */ -+ while (!present_pixmap_priv->released || present_pixmap_priv->present_complete_pending) -+ { -+ /* Note: following if should not happen because we'll never -+ * use two PRESENTWaitPixmapReleased in parallels on same window. -+ * However it would make it work in that case */ -+ if (present_priv->xcb_wait) -+ { -+ /* we allow only one thread to dispatch events */ -+ EnterCriticalSection(&present_priv->mutex_xcb_wait); -+ /* here the other thread got an event but hasn't treated it yet */ -+ LeaveCriticalSection(&present_priv->mutex_xcb_wait); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ Sleep(10); /* Let it treat the event */ -+ EnterCriticalSection(&present_priv->mutex_present); -+ } -+ else if (!PRESENTwait_events(present_priv, TRUE)) -+ { -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return FALSE; -+ } -+ } -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return TRUE; -+} -+ -+BOOL PRESENTIsPixmapReleased(PRESENTPixmapPriv *present_pixmap_priv) -+{ -+ PRESENTpriv *present_priv = present_pixmap_priv->present_priv; -+ BOOL ret; -+ -+ EnterCriticalSection(&present_priv->mutex_present); -+ -+ PRESENTflush_events(present_priv, FALSE); -+ -+ ret = present_pixmap_priv->released; -+ -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return ret; -+} -+ -+BOOL PRESENTWaitReleaseEvent(PRESENTpriv *present_priv) -+{ -+ -+ EnterCriticalSection(&present_priv->mutex_present); -+ -+ while (!present_priv->idle_notify_since_last_check) -+ { -+ /* Note: following if should not happen because we'll never -+ * use two PRESENTWaitPixmapReleased in parallels on same window. -+ * However it would make it work in that case */ -+ if (present_priv->xcb_wait) -+ { -+ /* we allow only one thread to dispatch events */ -+ EnterCriticalSection(&present_priv->mutex_xcb_wait); -+ /* here the other thread got an event but hasn't treated it yet */ -+ LeaveCriticalSection(&present_priv->mutex_xcb_wait); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ Sleep(10); /* Let it treat the event */ -+ EnterCriticalSection(&present_priv->mutex_present); -+ } -+ else if (!PRESENTwait_events(present_priv, TRUE)) -+ { -+ ERR("Issue in PRESENTWaitReleaseEvent\n"); -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return FALSE; -+ } -+ } -+ present_priv->idle_notify_since_last_check = FALSE; -+ -+ LeaveCriticalSection(&present_priv->mutex_present); -+ return TRUE; -+} -diff --git a/dlls/d3d9-nine/dri3.h b/dlls/d3d9-nine/dri3.h -new file mode 100644 -index 0000000000..3c9309dedb ---- /dev/null -+++ b/dlls/d3d9-nine/dri3.h -@@ -0,0 +1,91 @@ -+/* -+ * Wine X11DRV DRI3 interface -+ * -+ * Copyright 2014 Axel Davy -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#ifndef __WINE_DRI3_H -+#define __WINE_DRI3_H -+ -+#ifndef __WINE_CONFIG_H -+# error You must include config.h to use this header -+#endif -+ -+#include -+#include -+ -+BOOL DRI3CheckExtension(Display *dpy, int major, int minor); -+ -+#ifdef D3D9NINE_DRI2 -+struct DRI2priv; -+ -+BOOL DRI2FallbackInit(Display *dpy, struct DRI2priv **priv); -+ -+void DRI2FallbackDestroy(struct DRI2priv *priv); -+ -+BOOL DRI2FallbackCheckSupport(Display *dpy); -+#endif -+ -+BOOL PRESENTCheckExtension(Display *dpy, int major, int minor); -+ -+BOOL DRI3Open(Display *dpy, int screen, int *device_fd); -+ -+#ifdef D3D9NINE_DRI2 -+BOOL DRI2FallbackOpen(Display *dpy, int screen, int *device_fd); -+#endif -+ -+BOOL DRI3PixmapFromDmaBuf(Display *dpy, int screen, int fd, int width, int height, -+ int stride, int depth, int bpp, Pixmap *pixmap); -+ -+BOOL DRI3DmaBufFromPixmap(Display *dpy, Pixmap pixmap, int *fd, int *width, int *height, -+ int *stride, int *depth, int *bpp); -+ -+typedef struct PRESENTPriv PRESENTpriv; -+typedef struct PRESENTPixmapPriv PRESENTPixmapPriv; -+ -+BOOL PRESENTInit(Display *dpy, PRESENTpriv **present_priv); -+ -+/* will clean properly and free all PRESENTPixmapPriv associated to PRESENTpriv. -+ * PRESENTPixmapPriv should not be freed by something else. -+ * If never a PRESENTPixmapPriv has to be destroyed, -+ * please destroy the current PRESENTpriv and create a new one. -+ * This will take care than all pixmaps are released */ -+void PRESENTDestroy(Display *dpy, PRESENTpriv *present_priv); -+ -+BOOL PRESENTPixmapInit(PRESENTpriv *present_priv, Pixmap pixmap, PRESENTPixmapPriv **present_pixmap_priv); -+ -+#ifdef D3D9NINE_DRI2 -+BOOL DRI2FallbackPRESENTPixmap(PRESENTpriv *present_priv, struct DRI2priv *priv, -+ int fd, int width, int height, int stride, int depth, -+ int bpp, PRESENTPixmapPriv **present_pixmap_priv); -+#endif -+ -+BOOL PRESENTTryFreePixmap(Display *dpy, PRESENTPixmapPriv *present_pixmap_priv); -+ -+BOOL PRESENTHelperCopyFront(Display *dpy, PRESENTPixmapPriv *present_pixmap_priv); -+ -+BOOL PRESENTPixmap(Display *dpy, XID window, PRESENTPixmapPriv *present_pixmap_priv, -+ const UINT PresentationInterval, const BOOL PresentAsync, const BOOL SwapEffectCopy, -+ const RECT *pSourceRect, const RECT *pDestRect, const RGNDATA *pDirtyRegion); -+ -+BOOL PRESENTWaitPixmapReleased(PRESENTPixmapPriv *present_pixmap_priv); -+ -+BOOL PRESENTIsPixmapReleased(PRESENTPixmapPriv *present_pixmap_priv); -+ -+BOOL PRESENTWaitReleaseEvent(PRESENTpriv *present_priv); -+ -+#endif /* __WINE_DRI3_H */ -diff --git a/dlls/d3d9-nine/present.c b/dlls/d3d9-nine/present.c -new file mode 100644 -index 0000000000..2d9390a358 ---- /dev/null -+++ b/dlls/d3d9-nine/present.c -@@ -0,0 +1,1748 @@ -+/* -+ * Wine ID3DAdapter9 support functions -+ * -+ * Copyright 2013 Joakim Sindholt -+ * Christoph Bumiller -+ * Copyright 2014 Tiziano Bacocco -+ * David Heidelberger -+ * Copyright 2014-2015 Axel Davy -+ * Copyright 2015 Patrick Rudolph -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "config.h" -+#include "wine/port.h" -+#include "wine/debug.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(d3d9nine); -+ -+#include -+#include -+ -+#include "dri3.h" -+#include "wndproc.h" -+ -+#include "wine/library.h" // for wine_dl* -+#include "wine/unicode.h" // for strcpyW -+ -+#ifndef D3DPRESENT_DONOTWAIT -+#define D3DPRESENT_DONOTWAIT 0x00000001 -+#endif -+ -+#define WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MAJOR 1 -+#if defined (ID3DPresent_SetPresentParameters2) -+#define WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR 3 -+#elif defined (ID3DPresent_ResolutionMismatch) -+#define WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR 2 -+#elif defined (ID3DPresent_GetWindowOccluded) -+#define WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR 1 -+#else -+#define WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR 0 -+#endif -+ -+static const struct D3DAdapter9DRM *d3d9_drm = NULL; -+#ifdef D3D9NINE_DRI2 -+static int is_dri2_fallback = 0; -+#endif -+ -+/* Start section of x11drv.h */ -+#define X11DRV_ESCAPE 6789 -+enum x11drv_escape_codes -+{ -+ X11DRV_SET_DRAWABLE, /* set current drawable for a DC */ -+ X11DRV_GET_DRAWABLE, /* get current drawable for a DC */ -+ X11DRV_START_EXPOSURES, /* start graphics exposures */ -+ X11DRV_END_EXPOSURES, /* end graphics exposures */ -+ X11DRV_FLUSH_GL_DRAWABLE /* flush changes made to the gl drawable */ -+}; -+ -+struct x11drv_escape_get_drawable -+{ -+ enum x11drv_escape_codes code; /* escape code (X11DRV_GET_DRAWABLE) */ -+ Drawable drawable; /* X drawable */ -+ Drawable gl_drawable; /* GL drawable */ -+ int pixel_format; /* internal GL pixel format */ -+}; -+/* End section x11drv.h */ -+ -+static XContext d3d_hwnd_context; -+static CRITICAL_SECTION context_section; -+static CRITICAL_SECTION_DEBUG critsect_debug = -+{ -+ 0, 0, &context_section, -+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, -+ 0, 0, { (DWORD_PTR)(__FILE__ ": context_section") } -+}; -+static CRITICAL_SECTION context_section = { &critsect_debug, -1, 0, 0, 0, 0 }; -+ -+const GUID IID_ID3DPresent = { 0x77D60E80, 0xF1E6, 0x11DF, { 0x9E, 0x39, 0x95, 0x0C, 0xDF, 0xD7, 0x20, 0x85 } }; -+const GUID IID_ID3DPresentGroup = { 0xB9C3016E, 0xF32A, 0x11DF, { 0x9C, 0x18, 0x92, 0xEA, 0xDE, 0xD7, 0x20, 0x85 } }; -+ -+struct d3d_drawable -+{ -+ Drawable drawable; /* X11 drawable */ -+ HDC hdc; -+ HWND wnd; /* HWND (for convenience) */ -+}; -+ -+struct DRI3Present -+{ -+ /* COM vtable */ -+ void *vtable; -+ /* IUnknown reference count */ -+ LONG refs; -+ -+ D3DPRESENT_PARAMETERS params; -+ HWND focus_wnd; -+ PRESENTpriv *present_priv; -+#ifdef D3D9NINE_DRI2 -+ struct DRI2priv *dri2_priv; -+#endif -+ -+ WCHAR devname[32]; -+ HCURSOR hCursor; -+ -+ DEVMODEW initial_mode; -+ -+ DWORD style; -+ DWORD style_ex; -+ -+ BOOL reapply_mode; -+ BOOL ex; -+ BOOL resolution_mismatch; -+ BOOL occluded; -+ BOOL drop_wnd_messages; -+ BOOL no_window_changes; -+ Display *gdi_display; -+ -+ UINT present_interval; -+ BOOL present_async; -+ BOOL present_swapeffectcopy; -+ BOOL allow_discard_delayed_release; -+ BOOL tear_free_discard; -+ struct d3d_drawable *d3d; -+}; -+ -+struct D3DWindowBuffer -+{ -+ PRESENTPixmapPriv *present_pixmap_priv; -+}; -+ -+static void free_d3dadapter_drawable(struct d3d_drawable *d3d) -+{ -+ ReleaseDC(d3d->wnd, d3d->hdc); -+ HeapFree(GetProcessHeap(), 0, d3d); -+} -+ -+static void destroy_d3dadapter_drawable(Display *gdi_display, HWND hwnd) -+{ -+ struct d3d_drawable *d3d; -+ -+ EnterCriticalSection(&context_section); -+ if (!XFindContext(gdi_display, (XID)hwnd, -+ d3d_hwnd_context, (char **)&d3d)) -+ { -+ XDeleteContext(gdi_display, (XID)hwnd, d3d_hwnd_context); -+ free_d3dadapter_drawable(d3d); -+ } -+ LeaveCriticalSection(&context_section); -+} -+ -+static RECT DRI3Present_GetClientRecWindowRelative(HWND hwnd) -+{ -+ RECT rect; -+ RECT wnd; -+ -+ /* Get client space dimensions */ -+ GetClientRect(hwnd, &rect); -+ -+ /* Get window in screen space */ -+ GetWindowRect(hwnd, &wnd); -+ -+ /* Transform to offset */ -+ MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT) &wnd, 2); -+ wnd.top *= -1; -+ wnd.left *= -1; -+ wnd.bottom = wnd.top + rect.bottom; -+ wnd.right = wnd.left + rect.right; -+ -+ return wnd; -+} -+ -+static struct d3d_drawable *create_d3dadapter_drawable(HWND hwnd) -+{ -+ struct x11drv_escape_get_drawable extesc = { X11DRV_GET_DRAWABLE }; -+ struct d3d_drawable *d3d; -+ -+ d3d = HeapAlloc(GetProcessHeap(), 0, sizeof(*d3d)); -+ if (!d3d) -+ { -+ ERR("Couldn't allocate d3d_drawable.\n"); -+ return NULL; -+ } -+ -+ d3d->hdc = GetDCEx(hwnd, 0, DCX_CACHE | DCX_CLIPSIBLINGS); -+ if (ExtEscape(d3d->hdc, X11DRV_ESCAPE, sizeof(extesc), (LPCSTR)&extesc, -+ sizeof(extesc), (LPSTR)&extesc) <= 0) -+ { -+ ERR("Unexpected error in X Drawable lookup (hwnd=%p, hdc=%p)\n", hwnd, d3d->hdc); -+ ReleaseDC(hwnd, d3d->hdc); -+ HeapFree(GetProcessHeap(), 0, d3d); -+ return NULL; -+ } -+ -+ d3d->drawable = extesc.drawable; -+ d3d->wnd = hwnd; -+ -+ return d3d; -+} -+ -+static struct d3d_drawable *get_d3d_drawable(Display *gdi_display, HWND hwnd) -+{ -+ struct d3d_drawable *d3d, *race; -+ -+ EnterCriticalSection(&context_section); -+ if (!XFindContext(gdi_display, (XID)hwnd, d3d_hwnd_context, (char **)&d3d)) -+ { -+ return d3d; -+ } -+ LeaveCriticalSection(&context_section); -+ -+ TRACE("No d3d_drawable attached to hwnd %p, creating one.\n", hwnd); -+ -+ d3d = create_d3dadapter_drawable(hwnd); -+ if (!d3d) -+ return NULL; -+ -+ EnterCriticalSection(&context_section); -+ if (!XFindContext(gdi_display, (XID)hwnd, -+ d3d_hwnd_context, (char **)&race)) -+ { -+ /* apparently someone beat us to creating this d3d drawable. Let's not -+ waste more time with X11 calls and just use theirs instead. */ -+ free_d3dadapter_drawable(d3d); -+ return race; -+ } -+ XSaveContext(gdi_display, (XID)hwnd, d3d_hwnd_context, (char *)d3d); -+ return d3d; -+} -+ -+static void release_d3d_drawable(struct d3d_drawable *d3d) -+{ -+ if (!d3d) -+ ERR("Driver internal error: d3d_drawable is NULL\n"); -+ LeaveCriticalSection(&context_section); -+} -+ -+static ULONG WINAPI DRI3Present_AddRef(struct DRI3Present *This) -+{ -+ ULONG refs = InterlockedIncrement(&This->refs); -+ TRACE("%p increasing refcount to %u.\n", This, refs); -+ return refs; -+} -+ -+static ULONG WINAPI DRI3Present_Release(struct DRI3Present *This) -+{ -+ ULONG refs = InterlockedDecrement(&This->refs); -+ TRACE("%p decreasing refcount to %u.\n", This, refs); -+ if (refs == 0) -+ { -+ /* dtor */ -+ (void) nine_unregister_window(This->focus_wnd); -+ if (This->d3d) -+ destroy_d3dadapter_drawable(This->gdi_display, This->d3d->wnd); -+ ChangeDisplaySettingsExW(This->devname, &(This->initial_mode), 0, CDS_FULLSCREEN, NULL); -+ PRESENTDestroy(This->gdi_display, This->present_priv); -+#ifdef D3D9NINE_DRI2 -+ if (is_dri2_fallback) -+ DRI2FallbackDestroy(This->dri2_priv); -+#endif -+ HeapFree(GetProcessHeap(), 0, This); -+ } -+ return refs; -+} -+ -+static HRESULT WINAPI DRI3Present_QueryInterface(struct DRI3Present *This, -+ REFIID riid, void **ppvObject) -+{ -+ if (!ppvObject) -+ return E_POINTER; -+ -+ if (IsEqualGUID(&IID_ID3DPresent, riid) || -+ IsEqualGUID(&IID_IUnknown, riid)) -+ { -+ *ppvObject = This; -+ DRI3Present_AddRef(This); -+ return S_OK; -+ } -+ -+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); -+ *ppvObject = NULL; -+ -+ return E_NOINTERFACE; -+} -+ -+static HRESULT DRI3Present_ChangePresentParameters(struct DRI3Present *This, -+ D3DPRESENT_PARAMETERS *params); -+ -+static HRESULT WINAPI DRI3Present_SetPresentParameters(struct DRI3Present *This, -+ D3DPRESENT_PARAMETERS *pPresentationParameters, -+ D3DDISPLAYMODEEX *pFullscreenDisplayMode) -+{ -+ if (pFullscreenDisplayMode) -+ FIXME("Ignoring pFullscreenDisplayMode\n"); -+ return DRI3Present_ChangePresentParameters(This, pPresentationParameters); -+} -+ -+static HRESULT WINAPI DRI3Present_D3DWindowBufferFromDmaBuf(struct DRI3Present *This, -+ int dmaBufFd, int width, int height, int stride, int depth, -+ int bpp, struct D3DWindowBuffer **out) -+{ -+ Pixmap pixmap; -+ -+#ifdef D3D9NINE_DRI2 -+ if (is_dri2_fallback) -+ { -+ *out = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(struct D3DWindowBuffer)); -+ if (!DRI2FallbackPRESENTPixmap(This->present_priv, This->dri2_priv, -+ dmaBufFd, width, height, stride, depth, -+ bpp, &((*out)->present_pixmap_priv))) -+ { -+ ERR("DRI2FallbackPRESENTPixmap failed\n"); -+ HeapFree(GetProcessHeap(), 0, *out); -+ return D3DERR_DRIVERINTERNALERROR; -+ } -+ return D3D_OK; -+ } -+#endif -+ if (!DRI3PixmapFromDmaBuf(This->gdi_display, DefaultScreen(This->gdi_display), -+ dmaBufFd, width, height, stride, depth, bpp, &pixmap)) -+ { -+ ERR("DRI3PixmapFromDmaBuf failed\n"); -+ return D3DERR_DRIVERINTERNALERROR; -+ } -+ -+ *out = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(struct D3DWindowBuffer)); -+ if (!PRESENTPixmapInit(This->present_priv, pixmap, &((*out)->present_pixmap_priv))) -+ { -+ ERR("PRESENTPixmapInit failed\n"); -+ HeapFree(GetProcessHeap(), 0, *out); -+ return D3DERR_DRIVERINTERNALERROR; -+ } -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI DRI3Present_DestroyD3DWindowBuffer(struct DRI3Present *This, -+ struct D3DWindowBuffer *buffer) -+{ -+ /* the pixmap is managed by the PRESENT backend. -+ * But if it can delete it right away, we may have -+ * better performance */ -+ PRESENTTryFreePixmap(This->gdi_display, buffer->present_pixmap_priv); -+ HeapFree(GetProcessHeap(), 0, buffer); -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI DRI3Present_WaitBufferReleased(struct DRI3Present *This, -+ struct D3DWindowBuffer *buffer) -+{ -+ if(!PRESENTWaitPixmapReleased(buffer->present_pixmap_priv)) -+ { -+ ERR("PRESENTWaitPixmapReleased failed\n"); -+ return D3DERR_DRIVERINTERNALERROR; -+ } -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI DRI3Present_FrontBufferCopy(struct DRI3Present *This, -+ struct D3DWindowBuffer *buffer) -+{ -+#ifdef D3D9NINE_DRI2 -+ if (is_dri2_fallback) -+ return D3DERR_DRIVERINTERNALERROR; -+#endif -+ if (PRESENTHelperCopyFront(This->gdi_display, buffer->present_pixmap_priv)) -+ return D3D_OK; -+ else -+ return D3DERR_DRIVERINTERNALERROR; -+} -+ -+/* Try to detect client side window decorations by walking the X Drawable up. -+ * In case there's an intermediate Drawable, server side window decorations are used. -+ * TODO: Find a X11 function to query for window decorations. -+ */ -+static BOOL DRI3Present_HasClientSideWindowDecorations(struct DRI3Present *This, -+ HWND hwnd) -+{ -+ struct x11drv_escape_get_drawable extesc = { X11DRV_GET_DRAWABLE }; -+ Window Wroot; -+ Window Wparent; -+ Window *Wchildren; -+ unsigned int numchildren; -+ HWND parent; -+ HDC hdc; -+ BOOL ret = TRUE; -+ -+ parent = GetParent(hwnd); -+ if (!parent) -+ parent = GetDesktopWindow(); -+ if (!parent) -+ { -+ ERR("Unexpected error getting the parent hwnd (hwnd=%p)\n", hwnd); -+ return FALSE; -+ } -+ -+ hdc = GetDCEx(hwnd, 0, DCX_CACHE | DCX_CLIPSIBLINGS); -+ if (!hdc) -+ return FALSE; -+ if (ExtEscape(hdc, X11DRV_ESCAPE, sizeof(extesc), (LPCSTR)&extesc, -+ sizeof(extesc), (LPSTR)&extesc) <= 0) -+ { -+ ERR("Unexpected error in X Drawable lookup (hwnd=%p, hdc=%p)\n", hwnd, hdc); -+ ReleaseDC(hwnd, hdc); -+ return FALSE; -+ } -+ ReleaseDC(hwnd, hdc); -+ -+ if (XQueryTree(This->gdi_display, extesc.drawable, &Wroot, &Wparent, &Wchildren, &numchildren)) -+ { -+ hdc = GetDCEx(parent, 0, DCX_CACHE | DCX_CLIPSIBLINGS); -+ if (!hdc) -+ return FALSE; -+ -+ if (ExtEscape(hdc, X11DRV_ESCAPE, sizeof(extesc), (LPCSTR)&extesc, -+ sizeof(extesc), (LPSTR)&extesc) <= 0) -+ { -+ ERR("Unexpected error in X Drawable lookup (hwnd=%p, hdc=%p)\n", parent, hdc); -+ ReleaseDC(parent, hdc); -+ return FALSE; -+ } -+ ReleaseDC(parent, hdc); -+ -+ if (Wparent != extesc.drawable) -+ { -+ /* Found at least one intermediate window */ -+ ret = FALSE; -+ } -+ if (Wchildren) -+ free(Wchildren); -+ } -+ -+ return ret; -+} -+ -+static HRESULT WINAPI DRI3Present_PresentBuffer( struct DRI3Present *This, -+ struct D3DWindowBuffer *buffer, HWND hWndOverride, const RECT *pSourceRect, -+ const RECT *pDestRect, const RGNDATA *pDirtyRegion, DWORD Flags ) -+{ -+ struct d3d_drawable *d3d; -+ RECT dest_translate; -+ RECT offset; -+ HWND hwnd; -+ -+ if (hWndOverride) -+ hwnd = hWndOverride; -+ else if (This->params.hDeviceWindow) -+ hwnd = This->params.hDeviceWindow; -+ else -+ hwnd = This->focus_wnd; -+ -+ d3d = get_d3d_drawable(This->gdi_display, hwnd); -+ -+ if (!d3d) -+ return D3DERR_DRIVERINTERNALERROR; -+ -+ /* TODO: should we use a list here instead ? */ -+ if (This->d3d && (This->d3d->wnd != d3d->wnd)) -+ destroy_d3dadapter_drawable(This->gdi_display, This->d3d->wnd); -+ -+ This->d3d = d3d; -+ -+ /* In case of client side window decorations we need to add an offset within -+ * the X drawable. -+ * FIXME: Call once on window style / size change */ -+ if (DRI3Present_HasClientSideWindowDecorations(This, hwnd)) -+ { -+ offset = DRI3Present_GetClientRecWindowRelative(hwnd); -+ -+ if ((offset.top != 0) || (offset.left != 0)) -+ { -+ if (!pDestRect) -+ pDestRect = (const RECT *) &offset; -+ else -+ { -+ dest_translate.top = pDestRect->top + offset.top; -+ dest_translate.left = pDestRect->left + offset.left; -+ dest_translate.bottom = pDestRect->bottom + offset.bottom; -+ dest_translate.right = pDestRect->right + offset.right; -+ pDestRect = (const RECT *) &dest_translate; -+ } -+ } -+ } -+ -+ if (!PRESENTPixmap(This->gdi_display, d3d->drawable, buffer->present_pixmap_priv, -+ This->present_interval, This->present_async, This->present_swapeffectcopy, -+ pSourceRect, pDestRect, pDirtyRegion)) -+ { -+ release_d3d_drawable(d3d); -+ return D3DERR_DRIVERINTERNALERROR; -+ } -+ release_d3d_drawable(d3d); -+ -+ return D3D_OK; -+} -+ -+/* Based on wine's wined3d_get_adapter_raster_status. */ -+static HRESULT WINAPI DRI3Present_GetRasterStatus( struct DRI3Present *This, -+ D3DRASTER_STATUS *pRasterStatus ) -+{ -+ LONGLONG freq_per_frame, freq_per_line; -+ LARGE_INTEGER counter, freq_per_sec; -+ unsigned refresh_rate, height; -+ -+ TRACE("This=%p, pRasterStatus=%p\n", This, pRasterStatus); -+ -+ if (!QueryPerformanceCounter(&counter) || !QueryPerformanceFrequency(&freq_per_sec)) -+ return D3DERR_INVALIDCALL; -+ -+ if (This->params.Windowed) -+ { -+ refresh_rate = This->initial_mode.dmDisplayFrequency; -+ height = This->initial_mode.dmPelsHeight; -+ } -+ else -+ { -+ refresh_rate = This->params.FullScreen_RefreshRateInHz; -+ height = This->params.BackBufferHeight; -+ } -+ -+ if (refresh_rate == 0) -+ refresh_rate = 60; -+ -+ TRACE("refresh_rate=%u, height=%u\n", refresh_rate, height); -+ -+ freq_per_frame = freq_per_sec.QuadPart / refresh_rate; -+ /* Assume 20 scan lines in the vertical blank. */ -+ freq_per_line = freq_per_frame / (height + 20); -+ pRasterStatus->ScanLine = (counter.QuadPart % freq_per_frame) / freq_per_line; -+ if (pRasterStatus->ScanLine < height) -+ pRasterStatus->InVBlank = FALSE; -+ else -+ { -+ pRasterStatus->ScanLine = 0; -+ pRasterStatus->InVBlank = TRUE; -+ } -+ -+ TRACE("Returning fake value, InVBlank %u, ScanLine %u.\n", -+ pRasterStatus->InVBlank, pRasterStatus->ScanLine); -+ -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI DRI3Present_GetDisplayMode( struct DRI3Present *This, -+ D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation ) -+{ -+ DEVMODEW dm; -+ -+ ZeroMemory(&dm, sizeof(dm)); -+ dm.dmSize = sizeof(dm); -+ -+ EnumDisplaySettingsExW(This->devname, ENUM_CURRENT_SETTINGS, &dm, 0); -+ pMode->Width = dm.dmPelsWidth; -+ pMode->Height = dm.dmPelsHeight; -+ pMode->RefreshRate = dm.dmDisplayFrequency; -+ pMode->ScanLineOrdering = (dm.dmDisplayFlags & DM_INTERLACED) ? -+ D3DSCANLINEORDERING_INTERLACED : D3DSCANLINEORDERING_PROGRESSIVE; -+ -+ /* XXX This is called "guessing" */ -+ switch (dm.dmBitsPerPel) -+ { -+ case 32: pMode->Format = D3DFMT_X8R8G8B8; break; -+ case 24: pMode->Format = D3DFMT_R8G8B8; break; -+ case 16: pMode->Format = D3DFMT_R5G6B5; break; -+ default: -+ WARN("Unknown display format with %u bpp.\n", dm.dmBitsPerPel); -+ pMode->Format = D3DFMT_UNKNOWN; -+ } -+ -+ switch (dm.dmDisplayOrientation) -+ { -+ case DMDO_DEFAULT: *pRotation = D3DDISPLAYROTATION_IDENTITY; break; -+ case DMDO_90: *pRotation = D3DDISPLAYROTATION_90; break; -+ case DMDO_180: *pRotation = D3DDISPLAYROTATION_180; break; -+ case DMDO_270: *pRotation = D3DDISPLAYROTATION_270; break; -+ default: -+ WARN("Unknown display rotation %u.\n", dm.dmDisplayOrientation); -+ *pRotation = D3DDISPLAYROTATION_IDENTITY; -+ } -+ -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI DRI3Present_GetPresentStats( struct DRI3Present *This, D3DPRESENTSTATS *pStats ) -+{ -+ FIXME("(%p, %p), stub!\n", This, pStats); -+ return D3DERR_INVALIDCALL; -+} -+ -+static HRESULT WINAPI DRI3Present_GetCursorPos( struct DRI3Present *This, POINT *pPoint ) -+{ -+ BOOL ok; -+ HWND draw_window; -+ -+ if (!pPoint) -+ return D3DERR_INVALIDCALL; -+ -+ draw_window = This->params.hDeviceWindow ? -+ This->params.hDeviceWindow : This->focus_wnd; -+ -+ ok = GetCursorPos(pPoint); -+ ok = ok && ScreenToClient(draw_window, pPoint); -+ return ok ? S_OK : D3DERR_DRIVERINTERNALERROR; -+} -+ -+static HRESULT WINAPI DRI3Present_SetCursorPos( struct DRI3Present *This, POINT *pPoint ) -+{ -+ BOOL ok; -+ POINT real_pos; -+ -+ if (!pPoint) -+ return D3DERR_INVALIDCALL; -+ -+ ok = SetCursorPos(pPoint->x, pPoint->y); -+ if (!ok) -+ goto error; -+ -+ ok = GetCursorPos(&real_pos); -+ if (!ok || real_pos.x != pPoint->x || real_pos.y != pPoint->y) -+ goto error; -+ -+ return D3D_OK; -+ -+error: -+ SetCursor(NULL); /* Hide cursor rather than put wrong pos */ -+ return D3DERR_DRIVERINTERNALERROR; -+} -+ -+/* Note: assuming 32x32 cursor */ -+static HRESULT WINAPI DRI3Present_SetCursor( struct DRI3Present *This, void *pBitmap, -+ POINT *pHotspot, BOOL bShow ) -+{ -+ if (pBitmap) -+ { -+ ICONINFO info; -+ HCURSOR cursor; -+ -+ DWORD mask[32]; -+ memset(mask, ~0, sizeof(mask)); -+ -+ if (!pHotspot) -+ return D3DERR_INVALIDCALL; -+ info.fIcon = FALSE; -+ info.xHotspot = pHotspot->x; -+ info.yHotspot = pHotspot->y; -+ info.hbmMask = CreateBitmap(32, 32, 1, 1, mask); -+ info.hbmColor = CreateBitmap(32, 32, 1, 32, pBitmap); -+ -+ cursor = CreateIconIndirect(&info); -+ if (info.hbmMask) DeleteObject(info.hbmMask); -+ if (info.hbmColor) DeleteObject(info.hbmColor); -+ if (cursor) -+ DestroyCursor(This->hCursor); -+ This->hCursor = cursor; -+ } -+ SetCursor(bShow ? This->hCursor : NULL); -+ -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI DRI3Present_SetGammaRamp( struct DRI3Present *This, -+ const D3DGAMMARAMP *pRamp, HWND hWndOverride ) -+{ -+ HWND hWnd = hWndOverride ? hWndOverride : This->focus_wnd; -+ HDC hdc; -+ BOOL ok; -+ if (!pRamp) -+ return D3DERR_INVALIDCALL; -+ -+ hdc = GetDC(hWnd); -+ ok = SetDeviceGammaRamp(hdc, (void *)pRamp); -+ ReleaseDC(hWnd, hdc); -+ return ok ? D3D_OK : D3DERR_DRIVERINTERNALERROR; -+} -+ -+static HRESULT WINAPI DRI3Present_GetWindowInfo( struct DRI3Present *This, -+ HWND hWnd, int *width, int *height, int *depth ) -+{ -+ HRESULT hr; -+ RECT pRect; -+ -+ if (!hWnd) -+ hWnd = This->focus_wnd; -+ hr = GetClientRect(hWnd, &pRect); -+ if (!hr) -+ return D3DERR_INVALIDCALL; -+ *width = pRect.right - pRect.left; -+ *height = pRect.bottom - pRect.top; -+ *depth = 24; //TODO -+ return D3D_OK; -+} -+ -+#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 1 -+static BOOL WINAPI DRI3Present_GetWindowOccluded(struct DRI3Present *This) -+{ -+ return This->occluded; -+} -+#endif -+ -+#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 2 -+static BOOL WINAPI DRI3Present_ResolutionMismatch(struct DRI3Present *This) -+{ -+ /* The resolution might change due to a third party app. -+ * Poll this function to get the device's resolution match. -+ * A device reset is required to restore the requested resolution. -+ */ -+ return This->resolution_mismatch; -+} -+ -+static HANDLE WINAPI DRI3Present_CreateThread( struct DRI3Present *This, -+ void *pThreadfunc, void *pParam ) -+{ -+ LPTHREAD_START_ROUTINE lpStartAddress = -+ (LPTHREAD_START_ROUTINE) pThreadfunc; -+ -+ return CreateThread(NULL, 0, lpStartAddress, pParam, 0, NULL); -+} -+ -+static BOOL WINAPI DRI3Present_WaitForThread( struct DRI3Present *This, HANDLE thread ) -+{ -+ DWORD ExitCode = 0; -+ while (GetExitCodeThread(thread, &ExitCode) && ExitCode == STILL_ACTIVE) -+ Sleep(10); -+ -+ return TRUE; -+} -+#endif -+ -+#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 3 -+static HRESULT WINAPI DRI3Present_SetPresentParameters2( struct DRI3Present *This, D3DPRESENT_PARAMETERS2 *pParams ) -+{ -+ This->allow_discard_delayed_release = pParams->AllowDISCARDDelayedRelease; -+ This->tear_free_discard = pParams->AllowDISCARDDelayedRelease && pParams->TearFreeDISCARD; -+ return D3D_OK; -+} -+ -+static BOOL WINAPI DRI3Present_IsBufferReleased( struct DRI3Present *This, struct D3DWindowBuffer *buffer ) -+{ -+ return PRESENTIsPixmapReleased(buffer->present_pixmap_priv); -+} -+ -+static HRESULT WINAPI DRI3Present_WaitBufferReleaseEvent( struct DRI3Present *This ) -+{ -+ PRESENTWaitReleaseEvent(This->present_priv); -+ return D3D_OK; -+} -+#endif -+ -+/*----------*/ -+ -+static ID3DPresentVtbl DRI3Present_vtable = { -+ (void *)DRI3Present_QueryInterface, -+ (void *)DRI3Present_AddRef, -+ (void *)DRI3Present_Release, -+ (void *)DRI3Present_SetPresentParameters, -+ (void *)DRI3Present_D3DWindowBufferFromDmaBuf, -+ (void *)DRI3Present_DestroyD3DWindowBuffer, -+ (void *)DRI3Present_WaitBufferReleased, -+ (void *)DRI3Present_FrontBufferCopy, -+ (void *)DRI3Present_PresentBuffer, -+ (void *)DRI3Present_GetRasterStatus, -+ (void *)DRI3Present_GetDisplayMode, -+ (void *)DRI3Present_GetPresentStats, -+ (void *)DRI3Present_GetCursorPos, -+ (void *)DRI3Present_SetCursorPos, -+ (void *)DRI3Present_SetCursor, -+ (void *)DRI3Present_SetGammaRamp, -+ (void *)DRI3Present_GetWindowInfo, -+#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 1 -+ (void *)DRI3Present_GetWindowOccluded, -+#endif -+#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 2 -+ (void *)DRI3Present_ResolutionMismatch, -+ (void *)DRI3Present_CreateThread, -+ (void *)DRI3Present_WaitForThread, -+#endif -+#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 3 -+ (void *)DRI3Present_SetPresentParameters2, -+ (void *)DRI3Present_IsBufferReleased, -+ (void *)DRI3Present_WaitBufferReleaseEvent, -+#endif -+}; -+ -+/* The following code is based on WINE's wined3d/device.c and -+ * wined3d/swapchain.c and WINE's d3d9 files. */ -+ -+static LONG fullscreen_style(LONG style) -+{ -+ /* Make sure the window is managed, otherwise we won't get keyboard input. */ -+ style |= WS_POPUP | WS_SYSMENU; -+ style &= ~(WS_CAPTION | WS_THICKFRAME); -+ -+ return style; -+} -+ -+static LONG fullscreen_exstyle(LONG exstyle) -+{ -+ /* Filter out window decorations. */ -+ exstyle &= ~(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE); -+ -+ return exstyle; -+} -+ -+static HRESULT DRI3Present_ChangeDisplaySettingsIfNeccessary(struct DRI3Present *This, DEVMODEW *new_mode) -+{ -+ DEVMODEW current_mode; -+ LONG hr; -+ -+ /* Filter invalid resolution */ -+ if (!new_mode->dmPelsWidth || !new_mode->dmPelsHeight) -+ return D3DERR_INVALIDCALL; -+ -+ /* Ignore invalid frequency requested */ -+ if (new_mode->dmDisplayFrequency > 1000) -+ new_mode->dmDisplayFrequency = 0; -+ -+ ZeroMemory(¤t_mode, sizeof(DEVMODEW)); -+ current_mode.dmSize = sizeof(DEVMODEW); -+ /* Only change the mode if necessary. */ -+ if (!EnumDisplaySettingsW(This->devname, ENUM_CURRENT_SETTINGS, ¤t_mode)) -+ ERR("Failed to get current display mode.\n"); -+ else if (current_mode.dmPelsWidth != new_mode->dmPelsWidth -+ || current_mode.dmPelsHeight != new_mode->dmPelsHeight -+ || (current_mode.dmDisplayFrequency != new_mode->dmDisplayFrequency -+ && (new_mode->dmFields & DM_DISPLAYFREQUENCY))) -+ { -+ hr = ChangeDisplaySettingsExW(This->devname, new_mode, 0, CDS_FULLSCREEN, NULL); -+ if (hr != DISP_CHANGE_SUCCESSFUL) -+ { -+ /* try again without display RefreshRate */ -+ if (new_mode->dmFields & DM_DISPLAYFREQUENCY) -+ { -+ new_mode->dmFields &= ~DM_DISPLAYFREQUENCY; -+ new_mode->dmDisplayFrequency = 0; -+ hr = ChangeDisplaySettingsExW(This->devname, new_mode, 0, CDS_FULLSCREEN, NULL); -+ if (hr != DISP_CHANGE_SUCCESSFUL) -+ { -+ ERR("ChangeDisplaySettingsExW failed with 0x%08X\n", hr); -+ return D3DERR_INVALIDCALL; -+ } -+ } -+ else -+ { -+ ERR("ChangeDisplaySettingsExW failed with 0x%08X\n", hr); -+ return D3DERR_INVALIDCALL; -+ } -+ } -+ } -+ return D3D_OK; -+} -+ -+LRESULT device_process_message(struct DRI3Present *present, HWND window, BOOL unicode, -+ UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) -+{ -+ boolean drop_wnd_messages; -+ DEVMODEW current_mode; -+ DEVMODEW new_mode; -+ -+ TRACE("Got message: window %p, message %#x, wparam %#lx, lparam %#lx.\n", -+ window, message, wparam, lparam); -+ -+ if (present->drop_wnd_messages && message != WM_DISPLAYCHANGE) -+ { -+ TRACE("Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx.\n", -+ window, message, wparam, lparam); -+ if (unicode) -+ return DefWindowProcW(window, message, wparam, lparam); -+ else -+ return DefWindowProcA(window, message, wparam, lparam); -+ } -+ -+ if (message == WM_DESTROY) -+ { -+ TRACE("unregister window %p.\n", window); -+ (void) nine_unregister_window(window); -+ } -+ else if (message == WM_DISPLAYCHANGE) -+ { -+ /* Ex restores display mode, while non Ex requires the -+ * user to call Device::Reset() */ -+ ZeroMemory(¤t_mode, sizeof(DEVMODEW)); -+ current_mode.dmSize = sizeof(current_mode); -+ if (!present->ex && -+ !present->params.Windowed && -+ present->params.hDeviceWindow && -+ EnumDisplaySettingsW(present->devname, ENUM_CURRENT_SETTINGS, ¤t_mode) && -+ (current_mode.dmPelsWidth != present->params.BackBufferWidth || -+ current_mode.dmPelsHeight != present->params.BackBufferHeight)) -+ { -+ present->resolution_mismatch = TRUE; -+ } -+ else -+ { -+ present->resolution_mismatch = FALSE; -+ } -+ } -+ else if (message == WM_ACTIVATEAPP) -+ { -+ drop_wnd_messages = present->drop_wnd_messages; -+ present->drop_wnd_messages = TRUE; -+ -+ if (wparam == WA_INACTIVE) -+ { -+ present->occluded = TRUE; -+ present->reapply_mode = TRUE; -+ -+ ZeroMemory(&new_mode, sizeof(DEVMODEW)); -+ new_mode.dmSize = sizeof(new_mode); -+ if (EnumDisplaySettingsW(present->devname, ENUM_REGISTRY_SETTINGS, &new_mode)) -+ DRI3Present_ChangeDisplaySettingsIfNeccessary(present, &new_mode); -+ -+ if (!present->no_window_changes && -+ IsWindowVisible(present->params.hDeviceWindow)) -+ ShowWindow(present->params.hDeviceWindow, SW_MINIMIZE); -+ } -+ else -+ { -+ present->occluded = FALSE; -+ -+ if (!present->no_window_changes) -+ { -+ /* restore window */ -+ SetWindowPos(present->params.hDeviceWindow, NULL, 0, 0, -+ present->params.BackBufferWidth, present->params.BackBufferHeight, -+ SWP_NOACTIVATE | SWP_NOZORDER); -+ } -+ -+ if (present->ex) -+ { -+ ZeroMemory(&new_mode, sizeof(DEVMODEW)); -+ new_mode.dmSize = sizeof(new_mode); -+ new_mode.dmPelsWidth = present->params.BackBufferWidth; -+ new_mode.dmPelsHeight = present->params.BackBufferHeight; -+ new_mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; -+ if (present->params.FullScreen_RefreshRateInHz) -+ { -+ new_mode.dmFields |= DM_DISPLAYFREQUENCY; -+ new_mode.dmDisplayFrequency = present->params.FullScreen_RefreshRateInHz; -+ } -+ DRI3Present_ChangeDisplaySettingsIfNeccessary(present, &new_mode); -+ } -+ } -+ present->drop_wnd_messages = drop_wnd_messages; -+ } -+ else if (message == WM_SYSCOMMAND) -+ { -+ if (wparam == SC_RESTORE) -+ { -+ if (unicode) -+ DefWindowProcW(window, message, wparam, lparam); -+ else -+ DefWindowProcA(window, message, wparam, lparam); -+ } -+ } -+ -+ if (unicode) -+ return CallWindowProcW(proc, window, message, wparam, lparam); -+ else -+ return CallWindowProcA(proc, window, message, wparam, lparam); -+} -+ -+static void setup_fullscreen_window(struct DRI3Present *This, -+ HWND hwnd, int w, int h) -+{ -+ boolean drop_wnd_messages; -+ LONG style, style_ex; -+ -+ This->style = GetWindowLongW(hwnd, GWL_STYLE); -+ This->style_ex = GetWindowLongW(hwnd, GWL_EXSTYLE); -+ -+ style = fullscreen_style(This->style); -+ style_ex = fullscreen_exstyle(This->style_ex); -+ -+ drop_wnd_messages = This->drop_wnd_messages; -+ This->drop_wnd_messages = TRUE; -+ -+ SetWindowLongW(hwnd, GWL_STYLE, style); -+ SetWindowLongW(hwnd, GWL_EXSTYLE, style_ex); -+ -+ SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, w, h, -+ SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); -+ -+ This->drop_wnd_messages = drop_wnd_messages; -+} -+ -+static void move_fullscreen_window(struct DRI3Present *This, -+ HWND hwnd, int w, int h) -+{ -+ boolean drop_wnd_messages; -+ LONG style, style_ex; -+ -+ /* move draw window back to place */ -+ -+ style = GetWindowLongW(hwnd, GWL_STYLE); -+ style_ex = GetWindowLongW(hwnd, GWL_EXSTYLE); -+ -+ style = fullscreen_style(style); -+ style_ex = fullscreen_exstyle(style_ex); -+ -+ drop_wnd_messages = This->drop_wnd_messages; -+ This->drop_wnd_messages = TRUE; -+ SetWindowLongW(hwnd, GWL_STYLE, style); -+ SetWindowLongW(hwnd, GWL_EXSTYLE, style_ex); -+ SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, w, h, -+ SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); -+ This->drop_wnd_messages = drop_wnd_messages; -+} -+ -+static void restore_fullscreen_window(struct DRI3Present *This, -+ HWND hwnd) -+{ -+ boolean drop_wnd_messages; -+ LONG style, style_ex; -+ -+ /* switch from fullscreen to window */ -+ style = GetWindowLongW(hwnd, GWL_STYLE); -+ style_ex = GetWindowLongW(hwnd, GWL_EXSTYLE); -+ /* These flags are set by us, not the -+ * application, and we want to ignore them in the test below, since it's -+ * not the application's fault that they changed. Additionally, we want to -+ * preserve the current status of these flags (i.e. don't restore them) to -+ * more closely emulate the behavior of Direct3D, which leaves these flags -+ * alone when returning to windowed mode. */ -+ This->style ^= (This->style ^ style) & WS_VISIBLE; -+ This->style_ex ^= (This->style_ex ^ style_ex) & WS_EX_TOPMOST; -+ -+ /* Only restore the style if the application didn't modify it during the -+ * fullscreen phase. Some applications change it before calling Reset() -+ * when switching between windowed and fullscreen modes (HL2), some -+ * depend on the original style (Eve Online). */ -+ drop_wnd_messages = This->drop_wnd_messages; -+ This->drop_wnd_messages = TRUE; -+ if (style == fullscreen_style(This->style) && -+ style_ex == fullscreen_exstyle(This->style_ex)) -+ { -+ SetWindowLongW(hwnd, GWL_STYLE, This->style); -+ SetWindowLongW(hwnd, GWL_EXSTYLE, This->style_ex); -+ } -+ SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | -+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | -+ SWP_NOACTIVATE); -+ This->drop_wnd_messages = drop_wnd_messages; -+ -+ This->style = 0; -+ This->style_ex = 0; -+} -+ -+static void DRI3Present_UpdatePresentationInterval(struct DRI3Present *This) -+{ -+ switch(This->params.PresentationInterval) -+ { -+ case D3DPRESENT_INTERVAL_DEFAULT: -+ case D3DPRESENT_INTERVAL_ONE: -+ This->present_interval = 1; -+ This->present_async = FALSE; -+ break; -+ case D3DPRESENT_INTERVAL_TWO: -+ This->present_interval = 2; -+ This->present_async = FALSE; -+ break; -+ case D3DPRESENT_INTERVAL_THREE: -+ This->present_interval = 3; -+ This->present_async = FALSE; -+ break; -+ case D3DPRESENT_INTERVAL_FOUR: -+ This->present_interval = 4; -+ This->present_async = FALSE; -+ break; -+ case D3DPRESENT_INTERVAL_IMMEDIATE: -+ default: -+ This->present_interval = 0; -+ This->present_async = -+ !(This->params.SwapEffect == D3DSWAPEFFECT_DISCARD && -+ This->tear_free_discard); -+ break; -+ } -+ -+ /* D3DSWAPEFFECT_COPY: Force Copy. -+ * This->present_interval == 0: Force Copy to have buffers -+ * release as soon as possible (the display server/compositor -+ * won't hold any buffer), unless DISCARD and -+ * allow_discard_delayed_release */ -+ This->present_swapeffectcopy = -+ This->params.SwapEffect == D3DSWAPEFFECT_COPY || -+ (This->present_interval == 0 && -+ !(This->params.SwapEffect == D3DSWAPEFFECT_DISCARD && -+ This->allow_discard_delayed_release)); -+} -+ -+static HRESULT DRI3Present_ChangePresentParameters(struct DRI3Present *This, -+ D3DPRESENT_PARAMETERS *params) -+{ -+ HWND focus_window = This->focus_wnd ? This->focus_wnd : params->hDeviceWindow; -+ RECT rect; -+ DEVMODEW new_mode; -+ HRESULT hr; -+ boolean drop_wnd_messages; -+ -+ TRACE("This=%p, params=%p, focus_window=%p, params->hDeviceWindow=%p\n", -+ This, params, focus_window, params->hDeviceWindow); -+ -+ This->params.SwapEffect = params->SwapEffect; -+ This->params.AutoDepthStencilFormat = params->AutoDepthStencilFormat; -+ This->params.Flags = params->Flags; -+ This->params.FullScreen_RefreshRateInHz = params->FullScreen_RefreshRateInHz; -+ This->params.PresentationInterval = params->PresentationInterval; -+ This->params.EnableAutoDepthStencil = params->EnableAutoDepthStencil; -+ if (!params->hDeviceWindow) -+ params->hDeviceWindow = This->params.hDeviceWindow; -+ else -+ This->params.hDeviceWindow = params->hDeviceWindow; -+ -+ if ((This->params.BackBufferWidth != params->BackBufferWidth) || -+ (This->params.BackBufferHeight != params->BackBufferHeight) || -+ (This->params.Windowed != params->Windowed) || -+ This->reapply_mode) -+ { -+ This->reapply_mode = FALSE; -+ -+ if (!params->Windowed) -+ { -+ TRACE("Setting fullscreen mode: %dx%d@%d\n", params->BackBufferWidth, -+ params->BackBufferHeight, params->FullScreen_RefreshRateInHz); -+ -+ /* switch display mode */ -+ ZeroMemory(&new_mode, sizeof(DEVMODEW)); -+ new_mode.dmPelsWidth = params->BackBufferWidth; -+ new_mode.dmPelsHeight = params->BackBufferHeight; -+ new_mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; -+ if (params->FullScreen_RefreshRateInHz) -+ { -+ new_mode.dmFields |= DM_DISPLAYFREQUENCY; -+ new_mode.dmDisplayFrequency = params->FullScreen_RefreshRateInHz; -+ } -+ new_mode.dmSize = sizeof(DEVMODEW); -+ hr = DRI3Present_ChangeDisplaySettingsIfNeccessary(This, &new_mode); -+ if (FAILED(hr)) -+ return hr; -+ -+ /* Dirty as BackBufferWidth and BackBufferHeight hasn't been set yet */ -+ This->resolution_mismatch = FALSE; -+ } -+ else if(!This->params.Windowed && params->Windowed) -+ { -+ TRACE("Setting fullscreen mode: %dx%d@%d\n", This->initial_mode.dmPelsWidth, -+ This->initial_mode.dmPelsHeight, This->initial_mode.dmDisplayFrequency); -+ -+ hr = DRI3Present_ChangeDisplaySettingsIfNeccessary(This, &This->initial_mode); -+ if (FAILED(hr)) -+ return hr; -+ -+ /* Dirty as BackBufferWidth and BackBufferHeight hasn't been set yet */ -+ This->resolution_mismatch = FALSE; -+ } -+ -+ if (This->params.Windowed) -+ { -+ if (!params->Windowed) -+ { -+ /* switch from window to fullscreen */ -+ if (!nine_register_window(focus_window, This)) -+ return D3DERR_INVALIDCALL; -+ -+ SetWindowPos(focus_window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); -+ -+ setup_fullscreen_window(This, params->hDeviceWindow, -+ params->BackBufferWidth, params->BackBufferHeight); -+ } -+ } -+ else -+ { -+ if (!params->Windowed) -+ { -+ /* switch from fullscreen to fullscreen */ -+ drop_wnd_messages = This->drop_wnd_messages; -+ This->drop_wnd_messages = TRUE; -+ MoveWindow(params->hDeviceWindow, 0, 0, -+ params->BackBufferWidth, -+ params->BackBufferHeight, -+ TRUE); -+ This->drop_wnd_messages = drop_wnd_messages; -+ } -+ else if (This->style || This->style_ex) -+ { -+ restore_fullscreen_window(This, params->hDeviceWindow); -+ } -+ -+ if (params->Windowed && !nine_unregister_window(focus_window)) -+ ERR("Window %p is not registered with nine.\n", focus_window); -+ } -+ This->params.Windowed = params->Windowed; -+ } -+ else if (!params->Windowed) -+ { -+ move_fullscreen_window(This, params->hDeviceWindow, params->BackBufferWidth, params->BackBufferHeight); -+ } -+ else -+ { -+ TRACE("Nothing changed.\n"); -+ } -+ if (!params->BackBufferWidth || !params->BackBufferHeight) { -+ if (!params->Windowed) -+ return D3DERR_INVALIDCALL; -+ -+ if (!GetClientRect(params->hDeviceWindow, &rect)) -+ return D3DERR_INVALIDCALL; -+ -+ if (params->BackBufferWidth == 0) -+ params->BackBufferWidth = rect.right - rect.left; -+ -+ if (params->BackBufferHeight == 0) -+ params->BackBufferHeight = rect.bottom - rect.top; -+ } -+ -+ /* Set as last in case of failed reset those aren't updated */ -+ This->params.BackBufferWidth = params->BackBufferWidth; -+ This->params.BackBufferHeight = params->BackBufferHeight; -+ This->params.BackBufferFormat = params->BackBufferFormat; -+ This->params.BackBufferCount = params->BackBufferCount; -+ This->params.MultiSampleType = params->MultiSampleType; -+ This->params.MultiSampleQuality = params->MultiSampleQuality; -+ -+ DRI3Present_UpdatePresentationInterval(This); -+ -+ return D3D_OK; -+} -+ -+/* The following code isn't based on WINE's wined3d or d3d9. */ -+ -+static HRESULT DRI3Present_new(Display *gdi_display, const WCHAR *devname, -+ D3DPRESENT_PARAMETERS *params, HWND focus_wnd, struct DRI3Present **out, -+ boolean ex, boolean no_window_changes) -+{ -+ struct DRI3Present *This; -+ HWND focus_window; -+ DEVMODEW new_mode; -+ HRESULT hr; -+ RECT rect; -+ -+ if (!focus_wnd && !params->hDeviceWindow) -+ { -+ ERR("No focus HWND specified for presentation backend.\n"); -+ return D3DERR_INVALIDCALL; -+ } -+ -+ This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(struct DRI3Present)); -+ if (!This) -+ { -+ ERR("Out of memory.\n"); -+ return E_OUTOFMEMORY; -+ } -+ -+ This->gdi_display = gdi_display; -+ This->vtable = &DRI3Present_vtable; -+ This->refs = 1; -+ This->focus_wnd = focus_wnd; -+ This->ex = ex; -+ This->no_window_changes = no_window_changes; -+ -+ /* store current resolution */ -+ ZeroMemory(&(This->initial_mode), sizeof(This->initial_mode)); -+ This->initial_mode.dmSize = sizeof(This->initial_mode); -+ EnumDisplaySettingsExW(This->devname, ENUM_CURRENT_SETTINGS, &(This->initial_mode), 0); -+ -+ if (!params->hDeviceWindow) -+ params->hDeviceWindow = This->focus_wnd; -+ -+ if (!params->Windowed) { -+ focus_window = This->focus_wnd ? This->focus_wnd : params->hDeviceWindow; -+ -+ if (!nine_register_window(focus_window, This)) -+ return D3DERR_INVALIDCALL; -+ -+ SetWindowPos(focus_window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); -+ -+ /* switch display mode */ -+ ZeroMemory(&new_mode, sizeof(DEVMODEW)); -+ new_mode.dmSize = sizeof(DEVMODEW); -+ new_mode.dmPelsWidth = params->BackBufferWidth; -+ new_mode.dmPelsHeight = params->BackBufferHeight; -+ new_mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; -+ -+ if (params->FullScreen_RefreshRateInHz) -+ { -+ new_mode.dmFields |= DM_DISPLAYFREQUENCY; -+ new_mode.dmDisplayFrequency = params->FullScreen_RefreshRateInHz; -+ } -+ -+ hr = DRI3Present_ChangeDisplaySettingsIfNeccessary(This, &new_mode); -+ if (FAILED(hr)) -+ { -+ nine_unregister_window(focus_window); -+ HeapFree(GetProcessHeap(), 0, This); -+ return hr; -+ } -+ -+ /* Dirty as BackBufferWidth and BackBufferHeight hasn't been set yet */ -+ This->resolution_mismatch = FALSE; -+ -+ setup_fullscreen_window(This, params->hDeviceWindow, -+ params->BackBufferWidth, params->BackBufferHeight); -+ } else { -+ GetClientRect(params->hDeviceWindow, &rect); -+ if (!params->BackBufferWidth || !params->BackBufferHeight) { -+ -+ if (params->BackBufferWidth == 0) -+ params->BackBufferWidth = rect.right - rect.left; -+ -+ if (params->BackBufferHeight == 0) -+ params->BackBufferHeight = rect.bottom - rect.top; -+ } -+ } -+ -+ This->params = *params; -+ -+ DRI3Present_UpdatePresentationInterval(This); -+ -+ strcpyW(This->devname, devname); -+ -+ PRESENTInit(gdi_display, &(This->present_priv)); -+#ifdef D3D9NINE_DRI2 -+ if (is_dri2_fallback && !DRI2FallbackInit(gdi_display, &(This->dri2_priv))) -+ return D3DERR_INVALIDCALL; -+#endif -+ *out = This; -+ -+ return D3D_OK; -+} -+ -+struct DRI3PresentGroup -+{ -+ /* COM vtable */ -+ void *vtable; -+ /* IUnknown reference count */ -+ LONG refs; -+ -+ boolean ex; -+ struct DRI3Present **present_backends; -+ unsigned npresent_backends; -+ Display *gdi_display; -+ boolean no_window_changes; -+}; -+ -+static ULONG WINAPI DRI3PresentGroup_AddRef(struct DRI3PresentGroup *This) -+{ -+ ULONG refs = InterlockedIncrement(&This->refs); -+ TRACE("%p increasing refcount to %u.\n", This, refs); -+ return refs; -+} -+ -+static ULONG WINAPI DRI3PresentGroup_Release(struct DRI3PresentGroup *This) -+{ -+ ULONG refs = InterlockedDecrement(&This->refs); -+ TRACE("%p decreasing refcount to %u.\n", This, refs); -+ if (refs == 0) -+ { -+ unsigned i; -+ if (This->present_backends) -+ { -+ for (i = 0; i < This->npresent_backends; ++i) -+ { -+ if (This->present_backends[i]) -+ DRI3Present_Release(This->present_backends[i]); -+ } -+ HeapFree(GetProcessHeap(), 0, This->present_backends); -+ } -+ HeapFree(GetProcessHeap(), 0, This); -+ } -+ return refs; -+} -+ -+static HRESULT WINAPI DRI3PresentGroup_QueryInterface(struct DRI3PresentGroup *This, -+ REFIID riid, void **ppvObject ) -+{ -+ if (!ppvObject) -+ return E_POINTER; -+ if (IsEqualGUID(&IID_ID3DPresentGroup, riid) || -+ IsEqualGUID(&IID_IUnknown, riid)) -+ { -+ *ppvObject = This; -+ DRI3PresentGroup_AddRef(This); -+ return S_OK; -+ } -+ -+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); -+ *ppvObject = NULL; -+ -+ return E_NOINTERFACE; -+} -+ -+static UINT WINAPI DRI3PresentGroup_GetMultiheadCount(struct DRI3PresentGroup *This) -+{ -+ FIXME("(%p), stub!\n", This); -+ return 1; -+} -+ -+static HRESULT WINAPI DRI3PresentGroup_GetPresent(struct DRI3PresentGroup *This, -+ UINT Index, ID3DPresent **ppPresent) -+{ -+ if (Index >= DRI3PresentGroup_GetMultiheadCount(This)) -+ { -+ ERR("Index >= MultiHeadCount\n"); -+ return D3DERR_INVALIDCALL; -+ } -+ DRI3Present_AddRef(This->present_backends[Index]); -+ *ppPresent = (ID3DPresent *)This->present_backends[Index]; -+ -+ return D3D_OK; -+} -+ -+static HRESULT WINAPI DRI3PresentGroup_CreateAdditionalPresent(struct DRI3PresentGroup *This, -+ D3DPRESENT_PARAMETERS *pPresentationParameters, ID3DPresent **ppPresent) -+{ -+ HRESULT hr; -+ hr = DRI3Present_new(This->gdi_display, This->present_backends[0]->devname, -+ pPresentationParameters, 0, (struct DRI3Present **)ppPresent, -+ This->ex, This->no_window_changes); -+ -+ return hr; -+} -+ -+static void WINAPI DRI3PresentGroup_GetVersion(struct DRI3PresentGroup *This, -+ int *major, int *minor) -+{ -+ *major = WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MAJOR; -+ *minor = WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR; -+} -+ -+static ID3DPresentGroupVtbl DRI3PresentGroup_vtable = { -+ (void *)DRI3PresentGroup_QueryInterface, -+ (void *)DRI3PresentGroup_AddRef, -+ (void *)DRI3PresentGroup_Release, -+ (void *)DRI3PresentGroup_GetMultiheadCount, -+ (void *)DRI3PresentGroup_GetPresent, -+ (void *)DRI3PresentGroup_CreateAdditionalPresent, -+ (void *)DRI3PresentGroup_GetVersion -+}; -+ -+HRESULT present_create_present_group(Display *gdi_display, const WCHAR *device_name, -+ UINT adapter, HWND focus_wnd, D3DPRESENT_PARAMETERS *params, -+ unsigned nparams, ID3DPresentGroup **group, boolean ex, DWORD BehaviorFlags) -+{ -+ struct DRI3PresentGroup *This; -+ DISPLAY_DEVICEW dd; -+ HRESULT hr; -+ unsigned i; -+ -+ This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ sizeof(struct DRI3PresentGroup)); -+ if (!This) -+ { -+ ERR("Out of memory.\n"); -+ return E_OUTOFMEMORY; -+ } -+ -+ This->gdi_display = gdi_display; -+ This->vtable = &DRI3PresentGroup_vtable; -+ This->refs = 1; -+ This->ex = ex; -+ This->npresent_backends = nparams; -+ This->no_window_changes = !!(BehaviorFlags & D3DCREATE_NOWINDOWCHANGES); -+ This->present_backends = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, -+ This->npresent_backends * sizeof(struct DRI3Present *)); -+ if (!This->present_backends) -+ { -+ DRI3PresentGroup_Release(This); -+ ERR("Out of memory.\n"); -+ return E_OUTOFMEMORY; -+ } -+ -+ if (nparams != 1) -+ adapter = 0; -+ -+ for (i = 0; i < This->npresent_backends; ++i) -+ { -+ ZeroMemory(&dd, sizeof(dd)); -+ dd.cb = sizeof(dd); -+ /* find final device name */ -+ if (!EnumDisplayDevicesW(device_name, adapter + i, &dd, 0)) -+ { -+ WARN("Couldn't find subdevice %d from `%s'\n", -+ i, debugstr_w(device_name)); -+ } -+ -+ /* create an ID3DPresent for it */ -+ hr = DRI3Present_new(gdi_display, dd.DeviceName, ¶ms[i], -+ focus_wnd, &This->present_backends[i], ex, This->no_window_changes); -+ if (FAILED(hr)) -+ { -+ DRI3PresentGroup_Release(This); -+ return hr; -+ } -+ } -+ -+ *group = (ID3DPresentGroup *)This; -+ TRACE("Returning %p\n", *group); -+ -+ return D3D_OK; -+} -+ -+HRESULT present_create_adapter9(Display *gdi_display, HDC hdc, ID3DAdapter9 **out) -+{ -+ struct x11drv_escape_get_drawable extesc = { X11DRV_GET_DRAWABLE }; -+ HRESULT hr; -+ int fd; -+ -+ if (!d3d9_drm) -+ { -+ ERR("DRM drivers are not supported on your system.\n"); -+ return D3DERR_DRIVERINTERNALERROR; -+ } -+ -+ if (ExtEscape(hdc, X11DRV_ESCAPE, sizeof(extesc), (LPCSTR)&extesc, -+ sizeof(extesc), (LPSTR)&extesc) <= 0) -+ ERR("X11 drawable lookup failed (hdc=%p)\n", hdc); -+ -+#ifdef D3D9NINE_DRI2 -+ if (!is_dri2_fallback && !DRI3Open(gdi_display, DefaultScreen(gdi_display), &fd)) -+#else -+ if (!DRI3Open(gdi_display, DefaultScreen(gdi_display), &fd)) -+#endif -+ { -+ ERR("DRI3Open failed (fd=%d)\n", fd); -+ return D3DERR_DRIVERINTERNALERROR; -+ } -+#ifdef D3D9NINE_DRI2 -+ if (is_dri2_fallback && !DRI2FallbackOpen(gdi_display, DefaultScreen(gdi_display), &fd)) -+ { -+ ERR("DRI2Open failed (fd=%d)\n", fd); -+ return D3DERR_DRIVERINTERNALERROR; -+ } -+#endif -+ hr = d3d9_drm->create_adapter(fd, out); -+ if (FAILED(hr)) -+ { -+ ERR("Unable to create ID3DAdapter9 (fd=%d)\n", fd); -+ return hr; -+ } -+ -+ TRACE("Created ID3DAdapter9 with fd %d\n", fd); -+ -+ return D3D_OK; -+} -+ -+BOOL present_has_d3dadapter(Display *gdi_display) -+{ -+ static const void * WINAPI (*pD3DAdapter9GetProc)(const char *); -+ static void *handle = NULL; -+ static int done = 0; -+ HKEY regkey; -+ LSTATUS rc; -+ char *path = NULL; -+ -+ char errbuf[256]; -+ char pathbuf[MAX_PATH]; -+ -+ /* like in opengl.c (single threaded assumption OK?) */ -+ if (done) -+ return handle != NULL; -+ done = 1; -+ -+ if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Direct3DNine", ®key)) -+ { -+ DWORD type; -+ DWORD size = 0; -+ -+ rc = RegQueryValueExA(regkey, "ModulePath", 0, &type, NULL, &size); -+ if (rc == ERROR_FILE_NOT_FOUND) -+ goto use_default_path; -+ -+ TRACE("Reading registry key for module path\n"); -+ if (rc != ERROR_SUCCESS || type != REG_SZ) -+ { -+ ERR("Failed to read Direct3DNine ModulePath registry key: Invalid content\n"); -+ goto cleanup; -+ } -+ -+ path = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 1); -+ if (!path) -+ { -+ ERR("Out of memory\n"); -+ return FALSE; -+ } -+ rc = RegQueryValueExA(regkey, "ModulePath", 0, &type, (LPBYTE)path, &size); -+ if (rc != ERROR_SUCCESS) -+ { -+ ERR("Failed to read Direct3DNine registry\n"); -+ goto cleanup; -+ } -+ /* Split colon separated path for multi-arch support */ -+ if (strstr(path, ":")) -+ { -+ char *tmp_path = strstr(path, ":"); -+ -+ /* Replace colon by string terminate */ -+ *tmp_path = 0; -+ tmp_path ++; -+ handle = wine_dlopen(path, -+ RTLD_GLOBAL | RTLD_NOW, errbuf, sizeof(errbuf)); -+ if (!handle) -+ { -+ TRACE("Failed to load '%s': %s\n", path, errbuf); -+ -+ handle = wine_dlopen(tmp_path, -+ RTLD_GLOBAL | RTLD_NOW, errbuf, sizeof(errbuf)); -+ if (!handle) -+ { -+ TRACE("Failed to load '%s': %s\n", tmp_path, errbuf); -+ ERR("Failed to load '%s' and '%s' set by ModulePath.\n", -+ path, tmp_path); -+ goto cleanup; -+ } -+ } -+ } -+ else -+ { -+ handle = wine_dlopen(path, -+ RTLD_GLOBAL | RTLD_NOW, errbuf, sizeof(errbuf)); -+ if (!handle) -+ { -+ TRACE("Failed to load %s: %s\n", path, errbuf); -+ ERR("Failed to load '%s' set by ModulePath.\n", path); -+ goto cleanup; -+ } -+ } -+ memcpy(pathbuf, path, size >= sizeof(pathbuf) ? (sizeof(pathbuf)-1) : size); -+ pathbuf[sizeof(pathbuf)-1] = 0; -+ -+ HeapFree(GetProcessHeap(), 0, path); -+ } -+ -+use_default_path: -+#if !defined(D3D9NINE_MODULEPATH) -+ if (!handle) -+ { -+ ERR("d3d9-nine.dll was built without default module path.\n" -+ "Setting Software\\Wine\\Direct3DNine ModulePath is required\n"); -+ goto cleanup; -+ } -+#else -+ if (!handle) -+ { -+ handle = wine_dlopen(D3D9NINE_MODULEPATH, -+ RTLD_GLOBAL | RTLD_NOW, errbuf, sizeof(errbuf)); -+ if (!handle) -+ { -+ ERR("Failed to load '%s': %s\n", D3D9NINE_MODULEPATH, errbuf); -+ goto cleanup; -+ } -+ memcpy(pathbuf, D3D9NINE_MODULEPATH, -+ sizeof(D3D9NINE_MODULEPATH) >= sizeof(pathbuf) ? -+ (sizeof(pathbuf)-1) : sizeof(D3D9NINE_MODULEPATH)); -+ pathbuf[sizeof(pathbuf)-1] = 0; -+ } -+#endif -+ /* find our entry point in d3dadapter9 */ -+ pD3DAdapter9GetProc = wine_dlsym(handle, "D3DAdapter9GetProc", -+ errbuf, sizeof(errbuf)); -+ if (!pD3DAdapter9GetProc) -+ { -+ ERR("Failed to get the entry point from %s: %s", pathbuf, errbuf); -+ goto cleanup; -+ } -+ -+ /* get a handle to the drm backend struct */ -+ d3d9_drm = pD3DAdapter9GetProc("drm"); -+ if (!d3d9_drm) -+ { -+ ERR("%s doesn't support the drm backend.\n", pathbuf); -+ goto cleanup; -+ } -+ -+ /* verify that we're binary compatible */ -+ if (d3d9_drm->major_version != 0) -+ { -+ ERR("Version mismatch. %s has %d.%d, was expecting 0.x\n", -+ pathbuf, d3d9_drm->major_version, d3d9_drm->minor_version); -+ goto cleanup; -+ } -+ -+ /* this will be used to store d3d_drawables */ -+ d3d_hwnd_context = XUniqueContext(); -+ -+ if (!PRESENTCheckExtension(gdi_display, 1, 0)) -+ { -+ ERR("Unable to query PRESENT.\n"); -+ goto cleanup; -+ } -+ -+ if (!DRI3CheckExtension(gdi_display, 1, 0)) -+ { -+#ifndef D3D9NINE_DRI2 -+ ERR("Unable to query DRI3.\n"); -+ goto cleanup; -+#else -+ ERR("Unable to query DRI3. Trying DRI2 fallback (slower performance).\n"); -+ is_dri2_fallback = 1; -+ if (!DRI2FallbackCheckSupport(gdi_display)) -+ { -+ ERR("DRI2 fallback unsupported\n"); -+ goto cleanup; -+ } -+#endif -+ } -+ -+ return TRUE; -+ -+cleanup: -+ ERR("\033[1;31m\nNative Direct3D 9 will be unavailable." -+ "\nFor more information visit https://wiki.ixit.cz/d3d9\033[0m\n"); -+ if (handle) -+ { -+ wine_dlclose(handle, NULL, 0); -+ handle = NULL; -+ } -+ -+ if (path) -+ HeapFree(GetProcessHeap(), 0, path); -+ -+ return FALSE; -+} -+ -+BOOL enable_device_vtable_wrapper(void) -+{ -+ if (!d3d9_drm) -+ { -+ ERR("enable_device_vtable_wrapper call before init.\n"); -+ return FALSE; -+ } -+ /* Since minor version 1, we can assume a copy of the internal vtable is stored in second pos. -+ * For now always enable if possible the wrapper (enables Steam overlay for example), -+ * we might in the future let user choose. */ -+ return d3d9_drm->minor_version >= 1; -+} -diff --git a/dlls/d3d9-nine/present.h b/dlls/d3d9-nine/present.h -new file mode 100644 -index 0000000000..a5516877f1 ---- /dev/null -+++ b/dlls/d3d9-nine/present.h -@@ -0,0 +1,40 @@ -+/* -+ * Wine present interface -+ * -+ * Copyright 2015 Patrick Rudolph -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#ifndef __WINE_PRESENT_H -+#define __WINE_PRESENT_H -+ -+#ifndef __WINE_CONFIG_H -+# error You must include config.h to use this header -+#endif -+ -+#include -+ -+HRESULT present_create_present_group(Display *gdi_display, const WCHAR *device_name, UINT adapter, -+ HWND focus, D3DPRESENT_PARAMETERS *params, unsigned nparams, ID3DPresentGroup **group, -+ boolean ex, DWORD BehaviorFlags); -+ -+HRESULT present_create_adapter9(Display *gdi_display, HDC hdc, ID3DAdapter9 **adapter); -+ -+BOOL present_has_d3dadapter(Display *gdi_display); -+ -+BOOL enable_device_vtable_wrapper(void); -+ -+#endif /* __WINE_PRESENT_H */ -diff --git a/dlls/d3d9-nine/shader_validator.c b/dlls/d3d9-nine/shader_validator.c -new file mode 100644 -index 0000000000..03848b2aa2 ---- /dev/null -+++ b/dlls/d3d9-nine/shader_validator.c -@@ -0,0 +1,88 @@ -+/* -+ * Direct3D 9 ShaderValidator -+ * -+ * Copyright 2016 Patrick Rudolph -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ * -+ */ -+#include "wine/debug.h" -+WINE_DEFAULT_DEBUG_CHANNEL(d3d9nine); -+ -+#include "winbase.h" -+ -+#include "shader_validator.h" -+ -+static HRESULT WINAPI IDirect3DShaderValidator9Impl_QueryInterface(IDirect3DShaderValidator9Impl *This, -+ REFIID riid, LPVOID* ppobj) -+{ -+ /* TODO: AddRef(iface). */ -+ *ppobj = This; -+ TRACE("This=%p, riid=%s, object=%p.\n", This, debugstr_guid(riid), ppobj); -+ -+ return S_OK; -+} -+ -+static ULONG WINAPI IDirect3DShaderValidator9Impl_AddRef(IDirect3DShaderValidator9Impl *This) -+{ -+ ULONG ref = InterlockedIncrement(&This->ref); -+ TRACE("This=%p increasing refcount to %u.\n", This, ref); -+ -+ return ref; -+} -+ -+static ULONG WINAPI IDirect3DShaderValidator9Impl_Release(IDirect3DShaderValidator9Impl *This) -+{ -+ ULONG ref = InterlockedDecrement(&This->ref); -+ TRACE("This=%p decreasing refcount to %u.\n", This, ref); -+ -+ if (ref == 0) -+ HeapFree(GetProcessHeap(), 0, This); -+ -+ return ref; -+} -+ -+static LONG WINAPI IDirect3DShaderValidator9Impl_Begin(IDirect3DShaderValidator9Impl *This, -+ void* callback, void* unknown1, ULONG unknown2) -+{ -+ TRACE("This=%p, callback=%p, unknown1=%p, unknown2=%u\n", This, callback, unknown1, unknown2); -+ return 1; -+} -+ -+static LONG WINAPI IDirect3DShaderValidator9Impl_Instruction(IDirect3DShaderValidator9Impl *This, -+ const char* unknown1, unsigned int unknown2, const unsigned long* unknown3, unsigned int unknown4) -+{ -+ TRACE("This=%p, unknown1=%p, unknown2=%u, unknown3=%p, unknown4=%u\n", This, unknown1, unknown2, unknown3, unknown4); -+ return 1; -+} -+ -+static LONG WINAPI IDirect3DShaderValidator9Impl_End(IDirect3DShaderValidator9Impl *This) -+{ -+ TRACE("This=%p\n", This); -+ return 1; -+} -+ -+const void *IDirect3DShaderValidator9Vtbl[] = -+{ -+ /* IUnknown */ -+ IDirect3DShaderValidator9Impl_QueryInterface, -+ IDirect3DShaderValidator9Impl_AddRef, -+ IDirect3DShaderValidator9Impl_Release, -+ /* IDirect3DShaderValidator9 */ -+ IDirect3DShaderValidator9Impl_Begin, -+ IDirect3DShaderValidator9Impl_Instruction, -+ IDirect3DShaderValidator9Impl_End -+}; -+ -diff --git a/dlls/d3d9-nine/shader_validator.h b/dlls/d3d9-nine/shader_validator.h -new file mode 100644 -index 0000000000..07a5e2d2b4 ---- /dev/null -+++ b/dlls/d3d9-nine/shader_validator.h -@@ -0,0 +1,29 @@ -+/* -+ * Direct3D 9 ShaderValidator -+ * -+ * Copyright 2016 Patrick Rudolph -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ * -+ */ -+ -+typedef struct IDirect3DShaderValidator9Impl -+{ -+ /* IUnknown fields */ -+ void *lpVtbl; -+ LONG ref; -+} IDirect3DShaderValidator9Impl; -+ -+const void *IDirect3DShaderValidator9Vtbl[6]; -diff --git a/dlls/d3d9-nine/version.rc b/dlls/d3d9-nine/version.rc -new file mode 100644 -index 0000000000..bfafc2f24a ---- /dev/null -+++ b/dlls/d3d9-nine/version.rc -@@ -0,0 +1,26 @@ -+/* -+ * Copyright 2015 Patrick Rudolph -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#define WINE_FILEDESCRIPTION_STR "Wine Gallium Nine Direct3D" -+#define WINE_FILENAME_STR "d3d9-nine.dll" -+#define WINE_FILEVERSION 5,3,1,904 -+#define WINE_FILEVERSION_STR "5.3.1.904" -+#define WINE_PRODUCTVERSION 5,3,1,904 -+#define WINE_PRODUCTVERSION_STR "5.3.1.904" -+ -+#include "wine/wine_common_ver.rc" -diff --git a/dlls/d3d9-nine/wndproc.c b/dlls/d3d9-nine/wndproc.c -new file mode 100644 -index 0000000000..0ed80de7d7 ---- /dev/null -+++ b/dlls/d3d9-nine/wndproc.c -@@ -0,0 +1,277 @@ -+/* -+ * Copyright 2016 Patrick Rudolph -+ * -+ * Based on the file wined3d_main.c taken from wined3d: -+ * All credits go to the original developers: -+ * -+ * Copyright 2002-2003 The wine-d3d team -+ * Copyright 2002-2003 Raphael Junqueira -+ * Copyright 2004 Jason Edmeades -+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers -+ * Copyright 2009 Henri Verbeet for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "config.h" -+#include "wine/port.h" -+ -+#include -+#include -+#include -+#define NONAMELESSUNION -+#define NONAMELESSSTRUCT -+#define COBJMACROS -+#include "windef.h" -+#include "winbase.h" -+#include "winreg.h" -+#include "wingdi.h" -+#include "winuser.h" -+#include "wine/debug.h" -+#include "wine/unicode.h" -+ -+#include "wndproc.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(d3dadapter); -+ -+struct nine_wndproc -+{ -+ HWND window; -+ BOOL unicode; -+ WNDPROC proc; -+ struct DRI3Present *present; -+}; -+ -+struct nine_wndproc_table -+{ -+ struct nine_wndproc *entries; -+ unsigned int count; -+ unsigned int size; -+}; -+ -+static struct nine_wndproc_table wndproc_table; -+ -+static CRITICAL_SECTION nine_wndproc_cs; -+static CRITICAL_SECTION_DEBUG nine_wndproc_cs_debug = -+{ -+ 0, 0, &nine_wndproc_cs, -+ {&nine_wndproc_cs_debug.ProcessLocksList, -+ &nine_wndproc_cs_debug.ProcessLocksList}, -+ 0, 0, {(DWORD_PTR)(__FILE__ ": nine_wndproc_cs")} -+}; -+static CRITICAL_SECTION nine_wndproc_cs = {&nine_wndproc_cs_debug, -1, 0, 0, 0, 0}; -+ -+BOOL nine_dll_init(HINSTANCE hInstDLL) -+{ -+ WNDCLASSA wc; -+ -+ /* We need our own window class for a fake window which we use to retrieve GL capabilities */ -+ /* We might need CS_OWNDC in the future if we notice strange things on Windows. -+ * Various articles/posts about OpenGL problems on Windows recommend this. */ -+ wc.style = CS_HREDRAW | CS_VREDRAW; -+ wc.lpfnWndProc = DefWindowProcA; -+ wc.cbClsExtra = 0; -+ wc.cbWndExtra = 0; -+ wc.hInstance = hInstDLL; -+ wc.hIcon = LoadIconA(NULL, (const char *)IDI_WINLOGO); -+ wc.hCursor = LoadCursorA(NULL, (const char *)IDC_ARROW); -+ wc.hbrBackground = NULL; -+ wc.lpszMenuName = NULL; -+ wc.lpszClassName = NINE_WINDOW_CLASS_NAME; -+ -+ if (!RegisterClassA(&wc)) -+ { -+ ERR("Failed to register window class '%s'!\n", NINE_WINDOW_CLASS_NAME); -+ return FALSE; -+ } -+ -+ DisableThreadLibraryCalls(hInstDLL); -+ -+ return TRUE; -+} -+ -+BOOL nine_dll_destroy(HINSTANCE hInstDLL) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < wndproc_table.count; ++i) -+ { -+ /* Trying to unregister these would be futile. These entries can only -+ * exist if either we skipped them in nine_unregister_window() due -+ * to the application replacing the wndproc after the entry was -+ * registered, or if the application still has an active nine -+ * device. In the latter case the application has bigger problems than -+ * these entries. */ -+ WARN("Leftover wndproc table entry %p.\n", &wndproc_table.entries[i]); -+ } -+ HeapFree(GetProcessHeap(), 0, wndproc_table.entries); -+ -+ UnregisterClassA(NINE_WINDOW_CLASS_NAME, hInstDLL); -+ -+ DeleteCriticalSection(&nine_wndproc_cs); -+ return TRUE; -+} -+ -+static void nine_wndproc_mutex_lock(void) -+{ -+ EnterCriticalSection(&nine_wndproc_cs); -+} -+ -+static void nine_wndproc_mutex_unlock(void) -+{ -+ LeaveCriticalSection(&nine_wndproc_cs); -+} -+ -+static struct nine_wndproc *nine_find_wndproc(HWND window) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < wndproc_table.count; ++i) -+ { -+ if (wndproc_table.entries[i].window == window) -+ { -+ return &wndproc_table.entries[i]; -+ } -+ } -+ -+ return NULL; -+} -+ -+static LRESULT CALLBACK nine_wndproc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) -+{ -+ struct nine_wndproc *entry; -+ struct DRI3Present *present; -+ BOOL unicode; -+ WNDPROC proc; -+ -+ nine_wndproc_mutex_lock(); -+ entry = nine_find_wndproc(window); -+ -+ if (!entry) -+ { -+ nine_wndproc_mutex_unlock(); -+ ERR("Window %p is not registered with nine.\n", window); -+ return DefWindowProcW(window, message, wparam, lparam); -+ } -+ -+ present = entry->present; -+ unicode = entry->unicode; -+ proc = entry->proc; -+ nine_wndproc_mutex_unlock(); -+ -+ if (present) -+ return device_process_message(present, window, unicode, message, wparam, lparam, proc); -+ if (unicode) -+ return CallWindowProcW(proc, window, message, wparam, lparam); -+ return CallWindowProcA(proc, window, message, wparam, lparam); -+} -+ -+BOOL nine_register_window(HWND window, struct DRI3Present *present) -+{ -+ struct nine_wndproc *entry; -+ -+ nine_wndproc_mutex_lock(); -+ -+ if (nine_find_wndproc(window)) -+ { -+ nine_wndproc_mutex_unlock(); -+ WARN("Window %p is already registered with nine.\n", window); -+ return TRUE; -+ } -+ -+ if (wndproc_table.size == wndproc_table.count) -+ { -+ unsigned int new_size = max(1, wndproc_table.size * 2); -+ struct nine_wndproc *new_entries; -+ -+ if (!wndproc_table.entries) new_entries = HeapAlloc(GetProcessHeap(), 0, new_size * sizeof(*new_entries)); -+ else new_entries = HeapReAlloc(GetProcessHeap(), 0, wndproc_table.entries, new_size * sizeof(*new_entries)); -+ -+ if (!new_entries) -+ { -+ nine_wndproc_mutex_unlock(); -+ ERR("Failed to grow table.\n"); -+ return FALSE; -+ } -+ -+ wndproc_table.entries = new_entries; -+ wndproc_table.size = new_size; -+ } -+ -+ entry = &wndproc_table.entries[wndproc_table.count++]; -+ entry->window = window; -+ entry->unicode = IsWindowUnicode(window); -+ /* Set a window proc that matches the window. Some applications (e.g. NoX) -+ * replace the window proc after we've set ours, and expect to be able to -+ * call the previous one (ours) directly, without using CallWindowProc(). */ -+ if (entry->unicode) -+ entry->proc = (WNDPROC)SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)nine_wndproc); -+ else -+ entry->proc = (WNDPROC)SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)nine_wndproc); -+ entry->present = present; -+ -+ nine_wndproc_mutex_unlock(); -+ -+ return TRUE; -+} -+ -+BOOL nine_unregister_window(HWND window) -+{ -+ struct nine_wndproc *entry, *last; -+ LONG_PTR proc; -+ -+ nine_wndproc_mutex_lock(); -+ -+ if (!(entry = nine_find_wndproc(window))) -+ { -+ nine_wndproc_mutex_unlock(); -+ return FALSE; -+ } -+ -+ if (entry->unicode) -+ { -+ proc = GetWindowLongPtrW(window, GWLP_WNDPROC); -+ if (proc != (LONG_PTR)nine_wndproc) -+ { -+ entry->present = NULL; -+ nine_wndproc_mutex_unlock(); -+ WARN("Not unregistering window %p, window proc %#lx doesn't match nine window proc %p.\n", -+ window, proc, nine_wndproc); -+ return FALSE; -+ } -+ -+ SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)entry->proc); -+ } -+ else -+ { -+ proc = GetWindowLongPtrA(window, GWLP_WNDPROC); -+ if (proc != (LONG_PTR)nine_wndproc) -+ { -+ entry->present = NULL; -+ nine_wndproc_mutex_unlock(); -+ WARN("Not unregistering window %p, window proc %#lx doesn't match nine window proc %p.\n", -+ window, proc, nine_wndproc); -+ return FALSE; -+ } -+ -+ SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)entry->proc); -+ } -+ -+ last = &wndproc_table.entries[--wndproc_table.count]; -+ if (entry != last) *entry = *last; -+ -+ nine_wndproc_mutex_unlock(); -+ return TRUE; -+} -diff --git a/dlls/d3d9-nine/wndproc.h b/dlls/d3d9-nine/wndproc.h -new file mode 100644 -index 0000000000..15f26d491a ---- /dev/null -+++ b/dlls/d3d9-nine/wndproc.h -@@ -0,0 +1,41 @@ -+/* -+ * Direct3D wine internal interface main -+ * -+ * Copyright 2002-2003 The wine-d3d team -+ * Copyright 2002-2003 Raphael Junqueira -+ * Copyright 2004 Jason Edmeades -+ * Copyright 2007-2008 Stefan Dösinger for CodeWeavers -+ * Copyright 2009 Henri Verbeet for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#ifndef __WINE_NINE_WNDPROC_H -+#define __WINE_NINE_WNDPROC_H -+ -+struct DRI3Present; -+ -+BOOL nine_register_window(HWND window, struct DRI3Present *present); -+BOOL nine_unregister_window(HWND window); -+ -+BOOL nine_dll_init(HINSTANCE hInstDLL); -+BOOL nine_dll_destroy(HINSTANCE hInstDLL); -+ -+LRESULT device_process_message(struct DRI3Present *present, HWND window, BOOL unicode, -+ UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc); -+ -+#define NINE_WINDOW_CLASS_NAME "Gallium_Nine_Window" -+ -+#endif --- -2.20.1 - diff --git a/package.yml b/package.yml --- a/package.yml +++ b/package.yml @@ -1,8 +1,8 @@ name : wine -version : 4.1 -release : 58 +version : '4.7' +release : 59 source : - - https://dl.winehq.org/wine/source/4.x/wine-4.1.tar.xz : cef775be05245ebd0f8a5fd50920c6c7d0a6539b781d8185d6c16b8e5ae41bad + - https://dl.winehq.org/wine/source/4.x/wine-4.7.tar.xz : 3bca9084354a60d202f6b8e670b130366126db0583fa27054f1f02294de7bab0 license : LGPL-2.1-or-later component : virt summary : Wine compatibility layer for Windows emulation @@ -19,7 +19,6 @@ - pkgconfig32(gl) - pkgconfig32(glu) - pkgconfig32(gnutls) - - pkgconfig32(gtk+-2.0) - pkgconfig32(gtk+-3.0) - pkgconfig32(ice) - pkgconfig32(lcms2) @@ -40,7 +39,6 @@ - pkgconfig32(libvkd3d) - pkgconfig32(vulkan) - pkgconfig32(x11) - - pkgconfig32(xcb-dri3) - pkgconfig32(xcomposite) - pkgconfig32(xcursor) - pkgconfig32(xext) @@ -51,6 +49,7 @@ - pkgconfig32(xxf86vm) - pkgconfig32(zlib) - cups-32bit-devel + - faudio-32bit-devel - glibc-32bit-devel - libgcc-32bit - libpcap-32bit-devel @@ -78,12 +77,6 @@ - vulkan-32bit - libpng15 setup : | - # D3D9 support - %patch -p1 < $pkgfiles/d3d9-helper.patch - %patch -p1 < $pkgfiles/wine-d3d9.patch - - autoreconf -vfi - # Get 64-bit done first. mkdir wine64 && pushd wine64 ../configure %CONFOPTS% \ diff --git a/pspec_x86_64.xml b/pspec_x86_64.xml --- a/pspec_x86_64.xml +++ b/pspec_x86_64.xml @@ -2,8 +2,8 @@ wine - Bryan T. Meyers - bmeyers@datadrake.com + Pierre-Yves + pyu@riseup.net LGPL-2.1-or-later virt @@ -20,6 +20,7 @@ virt /usr/bin/function_grep.pl + /usr/bin/msidb /usr/bin/msiexec /usr/bin/notepad /usr/bin/regedit @@ -55,6 +56,7 @@ /usr/lib64/wine/adsldpc.dll.so /usr/lib64/wine/advapi32.dll.so /usr/lib64/wine/advpack.dll.so + /usr/lib64/wine/amsi.dll.so /usr/lib64/wine/amstream.dll.so /usr/lib64/wine/api-ms-win-appmodel-identity-l1-1-0.dll.so /usr/lib64/wine/api-ms-win-appmodel-runtime-l1-1-1.dll.so @@ -280,6 +282,7 @@ /usr/lib64/wine/atl110.dll.so /usr/lib64/wine/atl80.dll.so /usr/lib64/wine/atl90.dll.so + /usr/lib64/wine/atlthunk.dll.so /usr/lib64/wine/atmlib.dll.so /usr/lib64/wine/attrib.exe.so /usr/lib64/wine/authz.dll.so @@ -328,7 +331,6 @@ /usr/lib64/wine/d3d11.dll.so /usr/lib64/wine/d3d12.dll.so /usr/lib64/wine/d3d8.dll.so - /usr/lib64/wine/d3d9-nine.dll.so /usr/lib64/wine/d3d9.dll.so /usr/lib64/wine/d3dcompiler_33.dll.so /usr/lib64/wine/d3dcompiler_34.dll.so @@ -433,17 +435,25 @@ /usr/lib64/wine/ext-ms-win-authz-context-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-domainjoin-netjoin-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-dwmapi-ext-l1-1-0.dll.so + /usr/lib64/wine/ext-ms-win-gdi-dc-create-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-gdi-dc-create-l1-1-1.dll.so /usr/lib64/wine/ext-ms-win-gdi-dc-l1-2-0.dll.so /usr/lib64/wine/ext-ms-win-gdi-devcaps-l1-1-0.dll.so + /usr/lib64/wine/ext-ms-win-gdi-draw-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-gdi-draw-l1-1-1.dll.so + /usr/lib64/wine/ext-ms-win-gdi-font-l1-1-0.dll.so + /usr/lib64/wine/ext-ms-win-gdi-font-l1-1-1.dll.so /usr/lib64/wine/ext-ms-win-gdi-render-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-kernel32-package-current-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-kernel32-package-l1-1-1.dll.so + /usr/lib64/wine/ext-ms-win-ntuser-dialogbox-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-ntuser-draw-l1-1-0.dll.so + /usr/lib64/wine/ext-ms-win-ntuser-gui-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-ntuser-gui-l1-3-0.dll.so /usr/lib64/wine/ext-ms-win-ntuser-keyboard-l1-3-0.dll.so + /usr/lib64/wine/ext-ms-win-ntuser-message-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-ntuser-message-l1-1-1.dll.so + /usr/lib64/wine/ext-ms-win-ntuser-misc-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-ntuser-misc-l1-2-0.dll.so /usr/lib64/wine/ext-ms-win-ntuser-misc-l1-5-1.dll.so /usr/lib64/wine/ext-ms-win-ntuser-mouse-l1-1-0.dll.so @@ -451,8 +461,10 @@ /usr/lib64/wine/ext-ms-win-ntuser-private-l1-3-1.dll.so /usr/lib64/wine/ext-ms-win-ntuser-rectangle-ext-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-ntuser-uicontext-ext-l1-1-0.dll.so + /usr/lib64/wine/ext-ms-win-ntuser-window-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-ntuser-window-l1-1-1.dll.so /usr/lib64/wine/ext-ms-win-ntuser-window-l1-1-4.dll.so + /usr/lib64/wine/ext-ms-win-ntuser-windowclass-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-ntuser-windowclass-l1-1-1.dll.so /usr/lib64/wine/ext-ms-win-oleacc-l1-1-0.dll.so /usr/lib64/wine/ext-ms-win-ras-rasapi32-l1-1-0.dll.so @@ -478,6 +490,7 @@ /usr/lib64/wine/fakedlls/adsldpc.dll /usr/lib64/wine/fakedlls/advapi32.dll /usr/lib64/wine/fakedlls/advpack.dll + /usr/lib64/wine/fakedlls/amsi.dll /usr/lib64/wine/fakedlls/amstream.dll /usr/lib64/wine/fakedlls/api-ms-win-appmodel-identity-l1-1-0.dll /usr/lib64/wine/fakedlls/api-ms-win-appmodel-runtime-l1-1-1.dll @@ -703,6 +716,7 @@ /usr/lib64/wine/fakedlls/atl110.dll /usr/lib64/wine/fakedlls/atl80.dll /usr/lib64/wine/fakedlls/atl90.dll + /usr/lib64/wine/fakedlls/atlthunk.dll /usr/lib64/wine/fakedlls/atmlib.dll /usr/lib64/wine/fakedlls/attrib.exe /usr/lib64/wine/fakedlls/authz.dll @@ -751,7 +765,6 @@ /usr/lib64/wine/fakedlls/d3d11.dll /usr/lib64/wine/fakedlls/d3d12.dll /usr/lib64/wine/fakedlls/d3d8.dll - /usr/lib64/wine/fakedlls/d3d9-nine.dll /usr/lib64/wine/fakedlls/d3d9.dll /usr/lib64/wine/fakedlls/d3dcompiler_33.dll /usr/lib64/wine/fakedlls/d3dcompiler_34.dll @@ -856,17 +869,25 @@ /usr/lib64/wine/fakedlls/ext-ms-win-authz-context-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-domainjoin-netjoin-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-dwmapi-ext-l1-1-0.dll + /usr/lib64/wine/fakedlls/ext-ms-win-gdi-dc-create-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-gdi-dc-create-l1-1-1.dll /usr/lib64/wine/fakedlls/ext-ms-win-gdi-dc-l1-2-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-gdi-devcaps-l1-1-0.dll + /usr/lib64/wine/fakedlls/ext-ms-win-gdi-draw-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-gdi-draw-l1-1-1.dll + /usr/lib64/wine/fakedlls/ext-ms-win-gdi-font-l1-1-0.dll + /usr/lib64/wine/fakedlls/ext-ms-win-gdi-font-l1-1-1.dll /usr/lib64/wine/fakedlls/ext-ms-win-gdi-render-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-kernel32-package-current-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-kernel32-package-l1-1-1.dll + /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-dialogbox-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-draw-l1-1-0.dll + /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-gui-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-gui-l1-3-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-keyboard-l1-3-0.dll + /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-message-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-message-l1-1-1.dll + /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-misc-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-misc-l1-2-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-misc-l1-5-1.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-mouse-l1-1-0.dll @@ -874,8 +895,10 @@ /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-private-l1-3-1.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-rectangle-ext-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-uicontext-ext-l1-1-0.dll + /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-window-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-window-l1-1-1.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-window-l1-1-4.dll + /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-windowclass-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-ntuser-windowclass-l1-1-1.dll /usr/lib64/wine/fakedlls/ext-ms-win-oleacc-l1-1-0.dll /usr/lib64/wine/fakedlls/ext-ms-win-ras-rasapi32-l1-1-0.dll @@ -949,6 +972,7 @@ /usr/lib64/wine/fakedlls/kerberos.dll /usr/lib64/wine/fakedlls/kernel32.dll /usr/lib64/wine/fakedlls/kernelbase.dll + /usr/lib64/wine/fakedlls/ksecdd.sys /usr/lib64/wine/fakedlls/ksuser.dll /usr/lib64/wine/fakedlls/ktmw32.dll /usr/lib64/wine/fakedlls/l3codeca.acm @@ -966,7 +990,9 @@ /usr/lib64/wine/fakedlls/mciwave.dll /usr/lib64/wine/fakedlls/mf.dll /usr/lib64/wine/fakedlls/mf3216.dll + /usr/lib64/wine/fakedlls/mferror.dll /usr/lib64/wine/fakedlls/mfplat.dll + /usr/lib64/wine/fakedlls/mfplay.dll /usr/lib64/wine/fakedlls/mfreadwrite.dll /usr/lib64/wine/fakedlls/mgmtapi.dll /usr/lib64/wine/fakedlls/midimap.dll @@ -998,6 +1024,7 @@ /usr/lib64/wine/fakedlls/mshtml.dll /usr/lib64/wine/fakedlls/mshtml.tlb /usr/lib64/wine/fakedlls/msi.dll + /usr/lib64/wine/fakedlls/msidb.exe /usr/lib64/wine/fakedlls/msident.dll /usr/lib64/wine/fakedlls/msiexec.exe /usr/lib64/wine/fakedlls/msimg32.dll @@ -1189,6 +1216,7 @@ /usr/lib64/wine/fakedlls/twain_32.dll /usr/lib64/wine/fakedlls/tzres.dll /usr/lib64/wine/fakedlls/ucrtbase.dll + /usr/lib64/wine/fakedlls/uianimation.dll /usr/lib64/wine/fakedlls/uiautomationcore.dll /usr/lib64/wine/fakedlls/uiribbon.dll /usr/lib64/wine/fakedlls/unicows.dll @@ -1376,6 +1404,7 @@ /usr/lib64/wine/kerberos.dll.so /usr/lib64/wine/kernel32.dll.so /usr/lib64/wine/kernelbase.dll.so + /usr/lib64/wine/ksecdd.sys.so /usr/lib64/wine/ksuser.dll.so /usr/lib64/wine/ktmw32.dll.so /usr/lib64/wine/l3codeca.acm.so @@ -1387,6 +1416,7 @@ /usr/lib64/wine/libatl.def /usr/lib64/wine/libatl100.def /usr/lib64/wine/libatl80.def + /usr/lib64/wine/libatlthunk.def /usr/lib64/wine/libavicap32.def /usr/lib64/wine/libavifil32.def /usr/lib64/wine/libavrt.def @@ -1478,7 +1508,7 @@ /usr/lib64/wine/libmsvcr71.def /usr/lib64/wine/libmsvcr80.def /usr/lib64/wine/libmsvcr90.def - /usr/lib64/wine/libmsvcrt.def + /usr/lib64/wine/libmsvcrt.a /usr/lib64/wine/libmsvcrtd.def /usr/lib64/wine/libmsvfw32.def /usr/lib64/wine/libmswsock.def @@ -1505,6 +1535,7 @@ /usr/lib64/wine/libpropsys.def /usr/lib64/wine/libpsapi.def /usr/lib64/wine/libquartz.def + /usr/lib64/wine/libqwave.def /usr/lib64/wine/librasapi32.def /usr/lib64/wine/librasdlg.def /usr/lib64/wine/libresutils.def @@ -1531,6 +1562,7 @@ /usr/lib64/wine/libt2embed.def /usr/lib64/wine/libtapi32.def /usr/lib64/wine/libucrtbase.def + /usr/lib64/wine/libuiautomationcore.def /usr/lib64/wine/libunicows.def /usr/lib64/wine/liburl.def /usr/lib64/wine/liburlmon.def @@ -1584,7 +1616,9 @@ /usr/lib64/wine/mciwave.dll.so /usr/lib64/wine/mf.dll.so /usr/lib64/wine/mf3216.dll.so + /usr/lib64/wine/mferror.dll.so /usr/lib64/wine/mfplat.dll.so + /usr/lib64/wine/mfplay.dll.so /usr/lib64/wine/mfreadwrite.dll.so /usr/lib64/wine/mgmtapi.dll.so /usr/lib64/wine/midimap.dll.so @@ -1616,6 +1650,7 @@ /usr/lib64/wine/mshtml.dll.so /usr/lib64/wine/mshtml.tlb.so /usr/lib64/wine/msi.dll.so + /usr/lib64/wine/msidb.exe.so /usr/lib64/wine/msident.dll.so /usr/lib64/wine/msiexec.exe.so /usr/lib64/wine/msimg32.dll.so @@ -1807,6 +1842,7 @@ /usr/lib64/wine/twain_32.dll.so /usr/lib64/wine/tzres.dll.so /usr/lib64/wine/ucrtbase.dll.so + /usr/lib64/wine/uianimation.dll.so /usr/lib64/wine/uiautomationcore.dll.so /usr/lib64/wine/uiribbon.dll.so /usr/lib64/wine/unicows.dll.so @@ -2035,7 +2071,7 @@ emul32 - wine + wine /usr/bin/wine @@ -2049,6 +2085,7 @@ /usr/lib32/wine/adsldpc.dll.so /usr/lib32/wine/advapi32.dll.so /usr/lib32/wine/advpack.dll.so + /usr/lib32/wine/amsi.dll.so /usr/lib32/wine/amstream.dll.so /usr/lib32/wine/api-ms-win-appmodel-identity-l1-1-0.dll.so /usr/lib32/wine/api-ms-win-appmodel-runtime-l1-1-1.dll.so @@ -2274,6 +2311,7 @@ /usr/lib32/wine/atl110.dll.so /usr/lib32/wine/atl80.dll.so /usr/lib32/wine/atl90.dll.so + /usr/lib32/wine/atlthunk.dll.so /usr/lib32/wine/atmlib.dll.so /usr/lib32/wine/attrib.exe.so /usr/lib32/wine/authz.dll.so @@ -2328,7 +2366,6 @@ /usr/lib32/wine/d3d11.dll.so /usr/lib32/wine/d3d12.dll.so /usr/lib32/wine/d3d8.dll.so - /usr/lib32/wine/d3d9-nine.dll.so /usr/lib32/wine/d3d9.dll.so /usr/lib32/wine/d3dcompiler_33.dll.so /usr/lib32/wine/d3dcompiler_34.dll.so @@ -2436,17 +2473,25 @@ /usr/lib32/wine/ext-ms-win-authz-context-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-domainjoin-netjoin-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-dwmapi-ext-l1-1-0.dll.so + /usr/lib32/wine/ext-ms-win-gdi-dc-create-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-gdi-dc-create-l1-1-1.dll.so /usr/lib32/wine/ext-ms-win-gdi-dc-l1-2-0.dll.so /usr/lib32/wine/ext-ms-win-gdi-devcaps-l1-1-0.dll.so + /usr/lib32/wine/ext-ms-win-gdi-draw-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-gdi-draw-l1-1-1.dll.so + /usr/lib32/wine/ext-ms-win-gdi-font-l1-1-0.dll.so + /usr/lib32/wine/ext-ms-win-gdi-font-l1-1-1.dll.so /usr/lib32/wine/ext-ms-win-gdi-render-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-kernel32-package-current-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-kernel32-package-l1-1-1.dll.so + /usr/lib32/wine/ext-ms-win-ntuser-dialogbox-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-ntuser-draw-l1-1-0.dll.so + /usr/lib32/wine/ext-ms-win-ntuser-gui-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-ntuser-gui-l1-3-0.dll.so /usr/lib32/wine/ext-ms-win-ntuser-keyboard-l1-3-0.dll.so + /usr/lib32/wine/ext-ms-win-ntuser-message-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-ntuser-message-l1-1-1.dll.so + /usr/lib32/wine/ext-ms-win-ntuser-misc-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-ntuser-misc-l1-2-0.dll.so /usr/lib32/wine/ext-ms-win-ntuser-misc-l1-5-1.dll.so /usr/lib32/wine/ext-ms-win-ntuser-mouse-l1-1-0.dll.so @@ -2454,8 +2499,10 @@ /usr/lib32/wine/ext-ms-win-ntuser-private-l1-3-1.dll.so /usr/lib32/wine/ext-ms-win-ntuser-rectangle-ext-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-ntuser-uicontext-ext-l1-1-0.dll.so + /usr/lib32/wine/ext-ms-win-ntuser-window-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-ntuser-window-l1-1-1.dll.so /usr/lib32/wine/ext-ms-win-ntuser-window-l1-1-4.dll.so + /usr/lib32/wine/ext-ms-win-ntuser-windowclass-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-ntuser-windowclass-l1-1-1.dll.so /usr/lib32/wine/ext-ms-win-oleacc-l1-1-0.dll.so /usr/lib32/wine/ext-ms-win-ras-rasapi32-l1-1-0.dll.so @@ -2481,6 +2528,7 @@ /usr/lib32/wine/fakedlls/adsldpc.dll /usr/lib32/wine/fakedlls/advapi32.dll /usr/lib32/wine/fakedlls/advpack.dll + /usr/lib32/wine/fakedlls/amsi.dll /usr/lib32/wine/fakedlls/amstream.dll /usr/lib32/wine/fakedlls/api-ms-win-appmodel-identity-l1-1-0.dll /usr/lib32/wine/fakedlls/api-ms-win-appmodel-runtime-l1-1-1.dll @@ -2706,6 +2754,7 @@ /usr/lib32/wine/fakedlls/atl110.dll /usr/lib32/wine/fakedlls/atl80.dll /usr/lib32/wine/fakedlls/atl90.dll + /usr/lib32/wine/fakedlls/atlthunk.dll /usr/lib32/wine/fakedlls/atmlib.dll /usr/lib32/wine/fakedlls/attrib.exe /usr/lib32/wine/fakedlls/authz.dll @@ -2760,7 +2809,6 @@ /usr/lib32/wine/fakedlls/d3d11.dll /usr/lib32/wine/fakedlls/d3d12.dll /usr/lib32/wine/fakedlls/d3d8.dll - /usr/lib32/wine/fakedlls/d3d9-nine.dll /usr/lib32/wine/fakedlls/d3d9.dll /usr/lib32/wine/fakedlls/d3dcompiler_33.dll /usr/lib32/wine/fakedlls/d3dcompiler_34.dll @@ -2868,17 +2916,25 @@ /usr/lib32/wine/fakedlls/ext-ms-win-authz-context-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-domainjoin-netjoin-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-dwmapi-ext-l1-1-0.dll + /usr/lib32/wine/fakedlls/ext-ms-win-gdi-dc-create-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-gdi-dc-create-l1-1-1.dll /usr/lib32/wine/fakedlls/ext-ms-win-gdi-dc-l1-2-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-gdi-devcaps-l1-1-0.dll + /usr/lib32/wine/fakedlls/ext-ms-win-gdi-draw-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-gdi-draw-l1-1-1.dll + /usr/lib32/wine/fakedlls/ext-ms-win-gdi-font-l1-1-0.dll + /usr/lib32/wine/fakedlls/ext-ms-win-gdi-font-l1-1-1.dll /usr/lib32/wine/fakedlls/ext-ms-win-gdi-render-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-kernel32-package-current-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-kernel32-package-l1-1-1.dll + /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-dialogbox-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-draw-l1-1-0.dll + /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-gui-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-gui-l1-3-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-keyboard-l1-3-0.dll + /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-message-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-message-l1-1-1.dll + /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-misc-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-misc-l1-2-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-misc-l1-5-1.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-mouse-l1-1-0.dll @@ -2886,8 +2942,10 @@ /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-private-l1-3-1.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-rectangle-ext-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-uicontext-ext-l1-1-0.dll + /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-window-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-window-l1-1-1.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-window-l1-1-4.dll + /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-windowclass-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-ntuser-windowclass-l1-1-1.dll /usr/lib32/wine/fakedlls/ext-ms-win-oleacc-l1-1-0.dll /usr/lib32/wine/fakedlls/ext-ms-win-ras-rasapi32-l1-1-0.dll @@ -2966,6 +3024,7 @@ /usr/lib32/wine/fakedlls/kernelbase.dll /usr/lib32/wine/fakedlls/keyboard.drv16 /usr/lib32/wine/fakedlls/krnl386.exe16 + /usr/lib32/wine/fakedlls/ksecdd.sys /usr/lib32/wine/fakedlls/ksuser.dll /usr/lib32/wine/fakedlls/ktmw32.dll /usr/lib32/wine/fakedlls/l3codeca.acm @@ -2984,7 +3043,9 @@ /usr/lib32/wine/fakedlls/mciwave.dll /usr/lib32/wine/fakedlls/mf.dll /usr/lib32/wine/fakedlls/mf3216.dll + /usr/lib32/wine/fakedlls/mferror.dll /usr/lib32/wine/fakedlls/mfplat.dll + /usr/lib32/wine/fakedlls/mfplay.dll /usr/lib32/wine/fakedlls/mfreadwrite.dll /usr/lib32/wine/fakedlls/mgmtapi.dll /usr/lib32/wine/fakedlls/midimap.dll @@ -3021,6 +3082,7 @@ /usr/lib32/wine/fakedlls/mshtml.dll /usr/lib32/wine/fakedlls/mshtml.tlb /usr/lib32/wine/fakedlls/msi.dll + /usr/lib32/wine/fakedlls/msidb.exe /usr/lib32/wine/fakedlls/msident.dll /usr/lib32/wine/fakedlls/msiexec.exe /usr/lib32/wine/fakedlls/msimg32.dll @@ -3232,6 +3294,7 @@ /usr/lib32/wine/fakedlls/typelib.dll16 /usr/lib32/wine/fakedlls/tzres.dll /usr/lib32/wine/fakedlls/ucrtbase.dll + /usr/lib32/wine/fakedlls/uianimation.dll /usr/lib32/wine/fakedlls/uiautomationcore.dll /usr/lib32/wine/fakedlls/uiribbon.dll /usr/lib32/wine/fakedlls/unicows.dll @@ -3447,6 +3510,7 @@ /usr/lib32/wine/kernelbase.dll.so /usr/lib32/wine/keyboard.drv16.so /usr/lib32/wine/krnl386.exe16.so + /usr/lib32/wine/ksecdd.sys.so /usr/lib32/wine/ksuser.dll.so /usr/lib32/wine/ktmw32.dll.so /usr/lib32/wine/l3codeca.acm.so @@ -3458,6 +3522,7 @@ /usr/lib32/wine/libatl.def /usr/lib32/wine/libatl100.def /usr/lib32/wine/libatl80.def + /usr/lib32/wine/libatlthunk.def /usr/lib32/wine/libavicap32.def /usr/lib32/wine/libavifil32.def /usr/lib32/wine/libavrt.def @@ -3550,7 +3615,7 @@ /usr/lib32/wine/libmsvcr71.def /usr/lib32/wine/libmsvcr80.def /usr/lib32/wine/libmsvcr90.def - /usr/lib32/wine/libmsvcrt.def + /usr/lib32/wine/libmsvcrt.a /usr/lib32/wine/libmsvcrtd.def /usr/lib32/wine/libmsvfw32.def /usr/lib32/wine/libmswsock.def @@ -3577,6 +3642,7 @@ /usr/lib32/wine/libpropsys.def /usr/lib32/wine/libpsapi.def /usr/lib32/wine/libquartz.def + /usr/lib32/wine/libqwave.def /usr/lib32/wine/librasapi32.def /usr/lib32/wine/librasdlg.def /usr/lib32/wine/libresutils.def @@ -3603,6 +3669,7 @@ /usr/lib32/wine/libt2embed.def /usr/lib32/wine/libtapi32.def /usr/lib32/wine/libucrtbase.def + /usr/lib32/wine/libuiautomationcore.def /usr/lib32/wine/libunicows.def /usr/lib32/wine/liburl.def /usr/lib32/wine/liburlmon.def @@ -3658,7 +3725,9 @@ /usr/lib32/wine/mciwave.dll.so /usr/lib32/wine/mf.dll.so /usr/lib32/wine/mf3216.dll.so + /usr/lib32/wine/mferror.dll.so /usr/lib32/wine/mfplat.dll.so + /usr/lib32/wine/mfplay.dll.so /usr/lib32/wine/mfreadwrite.dll.so /usr/lib32/wine/mgmtapi.dll.so /usr/lib32/wine/midimap.dll.so @@ -3695,6 +3764,7 @@ /usr/lib32/wine/mshtml.dll.so /usr/lib32/wine/mshtml.tlb.so /usr/lib32/wine/msi.dll.so + /usr/lib32/wine/msidb.exe.so /usr/lib32/wine/msident.dll.so /usr/lib32/wine/msiexec.exe.so /usr/lib32/wine/msimg32.dll.so @@ -3906,6 +3976,7 @@ /usr/lib32/wine/typelib.dll16.so /usr/lib32/wine/tzres.dll.so /usr/lib32/wine/ucrtbase.dll.so + /usr/lib32/wine/uianimation.dll.so /usr/lib32/wine/uiautomationcore.dll.so /usr/lib32/wine/uiribbon.dll.so /usr/lib32/wine/unicows.dll.so @@ -4070,8 +4141,8 @@ programming.devel - wine-32bit - wine-devel + wine-32bit + wine-devel /usr/lib32/libwine.so @@ -4084,7 +4155,7 @@ programming.devel - wine + wine /usr/include/wine/debug.h @@ -4119,6 +4190,7 @@ /usr/include/wine/msvcrt/share.h /usr/include/wine/msvcrt/signal.h /usr/include/wine/msvcrt/stddef.h + /usr/include/wine/msvcrt/stdint.h /usr/include/wine/msvcrt/stdio.h /usr/include/wine/msvcrt/stdlib.h /usr/include/wine/msvcrt/string.h @@ -4134,7 +4206,6 @@ /usr/include/wine/msvcrt/wctype.h /usr/include/wine/svcctl.h /usr/include/wine/svcctl.idl - /usr/include/wine/unicode.h /usr/include/wine/windows/accctrl.h /usr/include/wine/windows/access.idl /usr/include/wine/windows/aclapi.h @@ -4151,6 +4222,8 @@ /usr/include/wine/windows/advpub.h /usr/include/wine/windows/af_irda.h /usr/include/wine/windows/amaudio.h + /usr/include/wine/windows/amsi.h + /usr/include/wine/windows/amsi.idl /usr/include/wine/windows/amstream.h /usr/include/wine/windows/amstream.idl /usr/include/wine/windows/amvideo.h @@ -4166,6 +4239,7 @@ /usr/include/wine/windows/atlcom.h /usr/include/wine/windows/atliface.h /usr/include/wine/windows/atliface.idl + /usr/include/wine/windows/atlthunk.h /usr/include/wine/windows/atlwin.h /usr/include/wine/windows/audevcod.h /usr/include/wine/windows/audioclient.h @@ -4320,6 +4394,7 @@ /usr/include/wine/windows/dbccmd.idl /usr/include/wine/windows/dbcses.idl /usr/include/wine/windows/dbdsad.idl + /usr/include/wine/windows/dbgeng.h /usr/include/wine/windows/dbghelp.h /usr/include/wine/windows/dbinit.idl /usr/include/wine/windows/dbprop.idl @@ -4595,6 +4670,8 @@ /usr/include/wine/windows/mfidl.idl /usr/include/wine/windows/mfobjects.h /usr/include/wine/windows/mfobjects.idl + /usr/include/wine/windows/mfplay.h + /usr/include/wine/windows/mfplay.idl /usr/include/wine/windows/mfreadwrite.h /usr/include/wine/windows/mfreadwrite.idl /usr/include/wine/windows/mftransform.h @@ -4904,11 +4981,14 @@ /usr/include/wine/windows/vmr9.h /usr/include/wine/windows/vmr9.idl /usr/include/wine/windows/vmrender.idl + /usr/include/wine/windows/vsbackup.h + /usr/include/wine/windows/vsbackup.idl /usr/include/wine/windows/vss.h /usr/include/wine/windows/vss.idl /usr/include/wine/windows/vsstyle.h /usr/include/wine/windows/vssym32.h /usr/include/wine/windows/vswriter.h + /usr/include/wine/windows/vswriter.idl /usr/include/wine/windows/wbemcli.h /usr/include/wine/windows/wbemcli.idl /usr/include/wine/windows/wbemdisp.h @@ -5039,12 +5119,12 @@ - - 2019-03-31 - 4.1 + + 2019-05-03 + 4.7 Packaging update - Bryan T. Meyers - bmeyers@datadrake.com + Pierre-Yves + pyu@riseup.net \ No newline at end of file