mirror of
https://github.com/Ryujinx/SDL.git
synced 2025-03-08 10:00:15 +00:00
Our caller SDL_VideoQuit() already frees display_modes, driverdata, etc. Noticed in bitwiseworks' version at https://github.com/bitwiseworks/SDL2-os2
1770 lines
54 KiB
C
1770 lines
54 KiB
C
/*
|
|
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." );
|
|
}
|
|
|
|
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)
|
|
{
|
|
PSDL_VideoData pVData = (PSDL_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( "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 NULL;
|
|
}
|
|
|
|
/* 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->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->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;
|
|
}
|
|
|
|
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 */
|