diff --git a/dlls/user/user32.spec b/dlls/user/user32.spec index 0ba264ee2ab..2aa72d015f5 100644 --- a/dlls/user/user32.spec +++ b/dlls/user/user32.spec @@ -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) diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c index d965e17b672..b8aa63f2260 100644 --- a/dlls/user/user_main.c +++ b/dlls/user/user_main.c @@ -97,6 +97,8 @@ static BOOL load_driver(void) GET_USER_FUNC(GetClipboardFormatName); GET_USER_FUNC(IsSelectionOwner); GET_USER_FUNC(ResetSelectionOwner); + GET_USER_FUNC(ChangeDisplaySettingsExW); + GET_USER_FUNC(EnumDisplaySettingsExW); GET_USER_FUNC(CreateWindow); GET_USER_FUNC(DestroyWindow); GET_USER_FUNC(GetDC); diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec index dd687e61469..94469d72218 100644 --- a/dlls/x11drv/x11drv.spec +++ b/dlls/x11drv/x11drv.spec @@ -72,6 +72,8 @@ @ cdecl SetCursorPos(long long) X11DRV_SetCursorPos @ cdecl GetScreenSaveActive() X11DRV_GetScreenSaveActive @ cdecl SetScreenSaveActive(long) X11DRV_SetScreenSaveActive +@ cdecl ChangeDisplaySettingsExW (ptr ptr long long long) X11DRV_ChangeDisplaySettingsExW +@ cdecl EnumDisplaySettingsExW (ptr long ptr long) X11DRV_EnumDisplaySettingsExW @ cdecl CreateWindow(long ptr long) X11DRV_CreateWindow @ cdecl DestroyWindow(long) X11DRV_DestroyWindow @ cdecl GetDC(long long long long) X11DRV_GetDC diff --git a/dlls/x11drv/xvidmode.c b/dlls/x11drv/xvidmode.c index 5271784b2f4..cd03c4a97e3 100644 --- a/dlls/x11drv/xvidmode.c +++ b/dlls/x11drv/xvidmode.c @@ -18,10 +18,9 @@ * 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 +#include #include "ts_xlib.h" @@ -53,9 +52,10 @@ static int xf86vm_gammaramp_size; static BOOL xf86vm_use_gammaramp; #endif -LPDDHALMODEINFO xf86vm_modes; -unsigned xf86vm_mode_count; -XF86VidModeModeInfo** modes; +static LPDDHALMODEINFO xf86vm_modes; +static unsigned xf86vm_mode_count; +static XF86VidModeModeInfo** modes; +static unsigned int xf86vm_initial_mode; static void convert_modeinfo( const XF86VidModeModeInfo *mode, LPDDHALMODEINFO info ) { @@ -151,6 +151,10 @@ void X11DRV_XF86VM_Init(void) /* convert modes to DDHALMODEINFO format */ for (i=0; idmDisplayFlags = 0; + devmode->dmDisplayFrequency = 85; + devmode->dmSize = sizeof(DEVMODEW); + if (n==0 || n == (DWORD)-1 || n == (DWORD)-2) + { + devmode->dmBitsPerPel = dwBpp; + 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; + } +#ifdef HAVE_LIBXXF86VM + if (n <= xf86vm_mode_count) + { + XF86VidModeModeInfo *mode; + mode = modes[n-1]; + devmode->dmPelsWidth = mode->hdisplay; + devmode->dmPelsHeight = mode->vdisplay; + devmode->dmBitsPerPel = dwBpp; + 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; + } +#endif + TRACE("mode %ld -- not present\n", n); + return FALSE; +} + + + +#define _X_FIELD(prefix, bits) if ((fields) & prefix##_##bits) {p+=sprintf(p, "%s%s", first ? "" : ",", #bits); first=FALSE;} +static const char * _CDS_flags(DWORD fields) +{ + BOOL first = TRUE; + char buf[128]; + char *p = buf; + _X_FIELD(CDS,UPDATEREGISTRY);_X_FIELD(CDS,TEST);_X_FIELD(CDS,FULLSCREEN); + _X_FIELD(CDS,GLOBAL);_X_FIELD(CDS,SET_PRIMARY);_X_FIELD(CDS,RESET); + _X_FIELD(CDS,SETRECT);_X_FIELD(CDS,NORESET); + return wine_dbg_sprintf("%s", buf); +} +static const char * _DM_fields(DWORD fields) +{ + BOOL first = TRUE; + char buf[128]; + char *p = buf; + _X_FIELD(DM,BITSPERPEL);_X_FIELD(DM,PELSWIDTH);_X_FIELD(DM,PELSHEIGHT); + _X_FIELD(DM,DISPLAYFLAGS);_X_FIELD(DM,DISPLAYFREQUENCY);_X_FIELD(DM,POSITION); + return wine_dbg_sprintf("%s", buf); +} +#undef _X_FIELD + +/*********************************************************************** + * ChangeDisplaySettingsExW (X11DRV.@) + */ +LONG X11DRV_ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, + HWND hwnd, DWORD flags, LPVOID lpvoid ) +{ + DWORD i; + DWORD dwBpp = screen_depth; + if (dwBpp == 24) dwBpp = 32; + TRACE("(%s,%p,%p,0x%08lx,%p\n",debugstr_w(devname),devmode,hwnd,flags,lpvoid); + TRACE("flags=%s\n",_CDS_flags(flags)); + if (devmode==NULL) + { + TRACE("Return to original display mode\n"); +#ifdef HAVE_LIBXXF86VM + X11DRV_XF86VM_SetCurrentMode(xf86vm_initial_mode); +#endif + return DISP_CHANGE_SUCCESSFUL; + } + + if (TRACE_ON(x11drv)) + { + TRACE("DM_fields=%s\n",_DM_fields(devmode->dmFields)); + TRACE("width=%ld height=%ld bpp=%ld freq=%ld\n", + devmode->dmPelsWidth,devmode->dmPelsHeight, + devmode->dmBitsPerPel,devmode->dmDisplayFrequency); + } + if ((!(devmode->dmFields & DM_BITSPERPEL) || devmode->dmBitsPerPel == dwBpp) && + (!(devmode->dmFields & DM_PELSWIDTH) || devmode->dmPelsWidth == GetSystemMetrics(SM_CXSCREEN)) && + (!(devmode->dmFields & DM_PELSHEIGHT) || devmode->dmPelsHeight == GetSystemMetrics(SM_CYSCREEN))) + { + /* we have a valid mode */ + TRACE("Requested mode matches current mode -- no change!\n"); + return DISP_CHANGE_SUCCESSFUL; + } + +#ifdef HAVE_LIBXXF86VM + for (i = 0; i < xf86vm_mode_count; i++) + { + XF86VidModeModeInfo *mode = modes[i]; + if (devmode->dmFields & DM_BITSPERPEL) + { + if (devmode->dmBitsPerPel != dwBpp) + 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); +#if 0 /* FIXME */ + SYSMETRICS_Set( SM_CXSCREEN, devmode->dmPelsWidth ); + SYSMETRICS_Set( SM_CYSCREEN, devmode->dmPelsHeight ); +#endif + return DISP_CHANGE_SUCCESSFUL; + } +#endif + + /* no valid modes found */ + ERR("No matching mode found!\n"); + return DISP_CHANGE_BADMODE; +} diff --git a/include/user.h b/include/user.h index 2e7dcf90fb8..752ecc16b05 100644 --- a/include/user.h +++ b/include/user.h @@ -91,7 +91,9 @@ typedef struct tagUSER_DRIVER { BOOL (*pGetClipboardFormatName)(UINT, LPSTR, UINT); /* Get a clipboard format name */ BOOL (*pIsSelectionOwner)(void); /* Check if we own the selection */ void (*pResetSelectionOwner)(HWND, BOOL); - + /* display modes */ + LONG (*pChangeDisplaySettingsExW)(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID); + BOOL (*pEnumDisplaySettingsExW)(LPCWSTR,DWORD,LPDEVMODEW,DWORD); /* windowing functions */ BOOL (*pCreateWindow)(HWND,CREATESTRUCTA*,BOOL); BOOL (*pDestroyWindow)(HWND); diff --git a/include/winuser.h b/include/winuser.h index 1adfaf47b39..6c07a4227ec 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -3729,8 +3729,8 @@ typedef struct tagWINDOWINFO { 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 EnumDisplayDevicesW(LPVOID,DWORD,LPDISPLAY_DEVICEW,DWORD); 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); diff --git a/windows/user.c b/windows/user.c index 80255f86687..e8c60efb67e 100644 --- a/windows/user.c +++ b/windows/user.c @@ -257,39 +257,20 @@ BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reserved ) 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)) ) + return ChangeDisplaySettingsExA(NULL,devmode,NULL,flags,NULL); +} - { - - 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; +/*********************************************************************** + * ChangeDisplaySettingsW (USER32.@) + */ +LONG WINAPI ChangeDisplaySettingsW( LPDEVMODEW devmode, DWORD flags ) +{ + return ChangeDisplaySettingsExW(NULL,devmode,NULL,flags,NULL); } /*********************************************************************** @@ -297,7 +278,6 @@ LONG WINAPI ChangeDisplaySettingsA( LPDEVMODEA devmode, DWORD flags ) */ LONG WINAPI ChangeDisplaySettings16( LPDEVMODEA devmode, DWORD flags ) { - TRACE_(system)("(%p,0x%08lx), stub\n",devmode,flags); return ChangeDisplaySettingsA(devmode, flags); } @@ -306,34 +286,47 @@ LONG WINAPI ChangeDisplaySettings16( LPDEVMODEA devmode, DWORD flags ) */ 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)) ) + DEVMODEW devmodeW; + LONG ret; + UNICODE_STRING nameW; - { + if (devname) RtlCreateUnicodeStringFromAsciiz(&nameW, devname); + else nameW.Buffer = NULL; - 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; + 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) 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 +337,7 @@ BOOL WINAPI EnumDisplaySettingsW( 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)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 +345,7 @@ BOOL WINAPI EnumDisplaySettingsW( */ 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 +356,6 @@ BOOL16 WINAPI EnumDisplaySettings16( 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 +365,25 @@ BOOL16 WINAPI EnumDisplaySettings16( 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; - return EnumDisplaySettingsA(lpszDeviceName, iModeNum, lpDevMode); + if (lpszDeviceName) RtlCreateUnicodeStringFromAsciiz(&nameW, lpszDeviceName); + else nameW.Buffer = NULL; + + 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 +392,9 @@ BOOL WINAPI EnumDisplaySettingsExA(LPCSTR lpszDeviceName, DWORD iModeNum, 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) return FALSE; + return USER_Driver.pEnumDisplaySettingsExW(lpszDeviceName, iModeNum, lpDevMode, dwFlags); } /***********************************************************************