multimon.c 4.99 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3 4 5 6
/*
 * Multimonitor APIs
 *
 * Copyright 1998 Turchanov Sergey
 */

7
#include <string.h>
8 9
#include "windef.h"
#include "wingdi.h"
10 11
#include "winbase.h"
#include "winuser.h"
12
#include "wine/unicode.h"
13 14 15

/**********************************************************************/

Alexandre Julliard's avatar
Alexandre Julliard committed
16 17
#define xPRIMARY_MONITOR ((HMONITOR)0x12340042)

18
/***********************************************************************
19
 *		MonitorFromPoint (USER32.@)
20
 */
21
HMONITOR WINAPI MonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
Alexandre Julliard's avatar
Alexandre Julliard committed
22 23 24
{
    if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
        ((ptScreenCoords.x >= 0) &&
25
        (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
Alexandre Julliard's avatar
Alexandre Julliard committed
26
        (ptScreenCoords.y >= 0) &&
27
        (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
Alexandre Julliard's avatar
Alexandre Julliard committed
28 29 30
    {
        return xPRIMARY_MONITOR;
    }
31
    return (HMONITOR)0;
Alexandre Julliard's avatar
Alexandre Julliard committed
32 33
}

34
/***********************************************************************
35
 *		MonitorFromRect (USER32.@)
36
 */
37
HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags)
Alexandre Julliard's avatar
Alexandre Julliard committed
38 39 40 41
{
    if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
        ((lprcScreenCoords->right > 0) &&
        (lprcScreenCoords->bottom > 0) &&
42 43
        (lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
        (lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
Alexandre Julliard's avatar
Alexandre Julliard committed
44 45 46
    {
        return xPRIMARY_MONITOR;
    }
47
    return (HMONITOR)0;
Alexandre Julliard's avatar
Alexandre Julliard committed
48 49
}

50
/***********************************************************************
51
 *		MonitorFromWindow (USER32.@)
52
 */
53
HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
Alexandre Julliard's avatar
Alexandre Julliard committed
54
{
55
    WINDOWPLACEMENT wp;
Alexandre Julliard's avatar
Alexandre Julliard committed
56 57 58 59

    if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
        return xPRIMARY_MONITOR;

60 61 62
    if (IsIconic(hWnd) ? 
            GetWindowPlacement(hWnd, &wp) : 
            GetWindowRect(hWnd, &wp.rcNormalPosition)) {
Alexandre Julliard's avatar
Alexandre Julliard committed
63 64 65 66

        return MonitorFromRect(&wp.rcNormalPosition, dwFlags);
    }

67
    return (HMONITOR)0;
Alexandre Julliard's avatar
Alexandre Julliard committed
68 69
}

70
/***********************************************************************
71
 *		GetMonitorInfoA (USER32.@)
72
 */
73
BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
Alexandre Julliard's avatar
Alexandre Julliard committed
74
{
75
    RECT rcWork;
Alexandre Julliard's avatar
Alexandre Julliard committed
76 77 78 79

    if ((hMonitor == xPRIMARY_MONITOR) &&
        lpMonitorInfo &&
        (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
80
        SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
Alexandre Julliard's avatar
Alexandre Julliard committed
81
    {
82 83 84
        SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
                 GetSystemMetrics(SM_CXSCREEN),
                 GetSystemMetrics(SM_CYSCREEN) );
Alexandre Julliard's avatar
Alexandre Julliard committed
85 86 87
        lpMonitorInfo->rcWork = rcWork;
        lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
	
88
	if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXA))
89
            strcpy(((MONITORINFOEXA*)lpMonitorInfo)->szDevice, "DISPLAY");
Alexandre Julliard's avatar
Alexandre Julliard committed
90 91 92 93 94 95 96

        return TRUE;
    }

    return FALSE;
}

97
/***********************************************************************
98
 *		GetMonitorInfoW (USER32.@)
99
 */
100
BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
Alexandre Julliard's avatar
Alexandre Julliard committed
101
{
102
    RECT rcWork;
Alexandre Julliard's avatar
Alexandre Julliard committed
103 104 105 106

    if ((hMonitor == xPRIMARY_MONITOR) &&
        lpMonitorInfo &&
        (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
107
        SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWork, 0))
Alexandre Julliard's avatar
Alexandre Julliard committed
108
    {
109 110 111
        SetRect( &lpMonitorInfo->rcMonitor, 0, 0,
                 GetSystemMetrics(SM_CXSCREEN),
                 GetSystemMetrics(SM_CYSCREEN) );
Alexandre Julliard's avatar
Alexandre Julliard committed
112 113 114
        lpMonitorInfo->rcWork = rcWork;
        lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;

115
        if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW))
116
            strcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, (LPCWSTR)"D\0I\0S\0P\0L\0A\0Y\0\0");
Alexandre Julliard's avatar
Alexandre Julliard committed
117 118 119 120 121 122 123

        return TRUE;
    }

    return FALSE;
}

124
/***********************************************************************
125
 *		EnumDisplayMonitors (USER32.@)
126
 */
127 128 129
BOOL WINAPI EnumDisplayMonitors(
        HDC             hdcOptionalForPainting,
        LPRECT         lprcEnumMonitorsThatIntersect,
Alexandre Julliard's avatar
Alexandre Julliard committed
130 131 132
        MONITORENUMPROC lpfnEnumProc,
        LPARAM          dwData)
{
133 134 135
    RECT rcLimit;
    SetRect( &rcLimit, 0, 0, GetSystemMetrics(SM_CXSCREEN),
             GetSystemMetrics(SM_CYSCREEN) );
Alexandre Julliard's avatar
Alexandre Julliard committed
136 137 138 139 140 141

    if (!lpfnEnumProc)
        return FALSE;

    if (hdcOptionalForPainting)
    {
142 143
        RECT    rcClip;
        POINT   ptOrg;
Alexandre Julliard's avatar
Alexandre Julliard committed
144

145
        switch (GetClipBox(hdcOptionalForPainting, &rcClip))
Alexandre Julliard's avatar
Alexandre Julliard committed
146 147 148 149 150
        {
        default:
            if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
                return FALSE;

151 152
            OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
            if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
Alexandre Julliard's avatar
Alexandre Julliard committed
153
                (!lprcEnumMonitorsThatIntersect ||
154
                     IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
Alexandre Julliard's avatar
Alexandre Julliard committed
155 156 157

                break;
            }
158
            /* fall through */
Alexandre Julliard's avatar
Alexandre Julliard committed
159 160 161 162 163 164 165
        case NULLREGION:
             return TRUE;
        case ERROR:
             return FALSE;
        }
    } else {
        if (    lprcEnumMonitorsThatIntersect &&
166
                !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
Alexandre Julliard's avatar
Alexandre Julliard committed
167 168 169 170 171 172 173 174 175 176 177

            return TRUE;
        }
    }

    return lpfnEnumProc(
            xPRIMARY_MONITOR,
            hdcOptionalForPainting,
            &rcLimit,
            dwData);
}