user: monitor fixes

Huw D M Davies h.davies1 at physics.ox.ac.uk
Tue Sep 27 10:41:37 CDT 2005


I've put the tests here in monitor.c rather than misc.c - it didn't
seem right to create yet another misc file.  My hope is that as the
monitor code gets fleshed out it'll get moved to its own file so we
might as well start the tests off there too.

        Huw Davies <huw at codeweavers.com>
        EnumDisplayDevices and GetMonitorInfo should return the same
        device name for the primary device.
        Make both EnumDisplayDevicesA and GetMonitorInfoA call their
        unicode counterparts.
        Update prototype of EnumDisplayDevices.
        Add some tests.
-- 
Huw Davies
huw at codeweavers.com
Index: include/winuser.h
===================================================================
RCS file: /home/wine/wine/include/winuser.h,v
retrieving revision 1.226
diff -u -p -r1.226 winuser.h
--- include/winuser.h	12 Sep 2005 12:10:39 -0000	1.226
+++ include/winuser.h	27 Sep 2005 15:31:31 -0000
@@ -3895,8 +3895,8 @@ LONG        WINAPI ChangeDisplaySettings
 HDESK       WINAPI CreateDesktopA(LPCSTR,LPCSTR,LPDEVMODEA,DWORD,ACCESS_MASK,LPSECURITY_ATTRIBUTES);
 HDESK       WINAPI CreateDesktopW(LPCWSTR,LPCWSTR,LPDEVMODEW,DWORD,ACCESS_MASK,LPSECURITY_ATTRIBUTES);
 #define     CreateDesktop WINELIB_NAME_AW(CreateDesktop)
-BOOL        WINAPI EnumDisplayDevicesA(LPVOID,DWORD,LPDISPLAY_DEVICEA,DWORD);
-BOOL        WINAPI EnumDisplayDevicesW(LPVOID,DWORD,LPDISPLAY_DEVICEW,DWORD);
+BOOL        WINAPI EnumDisplayDevicesA(LPCSTR,DWORD,LPDISPLAY_DEVICEA,DWORD);
+BOOL        WINAPI EnumDisplayDevicesW(LPCWSTR,DWORD,LPDISPLAY_DEVICEW,DWORD);
 #define     EnumDisplayDevices WINELIB_NAME_AW(EnumDisplayDevices)
 BOOL        WINAPI EnumDisplaySettingsA(LPCSTR,DWORD,LPDEVMODEA);
 BOOL        WINAPI EnumDisplaySettingsW(LPCWSTR,DWORD,LPDEVMODEW);
Index: dlls/user/misc.c
===================================================================
RCS file: /home/wine/wine/dlls/user/misc.c,v
retrieving revision 1.26
diff -u -p -r1.26 misc.c
--- dlls/user/misc.c	9 Jun 2005 10:07:04 -0000	1.26
+++ dlls/user/misc.c	27 Sep 2005 15:31:32 -0000
@@ -28,6 +28,7 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winnls.h"
+#include "winternl.h"
 
 #include "wine/unicode.h"
 #include "wine/debug.h"
@@ -271,41 +272,67 @@ DWORD WINAPI SetLogonNotifyWindow(HWINST
     return 1;
 }
 
+static const WCHAR primary_device_name[] = {'\\','\\','.','\\','D','I','S','P','L','A','Y','1',0};
+static const WCHAR primary_device_string[] = {'X','1','1',' ','W','i','n','d','o','w','i','n','g',' ',
+                                              'S','y','s','t','e','m',0};
+
 /***********************************************************************
  *		EnumDisplayDevicesA (USER32.@)
  */
