PATCH: video mode changes

Alex Pasadyn ajp at mail.utexas.edu
Fri Apr 11 23:16:32 CDT 2003


Greetings,
This is a quick (not quite complete, but enough to make many programs 
happy) implementation of EnumDisplaySettings* and ChangeDisplaySettings* 
(from a FIXME in the X11DRV).

These are used by many OpenGL games, demos, and tutorials.

Unfortunately, many of those applications create unmanaged windows, and 
those don't seem to get along that well with KDE.  Using TWM everything 
seems happy.  With KDE running it's hit and miss as far as keyboard focus.

Half-Life seems to run beautifully for me with this, even with KDE.  It 
might be doing some extra work to grab the focus.  The NeHe OpenGL 
tutorials sometimes get the focus and sometimes don't.  Several programs 
seem happy just to get the real list of video modes instead of the old 
hardcoded list.

I had to export SYSMETRICS_Set from user32.  Otherwise some applications 
create windows in very odd places.



Changelog:
- Implement EnumDisplaySettings* and ChangeDisplaySettings*

License: X11/LGPL


-------------------------------------
Alex Pasadyn
ajp at mail.utexas.edu

-------------- next part --------------
Index: dlls/user/user32.spec
===================================================================
RCS file: /home/wine/wine/dlls/user/user32.spec,v
retrieving revision 1.69
diff -u -r1.69 user32.spec
--- dlls/user/user32.spec	28 Mar 2003 19:40:37 -0000	1.69
+++ dlls/user/user32.spec	12 Apr 2003 03:35:00 -0000
@@ -596,7 +596,7 @@
 
 #late additions
 @ stdcall ChangeDisplaySettingsA(ptr long)
-@ stub ChangeDisplaySettingsW
+@ stdcall ChangeDisplaySettingsW(ptr long)
 @ stdcall EnumDesktopWindows(long ptr ptr)
 @ stdcall EnumDisplaySettingsA(str long ptr)
 @ stdcall EnumDisplaySettingsW(wstr long ptr )
@@ -611,7 +611,7 @@
 @ stdcall DrawCaptionTempW(long long ptr long long wstr long)
 @ stub IsHungAppWindow
 @ stdcall ChangeDisplaySettingsExA(str ptr long long ptr)
-@ stub ChangeDisplaySettingsExW
+@ stdcall ChangeDisplaySettingsExW(wstr ptr long long ptr)
 @ stdcall SetWindowText(long str) SetWindowTextA
 @ stdcall GetMonitorInfoA(long ptr)
 @ stdcall GetMonitorInfoW(long ptr)
@@ -705,3 +705,4 @@
 @ cdecl WIN_SetStyle(long long)
 @ cdecl WIN_SuspendWndsLock()
 @ cdecl WIN_UnlinkWindow(long)
+@ cdecl SYSMETRICS_Set(long long)
Index: dlls/user/user_main.c
===================================================================
RCS file: /home/wine/wine/dlls/user/user_main.c,v
retrieving revision 1.50
diff -u -r1.50 user_main.c
--- dlls/user/user_main.c	3 Dec 2002 23:34:54 -0000	1.50
+++ dlls/user/user_main.c	12 Apr 2003 03:35:00 -0000
@@ -114,6 +114,9 @@
     GET_USER_FUNC(SetWindowText);
     GET_USER_FUNC(ShowWindow);
     GET_USER_FUNC(SysCommandSizeMove);
+    GET_USER_FUNC(InitDisplaySettings);
+    GET_USER_FUNC(EnumDisplaySettingsExW);
+    GET_USER_FUNC(ChangeDisplaySettingsExW);
 
     return TRUE;
 }
@@ -226,6 +229,9 @@
     /* Load the graphics driver */
     tweak_init();
     if (!load_driver()) return FALSE;
+
+    /* Initialize display modes*/
+    if (USER_Driver.pInitDisplaySettings) USER_Driver.pInitDisplaySettings();
 
     /* Initialize system colors and metrics */
     SYSMETRICS_Init();
