/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include "../SDL_sysvideo.h"

#define INCL_DOSERRORS
#define INCL_DOSPROCESS
#define INCL_DOSMODULEMGR
#define INCL_WIN
#define INCL_GPI
#define INCL_GPIBITMAPS /* GPI bit map functions */
#include <os2.h>
#include "SDL_os2output.h"
#include "SDL_os2video.h"

#include "SDL_gradd.h"

typedef struct _VODATA {
  PVOID    pBuffer;
  HRGN     hrgnVisible;
  ULONG    ulBPP;
  ULONG    ulScanLineSize;
  ULONG    ulWidth;
  ULONG    ulHeight;
  ULONG    ulScreenHeight;
  ULONG    ulScreenBytesPerLine;
  RECTL    rectlWin;

  PRECTL   pRectl;
  ULONG    cRectl;
  PBLTRECT pBltRect;
  ULONG    cBltRect;
} VODATA;

static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo);
static PVODATA voOpen();
static VOID voClose(PVODATA pVOData);
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
                               SDL_DisplayMode *pSDLDisplayMode,
                               HRGN hrgnShape, BOOL fVisible);
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
                             ULONG ulBPP, ULONG fccColorEncoding,
                             PULONG pulScanLineSize);
static VOID voVideoBufFree(PVODATA pVOData);
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
                     ULONG cSDLRects);

OS2VIDEOOUTPUT voVMan = {
    voQueryInfo,
    voOpen,
    voClose,
    voSetVisibleRegion,
    voVideoBufAlloc,
    voVideoBufFree,
    voUpdate
};


static HMODULE  hmodVMan = NULLHANDLE;
static FNVMIENTRY *pfnVMIEntry = NULL;
static ULONG        ulVRAMAddress = 0;

VOID APIENTRY ExitVMan(VOID)
{
    if (ulVRAMAddress != 0 && hmodVMan != NULLHANDLE) {
        pfnVMIEntry(0, VMI_CMD_TERMPROC, NULL, NULL);
        DosFreeModule(hmodVMan);
    }

    DosExitList(EXLST_EXIT, (PFNEXITLIST)NULL);
}

static BOOL _vmanInit(void)
{
    ULONG       ulRC;
    CHAR        acBuf[255];
    INITPROCOUT stInitProcOut;

    if (hmodVMan != NULLHANDLE) /* Already was initialized */
        return TRUE;

    /* Load vman.dll */
    ulRC = DosLoadModule(acBuf, sizeof(acBuf), "VMAN", &hmodVMan);
    if (ulRC != NO_ERROR) {
        debug_os2("Could not load VMAN.DLL, rc = %u : %s", ulRC, acBuf);
        hmodVMan = NULLHANDLE;
        return FALSE;
    }

    /* Get VMIEntry */
    ulRC = DosQueryProcAddr(hmodVMan, 0L, "VMIEntry", (PFN *)&pfnVMIEntry);
    if (ulRC != NO_ERROR) {
        debug_os2("Could not query address of pfnVMIEntry func. of VMAN.DLL, "
                  "rc = %u", ulRC);
        DosFreeModule(hmodVMan);
        hmodVMan = NULLHANDLE;
        return FALSE;
    }

    /* VMAN initialization */
    stInitProcOut.ulLength = sizeof(stInitProcOut);
    ulRC = pfnVMIEntry(0, VMI_CMD_INITPROC, NULL, &stInitProcOut);
    if (ulRC != RC_SUCCESS) {
        debug_os2("Could not initialize VMAN for this process");
        pfnVMIEntry = NULL;
        DosFreeModule(hmodVMan);
        hmodVMan = NULLHANDLE;
        return FALSE;
    }

    /* Store video memory virtual address */
    ulVRAMAddress = stInitProcOut.ulVRAMVirt;
    /* We use exit list for VMI_CMD_TERMPROC */
    if (DosExitList(EXLST_ADD | 0x00001000, (PFNEXITLIST)ExitVMan) != NO_ERROR) {
        debug_os2("DosExitList() failed");
    }

    return TRUE;
}

static PRECTL _getRectlArray(PVODATA pVOData, ULONG cRects)
{
    PRECTL  pRectl;

    if (pVOData->cRectl >= cRects)
        return pVOData->pRectl;

    pRectl = SDL_realloc(pVOData->pRectl, cRects * sizeof(RECTL));
    if (pRectl == NULL)
        return NULL;

    pVOData->pRectl = pRectl;
    pVOData->cRectl = cRects;
    return pRectl;
}

