/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2022 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);*/
        SDL_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) {
#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H)
        char *utf8 = SDL_iconv_string("UTF-8", "", (char *)&ulCharCode, 1);
        SDL_SendKeyboardText((utf8 && *utf8) ? utf8 : (char *)&ulCharCode);
        SDL_free(utf8);
#else
        char utf8[4];
        int rc = StrUTF8(1, utf8, sizeof(utf8), (char *)&ulCharCode, 1);
        SDL_SendKeyboardText((rc > 0) ? utf8 : (char *) &ulCharCode);
#endif
    }
}

static VOID _wmMove(WINDATA *pWinData)
{
    SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow(pWinData->window);
    POINTL  pointl = { 0,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[CCHMAXPATH];
    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 = SDL_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;
}

static 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);
}

static 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 routines.
 *  ------------
 */

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;
    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;

    SDL_zero(stShapeRects);
    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) + 1;

    ulRC = DosAllocSharedMem((PPVOID)&pszClipboard, 0, cbText,
                              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;
    }

    SDL_memcpy(pszClipboard, pszText, cbText);
    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;
    PSZ pszClipboard;
    SDL_bool  result;

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

    pszClipboard = (PSZ)WinQueryClipbrdData(pVData->hab, CF_TEXT);
    result = (pszClipboard && *pszClipboard) ? SDL_TRUE : SDL_FALSE;
    WinCloseClipbrd(pVData->hab);

    return result;
}


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 (SDL_strcasecmp(_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)
{
    SDL_DisplayMode mode;

    debug_os2("Enter");
    SDL_memcpy(&mode, &display->current_mode, sizeof(SDL_DisplayMode));
    mode.driverdata = (MODEDATA *) SDL_malloc(sizeof(MODEDATA));
    if (!mode.driverdata) return; /* yikes.. */
    SDL_memcpy(mode.driverdata, display->current_mode.driverdata, sizeof(MODEDATA));
    SDL_AddDisplayMode(display, &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: */