Index: dlls/x11drv/x11drv.spec
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv.spec,v
retrieving revision 1.44
diff -u -r1.44 x11drv.spec
--- dlls/x11drv/x11drv.spec	20 Mar 2003 03:53:12 -0000	1.44
+++ dlls/x11drv/x11drv.spec	12 Apr 2003 03:35:00 -0000
@@ -98,6 +98,9 @@
 @ cdecl GetClipboardFormatName(long str long) X11DRV_GetClipboardFormatName
 @ cdecl IsSelectionOwner() X11DRV_IsSelectionOwner
 @ cdecl ResetSelectionOwner(ptr long) X11DRV_ResetSelectionOwner
+@ cdecl InitDisplaySettings() X11DRV_XF86VM_Init
+@ cdecl EnumDisplaySettingsExW (ptr long ptr long) X11DRV_EnumDisplaySettingsExW
+@ cdecl ChangeDisplaySettingsExW (ptr ptr long long long) X11DRV_ChangeDisplaySettingsExW
 
 # X11 locks
 @ cdecl -norelay wine_tsx11_lock()
Index: dlls/x11drv/xvidmode.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/xvidmode.c,v
retrieving revision 1.17
diff -u -r1.17 xvidmode.c
--- dlls/x11drv/xvidmode.c	29 Sep 2002 18:02:40 -0000	1.17
+++ dlls/x11drv/xvidmode.c	12 Apr 2003 03:35:01 -0000
@@ -18,8 +18,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* FIXME: ChangeDisplaySettings ought to be able to use this */
-
 #include "config.h"
 #include <string.h>
 
@@ -38,6 +36,7 @@
 #include "windef.h"
 #include "wingdi.h"
 #include "ddrawi.h"
+#include "user.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
@@ -48,6 +47,8 @@
 
 static int xf86vm_event, xf86vm_error, xf86vm_major, xf86vm_minor;
 
+static int xf86vm_initcount;
+
 #ifdef X_XF86VidModeSetGammaRamp
 static int xf86vm_gammaramp_size;
 static BOOL xf86vm_use_gammaramp;
@@ -56,6 +57,7 @@
 LPDDHALMODEINFO xf86vm_modes;
 unsigned xf86vm_mode_count;
 XF86VidModeModeInfo** modes;
+static unsigned xf86vm_initial_mode;
 
 static void convert_modeinfo( const XF86VidModeModeInfo *mode, LPDDHALMODEINFO info )
 {
@@ -109,6 +111,9 @@
   int nmodes, i;
   Bool ok;
 
+  /* Keep reference count of times Init is called */
+  if (xf86vm_initcount++) return;
+
   if (xf86vm_major) return; /* already initialized? */
 
   /* if in desktop mode, don't use XVidMode */
@@ -151,11 +156,17 @@
   /* convert modes to DDHALMODEINFO format */
   for (i=0; i<nmodes; i++)
       convert_modeinfo(modes[i], &xf86vm_modes[i]);
+
+  /* store the current mode at the time we started */
+  xf86vm_initial_mode = X11DRV_XF86VM_GetCurrentMode();
+
   TRACE("Enabling XVidMode\n");
 }
 
 void X11DRV_XF86VM_Cleanup(void)
 {
+  /* Decrement count and do cleanup only if no more uncleaned up Init calls  */
+  if (--xf86vm_initcount) return;
   if (modes) TSXFree(modes);
 }
 
@@ -411,3 +422,116 @@
   return FALSE;
 #endif
 }
