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