[PATCH v3 resend 3/4] winex11.drv: Implement X11DRV_D3DKMTSetVidPnSourceOwner.
Zhiyi Zhang
zzhang at codeweavers.com
Tue Oct 22 03:39:06 CDT 2019
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
dlls/gdi32/tests/driver.c | 2 +-
dlls/winex11.drv/init.c | 2 +-
dlls/winex11.drv/x11drv.h | 1 +
dlls/winex11.drv/x11drv_main.c | 138 +++++++++++++++++++++++++++++++++
4 files changed, 141 insertions(+), 2 deletions(-)
diff --git a/dlls/gdi32/tests/driver.c b/dlls/gdi32/tests/driver.c
index b5f6f75a83..2ea43e3025 100644
--- a/dlls/gdi32/tests/driver.c
+++ b/dlls/gdi32/tests/driver.c
@@ -600,7 +600,7 @@ static void test_D3DKMTSetVidPnSourceOwner(void)
if (!pD3DKMTSetVidPnSourceOwner || pD3DKMTSetVidPnSourceOwner(&set_owner_desc) == STATUS_PROCEDURE_NOT_FOUND)
{
- skip("D3DKMTSetVidPnSourceOwner() is unavailable.\n");
+ win_skip("D3DKMTSetVidPnSourceOwner() is unavailable.\n");
return;
}
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index 0040dbb430..a833b3c208 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -472,7 +472,7 @@ static const struct gdi_dc_funcs x11drv_funcs =
X11DRV_UnrealizePalette, /* pUnrealizePalette */
NULL, /* pWidenPath */
NULL, /* pD3DKMTCheckVidPnExclusiveOwnership */
- NULL, /* pD3DKMTSetVidPnSourceOwner */
+ X11DRV_D3DKMTSetVidPnSourceOwner, /* pD3DKMTSetVidPnSourceOwner */
X11DRV_wine_get_wgl_driver, /* wine_get_wgl_driver */
X11DRV_wine_get_vulkan_driver, /* wine_get_vulkan_driver */
GDI_PRIORITY_GRAPHICS_DRV /* priority */
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 135faa8989..8930690f45 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -149,6 +149,7 @@ extern BOOL CDECL X11DRV_Arc( PHYSDEV dev, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
extern BOOL CDECL X11DRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend ) 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 INT CDECL X11DRV_EnumICMProfiles( PHYSDEV dev, ICMENUMPROCW proc, LPARAM lparam ) 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 21807af3f1..ac5ba66324 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -42,6 +42,8 @@
#include <X11/extensions/Xrender.h>
#endif
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
@@ -52,6 +54,8 @@
#include "wine/unicode.h"
#include "wine/debug.h"
#include "wine/library.h"
+#include "wine/list.h"
+#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
WINE_DECLARE_DEBUG_CHANNEL(synchronous);
@@ -96,6 +100,25 @@ static int (*old_error_handler)( Display *, XErrorEvent * );
static BOOL use_xim = TRUE;
static char input_style[20];
+static CRITICAL_SECTION x11drv_section;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+ 0, 0, &x11drv_section,
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": x11drv_section") }
+};
+static CRITICAL_SECTION x11drv_section = { &critsect_debug, -1, 0, 0, 0, 0 };
+
+struct d3dkmt_vidpn_source
+{
+ D3DKMT_VIDPNSOURCEOWNER_TYPE type; /* VidPN source owner type */
+ D3DDDI_VIDEO_PRESENT_SOURCE_ID id; /* VidPN present source id */
+ D3DKMT_HANDLE device; /* Kernel mode device context */
+ struct list entry; /* List entry */
+};
+
+static struct list d3dkmt_vidpn_sources = LIST_INIT( d3dkmt_vidpn_sources ); /* VidPN source information list */
+
#define IS_OPTION_TRUE(ch) \
((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
#define IS_OPTION_FALSE(ch) \
@@ -739,3 +762,118 @@ BOOL CDECL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_p
}
return FALSE; /* let user32 handle it */
}
+
+/**********************************************************************
+ * X11DRV_D3DKMTSetVidPnSourceOwner
+ */
+NTSTATUS CDECL X11DRV_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc )
+{
+ struct d3dkmt_vidpn_source *source, *source2;
+ NTSTATUS status = STATUS_SUCCESS;
+ BOOL found;
+ UINT i;
+
+ TRACE("(%p)\n", desc);
+
+ EnterCriticalSection( &x11drv_section );
+
+ /* Check parameters */
+ for (i = 0; i < desc->VidPnSourceCount; ++i)
+ {
+ LIST_FOR_EACH_ENTRY( source, &d3dkmt_vidpn_sources, struct d3dkmt_vidpn_source, entry )
+ {
+ if (source->id == desc->pVidPnSourceId[i])
+ {
+ /* Same device */
+ if (source->device == desc->hDevice)
+ {
+ if ((source->type == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
+ && (desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_SHARED
+ || desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_EMULATED))
+ || (source->type == D3DKMT_VIDPNSOURCEOWNER_EMULATED
+ && desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE))
+ {
+ status = STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+ }
+ /* Different devices */
+ else
+ {
+ if ((source->type == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
+ || source->type == D3DKMT_VIDPNSOURCEOWNER_EMULATED)
+ && (desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
+ || desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_EMULATED))
+ {
+ status = STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE;
+ goto done;
+ }
+ }
+ }
+ }
+
+ /* On Windows, it seems that all video present sources are owned by DMM clients, so any attempt to set
+ * D3DKMT_VIDPNSOURCEOWNER_SHARED come back STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE */
+ if (desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_SHARED)
+ {
+ status = STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE;
+ goto done;
+ }
+
+ /* FIXME: D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVEGDI unsupported */
+ if (desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVEGDI || desc->pType[i] > D3DKMT_VIDPNSOURCEOWNER_EMULATED)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+ }
+
+ /* Remove owner */
+ if (!desc->VidPnSourceCount && !desc->pType && !desc->pVidPnSourceId)
+ {
+ LIST_FOR_EACH_ENTRY_SAFE( source, source2, &d3dkmt_vidpn_sources, struct d3dkmt_vidpn_source, entry )
+ {
+ if (source->device == desc->hDevice)
+ {
+ list_remove( &source->entry );
+ heap_free( source );
+ }
+ }
+ goto done;
+ }
+
+ /* Add owner */
+ for (i = 0; i < desc->VidPnSourceCount; ++i)
+ {
+ found = FALSE;
+ LIST_FOR_EACH_ENTRY( source, &d3dkmt_vidpn_sources, struct d3dkmt_vidpn_source, entry )
+ {
+ if (source->device == desc->hDevice && source->id == desc->pVidPnSourceId[i])
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (found)
+ source->type = desc->pType[i];
+ else
+ {
+ source = heap_alloc( sizeof( *source ) );
+ if (!source)
+ {
+ status = STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ source->id = desc->pVidPnSourceId[i];
+ source->type = desc->pType[i];
+ source->device = desc->hDevice;
+ list_add_tail( &d3dkmt_vidpn_sources, &source->entry );
+ }
+ }
+
+done:
+ LeaveCriticalSection( &x11drv_section );
+ return status;
+}
--
2.23.0
More information about the wine-devel
mailing list