/*
  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"

#if SDL_VIDEO_DRIVER_OS2

#include "SDL_video.h"
#include "SDL_mouse.h"
#include "../SDL_pixels_c.h"
#include "../SDL_shape_internals.h"
#include "../../events/SDL_events_c.h"
#include "SDL_os2video.h"
#include "SDL_syswm.h"
#include "SDL_os2util.h"

#define __MEERROR_H__
#define  _MEERROR_H_
#include <mmioos2.h>
#include <fourcc.h>
#ifndef FOURCC_R666
#define FOURCC_R666 mmioFOURCC('R','6','6','6')
#endif

#define WIN_CLIENT_CLASS        "SDL2"
#define OS2DRIVER_NAME_DIVE     "DIVE"
#define OS2DRIVER_NAME_VMAN     "VMAN"


static const SDL_Scancode aSDLScancode[] = {
         /*   0                       1                           2                           3                           4                        5                                                       6                           7 */
         /*   8                       9                           A                           B                           C                        D                                                       E                           F */
         SDL_SCANCODE_UNKNOWN,        SDL_SCANCODE_ESCAPE,        SDL_SCANCODE_1,             SDL_SCANCODE_2,             SDL_SCANCODE_3,          SDL_SCANCODE_4,             SDL_SCANCODE_5,             SDL_SCANCODE_6,          /* 0 */
         SDL_SCANCODE_7,              SDL_SCANCODE_8,             SDL_SCANCODE_9,             SDL_SCANCODE_0,             SDL_SCANCODE_MINUS,      SDL_SCANCODE_EQUALS,        SDL_SCANCODE_BACKSPACE,     SDL_SCANCODE_TAB,        /* 0 */

         SDL_SCANCODE_Q,              SDL_SCANCODE_W,             SDL_SCANCODE_E,             SDL_SCANCODE_R,             SDL_SCANCODE_T,          SDL_SCANCODE_Y,             SDL_SCANCODE_U,             SDL_SCANCODE_I,          /* 1 */
         SDL_SCANCODE_O,              SDL_SCANCODE_P,             SDL_SCANCODE_LEFTBRACKET,   SDL_SCANCODE_RIGHTBRACKET,  SDL_SCANCODE_RETURN,     SDL_SCANCODE_LCTRL,         SDL_SCANCODE_A,             SDL_SCANCODE_S,          /* 1 */

         SDL_SCANCODE_D,              SDL_SCANCODE_F,             SDL_SCANCODE_G,             SDL_SCANCODE_H,             SDL_SCANCODE_J,          SDL_SCANCODE_K,             SDL_SCANCODE_L,             SDL_SCANCODE_SEMICOLON,  /* 2 */
         SDL_SCANCODE_APOSTROPHE,     SDL_SCANCODE_GRAVE,         SDL_SCANCODE_LSHIFT,        SDL_SCANCODE_BACKSLASH,     SDL_SCANCODE_Z,          SDL_SCANCODE_X,             SDL_SCANCODE_C,             SDL_SCANCODE_V,          /* 2 */

         SDL_SCANCODE_B,              SDL_SCANCODE_N,             SDL_SCANCODE_M,             SDL_SCANCODE_COMMA,         SDL_SCANCODE_PERIOD,     SDL_SCANCODE_SLASH,         SDL_SCANCODE_RSHIFT,  /*55*/SDL_SCANCODE_KP_MULTIPLY,/* 3 */
         SDL_SCANCODE_LALT,           SDL_SCANCODE_SPACE,         SDL_SCANCODE_CAPSLOCK,      SDL_SCANCODE_F1,            SDL_SCANCODE_F2,         SDL_SCANCODE_F3,            SDL_SCANCODE_F4,            SDL_SCANCODE_F5,         /* 3 */

         SDL_SCANCODE_F6,             SDL_SCANCODE_F7,            SDL_SCANCODE_F8,            SDL_SCANCODE_F9,            SDL_SCANCODE_F10,        SDL_SCANCODE_NUMLOCKCLEAR,  SDL_SCANCODE_SCROLLLOCK,    SDL_SCANCODE_KP_7,       /* 4 */
 /*72*/  SDL_SCANCODE_KP_8,     /*73*/SDL_SCANCODE_KP_9,          SDL_SCANCODE_KP_MINUS,/*75*/SDL_SCANCODE_KP_4,    /*76*/SDL_SCANCODE_KP_5, /*77*/SDL_SCANCODE_KP_6,    /*78*/SDL_SCANCODE_KP_PLUS, /*79*/SDL_SCANCODE_KP_1,       /* 4 */

 /*80*/  SDL_SCANCODE_KP_2,     /*81*/SDL_SCANCODE_KP_3,          SDL_SCANCODE_KP_0,    /*83*/SDL_SCANCODE_KP_PERIOD,     SDL_SCANCODE_UNKNOWN,    SDL_SCANCODE_UNKNOWN,       SDL_SCANCODE_NONUSBACKSLASH,SDL_SCANCODE_F11,        /* 5 */
 /*88*/  SDL_SCANCODE_F12,      /*89*/SDL_SCANCODE_PAUSE,   /*90*/SDL_SCANCODE_KP_ENTER,/*91*/SDL_SCANCODE_RCTRL,   /*92*/SDL_SCANCODE_KP_DIVIDE,  SDL_SCANCODE_APPLICATION,   SDL_SCANCODE_RALT,    /*95*/SDL_SCANCODE_UNKNOWN,    /* 5 */

 /*96*/  SDL_SCANCODE_HOME,     /*97*/SDL_SCANCODE_UP,      /*98*/SDL_SCANCODE_PAGEUP,        SDL_SCANCODE_LEFT,   /*100*/SDL_SCANCODE_RIGHT,      SDL_SCANCODE_END,    /*102*/SDL_SCANCODE_DOWN,   /*103*/SDL_SCANCODE_PAGEDOWN,   /* 6 */
/*104*/  SDL_SCANCODE_F17,     /*105*/SDL_SCANCODE_DELETE,        SDL_SCANCODE_F19,           SDL_SCANCODE_UNKNOWN,       SDL_SCANCODE_UNKNOWN,    SDL_SCANCODE_UNKNOWN,/*110*/SDL_SCANCODE_UNKNOWN,/*111*/SDL_SCANCODE_UNKNOWN,    /* 6 */

/*112*/  SDL_SCANCODE_INTERNATIONAL2, SDL_SCANCODE_UNKNOWN,       SDL_SCANCODE_UNKNOWN,       SDL_SCANCODE_INTERNATIONAL1,SDL_SCANCODE_UNKNOWN,    SDL_SCANCODE_UNKNOWN,       SDL_SCANCODE_UNKNOWN,       SDL_SCANCODE_UNKNOWN,    /* 7 */
/*120*/  SDL_SCANCODE_UNKNOWN,        SDL_SCANCODE_INTERNATIONAL4,SDL_SCANCODE_UNKNOWN,       SDL_SCANCODE_INTERNATIONAL5,SDL_SCANCODE_APPLICATION,SDL_SCANCODE_INTERNATIONAL3,SDL_SCANCODE_LGUI,          SDL_SCANCODE_RGUI        /* 7 */
};

/*  Utilites.
 *  ---------
 */
