[PATCH 4/4] gdi32: Implement D3DKMTQueryVideoMemoryInfo().

Zhiyi Zhang zzhang at codeweavers.com
Tue May 17 01:18:12 CDT 2022


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/gdi32/gdi32.spec          |  1 +
 dlls/gdi32/tests/driver.c      |  2 +-
 dlls/win32u/dibdrv/dc.c        |  2 ++
 dlls/win32u/driver.c           | 37 +++++++++++++++++++++
 dlls/win32u/emfdrv.c           |  1 +
 dlls/win32u/font.c             |  1 +
 dlls/win32u/gdiobj.c           |  1 +
 dlls/win32u/path.c             |  1 +
 dlls/win32u/win32u.spec        |  2 +-
 dlls/win32u/win32u_private.h   |  1 +
 dlls/win32u/wrappers.c         |  6 ++++
 dlls/wineps.drv/init.c         |  1 +
 dlls/winex11.drv/init.c        |  1 +
 dlls/winex11.drv/x11drv.h      |  1 +
 dlls/winex11.drv/x11drv_main.c | 59 ++++++++++++++++++++++++++++++++++
 dlls/winex11.drv/xrender.c     |  1 +
 include/ntgdi.h                |  1 +
 include/wine/gdi_driver.h      |  1 +
 18 files changed, 118 insertions(+), 2 deletions(-)

diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec
index d0ffe827539..d6a0ad90e1e 100644
--- a/dlls/gdi32/gdi32.spec
+++ b/dlls/gdi32/gdi32.spec
@@ -85,6 +85,7 @@
 @ stdcall D3DKMTOpenAdapterFromHdc(ptr) win32u.NtGdiDdDDIOpenAdapterFromHdc
 @ stdcall D3DKMTOpenAdapterFromLuid(ptr) win32u.NtGdiDdDDIOpenAdapterFromLuid
 @ stdcall D3DKMTQueryStatistics(ptr) win32u.NtGdiDdDDIQueryStatistics
+@ stdcall D3DKMTQueryVideoMemoryInfo(ptr) win32u.NtGdiDdDDIQueryVideoMemoryInfo
 @ stdcall D3DKMTSetQueuedLimit(ptr) win32u.NtGdiDdDDISetQueuedLimit
 @ stdcall D3DKMTSetVidPnSourceOwner(ptr) win32u.NtGdiDdDDISetVidPnSourceOwner
 @ stdcall DPtoLP(long ptr long)
diff --git a/dlls/gdi32/tests/driver.c b/dlls/gdi32/tests/driver.c
index 5117d34908d..79eedda1241 100644
--- a/dlls/gdi32/tests/driver.c
+++ b/dlls/gdi32/tests/driver.c
@@ -918,7 +918,7 @@ static void test_D3DKMTQueryVideoMemoryInfo(void)
 
     if (!pD3DKMTQueryVideoMemoryInfo)
     {
-        skip("D3DKMTQueryVideoMemoryInfo() is unavailable.\n");
+        win_skip("D3DKMTQueryVideoMemoryInfo() is unavailable.\n");
         return;
     }
 
diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c
index caa3cc92587..7c60466d9ee 100644
--- a/dlls/win32u/dibdrv/dc.c
+++ b/dlls/win32u/dibdrv/dc.c
@@ -711,6 +711,7 @@ const struct gdi_dc_funcs dib_driver =
     NULL,                               /* pD3DKMTCheckVidPnExclusiveOwnership */
     NULL,                               /* pD3DKMTCloseAdapter */
     NULL,                               /* pD3DKMTOpenAdapterFromLuid */
+    NULL,                               /* pD3DKMTQueryVideoMemoryInfo */
     NULL,                               /* pD3DKMTSetVidPnSourceOwner */
     GDI_PRIORITY_DIB_DRV                /* priority */
 };
@@ -1267,6 +1268,7 @@ static const struct gdi_dc_funcs window_driver =
     NULL,                               /* pD3DKMTCheckVidPnExclusiveOwnership */
     NULL,                               /* pD3DKMTCloseAdapter */
     NULL,                               /* pD3DKMTOpenAdapterFromLuid */
