[PATCH v2 2/3] winex11.drv: Use generic EnumDisplayMonitors.

Huw Davies huw at codeweavers.com
Fri Jun 21 03:59:15 CDT 2019


From: Zhiyi Zhang <zzhang at codeweavers.com>

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/user32/driver.c              | 10 -------
 dlls/user32/sysparams.c           | 48 +++++++++++++++++++++++++++++++
 dlls/user32/user_private.h        |  2 ++
 dlls/winex11.drv/display.c        |  5 ++++
 dlls/winex11.drv/winex11.drv.spec |  1 -
 dlls/winex11.drv/x11drv.h         |  2 ++
 dlls/winex11.drv/xinerama.c       | 15 +---------
 7 files changed, 58 insertions(+), 25 deletions(-)

diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index 5b2929245c..bf600708ed 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -354,16 +354,6 @@ static LONG CDECL nulldrv_ChangeDisplaySettingsEx( LPCWSTR name, LPDEVMODEW mode
     return DISP_CHANGE_FAILED;
 }
 
-static BOOL CDECL nulldrv_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
-{
-    RECT r = {0, 0, 640, 480};
-
-    TRACE("(%p, %p, %p, 0x%lx)\n", hdc, rect, proc, lp);
-
-    proc(NULLDRV_DEFAULT_HMONITOR, hdc, &r, lp);
-    return TRUE;
-}
-
 static BOOL CDECL nulldrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags )
 {
     return FALSE;
diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c
index 63fea14c2a..9f72d2725f 100644
--- a/dlls/user32/sysparams.c
+++ b/dlls/user32/sysparams.c
@@ -251,6 +251,9 @@ static const WCHAR CSrgb[] = {'%','u',' ','%','u',' ','%','u',0};
 
 /* Wine specific monitor properties */
 DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3);
+
+#define NULLDRV_DEFAULT_HMONITOR ((HMONITOR)(UINT_PTR)(0x10000 + 1))
 
 /* Strings for monitor functions */
 static const WCHAR DEFAULT_ADAPTER_NAME[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
@@ -3797,6 +3800,51 @@ static BOOL CALLBACK enum_mon_callback( HMONITOR monitor, HDC hdc, LPRECT rect,
 #endif
 }
 
+BOOL CDECL nulldrv_EnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc, LPARAM lp )
+{
+    SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+    BOOL success = FALSE;
+    HDEVINFO devinfo;
+    RECT monitor_rect;
+    DWORD state_flags;
+    DWORD type;
+    DWORD i = 0;
+
+    TRACE("(%p, %p, %p, 0x%lx)\n", hdc, rect, proc, lp);
+
+    /* Use SetupAPI to get monitors */
+    devinfo = SetupDiGetClassDevsW( &GUID_DEVCLASS_MONITOR, NULL, NULL, 0 );
+    while (SetupDiEnumDeviceInfo( devinfo, i++, &device_data ))
+    {
+        /* Inactive monitors don't get enumerated */
+        if (!SetupDiGetDevicePropertyW( devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, &type,
+                                        (BYTE *)&state_flags, sizeof(state_flags), NULL, 0 )
+            || !(state_flags & DISPLAY_DEVICE_ACTIVE))
+            continue;
+
+        if (SetupDiGetDevicePropertyW( devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, &type,
+                                       (BYTE *)&monitor_rect, sizeof(monitor_rect), NULL, 0) )
+        {
+            if (!proc( (HMONITOR)(UINT_PTR)i, hdc, &monitor_rect, lp ))
+            {
+                SetupDiDestroyDeviceInfoList( devinfo );
+                return FALSE;
+            }
+            success = TRUE;
+        }
+    }
+    SetupDiDestroyDeviceInfoList( devinfo );
+
+    /* Fallback to report one monitor if using SetupAPI failed */
+    if (!success)
+    {
+        RECT default_rect = {0, 0, 640, 480};
+        if (!proc( NULLDRV_DEFAULT_HMONITOR, hdc, &default_rect, lp ))
+            return FALSE;
+    }
+    return TRUE;
+}
+
 /***********************************************************************
  *		EnumDisplayMonitors (USER32.@)
  */
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 514cf6753f..a503ebe4db 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -122,6 +122,8 @@ extern const USER_DRIVER *USER_Driver DECLSPEC_HIDDEN;
 
 extern void USER_unload_driver(void) DECLSPEC_HIDDEN;
 
