user: Moved GetMonitorInfo and EnumDisplayMonitors to the display driver.
Added Xinerama support for these functions.
This commit is contained in:
parent
3c305f9db9
commit
8a8903516c
|
@ -101,7 +101,9 @@ static const USER_DRIVER *load_driver(void)
|
|||
GET_USER_FUNC(GetClipboardFormatName);
|
||||
GET_USER_FUNC(EndClipboardUpdate);
|
||||
GET_USER_FUNC(ChangeDisplaySettingsEx);
|
||||
GET_USER_FUNC(EnumDisplayMonitors);
|
||||
GET_USER_FUNC(EnumDisplaySettingsEx);
|
||||
GET_USER_FUNC(GetMonitorInfo);
|
||||
GET_USER_FUNC(CreateDesktopWindow);
|
||||
GET_USER_FUNC(CreateWindow);
|
||||
GET_USER_FUNC(DestroyWindow);
|
||||
|
@ -290,11 +292,21 @@ static LONG nulldrv_ChangeDisplaySettingsEx( LPCWSTR name, LPDEVMODEW mode, HWND
|
|||
return DISP_CHANGE_FAILED;
|
||||
}
|
||||
|
||||
static BOOL nulldrv_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL nulldrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL nulldrv_GetMonitorInfo( HMONITOR handle, LPMONITORINFO info )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL nulldrv_CreateDesktopWindow( HWND hwnd )
|
||||
{
|
||||
return TRUE;
|
||||
|
@ -435,7 +447,9 @@ static const USER_DRIVER null_driver =
|
|||
nulldrv_SetClipboardData,
|
||||
/* display modes */
|
||||
nulldrv_ChangeDisplaySettingsEx,
|
||||
nulldrv_EnumDisplayMonitors,
|
||||
nulldrv_EnumDisplaySettingsEx,
|
||||
nulldrv_GetMonitorInfo,
|
||||
/* windowing functions */
|
||||
nulldrv_CreateDesktopWindow,
|
||||
nulldrv_CreateWindow,
|
||||
|
@ -612,11 +626,21 @@ static LONG loaderdrv_ChangeDisplaySettingsEx( LPCWSTR name, LPDEVMODEW mode, HW
|
|||
return load_driver()->pChangeDisplaySettingsEx( name, mode, hwnd, flags, lparam );
|
||||
}
|
||||
|
||||
static BOOL loaderdrv_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
|
||||
{
|
||||
return load_driver()->pEnumDisplayMonitors( hdc, rect, proc, lp );
|
||||
}
|
||||
|
||||
static BOOL loaderdrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags )
|
||||
{
|
||||
return load_driver()->pEnumDisplaySettingsEx( name, num, mode, flags );
|
||||
}
|
||||
|
||||
static BOOL loaderdrv_GetMonitorInfo( HMONITOR handle, LPMONITORINFO info )
|
||||
{
|
||||
return load_driver()->pGetMonitorInfo( handle, info );
|
||||
}
|
||||
|
||||
static BOOL loaderdrv_CreateDesktopWindow( HWND hwnd )
|
||||
{
|
||||
return load_driver()->pCreateDesktopWindow( hwnd );
|
||||
|
@ -745,7 +769,9 @@ static const USER_DRIVER lazy_load_driver =
|
|||
loaderdrv_SetClipboardData,
|
||||
/* display modes */
|
||||
loaderdrv_ChangeDisplaySettingsEx,
|
||||
loaderdrv_EnumDisplayMonitors,
|
||||
loaderdrv_EnumDisplaySettingsEx,
|
||||
loaderdrv_GetMonitorInfo,
|
||||
/* windowing functions */
|
||||
loaderdrv_CreateDesktopWindow,
|
||||
loaderdrv_CreateWindow,
|
||||
|
|
181
dlls/user/misc.c
181
dlls/user/misc.c
|
@ -29,6 +29,7 @@
|
|||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "winternl.h"
|
||||
#include "user_private.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
@ -56,8 +57,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(win);
|
|||
#define USIG_PROCESS_RUNNING 0x0500
|
||||
#define USIG_PROCESS_LOADED 0x0600
|
||||
|
||||
#define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
|
||||
|
||||
/***********************************************************************
|
||||
* SignalProc32 (USER.391)
|
||||
* UserSignalProc (USER32.@)
|
||||
|
@ -339,36 +338,85 @@ BOOL WINAPI EnumDisplayDevicesW( LPCWSTR lpDevice, DWORD i, LPDISPLAY_DEVICEW lp
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MonitorFromPoint (USER32.@)
|
||||
*/
|
||||
HMONITOR WINAPI MonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
|
||||
struct monitor_enum_info
|
||||
{
|
||||
if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
|
||||
((ptScreenCoords.x >= 0) &&
|
||||
(ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
|
||||
(ptScreenCoords.y >= 0) &&
|
||||
(ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
|
||||
RECT rect;
|
||||
UINT max_area;
|
||||
UINT min_distance;
|
||||
HMONITOR primary;
|
||||
HMONITOR ret;
|
||||
};
|
||||
|
||||
/* helper callback for MonitorFromRect */
|
||||
static BOOL CALLBACK monitor_enum( HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM lp )
|
||||
{
|
||||
struct monitor_enum_info *info = (struct monitor_enum_info *)lp;
|
||||
RECT intersect;
|
||||
|
||||
if (IntersectRect( &intersect, rect, &info->rect ))
|
||||
{
|
||||
return xPRIMARY_MONITOR;
|
||||
/* check for larger intersecting area */
|
||||
UINT area = (intersect.right - intersect.left) * (intersect.bottom - intersect.top);
|
||||
if (area > info->max_area)
|
||||
{
|
||||
info->max_area = area;
|
||||
info->ret = monitor;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
else if (!info->max_area) /* if not intersecting, check for min distance */
|
||||
{
|
||||
UINT distance;
|
||||
INT x, y;
|
||||
|
||||
if (rect->left >= info->rect.right) x = info->rect.right - rect->left;
|
||||
else x = rect->right - info->rect.left;
|
||||
if (rect->top >= info->rect.bottom) y = info->rect.bottom - rect->top;
|
||||
else y = rect->bottom - info->rect.top;
|
||||
distance = x * x + y * y;
|
||||
if (distance < info->min_distance)
|
||||
{
|
||||
info->min_distance = distance;
|
||||
info->ret = monitor;
|
||||
}
|
||||
}
|
||||
if (!info->primary)
|
||||
{
|
||||
MONITORINFO mon_info;
|
||||
mon_info.cbSize = sizeof(mon_info);
|
||||
GetMonitorInfoW( monitor, &mon_info );
|
||||
if (mon_info.dwFlags & MONITORINFOF_PRIMARY) info->primary = monitor;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MonitorFromRect (USER32.@)
|
||||
*/
|
||||
HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags)
|
||||
HMONITOR WINAPI MonitorFromRect( LPRECT rect, DWORD flags )
|
||||
{
|
||||
if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
|
||||
((lprcScreenCoords->right > 0) &&
|
||||
(lprcScreenCoords->bottom > 0) &&
|
||||
(lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
|
||||
(lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
|
||||
{
|
||||
return xPRIMARY_MONITOR;
|
||||
}
|
||||
return NULL;
|
||||
struct monitor_enum_info info;
|
||||
|
||||
info.rect = *rect;
|
||||
info.max_area = 0;
|
||||
info.min_distance = ~0u;
|
||||
info.primary = 0;
|
||||
info.ret = 0;
|
||||
if (!EnumDisplayMonitors( 0, NULL, monitor_enum, (LPARAM)&info )) return 0;
|
||||
if (!info.ret && (flags & MONITOR_DEFAULTTOPRIMARY)) info.ret = info.primary;
|
||||
|
||||
TRACE( "%s flags %x returning %p\n", wine_dbgstr_rect(rect), flags, info.ret );
|
||||
return info.ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MonitorFromPoint (USER32.@)
|
||||
*/
|
||||
HMONITOR WINAPI MonitorFromPoint( POINT pt, DWORD flags )
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
SetRect( &rect, pt.x, pt.y, pt.x + 1, pt.y + 1 );
|
||||
return MonitorFromRect( &rect, flags );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -376,19 +424,14 @@ HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags)
|
|||
*/
|
||||
HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
|
||||
{
|
||||
RECT rect;
|
||||
WINDOWPLACEMENT wp;
|
||||
|
||||
if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
|
||||
return xPRIMARY_MONITOR;
|
||||
if (IsIconic(hWnd) && GetWindowPlacement(hWnd, &wp))
|
||||
return MonitorFromRect( &wp.rcNormalPosition, dwFlags );
|
||||
|
||||
if (IsIconic(hWnd) ?
|
||||
GetWindowPlacement(hWnd, &wp) :
|
||||
GetWindowRect(hWnd, &wp.rcNormalPosition)) {
|
||||
|
||||
return MonitorFromRect(&wp.rcNormalPosition, dwFlags);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
GetWindowRect( hWnd, &rect );
|
||||
return MonitorFromRect( &rect, dwFlags );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -418,81 +461,15 @@ BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
|
|||
*/
|
||||
BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
|
||||
{
|
||||
RECT rcWork;
|
||||
|
||||
if ((hMonitor == xPRIMARY_MONITOR) &&
|
||||
lpMonitorInfo &&
|
||||
(lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
|
||||
SystemParametersInfoW(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(MONITORINFOEXW))
|
||||
strcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, primary_device_name);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return USER_Driver->pGetMonitorInfo( hMonitor, lpMonitorInfo );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* EnumDisplayMonitors (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI EnumDisplayMonitors(
|
||||
HDC hdcOptionalForPainting,
|
||||
LPRECT lprcEnumMonitorsThatIntersect,
|
||||
MONITORENUMPROC lpfnEnumProc,
|
||||
LPARAM dwData)
|
||||
BOOL WINAPI EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
|
||||
{
|
||||
RECT rcLimit;
|
||||
SetRect( &rcLimit, 0, 0, GetSystemMetrics(SM_CXSCREEN),
|
||||
GetSystemMetrics(SM_CYSCREEN) );
|
||||
|
||||
if (!lpfnEnumProc)
|
||||
return FALSE;
|
||||
|
||||
if (hdcOptionalForPainting)
|
||||
{
|
||||
RECT rcClip;
|
||||
POINT ptOrg;
|
||||
|
||||
switch (GetClipBox(hdcOptionalForPainting, &rcClip))
|
||||
{
|
||||
default:
|
||||
if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
|
||||
return FALSE;
|
||||
|
||||
OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
|
||||
if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
|
||||
(!lprcEnumMonitorsThatIntersect ||
|
||||
IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
|
||||
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case NULLREGION:
|
||||
return TRUE;
|
||||
case ERROR:
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if ( lprcEnumMonitorsThatIntersect &&
|
||||
!IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return lpfnEnumProc(
|
||||
xPRIMARY_MONITOR,
|
||||
hdcOptionalForPainting,
|
||||
&rcLimit,
|
||||
dwData);
|
||||
return USER_Driver->pEnumDisplayMonitors( hdc, rect, proc, lp );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -134,7 +134,9 @@ typedef struct tagUSER_DRIVER {
|
|||
BOOL (*pSetClipboardData)(UINT, HANDLE16, HANDLE, BOOL); /* Set specified selection data */
|
||||
/* display modes */
|
||||
LONG (*pChangeDisplaySettingsEx)(LPCWSTR,LPDEVMODEW,HWND,DWORD,LPVOID);
|
||||
BOOL (*pEnumDisplayMonitors)(HDC,LPRECT,MONITORENUMPROC,LPARAM);
|
||||
BOOL (*pEnumDisplaySettingsEx)(LPCWSTR,DWORD,LPDEVMODEW,DWORD);
|
||||
BOOL (*pGetMonitorInfo)(HMONITOR,MONITORINFO*);
|
||||
/* windowing functions */
|
||||
BOOL (*pCreateDesktopWindow)(HWND);
|
||||
BOOL (*pCreateWindow)(HWND,CREATESTRUCTA*,BOOL);
|
||||
|
|
|
@ -82,7 +82,9 @@
|
|||
@ cdecl GetScreenSaveActive() X11DRV_GetScreenSaveActive
|
||||
@ cdecl SetScreenSaveActive(long) X11DRV_SetScreenSaveActive
|
||||
@ 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 AcquireClipboard(long) X11DRV_AcquireClipboard
|
||||
@ cdecl CountClipboardFormats() X11DRV_CountClipboardFormats
|
||||
@ cdecl CreateDesktopWindow(long) X11DRV_CreateDesktopWindow
|
||||
|
|
|
@ -53,6 +53,19 @@ static inline MONITORINFOEXW *get_primary(void)
|
|||
return &monitors[idx];
|
||||
}
|
||||
|
||||
static inline HMONITOR index_to_monitor( int index )
|
||||
{
|
||||
return (HMONITOR)(UINT_PTR)(index + 1);
|
||||
}
|
||||
|
||||
static inline int monitor_to_index( HMONITOR handle )
|
||||
{
|
||||
UINT_PTR index = (UINT_PTR)handle;
|
||||
if (index < 1 || index > nb_monitors) return -1;
|
||||
return index - 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_LIBXINERAMA
|
||||
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
|
@ -110,8 +123,8 @@ static int query_screens(void)
|
|||
get_primary()->dwFlags |= MONITORINFOF_PRIMARY;
|
||||
|
||||
for (i = 0; i < nb_monitors; i++)
|
||||
TRACE( "monitor %d: %s%s\n",
|
||||
i, wine_dbgstr_rect(&monitors[i].rcMonitor),
|
||||
TRACE( "monitor %p: %s%s\n",
|
||||
index_to_monitor(i), wine_dbgstr_rect(&monitors[i].rcMonitor),
|
||||
(monitors[i].dwFlags & MONITORINFOF_PRIMARY) ? " (primary)" : "" );
|
||||
}
|
||||
else count = 0;
|
||||
|
@ -154,3 +167,62 @@ void xinerama_init(void)
|
|||
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_GetMonitorInfo (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_GetMonitorInfo( HMONITOR handle, LPMONITORINFO info )
|
||||
{
|
||||
int i = monitor_to_index( handle );
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
info->rcMonitor = monitors[i].rcMonitor;
|
||||
info->rcWork = monitors[i].rcWork;
|
||||
info->dwFlags = monitors[i].dwFlags;
|
||||
if (info->cbSize >= sizeof(MONITORINFOEXW))
|
||||
lstrcpyW( ((MONITORINFOEXW *)info)->szDevice, monitors[i].szDevice );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_EnumDisplayMonitors (X11DRV.@)
|
||||
*/
|
||||
BOOL X11DRV_EnumDisplayMonitors( HDC hdc, LPRECT rect, MONITORENUMPROC proc, LPARAM lp )
|
||||
{
|
||||
int i;
|
||||
|
||||
if (hdc)
|
||||
{
|
||||
POINT origin;
|
||||
RECT limit;
|
||||
|
||||
if (!GetDCOrgEx( hdc, &origin )) return FALSE;
|
||||
if (GetClipBox( hdc, &limit ) == ERROR) return FALSE;
|
||||
|
||||
if (rect && !IntersectRect( &limit, &limit, rect )) return TRUE;
|
||||
|
||||
for (i = 0; i < nb_monitors; i++)
|
||||
{
|
||||
RECT monrect = monitors[i].rcMonitor;
|
||||
OffsetRect( &monrect, -origin.x, -origin.y );
|
||||
if (IntersectRect( &monrect, &monrect, &limit ))
|
||||
if (!proc( index_to_monitor(i), hdc, &monrect, lp )) break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < nb_monitors; i++)
|
||||
{
|
||||
RECT unused;
|
||||
if (!rect || IntersectRect( &unused, &monitors[i].rcMonitor, rect ))
|
||||
if (!proc( index_to_monitor(i), 0, &monitors[i].rcMonitor, lp )) break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue