winex11.drv: Implement X11DRV_D3DKMTSetVidPnSourceOwner.

Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Zhiyi Zhang 2019-10-22 16:39:06 +08:00 committed by Alexandre Julliard
parent 354359197b
commit e08dd25f32
4 changed files with 141 additions and 2 deletions

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}