+
+/***********************************************************************
+ *		X11DRV_EnumDisplaySettingsExW (X11DRV.@)
+ *
+ */
+BOOL X11DRV_EnumDisplaySettingsExW( LPCWSTR name, DWORD n, LPDEVMODEW devmode, DWORD flags) 
+{
+    XF86VidModeModeInfo *mode;
+    devmode->dmDisplayFlags = 0;
+    devmode->dmDisplayFrequency = 85;
+    devmode->dmSize = sizeof(DEVMODEW);
+    if (n==0 || n == (DWORD)-1 || n == (DWORD)-2) {
+        devmode->dmBitsPerPel = GetSystemMetrics(SM_WINE_BPP);
+	devmode->dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
+	devmode->dmPelsWidth  = GetSystemMetrics(SM_CXSCREEN);
+        devmode->dmFields = (DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL);
+        TRACE("mode %ld -- returning default %ldx%ldx%ldbpp\n", n, 
+          devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel);
+	return TRUE;
+	}
+    if (n > xf86vm_mode_count) {
+        TRACE("mode %ld -- not present\n", n);
+        return FALSE;
+    }
+
+    mode = modes[n-1];
+    devmode->dmPelsWidth = mode->hdisplay;
+    devmode->dmPelsHeight = mode->vdisplay;
+    devmode->dmBitsPerPel = GetSystemMetrics(SM_WINE_BPP);
+    devmode->dmDisplayFrequency = mode->dotclock * 1000 / (mode->htotal * mode->vtotal);
+    devmode->dmFields = (DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL|DM_DISPLAYFREQUENCY);
+    TRACE("mode %ld -- %ldx%ldx%ldbpp\n", n, 
+          devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel);
+    return TRUE;
+}
+
+/***********************************************************************
+ *		X11DRV_ChangeDisplaySettingsExW (X11DRV.@)
+ *
+ */
+
+static void _dump_CDS_flags(DWORD flags) {
+#define X(x) if (flags & CDS_##x) MESSAGE(""#x ",");
+	X(UPDATEREGISTRY);X(TEST);X(FULLSCREEN);X(GLOBAL);
+	X(SET_PRIMARY);X(RESET);X(SETRECT);X(NORESET);
+#undef X
+}
+static void _dump_DM_fields(DWORD fields) {
+#define X(x) if ((fields) & DM_##x) MESSAGE(""#x ",");
+	X(BITSPERPEL);X(PELSWIDTH);X(PELSHEIGHT);X(DISPLAYFLAGS);
+	X(DISPLAYFREQUENCY);X(POSITION);
+#undef X
+}
+  
+LONG X11DRV_ChangeDisplaySettingsExW(
+	LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd, DWORD flags,
+	LPVOID lpvoid
+) {
+    XF86VidModeModeInfo *mode;
+    DWORD i;
+    i = 0;
+    TRACE("(%s,%p,%p,0x%08lx,%p\n",debugstr_w(devname),devmode,hwnd,flags,lpvoid);
+    if (TRACE_ON(x11drv))
+    {
+        MESSAGE("\tflags=");_dump_CDS_flags(flags);MESSAGE("\n");
+    }
+    if (devmode==NULL)
+    {
+        TRACE("Return to original display mode\n");
+        X11DRV_XF86VM_SetCurrentMode(xf86vm_initial_mode);
+        return DISP_CHANGE_SUCCESSFUL;
+    }
+    else 
+    {
+        if (TRACE_ON(x11drv))
+        {
+            MESSAGE("\tDM_fields=");_dump_DM_fields(devmode->dmFields);MESSAGE("\n");
+            MESSAGE("   bpp=%ld\n",devmode->dmBitsPerPel);
+            MESSAGE("   width=%ld\n",devmode->dmPelsWidth);
+            MESSAGE("   height=%ld\n",devmode->dmPelsHeight);
+            MESSAGE("   freq=%ld\n",devmode->dmDisplayFrequency);
+        }
+        while (i < xf86vm_mode_count) 
+        {
+            mode = modes[i++];
+            if (devmode->dmFields & DM_BITSPERPEL)
+            {
+                if (devmode->dmBitsPerPel != GetSystemMetrics(SM_WINE_BPP))
+                    continue;
+            }        
+            if (devmode->dmFields & DM_PELSWIDTH)
+            {
+                if (devmode->dmPelsWidth != mode->hdisplay)
+                    continue;
+            }
+            if (devmode->dmFields & DM_PELSHEIGHT)
+            {
+                if (devmode->dmPelsHeight != mode->vdisplay)
+                    continue;
+            }
+            /* we have a valid mode */
+            TRACE("Matches mode %ld\n", i);
+            X11DRV_XF86VM_SetCurrentMode(i-1);
+            SYSMETRICS_Set( SM_CXSCREEN, devmode->dmPelsWidth );
+            SYSMETRICS_Set( SM_CYSCREEN, devmode->dmPelsHeight );
+            return DISP_CHANGE_SUCCESSFUL;
+        }
+        /* no valid modes found */
+        ERR("No matching mode found!");
+        return DISP_CHANGE_BADMODE;
+    }
+}
+
Index: include/user.h
===================================================================
RCS file: /home/wine/wine/include/user.h,v
retrieving revision 1.50
diff -u -r1.50 user.h
--- include/user.h	3 Dec 2002 23:34:53 -0000	1.50
+++ include/user.h	12 Apr 2003 03:35:01 -0000
@@ -110,6 +110,12 @@
     BOOL   (*pSetWindowText)(HWND,LPCWSTR);
     BOOL   (*pShowWindow)(HWND,INT);
     void   (*pSysCommandSizeMove)(HWND,WPARAM);