static BOOL _getSDLPixelFormatData(SDL_PixelFormat *pSDLPixelFormat,
                                   ULONG ulBPP, ULONG fccColorEncoding)
{
    ULONG   ulRshift, ulGshift, ulBshift;
    ULONG   ulRmask, ulGmask, ulBmask;
    ULONG   ulRloss, ulGloss, ulBloss;

    pSDLPixelFormat->BitsPerPixel = ulBPP;
    pSDLPixelFormat->BytesPerPixel = (pSDLPixelFormat->BitsPerPixel + 7) / 8;

    switch (fccColorEncoding) {
    case FOURCC_LUT8:
        ulRshift = 0; ulGshift = 0; ulBshift = 0;
        ulRmask = 0; ulGmask = 0; ulBmask = 0;
        ulRloss = 8; ulGloss = 8; ulBloss = 8;
        break;

    case FOURCC_R555:
        ulRshift = 10; ulGshift = 5; ulBshift = 0;
        ulRmask = 0x7C00; ulGmask = 0x03E0; ulBmask = 0x001F;
        ulRloss = 3; ulGloss = 3; ulBloss = 3;
        break;

    case FOURCC_R565:
        ulRshift = 11; ulGshift = 5; ulBshift = 0;
        ulRmask = 0xF800; ulGmask = 0x07E0; ulBmask = 0x001F;
        ulRloss = 3; ulGloss = 2; ulBloss = 3;
        break;

    case FOURCC_R664:
        ulRshift = 10; ulGshift = 4; ulBshift = 0;
        ulRmask = 0xFC00; ulGmask = 0x03F0; ulBmask = 0x000F;
        ulRloss = 2; ulGloss = 4; ulBloss = 3;
        break;

    case FOURCC_R666:
        ulRshift = 12; ulGshift = 6; ulBshift = 0;
        ulRmask = 0x03F000; ulGmask = 0x000FC0; ulBmask = 0x00003F;
        ulRloss = 2; ulGloss = 2; ulBloss = 2;
        break;

    case FOURCC_RGB3:
    case FOURCC_RGB4:
        ulRshift = 0; ulGshift = 8; ulBshift = 16;
        ulRmask = 0x0000FF; ulGmask = 0x00FF00; ulBmask = 0xFF0000;
        ulRloss = 0x00; ulGloss = 0x00; ulBloss = 0x00;
        break;

    case FOURCC_BGR3:
    case FOURCC_BGR4:
        ulRshift = 16; ulGshift = 8; ulBshift = 0;
        ulRmask = 0xFF0000; ulGmask = 0x00FF00; ulBmask = 0x0000FF;
        ulRloss = 0; ulGloss = 0; ulBloss = 0;
        break;

    default:
/*      printf("Unknown color encoding: %.4s\n", fccColorEncoding);*/
        memset(pSDLPixelFormat, 0, sizeof(SDL_PixelFormat));
        return FALSE;
    }

    pSDLPixelFormat->Rshift = ulRshift;
    pSDLPixelFormat->Gshift = ulGshift;
    pSDLPixelFormat->Bshift = ulBshift;
    pSDLPixelFormat->Rmask  = ulRmask;
    pSDLPixelFormat->Gmask  = ulGmask;
    pSDLPixelFormat->Bmask  = ulBmask;
    pSDLPixelFormat->Rloss  = ulRloss;
    pSDLPixelFormat->Gloss  = ulGloss;
    pSDLPixelFormat->Bloss  = ulBloss;

    pSDLPixelFormat->Ashift = 0x00;
    pSDLPixelFormat->Amask  = 0x00;
    pSDLPixelFormat->Aloss  = 0x00;

    return TRUE;
}

static Uint32 _getSDLPixelFormat(ULONG ulBPP, FOURCC fccColorEncoding)
{
    SDL_PixelFormat stSDLPixelFormat;
    Uint32          uiResult = SDL_PIXELFORMAT_UNKNOWN;

    if (_getSDLPixelFormatData(&stSDLPixelFormat, ulBPP, fccColorEncoding))
        uiResult = SDL_MasksToPixelFormatEnum(ulBPP, stSDLPixelFormat.Rmask,
                                              stSDLPixelFormat.Gmask,
                                              stSDLPixelFormat.Bmask, 0);

    return uiResult;
}

static SDL_DisplayMode *_getDisplayModeForSDLWindow(SDL_Window *window)
{
    SDL_VideoDisplay *pSDLDisplay = SDL_GetDisplayForWindow(window);

    if (pSDLDisplay == NULL) {
        debug_os2("No display for the window");
        return FALSE;
    }

    return &pSDLDisplay->current_mode;
}

static VOID _mouseCheck(WINDATA *pWinData)
{
    SDL_Mouse *pSDLMouse = SDL_GetMouse();

    if ((pSDLMouse->relative_mode || (pWinData->window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) &&
        ((pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0)) {
        /* We will make a real capture in _wmMouseButton() */
    } else {
        WinSetCapture(HWND_DESKTOP, NULLHANDLE);
    }
}


/*  PM window procedure.
 *  --------------------
 */
static int OS2_ResizeWindowShape(SDL_Window *window);

static VOID _setVisibleRegion(WINDATA *pWinData, BOOL fVisible)
{
    SDL_VideoDisplay *pSDLDisplay;

    if (! pWinData->pVOData)
        return;

     pSDLDisplay = (fVisible)? SDL_GetDisplayForWindow(pWinData->window) : NULL;
     pWinData->pOutput->SetVisibleRegion(pWinData->pVOData, pWinData->hwnd,
                                         (pSDLDisplay == NULL) ?
                                            NULL : &pSDLDisplay->current_mode,
                                         pWinData->hrgnShape, fVisible);
}

static VOID _wmPaint(WINDATA *pWinData, HWND hwnd)
{
    if (pWinData->pVOData == NULL ||
        !pWinData->pOutput->Update(pWinData->pVOData, hwnd, NULL, 0)) {
        RECTL   rectl;
        HPS     hps;

        hps = WinBeginPaint(hwnd, 0, &rectl);
        WinFillRect(hps, &rectl, CLR_BLACK);
        WinEndPaint(hps);
    }
}

static VOID _wmMouseMove(WINDATA *pWinData, SHORT lX, SHORT lY)
{
    SDL_Mouse *pSDLMouse = SDL_GetMouse();
    POINTL  pointl;
    BOOL    fWinActive = (pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0;

    if (!pSDLMouse->relative_mode || pSDLMouse->relative_mode_warp) {
        if (!pSDLMouse->relative_mode && fWinActive &&
            ((pWinData->window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) &&
            (WinQueryCapture(HWND_DESKTOP) == pWinData->hwnd)) {

            pointl.x = lX;
            pointl.y = lY;

            if (lX < 0)
                lX = 0;
            else if (lX >= pWinData->window->w)
                lX = pWinData->window->w - 1;

            if (lY < 0)
                lY = 0;
            else if (lY >= pWinData->window->h)
                lY = pWinData->window->h - 1;

            if (lX != pointl.x || lY != pointl.x) {
                pointl.x = lX;
                pointl.y = lY;
                WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1);
                pWinData->lSkipWMMouseMove++;
                WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y);
            }
        }

        SDL_SendMouseMotion(pWinData->window, 0, 0, lX,
                            pWinData->window->h - lY - 1);
        return;
    }

    if (fWinActive) {
        pointl.x = pWinData->window->w / 2;
        pointl.y = pWinData->window->h / 2;
        WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1);

        SDL_SendMouseMotion(pWinData->window, 0, 1,
                            lX - pointl.x, pointl.y - lY);

        pWinData->lSkipWMMouseMove++;
        WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y);
    }
}

static VOID _wmMouseButton(WINDATA *pWinData, ULONG ulButton, BOOL fDown)
{
    static ULONG  aBtnGROP2SDL[3] = { SDL_BUTTON_LEFT, SDL_BUTTON_RIGHT,
                                      SDL_BUTTON_MIDDLE };
    SDL_Mouse *pSDLMouse = SDL_GetMouse();

    if ((pSDLMouse->relative_mode || ((pWinData->window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0)) &&
        ((pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0) &&
        (WinQueryCapture(HWND_DESKTOP) != pWinData->hwnd)) {
        /* Mouse should be captured. */
        if (pSDLMouse->relative_mode && !pSDLMouse->relative_mode_warp) {
            POINTL  pointl;

            pointl.x = pWinData->window->w / 2;
            pointl.y = pWinData->window->h / 2;
            WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1);
            pWinData->lSkipWMMouseMove++;
            WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y);
        }

        WinSetCapture(HWND_DESKTOP, pWinData->hwnd);
    }

    SDL_SendMouseButton(pWinData->window, 0,
                        (fDown)? SDL_PRESSED : SDL_RELEASED,
                        aBtnGROP2SDL[ulButton]);
}

static VOID _wmChar(WINDATA *pWinData, MPARAM mp1, MPARAM mp2)
{
    ULONG   ulFlags = SHORT1FROMMP(mp1);      /* WM_CHAR flags         */
    ULONG   ulVirtualKey = SHORT2FROMMP(mp2); /* Virtual key code VK_* */
    ULONG   ulCharCode = SHORT1FROMMP(mp2);   /* Character code        */
    ULONG   ulScanCode = CHAR4FROMMP(mp1);    /* Scan code             */

    if (((ulFlags & (KC_VIRTUALKEY | KC_KEYUP | KC_ALT)) == (KC_VIRTUALKEY | KC_ALT)) &&
        (ulVirtualKey == VK_F4)) {
        SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
    }

    if ((ulFlags & KC_SCANCODE) != 0) {
        SDL_SendKeyboardKey(((ulFlags & KC_KEYUP) == 0)? SDL_PRESSED : SDL_RELEASED, aSDLScancode[ulScanCode]);
    }

    if ((ulFlags & KC_CHAR) != 0) {
        CHAR    acUTF8[4];
        LONG    lRC = StrUTF8(1, acUTF8, sizeof(acUTF8), (PSZ)&ulCharCode, 1);

        SDL_SendKeyboardText((lRC > 0)? acUTF8 : (PSZ)&ulCharCode);
    }
}

static VOID _wmMove(WINDATA *pWinData)
{
    SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow(pWinData->window);
    POINTL  pointl = { 0 };
    RECTL   rectl;

    WinQueryWindowRect(pWinData->hwnd, &rectl);
    WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, (PPOINTL)&rectl, 2);

    WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1);
    SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_MOVED, rectl.xLeft,
                       pSDLDisplayMode->h - rectl.yTop);
}

static MRESULT _wmDragOver(WINDATA *pWinData, PDRAGINFO pDragInfo)
{
    ULONG       ulIdx;
    PDRAGITEM   pDragItem;
    USHORT      usDrag   = DOR_NEVERDROP;
    USHORT      usDragOp = DO_UNKNOWN;

    if (!DrgAccessDraginfo(pDragInfo))
        return MRFROM2SHORT(DOR_NEVERDROP, DO_UNKNOWN);

    for (ulIdx = 0; ulIdx < pDragInfo->cditem; ulIdx++) {
        pDragItem = DrgQueryDragitemPtr(pDragInfo, ulIdx);

        /* We accept WPS files only. */
        if (!DrgVerifyRMF(pDragItem, "DRM_OS2FILE", NULL)) {
            usDrag   = DOR_NEVERDROP;
            usDragOp = DO_UNKNOWN;
            break;
        }

        if (pDragInfo->usOperation == DO_DEFAULT &&
            (pDragItem->fsSupportedOps & DO_COPYABLE) != 0) {
            usDrag   = DOR_DROP;
            usDragOp = DO_COPY;
        } else
        if (pDragInfo->usOperation == DO_LINK &&
            (pDragItem->fsSupportedOps & DO_LINKABLE) != 0) {
            usDrag   = DOR_DROP;
            usDragOp = DO_LINK;
        } else {
            usDrag   = DOR_NODROPOP;
            usDragOp = DO_UNKNOWN;
            break;
        }
    }

    /* Update window (The DIVE surface spoiled while dragging) */
    WinInvalidateRect(pWinData->hwnd, NULL, FALSE);
    WinUpdateWindow(pWinData->hwnd);

    DrgFreeDraginfo(pDragInfo);
    return MPFROM2SHORT(usDrag, usDragOp);
}

static MRESULT _wmDrop(WINDATA *pWinData, PDRAGINFO pDragInfo)
{
    ULONG       ulIdx;
    PDRAGITEM   pDragItem;
    CHAR        acFName[_MAX_PATH];
    PCHAR       pcFName;

    if (!DrgAccessDraginfo(pDragInfo))
        return MRFROM2SHORT(DOR_NEVERDROP, 0);

    for (ulIdx = 0; ulIdx < pDragInfo->cditem; ulIdx++) {
        pDragItem = DrgQueryDragitemPtr(pDragInfo, ulIdx);

        if (DrgVerifyRMF(pDragItem, "DRM_OS2FILE", NULL) &&
            pDragItem->hstrContainerName != NULLHANDLE &&
            pDragItem->hstrSourceName != NULLHANDLE) {
            /* Get file name from the item. */
            DrgQueryStrName(pDragItem->hstrContainerName, sizeof(acFName), acFName);
            pcFName = strchr(acFName, '\0');
            DrgQueryStrName(pDragItem->hstrSourceName,
                            sizeof(acFName) - (pcFName - acFName), pcFName);

            /* Send to SDL full file name converted to UTF-8. */
            pcFName = OS2_SysToUTF8(acFName);
            SDL_SendDropFile(pWinData->window, pcFName);
            SDL_free(pcFName);

            /* Notify a source that a drag operation is complete. */
            if (pDragItem->hwndItem)
                DrgSendTransferMsg(pDragItem->hwndItem, DM_ENDCONVERSATION,
                                   (MPARAM)pDragItem->ulItemID,
                                   (MPARAM)DMFL_TARGETSUCCESSFUL);
        }
    }

    DrgDeleteDraginfoStrHandles(pDragInfo);
    DrgFreeDraginfo(pDragInfo);

    SDL_SendDropComplete(pWinData->window);

    return (MRESULT)FALSE;
}

MRESULT EXPENTRY wndFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
    HWND    hwndClient = WinQueryWindow(hwnd, QW_BOTTOM);
    WINDATA * pWinData = (WINDATA *)WinQueryWindowULong(hwndClient, 0);

    if (pWinData == NULL)
        return WinDefWindowProc(hwnd, msg, mp1, mp2);

    /* Send a SDL_SYSWMEVENT if the application wants them */
    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
        SDL_SysWMmsg wmmsg;

        SDL_VERSION(&wmmsg.version);
        wmmsg.subsystem = SDL_SYSWM_OS2;
        wmmsg.msg.os2.fFrame = TRUE;
        wmmsg.msg.os2.hwnd = hwnd;
        wmmsg.msg.os2.msg = msg;
        wmmsg.msg.os2.mp1 = mp1;
        wmmsg.msg.os2.mp2 = mp2;
        SDL_SendSysWMEvent(&wmmsg);
    }

    switch (msg) {
    case WM_MINMAXFRAME:
        if ((((PSWP)mp1)->fl & SWP_RESTORE) != 0) {
            pWinData->lSkipWMMove += 2;
            SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
        }
        if ((((PSWP)mp1)->fl & SWP_MINIMIZE) != 0) {
            pWinData->lSkipWMSize++;
            pWinData->lSkipWMMove += 2;
            SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
        }
        if ((((PSWP)mp1)->fl & SWP_MAXIMIZE) != 0) {
            SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
        }
        break;

    case WM_ADJUSTFRAMEPOS:
        if (pWinData->lSkipWMAdjustFramePos > 0) {
            pWinData->lSkipWMAdjustFramePos++;
            break;
        }
        if ((pWinData->window->flags & SDL_WINDOW_FULLSCREEN) != 0 &&
            (((PSWP)mp1)->fl & SWP_RESTORE) != 0) {
            /* Keep fullscreen window size on restore. */
            RECTL rectl;

            rectl.xLeft = 0;
            rectl.yBottom = 0;
            rectl.xRight = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
            rectl.yTop = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
            WinCalcFrameRect(hwnd, &rectl, FALSE);
            ((PSWP)mp1)->x = rectl.xLeft;
            ((PSWP)mp1)->y = rectl.yBottom;
            ((PSWP)mp1)->cx = rectl.xRight - rectl.xLeft;
            ((PSWP)mp1)->cy = rectl.yTop - rectl.yBottom;
        }
        if ((((PSWP)mp1)->fl & (SWP_SIZE | SWP_MINIMIZE)) == SWP_SIZE) {
            if ((pWinData->window->flags & SDL_WINDOW_FULLSCREEN) != 0) {
                /* SDL_WINDOW_FULLSCREEN_DESKTOP have flag SDL_WINDOW_FULLSCREEN... */
                if (SDL_IsShapedWindow(pWinData->window))
                    OS2_ResizeWindowShape(pWinData->window);
                break;
            }
            if ((SDL_GetWindowFlags(pWinData->window) & SDL_WINDOW_RESIZABLE) != 0) {
                RECTL   rectl;
                int     iMinW, iMinH, iMaxW, iMaxH;
                int     iWinW, iWinH;

                rectl.xLeft = 0;
                rectl.yBottom = 0;
                SDL_GetWindowSize(pWinData->window,
                                  (int *)&rectl.xRight, (int *)&rectl.yTop);
                iWinW = rectl.xRight;
                iWinH = rectl.yTop;

                SDL_GetWindowMinimumSize(pWinData->window, &iMinW, &iMinH);
                SDL_GetWindowMaximumSize(pWinData->window, &iMaxW, &iMaxH);

                if (iWinW < iMinW)
                    rectl.xRight = iMinW;
                else if (iMaxW != 0 && iWinW > iMaxW)
                    rectl.xRight = iMaxW;

                if (iWinH < iMinH)
                    rectl.yTop = iMinW;
                else if (iMaxH != 0 && iWinH > iMaxH)
                    rectl.yTop = iMaxH;

                if (rectl.xRight == iWinW && rectl.yTop == iWinH) {
                    if (SDL_IsShapedWindow(pWinData->window))
                        OS2_ResizeWindowShape(pWinData->window);
                    break;
                }

                WinCalcFrameRect(hwnd, &rectl, FALSE);
                ((PSWP)mp1)->cx = rectl.xRight - rectl.xLeft;
                ((PSWP)mp1)->cy = rectl.yTop - rectl.yBottom;
            }
        }
        break;
    }

    return pWinData->fnWndFrameProc(hwnd, msg, mp1, mp2);
}

MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
    WINDATA *pWinData = (WINDATA *)WinQueryWindowULong(hwnd, 0);

    if (pWinData == NULL)
        return WinDefWindowProc(hwnd, msg, mp1, mp2);

    /* Send a SDL_SYSWMEVENT if the application wants them */
    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
        SDL_SysWMmsg wmmsg;

        SDL_VERSION(&wmmsg.version);
        wmmsg.subsystem = SDL_SYSWM_OS2;
        wmmsg.msg.os2.fFrame = FALSE;
        wmmsg.msg.os2.hwnd = hwnd;
        wmmsg.msg.os2.msg = msg;
        wmmsg.msg.os2.mp1 = mp1;
        wmmsg.msg.os2.mp2 = mp2;
        SDL_SendSysWMEvent(&wmmsg);
    }

    switch (msg) {
    case WM_CLOSE:
    case WM_QUIT:
        SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
        if (pWinData->fnUserWndProc == NULL)
            return (MRESULT)FALSE;
        break;

    case WM_PAINT:
        _wmPaint(pWinData, hwnd);
        break;

    case WM_SHOW:
        SDL_SendWindowEvent(pWinData->window, (SHORT1FROMMP(mp1) == 0)?
                                               SDL_WINDOWEVENT_HIDDEN :
                                               SDL_WINDOWEVENT_SHOWN   ,
                            0, 0);
        break;

    case WM_UPDATEFRAME:
        /* Return TRUE - no further action for the frame control window procedure */
        return (MRESULT)TRUE;

    case WM_ACTIVATE:
        if ((BOOL)mp1) {
            POINTL  pointl;

            if (SDL_GetKeyboardFocus() != pWinData->window)
                SDL_SetKeyboardFocus(pWinData->window);

            WinQueryPointerPos(HWND_DESKTOP, &pointl);
            WinMapWindowPoints(HWND_DESKTOP, pWinData->hwnd, &pointl, 1);
            SDL_SendMouseMotion(pWinData->window, 0, 0,
                                    pointl.x, pWinData->window->h - pointl.y - 1);
        } else {
            if (SDL_GetKeyboardFocus() == pWinData->window)
                SDL_SetKeyboardFocus(NULL);

            WinSetCapture(HWND_DESKTOP,  NULLHANDLE);
        }
        break;

    case WM_MOUSEMOVE:
        WinSetPointer(HWND_DESKTOP, hptrCursor);

        if (pWinData->lSkipWMMouseMove > 0)
            pWinData->lSkipWMMouseMove--;
        else {
            _wmMouseMove(pWinData, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));
        }
        return (MRESULT)FALSE;

    case WM_BUTTON1DOWN:
    case WM_BUTTON1DBLCLK:
        _wmMouseButton(pWinData, 0, TRUE);
        break;

    case WM_BUTTON1UP:
        _wmMouseButton(pWinData, 0, FALSE);
        break;

    case WM_BUTTON2DOWN:
    case WM_BUTTON2DBLCLK:
        _wmMouseButton(pWinData, 1, TRUE);
        break;

    case WM_BUTTON2UP:
        _wmMouseButton(pWinData, 1, FALSE);
        break;

    case WM_BUTTON3DOWN:
    case WM_BUTTON3DBLCLK:
        _wmMouseButton(pWinData, 2, TRUE);
        break;

    case WM_BUTTON3UP:
        _wmMouseButton(pWinData, 2, FALSE);
        break;

    case WM_TRANSLATEACCEL:
        /* ALT and acceleration keys not allowed (must be processed in WM_CHAR) */
        if (mp1 == NULL || ((PQMSG)mp1)->msg != WM_CHAR)
            break;
        return (MRESULT)FALSE;

    case WM_CHAR:
        _wmChar(pWinData, mp1, mp2);
        break;

    case WM_SIZE:
        if (pWinData->lSkipWMSize > 0)
            pWinData->lSkipWMSize--;
        else {
            if ((pWinData->window->flags & SDL_WINDOW_FULLSCREEN) == 0) {
                SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_RESIZED,
                                    SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
            } else {
                pWinData->lSkipWMVRNEnabled++;
            }
        }
        break;

    case WM_MOVE:
        if (pWinData->lSkipWMMove > 0)
            pWinData->lSkipWMMove--;
        else if ((pWinData->window->flags & SDL_WINDOW_FULLSCREEN) == 0) {
            _wmMove(pWinData);
        }
        break;

    case WM_VRNENABLED:
        if (pWinData->lSkipWMVRNEnabled > 0)
            pWinData->lSkipWMVRNEnabled--;
        else {
            _setVisibleRegion(pWinData, TRUE);
        }
        return (MRESULT)TRUE;

    case WM_VRNDISABLED:
        _setVisibleRegion(pWinData, FALSE);
        return (MRESULT)TRUE;

    case DM_DRAGOVER:
        return _wmDragOver(pWinData, (PDRAGINFO)PVOIDFROMMP(mp1));

    case DM_DROP:
        return _wmDrop(pWinData, (PDRAGINFO)PVOIDFROMMP(mp1));
    }

    return (pWinData->fnUserWndProc != NULL)?
            pWinData->fnUserWndProc(hwnd, msg, mp1, mp2) :
            WinDefWindowProc(hwnd, msg, mp1, mp2);
}


/*  SDL routnes.
 *  ------------
 */

static void OS2_PumpEvents(_THIS)
{
    SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata;
    QMSG  qmsg;

    if (WinPeekMsg(pVData->hab, &qmsg, NULLHANDLE, 0, 0, PM_REMOVE))
        WinDispatchMsg(pVData->hab, &qmsg);
}

static WINDATA *_setupWindow(_THIS, SDL_Window *window, HWND hwndFrame,
                             HWND hwnd)
{
    SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata;
    WINDATA       *pWinData = SDL_calloc(1, sizeof(WINDATA));

    if (pWinData == NULL) {
        SDL_OutOfMemory();
        return NULL;
     }
    pWinData->hwnd = hwnd;
    pWinData->hwndFrame = hwndFrame;
    pWinData->window = window;
    window->driverdata = pWinData;

    WinSetWindowULong(hwnd, 0, (ULONG)pWinData);
    pWinData->fnWndFrameProc = WinSubclassWindow(hwndFrame, wndFrameProc);

    pWinData->pOutput = pVData->pOutput;
    pWinData->pVOData = pVData->pOutput->Open();

    WinSetVisibleRegionNotify(hwnd, TRUE);

    return pWinData;
}

