winex11.drv: Add Xinerama display device handler.

Display device handlers are used to initialize the display device
registry data. Different handlers can be implemented according to
the defined interface, for example, via Xinerama or XRandR.
With those registry data, EnumDisplayDevices, EnumDisplayMonitors
and GetMonitorInfo can be built on top of it.

Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2019-06-10 22:07:02 +08:00 committed by Alexandre Julliard
parent 1a79d1c765
commit 52a3d5db48
6 changed files with 104 additions and 3 deletions

View File

@ -81,7 +81,7 @@ static int monitor_count = 0;
static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *device, DWORD flags)
{
char video_name[16];
char video_name[32];
char video_value[128];
char buffer[128];
int number;
@ -107,13 +107,13 @@ static void test_enumdisplaydevices_adapter(int index, const DISPLAY_DEVICEA *de
{
sprintf(video_name, "\\Device\\Video%d", index);
ls = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\VIDEO", 0, KEY_READ, &hkey);
todo_wine ok(!ls, "#%d: failed to open registry, error: %#x\n", index, ls);
ok(!ls, "#%d: failed to open registry, error: %#x\n", index, ls);
if (!ls)
{
memset(video_value, 0, sizeof(video_value));
size = sizeof(video_value);
ls = RegQueryValueExA(hkey, video_name, NULL, NULL, (unsigned char *)video_value, &size);
ok(!ls, "#%d: failed to get registry value, error: %#x\n", index, ls);
todo_wine ok(!ls, "#%d: failed to get registry value, error: %#x\n", index, ls);
RegCloseKey(hkey);
ok(!strcmp(video_value, device->DeviceKey), "#%d: wrong DeviceKey: %s\n", index, device->DeviceKey);
}

View File

@ -9,6 +9,7 @@ C_SRCS = \
brush.c \
clipboard.c \
desktop.c \
display.c \
event.c \
graphics.c \
ime.c \

View File

@ -0,0 +1,77 @@
/*
* X11DRV display device functions
*
* Copyright 2019 Zhiyi Zhang for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "wine/debug.h"
#include "x11drv.h"
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
static const WCHAR video_keyW[] = {
'H','A','R','D','W','A','R','E','\\',
'D','E','V','I','C','E','M','A','P','\\',
'V','I','D','E','O',0};
static struct x11drv_display_device_handler handler;
void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *new_handler)
{
if (new_handler->priority > handler.priority)
{
handler = *new_handler;
TRACE("Display device functions are now handled by: %s\n", handler.name);
}
}
void X11DRV_DisplayDevices_Init(void)
{
static const WCHAR init_mutexW[] = {'d','i','s','p','l','a','y','_','d','e','v','i','c','e','_','i','n','i','t',0};
HANDLE mutex;
HKEY video_hkey = NULL;
DWORD disposition = 0;
mutex = CreateMutexW(NULL, FALSE, init_mutexW);
WaitForSingleObject(mutex, INFINITE);
if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, video_keyW, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &video_hkey,
&disposition))
{
ERR("Failed to create video device key\n");
goto done;
}
/* Avoid unnecessary reinit */
if (disposition != REG_CREATED_NEW_KEY)
goto done;
TRACE("via %s\n", wine_dbgstr_a(handler.name));
done:
RegCloseKey(video_hkey);
ReleaseMutex(mutex);
CloseHandle(mutex);
}

View File

@ -665,6 +665,21 @@ struct x11drv_mode_info *X11DRV_Settings_SetHandlers(const char *name,
void X11DRV_XF86VM_Init(void) DECLSPEC_HIDDEN;
void X11DRV_XRandR_Init(void) DECLSPEC_HIDDEN;
/* X11 display device handler. Used to initialize display device registry data */
/* Required functions for display device registry initialization */
struct x11drv_display_device_handler
{
/* A name to tell what host driver is used */
const char *name;
/* Higher priority can override handlers with lower proprity */
INT priority;
};
extern void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *handler) DECLSPEC_HIDDEN;
extern void X11DRV_DisplayDevices_Init(void) DECLSPEC_HIDDEN;
/* XIM support */
extern BOOL X11DRV_InitXIM( const char *input_style ) DECLSPEC_HIDDEN;
extern XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data) DECLSPEC_HIDDEN;

View File

@ -597,6 +597,7 @@ static BOOL process_attach(void)
X11DRV_InitKeyboard( gdi_display );
if (use_xim) use_xim = X11DRV_InitXIM( input_style );
X11DRV_DisplayDevices_Init();
return TRUE;
}

View File

@ -30,6 +30,8 @@
#include "wine/library.h"
#include "x11drv.h"
#include "wine/debug.h"
#include "wine/heap.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
@ -201,6 +203,7 @@ RECT get_primary_monitor_rect(void)
void xinerama_init( unsigned int width, unsigned int height )
{
struct x11drv_display_device_handler handler;
MONITORINFOEXW *primary;
int i;
RECT rect;
@ -234,6 +237,10 @@ void xinerama_init( unsigned int width, unsigned int height )
(monitors[i].dwFlags & MONITORINFOF_PRIMARY) ? " (primary)" : "" );
}
handler.name = "Xinerama";
handler.priority = 100;
X11DRV_DisplayDevices_SetHandler( &handler );
TRACE( "virtual size: %s primary: %s\n",
wine_dbgstr_rect(&virtual_screen_rect), wine_dbgstr_rect(&primary->rcMonitor) );
}