+
+    /* Display modes */
+    void (*pInitDisplaySettings)(void);
+    BOOL (*pEnumDisplaySettingsExW)(LPCWSTR,DWORD,LPDEVMODEW, DWORD);
+    LONG (*pChangeDisplaySettingsExW)(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
+
 } USER_DRIVER;
 
 extern USER_DRIVER USER_Driver;
Index: include/winuser.h
===================================================================
RCS file: /home/wine/wine/include/winuser.h,v
retrieving revision 1.159
diff -u -r1.159 winuser.h
--- include/winuser.h	4 Apr 2003 19:31:41 -0000	1.159
+++ include/winuser.h	12 Apr 2003 03:35:03 -0000
@@ -3729,8 +3729,8 @@
 LONG        WINAPI ChangeDisplaySettingsA(LPDEVMODEA,DWORD);
 LONG        WINAPI ChangeDisplaySettingsW(LPDEVMODEW,DWORD);
 #define     ChangeDisplaySettings WINELIB_NAME_AW(ChangeDisplaySettings)
-LONG        WINAPI ChangeDisplaySettingsExA(LPCSTR,LPDEVMODEA,HWND,DWORD,LPARAM);
-LONG        WINAPI ChangeDisplaySettingsExW(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPARAM);
+LONG        WINAPI ChangeDisplaySettingsExA(LPCSTR,LPDEVMODEA,HWND,DWORD,LPVOID);
+LONG        WINAPI ChangeDisplaySettingsExW(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
 #define     ChangeDisplaySettingsEx WINELIB_NAME_AW(ChangeDisplaySettingsEx)
 BOOL        WINAPI EnumDisplayDevicesA(LPVOID,DWORD,LPDISPLAY_DEVICEA,DWORD);
 BOOL        WINAPI EnumDisplayDevicesW(LPVOID,DWORD,LPDISPLAY_DEVICEW,DWORD);
@@ -3738,6 +3738,9 @@
 BOOL        WINAPI EnumDisplaySettingsA(LPCSTR,DWORD,LPDEVMODEA);
 BOOL        WINAPI EnumDisplaySettingsW(LPCWSTR,DWORD,LPDEVMODEW);
 #define     EnumDisplaySettings WINELIB_NAME_AW(EnumDisplaySettings)
+BOOL        WINAPI EnumDisplaySettingsExA(LPCSTR,DWORD,LPDEVMODEA,DWORD);
+BOOL        WINAPI EnumDisplaySettingsExW(LPCWSTR,DWORD,LPDEVMODEW,DWORD);
+#define     EnumDisplaySettingsEx WINELIB_NAME_AW(EnumDisplaySettingsEx)
 #endif /* defined(_WINGDI_) && !defined(NOGDI) */
 
 HKL         WINAPI ActivateKeyboardLayout(HKL,UINT);
Index: windows/user.c
===================================================================
RCS file: /home/wine/wine/windows/user.c,v
retrieving revision 1.92
diff -u -r1.92 user.c
--- windows/user.c	3 Dec 2002 23:34:52 -0000	1.92
+++ windows/user.c	12 Apr 2003 03:35:03 -0000
@@ -257,39 +257,20 @@
     return FALSE;
 }
 