static int OS2_CreateWindow(_THIS, SDL_Window *window)
{
    RECTL            rectl;
    HWND             hwndFrame, hwnd;
    SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow(window);
    ULONG            ulFrameFlags = FCF_TASKLIST  | FCF_TITLEBAR | FCF_SYSMENU |
                                    FCF_MINBUTTON | FCF_SHELLPOSITION;
    ULONG            ulSWPFlags   = SWP_SIZE | SWP_SHOW | SWP_ZORDER | SWP_ACTIVATE;
    WINDATA         *pWinData;

    if (pSDLDisplayMode == NULL)
        return -1;

    /* Create a PM window */
    if ((window->flags & SDL_WINDOW_RESIZABLE) != 0)
        ulFrameFlags |= FCF_SIZEBORDER | FCF_DLGBORDER | FCF_MAXBUTTON;
    else if ((window->flags & SDL_WINDOW_BORDERLESS) == 0)
        ulFrameFlags |= FCF_DLGBORDER;

    if ((window->flags & SDL_WINDOW_MAXIMIZED) != 0)
        ulSWPFlags |= SWP_MAXIMIZE;
    else if ((window->flags & SDL_WINDOW_MINIMIZED) != 0)
        ulSWPFlags |= SWP_MINIMIZE;

    hwndFrame = WinCreateStdWindow(HWND_DESKTOP, 0, &ulFrameFlags,
                                   WIN_CLIENT_CLASS, "SDL2", 0, 0, 0, &hwnd);
    if (hwndFrame == NULLHANDLE)
        return SDL_SetError("Couldn't create window");

    /* Setup window data and frame window procedure */
    pWinData = _setupWindow(_this, window, hwndFrame, hwnd);
    if (pWinData == NULL) {
        WinDestroyWindow(hwndFrame);
        return -1;
    }

    /* Show window */
    rectl.xLeft   = 0;
    rectl.yBottom = 0;
    rectl.xRight  = window->w;
    rectl.yTop    = window->h;
    WinCalcFrameRect(hwndFrame, &rectl, FALSE);
    pWinData->lSkipWMSize++;
    pWinData->lSkipWMMove++;
    WinSetWindowPos(hwndFrame, HWND_TOP, rectl.xLeft, rectl.yBottom,
                    rectl.xRight - rectl.xLeft, rectl.yTop - rectl.yBottom,
                    ulSWPFlags);

    rectl.xLeft   = 0;
    rectl.yBottom = 0;
    WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL)&rectl, 1);
    window->x = rectl.xLeft;
    window->y = pSDLDisplayMode->h - (rectl.yBottom + window->h);

    window->flags |= SDL_WINDOW_SHOWN;

    return 0;
}

static int OS2_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
{
    SDL_VideoData   *pVData = (SDL_VideoData *)_this->driverdata;
    CHAR             acBuf[256];
    CLASSINFO        stCI;
    HWND             hwndUser = (HWND)data;
    HWND             hwndFrame, hwnd;
    ULONG            cbText;
    PSZ              pszText;
    WINDATA         *pWinData;
    SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow(window);
    SWP              swp;
    POINTL           pointl;

    debug_os2("Enter");
    if (pSDLDisplayMode == NULL)
        return -1;

    /* User can accept client OR frame window handle.
     * Get client and frame window handles. */
    WinQueryClassName(hwndUser, sizeof(acBuf), acBuf);
    if (!WinQueryClassInfo(pVData->hab, acBuf, &stCI))
        return SDL_SetError("Cannot get user window class information");

    if ((stCI.flClassStyle & CS_FRAME) == 0) {
        /* Client window handle is specified */
        hwndFrame = WinQueryWindow(hwndUser, QW_PARENT);
        if (hwndFrame == NULLHANDLE)
            return SDL_SetError("Cannot get parent window handle");

        if ((ULONG)WinSendMsg(hwndFrame, WM_QUERYFRAMEINFO, 0, 0) == 0)
            return SDL_SetError("Parent window is not a frame window");

        hwnd = hwndUser;
    } else {
        /* Frame window handle is specified */
        hwnd = WinWindowFromID(hwndUser, FID_CLIENT);
        if (hwnd == NULLHANDLE)
            return SDL_SetError("Cannot get client window handle");

        hwndFrame = hwndUser;

        WinQueryClassName(hwnd, sizeof(acBuf), acBuf);
        if (!WinQueryClassInfo(pVData->hab, acBuf, &stCI))
            return SDL_SetError("Cannot get client window class information");
    }

    /* Check window's reserved storage */
    if (stCI.cbWindowData < sizeof(ULONG))
        return SDL_SetError("Reserved storage of window must be at least %u bytes", sizeof(ULONG));

    /* Set SDL-window title */
    cbText = WinQueryWindowTextLength(hwndFrame);
    pszText = SDL_stack_alloc(CHAR, cbText + 1);

    if (pszText != NULL)
        cbText = (pszText != NULL)? WinQueryWindowText(hwndFrame, cbText, pszText) : 0;

    if (cbText != 0)
        window->title = OS2_SysToUTF8(pszText);

    if (pszText != NULL)
        SDL_stack_free(pszText);

    /* Set SDL-window flags */
    window->flags &= ~(SDL_WINDOW_SHOWN     | SDL_WINDOW_BORDERLESS |
                       SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED  |
                       SDL_WINDOW_MINIMIZED | SDL_WINDOW_INPUT_FOCUS);

    if (WinIsWindowVisible(hwnd))
        window->flags |= SDL_WINDOW_SHOWN;

    WinSendMsg(hwndFrame, WM_QUERYBORDERSIZE, MPFROMP(&pointl), 0);
    if (pointl.y == WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER))
        window->flags |= SDL_WINDOW_RESIZABLE;
    else if (pointl.y <= WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER))
        window->flags |= SDL_WINDOW_BORDERLESS;

    WinQueryWindowPos(hwndFrame, &swp);

    if ((swp.fl & SWP_MAXIMIZE) != 0)
        window->flags |= SDL_WINDOW_MAXIMIZED;
    if ((swp.fl & SWP_MINIMIZE) != 0)
        window->flags |= SDL_WINDOW_MINIMIZED;

    pointl.x = 0;
    pointl.y = 0;
    WinMapWindowPoints(hwnd, HWND_DESKTOP, &pointl, 1);
    window->x = pointl.x;
    window->y = pSDLDisplayMode->h - (pointl.y + swp.cy);

    WinQueryWindowPos(hwnd, &swp);
    window->w = swp.cx;
    window->h = swp.cy;

    /* Setup window data and frame window procedure */
    pWinData = _setupWindow(_this, window, hwndFrame, hwnd);
    if (pWinData == NULL) {
        SDL_free(window->title);
        window->title = NULL;
        return -1;
    }
    pWinData->fnUserWndProc = WinSubclassWindow(hwnd, wndProc);

    if (WinQueryActiveWindow(HWND_DESKTOP) == hwndFrame)
        SDL_SetKeyboardFocus(window);

    return 0;
}

static void OS2_DestroyWindow(_THIS, SDL_Window * window)
{
    SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata;
    WINDATA       *pWinData = (WINDATA *)window->driverdata;

    debug_os2("Enter");
    if (pWinData == NULL)
        return;

    if (pWinData->fnUserWndProc == NULL) {
        /* Window was created by SDL (OS2_CreateWindow()),
         * not by user (OS2_CreateWindowFrom()) */
        WinDestroyWindow(pWinData->hwndFrame);
    } else {
        WinSetWindowULong(pWinData->hwnd, 0, 0);
    }

    if ((pVData != NULL) && (pWinData->pVOData != NULL)) {
        pVData->pOutput->Close(pWinData->pVOData);
        pWinData->pVOData = NULL;
    }

    if (pWinData->hptrIcon != NULLHANDLE) {
        WinDestroyPointer(pWinData->hptrIcon);
        pWinData->hptrIcon = NULLHANDLE;
    }

    SDL_free(pWinData);
    window->driverdata = NULL;
}

static void OS2_SetWindowTitle(_THIS, SDL_Window *window)
{
    PSZ pszTitle = (window->title == NULL)? NULL : OS2_UTF8ToSys(window->title);

    WinSetWindowText(((WINDATA *)window->driverdata)->hwndFrame, pszTitle);
    SDL_free(pszTitle);
}

static void OS2_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
{
    WINDATA  *pWinData = (WINDATA *)window->driverdata;
    HPOINTER  hptr = utilCreatePointer(icon, 0, 0);

    if (hptr == NULLHANDLE)
        return;

    /* Destroy old icon */
    if (pWinData->hptrIcon != NULLHANDLE)
        WinDestroyPointer(pWinData->hptrIcon);

    /* Set new window icon */
    pWinData->hptrIcon = hptr;
    if (!WinSendMsg(pWinData->hwndFrame, WM_SETICON, MPFROMLONG(hptr), 0)) {
        debug_os2("Cannot set icon for the window");
    }
}

static void OS2_SetWindowPosition(_THIS, SDL_Window *window)
{
    WINDATA         *pWinData = (WINDATA *)window->driverdata;
    RECTL            rectl;
    ULONG            ulFlags;
    SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow(window);

    debug_os2("Enter");
    if (pSDLDisplayMode == NULL)
        return;

    rectl.xLeft = 0;
    rectl.yBottom = 0;
    rectl.xRight = window->w;
    rectl.yTop = window->h;
    WinCalcFrameRect(pWinData->hwndFrame, &rectl, FALSE);

    if (SDL_ShouldAllowTopmost() &&
        (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) ==
                         (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) )
        ulFlags = SWP_ZORDER | SWP_MOVE | SWP_SIZE;
    else
        ulFlags = SWP_MOVE | SWP_SIZE;

    pWinData->lSkipWMSize++;
    pWinData->lSkipWMMove++;
    WinSetWindowPos(pWinData->hwndFrame, HWND_TOP,
                    window->x + rectl.xLeft,
                    (pSDLDisplayMode->h - window->y) - window->h + rectl.yBottom,
                    rectl.xRight - rectl.xLeft, rectl.yTop - rectl.yBottom,
                    ulFlags);
}