+    NULL,                               /* pD3DKMTQueryVideoMemoryInfo */
     NULL,                               /* pD3DKMTSetVidPnSourceOwner */
     GDI_PRIORITY_DIB_DRV + 10           /* priority */
 };
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c
index 31383330bc4..9185069208a 100644
--- a/dlls/win32u/driver.c
+++ b/dlls/win32u/driver.c
@@ -560,6 +560,11 @@ static NTSTATUS CDECL nulldrv_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROML
     return STATUS_PROCEDURE_NOT_FOUND;
 }
 
+static NTSTATUS CDECL nulldrv_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc )
+{
+    return STATUS_PROCEDURE_NOT_FOUND;
+}
+
 static NTSTATUS CDECL nulldrv_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc )
 {
     return STATUS_PROCEDURE_NOT_FOUND;
@@ -659,6 +664,7 @@ const struct gdi_dc_funcs null_driver =
     nulldrv_D3DKMTCheckVidPnExclusiveOwnership, /* pD3DKMTCheckVidPnExclusiveOwnership */
     nulldrv_D3DKMTCloseAdapter,         /* pD3DKMTCloseAdapter */
     nulldrv_D3DKMTOpenAdapterFromLuid,  /* pD3DKMTOpenAdapterFromLuid */
+    nulldrv_D3DKMTQueryVideoMemoryInfo, /* pD3DKMTQueryVideoMemoryInfo */
     nulldrv_D3DKMTSetVidPnSourceOwner,  /* pD3DKMTSetVidPnSourceOwner */
 
     GDI_PRIORITY_NULL_DRV               /* priority */
@@ -1475,6 +1481,37 @@ NTSTATUS WINAPI NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS *stats )
     return STATUS_SUCCESS;
 }
 
+/******************************************************************************
+ *           NtGdiDdDDIQueryVideoMemoryInfo    (win32u.@)
+ */
+NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc )
+{
+    OBJECT_BASIC_INFORMATION info;
+    NTSTATUS status;
+
+    TRACE("(%p)\n", desc);
+
+    if (!desc || !desc->hAdapter ||
+        (desc->MemorySegmentGroup != D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL &&
+         desc->MemorySegmentGroup != D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL))
+        return STATUS_INVALID_PARAMETER;
+
+    /* FIXME: Wine currently doesn't support linked adapters */
+    if (desc->PhysicalAdapterIndex > 0)
+        return STATUS_INVALID_PARAMETER;
+
+    status = NtQueryObject(desc->hProcess ? desc->hProcess : GetCurrentProcess(),
+                           ObjectBasicInformation, &info, sizeof(info), NULL);
+    if (status != STATUS_SUCCESS)
+        return status;
+    if (!(info.GrantedAccess & PROCESS_QUERY_INFORMATION))
+        return STATUS_ACCESS_DENIED;
+
+    if (!get_display_driver()->pD3DKMTQueryVideoMemoryInfo)
+        return STATUS_PROCEDURE_NOT_FOUND;
+    return get_display_driver()->pD3DKMTQueryVideoMemoryInfo(desc);
+}
+
 /******************************************************************************
  *           NtGdiDdDDISetQueuedLimit    (win32u.@)
  */
diff --git a/dlls/win32u/emfdrv.c b/dlls/win32u/emfdrv.c
index fafceb71438..848a5bbaa4b 100644
--- a/dlls/win32u/emfdrv.c
+++ b/dlls/win32u/emfdrv.c
@@ -525,6 +525,7 @@ static const struct gdi_dc_funcs emfdrv_driver =
     NULL,                            /* pD3DKMTCheckVidPnExclusiveOwnership */
     NULL,                            /* pD3DKMTCloseAdapter */
     NULL,                            /* pD3DKMTOpenAdapterFromLuid */
+    NULL,                            /* pD3DKMTQueryVideoMemoryInfo */
     NULL,                            /* pD3DKMTSetVidPnSourceOwner */
     GDI_PRIORITY_GRAPHICS_DRV        /* priority */
 };
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c
index 6e0207b7bb6..571379976a5 100644
--- a/dlls/win32u/font.c
+++ b/dlls/win32u/font.c
@@ -4270,6 +4270,7 @@ const struct gdi_dc_funcs font_driver =
     NULL,                           /* pD3DKMTCheckVidPnExclusiveOwnership */
     NULL,                           /* pD3DKMTCloseAdapter */
     NULL,                           /* pD3DKMTOpenAdapterFromLuid */