-static void _dump_CDS_flags(DWORD flags) {
-#define X(x) if (flags & CDS_##x) MESSAGE(""#x ",");
-	X(UPDATEREGISTRY);X(TEST);X(FULLSCREEN);X(GLOBAL);
-	X(SET_PRIMARY);X(RESET);X(SETRECT);X(NORESET);
-#undef X
-}
-
 /***********************************************************************
  *		ChangeDisplaySettingsA (USER32.@)
  */
 LONG WINAPI ChangeDisplaySettingsA( LPDEVMODEA devmode, DWORD flags )
 {
-  FIXME_(system)("(%p,0x%08lx), stub\n",devmode,flags);
-  MESSAGE("\tflags=");_dump_CDS_flags(flags);MESSAGE("\n");
-  if (devmode==NULL)
-    FIXME_(system)("   devmode=NULL (return to default mode)\n");
-  else if ( (devmode->dmBitsPerPel != GetSystemMetrics(SM_WINE_BPP))
-	    || (devmode->dmPelsHeight != GetSystemMetrics(SM_CYSCREEN))
-	    || (devmode->dmPelsWidth != GetSystemMetrics(SM_CXSCREEN)) )
-
-  {
-
-    if (devmode->dmFields & DM_BITSPERPEL)
-      FIXME_(system)("   bpp=%ld\n",devmode->dmBitsPerPel);
-    if (devmode->dmFields & DM_PELSWIDTH)
-      FIXME_(system)("   width=%ld\n",devmode->dmPelsWidth);
-    if (devmode->dmFields & DM_PELSHEIGHT)
-      FIXME_(system)("   height=%ld\n",devmode->dmPelsHeight);
-    FIXME_(system)(" (Putting X in this mode beforehand might help)\n");
-    /* we don't, but the program ... does not need to know */
-    return DISP_CHANGE_SUCCESSFUL;
-  }
-  return DISP_CHANGE_SUCCESSFUL;
+  return ChangeDisplaySettingsExA(NULL,devmode,NULL,flags,NULL);
+}
+
+/***********************************************************************
+ *		ChangeDisplaySettingsW (USER32.@)
+ */
+LONG WINAPI ChangeDisplaySettingsW( LPDEVMODEW devmode, DWORD flags )
+{
+  return ChangeDisplaySettingsExW(NULL,devmode,NULL,flags,NULL);
 }
 
 /***********************************************************************
@@ -297,7 +278,6 @@
  */
 LONG WINAPI ChangeDisplaySettings16( LPDEVMODEA devmode, DWORD flags )
 {
-	TRACE_(system)("(%p,0x%08lx), stub\n",devmode,flags);
 	return ChangeDisplaySettingsA(devmode, flags);
 }
 