+extern BOOL CDECL nulldrv_EnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc, LPARAM lp ) DECLSPEC_HIDDEN;
+
 struct received_message_info;
 
 enum user_obj_type
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index ce2c568ad8..d6969b0cfe 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -41,6 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
 
 /* Wine specific monitor properties */
 DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
+DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3);
 
 static const WCHAR driver_descW[] = {'D','r','i','v','e','r','D','e','s','c',0};
 static const WCHAR video_idW[] = {'V','i','d','e','o','I','D',0};
@@ -276,6 +277,10 @@ static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *mo
     if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, DEVPROP_TYPE_UINT32,
                                    (const BYTE *)&monitor->state_flags, sizeof(monitor->state_flags), 0))
         goto done;
+    /* RcMonitor */
+    if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY,
+                                   (const BYTE *)&monitor->rc_monitor, sizeof(monitor->rc_monitor), 0))
+        goto done;
 
     ret = TRUE;
 done:
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 614f0b90f4..5b00a5dc5d 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -20,7 +20,6 @@
 @ cdecl SetCursorPos(long long) X11DRV_SetCursorPos
 @ cdecl ClipCursor(ptr) X11DRV_ClipCursor
 @ cdecl ChangeDisplaySettingsEx(ptr ptr long long long) X11DRV_ChangeDisplaySettingsEx
-@ cdecl EnumDisplayMonitors(long ptr ptr long) X11DRV_EnumDisplayMonitors
 @ cdecl EnumDisplaySettingsEx(ptr long ptr long) X11DRV_EnumDisplaySettingsEx
 @ cdecl GetMonitorInfo(long ptr) X11DRV_GetMonitorInfo
 @ cdecl CreateDesktopWindow(long) X11DRV_CreateDesktopWindow
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index ed5e268391..a6b07699a7 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -695,6 +695,8 @@ struct x11drv_monitor
 {
     /* Name */
     WCHAR name[128];
+    /* RcMonitor in MONITORINFO struct */
+    RECT rc_monitor;
     /* StateFlags in DISPLAY_DEVICE struct */
     DWORD state_flags;
 };
diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c
index e401531450..c8fa63f459 100644
--- a/dlls/winex11.drv/xinerama.c
+++ b/dlls/winex11.drv/xinerama.c
@@ -321,6 +321,7 @@ static BOOL xinerama_get_monitors( ULONG_PTR adapter_id, struct x11drv_monitor *
                 && !IsRectEmpty( &monitors[first].rcMonitor )))
         {
             lstrcpyW( monitor[index].name, generic_nonpnp_monitorW );
+            monitor[index].rc_monitor = monitors[i].rcMonitor;
             /* Xinerama only reports monitors already attached */
             monitor[index].state_flags = DISPLAY_DEVICE_ATTACHED;
             if (!IsRectEmpty( &monitors[i].rcMonitor ))
@@ -410,17 +411,3 @@ BOOL CDECL X11DRV_GetMonitorInfo( HMONITOR handle, LPMONITORINFO info )
         lstrcpyW( ((MONITORINFOEXW *)info)->szDevice, monitors[i].szDevice );
     return TRUE;
 }
-
-
-/***********************************************************************
- *		X11DRV_EnumDisplayMonitors  (X11DRV.@)
- */
-BOOL CDECL X11DRV_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
-{
-    int i;
-
-    for (i = 0; i < nb_monitors; i++)
-        if (!proc( index_to_monitor(i), 0, &monitors[i].rcMonitor, lp )) return FALSE;
-
-    return TRUE;
-}
-- 
2.17.1




More information about the wine-devel mailing list