/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2017 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_
#include <mmioos2.h>
#include <fourcc.h>

#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( "No display for the window" );
    return FALSE;
  }

  return &pSDLDisplay->current_mode;
}


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

  if ( ( pSDLMouse->relative_mode ||
         (pWinData->window->flags & SDL_WINDOW_INPUT_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(PWINDATA pWinData, BOOL fVisible)
{
  SDL_VideoDisplay  *pSDLDisplay;

  if ( pWinData->pVOData == NULL )
    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(PWINDATA 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(PWINDATA 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_INPUT_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(PWINDATA 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_INPUT_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(PWINDATA 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(PWINDATA 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(PWINDATA 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(PWINDATA 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 );
  PWINDATA   pWinData = (PWINDATA)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;
          int          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)
{
  PWINDATA             pWinData = (PWINDATA)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)
{
  PSDL_VideoData       pVData = (PSDL_VideoData)_this->driverdata;
  QMSG                 qmsg;

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

static PWINDATA _setupWindow(_THIS, SDL_Window *window, HWND hwndFrame,
                             HWND hwnd)
{
  PSDL_VideoData       pVData = (PSDL_VideoData)_this->driverdata;
  PWINDATA             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;
  PWINDATA             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)
{
  PSDL_VideoData       pVData = (PSDL_VideoData)_this->driverdata;
  CHAR                 acBuf[256];
  CLASSINFO            stCI;
  HWND                 hwndUser = (HWND)data;
  HWND                 hwndFrame, hwnd;
  ULONG                cbText;
  PSZ                  pszText;
  PWINDATA             pWinData;
  SDL_DisplayMode      *pSDLDisplayMode = _getDisplayModeForSDLWindow( window );
  SWP                  swp;
  POINTL               pointl;

  debug( "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)
{
  PSDL_VideoData       pVData = (PSDL_VideoData)_this->driverdata;
  PWINDATA             pWinData = (PWINDATA)window->driverdata;

  debug( "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( ((PWINDATA)window->driverdata)->hwndFrame, pszTitle );
  SDL_free( pszTitle );
}

static void OS2_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
{
  PWINDATA             pWinData = (PWINDATA)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( "Cannot set icon for the window" );
}

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

  debug( "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( "Enter" );
  OS2_SetWindowPosition( _this, window );
}

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

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

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

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

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

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

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

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

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

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

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

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

  debug( "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;
  PWINDATA             pWinData = (PWINDATA)window->driverdata;
  SDL_DisplayMode      *pSDLDisplayMode = &display->current_mode;

  debug( "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( "WinCalcFrameRect() failed" );
  else if ( !WinSetWindowPos( pWinData->hwndFrame, HWND_TOP,
                        rectl.xLeft, rectl.yBottom,
                        rectl.xRight - rectl.xLeft, rectl.yTop - rectl.yBottom,
                        ulFlags ) )
    debug( "WinSetWindowPos() failed" );
}

static SDL_bool OS2_GetWindowWMInfo(_THIS, SDL_Window * window,
                                    struct SDL_SysWMinfo *info)
{
  PWINDATA             pWinData = (PWINDATA)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( "Enter" );
  return 0;
}

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

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


// Shaper.

typedef struct _SHAPERECTS {
  PRECTL     pRects;
  ULONG      cRects;
  ULONG      ulWinHeight;
} SHAPERECTS, *PSHAPERECTS;

static void _combineRectRegions(SDL_ShapeTree *node, void *closure)
{
  PSHAPERECTS          pShapeRects = (PSHAPERECTS)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( "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;
  PWINDATA             pWinData;
  SHAPERECTS           stShapeRects = { 0 };
  HPS                  hps;

  debug( "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 = (PWINDATA)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( "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)
{
  PWINDATA             pWinData = (PWINDATA)window->driverdata;

  debug( "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)
{
  PWINDATA             pWinData = (PWINDATA)window->driverdata;
  SDL_VideoDisplay     *pSDLDisplay = SDL_GetDisplayForWindow( window );
  SDL_DisplayMode      *pSDLDisplayMode;
  PMODEDATA            pModeData;
  ULONG                ulWidth, ulHeight;

  debug( "Enter" );

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

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

  SDL_GetWindowSize( window, (int *)&ulWidth, (int *)&ulHeight );
  debug( "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( "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)
{
  PWINDATA             pWinData = (PWINDATA)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)
{
  PSDL_VideoData       pVData = (PSDL_VideoData)_this->driverdata;
  PSZ                  pszClipboard;
  PSZ                  pszText = text == NULL ? NULL : OS2_UTF8ToSys( text );
  ULONG                cbText;
  ULONG                ulRC;
  BOOL                 fSuccess;

  debug( "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( "DosAllocSharedMem() failed, rc = %u", ulRC );
    SDL_free( pszText );
    return -1;
  }

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

  if ( !WinOpenClipbrd( pVData->hab ) )
  {
    debug( "WinOpenClipbrd() failed" );
    fSuccess = FALSE;
  }
  else
  {    
    WinEmptyClipbrd( pVData->hab );

    fSuccess = WinSetClipbrdData( pVData->hab, (ULONG)pszClipboard, CF_TEXT,
                                  CFI_POINTER );
    if ( !fSuccess )
      debug( "WinOpenClipbrd() failed" );

    WinCloseClipbrd( pVData->hab );
  }

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

  return 0;
}

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

  if ( !WinOpenClipbrd( pVData->hab ) )
    debug( "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)
{
  PSDL_VideoData       pVData = (PSDL_VideoData)_this->driverdata;
  SDL_bool             fClipboard;

  if ( !WinOpenClipbrd( pVData->hab ) )
  {
    debug( "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)
{
  PSDL_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(PSDL_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;
    PDISPLAYDATA         pDisplayData;
    PMODEDATA            pModeData;
    VIDEOOUTPUTINFO      stVOInfo;

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

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

  OS2_InitMouse( _this, pVData->hab );

  return 0;
}

static void OS2_VideoQuit(_THIS)
{
  PSDL_VideoData       pVData = (PSDL_VideoData)_this->driverdata;
  ULONG                ulDisplayIdx, ulModeIdx;
  SDL_VideoDisplay     *pSDLDisplay;

  OS2_QuitMouse( _this );

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

  // We support only one display. Free all listed displays data for the future.
  for( ulDisplayIdx = 0; ulDisplayIdx < _this->num_displays; ulDisplayIdx++ )
  {
    pSDLDisplay = &_this->displays[ulDisplayIdx];

    // Free video mode data (PMODEDATA).
    if ( pSDLDisplay->desktop_mode.driverdata != NULL )
      SDL_free( pSDLDisplay->desktop_mode.driverdata );

    // We support only one mode - desktop_mode. Free all modes for the future.
    for( ulModeIdx = 0; ulModeIdx < pSDLDisplay->num_display_modes;
         ulModeIdx++ )
      if ( pSDLDisplay->display_modes[ulModeIdx].driverdata != NULL )
        SDL_free( pSDLDisplay->display_modes[ulModeIdx].driverdata );

    // Free display data (PDISPLAYDATA).
    if ( pSDLDisplay->driverdata != NULL )
    {
      SDL_free( pSDLDisplay->driverdata );
      pSDLDisplay->driverdata = NULL;
    }
  }
}

static int OS2_GetDisplayBounds(_THIS, SDL_VideoDisplay *display,
                                SDL_Rect *rect)
{
  debug( "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)
{
  PDISPLAYDATA         pDisplayData = (PDISPLAYDATA)display->driverdata;

  debug( "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( "Enter" );
  SDL_AddDisplayMode( display, &display->current_mode );
}

static int OS2_SetDisplayMode(_THIS, SDL_VideoDisplay *display,
                              SDL_DisplayMode *mode)
{
  debug( "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 (0);
  }

  /* Set the function pointers */
  device->VideoInit = OS2_VideoInit;
  device->VideoQuit = OS2_VideoQuit;
  device->SetDisplayMode = OS2_SetDisplayMode;
  device->GetDisplayBounds = OS2_GetDisplayBounds;
  device->GetDisplayDPI = OS2_GetDisplayDPI;
  device->GetDisplayModes = OS2_GetDisplayModes;
  device->SetDisplayMode = OS2_SetDisplayMode;
  device->PumpEvents = OS2_PumpEvents;
  device->CreateWindow = OS2_CreateWindow;
  device->CreateWindowFrom = 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->SetWindowGrab = OS2_SetWindowGrab;
  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;
}


// Output video system availability checking.

static int OS2DIVE_Available(void)
{
  VIDEOOUTPUTINFO      stVOInfo;

  return voDive.QueryInfo( &stVOInfo );
}

static int OS2VMAN_Available(void)
{
  VIDEOOUTPUTINFO      stVOInfo;

  return voVMan.QueryInfo( &stVOInfo );
}


// 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_Available, OS2_CreateDevice
};

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

#endif /* SDL_VIDEO_DRIVER_OS2 */
