/*
 * Multimonitor APIs
 *
 * Copyright 1998 Turchanov Sergey
 */

#include "monitor.h"
#include "winbase.h"
#include "winuser.h"

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

MONITOR_DRIVER *MONITOR_Driver;

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

#define xPRIMARY_MONITOR ((HMONITOR)0x12340042)

MONITOR MONITOR_PrimaryMonitor;

/***********************************************************************
 *              MONITOR_GetMonitor
 */
MONITOR *MONITOR_GetMonitor(HMONITOR hMonitor)
{
  if(hMonitor == xPRIMARY_MONITOR)
    {
      return &MONITOR_PrimaryMonitor;
    }
  else
    {
      return NULL;
    }
}

/***********************************************************************
 *              MONITOR_Initialize
 */
void MONITOR_Initialize(MONITOR *pMonitor)
{
  MONITOR_Driver->pInitialize(pMonitor);
}

/***********************************************************************
 *              MONITOR_Finalize
 */
void MONITOR_Finalize(MONITOR *pMonitor)
{
  MONITOR_Driver->pFinalize(pMonitor);
}

/***********************************************************************
 *              MONITOR_IsSingleWindow
 */
BOOL MONITOR_IsSingleWindow(MONITOR *pMonitor)
{
  return MONITOR_Driver->pIsSingleWindow(pMonitor);
}

/***********************************************************************
 *              MONITOR_GetWidth
 */
int MONITOR_GetWidth(MONITOR *pMonitor)
{
  return MONITOR_Driver->pGetWidth(pMonitor);
}

/***********************************************************************
 *              MONITOR_GetHeight
 */
int MONITOR_GetHeight(MONITOR *pMonitor)
{
  return MONITOR_Driver->pGetHeight(pMonitor);
}

/***********************************************************************
 *              MONITOR_GetDepth
 */
int MONITOR_GetDepth(MONITOR *pMonitor)
{
  return MONITOR_Driver->pGetDepth(pMonitor);
}

/***********************************************************************
 *              MONITOR_GetScreenSaveActive
 */
BOOL MONITOR_GetScreenSaveActive(MONITOR *pMonitor)
{
  return MONITOR_Driver->pGetScreenSaveActive(pMonitor);
}

/***********************************************************************
 *              MONITOR_SetScreenSaveActive
 */
void MONITOR_SetScreenSaveActive(MONITOR *pMonitor, BOOL bActivate)
{
  MONITOR_Driver->pSetScreenSaveActive(pMonitor, bActivate);
}

/***********************************************************************
 *              MONITOR_GetScreenSaveTimeout
 */
int MONITOR_GetScreenSaveTimeout(MONITOR *pMonitor)
{
  return MONITOR_Driver->pGetScreenSaveTimeout(pMonitor);
}

/***********************************************************************
 *              MONITOR_SetScreenSaveTimeout
 */
void MONITOR_SetScreenSaveTimeout(MONITOR *pMonitor, int nTimeout)
{
  MONITOR_Driver->pSetScreenSaveTimeout(pMonitor, nTimeout);
}


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

HMONITOR WINAPI MonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
{
    if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
        ((ptScreenCoords.x >= 0) &&
        (ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
        (ptScreenCoords.y >= 0) &&
        (ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
    {
        return xPRIMARY_MONITOR;
    }
        return NULL;
}

HMONITOR WINAPI MonitorFromRect(LPRECT lprcScreenCoords, DWORD dwFlags)
{
    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;
}

HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
{
    WINDOWPLACEMENT wp;

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

    if (IsIconic(hWnd) ? 
            GetWindowPlacement(hWnd, &wp) : 
            GetWindowRect(hWnd, &wp.rcNormalPosition)) {

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

    return NULL;
}

BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
{
    RECT rcWork;

    if ((hMonitor == xPRIMARY_MONITOR) &&
        lpMonitorInfo &&
        (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
        SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
    {
        lpMonitorInfo->rcMonitor.left = 0;
        lpMonitorInfo->rcMonitor.top  = 0;
        lpMonitorInfo->rcMonitor.right  = GetSystemMetrics(SM_CXSCREEN);
        lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
        lpMonitorInfo->rcWork = rcWork;
        lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
	
	if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXA))
            lstrcpyA(((MONITORINFOEXA*)lpMonitorInfo)->szDevice, "DISPLAY");

        return TRUE;
    }

    return FALSE;
}

BOOL WINAPI GetMonitorInfoW(HMONITOR hMonitor, LPMONITORINFO lpMonitorInfo)
{
    RECT rcWork;

    if ((hMonitor == xPRIMARY_MONITOR) &&
        lpMonitorInfo &&
        (lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
        SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWork, 0))
    {
        lpMonitorInfo->rcMonitor.left = 0;
        lpMonitorInfo->rcMonitor.top  = 0;
        lpMonitorInfo->rcMonitor.right  = GetSystemMetrics(SM_CXSCREEN);
        lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
        lpMonitorInfo->rcWork = rcWork;
        lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;

        if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEXW))
            lstrcpyW(((MONITORINFOEXW*)lpMonitorInfo)->szDevice, (LPCWSTR)"D\0I\0S\0P\0L\0A\0Y\0\0");

        return TRUE;
    }

    return FALSE;
}

BOOL WINAPI EnumDisplayMonitors(
        HDC             hdcOptionalForPainting,
        LPRECT         lprcEnumMonitorsThatIntersect,
        MONITORENUMPROC lpfnEnumProc,
        LPARAM          dwData)
{
    RECT rcLimit;

    if (!lpfnEnumProc)
        return FALSE;

    rcLimit.left   = 0;
    rcLimit.top    = 0;
    rcLimit.right  = GetSystemMetrics(SM_CXSCREEN);
    rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);

    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 thru */
        case NULLREGION:
             return TRUE;
        case ERROR:
             return FALSE;
        }
    } else {
        if (    lprcEnumMonitorsThatIntersect &&
                !IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {

            return TRUE;
        }
    }

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