static void OS2_SetWindowSize(_THIS, SDL_Window *window)
{
    debug_os2("Enter");
    OS2_SetWindowPosition(_this, window);
}

static void OS2_ShowWindow(_THIS, SDL_Window *window)
{
    WINDATA *pWinData = (WINDATA *)window->driverdata;

    debug_os2("Enter");
    WinShowWindow(pWinData->hwndFrame, TRUE);
}

static void OS2_HideWindow(_THIS, SDL_Window *window)
{
    WINDATA *pWinData = (WINDATA *)window->driverdata;

    debug_os2("Enter");
    WinShowWindow(pWinData->hwndFrame, FALSE);
}

static void OS2_RaiseWindow(_THIS, SDL_Window *window)
{
    debug_os2("Enter");
    OS2_SetWindowPosition(_this, window);
}

static void OS2_MaximizeWindow(_THIS, SDL_Window *window)
{
    WINDATA *pWinData = (WINDATA *)window->driverdata;

    debug_os2("Enter");
    WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_MAXIMIZE);
}

static void OS2_MinimizeWindow(_THIS, SDL_Window *window)
{
    WINDATA *pWinData = (WINDATA *)window->driverdata;

    debug_os2("Enter");
    WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_MINIMIZE | SWP_DEACTIVATE);
}

static void OS2_RestoreWindow(_THIS, SDL_Window *window)
{
    WINDATA *pWinData = (WINDATA *)window->driverdata;

    debug_os2("Enter");
    WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_RESTORE);
}

static void OS2_SetWindowBordered(_THIS, SDL_Window * window,
                                  SDL_bool bordered)
{
    WINDATA *pWinData = (WINDATA *)window->driverdata;
    ULONG    ulStyle = WinQueryWindowULong(pWinData->hwndFrame, QWL_STYLE);
    RECTL    rectl;

    debug_os2("Enter");

    /* New frame sytle */
    if (bordered)
        ulStyle |= ((window->flags & SDL_WINDOW_RESIZABLE) != 0) ? FS_SIZEBORDER : FS_DLGBORDER;
    else
        ulStyle &= ~(FS_SIZEBORDER | FS_BORDER | FS_DLGBORDER);

    /* Save client window position */
    WinQueryWindowRect(pWinData->hwnd, &rectl);
    WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, (PPOINTL)&rectl, 2);

    /* Change the frame */
    WinSetWindowULong(pWinData->hwndFrame, QWL_STYLE, ulStyle);
    WinSendMsg(pWinData->hwndFrame, WM_UPDATEFRAME, MPFROMLONG(FCF_BORDER), 0);

    /* Restore client window position */
    WinCalcFrameRect(pWinData->hwndFrame, &rectl, FALSE);
    pWinData->lSkipWMMove++;
    WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, rectl.xLeft, rectl.yBottom,
                    rectl.xRight - rectl.xLeft,
                    rectl.yTop - rectl.yBottom,
                    SWP_SIZE | SWP_MOVE | SWP_NOADJUST);
}

static void OS2_SetWindowFullscreen(_THIS, SDL_Window *window,
                                    SDL_VideoDisplay *display,
                                    SDL_bool fullscreen)
{
    RECTL            rectl;
    ULONG            ulFlags;
    WINDATA         *pWinData = (WINDATA *)window->driverdata;
    SDL_DisplayMode *pSDLDisplayMode = &display->current_mode;

    debug_os2("Enter, fullscreen: %u", fullscreen);

    if (pSDLDisplayMode == NULL)
        return;

    if (SDL_ShouldAllowTopmost() &&
        (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS))
        ulFlags = SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_NOADJUST;
    else
        ulFlags = SWP_SIZE | SWP_MOVE | SWP_NOADJUST;

    if (fullscreen) {
        rectl.xLeft = 0;
        rectl.yBottom = 0;
        rectl.xRight = pSDLDisplayMode->w;
        rectl.yTop = pSDLDisplayMode->h;
        /* We need send the restore command now to allow WinCalcFrameRect() */
        WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_RESTORE);
    } else {
        pWinData->lSkipWMMove++;
        rectl.xLeft = window->windowed.x;
        rectl.yTop = pSDLDisplayMode->h - window->windowed.y;
        rectl.xRight = rectl.xLeft + window->windowed.w;
        rectl.yBottom = rectl.yTop - window->windowed.h;
    }

    if (!WinCalcFrameRect(pWinData->hwndFrame, &rectl, FALSE)) {
        debug_os2("WinCalcFrameRect() failed");
    }
    else if (!WinSetWindowPos(pWinData->hwndFrame, HWND_TOP,
                              rectl.xLeft, rectl.yBottom,
                              rectl.xRight - rectl.xLeft, rectl.yTop - rectl.yBottom,
                              ulFlags)) {
        debug_os2("WinSetWindowPos() failed");
    }
}

static SDL_bool OS2_GetWindowWMInfo(_THIS, SDL_Window * window,
                                    struct SDL_SysWMinfo *info)
{
    WINDATA *pWinData = (WINDATA *)window->driverdata;

    if (info->version.major <= SDL_MAJOR_VERSION) {
        info->subsystem = SDL_SYSWM_OS2;
        info->info.os2.hwnd = pWinData->hwnd;
        info->info.os2.hwndFrame = pWinData->hwndFrame;
        return SDL_TRUE;
    }

    SDL_SetError("Application not compiled with SDL %u.%u",
                 SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
    return SDL_FALSE;
}

static void OS2_OnWindowEnter(_THIS, SDL_Window * window)
{
}

static int OS2_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
{
  debug_os2("Enter");
  return 0;
}

static void OS2_SetWindowMouseGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
{
    WINDATA *pWinData = (WINDATA *)window->driverdata;

    debug_os2("Enter, %u", grabbed);
    _mouseCheck(pWinData);
}


/* Shaper
 */
typedef struct _SHAPERECTS {
  PRECTL     pRects;
  ULONG      cRects;
  ULONG      ulWinHeight;
} SHAPERECTS;

static void _combineRectRegions(SDL_ShapeTree *node, void *closure)
{
    SHAPERECTS *pShapeRects = (SHAPERECTS *)closure;
    PRECTL      pRect;

    /* Expand rectangles list */
    if ((pShapeRects->cRects & 0x0F) == 0) {
        pRect = SDL_realloc(pShapeRects->pRects, (pShapeRects->cRects + 0x10) * sizeof(RECTL));
        if (pRect == NULL)
            return;
        pShapeRects->pRects = pRect;
    }

    /* Add a new rectangle */
    pRect = &pShapeRects->pRects[pShapeRects->cRects];
    pShapeRects->cRects++;
    /* Fill rectangle data */
    pRect->xLeft = node->data.shape.x;
    pRect->yTop = pShapeRects->ulWinHeight - node->data.shape.y;
    pRect->xRight += node->data.shape.w;
    pRect->yBottom = pRect->yTop - node->data.shape.h;
}

static SDL_WindowShaper* OS2_CreateShaper(SDL_Window * window)
{
    SDL_WindowShaper* pSDLShaper = SDL_malloc(sizeof(SDL_WindowShaper));

    debug_os2("Enter");
    pSDLShaper->window = window;
    pSDLShaper->mode.mode = ShapeModeDefault;
    pSDLShaper->mode.parameters.binarizationCutoff = 1;
    pSDLShaper->userx = 0;
    pSDLShaper->usery = 0;
    pSDLShaper->driverdata = (SDL_ShapeTree *)NULL;
    window->shaper = pSDLShaper;

    if (OS2_ResizeWindowShape(window) != 0) {
        window->shaper = NULL;
        SDL_free(pSDLShaper);
        return NULL;
    }

    return pSDLShaper;
}

static int OS2_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape,
                              SDL_WindowShapeMode *shape_mode)
{
    SDL_ShapeTree *pShapeTree;
    WINDATA       *pWinData;
    SHAPERECTS     stShapeRects = { 0 };
    HPS            hps;

    debug_os2("Enter");
    if (shaper == NULL || shape == NULL ||
        (shape->format->Amask == 0 && shape_mode->mode != ShapeModeColorKey) ||
        shape->w != shaper->window->w || shape->h != shaper->window->h) {
        return SDL_INVALID_SHAPE_ARGUMENT;
    }

    if (shaper->driverdata != NULL)
        SDL_FreeShapeTree((SDL_ShapeTree **)&shaper->driverdata);

    pShapeTree = SDL_CalculateShapeTree(*shape_mode, shape);
    shaper->driverdata = pShapeTree;

    stShapeRects.ulWinHeight = shaper->window->h;
    SDL_TraverseShapeTree(pShapeTree, &_combineRectRegions, &stShapeRects);

    pWinData = (WINDATA *)shaper->window->driverdata;
    hps = WinGetPS(pWinData->hwnd);

    if (pWinData->hrgnShape != NULLHANDLE)
        GpiDestroyRegion(hps, pWinData->hrgnShape);

    pWinData->hrgnShape = (stShapeRects.pRects == NULL) ? NULLHANDLE :
                                GpiCreateRegion(hps, stShapeRects.cRects, stShapeRects.pRects);

    WinReleasePS(hps);
    SDL_free(stShapeRects.pRects);
    WinSendMsg(pWinData->hwnd, WM_VRNENABLED, 0, 0);

    return 0;
}