-BOOL WINAPI EnumDisplayDevicesA( LPVOID unused, DWORD i, LPDISPLAY_DEVICEA lpDisplayDevice,
+BOOL WINAPI EnumDisplayDevicesA( LPCSTR lpDevice, DWORD i, LPDISPLAY_DEVICEA lpDispDev,
                                  DWORD dwFlags )
 {
-    if (i)
-        return FALSE;
-    FIXME("(%p,%ld,%p,0x%08lx), stub!\n",unused,i,lpDisplayDevice,dwFlags);
-    strcpy(lpDisplayDevice->DeviceName,"X11");
-    strcpy(lpDisplayDevice->DeviceString,"X 11 Windowing System");
-    lpDisplayDevice->StateFlags =
-        DISPLAY_DEVICE_ATTACHED_TO_DESKTOP |
-        DISPLAY_DEVICE_PRIMARY_DEVICE |
-        DISPLAY_DEVICE_VGA_COMPATIBLE;
+    UNICODE_STRING deviceW;
+    DISPLAY_DEVICEW ddW;
+    BOOL ret;
+
+    if(lpDevice)
+        RtlCreateUnicodeStringFromAsciiz(&deviceW, lpDevice); 
+    else
+        deviceW.Buffer = NULL;
+
+    ddW.cb = sizeof(ddW);
+    ret = EnumDisplayDevicesW(deviceW.Buffer, i, &ddW, dwFlags);
+    RtlFreeUnicodeString(&deviceW);
+
+    if(!ret) return ret;
+
+    WideCharToMultiByte(CP_ACP, 0, ddW.DeviceName, -1, lpDispDev->DeviceName, sizeof(lpDispDev->DeviceName), NULL, NULL);
+    WideCharToMultiByte(CP_ACP, 0, ddW.DeviceString, -1, lpDispDev->DeviceString, sizeof(lpDispDev->DeviceString), NULL, NULL);
+    lpDispDev->StateFlags = ddW.StateFlags;
+
+    if(lpDispDev->cb >= offsetof(DISPLAY_DEVICEA, DeviceID) + sizeof(lpDispDev->DeviceID))
+        WideCharToMultiByte(CP_ACP, 0, ddW.DeviceID, -1, lpDispDev->DeviceID, sizeof(lpDispDev->DeviceID), NULL, NULL);
+    if(lpDispDev->cb >= offsetof(DISPLAY_DEVICEA, DeviceKey) + sizeof(lpDispDev->DeviceKey))
+        WideCharToMultiByte(CP_ACP, 0, ddW.DeviceKey, -1, lpDispDev->DeviceKey, sizeof(lpDispDev->DeviceKey), NULL, NULL);
+
     return TRUE;
 }
 
 /***********************************************************************
  *		EnumDisplayDevicesW (USER32.@)
  */
-BOOL WINAPI EnumDisplayDevicesW( LPVOID unused, DWORD i, LPDISPLAY_DEVICEW lpDisplayDevice,
+BOOL WINAPI EnumDisplayDevicesW( LPCWSTR lpDevice, DWORD i, LPDISPLAY_DEVICEW lpDisplayDevice,
                                  DWORD dwFlags )
 {
+    FIXME("(%s,%ld,%p,0x%08lx), stub!\n",debugstr_w(lpDevice),i,lpDisplayDevice,dwFlags);
+
     if (i)
         return FALSE;
-    FIXME("(%p,%ld,%p,0x%08lx), stub!\n",unused,i,lpDisplayDevice,dwFlags);
-    MultiByteToWideChar( CP_ACP, 0, "X11", -1, lpDisplayDevice->DeviceName,
-                         sizeof(lpDisplayDevice->DeviceName)/sizeof(WCHAR) );
-    MultiByteToWideChar( CP_ACP, 0, "X11 Windowing System", -1, lpDisplayDevice->DeviceString,
-                         sizeof(lpDisplayDevice->DeviceString)/sizeof(WCHAR) );
+
+    memcpy(lpDisplayDevice->DeviceName, primary_device_name, sizeof(primary_device_name));
+    memcpy(lpDisplayDevice->DeviceString, primary_device_string, sizeof(primary_device_string));
+  
     lpDisplayDevice->StateFlags =
         DISPLAY_DEVICE_ATTACHED_TO_DESKTOP |
         DISPLAY_DEVICE_PRIMARY_DEVICE |
         DISPLAY_DEVICE_VGA_COMPATIBLE;
+
+    if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceID) + sizeof(lpDisplayDevice->DeviceID))
+        lpDisplayDevice->DeviceID[0] = 0;
+    if(lpDisplayDevice->cb >= offsetof(DISPLAY_DEVICEW, DeviceKey) + sizeof(lpDisplayDevice->DeviceKey))
+        lpDisplayDevice->DeviceKey[0] = 0;
+
     return TRUE;
 }
 
