[PATCH v7 1/7] winex11.drv: Add Xinerama display device handler.

Zhiyi Zhang zzhang at codeweavers.com
Tue May 28 02:19:24 CDT 2019


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 at codeweavers.com>
---
v2: Supersede 162308~162314, fix xinerama primary adapter reporting, fix registry data reinit failure.
v3: Rebase
v4: Merge patches. Rebase. Supersede 164594~164599, 164612~164613
v5: Fix explorer patch triggered user32 test failures. Supersede 165122~165128.
v6: Restructure patches. Supersede 165134~165140
v7: Supersede 165307~165313. Add mutex to avoid init race. Remove old adapter keys during reinit.
    Add fallback monitor data in explorer. Simplify code.

 dlls/winex11.drv/Makefile.in   |  1 +
 dlls/winex11.drv/display.c     | 82 ++++++++++++++++++++++++++++++++++
 dlls/winex11.drv/x11drv.h      | 15 +++++++
 dlls/winex11.drv/x11drv_main.c |  1 +
 dlls/winex11.drv/xinerama.c    |  7 +++
 5 files changed, 106 insertions(+)
 create mode 100644 dlls/winex11.drv/display.c

diff --git a/dlls/winex11.drv/Makefile.in b/dlls/winex11.drv/Makefile.in
index 747f509b44..9ca2fc6efe 100644
--- a/dlls/winex11.drv/Makefile.in
+++ b/dlls/winex11.drv/Makefile.in
@@ -9,6 +9,7 @@ C_SRCS = \
 	brush.c \
 	clipboard.c \
 	desktop.c \
+	display.c \
 	event.c \
 	graphics.c \
 	ime.c \
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
new file mode 100644
index 0000000000..a82975bfb9
--- /dev/null
+++ b/dlls/winex11.drv/display.c
@@ -0,0 +1,82 @@
+/*
+ * 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[] =
+        {'_','_','x','1','1','_','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;
+    BOOL success = FALSE;
+
+    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))
+        goto fail;
+
+    /* Avoid unnecessary reinit */
+    if (disposition != REG_CREATED_NEW_KEY)
+    {
+        success = TRUE;
+        goto fail;
+    }
+
+    TRACE("via %s\n", wine_dbgstr_a(handler.name));
+
+    success = TRUE;
+fail:
+    RegCloseKey(video_hkey);
+    ReleaseMutex(mutex);
+    CloseHandle(mutex);
+    if (!success)
+        ERR("Failed to initialize display devices\n");
+}
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index c633102a38..fbc5a104f6 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -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 */
+    CHAR name[MAX_PATH];
+
+    /* 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;
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index e67a3c05a9..69478741f1 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -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;
 }
 
diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c
index 739b139736..35dd36049b 100644
--- a/dlls/winex11.drv/xinerama.c
+++ b/dlls/winex11.drv/xinerama.c
@@ -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)" : "" );
     }
 
+    strcpy( 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) );
 }
-- 
2.20.1





More information about the wine-devel mailing list