static PBLTRECT _getBltRectArray(PVODATA pVOData, ULONG cRects)
{
    PBLTRECT    pBltRect;

    if (pVOData->cBltRect >= cRects)
        return pVOData->pBltRect;

    pBltRect = SDL_realloc(pVOData->pBltRect, cRects * sizeof(BLTRECT));
    if (pBltRect == NULL)
        return NULL;

    pVOData->pBltRect = pBltRect;
    pVOData->cBltRect = cRects;
    return pBltRect;
}


static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo)
{
    ULONG       ulRC;
    GDDMODEINFO sCurModeInfo;

    if (!_vmanInit())
        return FALSE;

    /* Query current (desktop) mode */
    ulRC = pfnVMIEntry(0, VMI_CMD_QUERYCURRENTMODE, NULL, &sCurModeInfo);
    if (ulRC != RC_SUCCESS) {
        debug_os2("Could not query desktop video mode.");
        return FALSE;
    }

    pInfo->ulBPP             = sCurModeInfo.ulBpp;
    pInfo->ulHorizResolution = sCurModeInfo.ulHorizResolution;
    pInfo->ulVertResolution  = sCurModeInfo.ulVertResolution;
    pInfo->ulScanLineSize    = sCurModeInfo.ulScanLineSize;
    pInfo->fccColorEncoding  = sCurModeInfo.fccColorEncoding;

    return TRUE;
}

static PVODATA voOpen(void)
{
    PVODATA pVOData;

    if (!_vmanInit())
        return NULL;

    pVOData = SDL_calloc(1, sizeof(VODATA));
    if (pVOData == NULL) {
        SDL_OutOfMemory();
        return NULL;
    }

    return pVOData;
}

static VOID voClose(PVODATA pVOData)
{
    if (pVOData->pRectl != NULL)
        SDL_free(pVOData->pRectl);

    if (pVOData->pBltRect != NULL)
        SDL_free(pVOData->pBltRect);

    voVideoBufFree(pVOData);
}

static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
                               SDL_DisplayMode *pSDLDisplayMode,
                               HRGN hrgnShape, BOOL fVisible)
{
    HPS   hps;
    BOOL  fSuccess = FALSE;

    hps = WinGetPS(hwnd);

    if (pVOData->hrgnVisible != NULLHANDLE) {
        GpiDestroyRegion(hps, pVOData->hrgnVisible);
        pVOData->hrgnVisible = NULLHANDLE;
    }

    if (fVisible) {
        /* Query visible rectangles */
        pVOData->hrgnVisible = GpiCreateRegion(hps, 0, NULL);
        if (pVOData->hrgnVisible == NULLHANDLE) {
            SDL_SetError("GpiCreateRegion() failed");
        } else {
            if (WinQueryVisibleRegion(hwnd, pVOData->hrgnVisible) == RGN_ERROR) {
                GpiDestroyRegion(hps, pVOData->hrgnVisible);
                pVOData->hrgnVisible = NULLHANDLE;
            } else {
                if (hrgnShape != NULLHANDLE)
                    GpiCombineRegion(hps, pVOData->hrgnVisible, pVOData->hrgnVisible,
                                     hrgnShape, CRGN_AND);
                fSuccess = TRUE;
            }
        }

        WinQueryWindowRect(hwnd, &pVOData->rectlWin);
        WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL)&pVOData->rectlWin, 2);

        if (pSDLDisplayMode != NULL) {
            pVOData->ulScreenHeight = pSDLDisplayMode->h;
            pVOData->ulScreenBytesPerLine =
                     ((MODEDATA *)pSDLDisplayMode->driverdata)->ulScanLineBytes;
        }
    }

    WinReleasePS(hps);

    return fSuccess;
}

static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
                             ULONG ulBPP, ULONG fccColorEncoding,
                             PULONG pulScanLineSize)
{
    ULONG ulRC;
    ULONG ulScanLineSize = ulWidth * (ulBPP >> 3);

    /* Destroy previous buffer */
    voVideoBufFree(pVOData);

    if (ulWidth == 0 || ulHeight == 0 || ulBPP == 0)
        return NULL;

    /* Bytes per line */
    ulScanLineSize  = (ulScanLineSize + 3) & ~3; /* 4-byte aligning */
    *pulScanLineSize = ulScanLineSize;

    ulRC = DosAllocMem(&pVOData->pBuffer,
                       (ulHeight * ulScanLineSize) + sizeof(ULONG),
                       PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE);
    if (ulRC != NO_ERROR) {
        debug_os2("DosAllocMem(), rc = %u", ulRC);
        return NULL;
    }

    pVOData->ulBPP          = ulBPP;
    pVOData->ulScanLineSize = ulScanLineSize;
    pVOData->ulWidth        = ulWidth;
    pVOData->ulHeight       = ulHeight;

    return pVOData->pBuffer;
}