static int OS2_ResizeWindowShape(SDL_Window *window)
{
    debug_os2("Enter");
    if (window == NULL)
        return -1;

    if (window->x != -1000) {
        if (window->shaper->driverdata != NULL)
            SDL_FreeShapeTree((SDL_ShapeTree **)window->shaper->driverdata);

        if (window->shaper->hasshape == SDL_TRUE) {
            window->shaper->userx = window->x;
            window->shaper->usery = window->y;
            SDL_SetWindowPosition(window, -1000, -1000);
        }
    }

    return 0;
}


/* Frame buffer
 */
static void OS2_DestroyWindowFramebuffer(_THIS, SDL_Window *window)
{
    WINDATA *pWinData = (WINDATA *)window->driverdata;

    debug_os2("Enter");
    if (pWinData != NULL && pWinData->pVOData != NULL)
        pWinData->pOutput->VideoBufFree(pWinData->pVOData);
}

static int OS2_CreateWindowFramebuffer(_THIS, SDL_Window *window,
                                       Uint32 *format, void **pixels,
                                       int *pitch)
{
    WINDATA          *pWinData = (WINDATA *)window->driverdata;
    SDL_VideoDisplay *pSDLDisplay = SDL_GetDisplayForWindow(window);
    SDL_DisplayMode  *pSDLDisplayMode;
    MODEDATA         *pModeData;
    ULONG             ulWidth, ulHeight;

    debug_os2("Enter");
    if (pSDLDisplay == NULL) {
        debug_os2("No display for the window");
        return -1;
    }

    pSDLDisplayMode = &pSDLDisplay->current_mode;
    pModeData = (MODEDATA *)pSDLDisplayMode->driverdata;
    if (pModeData == NULL)
        return SDL_SetError("No mode data for the display");

    SDL_GetWindowSize(window, (int *)&ulWidth, (int *)&ulHeight);
    debug_os2("Window size: %u x %u", ulWidth, ulHeight);

    *pixels = pWinData->pOutput->VideoBufAlloc(
                        pWinData->pVOData, ulWidth, ulHeight, pModeData->ulDepth,
                        pModeData->fccColorEncoding, (PULONG)pitch);
    if (*pixels == NULL)
        return -1;

    *format = pSDLDisplayMode->format;
    debug_os2("Pitch: %u, frame buffer: 0x%X.", *pitch, *pixels);
    WinSendMsg(pWinData->hwnd, WM_VRNENABLED, 0, 0);

    return 0;
}

static int OS2_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
                                       const SDL_Rect *rects, int numrects)
{
    WINDATA *pWinData = (WINDATA *)window->driverdata;

    return pWinData->pOutput->Update(pWinData->pVOData, pWinData->hwnd,
                                     (SDL_Rect *)rects, (ULONG)numrects)
           ? 0 : -1;
}


/* Clipboard
 */
static int OS2_SetClipboardText(_THIS, const char *text)
{
    SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata;
    PSZ   pszClipboard;
    PSZ   pszText = (text == NULL)? NULL : OS2_UTF8ToSys(text);
    ULONG cbText;
    ULONG ulRC;
    BOOL  fSuccess;

    debug_os2("Enter");
    if (pszText == NULL)
        return -1;
    cbText = SDL_strlen(pszText);

    ulRC = DosAllocSharedMem((PPVOID)&pszClipboard, 0, cbText + 1,
                              PAG_COMMIT | PAG_READ | PAG_WRITE |
                              OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE);
    if (ulRC != NO_ERROR) {
        debug_os2("DosAllocSharedMem() failed, rc = %u", ulRC);
        SDL_free(pszText);
        return -1;
    }

    strcpy(pszClipboard, pszText);
    SDL_free(pszText);

    if (!WinOpenClipbrd(pVData->hab)) {
        debug_os2("WinOpenClipbrd() failed");
        fSuccess = FALSE;
    } else {
        WinEmptyClipbrd(pVData->hab);
        fSuccess = WinSetClipbrdData(pVData->hab, (ULONG)pszClipboard, CF_TEXT, CFI_POINTER);
        if (!fSuccess) {
            debug_os2("WinOpenClipbrd() failed");
        }
        WinCloseClipbrd(pVData->hab);
    }

    if (!fSuccess) {
        DosFreeMem(pszClipboard);
        return -1;
    }
    return 0;
}

static char *OS2_GetClipboardText(_THIS)
{
    SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata;
    PSZ pszClipboard = NULL;

    if (!WinOpenClipbrd(pVData->hab)) {
        debug_os2("WinOpenClipbrd() failed");
    } else {
        pszClipboard = (PSZ)WinQueryClipbrdData(pVData->hab, CF_TEXT);
        if (pszClipboard != NULL)
            pszClipboard = OS2_SysToUTF8(pszClipboard);
        WinCloseClipbrd(pVData->hab);
    }

    return (pszClipboard == NULL) ? SDL_strdup("") : pszClipboard;
}

static SDL_bool OS2_HasClipboardText(_THIS)
{
    SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata;
    SDL_bool   fClipboard;

    if (!WinOpenClipbrd(pVData->hab)) {
        debug_os2("WinOpenClipbrd() failed");
        return SDL_FALSE;
    }

    fClipboard = ((PSZ)WinQueryClipbrdData(pVData->hab, CF_TEXT) != NULL)?
                   SDL_TRUE : SDL_FALSE;
    WinCloseClipbrd(pVData->hab);

    return fClipboard;
}