+    NULL,                           /* pD3DKMTQueryVideoMemoryInfo */
     NULL,                           /* pD3DKMTSetVidPnSourceOwner */
     GDI_PRIORITY_FONT_DRV           /* priority */
 };
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c
index 8d19e231f46..96d52e4d38e 100644
--- a/dlls/win32u/gdiobj.c
+++ b/dlls/win32u/gdiobj.c
@@ -1053,6 +1053,7 @@ static struct unix_funcs unix_funcs =
     NtGdiDdDDIEscape,
     NtGdiDdDDIOpenAdapterFromDeviceName,
     NtGdiDdDDIOpenAdapterFromLuid,
+    NtGdiDdDDIQueryVideoMemoryInfo,
     NtGdiDdDDISetVidPnSourceOwner,
     NtGdiDeleteObjectApp,
     NtGdiDoPalette,
diff --git a/dlls/win32u/path.c b/dlls/win32u/path.c
index 00a1f58e969..0032ee1a5ab 100644
--- a/dlls/win32u/path.c
+++ b/dlls/win32u/path.c
@@ -2122,6 +2122,7 @@ const struct gdi_dc_funcs path_driver =
     NULL,                               /* pD3DKMTCheckVidPnExclusiveOwnership */
     NULL,                               /* pD3DKMTCloseAdapter */
     NULL,                               /* pD3DKMTOpenAdapterFromLuid */
+    NULL,                               /* pD3DKMTQueryVideoMemoryInfo */
     NULL,                               /* pD3DKMTSetVidPnSourceOwner */
     GDI_PRIORITY_PATH_DRV               /* priority */
 };
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index 2f0682fe915..1c3cbc59dc2 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -307,7 +307,7 @@
 @ stub NtGdiDdDDIQueryResourceInfoFromNtHandle
 @ stdcall -syscall NtGdiDdDDIQueryStatistics(ptr)
 @ stub NtGdiDdDDIQueryVidPnExclusiveOwnership
-@ stub NtGdiDdDDIQueryVideoMemoryInfo
+@ stdcall NtGdiDdDDIQueryVideoMemoryInfo(ptr)
 @ stub NtGdiDdDDIReclaimAllocations
 @ stub NtGdiDdDDIReclaimAllocations2
 @ stub NtGdiDdDDIReleaseKeyedMutex
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h
index e221dff4d01..02784df64f8 100644
--- a/dlls/win32u/win32u_private.h
+++ b/dlls/win32u/win32u_private.h
@@ -65,6 +65,7 @@ struct unix_funcs
     NTSTATUS (WINAPI *pNtGdiDdDDIEscape)( const D3DKMT_ESCAPE *desc );
     NTSTATUS (WINAPI *pNtGdiDdDDIOpenAdapterFromDeviceName)( D3DKMT_OPENADAPTERFROMDEVICENAME *desc );
     NTSTATUS (WINAPI *pNtGdiDdDDIOpenAdapterFromLuid)( D3DKMT_OPENADAPTERFROMLUID *desc );
+    NTSTATUS (WINAPI *pNtGdiDdDDIQueryVideoMemoryInfo)( D3DKMT_QUERYVIDEOMEMORYINFO *desc );
     NTSTATUS (WINAPI *pNtGdiDdDDISetVidPnSourceOwner)( const D3DKMT_SETVIDPNSOURCEOWNER *desc );
     BOOL     (WINAPI *pNtGdiDeleteObjectApp)( HGDIOBJ obj );
     LONG     (WINAPI *pNtGdiDoPalette)( HGDIOBJ handle, WORD start, WORD count, void *entries,
diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c
index 9438660d3ec..4e750e5aea2 100644
--- a/dlls/win32u/wrappers.c
+++ b/dlls/win32u/wrappers.c
@@ -713,6 +713,12 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc
     return unix_funcs->pNtGdiDdDDIOpenAdapterFromLuid( desc );
 }
 
+NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc )
+{
+    if (!unix_funcs) return STATUS_NOT_SUPPORTED;
+    return unix_funcs->pNtGdiDdDDIQueryVideoMemoryInfo( desc );
+}
+
 NTSTATUS WINAPI NtGdiDdDDISetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc )
 {
     if (!unix_funcs) return STATUS_NOT_SUPPORTED;
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c
index d02c2cfc4c2..0d4467b6964 100644
--- a/dlls/wineps.drv/init.c
+++ b/dlls/wineps.drv/init.c
@@ -859,6 +859,7 @@ static const struct gdi_dc_funcs psdrv_funcs =
     NULL,                               /* pD3DKMTCheckVidPnExclusiveOwnership */
     NULL,                               /* pD3DKMTCloseAdapter */
     NULL,                               /* pD3DKMTOpenAdapterFromLuid */
+    NULL,                               /* pD3DKMTQueryVideoMemoryInfo */
     NULL,                               /* pD3DKMTSetVidPnSourceOwner */
     GDI_PRIORITY_GRAPHICS_DRV           /* priority */
 };
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index bff2d9db4c5..fc190805401 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -388,6 +388,7 @@ static const struct user_driver_funcs x11drv_funcs =
     .dc_funcs.pD3DKMTCheckVidPnExclusiveOwnership = X11DRV_D3DKMTCheckVidPnExclusiveOwnership,
     .dc_funcs.pD3DKMTCloseAdapter = X11DRV_D3DKMTCloseAdapter,
     .dc_funcs.pD3DKMTOpenAdapterFromLuid = X11DRV_D3DKMTOpenAdapterFromLuid,
+    .dc_funcs.pD3DKMTQueryVideoMemoryInfo = X11DRV_D3DKMTQueryVideoMemoryInfo,
     .dc_funcs.pD3DKMTSetVidPnSourceOwner = X11DRV_D3DKMTSetVidPnSourceOwner,
     .dc_funcs.priority = GDI_PRIORITY_GRAPHICS_DRV,
 
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index a4f93150ed9..9a775215321 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -157,6 +157,7 @@ extern BOOL CDECL X11DRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT b
 extern NTSTATUS CDECL X11DRV_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *desc ) DECLSPEC_HIDDEN;
 extern NTSTATUS CDECL X11DRV_D3DKMTCloseAdapter( const D3DKMT_CLOSEADAPTER *desc ) DECLSPEC_HIDDEN;
 extern NTSTATUS CDECL X11DRV_D3DKMTOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc ) DECLSPEC_HIDDEN;
+extern NTSTATUS CDECL X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc ) DECLSPEC_HIDDEN;
 extern NTSTATUS CDECL X11DRV_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc ) DECLSPEC_HIDDEN;
 extern BOOL CDECL X11DRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
 extern BOOL CDECL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ) DECLSPEC_HIDDEN;
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 77f1ec87a31..40d0e750d1b 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -1228,6 +1228,65 @@ done:
     return status;
 }
 