static VOID voVideoBufFree(PVODATA pVOData)
{
    ULONG ulRC;

    if (pVOData->pBuffer == NULL)
        return;

    ulRC = DosFreeMem(pVOData->pBuffer);
    if (ulRC != NO_ERROR) {
        debug_os2("DosFreeMem(), rc = %u", ulRC);
    } else {
        pVOData->pBuffer = NULL;
    }
}

static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
                     ULONG cSDLRects)
{
    PRECTL      prectlDst, prectlScan;
    HPS         hps;
    HRGN        hrgnUpdate;
    RGNRECT     rgnCtl;
    SDL_Rect    stSDLRectDef;
    BMAPINFO    bmiSrc;
    BMAPINFO    bmiDst;
    PPOINTL     pptlSrcOrg;
    PBLTRECT    pbrDst;
    HWREQIN     sHWReqIn;
    BITBLTINFO  sBitbltInfo = { 0 };
    ULONG       ulIdx;
/*  RECTL       rectlScreenUpdate;*/

    if (pVOData->pBuffer == NULL)
        return FALSE;

    if (pVOData->hrgnVisible == NULLHANDLE)
        return TRUE;

    bmiSrc.ulLength = sizeof(BMAPINFO);
    bmiSrc.ulType = BMAP_MEMORY;
    bmiSrc.ulWidth = pVOData->ulWidth;
    bmiSrc.ulHeight = pVOData->ulHeight;
    bmiSrc.ulBpp = pVOData->ulBPP;
    bmiSrc.ulBytesPerLine = pVOData->ulScanLineSize;
    bmiSrc.pBits = (PBYTE)pVOData->pBuffer;

    bmiDst.ulLength = sizeof(BMAPINFO);
    bmiDst.ulType = BMAP_VRAM;
    bmiDst.pBits = (PBYTE)ulVRAMAddress;
    bmiDst.ulWidth = bmiSrc.ulWidth;
    bmiDst.ulHeight = bmiSrc.ulHeight;
    bmiDst.ulBpp = bmiSrc.ulBpp;
    bmiDst.ulBytesPerLine = pVOData->ulScreenBytesPerLine;

    /* List of update rectangles. This is the intersection of requested
     * rectangles and visible rectangles.  */
    if (cSDLRects == 0) {
        /* Full update requested */
        stSDLRectDef.x = 0;
        stSDLRectDef.y = 0;
        stSDLRectDef.w = bmiSrc.ulWidth;
        stSDLRectDef.h = bmiSrc.ulHeight;
        pSDLRects = &stSDLRectDef;
        cSDLRects = 1;
    }

    /* Make list of destination rectangles (prectlDst) list from the source
     * list (prectl).  */
    prectlDst = _getRectlArray(pVOData, cSDLRects);
    if (prectlDst == NULL) {
        debug_os2("Not enough memory");
        return FALSE;
    }
    prectlScan = prectlDst;
    for (ulIdx = 0; ulIdx < cSDLRects; ulIdx++, pSDLRects++, prectlScan++) {
        prectlScan->xLeft   = pSDLRects->x;
        prectlScan->yTop    = pVOData->ulHeight - pSDLRects->y;
        prectlScan->xRight  = prectlScan->xLeft + pSDLRects->w;
        prectlScan->yBottom = prectlScan->yTop - pSDLRects->h;
    }

    hps = WinGetPS(hwnd);
    if (hps == NULLHANDLE)
        return FALSE;

    /* Make destination region to update */
    hrgnUpdate = GpiCreateRegion(hps, cSDLRects, prectlDst);
    /* "AND" on visible and destination regions, result is region to update */
    GpiCombineRegion(hps, hrgnUpdate, hrgnUpdate, pVOData->hrgnVisible, CRGN_AND);

    /* Get rectangles of the region to update */
    rgnCtl.ircStart     = 1;
    rgnCtl.crc          = 0;
    rgnCtl.ulDirection  = 1;
    rgnCtl.crcReturned  = 0;
    GpiQueryRegionRects(hps, hrgnUpdate, NULL, &rgnCtl, NULL);
    if (rgnCtl.crcReturned == 0) {
        GpiDestroyRegion(hps, hrgnUpdate);
        WinReleasePS(hps);
        return TRUE;
    }
    /* We don't need prectlDst, use it again to store update regions */
    prectlDst = _getRectlArray(pVOData, rgnCtl.crcReturned);
    if (prectlDst == NULL) {
        debug_os2("Not enough memory");
        GpiDestroyRegion(hps, hrgnUpdate);
        WinReleasePS(hps);
        return FALSE;
    }
    rgnCtl.ircStart     = 1;
    rgnCtl.crc          = rgnCtl.crcReturned;
    rgnCtl.ulDirection  = 1;
    GpiQueryRegionRects(hps, hrgnUpdate, NULL, &rgnCtl, prectlDst);
    GpiDestroyRegion(hps, hrgnUpdate);
    WinReleasePS(hps);
    cSDLRects = rgnCtl.crcReturned;

    /* Now cRect/prectlDst is a list of regions in window (update && visible) */

    /* Make lists for blitting from update regions */
    pbrDst = _getBltRectArray(pVOData, cSDLRects);
    if (pbrDst == NULL) {
        debug_os2("Not enough memory");
        return FALSE;
    }

    prectlScan = prectlDst;
    pptlSrcOrg = (PPOINTL)prectlDst; /* Yes, this memory block will be used again */
    for (ulIdx = 0; ulIdx < cSDLRects; ulIdx++, prectlScan++, pptlSrcOrg++) {
        pbrDst[ulIdx].ulXOrg = pVOData->rectlWin.xLeft + prectlScan->xLeft;
        pbrDst[ulIdx].ulYOrg = pVOData->ulScreenHeight -
                              (pVOData->rectlWin.yBottom + prectlScan->yTop);
        pbrDst[ulIdx].ulXExt = prectlScan->xRight - prectlScan->xLeft;
        pbrDst[ulIdx].ulYExt = prectlScan->yTop - prectlScan->yBottom;
        pptlSrcOrg->x = prectlScan->xLeft;
        pptlSrcOrg->y = bmiSrc.ulHeight - prectlScan->yTop;
    }
    pptlSrcOrg = (PPOINTL)prectlDst;

    /* Request HW */
    sHWReqIn.ulLength = sizeof(HWREQIN);
    sHWReqIn.ulFlags = REQUEST_HW;
    sHWReqIn.cScrChangeRects = 1;
    sHWReqIn.arectlScreen = &pVOData->rectlWin;
    if (pfnVMIEntry(0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL) != RC_SUCCESS) {
        debug_os2("pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed");
        sHWReqIn.cScrChangeRects = 0; /* for fail signal only */
    } else {
        RECTL rclSrcBounds;

        rclSrcBounds.xLeft = 0;
        rclSrcBounds.yBottom = 0;
        rclSrcBounds.xRight = bmiSrc.ulWidth;
        rclSrcBounds.yTop = bmiSrc.ulHeight;

        sBitbltInfo.ulLength = sizeof(BITBLTINFO);
        sBitbltInfo.ulBltFlags = BF_DEFAULT_STATE | BF_ROP_INCL_SRC | BF_PAT_HOLLOW;
        sBitbltInfo.cBlits = cSDLRects;
        sBitbltInfo.ulROP = ROP_SRCCOPY;
        sBitbltInfo.pSrcBmapInfo = &bmiSrc;
        sBitbltInfo.pDstBmapInfo = &bmiDst;
        sBitbltInfo.prclSrcBounds = &rclSrcBounds;
        sBitbltInfo.prclDstBounds = &pVOData->rectlWin;
        sBitbltInfo.aptlSrcOrg = pptlSrcOrg;
        sBitbltInfo.abrDst = pbrDst;

        /* Screen update */
        if (pfnVMIEntry(0, VMI_CMD_BITBLT, &sBitbltInfo, NULL) != RC_SUCCESS) {
            debug_os2("pfnVMIEntry(,VMI_CMD_BITBLT,,) failed");
            sHWReqIn.cScrChangeRects = 0; /* for fail signal only */
        }

        /* Release HW */
        sHWReqIn.ulFlags = 0;
        if (pfnVMIEntry(0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL) != RC_SUCCESS) {
          debug_os2("pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed");
        }
    }

    return sHWReqIn.cScrChangeRects != 0;
}

/* vi: set ts=4 sw=4 expandtab: */