static int OS2_VideoInit(_THIS)
{
    SDL_VideoData *pVData;
    PTIB  tib;
    PPIB  pib;

    /* Create SDL video driver private data */
    pVData = SDL_calloc(1, sizeof(SDL_VideoData));
    if (pVData == NULL)
        return SDL_OutOfMemory();

    /* Change process type code for use Win* API from VIO session */
    DosGetInfoBlocks(&tib, &pib);
    if (pib->pib_ultype == 2 || pib->pib_ultype == 0) {
        /* VIO windowable or fullscreen protect-mode session */
        pib->pib_ultype = 3; /* Presentation Manager protect-mode session */
    }

    /* PM initialization */
    pVData->hab = WinInitialize(0);
    pVData->hmq = WinCreateMsgQueue(pVData->hab, 0);
    if (pVData->hmq == NULLHANDLE) {
        SDL_free(pVData);
        return SDL_SetError("Message queue cannot be created.");
    }

    if (!WinRegisterClass(pVData->hab, WIN_CLIENT_CLASS, wndProc,
                          CS_SIZEREDRAW | CS_MOVENOTIFY | CS_SYNCPAINT,
                          sizeof(SDL_VideoData*))) {
        SDL_free(pVData);
        return SDL_SetError("Window class not successfully registered.");
    }

    if (stricmp(_this->name, OS2DRIVER_NAME_VMAN) == 0)
        pVData->pOutput = &voVMan;
    else
        pVData->pOutput = &voDive;

    _this->driverdata = pVData;

    /* Add display */
    {
        SDL_VideoDisplay    stSDLDisplay;
        SDL_DisplayMode     stSDLDisplayMode;
        DISPLAYDATA        *pDisplayData;
        MODEDATA           *pModeData;
        VIDEOOUTPUTINFO     stVOInfo;

        if (!pVData->pOutput->QueryInfo(&stVOInfo)) {
            SDL_free(pVData);
            return SDL_SetError("Video mode query failed.");
        }

        SDL_zero(stSDLDisplay); SDL_zero(stSDLDisplayMode);

        stSDLDisplayMode.format = _getSDLPixelFormat(stVOInfo.ulBPP,
                                                     stVOInfo.fccColorEncoding);
        stSDLDisplayMode.w = stVOInfo.ulHorizResolution;
        stSDLDisplayMode.h = stVOInfo.ulVertResolution;
        stSDLDisplayMode.refresh_rate = 0;
        stSDLDisplayMode.driverdata = NULL;

        pModeData = SDL_malloc(sizeof(MODEDATA));
        if (pModeData != NULL) {
            pModeData->ulDepth = stVOInfo.ulBPP;
            pModeData->fccColorEncoding = stVOInfo.fccColorEncoding;
            pModeData->ulScanLineBytes = stVOInfo.ulScanLineSize;
            stSDLDisplayMode.driverdata = pModeData;
        }

        stSDLDisplay.name = "Primary";
        stSDLDisplay.desktop_mode = stSDLDisplayMode;
        stSDLDisplay.current_mode = stSDLDisplayMode;
        stSDLDisplay.driverdata = NULL;
        stSDLDisplay.num_display_modes = 0;

        pDisplayData = SDL_malloc(sizeof(DISPLAYDATA));
        if (pDisplayData != NULL) {
            HPS hps = WinGetPS(HWND_DESKTOP);
            HDC hdc = GpiQueryDevice(hps);

            /* May be we can use CAPS_HORIZONTAL_RESOLUTION and
             * CAPS_VERTICAL_RESOLUTION - pels per meter?  */
            DevQueryCaps(hdc, CAPS_HORIZONTAL_FONT_RES, 1,
                          (PLONG)&pDisplayData->ulDPIHor);
            DevQueryCaps(hdc, CAPS_VERTICAL_FONT_RES, 1,
                          (PLONG)&pDisplayData->ulDPIVer);
            WinReleasePS(hps);

            pDisplayData->ulDPIDiag = SDL_ComputeDiagonalDPI(
                  stVOInfo.ulHorizResolution, stVOInfo.ulVertResolution,
                  (float)stVOInfo.ulHorizResolution / pDisplayData->ulDPIHor,
                  (float)stVOInfo.ulVertResolution / pDisplayData->ulDPIVer);

            stSDLDisplayMode.driverdata = pDisplayData;
        }

        SDL_AddVideoDisplay(&stSDLDisplay, SDL_FALSE);
    }

    OS2_InitMouse(_this, pVData->hab);

    return 0;
}

static void OS2_VideoQuit(_THIS)
{
    SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata;

    OS2_QuitMouse(_this);

    WinDestroyMsgQueue(pVData->hmq);
    WinTerminate(pVData->hab);

    /* our caller SDL_VideoQuit() already frees display_modes, driverdata, etc. */
}

static int OS2_GetDisplayBounds(_THIS, SDL_VideoDisplay *display,
                                SDL_Rect *rect)
{
    debug_os2("Enter");

    rect->x = 0;
    rect->y = 0;
    rect->w = display->desktop_mode.w;
    rect->h = display->desktop_mode.h;

    return 0;
}

static int OS2_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi,
                             float *hdpi, float *vdpi)
{
    DISPLAYDATA *pDisplayData = (DISPLAYDATA *)display->driverdata;

    debug_os2("Enter");
    if (pDisplayData == NULL)
        return -1;

    if (ddpi != NULL)
        *hdpi = pDisplayData->ulDPIDiag;
    if (hdpi != NULL)
        *hdpi = pDisplayData->ulDPIHor;
    if (vdpi != NULL)
        *vdpi = pDisplayData->ulDPIVer;

    return 0;
}

static void OS2_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
{
    debug_os2("Enter");
    SDL_AddDisplayMode(display, &display->current_mode);
}

static int OS2_SetDisplayMode(_THIS, SDL_VideoDisplay *display,
                              SDL_DisplayMode *mode)
{
    debug_os2("Enter");
    return -1;
}


static void OS2_DeleteDevice(SDL_VideoDevice *device)
{
    SDL_free(device);
}

static SDL_VideoDevice *OS2_CreateDevice(int devindex)
{
    SDL_VideoDevice *device;

    /* Initialize all variables that we clean on shutdown */
    device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
    if (!device) {
        SDL_OutOfMemory();
        return NULL;
    }

    /* Set the function pointers */
    device->VideoInit = OS2_VideoInit;
    device->VideoQuit = OS2_VideoQuit;
    device->GetDisplayBounds = OS2_GetDisplayBounds;
    device->GetDisplayDPI = OS2_GetDisplayDPI;
    device->GetDisplayModes = OS2_GetDisplayModes;
    device->SetDisplayMode = OS2_SetDisplayMode;
    device->PumpEvents = OS2_PumpEvents;
    device->CreateSDLWindow = OS2_CreateWindow;
    device->CreateSDLWindowFrom = OS2_CreateWindowFrom;
    device->DestroyWindow = OS2_DestroyWindow;
    device->SetWindowTitle = OS2_SetWindowTitle;
    device->SetWindowIcon = OS2_SetWindowIcon;
    device->SetWindowPosition = OS2_SetWindowPosition;
    device->SetWindowSize = OS2_SetWindowSize;
    device->ShowWindow = OS2_ShowWindow;
    device->HideWindow = OS2_HideWindow;
    device->RaiseWindow = OS2_RaiseWindow;
    device->MaximizeWindow = OS2_MaximizeWindow;
    device->MinimizeWindow = OS2_MinimizeWindow;
    device->RestoreWindow = OS2_RestoreWindow;
    device->SetWindowBordered = OS2_SetWindowBordered;
    device->SetWindowFullscreen = OS2_SetWindowFullscreen;
    device->GetWindowWMInfo = OS2_GetWindowWMInfo;
    device->OnWindowEnter = OS2_OnWindowEnter;
    device->SetWindowHitTest = OS2_SetWindowHitTest;
    device->SetWindowMouseGrab = OS2_SetWindowMouseGrab;
    device->CreateWindowFramebuffer = OS2_CreateWindowFramebuffer;
    device->UpdateWindowFramebuffer = OS2_UpdateWindowFramebuffer;
    device->DestroyWindowFramebuffer = OS2_DestroyWindowFramebuffer;

    device->SetClipboardText = OS2_SetClipboardText;
    device->GetClipboardText = OS2_GetClipboardText;
    device->HasClipboardText = OS2_HasClipboardText;

    device->shape_driver.CreateShaper = OS2_CreateShaper;
    device->shape_driver.SetWindowShape = OS2_SetWindowShape;
    device->shape_driver.ResizeWindowShape = OS2_ResizeWindowShape;

    device->free = OS2_DeleteDevice;

    return device;
}

static SDL_VideoDevice *OS2DIVE_CreateDevice(int devindex)
{
    VIDEOOUTPUTINFO stVOInfo;
    if (!voDive.QueryInfo(&stVOInfo)) {
        return NULL;
    }
    return OS2_CreateDevice(devindex);
}

static SDL_VideoDevice *OS2VMAN_CreateDevice(int devindex)
{
    VIDEOOUTPUTINFO stVOInfo;
    if (!voVMan.QueryInfo(&stVOInfo)) {
          return NULL;
    }
    return OS2_CreateDevice(devindex);
}


/* Both bootstraps for DIVE and VMAN are uing same function OS2_CreateDevice().
 * Video output system will be selected in OS2_VideoInit() by driver name.  */
VideoBootStrap OS2DIVE_bootstrap =
{
  OS2DRIVER_NAME_DIVE, "OS/2 video driver",
  OS2DIVE_CreateDevice
};

VideoBootStrap OS2VMAN_bootstrap =
{
  OS2DRIVER_NAME_VMAN, "OS/2 video driver",
  OS2VMAN_CreateDevice
};

#endif /* SDL_VIDEO_DRIVER_OS2 */

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