+NTSTATUS CDECL X11DRV_D3DKMTQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc )
+{
+    const struct vulkan_funcs *vulkan_funcs = get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION);
+    PFN_vkGetPhysicalDeviceMemoryProperties2KHR pvkGetPhysicalDeviceMemoryProperties2KHR;
+    VkPhysicalDeviceMemoryBudgetPropertiesEXT budget;
+    VkPhysicalDeviceMemoryProperties2 properties2;
+    NTSTATUS status = STATUS_INVALID_PARAMETER;
+    struct x11_d3dkmt_adapter *adapter;
+    unsigned int i;
+
+    desc->Budget = 0;
+    desc->CurrentUsage = 0;
+    desc->CurrentReservation = 0;
+    desc->AvailableForReservation = 0;
+
+    if (!vulkan_funcs)
+    {
+        WARN("Vulkan is unavailable.\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    pthread_mutex_lock(&d3dkmt_mutex);
+    LIST_FOR_EACH_ENTRY(adapter, &x11_d3dkmt_adapters, struct x11_d3dkmt_adapter, entry)
+    {
+        if (adapter->handle != desc->hAdapter)
+            continue;
+
+        if (!(pvkGetPhysicalDeviceMemoryProperties2KHR = (void *)vulkan_funcs->p_vkGetInstanceProcAddr(adapter->vk_instance, "vkGetPhysicalDeviceMemoryProperties2KHR")))
+        {
+            WARN("Failed to load vkGetPhysicalDeviceMemoryProperties2KHR.\n");
+            status = STATUS_UNSUCCESSFUL;
+            goto done;
+        }
+
+        memset(&budget, 0, sizeof(budget));
+        budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
+        properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
+        properties2.pNext = &budget;
+        pvkGetPhysicalDeviceMemoryProperties2KHR(adapter->vk_device, &properties2);
+        for (i = 0; i < properties2.memoryProperties.memoryHeapCount; ++i)
+        {
+            if ((desc->MemorySegmentGroup == D3DKMT_MEMORY_SEGMENT_GROUP_LOCAL
+                && properties2.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
+                || (desc->MemorySegmentGroup == D3DKMT_MEMORY_SEGMENT_GROUP_NON_LOCAL
+                && !(properties2.memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)))
+            {
+                desc->Budget += budget.heapBudget[i];
+                desc->CurrentUsage += budget.heapUsage[i];
+            }
+        }
+        desc->AvailableForReservation = desc->Budget / 2;
+        status = STATUS_SUCCESS;
+        break;
+    }
+done:
+    pthread_mutex_unlock(&d3dkmt_mutex);
+    return status;
+}
+
 NTSTATUS x11drv_client_func( enum x11drv_client_funcs id, const void *params, ULONG size )
 {
     void *ret_ptr;
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index 697fe0432ae..585299cba9e 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -2238,6 +2238,7 @@ static const struct gdi_dc_funcs xrender_funcs =
     NULL,                               /* pD3DKMTCheckVidPnExclusiveOwnership */
     NULL,                               /* pD3DKMTCloseAdapter */
     NULL,                               /* pD3DKMTOpenAdapterFromLuid */
+    NULL,                               /* pD3DKMTQueryVideoMemoryInfo */
     NULL,                               /* pD3DKMTSetVidPnSourceOwner */
     GDI_PRIORITY_GRAPHICS_DRV + 10      /* priority */
 };
diff --git a/include/ntgdi.h b/include/ntgdi.h
index 78d0f620be3..5a9d5a798fe 100644
--- a/include/ntgdi.h
+++ b/include/ntgdi.h
@@ -472,6 +472,7 @@ NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromHdc( D3DKMT_OPENADAPTERFROMHDC *desc );
 NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromDeviceName( D3DKMT_OPENADAPTERFROMDEVICENAME *desc );
 NTSTATUS WINAPI NtGdiDdDDIOpenAdapterFromLuid( D3DKMT_OPENADAPTERFROMLUID *desc );
 NTSTATUS WINAPI NtGdiDdDDIQueryStatistics( D3DKMT_QUERYSTATISTICS *stats );
+NTSTATUS WINAPI NtGdiDdDDIQueryVideoMemoryInfo( D3DKMT_QUERYVIDEOMEMORYINFO *desc );
 NTSTATUS WINAPI NtGdiDdDDISetQueuedLimit( D3DKMT_SETQUEUEDLIMIT *desc );
 NTSTATUS WINAPI NtGdiDdDDISetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc );
 
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index f16b1456483..82bac557c2a 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -160,6 +160,7 @@ struct gdi_dc_funcs
     NTSTATUS (CDECL *pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *);
     NTSTATUS (CDECL *pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *);
     NTSTATUS (CDECL *pD3DKMTOpenAdapterFromLuid)(D3DKMT_OPENADAPTERFROMLUID *);
+    NTSTATUS (CDECL *pD3DKMTQueryVideoMemoryInfo)(D3DKMT_QUERYVIDEOMEMORYINFO *);
     NTSTATUS (CDECL *pD3DKMTSetVidPnSourceOwner)(const D3DKMT_SETVIDPNSOURCEOWNER *);
 
     /* priority order for the driver on the stack */
-- 
2.34.1



More information about the wine-devel mailing list