@@ -306,34 +286,56 @@
  */
 LONG WINAPI ChangeDisplaySettingsExA(
 	LPCSTR devname, LPDEVMODEA devmode, HWND hwnd, DWORD flags,
-	LPARAM lparam
+	LPVOID lparam
 ) {
-  FIXME_(system)("(%s,%p,%p,0x%08lx,0x%08lx), stub\n",devname,devmode,hwnd,flags,lparam);
-  MESSAGE("\tflags=");_dump_CDS_flags(flags);MESSAGE("\n");
-  if (devmode==NULL)
-    FIXME_(system)("   devmode=NULL (return to default mode)\n");
-  else if ( (devmode->dmBitsPerPel != GetSystemMetrics(SM_WINE_BPP))
-	    || (devmode->dmPelsHeight != GetSystemMetrics(SM_CYSCREEN))
-	    || (devmode->dmPelsWidth != GetSystemMetrics(SM_CXSCREEN)) )
-
-  {
-
-    if (devmode->dmFields & DM_BITSPERPEL)
-      FIXME_(system)("   bpp=%ld\n",devmode->dmBitsPerPel);
-    if (devmode->dmFields & DM_PELSWIDTH)
-      FIXME_(system)("   width=%ld\n",devmode->dmPelsWidth);
-    if (devmode->dmFields & DM_PELSHEIGHT)
-      FIXME_(system)("   height=%ld\n",devmode->dmPelsHeight);
-    FIXME_(system)(" (Putting X in this mode beforehand might help)\n");
-    /* we don't, but the program ... does not need to know */
-    return DISP_CHANGE_SUCCESSFUL;
-  }
-  return DISP_CHANGE_SUCCESSFUL;
+    DEVMODEW devmodeW;
+    LONG ret;
+    UNICODE_STRING nameW;
+
+    if (devname) RtlCreateUnicodeStringFromAsciiz(&nameW, devname);
+    else nameW.Buffer = NULL;
+
+    if (devmode)
+    {
+        devmodeW.dmBitsPerPel       = devmode->dmBitsPerPel;
+        devmodeW.dmPelsHeight       = devmode->dmPelsHeight;
+        devmodeW.dmPelsWidth        = devmode->dmPelsWidth;
+        devmodeW.dmDisplayFlags     = devmode->dmDisplayFlags;
+        devmodeW.dmDisplayFrequency = devmode->dmDisplayFrequency;
+        devmodeW.dmFields           = devmode->dmFields;
+        ret = ChangeDisplaySettingsExW(nameW.Buffer, &devmodeW, hwnd, flags, lparam);
+    }
+    else
+    {
+        ret = ChangeDisplaySettingsExW(nameW.Buffer, NULL, hwnd, flags, lparam);
+    }
+
+    if (devname) RtlFreeUnicodeString(&nameW);
+    return ret;
+}
+
+/***********************************************************************
+ *		ChangeDisplaySettingsExW (USER32.@)
+ */
+LONG WINAPI ChangeDisplaySettingsExW(
+	LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd, DWORD flags,
+	LPVOID lparam
+) {
+    /* Pass the request on to the driver */
+    if (!USER_Driver.pChangeDisplaySettingsExW)
+    {
+        FIXME_(system)(" :stub\n");
+        return DISP_CHANGE_FAILED;
+    }
+    return USER_Driver.pChangeDisplaySettingsExW(devname,
+                                                 devmode,
+                                                 hwnd,
+                                                 flags,
+                                                 lparam);
 }
 
 /***********************************************************************
  *		EnumDisplaySettingsW (USER32.@)
- * FIXME: Currently uses static list of modes.
  *
  * RETURNS
  *	TRUE if nth setting exists found (described in the LPDEVMODEW struct)
@@ -344,29 +346,7 @@
 	DWORD n,		/* [in] nth entry in display settings list*/
 	LPDEVMODEW devmode	/* [out] devmode for that setting */
 ) {
-#define NRMODES 5
-#define NRDEPTHS 4
-	struct {
-		int w,h;
-	} modes[NRMODES]={{512,384},{640,400},{640,480},{800,600},{1024,768}};
-	int depths[4] = {8,16,24,32};
-
-	TRACE_(system)("(%s,%ld,%p)\n",debugstr_w(name),n,devmode);
-	devmode->dmDisplayFlags = 0;
-	devmode->dmDisplayFrequency = 85;
-	if (n==0 || n == (DWORD)-1 || n == (DWORD)-2) {
-		devmode->dmBitsPerPel = GetSystemMetrics(SM_WINE_BPP);
-		devmode->dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
-		devmode->dmPelsWidth  = GetSystemMetrics(SM_CXSCREEN);
-		return TRUE;
-	}
-	if ((n-1)<NRMODES*NRDEPTHS) {
-		devmode->dmBitsPerPel	= depths[(n-1)/NRMODES];
-		devmode->dmPelsHeight	= modes[(n-1)%NRMODES].h;
-		devmode->dmPelsWidth	= modes[(n-1)%NRMODES].w;
-		return TRUE;
-	}
-	return FALSE;
+    return EnumDisplaySettingsExW(name, n, devmode, 0);
 }
 
 /***********************************************************************
@@ -374,25 +354,7 @@
  */
 BOOL WINAPI EnumDisplaySettingsA(LPCSTR name,DWORD n,LPDEVMODEA devmode)
 {
-    DEVMODEW devmodeW;
-    BOOL ret;
-    UNICODE_STRING nameW;
-
-    if (name) RtlCreateUnicodeStringFromAsciiz(&nameW, name);
-    else nameW.Buffer = NULL;
-
-    ret = EnumDisplaySettingsW(nameW.Buffer,n,&devmodeW);
-    if (ret)
-    {
-        devmode->dmBitsPerPel       = devmodeW.dmBitsPerPel;
-        devmode->dmPelsHeight       = devmodeW.dmPelsHeight;
-        devmode->dmPelsWidth        = devmodeW.dmPelsWidth;
-        devmode->dmDisplayFlags     = devmodeW.dmDisplayFlags;
-        devmode->dmDisplayFrequency = devmodeW.dmDisplayFrequency;
-        /* FIXME: convert rest too, if they are ever returned */
-    }
-    RtlFreeUnicodeString(&nameW);
-    return ret;
+    return EnumDisplaySettingsExA(name, n, devmode, 0);
 }
 
 /***********************************************************************
@@ -403,7 +365,6 @@
 	DWORD n,		/* [in] nth entry in display settings list*/
 	LPDEVMODEA devmode	/* [out] devmode for that setting */
 ) {
-	TRACE_(system)("(%s, %ld, %p)\n", name, n, devmode);
 	return (BOOL16)EnumDisplaySettingsA(name, n, devmode);
 }
 
