Home | History | Annotate | Download | only in include
      1 /**
      2  * This file is part of the mingw-w64 runtime package.
      3  * No warranty is given; refer to the file DISCLAIMER within this package.
      4  */
      5 
      6 #include <winapifamily.h>
      7 
      8 #if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP)
      9 
     10 #ifdef __cplusplus
     11 extern "C" {
     12 #endif
     13 
     14 #ifndef SM_CMONITORS
     15 
     16 #define SM_XVIRTUALSCREEN 76
     17 #define SM_YVIRTUALSCREEN 77
     18 #define SM_CXVIRTUALSCREEN 78
     19 #define SM_CYVIRTUALSCREEN 79
     20 #define SM_CMONITORS 80
     21 #define SM_SAMEDISPLAYFORMAT 81
     22 
     23 #define MONITOR_DEFAULTTONULL 0x00000000
     24 #define MONITOR_DEFAULTTOPRIMARY 0x00000001
     25 #define MONITOR_DEFAULTTONEAREST 0x00000002
     26 
     27 #define MONITORINFOF_PRIMARY 0x00000001
     28 
     29   typedef struct tagMONITORINFO {
     30     DWORD cbSize;
     31     RECT rcMonitor;
     32     RECT rcWork;
     33     DWORD dwFlags;
     34   } MONITORINFO,*LPMONITORINFO;
     35 
     36 #ifndef CCHDEVICENAME
     37 #define CCHDEVICENAME 32
     38 #endif
     39 
     40 #ifdef __cplusplus
     41   typedef struct tagMONITORINFOEXA : public tagMONITORINFO {
     42     CHAR szDevice[CCHDEVICENAME];
     43   } MONITORINFOEXA,*LPMONITORINFOEXA;
     44 
     45   typedef struct tagMONITORINFOEXW : public tagMONITORINFO {
     46     WCHAR szDevice[CCHDEVICENAME];
     47   } MONITORINFOEXW,*LPMONITORINFOEXW;
     48 #else
     49   typedef struct tagMONITORINFOEXA {
     50     __C89_NAMELESS struct {
     51       DWORD cbSize;
     52       RECT rcMonitor;
     53       RECT rcWork;
     54       DWORD dwFlags;
     55     }; /* MONITORINFO */;
     56     CHAR szDevice[CCHDEVICENAME];
     57   } MONITORINFOEXA,*LPMONITORINFOEXA;
     58 
     59   typedef struct tagMONITORINFOEXW {
     60     __C89_NAMELESS struct {
     61       DWORD cbSize;
     62       RECT rcMonitor;
     63       RECT rcWork;
     64       DWORD dwFlags;
     65     }; /* MONITORINFO */;
     66     WCHAR szDevice[CCHDEVICENAME];
     67   } MONITORINFOEXW,*LPMONITORINFOEXW;
     68 #endif
     69   __MINGW_TYPEDEF_AW(MONITORINFOEX)
     70   __MINGW_TYPEDEF_AW(LPMONITORINFOEX)
     71 
     72   typedef WINBOOL (CALLBACK *MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
     73 
     74 #ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
     75   typedef struct _DISPLAY_DEVICEA {
     76     DWORD cb;
     77     CHAR DeviceName[32];
     78     CHAR DeviceString[128];
     79     DWORD StateFlags;
     80     CHAR DeviceID[128];
     81     CHAR DeviceKey[128];
     82   } DISPLAY_DEVICEA,*PDISPLAY_DEVICEA,*LPDISPLAY_DEVICEA;
     83 
     84   typedef struct _DISPLAY_DEVICEW {
     85     DWORD cb;
     86     WCHAR DeviceName[32];
     87     WCHAR DeviceString[128];
     88     DWORD StateFlags;
     89     WCHAR DeviceID[128];
     90     WCHAR DeviceKey[128];
     91   } DISPLAY_DEVICEW,*PDISPLAY_DEVICEW,*LPDISPLAY_DEVICEW;
     92 
     93   __MINGW_TYPEDEF_AW(DISPLAY_DEVICE)
     94   __MINGW_TYPEDEF_AW(PDISPLAY_DEVICE)
     95   __MINGW_TYPEDEF_AW(LPDISPLAY_DEVICE)
     96 
     97 #define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
     98 #define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002
     99 #define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004
    100 #define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
    101 #define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010
    102 #endif
    103 #endif
    104 
    105 #undef GetMonitorInfo
    106 #undef GetSystemMetrics
    107 #undef MonitorFromWindow
    108 #undef MonitorFromRect
    109 #undef MonitorFromPoint
    110 #undef EnumDisplayMonitors
    111 #undef EnumDisplayDevices
    112 
    113 #ifdef COMPILE_MULTIMON_STUBS
    114 
    115 #ifndef MULTIMON_FNS_DEFINED
    116   int (WINAPI *g_pfnGetSystemMetrics)(int) = NULL;
    117   HMONITOR (WINAPI *g_pfnMonitorFromWindow)(HWND, DWORD) = NULL;
    118   HMONITOR (WINAPI *g_pfnMonitorFromRect)(LPCRECT, DWORD) = NULL;
    119   HMONITOR (WINAPI *g_pfnMonitorFromPoint)(POINT, DWORD) = NULL;
    120   WINBOOL (WINAPI *g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;
    121   WINBOOL (WINAPI *g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM) = NULL;
    122   WINBOOL (WINAPI *g_pfnEnumDisplayDevices)(PVOID, DWORD, PDISPLAY_DEVICE, DWORD) = NULL;
    123   WINBOOL g_fMultiMonInitDone = FALSE;
    124   WINBOOL g_fMultimonPlatformNT = FALSE;
    125 #endif
    126 
    127   WINBOOL IsPlatformNT() {
    128     OSVERSIONINFOA oi = { 0 };
    129 
    130     oi.dwOSVersionInfoSize = sizeof (osvi);
    131     GetVersionExA ((OSVERSIONINFOA *) &oi);
    132     return (oi.dwPlatformId == VER_PLATFORM_WIN32_NT);
    133   }
    134 
    135   WINBOOL InitMultipleMonitorStubs(void) {
    136     HMODULE h;
    137 
    138     if (g_fMultiMonInitDone)
    139       return g_pfnGetMonitorInfo != NULL;
    140 
    141     g_fMultimonPlatformNT = IsPlatformNT ();
    142     h = GetModuleHandle (TEXT ("USER32"));
    143 
    144     if (h
    145         && (*((FARPROC *) &g_pfnGetSystemMetrics) = GetProcAddress (h, "GetSystemMetrics")) != NULL
    146 	&& (*((FARPROC *) &g_pfnMonitorFromWindow) = GetProcAddress (h, "MonitorFromWindow")) != NULL
    147 	&& (*((FARPROC *) &g_pfnMonitorFromRect) = GetProcAddress (h, "MonitorFromRect")) != NULL
    148 	&& (*((FARPROC *) &g_pfnMonitorFromPoint) = GetProcAddress (h, "MonitorFromPoint")) != NULL
    149 	&& (*((FARPROC *) &g_pfnEnumDisplayMonitors) = GetProcAddress (h, "EnumDisplayMonitors")) != NULL
    150 #ifdef UNICODE
    151         && (*((FARPROC *) &g_pfnEnumDisplayDevices) = GetProcAddress (h, "EnumDisplayDevicesW")) != NULL
    152 	&& (*((FARPROC *) &g_pfnGetMonitorInfo) = (g_fMultimonPlatformNT ? GetProcAddress (h, "GetMonitorInfoW") : GetProcAddress (h, "GetMonitorInfoA"))) != NULL
    153 #else
    154         && (*((FARPROC *) &g_pfnGetMonitorInfo) = GetProcAddress (h, "GetMonitorInfoA")) != NULL
    155 	&& (*((FARPROC *) &g_pfnEnumDisplayDevices) = GetProcAddress (h, "EnumDisplayDevicesA")) != NULL
    156 #endif
    157     ) {
    158       g_fMultiMonInitDone = TRUE;
    159       return TRUE;
    160     }
    161 
    162     g_pfnGetSystemMetrics = NULL;
    163     g_pfnMonitorFromWindow = NULL;
    164     g_pfnMonitorFromRect = NULL;
    165     g_pfnMonitorFromPoint = NULL;
    166     g_pfnGetMonitorInfo = NULL;
    167     g_pfnEnumDisplayMonitors = NULL;
    168     g_pfnEnumDisplayDevices = NULL;
    169     g_fMultiMonInitDone = TRUE;
    170     return FALSE;
    171   }
    172 
    173   int WINAPI xGetSystemMetrics(int n) {
    174     if (InitMultipleMonitorStubs ())
    175       return g_pfnGetSystemMetrics (n);
    176 
    177     switch (n) {
    178     case SM_CMONITORS:
    179     case SM_SAMEDISPLAYFORMAT:
    180       return 1;
    181     case SM_XVIRTUALSCREEN:
    182     case SM_YVIRTUALSCREEN:
    183       return 0;
    184     case SM_CXVIRTUALSCREEN:
    185       return GetSystemMetrics (SM_CXSCREEN);
    186     case SM_CYVIRTUALSCREEN:
    187       return GetSystemMetrics (SM_CYSCREEN);
    188     default:
    189       break;
    190     }
    191 
    192     return GetSystemMetrics (n);
    193   }
    194 
    195 #define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
    196 
    197   HMONITOR WINAPI xMonitorFromPoint (POINT pt, DWORD flags) {
    198     if (InitMultipleMonitorStubs ())
    199       return g_pfnMonitorFromPoint (pt, flags);
    200 
    201     if ((flags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) != 0
    202         || (pt.x >= 0 && pt.y >= 0 && pt.x < GetSystemMetrics (SM_CXSCREEN) && pt.y < GetSystemMetrics (SM_CYSCREEN)))
    203       return xPRIMARY_MONITOR;
    204 
    205     return NULL;
    206   }
    207 
    208   HMONITOR WINAPI xMonitorFromRect (LPCRECT pr, DWORD flags) {
    209     if (InitMultipleMonitorStubs ())
    210       return g_pfnMonitorFromRect (pr, flags);
    211 
    212     if ((flags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) != 0
    213         || (pr->right > 0 && pr->bottom > 0 && pr->left < GetSystemMetrics (SM_CXSCREEN) && pr->top < GetSystemMetrics (SM_CYSCREEN)))
    214       return xPRIMARY_MONITOR;
    215 
    216     return NULL;
    217   }
    218 
    219   HMONITOR WINAPI xMonitorFromWindow (HWND hw, DWORD flags) {
    220     WINDOWPLACEMENT wp;
    221 
    222     if (InitMultipleMonitorStubs ())
    223       return g_pfnMonitorFromWindow (hw, flags);
    224 
    225     if ((flags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) != 0)
    226       return xPRIMARY_MONITOR;
    227 
    228     if ((IsIconic (hw) ? GetWindowPlacement (hw, &wp) : GetWindowRect (hw, &wp.rcNormalPosition)) != 0)
    229       return xMonitorFromRect (&wp.rcNormalPosition, flags);
    230 
    231     return NULL;
    232   }
    233 
    234   WINBOOL WINAPI xGetMonitorInfo (HMONITOR hmon, LPMONITORINFO pmi) {
    235     RECT r;
    236     WINBOOL f;
    237     union { LPMONITORINFO mi; MONITORINFOEX ex; } c;
    238 
    239     c.mi = pmi;
    240     if (InitMultipleMonitorStubs ()) {
    241       f = g_pfnGetMonitorInfo (hmon, pmi);
    242 #ifdef UNICODE
    243       if (f && !g_fMultimonPlatformNT && pmi->cbSize >= sizeof (MONITORINFOEX))
    244 	MultiByteToWideChar (CP_ACP, 0, (LPSTR) c.ex->szDevice, -1, c.ex->szDevice, (sizeof (c.ex->szDevice) / 2));
    245 #endif
    246       return f;
    247     }
    248 
    249     if ((hmon == xPRIMARY_MONITOR) && pmi &&(pmi->cbSize >= sizeof (MONITORINFO)) && SystemParametersInfoA (SPI_GETWORKAREA, 0,&r, 0)) {
    250       pmi->rcMonitor.left = 0;
    251       pmi->rcMonitor.top = 0;
    252       pmi->rcMonitor.right = GetSystemMetrics (SM_CXSCREEN);
    253       pmi->rcMonitor.bottom = GetSystemMetrics (SM_CYSCREEN);
    254       pmi->rcWork = r;
    255       pmi->dwFlags = MONITORINFOF_PRIMARY;
    256       if (pmi->cbSize >= sizeof (MONITORINFOEX)) {
    257 #ifdef UNICODE
    258 	MultiByteToWideChar (CP_ACP, 0, "DISPLAY", -1, c.ex->szDevice, (sizeof (c.ex->szDevice) / 2));
    259 #else
    260 	lstrcpyn (c.ex->szDevice, "DISPLAY", sizeof (c.ex->szDevice));
    261 #endif
    262       }
    263 
    264       return TRUE;
    265     }
    266 
    267     return FALSE;
    268   }
    269 
    270   WINBOOL WINAPI xEnumDisplayMonitors (HDC hdcOptionalForPainting, LPCRECT lprcEnumMonitorsThatIntersect, MONITORENUMPROC lpfnEnumProc, LPARAM dwData) {
    271     RECT rcLimit, rcClip;
    272     POINT ptOrg;
    273 
    274     if (InitMultipleMonitorStubs ())
    275       return g_pfnEnumDisplayMonitors (hdcOptionalForPainting, lprcEnumMonitorsThatIntersect, lpfnEnumProc, dwData);
    276 
    277     if (!lpfnEnumProc)
    278       return FALSE;
    279 
    280     rcLimit.left = rcLimit.top = 0;
    281     rcLimit.right = GetSystemMetrics (SM_CXSCREEN);
    282     rcLimit.bottom = GetSystemMetrics (SM_CYSCREEN);
    283 
    284     if (hdcOptionalForPainting) {
    285       switch (GetClipBox (hdcOptionalForPainting,&rcClip)) {
    286       default:
    287 	if (!GetDCOrgEx (hdcOptionalForPainting,&ptOrg))
    288 	  return FALSE;
    289 
    290 	OffsetRect (&rcLimit, -ptOrg.x, -ptOrg.y);
    291 
    292 	if (IntersectRect (&rcLimit, &rcLimit, &rcClip)
    293 	    && (!lprcEnumMonitorsThatIntersect || IntersectRect (&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)))
    294 	  break;
    295 
    296       case NULLREGION:
    297 	return TRUE;
    298       case ERROR:
    299 	return FALSE;
    300       }
    301     } else if (lprcEnumMonitorsThatIntersect && !IntersectRect (&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))
    302       return TRUE;
    303 
    304     return lpfnEnumProc (xPRIMARY_MONITOR, hdcOptionalForPainting, &rcLimit, dwData);
    305   }
    306 
    307   WINBOOL WINAPI xEnumDisplayDevices (PVOID Unused, DWORD iDevNum, PDISPLAY_DEVICE lpDisplayDevice, DWORD flags) {
    308     if (InitMultipleMonitorStubs ())
    309       return g_pfnEnumDisplayDevices (Unused, iDevNum, lpDisplayDevice, flags);
    310     if (Unused || iDevNum || lpDisplayDevice == NULL || lpDisplayDevice->cb < sizeof (DISPLAY_DEVICE))
    311       return FALSE;
    312 #ifdef UNICODE
    313     MultiByteToWideChar (CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceName, (sizeof (lpDisplayDevice->DeviceName) / 2));
    314     MultiByteToWideChar (CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceString, (sizeof (lpDisplayDevice->DeviceString) / 2));
    315 #else
    316     lstrcpyn ((LPTSTR)lpDisplayDevice->DeviceName, "DISPLAY", sizeof (lpDisplayDevice->DeviceName));
    317     lstrcpyn ((LPTSTR)lpDisplayDevice->DeviceString, "DISPLAY", sizeof (lpDisplayDevice->DeviceString));
    318 #endif
    319     lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE;
    320 
    321     return TRUE;
    322   }
    323 
    324 #undef xPRIMARY_MONITOR
    325 #undef COMPILE_MULTIMON_STUBS
    326 #else
    327   extern int WINAPI xGetSystemMetrics (int);
    328   extern HMONITOR WINAPI xMonitorFromWindow (HWND, DWORD);
    329   extern HMONITOR WINAPI xMonitorFromRect (LPCRECT, DWORD);
    330   extern HMONITOR WINAPI xMonitorFromPoint (POINT, DWORD);
    331   extern WINBOOL WINAPI xGetMonitorInfo (HMONITOR, LPMONITORINFO);
    332   extern WINBOOL WINAPI xEnumDisplayMonitors (HDC, LPCRECT, MONITORENUMPROC, LPARAM);
    333   extern WINBOOL WINAPI xEnumDisplayDevices (PVOID, DWORD, PDISPLAY_DEVICE, DWORD);
    334 #endif
    335 
    336 #define GetSystemMetrics xGetSystemMetrics
    337 #define MonitorFromWindow xMonitorFromWindow
    338 #define MonitorFromRect xMonitorFromRect
    339 #define MonitorFromPoint xMonitorFromPoint
    340 #define GetMonitorInfo xGetMonitorInfo
    341 #define EnumDisplayMonitors xEnumDisplayMonitors
    342 #define EnumDisplayDevices xEnumDisplayDevices
    343 
    344 #ifdef __cplusplus
    345 }
    346 #endif
    347 
    348 #endif
    349