@@ -366,26 +393,21 @@ HMONITOR WINAPI MonitorFromWindow(HWND h
  */
 BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
 {
-    RECT rcWork;
-
-    if ((hMonitor == xPRIMARY_MONITOR) &&
-        lpMonitorInfo &&
-        (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
-        SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
-    {
-        SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
-                 GetSystemMetrics(SM_CXSCREEN),
-                 GetSystemMetrics(SM_CYSCREEN) );
-        lpMonitorInfo->rcWork = rcWork;
-        lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
-
-	if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXA))
-            strcpy(((MONITORINFOEXA*)lpMonitorInfo)->szDevice, "DISPLAY");
-
-        return TRUE;
-    }
-
-    return FALSE;
+    MONITORINFOEXW miW;
+    MONITORINFOEXA *miA = (MONITORINFOEXA*)lpMonitorInfo;
+    BOOL ret;
+
+    miW.cbSize = sizeof(miW);
+
+    ret = GetMonitorInfoW(hMonitor, (MONITORINFO*)&miW);
+    if(!ret) return ret;
+
+    miA->rcMonitor = miW.rcMonitor;
+    miA->rcWork = miW.rcWork;
+    miA->dwFlags = miW.dwFlags;
+    if(miA->cbSize >= offsetof(MONITORINFOEXA, szDevice) + sizeof(miA->szDevice))
+        WideCharToMultiByte(CP_ACP, 0, miW.szDevice, -1, miA->szDevice, sizeof(miA->szDevice), NULL, NULL);
+    return ret;
 }
 
 /***********************************************************************
@@ -393,7 +415,6 @@ BOOL WINAPI GetMonitorInfoA(HMONITOR hMo
  */
 BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
 {
-    static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0};
     RECT rcWork;
 
     if ((hMonitor == xPRIMARY_MONITOR) &&
@@ -408,7 +429,7 @@ BOOL WINAPI GetMonitorInfoW(HMONITOR hMo
         lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
 
         if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW))
-            strcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, displayW);
+            strcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, primary_device_name);
 
         return TRUE;
     }
Index: dlls/user/tests/.cvsignore
===================================================================
RCS file: /home/wine/wine/dlls/user/tests/.cvsignore,v
retrieving revision 1.20
diff -u -p -r1.20 .cvsignore
--- dlls/user/tests/.cvsignore	8 Jun 2005 18:44:50 -0000	1.20
+++ dlls/user/tests/.cvsignore	27 Sep 2005 15:31:32 -0000
@@ -9,6 +9,7 @@ generated.ok
 input.ok
 listbox.ok
 menu.ok
+monitor.ok
 msg.ok
 resource.ok
 resource.res
Index: dlls/user/tests/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/user/tests/Makefile.in,v
retrieving revision 1.16
diff -u -p -r1.16 Makefile.in
--- dlls/user/tests/Makefile.in	27 Aug 2005 09:27:10 -0000	1.16
+++ dlls/user/tests/Makefile.in	27 Sep 2005 15:31:32 -0000
@@ -16,6 +16,7 @@ CTESTS = \
 	input.c \
 	listbox.c \
 	menu.c \
+	monitor.c \
 	msg.c \
 	resource.c \
 	sysparams.c \
--- /dev/null	2004-02-23 21:02:56.000000000 +0000
+++ dlls/user/tests/monitor.c	2005-09-27 15:44:35.731516042 +0100
@@ -0,0 +1,77 @@
+/*
+ * Unit tests for monitor APIs
+ *
+ * Copyright 2005 Huw Davies
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "wine/test.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+
+static BOOL CALLBACK monitor_enum_proc(HMONITOR hmon, HDC hdc, LPRECT lprc,
+                                       LPARAM lparam)
+{
+    MONITORINFOEXA mi;
+    char *primary = (char *)lparam;
+
+    mi.cbSize = sizeof(mi);
+
+    ok(GetMonitorInfoA(hmon, (MONITORINFO*)&mi), "GetMonitorInfo failed\n");
+    if(mi.dwFlags == MONITORINFOF_PRIMARY)
+        strcpy(primary, mi.szDevice);
+
+    return TRUE;
+}
+
+static void test_enumdisplaydevices(void)
+{
+    DISPLAY_DEVICEA dd;
+    char primary_device_name[32];
+    char primary_monitor_device_name[32];
+    DWORD primary_num = -1, num = 0;
+
+    dd.cb = sizeof(dd);
+    while(1)
+    {
+        BOOL ret;
+        ret = EnumDisplayDevicesA(NULL, num, &dd, 0), "EnumDisplayDevices fails\n";
+        ok(ret || num != 0, "EnumDisplayDevices fails with num == 0\n");
+        if(!ret) break;
+        if(dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
+        {
+            strcpy(primary_device_name, dd.DeviceName);
+            primary_num = num;
+        }
+        num++;
+    }
+    ok(primary_num != -1, "Didn't get the primary device\n");
+
+    ok(EnumDisplayMonitors(NULL, NULL, monitor_enum_proc, (LPARAM)primary_monitor_device_name),
+       "EnumDisplayMonitors failed\n");
+
+    ok(!strcmp(primary_monitor_device_name, primary_device_name),
+       "monitor device name %s, device name %s\n", primary_monitor_device_name,
+       primary_device_name);
+}
+
+
+
+START_TEST(monitor)
+{
+    test_enumdisplaydevices();
+}



More information about the wine-patches mailing list