@@ -413,10 +374,25 @@
 BOOL WINAPI EnumDisplaySettingsExA(LPCSTR lpszDeviceName, DWORD iModeNum,
 				   LPDEVMODEA lpDevMode, DWORD dwFlags)
 {
-        TRACE_(system)("(%s,%lu,%p,%08lx): stub\n",
-		       debugstr_a(lpszDeviceName), iModeNum, lpDevMode, dwFlags);
+    DEVMODEW devmodeW;
+    BOOL ret;
+    UNICODE_STRING nameW;
+
+    if (lpszDeviceName) RtlCreateUnicodeStringFromAsciiz(&nameW, lpszDeviceName);
+    else nameW.Buffer = NULL;
 
-	return EnumDisplaySettingsA(lpszDeviceName, iModeNum, lpDevMode);
+    ret = EnumDisplaySettingsExW(nameW.Buffer,iModeNum,&devmodeW,dwFlags);
+    if (ret)
+    {
+        lpDevMode->dmBitsPerPel       = devmodeW.dmBitsPerPel;
+        lpDevMode->dmPelsHeight       = devmodeW.dmPelsHeight;
+        lpDevMode->dmPelsWidth        = devmodeW.dmPelsWidth;
+        lpDevMode->dmDisplayFlags     = devmodeW.dmDisplayFlags;
+        lpDevMode->dmDisplayFrequency = devmodeW.dmDisplayFrequency;
+        lpDevMode->dmFields           = devmodeW.dmFields;
+    }
+    if (lpszDeviceName) RtlFreeUnicodeString(&nameW);
+    return ret;
 }
 
 /***********************************************************************
@@ -425,10 +401,16 @@
 BOOL WINAPI EnumDisplaySettingsExW(LPCWSTR lpszDeviceName, DWORD iModeNum,
 				   LPDEVMODEW lpDevMode, DWORD dwFlags)
 {
-	TRACE_(system)("(%s,%lu,%p,%08lx): stub\n",
-			debugstr_w(lpszDeviceName), iModeNum, lpDevMode, dwFlags);
-
-	return EnumDisplaySettingsW(lpszDeviceName, iModeNum, lpDevMode);
+    /* Pass the request on to the driver */
+    if (!USER_Driver.pEnumDisplaySettingsExW) 
+    {
+        FIXME_(system)(" :stub\n");
+        return FALSE;
+    }
+    else return USER_Driver.pEnumDisplaySettingsExW(lpszDeviceName,
+                                                    iModeNum,
+                                                    lpDevMode,
+                                                    dwFlags);
 }
 
 /***********************************************************************


More information about the wine-patches mailing list