From 45419c07c25bd787adeb777f2b7914c79cdc59d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Duarte?= Date: Fri, 22 Dec 2023 10:12:02 +0000 Subject: [PATCH] add wine-staging-9.0-rc2 with dlssg-fsr3 mod patches https://github.com/ValveSoftware/Proton/issues/7361 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gonçalo Duarte --- app-emulation/wine-staging/Manifest | 4 + .../files/wine-staging-7.17-noexecstack.patch | 7 + .../files/wine-staging-7.20-unwind.patch | 36 ++ .../files/wine-staging-8.13-rpath.patch | 15 + .../wine-staging-9.0-gpu_detection.patch | 227 ++++++++ .../files/wine-staging-9.0-hags-0001.patch | 543 ++++++++++++++++++ .../files/wine-staging-9.0-hags-0002.patch | 89 +++ app-emulation/wine-staging/metadata.xml | 41 ++ .../wine-staging/wine-staging-8.21.ebuild | 460 +++++++++++++++ .../wine-staging/wine-staging-9.0-r2.ebuild | 460 +++++++++++++++ .../wine-staging/wine-staging-9999.ebuild | 454 +++++++++++++++ 11 files changed, 2336 insertions(+) create mode 100644 app-emulation/wine-staging/Manifest create mode 100644 app-emulation/wine-staging/files/wine-staging-7.17-noexecstack.patch create mode 100644 app-emulation/wine-staging/files/wine-staging-7.20-unwind.patch create mode 100644 app-emulation/wine-staging/files/wine-staging-8.13-rpath.patch create mode 100644 app-emulation/wine-staging/files/wine-staging-9.0-gpu_detection.patch create mode 100644 app-emulation/wine-staging/files/wine-staging-9.0-hags-0001.patch create mode 100644 app-emulation/wine-staging/files/wine-staging-9.0-hags-0002.patch create mode 100644 app-emulation/wine-staging/metadata.xml create mode 100644 app-emulation/wine-staging/wine-staging-8.21.ebuild create mode 100644 app-emulation/wine-staging/wine-staging-9.0-r2.ebuild create mode 100644 app-emulation/wine-staging/wine-staging-9999.ebuild diff --git a/app-emulation/wine-staging/Manifest b/app-emulation/wine-staging/Manifest new file mode 100644 index 0000000..187f2b5 --- /dev/null +++ b/app-emulation/wine-staging/Manifest @@ -0,0 +1,4 @@ +DIST wine-8.21.tar.xz 29919212 BLAKE2B 2e1c135d1c247f4b268c0323538748944b01fe65c82dee27d81f70613aa2fe632c1b4d696f05838a6ab801579a4d13a191de0f4c1a2e2222d40ca767499a98c3 SHA512 4d04d40141d2ea5e548b76aed870ac28d8a03241ffd4e761979c795310baa19136e54a8e518c6ea9bf563c3b23d3c4eb1baefc9906d7eeca469e9942ff99dc40 +DIST wine-9.0-rc2.tar.xz 29989604 BLAKE2B 2eddc96df30a8239b4b3314b7127eb3a11f953826506f12b8f5dc2acfe45f8a4fc3de7a4af4ada5c14c60783771ba865eb35189dcdb09eeb7e52438dd34fe668 SHA512 20644b626c3e5eb5864ea5beb91f4470f19bf7a51dbd706efcce86ca552cab5e6754dc5705ec24255e0fd75bd5ea185cd2f63a47cd255a54796b4514ccfc4ad9 +DIST wine-staging-8.21.tar.gz 9669500 BLAKE2B 600ad4b5696a38adefbde2fb9f51623dc7a7d9249ba15ceddcf1062040d840064285c6d2602266fd90f3658f0bdfe2fbca6a486f40e6e3f317fe704553ce39c7 SHA512 abba6084f2aefa8507c2a79c688b717f8137375168e5457ee40a0c96bfce31e9dc44370ecb5a8e8a397e90ce2eb8543fd07b447bf48c4b2d4c68aac9b3674214 +DIST wine-staging-9.0-rc2.tar.gz 9536907 BLAKE2B ba63735fa9f0081b0b2cb854f6ef90a4dab596f1900022a3d23449ae823d4fc40e1dd53099f7c7dc186a3141ad27a1a68cd36b8a94ec632372876f076fb4375b SHA512 b2cacb51bc8d68c5b37b2969b22dae7e8f5e6d1cb2c363924d11a04f650068dde5d2af2098ac84bc3bbdcffafa3127f1e4a4042e6f663253b7fde4e27ed9f252 diff --git a/app-emulation/wine-staging/files/wine-staging-7.17-noexecstack.patch b/app-emulation/wine-staging/files/wine-staging-7.17-noexecstack.patch new file mode 100644 index 0000000..4baa48c --- /dev/null +++ b/app-emulation/wine-staging/files/wine-staging-7.17-noexecstack.patch @@ -0,0 +1,7 @@ +Also write GNU-stack note on dummy files used for stub libraries. +--- a/tools/winebuild/import.c ++++ b/tools/winebuild/import.c +@@ -1676,2 +1676,3 @@ + output( "\t.text\n" ); ++ output_gnu_stack_note(); + } diff --git a/app-emulation/wine-staging/files/wine-staging-7.20-unwind.patch b/app-emulation/wine-staging/files/wine-staging-7.20-unwind.patch new file mode 100644 index 0000000..f130ef5 --- /dev/null +++ b/app-emulation/wine-staging/files/wine-staging-7.20-unwind.patch @@ -0,0 +1,36 @@ +Fix build with llvm-libunwind, and also fix for non-llvm libunwind +when using clang+bfd given clang doesn't have _Unwind_Find_FDE in +its rtlib and expects it from llvm-libunwind. + +The _CONFIG_H_ check is for Rip - 1), &bases ); + +@@ -760,4 +761,5 @@ + return dwarf_virtual_unwind( context->Rip, &dispatch->EstablisherFrame, context, fde, + &bases, &dispatch->LanguageHandler, &dispatch->HandlerData ); ++#endif + #ifdef HAVE_LIBUNWIND + return libunwind_virtual_unwind( context->Rip, &dispatch->EstablisherFrame, context, diff --git a/app-emulation/wine-staging/files/wine-staging-8.13-rpath.patch b/app-emulation/wine-staging/files/wine-staging-8.13-rpath.patch new file mode 100644 index 0000000..5f0d63b --- /dev/null +++ b/app-emulation/wine-staging/files/wine-staging-8.13-rpath.patch @@ -0,0 +1,15 @@ +Patch Source: https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/community/wine/rpath.patch +Alpine Bug: https://gitlab.alpinelinux.org/alpine/aports/-/issues/13249 + +--- a/configure.ac ++++ b/configure.ac +@@ -784,6 +784,9 @@ case $host_os in + [WINELOADER_LDFLAGS="$WINELOADER_LDFLAGS -Wl,-z,max-page-size=0x1000"]) + ;; + esac ++ ++ # do this at the end because it needs double dollar for makefile ++ WINE_TRY_CFLAGS([-Wl,-rpath,\\\$ORIGIN],[UNIXLDFLAGS="$UNIXLDFLAGS '-Wl,-rpath,\$\$ORIGIN'"]) + ;; + esac + diff --git a/app-emulation/wine-staging/files/wine-staging-9.0-gpu_detection.patch b/app-emulation/wine-staging/files/wine-staging-9.0-gpu_detection.patch new file mode 100644 index 0000000..1f6282b --- /dev/null +++ b/app-emulation/wine-staging/files/wine-staging-9.0-gpu_detection.patch @@ -0,0 +1,227 @@ +diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c +index c5e47cb355c..8bc83755746 100644 +--- a/dlls/winex11.drv/xrandr.c ++++ b/dlls/winex11.drv/xrandr.c +@@ -367,7 +367,6 @@ static BOOL is_broken_driver(void) + XRRScreenResources *screen_resources; + XRROutputInfo *output_info; + XRRModeInfo *first_mode; +- INT major, event, error; + INT output_idx, i, j; + BOOL only_one_mode; + +@@ -418,15 +417,6 @@ static BOOL is_broken_driver(void) + + if (!only_one_mode) + continue; +- +- /* Check if it is NVIDIA proprietary driver */ +- if (XQueryExtension( gdi_display, "NV-CONTROL", &major, &event, &error )) +- { +- ERR_(winediag)("Broken NVIDIA RandR detected, falling back to RandR 1.0. " +- "Please consider using the Nouveau driver instead.\n"); +- pXRRFreeScreenResources( screen_resources ); +- return TRUE; +- } + } + pXRRFreeScreenResources( screen_resources ); + return FALSE; +@@ -625,6 +615,113 @@ static BOOL is_crtc_primary( RECT primary, const XRRCrtcInfo *crtc ) + crtc->y + crtc->height == primary.bottom; + } + ++static void add_remaining_gpus_via_vulkan( struct gdi_gpu **gpus, int *count ) ++{ ++ static const char *extensions[] = ++ { ++ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, ++ }; ++ const struct vulkan_funcs *vulkan_funcs = get_vulkan_driver( WINE_VULKAN_DRIVER_VERSION ); ++ PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; ++ PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; ++ uint32_t device_count; ++ VkPhysicalDevice *vk_physical_devices = NULL; ++ VkPhysicalDeviceProperties2 properties2; ++ VkInstanceCreateInfo create_info; ++ VkPhysicalDeviceIDProperties id; ++ VkInstance vk_instance = NULL; ++ INT gpu_idx, device_idx; ++ INT original_gpu_count = *count; ++ struct gdi_gpu *new_gpu; ++ BOOL new; ++ VkResult vr; ++ ++ memset( &create_info, 0, sizeof(create_info) ); ++ create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; ++ create_info.enabledExtensionCount = ARRAY_SIZE(extensions); ++ create_info.ppEnabledExtensionNames = extensions; ++ vr = vulkan_funcs->p_vkCreateInstance( &create_info, NULL, &vk_instance ); ++ ++ if (vr != VK_SUCCESS) ++ { ++ WARN("Failed to create a Vulkan instance, vr %d.\n", vr); ++ goto done; ++ } ++ ++#define LOAD_VK_FUNC(f) \ ++ if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr( vk_instance, #f ))) \ ++ { \ ++ WARN("Failed to load " #f ".\n"); \ ++ goto done; \ ++ } ++ ++ LOAD_VK_FUNC(vkEnumeratePhysicalDevices) ++ LOAD_VK_FUNC(vkGetPhysicalDeviceProperties2KHR) ++#undef LOAD_VK_FUNC ++ ++ vr = pvkEnumeratePhysicalDevices( vk_instance, &device_count, NULL ); ++ if (vr != VK_SUCCESS || !device_count) ++ { ++ WARN("No Vulkan device found, vr %d, device_count %d.\n", vr, device_count); ++ goto done; ++ } ++ ++ if (!(vk_physical_devices = calloc( device_count, sizeof(*vk_physical_devices) ))) ++ goto done; ++ ++ vr = pvkEnumeratePhysicalDevices( vk_instance, &device_count, vk_physical_devices ); ++ if (vr != VK_SUCCESS) ++ { ++ WARN("vkEnumeratePhysicalDevices failed, vr %d.\n", vr); ++ goto done; ++ } ++ ++ for (device_idx = 0; device_idx < device_count; ++device_idx) ++ { ++ memset( &id, 0, sizeof(id) ); ++ id.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; ++ properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; ++ properties2.pNext = &id; ++ ++ pvkGetPhysicalDeviceProperties2KHR( vk_physical_devices[device_idx], &properties2 ); ++ ++ /* Ignore Khronos vendor IDs */ ++ if (properties2.properties.vendorID >= 0x10000) ++ continue; ++ ++ new = TRUE; ++ for (gpu_idx = 0; gpu_idx < original_gpu_count; ++gpu_idx) ++ { ++ if (!memcmp( &(*gpus)[gpu_idx].vulkan_uuid, id.deviceUUID, sizeof(id.deviceUUID) )) ++ { ++ new = FALSE; ++ break; ++ } ++ } ++ ++ if (!new) ++ continue; ++ ++ *gpus = realloc( *gpus, (*count + 1) * sizeof(**gpus) ); ++ if (!gpus) goto done; ++ new_gpu = &(*gpus)[(*count)++]; ++ memset( new_gpu, 0, sizeof(*new_gpu) ); ++ new_gpu->id = -1; ++ ++ memcpy( &new_gpu->vulkan_uuid, id.deviceUUID, sizeof(id.deviceUUID) ); ++ new_gpu->vendor_id = properties2.properties.vendorID; ++ new_gpu->device_id = properties2.properties.deviceID; ++ ntdll_umbstowcs( properties2.properties.deviceName, -1, new_gpu->name, ARRAY_SIZE(new_gpu->name) ); ++ ++ TRACE("Added a new GPU via Vulkan: %04x:%04x %s\n", new_gpu->vendor_id, new_gpu->device_id, debugstr_w(new_gpu->name)); ++ } ++ ++done: ++ free( vk_physical_devices ); ++ if (vk_instance) ++ vulkan_funcs->p_vkDestroyInstance( vk_instance, NULL ); ++} ++ + VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR) + + static BOOL get_gpu_properties_from_vulkan( struct gdi_gpu *gpu, const XRRProviderInfo *provider_info, +@@ -772,6 +869,7 @@ static BOOL xrandr14_get_gpus( struct gdi_gpu **new_gpus, int *count, BOOL get_p + XRRProviderInfo *provider_info = NULL; + XRRCrtcInfo *crtc_info = NULL; + INT primary_provider = -1; ++ INT gpu_count = 0; + RECT primary_rect; + BOOL ret = FALSE; + DWORD len; +@@ -785,21 +883,16 @@ static BOOL xrandr14_get_gpus( struct gdi_gpu **new_gpus, int *count, BOOL get_p + if (!provider_resources) + goto done; + +- gpus = calloc( provider_resources->nproviders ? provider_resources->nproviders : 1, sizeof(*gpus) ); +- if (!gpus) +- goto done; +- + /* Some XRandR implementations don't support providers. + * In this case, report a fake one to try searching adapters in screen resources */ + if (!provider_resources->nproviders) + { + WARN("XRandR implementation doesn't report any providers, faking one.\n"); +- lstrcpyW( gpus[0].name, wine_adapterW ); +- *new_gpus = gpus; +- *count = 1; +- ret = TRUE; +- goto done; ++ goto fallback; + } ++ ++ gpus = calloc( provider_resources->nproviders, sizeof(*gpus) ); ++ if (!gpus) goto done; + + primary_rect = get_primary_rect( screen_resources ); + for (i = 0; i < provider_resources->nproviders; ++i) +@@ -834,6 +927,7 @@ static BOOL xrandr14_get_gpus( struct gdi_gpu **new_gpus, int *count, BOOL get_p + /* FIXME: Add an alternate method of getting PCI IDs, for systems that don't support Vulkan */ + } + pXRRFreeProviderInfo( provider_info ); ++ gpu_count++; + } + + /* Make primary GPU the first */ +@@ -843,9 +937,30 @@ static BOOL xrandr14_get_gpus( struct gdi_gpu **new_gpus, int *count, BOOL get_p + gpus[0] = gpus[primary_provider]; + gpus[primary_provider] = tmp; + } ++ ++ fallback: ++ /* Add the Vulkan only GPUs only if we need all the detailed properties */ ++ if (get_properties) ++ add_remaining_gpus_via_vulkan( &gpus, &gpu_count ); ++ ++ if (gpu_count == 0) ++ { ++ /* we need at least one for get_adapters() / get_id() */ ++ gpus = calloc( 1, sizeof(*gpus) ); ++ if (!gpus) goto done; ++ lstrcpyW( gpus[0].name, wine_adapterW ); ++ gpu_count = 1; ++ } ++ else if (gpus[0].id == -1) ++ { ++ /* the only GPUs we have are from Vulkan, mark the first one ++ * as main so that we can use screen resources for adapters, ++ * see xrandr14_get_adapters() */ ++ gpus[0].id = 0; ++ } + + *new_gpus = gpus; +- *count = provider_resources->nproviders; ++ *count = gpu_count; + ret = TRUE; + done: + if (provider_resources) +@@ -885,6 +1000,10 @@ static BOOL xrandr14_get_adapters( ULONG_PTR gpu_id, struct gdi_adapter **new_ad + if (!screen_resources) + goto done; + ++ /* Vulkan-only, adapter-less GPU */ ++ if (gpu_id == -1) ++ goto done; ++ + if (gpu_id) + { + provider_info = pXRRGetProviderInfo( gdi_display, screen_resources, gpu_id ); diff --git a/app-emulation/wine-staging/files/wine-staging-9.0-hags-0001.patch b/app-emulation/wine-staging/files/wine-staging-9.0-hags-0001.patch new file mode 100644 index 0000000..6f23556 --- /dev/null +++ b/app-emulation/wine-staging/files/wine-staging-9.0-hags-0001.patch @@ -0,0 +1,543 @@ +commit abb67b8aee120c52847abda19efb7641eeb184ac +Author: Krzysztof Bogacki +Date: Tue Dec 19 23:51:33 2023 +0100 + + gdi32,win32u,winex11: Implement D3DKMTEnumAdapters2. + +diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec +index 0ad4711..69ad9b2 100644 +--- a/dlls/gdi32/gdi32.spec ++++ b/dlls/gdi32/gdi32.spec +@@ -79,6 +79,7 @@ + @ stdcall D3DKMTCreateDevice(ptr) win32u.NtGdiDdDDICreateDevice + @ stdcall D3DKMTDestroyDCFromMemory(ptr) win32u.NtGdiDdDDIDestroyDCFromMemory + @ stdcall D3DKMTDestroyDevice(ptr) win32u.NtGdiDdDDIDestroyDevice ++@ stdcall D3DKMTEnumAdapters2(ptr) win32u.NtGdiDdDDIEnumAdapters2 + @ stdcall D3DKMTEscape(ptr) win32u.NtGdiDdDDIEscape + @ stdcall D3DKMTOpenAdapterFromDeviceName(ptr) win32u.NtGdiDdDDIOpenAdapterFromDeviceName + @ stdcall D3DKMTOpenAdapterFromGdiDisplayName(ptr) +diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c +index 7fe4b76..0a4b0ac 100644 +--- a/dlls/win32u/dibdrv/dc.c ++++ b/dlls/win32u/dibdrv/dc.c +@@ -709,6 +709,7 @@ const struct gdi_dc_funcs dib_driver = + NULL, /* pUnrealizePalette */ + NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ ++ NULL, /* pD3DKMTEnumAdapters2 */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ + NULL, /* pD3DKMTSetVidPnSourceOwner */ +@@ -1270,6 +1271,7 @@ static const struct gdi_dc_funcs window_driver = + NULL, /* pUnrealizePalette */ + NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ ++ NULL, /* pD3DKMTEnumAdapters2 */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ + NULL, /* pD3DKMTSetVidPnSourceOwner */ +diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c +index 3065a61..3f7b9e4 100644 +--- a/dlls/win32u/driver.c ++++ b/dlls/win32u/driver.c +@@ -54,6 +54,7 @@ static struct user_driver_funcs null_user_driver; + + static struct list d3dkmt_adapters = LIST_INIT( d3dkmt_adapters ); + static struct list d3dkmt_devices = LIST_INIT( d3dkmt_devices ); ++static D3DKMT_HANDLE handle_start = 0; + + static pthread_mutex_t driver_lock = PTHREAD_MUTEX_INITIALIZER; + static WCHAR driver_load_error[80]; +@@ -549,6 +550,11 @@ static NTSTATUS nulldrv_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) + return STATUS_PROCEDURE_NOT_FOUND; + } + ++static NTSTATUS nulldrv_D3DKMTEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) ++{ ++ return STATUS_PROCEDURE_NOT_FOUND; ++} ++ + static NTSTATUS nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) + { + return STATUS_PROCEDURE_NOT_FOUND; +@@ -657,6 +663,7 @@ const struct gdi_dc_funcs null_driver = + nulldrv_UnrealizePalette, /* pUnrealizePalette */ + nulldrv_D3DKMTCheckVidPnExclusiveOwnership, /* pD3DKMTCheckVidPnExclusiveOwnership */ + nulldrv_D3DKMTCloseAdapter, /* pD3DKMTCloseAdapter */ ++ nulldrv_D3DKMTEnumAdapters2, /* pD3DKMTEnumAdapters2 */ + nulldrv_D3DKMTOpenAdapterFromLuid, /* pD3DKMTOpenAdapterFromLuid */ + nulldrv_D3DKMTQueryVideoMemoryInfo, /* pD3DKMTQueryVideoMemoryInfo */ + nulldrv_D3DKMTSetVidPnSourceOwner, /* pD3DKMTSetVidPnSourceOwner */ +@@ -1526,6 +1533,46 @@ NTSTATUS WINAPI NtGdiDdDDICloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) + return status; + } + ++/****************************************************************************** ++ * NtGdiDdDDIEnumAdapters2 (win32u.@) ++ */ ++NTSTATUS WINAPI NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) ++{ ++ NTSTATUS status = STATUS_UNSUCCESSFUL; ++ struct d3dkmt_adapter *adapter; ++ ULONG i; ++ ++ TRACE("(%p)\n", desc); ++ ++ if (!desc) return STATUS_INVALID_PARAMETER; ++ ++ if (get_display_driver()->pD3DKMTEnumAdapters2) ++ { ++ if (desc->pAdapters) ++ { ++ pthread_mutex_lock( &driver_lock ); ++ ++ for (i = 0; i < desc->NumAdapters; ++i) ++ { ++ if (!(adapter = malloc( sizeof( *adapter ) ))) ++ { ++ pthread_mutex_unlock( &driver_lock ); ++ return STATUS_NO_MEMORY; ++ } ++ ++ desc->pAdapters[i].hAdapter = adapter->handle = ++handle_start; ++ list_add_tail( &d3dkmt_adapters, &adapter->entry ); ++ } ++ ++ pthread_mutex_unlock( &driver_lock ); ++ } ++ ++ status = get_display_driver()->pD3DKMTEnumAdapters2( desc ); ++ } ++ ++ return status; ++} ++ + /****************************************************************************** + * NtGdiDdDDIOpenAdapterFromDeviceName (win32u.@) + */ +@@ -1551,7 +1598,6 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVIC + */ + NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) + { +- static D3DKMT_HANDLE handle_start = 0; + struct d3dkmt_adapter *adapter; + + if (!(adapter = malloc( sizeof( *adapter ) ))) return STATUS_NO_MEMORY; +diff --git a/dlls/win32u/emfdrv.c b/dlls/win32u/emfdrv.c +index 069ad9d..9c07f9e 100644 +--- a/dlls/win32u/emfdrv.c ++++ b/dlls/win32u/emfdrv.c +@@ -521,6 +521,7 @@ static const struct gdi_dc_funcs emfdrv_driver = + NULL, /* pUnrealizePalette */ + NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ ++ NULL, /* pD3DKMTEnumAdapters2 */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ + NULL, /* pD3DKMTSetVidPnSourceOwner */ +diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c +index af1a9b9..2f84ff3 100644 +--- a/dlls/win32u/font.c ++++ b/dlls/win32u/font.c +@@ -4774,6 +4774,7 @@ const struct gdi_dc_funcs font_driver = + NULL, /* pUnrealizePalette */ + NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ ++ NULL, /* pD3DKMTEnumAdapters2 */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ + NULL, /* pD3DKMTSetVidPnSourceOwner */ +diff --git a/dlls/win32u/main.c b/dlls/win32u/main.c +index 2dc66e5..3f910c2 100644 +--- a/dlls/win32u/main.c ++++ b/dlls/win32u/main.c +@@ -236,6 +236,11 @@ NTSTATUS SYSCALL_API NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE *desc ) + __ASM_SYSCALL_FUNC( __id_NtGdiDdDDIDestroyDevice ); + } + ++NTSTATUS SYSCALL_API NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) ++{ ++ __ASM_SYSCALL_FUNC( __id_NtGdiDdDDIEnumAdapters2 ); ++} ++ + NTSTATUS SYSCALL_API NtGdiDdDDIEscape( const D3DKMT_ESCAPE *desc ) + { + __ASM_SYSCALL_FUNC( __id_NtGdiDdDDIEscape ); +diff --git a/dlls/win32u/path.c b/dlls/win32u/path.c +index e0c96f5..6d494a9 100644 +--- a/dlls/win32u/path.c ++++ b/dlls/win32u/path.c +@@ -2120,6 +2120,7 @@ const struct gdi_dc_funcs path_driver = + NULL, /* pUnrealizePalette */ + NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ ++ NULL, /* pD3DKMTEnumAdapters2 */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ + NULL, /* pD3DKMTSetVidPnSourceOwner */ +diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec +index 24dccb6..76a60bf 100644 +--- a/dlls/win32u/win32u.spec ++++ b/dlls/win32u/win32u.spec +@@ -223,7 +223,7 @@ + @ stub NtGdiDdDDIDispMgrSourceOperation + @ stub NtGdiDdDDIDispMgrTargetOperation + @ stub NtGdiDdDDIEnumAdapters +-@ stub NtGdiDdDDIEnumAdapters2 ++@ stdcall -syscall NtGdiDdDDIEnumAdapters2(ptr) + @ stdcall -syscall NtGdiDdDDIEscape(ptr) + @ stub NtGdiDdDDIEvict + @ stub NtGdiDdDDIExtractBundleObject +diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c +index 71e9207..840a4a8 100644 +--- a/dlls/winex11.drv/init.c ++++ b/dlls/winex11.drv/init.c +@@ -415,6 +415,7 @@ static const struct user_driver_funcs x11drv_funcs = + .dc_funcs.pUnrealizePalette = X11DRV_UnrealizePalette, + .dc_funcs.pD3DKMTCheckVidPnExclusiveOwnership = X11DRV_D3DKMTCheckVidPnExclusiveOwnership, + .dc_funcs.pD3DKMTCloseAdapter = X11DRV_D3DKMTCloseAdapter, ++ .dc_funcs.pD3DKMTEnumAdapters2 = X11DRV_D3DKMTEnumAdapters2, + .dc_funcs.pD3DKMTOpenAdapterFromLuid = X11DRV_D3DKMTOpenAdapterFromLuid, + .dc_funcs.pD3DKMTQueryVideoMemoryInfo = X11DRV_D3DKMTQueryVideoMemoryInfo, + .dc_funcs.pD3DKMTSetVidPnSourceOwner = X11DRV_D3DKMTSetVidPnSourceOwner, +diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h +index 666bd48..cf49660 100644 +--- a/dlls/winex11.drv/x11drv.h ++++ b/dlls/winex11.drv/x11drv.h +@@ -160,6 +160,7 @@ extern BOOL X11DRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom, + INT xstart, INT ystart, INT xend, INT yend ); + extern NTSTATUS X11DRV_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *desc ); + extern NTSTATUS X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ); ++extern NTSTATUS X11DRV_D3DKMTEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ); + extern NTSTATUS X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ); + extern NTSTATUS X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ); + extern NTSTATUS X11DRV_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc ); +diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c +index c4978d1..e523b85 100644 +--- a/dlls/winex11.drv/x11drv_main.c ++++ b/dlls/winex11.drv/x11drv_main.c +@@ -1241,6 +1241,243 @@ static void release_display_device_init_mutex(HANDLE mutex) + NtClose( mutex ); + } + ++/* Find the Vulkan device LUID corresponding to a GUID */ ++static BOOL get_vulkan_luid_from_uuid( const GUID *uuid, LUID *luid ) ++{ ++ static const WCHAR class_guidW[] = {'C','l','a','s','s','G','U','I','D',0}; ++ static const WCHAR devpropkey_gpu_vulkan_uuidW[] = ++ { ++ 'P','r','o','p','e','r','t','i','e','s', ++ '\\','{','2','3','3','A','9','E','F','3','-','A','F','C','4','-','4','A','B','D', ++ '-','B','5','6','4','-','C','3','2','F','2','1','F','1','5','3','5','C','}', ++ '\\','0','0','0','2' ++ }; ++ static const WCHAR devpropkey_gpu_luidW[] = ++ { ++ 'P','r','o','p','e','r','t','i','e','s', ++ '\\','{','6','0','B','1','9','3','C','B','-','5','2','7','6','-','4','D','0','F', ++ '-','9','6','F','C','-','F','1','7','3','A','B','A','D','3','E','C','6','}', ++ '\\','0','0','0','2' ++ }; ++ static const WCHAR guid_devclass_displayW[] = ++ {'{','4','D','3','6','E','9','6','8','-','E','3','2','5','-','1','1','C','E','-', ++ 'B','F','C','1','-','0','8','0','0','2','B','E','1','0','3','1','8','}',0}; ++ static const WCHAR pci_keyW[] = ++ { ++ '\\','R','e','g','i','s','t','r','y', ++ '\\','M','a','c','h','i','n','e', ++ '\\','S','y','s','t','e','m', ++ '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t', ++ '\\','E','n','u','m', ++ '\\','P','C','I' ++ }; ++ char buffer[4096]; ++ KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; ++ HKEY subkey, device_key, prop_key, pci_key; ++ KEY_NODE_INFORMATION *key = (void *)buffer; ++ DWORD size, i = 0; ++ HANDLE mutex; ++ ++ mutex = get_display_device_init_mutex(); ++ ++ pci_key = reg_open_key(NULL, pci_keyW, sizeof(pci_keyW)); ++ while (!NtEnumerateKey(pci_key, i++, KeyNodeInformation, key, sizeof(buffer), &size)) ++ { ++ unsigned int j = 0; ++ ++ if (!(subkey = reg_open_key(pci_key, key->Name, key->NameLength))) ++ continue; ++ ++ while (!NtEnumerateKey(subkey, j++, KeyNodeInformation, key, sizeof(buffer), &size)) ++ { ++ if (!(device_key = reg_open_key(subkey, key->Name, key->NameLength))) ++ continue; ++ ++ size = query_reg_value(device_key, class_guidW, value, sizeof(buffer)); ++ if (size != sizeof(guid_devclass_displayW) || ++ wcscmp((WCHAR *)value->Data, guid_devclass_displayW)) ++ { ++ NtClose(device_key); ++ continue; ++ } ++ ++ if (!(prop_key = reg_open_key(device_key, devpropkey_gpu_vulkan_uuidW, ++ sizeof(devpropkey_gpu_vulkan_uuidW)))) ++ { ++ NtClose(device_key); ++ continue; ++ } ++ ++ size = query_reg_value(prop_key, NULL, value, sizeof(buffer)); ++ NtClose(prop_key); ++ if (size != sizeof(GUID) || memcmp(value->Data, uuid, sizeof(GUID))) ++ { ++ NtClose(device_key); ++ continue; ++ } ++ ++ if (!(prop_key = reg_open_key(device_key, devpropkey_gpu_luidW, ++ sizeof(devpropkey_gpu_luidW)))) ++ { ++ NtClose(device_key); ++ continue; ++ } ++ ++ size = query_reg_value(prop_key, NULL, value, sizeof(buffer)); ++ NtClose(prop_key); ++ if (size != sizeof(LUID)) ++ { ++ NtClose(device_key); ++ continue; ++ } ++ ++ *luid = *(const LUID *)value->Data; ++ NtClose(device_key); ++ NtClose(subkey); ++ NtClose(pci_key); ++ release_display_device_init_mutex(mutex); ++ return TRUE; ++ } ++ NtClose(subkey); ++ } ++ NtClose(pci_key); ++ ++ release_display_device_init_mutex(mutex); ++ return FALSE; ++} ++ ++NTSTATUS X11DRV_D3DKMTEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ) ++{ ++ static const char *extensions[] = ++ { ++ VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, ++ VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, ++ }; ++ const struct vulkan_funcs *vulkan_funcs; ++ PFN_vkGetPhysicalDeviceProperties2KHR pvkGetPhysicalDeviceProperties2KHR; ++ PFN_vkEnumeratePhysicalDevices pvkEnumeratePhysicalDevices; ++ VkPhysicalDevice *vk_physical_devices = NULL; ++ VkPhysicalDeviceProperties2 properties2; ++ NTSTATUS status = STATUS_UNSUCCESSFUL; ++ UINT device_count = 0, device_idx = 0; ++ struct x11_d3dkmt_adapter *adapter; ++ VkInstanceCreateInfo create_info; ++ VkPhysicalDeviceIDProperties id; ++ VkResult vr; ++ LUID luid; ++ ++ if (!(vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION))) ++ { ++ WARN("Vulkan is unavailable.\n"); ++ return STATUS_UNSUCCESSFUL; ++ } ++ ++ pthread_mutex_lock(&d3dkmt_mutex); ++ ++ if (!d3dkmt_vk_instance) ++ { ++ memset(&create_info, 0, sizeof(create_info)); ++ create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; ++ create_info.enabledExtensionCount = ARRAY_SIZE(extensions); ++ create_info.ppEnabledExtensionNames = extensions; ++ ++ vr = vulkan_funcs->p_vkCreateInstance(&create_info, NULL, &d3dkmt_vk_instance); ++ if (vr != VK_SUCCESS) ++ { ++ WARN("Failed to create a Vulkan instance, vr %d.\n", vr); ++ goto done; ++ } ++ } ++ ++#define LOAD_VK_FUNC(f) \ ++ if (!(p##f = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(d3dkmt_vk_instance, #f))) \ ++ { \ ++ WARN("Failed to load " #f ".\n"); \ ++ goto done; \ ++ } ++ ++ LOAD_VK_FUNC(vkEnumeratePhysicalDevices) ++ LOAD_VK_FUNC(vkGetPhysicalDeviceProperties2KHR) ++#undef LOAD_VK_FUNC ++ ++ vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, NULL); ++ if (vr != VK_SUCCESS || !device_count) ++ { ++ WARN("No Vulkan device found, vr %d, device_count %d.\n", vr, device_count); ++ goto done; ++ } ++ ++ if (!desc->pAdapters) ++ { ++ status = STATUS_SUCCESS; ++ goto done; ++ } ++ else if (desc->NumAdapters < device_count) ++ { ++ status = STATUS_BUFFER_TOO_SMALL; ++ goto done; ++ } ++ ++ if (!(vk_physical_devices = calloc(device_count, sizeof(*vk_physical_devices)))) ++ { ++ status = STATUS_NO_MEMORY; ++ goto done; ++ } ++ ++ vr = pvkEnumeratePhysicalDevices(d3dkmt_vk_instance, &device_count, vk_physical_devices); ++ if (vr != VK_SUCCESS) ++ { ++ WARN("vkEnumeratePhysicalDevices failed, vr %d.\n", vr); ++ goto done; ++ } ++ ++ for (device_idx = 0; device_idx < device_count; ++device_idx) ++ { ++ memset(&id, 0, sizeof(id)); ++ id.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; ++ properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; ++ properties2.pNext = &id; ++ ++ pvkGetPhysicalDeviceProperties2KHR(vk_physical_devices[device_idx], &properties2); ++ ++ if (!(adapter = malloc(sizeof(*adapter)))) ++ { ++ status = STATUS_NO_MEMORY; ++ goto done; ++ } ++ ++ adapter->handle = desc->pAdapters[device_idx].hAdapter; ++ adapter->vk_device = vk_physical_devices[device_idx]; ++ list_add_tail(&x11_d3dkmt_adapters, &adapter->entry); ++ ++ if (get_vulkan_luid_from_uuid((const GUID *)id.deviceUUID, &luid)) ++ { ++ memcpy(&desc->pAdapters[device_idx].AdapterLuid, &luid, sizeof(LUID)); ++ } ++ else ++ { ++ WARN("get_vulkan_luid_from_uuid failed, AdapterLuid will remain empty.\n"); ++ memset(&desc->pAdapters[device_idx].AdapterLuid, 0, sizeof(LUID)); ++ } ++ ++ desc->pAdapters[device_idx].NumOfSources = 1; ++ desc->pAdapters[device_idx].bPrecisePresentRegionsPreferred = FALSE; ++ } ++ ++ status = STATUS_SUCCESS; ++ ++done: ++ desc->NumAdapters = device_count; ++ if (d3dkmt_vk_instance && list_empty(&x11_d3dkmt_adapters)) ++ { ++ vulkan_funcs->p_vkDestroyInstance(d3dkmt_vk_instance, NULL); ++ d3dkmt_vk_instance = NULL; ++ } ++ pthread_mutex_unlock(&d3dkmt_mutex); ++ free(vk_physical_devices); ++ return status; ++} ++ + /* Find the Vulkan device UUID corresponding to a LUID */ + static BOOL get_vulkan_uuid_from_luid( const LUID *luid, GUID *uuid ) + { +diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c +index 7472391..7e605f9 100644 +--- a/dlls/winex11.drv/xrender.c ++++ b/dlls/winex11.drv/xrender.c +@@ -2236,6 +2236,7 @@ static const struct gdi_dc_funcs xrender_funcs = + NULL, /* pUnrealizePalette */ + NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */ + NULL, /* pD3DKMTCloseAdapter */ ++ NULL, /* pD3DKMTEnumAdapters2 */ + NULL, /* pD3DKMTOpenAdapterFromLuid */ + NULL, /* pD3DKMTQueryVideoMemoryInfo */ + NULL, /* pD3DKMTSetVidPnSourceOwner */ +diff --git a/dlls/wow64win/gdi.c b/dlls/wow64win/gdi.c +index 36af173..993580c 100644 +--- a/dlls/wow64win/gdi.c ++++ b/dlls/wow64win/gdi.c +@@ -507,6 +507,28 @@ NTSTATUS WINAPI wow64_NtGdiDdDDIDestroyDevice( UINT *args ) + return NtGdiDdDDIDestroyDevice( desc ); + } + ++NTSTATUS WINAPI wow64_NtGdiDdDDIEnumAdapters2( UINT *args ) ++{ ++ struct ++ { ++ ULONG NumAdapters; ++ ULONG pAdapters; ++ } *desc32 = get_ptr( &args ); ++ D3DKMT_ENUMADAPTERS2 desc; ++ NTSTATUS status; ++ ++ if (!desc32) return STATUS_INVALID_PARAMETER; ++ ++ desc.NumAdapters = desc32->NumAdapters; ++ desc.pAdapters = UlongToPtr( desc32->pAdapters ); ++ ++ status = NtGdiDdDDIEnumAdapters2( &desc ); ++ ++ desc32->NumAdapters = desc.NumAdapters; ++ ++ return status; ++} ++ + NTSTATUS WINAPI wow64_NtGdiDdDDIEscape( UINT *args ) + { + const struct +diff --git a/include/ddk/d3dkmthk.h b/include/ddk/d3dkmthk.h +index 2d30bdd..918a4ad 100644 +--- a/include/ddk/d3dkmthk.h ++++ b/include/ddk/d3dkmthk.h +@@ -785,6 +785,7 @@ NTSTATUS WINAPI D3DKMTCreateDCFromMemory(D3DKMT_CREATEDCFROMMEMORY *desc); + NTSTATUS WINAPI D3DKMTDestroyDCFromMemory(const D3DKMT_DESTROYDCFROMMEMORY *desc); + NTSTATUS WINAPI D3DKMTDestroyDevice(const D3DKMT_DESTROYDEVICE *desc); + NTSTATUS WINAPI D3DKMTEscape( const D3DKMT_ESCAPE *desc ); ++NTSTATUS WINAPI D3DKMTEnumAdapters2(D3DKMT_ENUMADAPTERS2 *desc); + NTSTATUS WINAPI D3DKMTOpenAdapterFromGdiDisplayName(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *desc); + NTSTATUS WINAPI D3DKMTOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC *desc ); + NTSTATUS WINAPI D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID * desc ); +diff --git a/include/ntgdi.h b/include/ntgdi.h +index c2cb192..5097353 100644 +--- a/include/ntgdi.h ++++ b/include/ntgdi.h +@@ -481,6 +481,7 @@ W32KAPI NTSTATUS WINAPI NtGdiDdDDICreateDCFromMemory( D3DKMT_CREATEDCFROMMEMORY + W32KAPI NTSTATUS WINAPI NtGdiDdDDICreateDevice( D3DKMT_CREATEDEVICE *desc ); + W32KAPI NTSTATUS WINAPI NtGdiDdDDIDestroyDCFromMemory( const D3DKMT_DESTROYDCFROMMEMORY *desc ); + W32KAPI NTSTATUS WINAPI NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE *desc ); ++W32KAPI NTSTATUS WINAPI NtGdiDdDDIEnumAdapters2( D3DKMT_ENUMADAPTERS2 *desc ); + W32KAPI NTSTATUS WINAPI NtGdiDdDDIEscape( const D3DKMT_ESCAPE *desc ); + W32KAPI NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC *desc ); + W32KAPI NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME *desc ); +diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h +index 5689e8c..0c3c919 100644 +--- a/include/wine/gdi_driver.h ++++ b/include/wine/gdi_driver.h +@@ -168,6 +168,7 @@ struct gdi_dc_funcs + BOOL (*pUnrealizePalette)(HPALETTE); + NTSTATUS (*pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *); + NTSTATUS (*pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *); ++ NTSTATUS (*pD3DKMTEnumAdapters2)(D3DKMT_ENUMADAPTERS2 *); + NTSTATUS (*pD3DKMTOpenAdapterFromLuid)(D3DKMT_OPENADAPTERFROMLUID *); + NTSTATUS (*pD3DKMTQueryVideoMemoryInfo)(D3DKMT_QUERYVIDEOMEMORYINFO *); + NTSTATUS (*pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *); \ No newline at end of file diff --git a/app-emulation/wine-staging/files/wine-staging-9.0-hags-0002.patch b/app-emulation/wine-staging/files/wine-staging-9.0-hags-0002.patch new file mode 100644 index 0000000..b8216c1 --- /dev/null +++ b/app-emulation/wine-staging/files/wine-staging-9.0-hags-0002.patch @@ -0,0 +1,89 @@ +commit 078cdc32a3c1c7cf95f213159d4a97b98b04789b +Author: Krzysztof Bogacki +Date: Tue Dec 19 23:57:14 2023 +0100 + + win32u: Allow faking HAGS in QueryAdapterInfo. + +diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c +index 3f7b9e4..2bc7c37 100644 +--- a/dlls/win32u/driver.c ++++ b/dlls/win32u/driver.c +@@ -1691,16 +1691,49 @@ NTSTATUS WINAPI NtGdiDdDDIDestroyDevice( const D3DKMT_DESTROYDEVICE *desc ) + return status; + } + ++static BOOL check_hags_enabled( void ) ++{ ++ const char *winehags = getenv( "WINEHAGS" ); ++ return winehags && *winehags != '0'; ++} ++ + /****************************************************************************** + * NtGdiDdDDIQueryAdapterInfo (win32u.@) + */ + NTSTATUS WINAPI NtGdiDdDDIQueryAdapterInfo( D3DKMT_QUERYADAPTERINFO *desc ) + { ++ D3DKMT_WDDM_2_7_CAPS *d3dkmt_wddm_2_7_caps; ++ + if (!desc) + return STATUS_INVALID_PARAMETER; + +- FIXME("desc %p, type %d stub\n", desc, desc->Type); +- return STATUS_NOT_IMPLEMENTED; ++ TRACE("desc %p, type %d\n", desc, desc->Type); ++ ++ switch (desc->Type) ++ { ++ case KMTQAITYPE_WDDM_2_7_CAPS: ++ if (!desc->pPrivateDriverData || desc->PrivateDriverDataSize != sizeof(D3DKMT_WDDM_2_7_CAPS)) ++ return STATUS_INVALID_PARAMETER; ++ ++ d3dkmt_wddm_2_7_caps = desc->pPrivateDriverData; ++ d3dkmt_wddm_2_7_caps->HwSchSupported = 1; ++ d3dkmt_wddm_2_7_caps->HwSchEnabled = 0; ++ d3dkmt_wddm_2_7_caps->HwSchEnabledByDefault = 0; ++ d3dkmt_wddm_2_7_caps->IndependentVidPnVSyncControl = 0; ++ ++ if (check_hags_enabled()) ++ { ++ d3dkmt_wddm_2_7_caps->HwSchEnabled = 1; ++ d3dkmt_wddm_2_7_caps->HwSchEnabledByDefault = 1; ++ } ++ break; ++ ++ default: ++ FIXME("type %d not supported\n", desc->Type); ++ return STATUS_NOT_IMPLEMENTED; ++ } ++ ++ return STATUS_SUCCESS; + } + + /****************************************************************************** +diff --git a/include/ddk/d3dkmthk.h b/include/ddk/d3dkmthk.h +index 918a4ad..4b2c5a7 100644 +--- a/include/ddk/d3dkmthk.h ++++ b/include/ddk/d3dkmthk.h +@@ -773,6 +773,22 @@ typedef struct _D3DKMT_ENUMADAPTERS2 + D3DKMT_ADAPTERINFO *pAdapters; + } D3DKMT_ENUMADAPTERS2; + ++typedef struct _D3DKMT_WDDM_2_7_CAPS ++{ ++ union ++ { ++ struct ++ { ++ UINT HwSchSupported : 1; ++ UINT HwSchEnabled : 1; ++ UINT HwSchEnabledByDefault : 1; ++ UINT IndependentVidPnVSyncControl : 1; ++ UINT Reserved : 28; ++ }; ++ UINT Value; ++ }; ++} D3DKMT_WDDM_2_7_CAPS; ++ + #ifdef __cplusplus + extern "C" + { \ No newline at end of file diff --git a/app-emulation/wine-staging/metadata.xml b/app-emulation/wine-staging/metadata.xml new file mode 100644 index 0000000..41ee07d --- /dev/null +++ b/app-emulation/wine-staging/metadata.xml @@ -0,0 +1,41 @@ + + + + + wine@gentoo.org + Wine + + +Wine is an Open Source implementation of the Windows API on top of X and Unix. + +Think of Wine as a compatibility layer for running Windows programs. Wine does not require Microsoft Windows, as it is a completely free alternative implementation of the Windows API consisting of 100% non-Microsoft code, however Wine can optionally use native Windows DLLs if they are available. Wine provides both a development toolkit for porting Windows source code to Unix as well as a program loader, allowing many unmodified Windows programs to run on x86-based Unixes, including Linux, FreeBSD, and Solaris. + +This variant of the Wine packaging includes the Wine-Staging patchset. + + + Enable ISDN support using net-libs/libcapi + + Use sys-devel/crossdev for the toolchain rather than + dev-util/mingw64-toolchain (requires manual setting up) + + Pull in games-emulation/dosbox to run DOS applications + Enable mshtml support using app-emulation/wine-gecko + Build PE files using a MinGW toolchain for better compatibility + Enable .NET support using app-emulation/wine-mono + Enable support for configuring remote shares using net-fs/samba + Enable off-screen rendering (OpenGL in bitmaps) support + Support packet capture software (e.g. wireshark) + Install helpers that require perl (winedump/winemaker) + Pull in net-fs/samba with winbind for NTLM auth support + Enable gamepad support using media-libs/libsdl2 + + Enable running 32bit applications without 32bit ELF + multilib by mapping to 64bit calls (experimental/WIP, + USE=abi_x86_32 is recommended for complete support) + + + + https://bugs.winehq.org/describecomponents.cgi?product=Wine-staging + wine-staging/wine-staging + + diff --git a/app-emulation/wine-staging/wine-staging-8.21.ebuild b/app-emulation/wine-staging/wine-staging-8.21.ebuild new file mode 100644 index 0000000..bd1e1b1 --- /dev/null +++ b/app-emulation/wine-staging/wine-staging-8.21.ebuild @@ -0,0 +1,460 @@ +# Copyright 2022-2023 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +MULTILIB_COMPAT=( abi_x86_{32,64} ) +PYTHON_COMPAT=( python3_{10..12} ) +inherit autotools edo flag-o-matic multilib multilib-build +inherit prefix python-any-r1 toolchain-funcs wrapper + +WINE_GECKO=2.47.4 +WINE_MONO=8.1.0 +WINE_P=wine-$(ver_cut 1-2) + +if [[ ${PV} == *9999 ]]; then + inherit git-r3 + EGIT_REPO_URI="https://gitlab.winehq.org/wine/wine-staging.git" + WINE_EGIT_REPO_URI="https://gitlab.winehq.org/wine/wine.git" +else + (( $(ver_cut 2) )) && WINE_SDIR=$(ver_cut 1).x || WINE_SDIR=$(ver_cut 1).0 + SRC_URI=" + https://dl.winehq.org/wine/source/${WINE_SDIR}/${WINE_P}.tar.xz + https://github.com/wine-staging/wine-staging/archive/v${PV}.tar.gz -> ${P}.tar.gz" + KEYWORDS="-* ~amd64 ~x86" +fi +S="${WORKDIR}/${WINE_P}" + +DESCRIPTION="Free implementation of Windows(tm) on Unix, with Wine-Staging patchset" +HOMEPAGE=" + https://wiki.winehq.org/Wine-Staging + https://gitlab.winehq.org/wine/wine-staging/" + +LICENSE="LGPL-2.1+ BSD-2 IJG MIT OPENLDAP ZLIB gsm libpng2 libtiff" +SLOT="${PV}" +IUSE=" + +X +abi_x86_32 +abi_x86_64 +alsa capi crossdev-mingw cups dos + llvm-libunwind custom-cflags +fontconfig +gecko gphoto2 +gstreamer + kerberos +mingw +mono netapi nls opencl +opengl osmesa pcap perl + pulseaudio samba scanner +sdl selinux smartcard +ssl +strip + +truetype udev udisks +unwind usb v4l +vulkan wayland wow64 + +xcomposite xinerama" +# bug #551124 for truetype +# TODO: wow64 can be done without mingw if using clang (needs bug #912237) +REQUIRED_USE=" + X? ( truetype ) + crossdev-mingw? ( mingw ) + wow64? ( abi_x86_64 !abi_x86_32 mingw )" + +# tests are non-trivial to run, can hang easily, don't play well with +# sandbox, and several need real opengl/vulkan or network access +RESTRICT="test" + +# `grep WINE_CHECK_SONAME configure.ac` + if not directly linked +WINE_DLOPEN_DEPEND=" + X? ( + x11-libs/libXcursor[${MULTILIB_USEDEP}] + x11-libs/libXfixes[${MULTILIB_USEDEP}] + x11-libs/libXi[${MULTILIB_USEDEP}] + x11-libs/libXrandr[${MULTILIB_USEDEP}] + x11-libs/libXrender[${MULTILIB_USEDEP}] + x11-libs/libXxf86vm[${MULTILIB_USEDEP}] + opengl? ( + media-libs/libglvnd[X,${MULTILIB_USEDEP}] + osmesa? ( media-libs/mesa[osmesa,${MULTILIB_USEDEP}] ) + ) + xcomposite? ( x11-libs/libXcomposite[${MULTILIB_USEDEP}] ) + xinerama? ( x11-libs/libXinerama[${MULTILIB_USEDEP}] ) + ) + cups? ( net-print/cups[${MULTILIB_USEDEP}] ) + fontconfig? ( media-libs/fontconfig[${MULTILIB_USEDEP}] ) + kerberos? ( virtual/krb5[${MULTILIB_USEDEP}] ) + netapi? ( net-fs/samba[${MULTILIB_USEDEP}] ) + sdl? ( media-libs/libsdl2[haptic,joystick,${MULTILIB_USEDEP}] ) + ssl? ( net-libs/gnutls:=[${MULTILIB_USEDEP}] ) + truetype? ( media-libs/freetype[${MULTILIB_USEDEP}] ) + udisks? ( sys-apps/dbus[${MULTILIB_USEDEP}] ) + v4l? ( media-libs/libv4l[${MULTILIB_USEDEP}] ) + vulkan? ( media-libs/vulkan-loader[${MULTILIB_USEDEP}] )" +WINE_COMMON_DEPEND=" + ${WINE_DLOPEN_DEPEND} + X? ( + x11-libs/libX11[${MULTILIB_USEDEP}] + x11-libs/libXext[${MULTILIB_USEDEP}] + ) + alsa? ( media-libs/alsa-lib[${MULTILIB_USEDEP}] ) + capi? ( net-libs/libcapi:=[${MULTILIB_USEDEP}] ) + gphoto2? ( media-libs/libgphoto2:=[${MULTILIB_USEDEP}] ) + gstreamer? ( + dev-libs/glib:2[${MULTILIB_USEDEP}] + media-libs/gst-plugins-base:1.0[${MULTILIB_USEDEP}] + media-libs/gstreamer:1.0[${MULTILIB_USEDEP}] + ) + opencl? ( virtual/opencl[${MULTILIB_USEDEP}] ) + pcap? ( net-libs/libpcap[${MULTILIB_USEDEP}] ) + pulseaudio? ( media-libs/libpulse[${MULTILIB_USEDEP}] ) + scanner? ( media-gfx/sane-backends[${MULTILIB_USEDEP}] ) + smartcard? ( sys-apps/pcsc-lite[${MULTILIB_USEDEP}] ) + udev? ( virtual/libudev:=[${MULTILIB_USEDEP}] ) + unwind? ( + llvm-libunwind? ( sys-libs/llvm-libunwind[${MULTILIB_USEDEP}] ) + !llvm-libunwind? ( sys-libs/libunwind:=[${MULTILIB_USEDEP}] ) + ) + usb? ( dev-libs/libusb:1[${MULTILIB_USEDEP}] ) + wayland? ( + dev-libs/wayland[${MULTILIB_USEDEP}] + x11-libs/libxkbcommon[${MULTILIB_USEDEP}] + )" +RDEPEND=" + ${WINE_COMMON_DEPEND} + app-emulation/wine-desktop-common + dos? ( + || ( + games-emulation/dosbox + games-emulation/dosbox-staging + ) + ) + gecko? ( + app-emulation/wine-gecko:${WINE_GECKO}[${MULTILIB_USEDEP}] + wow64? ( app-emulation/wine-gecko[abi_x86_32] ) + ) + gstreamer? ( media-plugins/gst-plugins-meta:1.0[${MULTILIB_USEDEP}] ) + mono? ( app-emulation/wine-mono:${WINE_MONO} ) + perl? ( + dev-lang/perl + dev-perl/XML-LibXML + ) + samba? ( net-fs/samba[winbind] ) + selinux? ( sec-policy/selinux-wine ) + udisks? ( sys-fs/udisks:2 )" +DEPEND=" + ${WINE_COMMON_DEPEND} + sys-kernel/linux-headers + X? ( x11-base/xorg-proto )" +# gitapply.sh prefers git but can fallback to patch+extras +BDEPEND=" + ${PYTHON_DEPS} + || ( + dev-vcs/git + ( + sys-apps/gawk + sys-apps/util-linux + ) + ) + || ( + sys-devel/binutils + sys-devel/lld + ) + dev-lang/perl + sys-devel/bison + sys-devel/flex + virtual/pkgconfig + mingw? ( !crossdev-mingw? ( + >=dev-util/mingw64-toolchain-10.0.0_p1-r2[${MULTILIB_USEDEP}] + wow64? ( dev-util/mingw64-toolchain[abi_x86_32] ) + ) ) + nls? ( sys-devel/gettext ) + wayland? ( dev-util/wayland-scanner )" +IDEPEND=">=app-eselect/eselect-wine-2" + +QA_CONFIG_IMPL_DECL_SKIP=( + __clear_cache # unused on amd64+x86 (bug #900334) + res_getservers # false positive +) +QA_FLAGS_IGNORED="usr/lib/.*/wine/.*-unix/odbc32.so" # has no compiled objects +QA_TEXTRELS="usr/lib/*/wine/i386-unix/*.so" # uses -fno-PIC -Wl,-z,notext + +PATCHES=( + "${FILESDIR}"/${PN}-7.17-noexecstack.patch + "${FILESDIR}"/${PN}-7.20-unwind.patch + "${FILESDIR}"/${PN}-8.13-rpath.patch +) + +pkg_pretend() { + [[ ${MERGE_TYPE} == binary ]] && return + + if use crossdev-mingw && [[ ! -v MINGW_BYPASS ]]; then + local mingw=-w64-mingw32 + for mingw in $(usev abi_x86_64 x86_64${mingw}) \ + $(use abi_x86_32 || use wow64 && echo i686${mingw}); do + if ! type -P ${mingw}-gcc >/dev/null; then + eerror "With USE=crossdev-mingw, you must prepare the MinGW toolchain" + eerror "yourself by installing sys-devel/crossdev then running:" + eerror + eerror " crossdev --target ${mingw}" + eerror + eerror "For more information, please see: https://wiki.gentoo.org/wiki/Mingw" + die "USE=crossdev-mingw is enabled, but ${mingw}-gcc was not found" + fi + done + fi +} + +src_unpack() { + if [[ ${PV} == *9999 ]]; then + EGIT_CHECKOUT_DIR=${WORKDIR}/${P} + git-r3_src_unpack + + # hack: use subshell to preserve state (including what git-r3 unpack + # sets) for smart-live-rebuild as this is not the repo to look at + ( + EGIT_COMMIT=$(<"${EGIT_CHECKOUT_DIR}"/staging/upstream-commit) || die + EGIT_REPO_URI=${WINE_EGIT_REPO_URI} + EGIT_CHECKOUT_DIR=${S} + einfo "Fetching Wine commit matching the current patchset by default (${EGIT_COMMIT})" + git-r3_src_unpack + ) + else + default + fi +} + +src_prepare() { + local patchinstallargs=( + --all + --no-autoconf + ${MY_WINE_STAGING_CONF} + ) + + edo "${PYTHON}" ../${P}/staging/patchinstall.py "${patchinstallargs[@]}" + + # sanity check, bumping these has a history of oversights + local geckomono=$(sed -En '/^#define (GECKO|MONO)_VER/{s/[^0-9.]//gp}' \ + dlls/appwiz.cpl/addons.c || die) + if [[ ${WINE_GECKO}$'\n'${WINE_MONO} != "${geckomono}" ]]; then + local gmfatal= + [[ ${PV} == *9999 ]] && gmfatal=nonfatal + ${gmfatal} die -n "gecko/mono mismatch in ebuild, has: " ${geckomono} " (please file a bug)" + fi + + default + + if tc-is-clang; then + if use mingw; then + # -mabi=ms was ignored by /dev/null) != @(LLD|GNU\ ld)* ]] + then + has_version -b sys-devel/binutils && + append-ldflags -fuse-ld=bfd || + append-ldflags -fuse-ld=lld + strip-unsupported-flags + fi + + if use mingw; then + use crossdev-mingw || PATH=${BROOT}/usr/lib/mingw64-toolchain/bin:${PATH} + + filter-flags -fno-plt # build failure + + # CROSSCC was formerly recognized by wine, thus been using similar + # variables (subject to change, esp. if ever make a mingw.eclass). + local mingwcc_amd64=${CROSSCC:-${CROSSCC_amd64:-x86_64-w64-mingw32-gcc}} + local mingwcc_x86=${CROSSCC:-${CROSSCC_x86:-i686-w64-mingw32-gcc}} + local -n mingwcc=mingwcc_$(usex abi_x86_64 amd64 x86) + + conf+=( + ac_cv_prog_x86_64_CC="${mingwcc_amd64}" + ac_cv_prog_i386_CC="${mingwcc_x86}" + + CROSSCFLAGS="${CROSSCFLAGS:-$( + filter-flags '-fstack-protector*' #870136 + filter-flags '-mfunction-return=thunk*' #878849 + + # -mavx with mingw-gcc has a history of obscure issues and + # disabling is seen as safer, e.g. `WINEARCH=win32 winecfg` + # crashes with -march=skylake >=wine-8.10, similar issues with + # znver4: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110273 + append-cflags -mno-avx #912268 + + CC=${mingwcc} test-flags-CC ${CFLAGS:--O2} + )}" + + CROSSLDFLAGS="${CROSSLDFLAGS:-$( + filter-flags '-fuse-ld=*' + + CC=${mingwcc} test-flags-CCLD ${LDFLAGS} + )}" + ) + fi + + # order matters with multilib: configure+compile 64->32, install 32->64 + local -i bits + for bits in $(usev abi_x86_64 64) $(usev abi_x86_32 32); do + ( + einfo "Configuring ${PN} for ${bits}bits in ${WORKDIR}/build${bits} ..." + + mkdir ../build${bits} || die + cd ../build${bits} || die + + if (( bits == 64 )); then + conf+=( --enable-win64 ) + elif use amd64; then + conf+=( + $(usev abi_x86_64 --with-wine64=../build64) + TARGETFLAGS=-m32 # for widl + ) + # _setup is optional, but use over Wine's auto-detect (+#472038) + multilib_toolchain_setup x86 + fi + + ECONF_SOURCE=${S} econf "${conf[@]}" + ) + done +} + +src_compile() { + use abi_x86_64 && emake -C ../build64 # do first + use abi_x86_32 && emake -C ../build32 +} + +src_install() { + use abi_x86_32 && emake DESTDIR="${D}" -C ../build32 install + use abi_x86_64 && emake DESTDIR="${D}" -C ../build64 install # do last + + # Ensure both wine64 and wine are available if USE=abi_x86_64 (wow64, + # -abi_x86_32, and/or EXTRA_ECONF could cause varying scenarios where + # one or the other could be missing and that is unexpected for users + # and some tools like winetricks) + if use abi_x86_64; then + if [[ -e ${ED}${WINE_PREFIX}/bin/wine64 && ! -e ${ED}${WINE_PREFIX}/bin/wine ]]; then + dosym wine64 ${WINE_PREFIX}/bin/wine + dosym wine64-preloader ${WINE_PREFIX}/bin/wine-preloader + + # also install wine(1) man pages (incl. translations) + local man + for man in ../build64/loader/wine.*man; do + : "${man##*/wine}" + : "${_%.*}" + insinto ${WINE_DATADIR}/man/${_:+${_#.}/}man1 + newins ${man} wine.1 + done + elif [[ ! -e ${ED}${WINE_PREFIX}/bin/wine64 && -e ${ED}${WINE_PREFIX}/bin/wine ]]; then + dosym wine ${WINE_PREFIX}/bin/wine64 + dosym wine-preloader ${WINE_PREFIX}/bin/wine64-preloader + fi + fi + + use perl || rm "${ED}"${WINE_DATADIR}/man/man1/wine{dump,maker}.1 \ + "${ED}"${WINE_PREFIX}/bin/{function_grep.pl,wine{dump,maker}} || die + + # create variant wrappers for eselect-wine + local bin + for bin in "${ED}"${WINE_PREFIX}/bin/*; do + make_wrapper "${bin##*/}-${P#wine-}" "${bin#"${ED}"}" + done + + if use mingw; then + # don't let portage try to strip PE files with the wrong + # strip executable and instead handle it here (saves ~120MB) + dostrip -x ${WINE_PREFIX}/wine/{i386,x86_64}-windows + + if use strip; then + ebegin "Stripping Windows (PE) binaries" + find "${ED}"${WINE_PREFIX}/wine/*-windows -regex '.*\.\(a\|dll\|exe\)' \ + -exec $(usex abi_x86_64 x86_64 i686)-w64-mingw32-strip --strip-unneeded {} + + eend ${?} || die + fi + fi + + dodoc ANNOUNCE AUTHORS README* documentation/README* +} + +pkg_postinst() { + if use !abi_x86_32 && use !wow64; then + ewarn "32bit support is disabled. While 64bit applications themselves will" + ewarn "work, be warned that it is not unusual that installers or other helpers" + ewarn "will attempt to use 32bit and fail. If do not want full USE=abi_x86_32," + ewarn "note the experimental/WIP USE=wow64 can allow 32bit without multilib." + elif use abi_x86_32 && { use opengl || use vulkan; } && + has_version 'x11-drivers/nvidia-drivers[-abi_x86_32]' + then + ewarn "x11-drivers/nvidia-drivers is installed but is built without" + ewarn "USE=abi_x86_32 (ABI_X86=32), hardware acceleration with 32bit" + ewarn "applications under ${PN} will likely not be usable." + fi + + eselect wine update --if-unset || die +} + +pkg_postrm() { + eselect wine update --if-unset || die +} diff --git a/app-emulation/wine-staging/wine-staging-9.0-r2.ebuild b/app-emulation/wine-staging/wine-staging-9.0-r2.ebuild new file mode 100644 index 0000000..5ecb25a --- /dev/null +++ b/app-emulation/wine-staging/wine-staging-9.0-r2.ebuild @@ -0,0 +1,460 @@ +# Copyright 2022-2023 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +MULTILIB_COMPAT=( abi_x86_{32,64} ) +PYTHON_COMPAT=( python3_{10..12} ) +inherit autotools edo flag-o-matic multilib multilib-build +inherit prefix python-any-r1 toolchain-funcs wrapper + +WINE_GECKO=2.47.4 +WINE_MONO=8.1.0 +WINE_P=wine-$(ver_cut 1-2) + +if [[ ${PV} == *9999 ]]; then + inherit git-r3 + EGIT_REPO_URI="https://gitlab.winehq.org/wine/wine-staging.git" + WINE_EGIT_REPO_URI="https://gitlab.winehq.org/wine/wine.git" +else + (( $(ver_cut 2) )) && WINE_SDIR=$(ver_cut 1).x || WINE_SDIR=$(ver_cut 1).0 + SRC_URI=" + https://dl.winehq.org/wine/source/${WINE_SDIR}/${WINE_P}-rc2.tar.xz + https://github.com/wine-staging/wine-staging/archive/v${PV}-rc2.tar.gz -> ${P}-rc2.tar.gz" + KEYWORDS="-* ~amd64 ~x86" +fi +S="${WORKDIR}/${WINE_P}" + +DESCRIPTION="Free implementation of Windows(tm) on Unix, with Wine-Staging patchset" +HOMEPAGE=" + https://wiki.winehq.org/Wine-Staging + https://gitlab.winehq.org/wine/wine-staging/" + +LICENSE="LGPL-2.1+ BSD-2 IJG MIT OPENLDAP ZLIB gsm libpng2 libtiff" +SLOT="${PV}" +IUSE=" + +X +abi_x86_32 +abi_x86_64 +alsa capi crossdev-mingw cups dos + llvm-libunwind custom-cflags +fontconfig +gecko gphoto2 +gstreamer + kerberos +mingw +mono netapi nls opencl +opengl osmesa pcap perl + pulseaudio samba scanner +sdl selinux smartcard +ssl +strip + +truetype udev udisks +unwind usb v4l +vulkan wayland wow64 + +xcomposite xinerama" +# bug #551124 for truetype +# TODO: wow64 can be done without mingw if using clang (needs bug #912237) +REQUIRED_USE=" + X? ( truetype ) + crossdev-mingw? ( mingw ) + wow64? ( abi_x86_64 !abi_x86_32 mingw )" + +# tests are non-trivial to run, can hang easily, don't play well with +# sandbox, and several need real opengl/vulkan or network access +RESTRICT="test" + +# `grep WINE_CHECK_SONAME configure.ac` + if not directly linked +WINE_DLOPEN_DEPEND=" + X? ( + x11-libs/libXcursor[${MULTILIB_USEDEP}] + x11-libs/libXfixes[${MULTILIB_USEDEP}] + x11-libs/libXi[${MULTILIB_USEDEP}] + x11-libs/libXrandr[${MULTILIB_USEDEP}] + x11-libs/libXrender[${MULTILIB_USEDEP}] + x11-libs/libXxf86vm[${MULTILIB_USEDEP}] + opengl? ( + media-libs/libglvnd[X,${MULTILIB_USEDEP}] + osmesa? ( media-libs/mesa[osmesa,${MULTILIB_USEDEP}] ) + ) + xcomposite? ( x11-libs/libXcomposite[${MULTILIB_USEDEP}] ) + xinerama? ( x11-libs/libXinerama[${MULTILIB_USEDEP}] ) + ) + cups? ( net-print/cups[${MULTILIB_USEDEP}] ) + fontconfig? ( media-libs/fontconfig[${MULTILIB_USEDEP}] ) + kerberos? ( virtual/krb5[${MULTILIB_USEDEP}] ) + netapi? ( net-fs/samba[${MULTILIB_USEDEP}] ) + sdl? ( media-libs/libsdl2[haptic,joystick,${MULTILIB_USEDEP}] ) + ssl? ( net-libs/gnutls:=[${MULTILIB_USEDEP}] ) + truetype? ( media-libs/freetype[${MULTILIB_USEDEP}] ) + udisks? ( sys-apps/dbus[${MULTILIB_USEDEP}] ) + v4l? ( media-libs/libv4l[${MULTILIB_USEDEP}] ) + vulkan? ( media-libs/vulkan-loader[${MULTILIB_USEDEP}] )" +WINE_COMMON_DEPEND=" + ${WINE_DLOPEN_DEPEND} + X? ( + x11-libs/libX11[${MULTILIB_USEDEP}] + x11-libs/libXext[${MULTILIB_USEDEP}] + ) + alsa? ( media-libs/alsa-lib[${MULTILIB_USEDEP}] ) + capi? ( net-libs/libcapi:=[${MULTILIB_USEDEP}] ) + gphoto2? ( media-libs/libgphoto2:=[${MULTILIB_USEDEP}] ) + gstreamer? ( + dev-libs/glib:2[${MULTILIB_USEDEP}] + media-libs/gst-plugins-base:1.0[${MULTILIB_USEDEP}] + media-libs/gstreamer:1.0[${MULTILIB_USEDEP}] + ) + opencl? ( virtual/opencl[${MULTILIB_USEDEP}] ) + pcap? ( net-libs/libpcap[${MULTILIB_USEDEP}] ) + pulseaudio? ( media-libs/libpulse[${MULTILIB_USEDEP}] ) + scanner? ( media-gfx/sane-backends[${MULTILIB_USEDEP}] ) + smartcard? ( sys-apps/pcsc-lite[${MULTILIB_USEDEP}] ) + udev? ( virtual/libudev:=[${MULTILIB_USEDEP}] ) + unwind? ( + llvm-libunwind? ( sys-libs/llvm-libunwind[${MULTILIB_USEDEP}] ) + !llvm-libunwind? ( sys-libs/libunwind:=[${MULTILIB_USEDEP}] ) + ) + usb? ( dev-libs/libusb:1[${MULTILIB_USEDEP}] ) + wayland? ( + dev-libs/wayland[${MULTILIB_USEDEP}] + x11-libs/libxkbcommon[${MULTILIB_USEDEP}] + )" +RDEPEND=" + ${WINE_COMMON_DEPEND} + app-emulation/wine-desktop-common + dos? ( + || ( + games-emulation/dosbox + games-emulation/dosbox-staging + ) + ) + gecko? ( + app-emulation/wine-gecko:${WINE_GECKO}[${MULTILIB_USEDEP}] + wow64? ( app-emulation/wine-gecko[abi_x86_32] ) + ) + gstreamer? ( media-plugins/gst-plugins-meta:1.0[${MULTILIB_USEDEP}] ) + mono? ( app-emulation/wine-mono:${WINE_MONO} ) + perl? ( + dev-lang/perl + dev-perl/XML-LibXML + ) + samba? ( net-fs/samba[winbind] ) + selinux? ( sec-policy/selinux-wine ) + udisks? ( sys-fs/udisks:2 )" +DEPEND=" + ${WINE_COMMON_DEPEND} + sys-kernel/linux-headers + X? ( x11-base/xorg-proto )" +# gitapply.sh prefers git but can fallback to patch+extras +BDEPEND=" + ${PYTHON_DEPS} + || ( + dev-vcs/git + ( + sys-apps/gawk + sys-apps/util-linux + ) + ) + || ( + sys-devel/binutils + sys-devel/lld + ) + dev-lang/perl + sys-devel/bison + sys-devel/flex + virtual/pkgconfig + mingw? ( !crossdev-mingw? ( + >=dev-util/mingw64-toolchain-10.0.0_p1-r2[${MULTILIB_USEDEP}] + wow64? ( dev-util/mingw64-toolchain[abi_x86_32] ) + ) ) + nls? ( sys-devel/gettext ) + wayland? ( dev-util/wayland-scanner )" +IDEPEND=">=app-eselect/eselect-wine-2" + +QA_CONFIG_IMPL_DECL_SKIP=( + __clear_cache # unused on amd64+x86 (bug #900334) + res_getservers # false positive +) +QA_FLAGS_IGNORED="usr/lib/.*/wine/.*-unix/odbc32.so" # has no compiled objects +QA_TEXTRELS="usr/lib/*/wine/i386-unix/*.so" # uses -fno-PIC -Wl,-z,notext + +PATCHES=( + "${FILESDIR}"/${PN}-7.17-noexecstack.patch + "${FILESDIR}"/${PN}-7.20-unwind.patch + "${FILESDIR}"/${PN}-8.13-rpath.patch + "${FILESDIR}"/${PN}-9.0-hags-0001.patch + "${FILESDIR}"/${PN}-9.0-hags-0002.patch + "${FILESDIR}"/${PN}-9.0-gpu_detection.patch +) + +pkg_pretend() { + [[ ${MERGE_TYPE} == binary ]] && return + + if use crossdev-mingw && [[ ! -v MINGW_BYPASS ]]; then + local mingw=-w64-mingw32 + for mingw in $(usev abi_x86_64 x86_64${mingw}) \ + $(use abi_x86_32 || use wow64 && echo i686${mingw}); do + if ! type -P ${mingw}-gcc >/dev/null; then + eerror "With USE=crossdev-mingw, you must prepare the MinGW toolchain" + eerror "yourself by installing sys-devel/crossdev then running:" + eerror + eerror " crossdev --target ${mingw}" + eerror + eerror "For more information, please see: https://wiki.gentoo.org/wiki/Mingw" + die "USE=crossdev-mingw is enabled, but ${mingw}-gcc was not found" + fi + done + fi +} + +src_unpack() { + if [[ ${PV} == *9999 ]]; then + EGIT_CHECKOUT_DIR=${WORKDIR}/${P} + git-r3_src_unpack + + # hack: use subshell to preserve state (including what git-r3 unpack + # sets) for smart-live-rebuild as this is not the repo to look at + ( + EGIT_COMMIT=$(<"${EGIT_CHECKOUT_DIR}"/staging/upstream-commit) || die + EGIT_REPO_URI=${WINE_EGIT_REPO_URI} + EGIT_CHECKOUT_DIR=${S} + einfo "Fetching Wine commit matching the current patchset by default (${EGIT_COMMIT})" + git-r3_src_unpack + ) + else + default + #fix names + mv ${WORKDIR}/wine-staging-${PV}-rc2 ${WORKDIR}/wine-staging-${PV} + mv ${WORKDIR}/wine-${PV}-rc2 ${WORKDIR}/wine-${PV} + fi +} + +src_prepare() { + local patchinstallargs=( + --all + --no-autoconf + ${MY_WINE_STAGING_CONF} + ) + + edo "${PYTHON}" ../${P}/staging/patchinstall.py "${patchinstallargs[@]}" + + # sanity check, bumping these has a history of oversights + local geckomono=$(sed -En '/^#define (GECKO|MONO)_VER/{s/[^0-9.]//gp}' \ + dlls/appwiz.cpl/addons.c || die) + if [[ ${WINE_GECKO}$'\n'${WINE_MONO} != "${geckomono}" ]]; then + local gmfatal= + [[ ${PV} == *9999 ]] && gmfatal=nonfatal + ${gmfatal} die -n "gecko/mono mismatch in ebuild, has: " ${geckomono} " (please file a bug)" + fi + + default + + if tc-is-clang; then + if use mingw; then + # -mabi=ms was ignored by /dev/null) != @(LLD|GNU\ ld)* ]] + then + has_version -b sys-devel/binutils && + append-ldflags -fuse-ld=bfd || + append-ldflags -fuse-ld=lld + strip-unsupported-flags + fi + + if use mingw; then + use crossdev-mingw || PATH=${BROOT}/usr/lib/mingw64-toolchain/bin:${PATH} + + filter-flags -fno-plt # build failure + + # CROSSCC was formerly recognized by wine, thus been using similar + # variables (subject to change, esp. if ever make a mingw.eclass). + local mingwcc_amd64=${CROSSCC:-${CROSSCC_amd64:-x86_64-w64-mingw32-gcc}} + local mingwcc_x86=${CROSSCC:-${CROSSCC_x86:-i686-w64-mingw32-gcc}} + local -n mingwcc=mingwcc_$(usex abi_x86_64 amd64 x86) + + conf+=( + ac_cv_prog_x86_64_CC="${mingwcc_amd64}" + ac_cv_prog_i386_CC="${mingwcc_x86}" + + CROSSCFLAGS="${CROSSCFLAGS:-$( + filter-flags '-fstack-protector*' #870136 + filter-flags '-mfunction-return=thunk*' #878849 + CC=${mingwcc} test-flags-CC ${CFLAGS:--O2} + )}" + + CROSSLDFLAGS="${CROSSLDFLAGS:-$( + filter-flags '-fuse-ld=*' + + CC=${mingwcc} test-flags-CCLD ${LDFLAGS} + )}" + ) + fi + + # order matters with multilib: configure+compile 64->32, install 32->64 + local -i bits + for bits in $(usev abi_x86_64 64) $(usev abi_x86_32 32); do + ( + einfo "Configuring ${PN} for ${bits}bits in ${WORKDIR}/build${bits} ..." + + mkdir ../build${bits} || die + cd ../build${bits} || die + + if (( bits == 64 )); then + conf+=( --enable-win64 ) + elif use amd64; then + conf+=( + $(usev abi_x86_64 --with-wine64=../build64) + TARGETFLAGS=-m32 # for widl + ) + # _setup is optional, but use over Wine's auto-detect (+#472038) + multilib_toolchain_setup x86 + fi + + ECONF_SOURCE=${S} econf "${conf[@]}" + ) + done +} + +src_compile() { + use abi_x86_64 && emake -C ../build64 # do first + use abi_x86_32 && emake -C ../build32 +} + +src_install() { + use abi_x86_32 && emake DESTDIR="${D}" -C ../build32 install + use abi_x86_64 && emake DESTDIR="${D}" -C ../build64 install # do last + + # Ensure both wine64 and wine are available if USE=abi_x86_64 (wow64, + # -abi_x86_32, and/or EXTRA_ECONF could cause varying scenarios where + # one or the other could be missing and that is unexpected for users + # and some tools like winetricks) + if use abi_x86_64; then + if [[ -e ${ED}${WINE_PREFIX}/bin/wine64 && ! -e ${ED}${WINE_PREFIX}/bin/wine ]]; then + dosym wine64 ${WINE_PREFIX}/bin/wine + dosym wine64-preloader ${WINE_PREFIX}/bin/wine-preloader + + # also install wine(1) man pages (incl. translations) + local man + for man in ../build64/loader/wine.*man; do + : "${man##*/wine}" + : "${_%.*}" + insinto ${WINE_DATADIR}/man/${_:+${_#.}/}man1 + newins ${man} wine.1 + done + elif [[ ! -e ${ED}${WINE_PREFIX}/bin/wine64 && -e ${ED}${WINE_PREFIX}/bin/wine ]]; then + dosym wine ${WINE_PREFIX}/bin/wine64 + dosym wine-preloader ${WINE_PREFIX}/bin/wine64-preloader + fi + fi + + use perl || rm "${ED}"${WINE_DATADIR}/man/man1/wine{dump,maker}.1 \ + "${ED}"${WINE_PREFIX}/bin/{function_grep.pl,wine{dump,maker}} || die + + # create variant wrappers for eselect-wine + local bin + for bin in "${ED}"${WINE_PREFIX}/bin/*; do + make_wrapper "${bin##*/}-${P#wine-}" "${bin#"${ED}"}" + done + + if use mingw; then + # don't let portage try to strip PE files with the wrong + # strip executable and instead handle it here (saves ~120MB) + dostrip -x ${WINE_PREFIX}/wine/{i386,x86_64}-windows + + if use strip; then + ebegin "Stripping Windows (PE) binaries" + find "${ED}"${WINE_PREFIX}/wine/*-windows -regex '.*\.\(a\|dll\|exe\)' \ + -exec $(usex abi_x86_64 x86_64 i686)-w64-mingw32-strip --strip-unneeded {} + + eend ${?} || die + fi + fi + + dodoc ANNOUNCE AUTHORS README* documentation/README* +} + +pkg_postinst() { + if use !abi_x86_32 && use !wow64; then + ewarn "32bit support is disabled. While 64bit applications themselves will" + ewarn "work, be warned that it is not unusual that installers or other helpers" + ewarn "will attempt to use 32bit and fail. If do not want full USE=abi_x86_32," + ewarn "note the experimental/WIP USE=wow64 can allow 32bit without multilib." + elif use abi_x86_32 && { use opengl || use vulkan; } && + has_version 'x11-drivers/nvidia-drivers[-abi_x86_32]' + then + ewarn "x11-drivers/nvidia-drivers is installed but is built without" + ewarn "USE=abi_x86_32 (ABI_X86=32), hardware acceleration with 32bit" + ewarn "applications under ${PN} will likely not be usable." + fi + + eselect wine update --if-unset || die +} + +pkg_postrm() { + eselect wine update --if-unset || die +} diff --git a/app-emulation/wine-staging/wine-staging-9999.ebuild b/app-emulation/wine-staging/wine-staging-9999.ebuild new file mode 100644 index 0000000..7cf53fb --- /dev/null +++ b/app-emulation/wine-staging/wine-staging-9999.ebuild @@ -0,0 +1,454 @@ +# Copyright 2022-2023 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +MULTILIB_COMPAT=( abi_x86_{32,64} ) +PYTHON_COMPAT=( python3_{10..12} ) +inherit autotools edo flag-o-matic multilib multilib-build +inherit prefix python-any-r1 toolchain-funcs wrapper + +WINE_GECKO=2.47.4 +WINE_MONO=8.1.0 +WINE_P=wine-$(ver_cut 1-2) + +if [[ ${PV} == *9999 ]]; then + inherit git-r3 + EGIT_REPO_URI="https://gitlab.winehq.org/wine/wine-staging.git" + WINE_EGIT_REPO_URI="https://gitlab.winehq.org/wine/wine.git" +else + (( $(ver_cut 2) )) && WINE_SDIR=$(ver_cut 1).x || WINE_SDIR=$(ver_cut 1).0 + SRC_URI=" + https://dl.winehq.org/wine/source/${WINE_SDIR}/${WINE_P}.tar.xz + https://github.com/wine-staging/wine-staging/archive/v${PV}.tar.gz -> ${P}.tar.gz" + KEYWORDS="-* ~amd64 ~x86" +fi +S="${WORKDIR}/${WINE_P}" + +DESCRIPTION="Free implementation of Windows(tm) on Unix, with Wine-Staging patchset" +HOMEPAGE=" + https://wiki.winehq.org/Wine-Staging + https://gitlab.winehq.org/wine/wine-staging/" + +LICENSE="LGPL-2.1+ BSD-2 IJG MIT OPENLDAP ZLIB gsm libpng2 libtiff" +SLOT="${PV}" +IUSE=" + +X +abi_x86_32 +abi_x86_64 +alsa capi crossdev-mingw cups dos + llvm-libunwind custom-cflags +fontconfig +gecko gphoto2 +gstreamer + kerberos +mingw +mono netapi nls opencl +opengl osmesa pcap perl + pulseaudio samba scanner +sdl selinux smartcard +ssl +strip + +truetype udev udisks +unwind usb v4l +vulkan wayland wow64 + +xcomposite xinerama" +# bug #551124 for truetype +# TODO: wow64 can be done without mingw if using clang (needs bug #912237) +REQUIRED_USE=" + X? ( truetype ) + crossdev-mingw? ( mingw ) + wow64? ( abi_x86_64 !abi_x86_32 mingw )" + +# tests are non-trivial to run, can hang easily, don't play well with +# sandbox, and several need real opengl/vulkan or network access +RESTRICT="test" + +# `grep WINE_CHECK_SONAME configure.ac` + if not directly linked +WINE_DLOPEN_DEPEND=" + X? ( + x11-libs/libXcursor[${MULTILIB_USEDEP}] + x11-libs/libXfixes[${MULTILIB_USEDEP}] + x11-libs/libXi[${MULTILIB_USEDEP}] + x11-libs/libXrandr[${MULTILIB_USEDEP}] + x11-libs/libXrender[${MULTILIB_USEDEP}] + x11-libs/libXxf86vm[${MULTILIB_USEDEP}] + opengl? ( + media-libs/libglvnd[X,${MULTILIB_USEDEP}] + osmesa? ( media-libs/mesa[osmesa,${MULTILIB_USEDEP}] ) + ) + xcomposite? ( x11-libs/libXcomposite[${MULTILIB_USEDEP}] ) + xinerama? ( x11-libs/libXinerama[${MULTILIB_USEDEP}] ) + ) + cups? ( net-print/cups[${MULTILIB_USEDEP}] ) + fontconfig? ( media-libs/fontconfig[${MULTILIB_USEDEP}] ) + kerberos? ( virtual/krb5[${MULTILIB_USEDEP}] ) + netapi? ( net-fs/samba[${MULTILIB_USEDEP}] ) + sdl? ( media-libs/libsdl2[haptic,joystick,${MULTILIB_USEDEP}] ) + ssl? ( net-libs/gnutls:=[${MULTILIB_USEDEP}] ) + truetype? ( media-libs/freetype[${MULTILIB_USEDEP}] ) + udisks? ( sys-apps/dbus[${MULTILIB_USEDEP}] ) + v4l? ( media-libs/libv4l[${MULTILIB_USEDEP}] ) + vulkan? ( media-libs/vulkan-loader[${MULTILIB_USEDEP}] )" +WINE_COMMON_DEPEND=" + ${WINE_DLOPEN_DEPEND} + X? ( + x11-libs/libX11[${MULTILIB_USEDEP}] + x11-libs/libXext[${MULTILIB_USEDEP}] + ) + alsa? ( media-libs/alsa-lib[${MULTILIB_USEDEP}] ) + capi? ( net-libs/libcapi:=[${MULTILIB_USEDEP}] ) + gphoto2? ( media-libs/libgphoto2:=[${MULTILIB_USEDEP}] ) + gstreamer? ( + dev-libs/glib:2[${MULTILIB_USEDEP}] + media-libs/gst-plugins-base:1.0[${MULTILIB_USEDEP}] + media-libs/gstreamer:1.0[${MULTILIB_USEDEP}] + ) + opencl? ( virtual/opencl[${MULTILIB_USEDEP}] ) + pcap? ( net-libs/libpcap[${MULTILIB_USEDEP}] ) + pulseaudio? ( media-libs/libpulse[${MULTILIB_USEDEP}] ) + scanner? ( media-gfx/sane-backends[${MULTILIB_USEDEP}] ) + smartcard? ( sys-apps/pcsc-lite[${MULTILIB_USEDEP}] ) + udev? ( virtual/libudev:=[${MULTILIB_USEDEP}] ) + unwind? ( + llvm-libunwind? ( sys-libs/llvm-libunwind[${MULTILIB_USEDEP}] ) + !llvm-libunwind? ( sys-libs/libunwind:=[${MULTILIB_USEDEP}] ) + ) + usb? ( dev-libs/libusb:1[${MULTILIB_USEDEP}] ) + wayland? ( + dev-libs/wayland[${MULTILIB_USEDEP}] + x11-libs/libxkbcommon[${MULTILIB_USEDEP}] + )" +RDEPEND=" + ${WINE_COMMON_DEPEND} + app-emulation/wine-desktop-common + dos? ( + || ( + games-emulation/dosbox + games-emulation/dosbox-staging + ) + ) + gecko? ( + app-emulation/wine-gecko:${WINE_GECKO}[${MULTILIB_USEDEP}] + wow64? ( app-emulation/wine-gecko[abi_x86_32] ) + ) + gstreamer? ( media-plugins/gst-plugins-meta:1.0[${MULTILIB_USEDEP}] ) + mono? ( app-emulation/wine-mono:${WINE_MONO} ) + perl? ( + dev-lang/perl + dev-perl/XML-LibXML + ) + samba? ( net-fs/samba[winbind] ) + selinux? ( sec-policy/selinux-wine ) + udisks? ( sys-fs/udisks:2 )" +DEPEND=" + ${WINE_COMMON_DEPEND} + sys-kernel/linux-headers + X? ( x11-base/xorg-proto )" +# gitapply.sh prefers git but can fallback to patch+extras +BDEPEND=" + ${PYTHON_DEPS} + || ( + dev-vcs/git + ( + sys-apps/gawk + sys-apps/util-linux + ) + ) + || ( + sys-devel/binutils + sys-devel/lld + ) + dev-lang/perl + sys-devel/bison + sys-devel/flex + virtual/pkgconfig + mingw? ( !crossdev-mingw? ( + >=dev-util/mingw64-toolchain-10.0.0_p1-r2[${MULTILIB_USEDEP}] + wow64? ( dev-util/mingw64-toolchain[abi_x86_32] ) + ) ) + nls? ( sys-devel/gettext ) + wayland? ( dev-util/wayland-scanner )" +IDEPEND=">=app-eselect/eselect-wine-2" + +QA_CONFIG_IMPL_DECL_SKIP=( + __clear_cache # unused on amd64+x86 (bug #900334) + res_getservers # false positive +) +QA_FLAGS_IGNORED="usr/lib/.*/wine/.*-unix/odbc32.so" # has no compiled objects +QA_TEXTRELS="usr/lib/*/wine/i386-unix/*.so" # uses -fno-PIC -Wl,-z,notext + +PATCHES=( + "${FILESDIR}"/${PN}-7.17-noexecstack.patch + "${FILESDIR}"/${PN}-7.20-unwind.patch + "${FILESDIR}"/${PN}-8.13-rpath.patch +) + +pkg_pretend() { + [[ ${MERGE_TYPE} == binary ]] && return + + if use crossdev-mingw && [[ ! -v MINGW_BYPASS ]]; then + local mingw=-w64-mingw32 + for mingw in $(usev abi_x86_64 x86_64${mingw}) \ + $(use abi_x86_32 || use wow64 && echo i686${mingw}); do + if ! type -P ${mingw}-gcc >/dev/null; then + eerror "With USE=crossdev-mingw, you must prepare the MinGW toolchain" + eerror "yourself by installing sys-devel/crossdev then running:" + eerror + eerror " crossdev --target ${mingw}" + eerror + eerror "For more information, please see: https://wiki.gentoo.org/wiki/Mingw" + die "USE=crossdev-mingw is enabled, but ${mingw}-gcc was not found" + fi + done + fi +} + +src_unpack() { + if [[ ${PV} == *9999 ]]; then + EGIT_CHECKOUT_DIR=${WORKDIR}/${P} + git-r3_src_unpack + + # hack: use subshell to preserve state (including what git-r3 unpack + # sets) for smart-live-rebuild as this is not the repo to look at + ( + EGIT_COMMIT=$(<"${EGIT_CHECKOUT_DIR}"/staging/upstream-commit) || die + EGIT_REPO_URI=${WINE_EGIT_REPO_URI} + EGIT_CHECKOUT_DIR=${S} + einfo "Fetching Wine commit matching the current patchset by default (${EGIT_COMMIT})" + git-r3_src_unpack + ) + else + default + fi +} + +src_prepare() { + local patchinstallargs=( + --all + --no-autoconf + ${MY_WINE_STAGING_CONF} + ) + + edo "${PYTHON}" ../${P}/staging/patchinstall.py "${patchinstallargs[@]}" + + # sanity check, bumping these has a history of oversights + local geckomono=$(sed -En '/^#define (GECKO|MONO)_VER/{s/[^0-9.]//gp}' \ + dlls/appwiz.cpl/addons.c || die) + if [[ ${WINE_GECKO}$'\n'${WINE_MONO} != "${geckomono}" ]]; then + local gmfatal= + [[ ${PV} == *9999 ]] && gmfatal=nonfatal + ${gmfatal} die -n "gecko/mono mismatch in ebuild, has: " ${geckomono} " (please file a bug)" + fi + + default + + if tc-is-clang; then + if use mingw; then + # -mabi=ms was ignored by /dev/null) != @(LLD|GNU\ ld)* ]] + then + has_version -b sys-devel/binutils && + append-ldflags -fuse-ld=bfd || + append-ldflags -fuse-ld=lld + strip-unsupported-flags + fi + + if use mingw; then + use crossdev-mingw || PATH=${BROOT}/usr/lib/mingw64-toolchain/bin:${PATH} + + filter-flags -fno-plt # build failure + + # CROSSCC was formerly recognized by wine, thus been using similar + # variables (subject to change, esp. if ever make a mingw.eclass). + local mingwcc_amd64=${CROSSCC:-${CROSSCC_amd64:-x86_64-w64-mingw32-gcc}} + local mingwcc_x86=${CROSSCC:-${CROSSCC_x86:-i686-w64-mingw32-gcc}} + local -n mingwcc=mingwcc_$(usex abi_x86_64 amd64 x86) + + conf+=( + ac_cv_prog_x86_64_CC="${mingwcc_amd64}" + ac_cv_prog_i386_CC="${mingwcc_x86}" + + CROSSCFLAGS="${CROSSCFLAGS:-$( + filter-flags '-fstack-protector*' #870136 + filter-flags '-mfunction-return=thunk*' #878849 + CC=${mingwcc} test-flags-CC ${CFLAGS:--O2} + )}" + + CROSSLDFLAGS="${CROSSLDFLAGS:-$( + filter-flags '-fuse-ld=*' + + CC=${mingwcc} test-flags-CCLD ${LDFLAGS} + )}" + ) + fi + + # order matters with multilib: configure+compile 64->32, install 32->64 + local -i bits + for bits in $(usev abi_x86_64 64) $(usev abi_x86_32 32); do + ( + einfo "Configuring ${PN} for ${bits}bits in ${WORKDIR}/build${bits} ..." + + mkdir ../build${bits} || die + cd ../build${bits} || die + + if (( bits == 64 )); then + conf+=( --enable-win64 ) + elif use amd64; then + conf+=( + $(usev abi_x86_64 --with-wine64=../build64) + TARGETFLAGS=-m32 # for widl + ) + # _setup is optional, but use over Wine's auto-detect (+#472038) + multilib_toolchain_setup x86 + fi + + ECONF_SOURCE=${S} econf "${conf[@]}" + ) + done +} + +src_compile() { + use abi_x86_64 && emake -C ../build64 # do first + use abi_x86_32 && emake -C ../build32 +} + +src_install() { + use abi_x86_32 && emake DESTDIR="${D}" -C ../build32 install + use abi_x86_64 && emake DESTDIR="${D}" -C ../build64 install # do last + + # Ensure both wine64 and wine are available if USE=abi_x86_64 (wow64, + # -abi_x86_32, and/or EXTRA_ECONF could cause varying scenarios where + # one or the other could be missing and that is unexpected for users + # and some tools like winetricks) + if use abi_x86_64; then + if [[ -e ${ED}${WINE_PREFIX}/bin/wine64 && ! -e ${ED}${WINE_PREFIX}/bin/wine ]]; then + dosym wine64 ${WINE_PREFIX}/bin/wine + dosym wine64-preloader ${WINE_PREFIX}/bin/wine-preloader + + # also install wine(1) man pages (incl. translations) + local man + for man in ../build64/loader/wine.*man; do + : "${man##*/wine}" + : "${_%.*}" + insinto ${WINE_DATADIR}/man/${_:+${_#.}/}man1 + newins ${man} wine.1 + done + elif [[ ! -e ${ED}${WINE_PREFIX}/bin/wine64 && -e ${ED}${WINE_PREFIX}/bin/wine ]]; then + dosym wine ${WINE_PREFIX}/bin/wine64 + dosym wine-preloader ${WINE_PREFIX}/bin/wine64-preloader + fi + fi + + use perl || rm "${ED}"${WINE_DATADIR}/man/man1/wine{dump,maker}.1 \ + "${ED}"${WINE_PREFIX}/bin/{function_grep.pl,wine{dump,maker}} || die + + # create variant wrappers for eselect-wine + local bin + for bin in "${ED}"${WINE_PREFIX}/bin/*; do + make_wrapper "${bin##*/}-${P#wine-}" "${bin#"${ED}"}" + done + + if use mingw; then + # don't let portage try to strip PE files with the wrong + # strip executable and instead handle it here (saves ~120MB) + dostrip -x ${WINE_PREFIX}/wine/{i386,x86_64}-windows + + if use strip; then + ebegin "Stripping Windows (PE) binaries" + find "${ED}"${WINE_PREFIX}/wine/*-windows -regex '.*\.\(a\|dll\|exe\)' \ + -exec $(usex abi_x86_64 x86_64 i686)-w64-mingw32-strip --strip-unneeded {} + + eend ${?} || die + fi + fi + + dodoc ANNOUNCE AUTHORS README* documentation/README* +} + +pkg_postinst() { + if use !abi_x86_32 && use !wow64; then + ewarn "32bit support is disabled. While 64bit applications themselves will" + ewarn "work, be warned that it is not unusual that installers or other helpers" + ewarn "will attempt to use 32bit and fail. If do not want full USE=abi_x86_32," + ewarn "note the experimental/WIP USE=wow64 can allow 32bit without multilib." + elif use abi_x86_32 && { use opengl || use vulkan; } && + has_version 'x11-drivers/nvidia-drivers[-abi_x86_32]' + then + ewarn "x11-drivers/nvidia-drivers is installed but is built without" + ewarn "USE=abi_x86_32 (ABI_X86=32), hardware acceleration with 32bit" + ewarn "applications under ${PN} will likely not be usable." + fi + + eselect wine update --if-unset || die +} + +pkg_postrm() { + eselect wine update --if-unset || die +}