mirror of
https://github.com/encounter/SDL.git
synced 2025-12-11 14:41:56 +00:00
os2: add port files for SDL2-2.0.4 from Andrey Vasilkin
only geniconv/iconv.h (was from LGPL libiconv) is replaced with a generic minimal iconv.h based on public knowledge.
This commit is contained in:
348
src/video/os2/SDL_os2dive.c
Normal file
348
src/video/os2/SDL_os2dive.c
Normal file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#include <os2.h>
|
||||
#define _MEERROR_H_
|
||||
#include <mmioos2.h>
|
||||
#include <os2me.h>
|
||||
#define INCL_MM_OS2
|
||||
#include <dive.h>
|
||||
#include <fourcc.h>
|
||||
#include "SDL_os2output.h"
|
||||
|
||||
typedef struct _VODATA {
|
||||
HDIVE hDive;
|
||||
PVOID pBuffer;
|
||||
ULONG ulDIVEBufNum;
|
||||
FOURCC fccColorEncoding;
|
||||
ULONG ulWidth;
|
||||
ULONG ulHeight;
|
||||
BOOL fBlitterReady;
|
||||
} VODATA;
|
||||
|
||||
static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo);
|
||||
static PVODATA voOpen();
|
||||
static VOID voClose(PVODATA pVOData);
|
||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||
SDL_DisplayMode *pSDLDisplayMode,
|
||||
HRGN hrgnShape, BOOL fVisible);
|
||||
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||
ULONG ulBPP, ULONG fccColorEncoding,
|
||||
PULONG pulScanLineSize);
|
||||
static VOID voVideoBufFree(PVODATA pVOData);
|
||||
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||
ULONG cSDLRects);
|
||||
|
||||
OS2VIDEOOUTPUT voDive = {
|
||||
voQueryInfo,
|
||||
voOpen,
|
||||
voClose,
|
||||
voSetVisibleRegion,
|
||||
voVideoBufAlloc,
|
||||
voVideoBufFree,
|
||||
voUpdate
|
||||
};
|
||||
|
||||
|
||||
static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo)
|
||||
{
|
||||
DIVE_CAPS sDiveCaps = { 0 };
|
||||
FOURCC fccFormats[100] = { 0 };
|
||||
|
||||
// Query information about display hardware from DIVE.
|
||||
|
||||
sDiveCaps.pFormatData = &fccFormats;
|
||||
sDiveCaps.ulFormatLength = 100;
|
||||
sDiveCaps.ulStructLen = sizeof(DIVE_CAPS);
|
||||
|
||||
if ( DiveQueryCaps( &sDiveCaps, DIVE_BUFFER_SCREEN ) )
|
||||
{
|
||||
debug( "DiveQueryCaps() failed." );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( sDiveCaps.ulDepth < 8 )
|
||||
{
|
||||
debug( "Not enough screen colors to run DIVE. "
|
||||
"Must be at least 256 colors." );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pInfo->ulBPP = sDiveCaps.ulDepth;
|
||||
pInfo->fccColorEncoding = sDiveCaps.fccColorEncoding;
|
||||
pInfo->ulScanLineSize = sDiveCaps.ulScanLineBytes;
|
||||
pInfo->ulHorizResolution = sDiveCaps.ulHorizontalResolution;
|
||||
pInfo->ulVertResolution = sDiveCaps.ulVerticalResolution;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PVODATA voOpen()
|
||||
{
|
||||
PVODATA pVOData = SDL_calloc( 1, sizeof(VODATA) );
|
||||
|
||||
if ( pVOData == NULL )
|
||||
{
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( DiveOpen( &pVOData->hDive, FALSE, NULL ) != DIVE_SUCCESS )
|
||||
{
|
||||
SDL_free( pVOData );
|
||||
SDL_SetError( "DIVE: A display engine instance open failed" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pVOData;
|
||||
}
|
||||
|
||||
static VOID voClose(PVODATA pVOData)
|
||||
{
|
||||
voVideoBufFree( pVOData );
|
||||
DiveClose( pVOData->hDive );
|
||||
SDL_free( pVOData );
|
||||
}
|
||||
|
||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||
SDL_DisplayMode *pSDLDisplayMode,
|
||||
HRGN hrgnShape, BOOL fVisible)
|
||||
{
|
||||
HPS hps;
|
||||
HRGN hrgn;
|
||||
RGNRECT rgnCtl;
|
||||
PRECTL prectl = NULL;
|
||||
ULONG ulRC;
|
||||
|
||||
if ( !fVisible )
|
||||
{
|
||||
if ( pVOData->fBlitterReady )
|
||||
{
|
||||
pVOData->fBlitterReady = FALSE;
|
||||
DiveSetupBlitter( pVOData->hDive, 0 );
|
||||
debug( "DIVE blitter is tuned off" );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Query visible rectangles
|
||||
|
||||
hps = WinGetPS( hwnd );
|
||||
hrgn = GpiCreateRegion( hps, 0, NULL );
|
||||
if ( hrgn == NULLHANDLE )
|
||||
{
|
||||
WinReleasePS( hps );
|
||||
SDL_SetError( "GpiCreateRegion() failed" );
|
||||
}
|
||||
else
|
||||
{
|
||||
WinQueryVisibleRegion( hwnd, hrgn );
|
||||
if ( hrgnShape != NULLHANDLE )
|
||||
GpiCombineRegion( hps, hrgn, hrgn, hrgnShape, CRGN_AND );
|
||||
|
||||
rgnCtl.ircStart = 1;
|
||||
rgnCtl.crc = 0;
|
||||
rgnCtl.ulDirection = 1;
|
||||
GpiQueryRegionRects( hps, hrgn, NULL, &rgnCtl, NULL );
|
||||
if ( rgnCtl.crcReturned != 0 )
|
||||
{
|
||||
prectl = SDL_malloc( rgnCtl.crcReturned * sizeof(RECTL) );
|
||||
if ( prectl != NULL )
|
||||
{
|
||||
rgnCtl.ircStart = 1;
|
||||
rgnCtl.crc = rgnCtl.crcReturned;
|
||||
rgnCtl.ulDirection = 1;
|
||||
GpiQueryRegionRects( hps, hrgn, NULL, &rgnCtl, prectl );
|
||||
}
|
||||
else
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
GpiDestroyRegion( hps, hrgn );
|
||||
WinReleasePS( hps );
|
||||
|
||||
if ( prectl != NULL )
|
||||
{
|
||||
// Setup DIVE blitter.
|
||||
SETUP_BLITTER sSetupBlitter;
|
||||
SWP swp;
|
||||
POINTL pointl = { 0 };
|
||||
|
||||
WinQueryWindowPos( hwnd, &swp );
|
||||
WinMapWindowPoints( hwnd, HWND_DESKTOP, &pointl, 1 );
|
||||
|
||||
sSetupBlitter.ulStructLen = sizeof(SETUP_BLITTER);
|
||||
sSetupBlitter.fccSrcColorFormat = pVOData->fccColorEncoding;
|
||||
sSetupBlitter.fInvert = FALSE;
|
||||
sSetupBlitter.ulSrcWidth = pVOData->ulWidth;
|
||||
sSetupBlitter.ulSrcHeight = pVOData->ulHeight;
|
||||
sSetupBlitter.ulSrcPosX = 0;
|
||||
sSetupBlitter.ulSrcPosY = 0;
|
||||
sSetupBlitter.ulDitherType = 0;
|
||||
sSetupBlitter.fccDstColorFormat = FOURCC_SCRN;
|
||||
sSetupBlitter.ulDstWidth = swp.cx;
|
||||
sSetupBlitter.ulDstHeight = swp.cy;
|
||||
sSetupBlitter.lDstPosX = 0;
|
||||
sSetupBlitter.lDstPosY = 0;
|
||||
sSetupBlitter.lScreenPosX = pointl.x;
|
||||
sSetupBlitter.lScreenPosY = pointl.y;
|
||||
|
||||
sSetupBlitter.ulNumDstRects = rgnCtl.crcReturned;
|
||||
sSetupBlitter.pVisDstRects = prectl;
|
||||
|
||||
ulRC = DiveSetupBlitter( pVOData->hDive, &sSetupBlitter );
|
||||
SDL_free( prectl );
|
||||
|
||||
if ( ulRC == DIVE_SUCCESS )
|
||||
{
|
||||
pVOData->fBlitterReady = TRUE;
|
||||
WinInvalidateRect( hwnd, NULL, TRUE );
|
||||
debug( "DIVE blitter is ready now." );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SDL_SetError( "DiveSetupBlitter(), rc = 0x%X", ulRC );
|
||||
} // if ( prectl != NULL )
|
||||
} // if ( hrgn == NULLHANDLE ) else
|
||||
|
||||
pVOData->fBlitterReady = FALSE;
|
||||
DiveSetupBlitter( pVOData->hDive, 0 );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||
ULONG ulBPP, FOURCC fccColorEncoding,
|
||||
PULONG pulScanLineSize)
|
||||
{
|
||||
ULONG ulRC;
|
||||
ULONG ulScanLineSize = ulWidth * (ulBPP >> 3);
|
||||
|
||||
// Destroy previous buffer.
|
||||
voVideoBufFree( pVOData );
|
||||
|
||||
if ( ( ulWidth == 0 ) || ( ulHeight == 0 ) || ( ulBPP == 0 ) )
|
||||
return NULL;
|
||||
|
||||
// Bytes per line.
|
||||
ulScanLineSize = ( ulScanLineSize + 3 ) & ~3; /* 4-byte aligning */
|
||||
*pulScanLineSize = ulScanLineSize;
|
||||
|
||||
ulRC = DosAllocMem( &pVOData->pBuffer,
|
||||
(ulHeight * ulScanLineSize) + sizeof(ULONG),
|
||||
PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE );
|
||||
if ( ulRC != NO_ERROR )
|
||||
{
|
||||
debug( "DosAllocMem(), rc = %u", ulRC );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ulRC = DiveAllocImageBuffer( pVOData->hDive, &pVOData->ulDIVEBufNum,
|
||||
fccColorEncoding, ulWidth, ulHeight,
|
||||
ulScanLineSize, pVOData->pBuffer );
|
||||
if ( ulRC != DIVE_SUCCESS )
|
||||
{
|
||||
debug( "DiveAllocImageBuffer(), rc = 0x%X", ulRC );
|
||||
DosFreeMem( pVOData->pBuffer );
|
||||
pVOData->pBuffer = NULL;
|
||||
pVOData->ulDIVEBufNum = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pVOData->fccColorEncoding = fccColorEncoding;
|
||||
pVOData->ulWidth = ulWidth;
|
||||
pVOData->ulHeight = ulHeight;
|
||||
|
||||
debug( "buffer: 0x%P, DIVE buffer number: %u",
|
||||
pVOData->pBuffer, pVOData->ulDIVEBufNum );
|
||||
|
||||
return pVOData->pBuffer;
|
||||
}
|
||||
|
||||
static VOID voVideoBufFree(PVODATA pVOData)
|
||||
{
|
||||
ULONG ulRC;
|
||||
|
||||
if ( pVOData->ulDIVEBufNum != 0 )
|
||||
{
|
||||
ulRC = DiveFreeImageBuffer( pVOData->hDive, pVOData->ulDIVEBufNum );
|
||||
if ( ulRC != DIVE_SUCCESS )
|
||||
debug( "DiveFreeImageBuffer(,%u), rc = %u", pVOData->ulDIVEBufNum, ulRC );
|
||||
else
|
||||
debug( "DIVE buffer %u destroyed", pVOData->ulDIVEBufNum );
|
||||
|
||||
pVOData->ulDIVEBufNum = 0;
|
||||
}
|
||||
|
||||
if ( pVOData->pBuffer != NULL )
|
||||
{
|
||||
ulRC = DosFreeMem( pVOData->pBuffer );
|
||||
if ( ulRC != NO_ERROR )
|
||||
debug( "DosFreeMem(), rc = %u", ulRC );
|
||||
|
||||
pVOData->pBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||
ULONG cSDLRects)
|
||||
{
|
||||
ULONG ulRC;
|
||||
|
||||
if ( !pVOData->fBlitterReady || ( pVOData->ulDIVEBufNum == 0 ) )
|
||||
{
|
||||
debug( "DIVE blitter is not ready" );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( pSDLRects != 0 )
|
||||
{
|
||||
PBYTE pbLineMask;
|
||||
|
||||
pbLineMask = SDL_stack_alloc( BYTE, pVOData->ulHeight );
|
||||
if ( pbLineMask == NULL )
|
||||
{
|
||||
debug( "Not enough stack size" );
|
||||
return FALSE;
|
||||
}
|
||||
memset( pbLineMask, 0, pVOData->ulHeight );
|
||||
|
||||
for( ; ((LONG)cSDLRects) > 0; cSDLRects--, pSDLRects++ )
|
||||
memset( &pbLineMask[pSDLRects->y], 1, pSDLRects->h );
|
||||
|
||||
ulRC = DiveBlitImageLines( pVOData->hDive, pVOData->ulDIVEBufNum,
|
||||
DIVE_BUFFER_SCREEN, pbLineMask );
|
||||
SDL_stack_free( pbLineMask );
|
||||
|
||||
if ( ulRC != DIVE_SUCCESS )
|
||||
debug( "DiveBlitImageLines(), rc = 0x%X", ulRC );
|
||||
}
|
||||
else
|
||||
{
|
||||
ulRC = DiveBlitImage( pVOData->hDive, pVOData->ulDIVEBufNum,
|
||||
DIVE_BUFFER_SCREEN );
|
||||
if ( ulRC != DIVE_SUCCESS )
|
||||
debug( "DiveBlitImage(), rc = 0x%X", ulRC );
|
||||
}
|
||||
|
||||
return ulRC == DIVE_SUCCESS;
|
||||
}
|
||||
593
src/video/os2/SDL_os2messagebox.c
Normal file
593
src/video/os2/SDL_os2messagebox.c
Normal file
@@ -0,0 +1,593 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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
|
||||
|
||||
/* Display a OS/2 message box */
|
||||
|
||||
#include "SDL.h"
|
||||
#include "../../core/os2/SDL_os2.h"
|
||||
#include "SDL_os2video.h"
|
||||
#define INCL_WIN
|
||||
#include <os2.h>
|
||||
|
||||
#define IDD_TEXT_MESSAGE 1001
|
||||
#define IDD_BITMAP 1002
|
||||
#define IDD_PB_FIRST 1003
|
||||
|
||||
typedef struct _MSGBOXDLGDATA {
|
||||
USHORT cb;
|
||||
HWND hwndUnder;
|
||||
} MSGBOXDLGDATA, *PMSGBOXDLGDATA;
|
||||
|
||||
static VOID _wmInitDlg(HWND hwnd, PMSGBOXDLGDATA pDlgData)
|
||||
{
|
||||
HPS hps = WinGetPS( hwnd );
|
||||
POINTL aptText[TXTBOX_COUNT];
|
||||
HENUM hEnum;
|
||||
HWND hWndNext;
|
||||
CHAR acBuf[256];
|
||||
ULONG cbBuf;
|
||||
ULONG cButtons = 0;
|
||||
ULONG ulButtonsCY = 0;
|
||||
ULONG ulButtonsCX = 0;
|
||||
RECTL rectl;
|
||||
ULONG ulX;
|
||||
ULONG ulIdx;
|
||||
struct _BUTTON {
|
||||
HWND hwnd; // Button window handle.
|
||||
ULONG ulCX; // Button width in dialog coordinates.
|
||||
} aButtons[32];
|
||||
RECTL rectlItem;
|
||||
HAB hab = WinQueryAnchorBlock( hwnd );
|
||||
|
||||
/* --- Align the buttons to the right/bottom. --- */
|
||||
|
||||
// Collect window handles of all buttons in dialog.
|
||||
|
||||
hEnum = WinBeginEnumWindows( hwnd );
|
||||
|
||||
while( ( hWndNext = WinGetNextWindow( hEnum ) ) != NULLHANDLE )
|
||||
{
|
||||
if ( WinQueryClassName( hWndNext, sizeof(acBuf), &acBuf ) == 0 )
|
||||
continue;
|
||||
|
||||
if ( strcmp( &acBuf, "#3" ) == 0 ) // Class name of button.
|
||||
{
|
||||
if ( cButtons < sizeof(aButtons) / sizeof(struct _BUTTON) )
|
||||
{
|
||||
aButtons[cButtons].hwnd = hWndNext;
|
||||
cButtons++;
|
||||
}
|
||||
}
|
||||
}
|
||||
WinEndEnumWindows( hEnum );
|
||||
|
||||
// Query size of text for each button, get width of each button, total
|
||||
// buttons width (ulButtonsCX) and max. height (ulButtonsCX) in _dialog
|
||||
// coordinates_.
|
||||
|
||||
hps = WinGetPS( hwnd );
|
||||
|
||||
for( ulIdx = 0; ulIdx < cButtons; ulIdx++ )
|
||||
{
|
||||
// Query size of text in window coordinates.
|
||||
cbBuf = WinQueryWindowText( aButtons[ulIdx].hwnd, sizeof(acBuf), &acBuf );
|
||||
GpiQueryTextBox( hps, cbBuf, acBuf, TXTBOX_COUNT, &aptText );
|
||||
aptText[TXTBOX_TOPRIGHT].x -= aptText[TXTBOX_BOTTOMLEFT].x;
|
||||
aptText[TXTBOX_TOPRIGHT].y -= aptText[TXTBOX_BOTTOMLEFT].y;
|
||||
// Convert text size to dialog coordinates.
|
||||
WinMapDlgPoints( hwnd, &aptText[TXTBOX_TOPRIGHT], 1, FALSE );
|
||||
// Add vertical and horizontal space for button's frame (dialog coord.).
|
||||
if ( aptText[TXTBOX_TOPRIGHT].x < 30 ) // Minimal button width.
|
||||
aptText[TXTBOX_TOPRIGHT].x = 30;
|
||||
else
|
||||
aptText[TXTBOX_TOPRIGHT].x += 4;
|
||||
aptText[TXTBOX_TOPRIGHT].y += 3;
|
||||
|
||||
aButtons[ulIdx].ulCX = aptText[TXTBOX_TOPRIGHT].x; // Store button width.
|
||||
ulButtonsCX += aptText[TXTBOX_TOPRIGHT].x + 2; // Add total btn. width.
|
||||
// Get max. height for buttons.
|
||||
if ( ulButtonsCY < aptText[TXTBOX_TOPRIGHT].y )
|
||||
ulButtonsCY = aptText[TXTBOX_TOPRIGHT].y + 1;
|
||||
}
|
||||
|
||||
WinReleasePS( hps );
|
||||
|
||||
// Expand horizontal size of the window to fit all buttons and move window
|
||||
// to the center of parent window.
|
||||
|
||||
// Convert total width of buttons to window coordinates.
|
||||
aptText[0].x = ulButtonsCX + 4;
|
||||
WinMapDlgPoints( hwnd, &aptText[0], 1, TRUE );
|
||||
// Check width of the window and expand as needed.
|
||||
WinQueryWindowRect( hwnd, &rectlItem );
|
||||
if ( rectlItem.xRight <= aptText[0].x )
|
||||
rectlItem.xRight = aptText[0].x;
|
||||
|
||||
// Move window rectangle to the center of owner window.
|
||||
WinQueryWindowRect( pDlgData->hwndUnder, &rectl );
|
||||
// Left-bottom point of centered dialog on owner window.
|
||||
rectl.xLeft = ( rectl.xRight - rectlItem.xRight ) / 2;
|
||||
rectl.yBottom = ( rectl.yTop - rectlItem.yTop ) / 2;
|
||||
// Map left-bottom point to desktop.
|
||||
WinMapWindowPoints( pDlgData->hwndUnder, HWND_DESKTOP, (PPOINTL)&rectl, 1 );
|
||||
WinOffsetRect( hab, &rectlItem, rectl.xLeft, rectl.yBottom );
|
||||
|
||||
// Set new rectangle for the window.
|
||||
WinSetWindowPos( hwnd, HWND_TOP, rectlItem.xLeft, rectlItem.yBottom,
|
||||
rectlItem.xRight - rectlItem.xLeft,
|
||||
rectlItem.yTop - rectlItem.yBottom,
|
||||
SWP_SIZE | SWP_MOVE );
|
||||
|
||||
// Set buttons positions.
|
||||
|
||||
// Get horizontal position for the first button.
|
||||
WinMapDlgPoints( hwnd, (PPOINTL)&rectlItem, 2, FALSE ); // Win size to dlg coord.
|
||||
ulX = rectlItem.xRight - rectlItem.xLeft - ulButtonsCX - 2; // First button position.
|
||||
|
||||
// Set positions and sizes for all buttons.
|
||||
for( ulIdx = 0; ulIdx < cButtons; ulIdx++ )
|
||||
{
|
||||
// Get poisition and size for the button in dialog coordinates.
|
||||
aptText[0].x = ulX;
|
||||
aptText[0].y = 2;
|
||||
aptText[1].x = aButtons[ulIdx].ulCX;
|
||||
aptText[1].y = ulButtonsCY;
|
||||
// Convert to window coordinates.
|
||||
WinMapDlgPoints( hwnd, &aptText, 2, TRUE );
|
||||
|
||||
WinSetWindowPos( aButtons[ulIdx].hwnd, HWND_TOP,
|
||||
aptText[0].x, aptText[0].y, aptText[1].x, aptText[1].y,
|
||||
SWP_MOVE | SWP_SIZE );
|
||||
|
||||
// Offset horizontal position for the next button.
|
||||
ulX += aButtons[ulIdx].ulCX + 2;
|
||||
}
|
||||
|
||||
// Set right bound of the text to right bound of the last button and
|
||||
// bottom bound of the text just above the buttons.
|
||||
|
||||
aptText[2].x = 25; // Left bound of text in dlg coordinates.
|
||||
aptText[2].y = ulButtonsCY + 3; // Bottom bound of the text in dlg coords.
|
||||
WinMapDlgPoints( hwnd, &aptText[2], 1, TRUE ); // Convert ^^^ to win. coords.
|
||||
hWndNext = WinWindowFromID( hwnd, IDD_TEXT_MESSAGE );
|
||||
WinQueryWindowRect( hWndNext, &rectlItem );
|
||||
rectlItem.xLeft = aptText[2].x;
|
||||
rectlItem.yBottom = aptText[2].y;
|
||||
// Right bound of the text equals right bound of the last button.
|
||||
rectlItem.xRight = aptText[0].x + aptText[1].x;
|
||||
WinSetWindowPos( hWndNext, HWND_TOP, rectlItem.xLeft, rectlItem.yBottom,
|
||||
rectlItem.xRight - rectlItem.xLeft,
|
||||
rectlItem.yTop - rectlItem.yBottom,
|
||||
SWP_MOVE | SWP_SIZE );
|
||||
}
|
||||
|
||||
MRESULT EXPENTRY DynDlgProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
switch( message )
|
||||
{
|
||||
case WM_INITDLG:
|
||||
_wmInitDlg( hwnd, (PMSGBOXDLGDATA)mp2 );
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch( SHORT1FROMMP(mp1) )
|
||||
{
|
||||
case DID_OK:
|
||||
WinDismissDlg( hwnd, FALSE );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return( WinDefDlgProc( hwnd, message, mp1, mp2 ) );
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
|
||||
{
|
||||
SDL_MessageBoxButtonData *pSDLBtnData =
|
||||
(SDL_MessageBoxButtonData *)messageboxdata->buttons;
|
||||
ULONG cSDLBtnData = messageboxdata->numbuttons;
|
||||
|
||||
PSZ pszTitle = OS2_UTF8ToSys( (PSZ)messageboxdata->title );
|
||||
ULONG cbTitle = pszTitle == NULL ?
|
||||
0 : strlen( pszTitle );
|
||||
PSZ pszText = OS2_UTF8ToSys( (PSZ)messageboxdata->message );
|
||||
ULONG cbText = pszText == NULL ?
|
||||
0 : strlen( pszText );
|
||||
|
||||
PDLGTEMPLATE pTemplate;
|
||||
ULONG cbTemplate;
|
||||
ULONG ulIdx;
|
||||
PCHAR pcDlgData;
|
||||
PDLGTITEM pDlgItem;
|
||||
PSZ pszBtnText;
|
||||
ULONG cbBtnText;
|
||||
HWND hwnd;
|
||||
SDL_MessageBoxColor *pSDLColors = messageboxdata->colorScheme == NULL
|
||||
? NULL
|
||||
: (SDL_MessageBoxColor *)&messageboxdata->colorScheme->colors;
|
||||
SDL_MessageBoxColor *pSDLColor;
|
||||
MSGBOXDLGDATA stDlgData;
|
||||
|
||||
/* Build a dialog tamplate in memory */
|
||||
|
||||
// Size of template (cbTemplate).
|
||||
|
||||
cbTemplate = sizeof(DLGTEMPLATE) + ( (2 + cSDLBtnData) * sizeof(DLGTITEM) ) +
|
||||
sizeof(ULONG) + // First item data - frame control data.
|
||||
cbTitle + 1 + // First item data - frame title + ZERO.
|
||||
cbText + 1 + // Second item data - ststic text + ZERO.
|
||||
3; // Third item data - system icon Id.
|
||||
// Button items datas - text for buttons.
|
||||
for( ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++ )
|
||||
{
|
||||
pszBtnText = (PSZ)pSDLBtnData[ulIdx].text;
|
||||
cbTemplate += pszBtnText == NULL ? 1 : ( strlen( pszBtnText ) + 1 );
|
||||
}
|
||||
// Presentation parameter space.
|
||||
if ( pSDLColors != NULL )
|
||||
cbTemplate += 26 /* PP for frame. */ + 26 /* PP for static text. */ +
|
||||
( 48 * cSDLBtnData ); /* PP for buttons. */
|
||||
|
||||
// Allocate memory for the dialog template.
|
||||
pTemplate = SDL_malloc( cbTemplate );
|
||||
// Pointer on data for dialog items in allocated memory.
|
||||
pcDlgData = &((PCHAR)pTemplate)[ sizeof(DLGTEMPLATE) +
|
||||
( (2 + cSDLBtnData) * sizeof(DLGTITEM) ) ];
|
||||
|
||||
/* Header info */
|
||||
|
||||
pTemplate->cbTemplate = cbTemplate; /* size of dialog template to pass to WinCreateDlg() */
|
||||
pTemplate->type = 0; /* Currently always 0. */
|
||||
pTemplate->codepage = 0;
|
||||
pTemplate->offadlgti = 14; /* Offset to array of DLGTITEMs. */
|
||||
pTemplate->fsTemplateStatus = 0; /* Reserved field? */
|
||||
|
||||
/* Index in array of dlg items of item to get focus, */
|
||||
/* if 0 then focus goes to first control that can have focus. */
|
||||
pTemplate->iItemFocus = 0;
|
||||
pTemplate->coffPresParams = 0;
|
||||
|
||||
/* First item info - frame */
|
||||
|
||||
pDlgItem = &pTemplate->adlgti;
|
||||
pDlgItem->fsItemStatus = 0; /* Reserved? */
|
||||
/* Number of dialog item child windows owned by this item. */
|
||||
pDlgItem->cChildren = 2 + cSDLBtnData; // Ststic text + buttons.
|
||||
/* Length of class name, if 0 then offClassname contains a WC_ value. */
|
||||
pDlgItem->cchClassName = 0;
|
||||
pDlgItem->offClassName = (USHORT)WC_FRAME;
|
||||
/* Length of text. */
|
||||
pDlgItem->cchText = cbTitle + 1; /* +1 - trailing ZERO. */
|
||||
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to title text. */
|
||||
/* Copy text for the title into the dialog template. */
|
||||
if ( pszTitle != NULL )
|
||||
strcpy( pcDlgData, pszTitle );
|
||||
else
|
||||
*pcDlgData = '\0';
|
||||
pcDlgData += pDlgItem->cchText;
|
||||
|
||||
pDlgItem->flStyle = WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS |
|
||||
FS_DLGBORDER | WS_SAVEBITS;
|
||||
pDlgItem->x = 100;
|
||||
pDlgItem->y = 100;
|
||||
pDlgItem->cx = 175;
|
||||
pDlgItem->cy = 65;
|
||||
pDlgItem->id = DID_OK; /* An ID value? */
|
||||
if ( pSDLColors == NULL )
|
||||
pDlgItem->offPresParams = 0;
|
||||
else
|
||||
{
|
||||
// Presentation parameter for the frame - dialog colors.
|
||||
pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
|
||||
((PPRESPARAMS)pcDlgData)->cb = 22;
|
||||
pcDlgData += 4;
|
||||
((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r;
|
||||
pcDlgData += 11;
|
||||
((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r;
|
||||
pcDlgData += 11;
|
||||
}
|
||||
|
||||
/* Offset to ctl data. */
|
||||
pDlgItem->offCtlData = pcDlgData - (PCHAR)pTemplate;
|
||||
/* Put CtlData for the dialog in here */
|
||||
*((PULONG)pcDlgData) = FCF_TITLEBAR | FCF_SYSMENU;
|
||||
pcDlgData += sizeof(ULONG);
|
||||
|
||||
/* Second item info - static text (message). */
|
||||
|
||||
pDlgItem++;
|
||||
pDlgItem->fsItemStatus = 0;
|
||||
/* No children since its a control, it could have child control */
|
||||
/* (ex. a group box). */
|
||||
pDlgItem->cChildren = 0;
|
||||
/* Length of class name, 0 - offClassname contains a WC_ constant. */
|
||||
pDlgItem->cchClassName = 0;
|
||||
pDlgItem->offClassName = (USHORT)WC_STATIC;
|
||||
|
||||
pDlgItem->cchText = cbText + 1;
|
||||
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */
|
||||
/* Copy message text into the dialog template. */
|
||||
if ( pszText != NULL )
|
||||
strcpy( pcDlgData, pszText );
|
||||
else
|
||||
*pcDlgData = '\0';
|
||||
pcDlgData += pDlgItem->cchText;
|
||||
|
||||
pDlgItem->flStyle = SS_TEXT | DT_TOP | DT_LEFT | DT_WORDBREAK | WS_VISIBLE;
|
||||
// It will be really set in _wmInitDlg().
|
||||
pDlgItem->x = 25;
|
||||
pDlgItem->y = 13;
|
||||
pDlgItem->cx = 147;
|
||||
pDlgItem->cy = 62; // It will be used.
|
||||
|
||||
pDlgItem->id = IDD_TEXT_MESSAGE; /* an ID value */
|
||||
if ( pSDLColors == NULL )
|
||||
pDlgItem->offPresParams = 0;
|
||||
else
|
||||
{
|
||||
// Presentation parameter for the static text - dialog colors.
|
||||
pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
|
||||
((PPRESPARAMS)pcDlgData)->cb = 22;
|
||||
pcDlgData += 4;
|
||||
((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r;
|
||||
pcDlgData += 11;
|
||||
((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r;
|
||||
pcDlgData += 11;
|
||||
}
|
||||
pDlgItem->offCtlData = 0;
|
||||
|
||||
/* Third item info - static bitmap. */
|
||||
|
||||
pDlgItem++;
|
||||
pDlgItem->fsItemStatus = 0;
|
||||
pDlgItem->cChildren = 0;
|
||||
pDlgItem->cchClassName = 0;
|
||||
pDlgItem->offClassName = (USHORT)WC_STATIC;
|
||||
|
||||
pDlgItem->cchText = 3; // 0xFF, low byte of the icon Id, high byte of icon Id.
|
||||
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the Id. */
|
||||
/* Write susyem icon ID into dialog template. */
|
||||
*pcDlgData = 0xFF; // First byte is 0xFF - next 2 bytes is system pointer Id.
|
||||
pcDlgData++;
|
||||
*((PUSHORT)pcDlgData) =
|
||||
(messageboxdata->flags & SDL_MESSAGEBOX_ERROR) != 0
|
||||
? SPTR_ICONERROR
|
||||
: (messageboxdata->flags & SDL_MESSAGEBOX_WARNING) != 0
|
||||
? SPTR_ICONWARNING : SPTR_ICONINFORMATION;
|
||||
pcDlgData += 2;
|
||||
|
||||
pDlgItem->flStyle = SS_SYSICON | WS_VISIBLE;
|
||||
|
||||
pDlgItem->x = 4;
|
||||
pDlgItem->y = 45; // It will be really set in _wmInitDlg().
|
||||
pDlgItem->cx = 0;
|
||||
pDlgItem->cy = 0;
|
||||
|
||||
pDlgItem->id = IDD_BITMAP;
|
||||
pDlgItem->offPresParams = 0;
|
||||
pDlgItem->offCtlData = 0;
|
||||
|
||||
/* Next items - buttons. */
|
||||
|
||||
for( ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++ )
|
||||
{
|
||||
pDlgItem++;
|
||||
|
||||
pDlgItem->fsItemStatus = 0;
|
||||
pDlgItem->cChildren = 0; /* No children. */
|
||||
pDlgItem->cchClassName = 0; /* 0 - offClassname is WC_ constant. */
|
||||
pDlgItem->offClassName = (USHORT)WC_BUTTON;
|
||||
|
||||
pszBtnText = OS2_UTF8ToSys( (PSZ)pSDLBtnData[ulIdx].text );
|
||||
cbBtnText = ( pszBtnText == NULL ?
|
||||
0 : strlen( pszBtnText ) );
|
||||
pDlgItem->cchText = cbBtnText + 1;
|
||||
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */
|
||||
/* Copy text for the button into the dialog template. */
|
||||
if ( pszBtnText != NULL )
|
||||
strcpy( pcDlgData, pszBtnText );
|
||||
else
|
||||
*pcDlgData = '\0';
|
||||
pcDlgData += pDlgItem->cchText;
|
||||
SDL_free( pszBtnText );
|
||||
|
||||
pDlgItem->flStyle = BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE;
|
||||
if ( pSDLBtnData[ulIdx].flags == SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT )
|
||||
{
|
||||
pDlgItem->flStyle |= BS_DEFAULT;
|
||||
pTemplate->iItemFocus = ulIdx + 3; // +3 - frame, static text and icon.
|
||||
pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED];
|
||||
}
|
||||
else
|
||||
pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT];
|
||||
|
||||
// It will be really set in _wmInitDlg()
|
||||
pDlgItem->x = 10;
|
||||
pDlgItem->y = 10;
|
||||
pDlgItem->cx = 70;
|
||||
pDlgItem->cy = 15;
|
||||
|
||||
pDlgItem->id = IDD_PB_FIRST + ulIdx; /* an ID value */
|
||||
if ( pSDLColors == NULL )
|
||||
pDlgItem->offPresParams = 0;
|
||||
else
|
||||
{
|
||||
// Presentation parameter for the button - dialog colors.
|
||||
pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
|
||||
((PPRESPARAMS)pcDlgData)->cb = 44;
|
||||
pcDlgData += 4;
|
||||
((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColor->b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColor->g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColor->r;
|
||||
pcDlgData += 11;
|
||||
((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].r;
|
||||
pcDlgData += 11;
|
||||
((PPARAM)pcDlgData)->id = PP_BORDERLIGHTCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r;
|
||||
pcDlgData += 11;
|
||||
((PPARAM)pcDlgData)->id = PP_BORDERDARKCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r;
|
||||
pcDlgData += 11;
|
||||
}
|
||||
pDlgItem->offCtlData = 0;
|
||||
}
|
||||
// Check, end of templ. data: &((PCHAR)pTemplate)[cbTemplate] == pcDlgData
|
||||
|
||||
// Create the dialog from template.
|
||||
|
||||
stDlgData.cb = sizeof(MSGBOXDLGDATA);
|
||||
stDlgData.hwndUnder = ( messageboxdata->window != NULL ) &&
|
||||
( messageboxdata->window->driverdata != NULL )
|
||||
? ((PWINDATA)messageboxdata->window->driverdata)->hwnd
|
||||
: HWND_DESKTOP;
|
||||
|
||||
hwnd = WinCreateDlg( HWND_DESKTOP, // Parent is desktop.
|
||||
stDlgData.hwndUnder,
|
||||
(PFNWP)DynDlgProc, pTemplate, &stDlgData );
|
||||
SDL_free( pTemplate );
|
||||
SDL_free( pszTitle );
|
||||
SDL_free( pszText );
|
||||
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
|
||||
int OS2_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
{
|
||||
HWND hwnd;
|
||||
ULONG ulRC;
|
||||
SDL_MessageBoxButtonData
|
||||
*pSDLBtnData =
|
||||
(SDL_MessageBoxButtonData *)messageboxdata->buttons;
|
||||
ULONG cSDLBtnData = messageboxdata->numbuttons;
|
||||
BOOL fVideoInitialized = SDL_WasInit( SDL_INIT_VIDEO );
|
||||
HAB hab;
|
||||
HMQ hmq;
|
||||
BOOL fSuccess = FALSE;
|
||||
|
||||
if ( !fVideoInitialized )
|
||||
{
|
||||
PTIB tib;
|
||||
PPIB pib;
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
hab = WinInitialize( 0 );
|
||||
if ( hab == NULLHANDLE )
|
||||
{
|
||||
debug( "WinInitialize() failed" );
|
||||
return -1;
|
||||
}
|
||||
hmq = WinCreateMsgQueue( hab, 0 );
|
||||
if ( hmq == NULLHANDLE )
|
||||
{
|
||||
debug( "WinCreateMsgQueue() failed" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Create dynamic dialog.
|
||||
hwnd = _makeDlg( messageboxdata );
|
||||
// Show dialog and obtain button Id.
|
||||
ulRC = WinProcessDlg( hwnd );
|
||||
// Destroy dialog,
|
||||
WinDestroyWindow( hwnd );
|
||||
|
||||
if ( ulRC == DID_CANCEL )
|
||||
{
|
||||
// Window closed by ESC, Alt+F4 or system menu.
|
||||
ULONG ulIdx;
|
||||
|
||||
for( ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++, pSDLBtnData++ )
|
||||
{
|
||||
if ( pSDLBtnData->flags == SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT )
|
||||
{
|
||||
*buttonid = pSDLBtnData->buttonid;
|
||||
fSuccess = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Button pressed.
|
||||
ulRC -= IDD_PB_FIRST;
|
||||
if ( ulRC < cSDLBtnData )
|
||||
{
|
||||
*buttonid = pSDLBtnData[ulRC].buttonid;
|
||||
fSuccess = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !fVideoInitialized )
|
||||
{
|
||||
WinDestroyMsgQueue( hmq );
|
||||
WinTerminate( hab );
|
||||
}
|
||||
|
||||
return fSuccess ? 0 : -1;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
29
src/video/os2/SDL_os2messagebox.h
Normal file
29
src/video/os2/SDL_os2messagebox.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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
|
||||
|
||||
extern int OS2_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
204
src/video/os2/SDL_os2mouse.c
Normal file
204
src/video/os2/SDL_os2mouse.c
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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_os2video.h"
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "SDL_os2util.h"
|
||||
|
||||
HPOINTER hptrCursor = NULLHANDLE;
|
||||
|
||||
static SDL_Cursor* OS2_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
||||
{
|
||||
ULONG ulMaxW = WinQuerySysValue( HWND_DESKTOP, SV_CXPOINTER );
|
||||
ULONG ulMaxH = WinQuerySysValue( HWND_DESKTOP, SV_CYPOINTER );
|
||||
HPOINTER hptr;
|
||||
SDL_Cursor *pSDLCursor;
|
||||
|
||||
if ( ( surface->w > ulMaxW ) || ( surface->h > ulMaxH ) )
|
||||
{
|
||||
debug( "Given image size is %u x %u, maximum allowed size is %u x %u",
|
||||
surface->w, surface->h, ulMaxW, ulMaxH );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hptr = utilCreatePointer( surface, hot_x, ulMaxH - hot_y - 1 );
|
||||
if ( hptr == NULLHANDLE )
|
||||
return NULL;
|
||||
|
||||
pSDLCursor = SDL_calloc( 1, sizeof(SDL_Cursor) );
|
||||
if ( pSDLCursor == NULL )
|
||||
{
|
||||
WinDestroyPointer( hptr );
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSDLCursor->driverdata = (void *)hptr;
|
||||
return pSDLCursor;
|
||||
}
|
||||
|
||||
static SDL_Cursor* OS2_CreateSystemCursor(SDL_SystemCursor id)
|
||||
{
|
||||
SDL_Cursor* pSDLCursor;
|
||||
LONG lSysId;
|
||||
HPOINTER hptr;
|
||||
|
||||
switch( id )
|
||||
{
|
||||
case SDL_SYSTEM_CURSOR_ARROW: lSysId = SPTR_ARROW; break;
|
||||
case SDL_SYSTEM_CURSOR_IBEAM: lSysId = SPTR_TEXT; break;
|
||||
case SDL_SYSTEM_CURSOR_WAIT: lSysId = SPTR_WAIT; break;
|
||||
case SDL_SYSTEM_CURSOR_CROSSHAIR: lSysId = SPTR_MOVE; break;
|
||||
case SDL_SYSTEM_CURSOR_WAITARROW: lSysId = SPTR_WAIT; break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENWSE: lSysId = SPTR_SIZENWSE; break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENESW: lSysId = SPTR_SIZENESW; break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEWE: lSysId = SPTR_SIZEWE; break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENS: lSysId = SPTR_SIZENS; break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEALL: lSysId = SPTR_MOVE; break;
|
||||
case SDL_SYSTEM_CURSOR_NO: lSysId = SPTR_ILLEGAL; break;
|
||||
case SDL_SYSTEM_CURSOR_HAND: lSysId = SPTR_ARROW; break;
|
||||
default:
|
||||
debug( "Unknown cursor id: %u", id );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// On eCS SPTR_WAIT for last paramether fCopy=TRUE/FALSE gives different
|
||||
// "wait" icons. -=8( )
|
||||
hptr = WinQuerySysPointer( HWND_DESKTOP, lSysId,
|
||||
id == SDL_SYSTEM_CURSOR_WAIT );
|
||||
if ( hptr == NULLHANDLE )
|
||||
{
|
||||
debug( "Cannot load OS/2 system pointer %u for SDL cursor id %u",
|
||||
lSysId, id );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSDLCursor = SDL_calloc( 1, sizeof(SDL_Cursor) );
|
||||
if ( pSDLCursor == NULL )
|
||||
{
|
||||
WinDestroyPointer( hptr );
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSDLCursor->driverdata = (void *)hptr;
|
||||
return pSDLCursor;
|
||||
}
|
||||
|
||||
static void OS2_FreeCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
HPOINTER hptr = (HPOINTER)cursor->driverdata;
|
||||
|
||||
WinDestroyPointer( hptr );
|
||||
SDL_free( cursor );
|
||||
}
|
||||
|
||||
static int OS2_ShowCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
hptrCursor = cursor != NULL ? (HPOINTER)cursor->driverdata : NULLHANDLE;
|
||||
|
||||
return ( ( SDL_GetMouseFocus() == NULL ) ||
|
||||
WinSetPointer( HWND_DESKTOP, hptrCursor ) ) ? 0 : -1;
|
||||
}
|
||||
|
||||
static void OS2_WarpMouse(SDL_Window * window, int x, int y)
|
||||
{
|
||||
PWINDATA pWinData = (PWINDATA)window->driverdata;
|
||||
POINTL pointl;
|
||||
|
||||
pointl.x = x;
|
||||
pointl.y = window->h - y;
|
||||
WinMapWindowPoints( pWinData->hwnd, HWND_DESKTOP, &pointl, 1 );
|
||||
// pWinData->lSkipWMMouseMove++; ???
|
||||
WinSetPointerPos( HWND_DESKTOP, pointl.x, pointl.y );
|
||||
}
|
||||
|
||||
static int OS2_WarpMouseGlobal(int x, int y)
|
||||
{
|
||||
WinSetPointerPos( HWND_DESKTOP, x,
|
||||
WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - y );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int OS2_CaptureMouse(SDL_Window *window)
|
||||
{
|
||||
return WinSetCapture( HWND_DESKTOP,
|
||||
window == NULL ? NULLHANDLE
|
||||
: ((PWINDATA)window->driverdata)->hwnd )
|
||||
? 0 : -1;
|
||||
}
|
||||
|
||||
static Uint32 OS2_GetGlobalMouseState(int *x, int *y)
|
||||
{
|
||||
POINTL pointl;
|
||||
ULONG ulRes;
|
||||
|
||||
WinQueryPointerPos( HWND_DESKTOP, &pointl );
|
||||
*x = pointl.x;
|
||||
*y = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - pointl.y - 1;
|
||||
|
||||
ulRes = WinGetKeyState( HWND_DESKTOP, VK_BUTTON1 ) & 0x8000
|
||||
? SDL_BUTTON_LMASK : 0;
|
||||
if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON2 ) & 0x8000 )
|
||||
ulRes |= SDL_BUTTON_RMASK;
|
||||
if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON3 ) & 0x8000 )
|
||||
ulRes |= SDL_BUTTON_MMASK;
|
||||
|
||||
return ulRes;
|
||||
}
|
||||
|
||||
|
||||
void OS2_InitMouse(_THIS, ULONG hab)
|
||||
{
|
||||
SDL_Mouse *pSDLMouse = SDL_GetMouse();
|
||||
|
||||
pSDLMouse->CreateCursor = OS2_CreateCursor;
|
||||
pSDLMouse->CreateSystemCursor = OS2_CreateSystemCursor;
|
||||
pSDLMouse->ShowCursor = OS2_ShowCursor;
|
||||
pSDLMouse->FreeCursor = OS2_FreeCursor;
|
||||
pSDLMouse->WarpMouse = OS2_WarpMouse;
|
||||
pSDLMouse->WarpMouseGlobal = OS2_WarpMouseGlobal;
|
||||
pSDLMouse->CaptureMouse = OS2_CaptureMouse;
|
||||
pSDLMouse->GetGlobalMouseState = OS2_GetGlobalMouseState;
|
||||
|
||||
SDL_SetDefaultCursor( OS2_CreateSystemCursor( SDL_SYSTEM_CURSOR_ARROW ) );
|
||||
if ( hptrCursor == NULLHANDLE )
|
||||
hptrCursor = WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, TRUE );
|
||||
|
||||
SDL_SetDoubleClickTime( WinQuerySysValue( HWND_DESKTOP, SV_DBLCLKTIME ) );
|
||||
}
|
||||
|
||||
void OS2_QuitMouse(_THIS)
|
||||
{
|
||||
SDL_Mouse *pSDLMouse = SDL_GetMouse();
|
||||
|
||||
if ( pSDLMouse->def_cursor != NULL )
|
||||
{
|
||||
SDL_free( pSDLMouse->def_cursor );
|
||||
pSDLMouse->def_cursor = NULL;
|
||||
pSDLMouse->cur_cursor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
||||
33
src/video/os2/SDL_os2mouse.h
Normal file
33
src/video/os2/SDL_os2mouse.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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"
|
||||
|
||||
#ifndef _SDL_os2mouse_h
|
||||
#define _SDL_os2mouse_h
|
||||
|
||||
extern HPOINTER hptrCursor;
|
||||
|
||||
extern void OS2_InitMouse(_THIS, ULONG hab);
|
||||
extern void OS2_QuitMouse(_THIS);
|
||||
|
||||
#endif /* _SDL_os2mouse_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
54
src/video/os2/SDL_os2output.h
Normal file
54
src/video/os2/SDL_os2output.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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.
|
||||
*/
|
||||
#ifndef _SDL_os2output_
|
||||
#define _SDL_os2output_
|
||||
|
||||
#include ".\core\os2\SDL_os2.h"
|
||||
|
||||
typedef struct _VODATA *PVODATA;
|
||||
|
||||
typedef struct _VIDEOOUTPUTINFO {
|
||||
ULONG ulBPP;
|
||||
ULONG fccColorEncoding;
|
||||
ULONG ulScanLineSize;
|
||||
ULONG ulHorizResolution;
|
||||
ULONG ulVertResolution;
|
||||
} VIDEOOUTPUTINFO, *PVIDEOOUTPUTINFO;
|
||||
|
||||
typedef struct _OS2VIDEOOUTPUT {
|
||||
BOOL (*QueryInfo)(PVIDEOOUTPUTINFO pInfo);
|
||||
PVODATA (*Open)();
|
||||
VOID (*Close)(PVODATA pVOData);
|
||||
BOOL (*SetVisibleRegion)(PVODATA pVOData, HWND hwnd,
|
||||
SDL_DisplayMode *pSDLDisplayMode, HRGN hrgnShape,
|
||||
BOOL fVisible);
|
||||
PVOID (*VideoBufAlloc)(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||
ULONG ulBPP, ULONG fccColorEncoding,
|
||||
PULONG pulScanLineSize);
|
||||
VOID (*VideoBufFree)(PVODATA pVOData);
|
||||
BOOL (*Update)(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||
ULONG cSDLRects);
|
||||
} OS2VIDEOOUTPUT, *POS2VIDEOOUTPUT;
|
||||
|
||||
extern OS2VIDEOOUTPUT voDive;
|
||||
extern OS2VIDEOOUTPUT voVMan;
|
||||
|
||||
#endif // _SDL_os2output_
|
||||
118
src/video/os2/SDL_os2util.c
Normal file
118
src/video/os2/SDL_os2util.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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_os2util.h"
|
||||
|
||||
|
||||
HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY)
|
||||
{
|
||||
HBITMAP hbm;
|
||||
BITMAPINFOHEADER2 bmih = { 0 };
|
||||
BITMAPINFO bmi = { 0 };
|
||||
HPS hps;
|
||||
PULONG pulBitmap;
|
||||
PULONG pulDst, pulSrc, pulDstMask;
|
||||
ULONG ulY, ulX;
|
||||
HPOINTER hptr = NULLHANDLE;
|
||||
|
||||
if ( surface->format->format != SDL_PIXELFORMAT_ARGB8888 )
|
||||
{
|
||||
debug( "Image format should be SDL_PIXELFORMAT_ARGB8888" );
|
||||
return NULLHANDLE;
|
||||
}
|
||||
|
||||
pulBitmap = SDL_malloc( surface->h * surface->w * 4 * 2 );
|
||||
if ( pulBitmap == NULL )
|
||||
{
|
||||
SDL_OutOfMemory();
|
||||
return NULLHANDLE;
|
||||
}
|
||||
|
||||
// pulDst - last line of surface (image) part of the result bitmap's
|
||||
pulDst = &pulBitmap[ (surface->h - 1) * surface->w ];
|
||||
// pulDstMask - last line of mask part of the result bitmap's
|
||||
pulDstMask = &pulBitmap[ (2 * surface->h - 1) * surface->w ];
|
||||
// pulSrc - first line of source image
|
||||
pulSrc = (PULONG)surface->pixels;
|
||||
|
||||
for( ulY = 0; ulY < surface->h; ulY++ )
|
||||
{
|
||||
for( ulX = 0; ulX < surface->w; ulX++ )
|
||||
{
|
||||
if ( (pulSrc[ulX] & 0xFF000000) == 0 )
|
||||
{
|
||||
pulDst[ulX] = 0;
|
||||
pulDstMask[ulX] = 0xFFFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
pulDst[ulX] = pulSrc[ulX] & 0xFFFFFF;
|
||||
pulDstMask[ulX] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Set image and mask pointers on one line up
|
||||
pulDst -= surface->w;
|
||||
pulDstMask -= surface->w;
|
||||
// Set source image pointer to the next line
|
||||
pulSrc = (PULONG)( ((PCHAR)pulSrc) + surface->pitch );
|
||||
}
|
||||
|
||||
// Create system bitmap object.
|
||||
|
||||
bmih.cbFix = sizeof(BITMAPINFOHEADER2);
|
||||
bmih.cx = surface->w;
|
||||
bmih.cy = 2 * surface->h;
|
||||
bmih.cPlanes = 1;
|
||||
bmih.cBitCount = 32;
|
||||
bmih.ulCompression = BCA_UNCOMP;
|
||||
bmih.cbImage = bmih.cx * bmih.cy * 4;
|
||||
|
||||
bmi.cbFix = sizeof(BITMAPINFOHEADER);
|
||||
bmi.cx = bmih.cx;
|
||||
bmi.cy = bmih.cy;
|
||||
bmi.cPlanes = 1;
|
||||
bmi.cBitCount = 32;
|
||||
|
||||
hps = WinGetPS( HWND_DESKTOP );
|
||||
hbm = GpiCreateBitmap( hps, (PBITMAPINFOHEADER2)&bmih, CBM_INIT,
|
||||
(PBYTE)pulBitmap, (PBITMAPINFO2)&bmi );
|
||||
if ( hbm == GPI_ERROR )
|
||||
debug( "GpiCreateBitmap() failed" );
|
||||
else
|
||||
{
|
||||
// Create a system pointer object.
|
||||
hptr = WinCreatePointer( HWND_DESKTOP, hbm, TRUE, ulHotX, ulHotY );
|
||||
if ( hptr == NULLHANDLE )
|
||||
debug( "WinCreatePointer() failed" );
|
||||
}
|
||||
GpiDeleteBitmap( hbm );
|
||||
|
||||
WinReleasePS( hps );
|
||||
SDL_free( pulBitmap );
|
||||
|
||||
return hptr;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
||||
38
src/video/os2/SDL_os2util.h
Normal file
38
src/video/os2/SDL_os2util.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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.
|
||||
*/
|
||||
|
||||
#ifndef _SDL_os2util_h
|
||||
#define _SDL_os2util_h
|
||||
|
||||
#include "SDL_log.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../core/os2/SDL_os2.h"
|
||||
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#include <os2.h>
|
||||
|
||||
/*#define debug(s,...) SDL_LogDebug( SDL_LOG_CATEGORY_VIDEO, \
|
||||
__func__"(): "##s, ##__VA_ARGS__ )*/
|
||||
|
||||
HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY);
|
||||
|
||||
#endif // _SDL_os2util_h
|
||||
1786
src/video/os2/SDL_os2video.c
Normal file
1786
src/video/os2/SDL_os2video.c
Normal file
File diff suppressed because it is too large
Load Diff
83
src/video/os2/SDL_os2video.h
Normal file
83
src/video/os2/SDL_os2video.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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"
|
||||
|
||||
#ifndef _SDL_os2video_h
|
||||
#define _SDL_os2video_h
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include ".\core\os2\SDL_os2.h"
|
||||
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_DOSPROCESS
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#define INCL_OS2MM
|
||||
#define INCL_DOSMEMMGR
|
||||
#include <os2.h>
|
||||
//#include <gradd.h> // Defines FOURCC_xxxx
|
||||
|
||||
|
||||
#include "SDL_os2mouse.h"
|
||||
#include "SDL_os2output.h"
|
||||
|
||||
typedef struct SDL_VideoData {
|
||||
HAB hab;
|
||||
HMQ hmq;
|
||||
POS2VIDEOOUTPUT pOutput; // Video output routines.
|
||||
} SDL_VideoData, *PSDL_VideoData;
|
||||
|
||||
typedef struct _WINDATA {
|
||||
SDL_Window *window;
|
||||
POS2VIDEOOUTPUT pOutput; // Video output routines.
|
||||
HWND hwndFrame;
|
||||
HWND hwnd;
|
||||
PFNWP fnUserWndProc;
|
||||
PFNWP fnWndFrameProc;
|
||||
|
||||
PVODATA pVOData; // Video output data.
|
||||
|
||||
HRGN hrgnShape;
|
||||
HPOINTER hptrIcon;
|
||||
RECTL rectlBeforeFS;
|
||||
|
||||
LONG lSkipWMSize;
|
||||
LONG lSkipWMMove;
|
||||
LONG lSkipWMMouseMove;
|
||||
LONG lSkipWMVRNEnabled;
|
||||
LONG lSkipWMAdjustFramePos;
|
||||
} WINDATA, *PWINDATA;
|
||||
|
||||
typedef struct _DISPLAYDATA {
|
||||
ULONG ulDPIHor;
|
||||
ULONG ulDPIVer;
|
||||
ULONG ulDPIDiag;
|
||||
} DISPLAYDATA, *PDISPLAYDATA;
|
||||
|
||||
typedef struct _MODEDATA {
|
||||
ULONG ulDepth;
|
||||
ULONG fccColorEncoding;
|
||||
ULONG ulScanLineBytes;
|
||||
} MODEDATA, *PMODEDATA;
|
||||
|
||||
|
||||
#endif /* _SDL_os2video_h */
|
||||
512
src/video/os2/SDL_os2vman.c
Normal file
512
src/video/os2/SDL_os2vman.c
Normal file
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_DOSPROCESS
|
||||
#define INCL_DOSMODULEMGR
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#define INCL_GPIBITMAPS // GPI bit map functions
|
||||
#include <os2.h>
|
||||
#define INCL_GRE_DEVICE
|
||||
#define INCL_GRE_DEVMISC
|
||||
#include <pmddi.h>
|
||||
#include "SDL_os2output.h"
|
||||
#include "gradd.h"
|
||||
#include "SDL_os2video.h"
|
||||
|
||||
typedef struct _VODATA {
|
||||
PVOID pBuffer;
|
||||
HRGN hrgnVisible;
|
||||
ULONG ulBPP;
|
||||
ULONG ulScanLineSize;
|
||||
ULONG ulWidth;
|
||||
ULONG ulHeight;
|
||||
ULONG ulScreenHeight;
|
||||
ULONG ulScreenBytesPerLine;
|
||||
RECTL rectlWin;
|
||||
|
||||
PRECTL pRectl;
|
||||
ULONG cRectl;
|
||||
PBLTRECT pBltRect;
|
||||
ULONG cBltRect;
|
||||
} VODATA;
|
||||
|
||||
static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo);
|
||||
static PVODATA voOpen();
|
||||
static VOID voClose(PVODATA pVOData);
|
||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||
SDL_DisplayMode *pSDLDisplayMode,
|
||||
HRGN hrgnShape, BOOL fVisible);
|
||||
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||
ULONG ulBPP, ULONG fccColorEncoding,
|
||||
PULONG pulScanLineSize);
|
||||
static VOID voVideoBufFree(PVODATA pVOData);
|
||||
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||
ULONG cSDLRects);
|
||||
|
||||
OS2VIDEOOUTPUT voVMan = {
|
||||
voQueryInfo,
|
||||
voOpen,
|
||||
voClose,
|
||||
voSetVisibleRegion,
|
||||
voVideoBufAlloc,
|
||||
voVideoBufFree,
|
||||
voUpdate
|
||||
};
|
||||
|
||||
|
||||
static HMODULE hmodVMan = NULLHANDLE;
|
||||
static FNVMIENTRY *pfnVMIEntry = NULL;
|
||||
static ULONG ulVRAMAddress = 0;
|
||||
|
||||
VOID APIENTRY ExitVMan(VOID)
|
||||
{
|
||||
if ( ( ulVRAMAddress != 0 ) && ( hmodVMan != NULLHANDLE ) )
|
||||
{
|
||||
pfnVMIEntry( 0, VMI_CMD_TERMPROC, NULL, NULL );
|
||||
DosFreeModule( hmodVMan );
|
||||
}
|
||||
|
||||
DosExitList( EXLST_EXIT, (PFNEXITLIST)NULL );
|
||||
}
|
||||
|
||||
static BOOL _vmanInit()
|
||||
{
|
||||
ULONG ulRC;
|
||||
CHAR acBuf[255];
|
||||
INITPROCOUT stInitProcOut;
|
||||
|
||||
if ( hmodVMan != NULLHANDLE )
|
||||
// Already was initialized.
|
||||
return TRUE;
|
||||
|
||||
// Load vman.dll
|
||||
ulRC = DosLoadModule( &acBuf, sizeof(acBuf), "VMAN", &hmodVMan );
|
||||
if ( ulRC != NO_ERROR )
|
||||
{
|
||||
debug( "Could not load VMAN.DLL, rc = %u : %s", ulRC, &acBuf );
|
||||
hmodVMan = NULLHANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get VMIEntry.
|
||||
ulRC = DosQueryProcAddr( hmodVMan, 0L, "VMIEntry", (PFN *)&pfnVMIEntry );
|
||||
if ( ulRC != NO_ERROR )
|
||||
{
|
||||
debug( "Could not query address of pfnVMIEntry func. of VMAN.DLL, "
|
||||
"rc = %u", ulRC );
|
||||
DosFreeModule( hmodVMan );
|
||||
hmodVMan = NULLHANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// VMAN initialization.
|
||||
stInitProcOut.ulLength = sizeof(stInitProcOut);
|
||||
ulRC = pfnVMIEntry( 0, VMI_CMD_INITPROC, NULL, &stInitProcOut );
|
||||
if ( ulRC != RC_SUCCESS )
|
||||
{
|
||||
debug( "Could not initialize VMAN for this process" );
|
||||
pfnVMIEntry = NULL;
|
||||
DosFreeModule( hmodVMan );
|
||||
hmodVMan = NULLHANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Store video memory virtual address.
|
||||
ulVRAMAddress = stInitProcOut.ulVRAMVirt;
|
||||
// We use exit list for VMI_CMD_TERMPROC.
|
||||
if ( DosExitList( EXLST_ADD | 0x00001000, (PFNEXITLIST)ExitVMan )
|
||||
!= NO_ERROR )
|
||||
debug( "DosExitList() failed" );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static PRECTL _getRectlArray(PVODATA pVOData, ULONG cRects)
|
||||
{
|
||||
PRECTL pRectl;
|
||||
|
||||
if ( pVOData->cRectl >= cRects )
|
||||
return pVOData->pRectl;
|
||||
|
||||
pRectl = SDL_realloc( pVOData->pRectl, cRects * sizeof(RECTL) );
|
||||
if ( pRectl == NULL )
|
||||
return NULL;
|
||||
|
||||
pVOData->pRectl = pRectl;
|
||||
pVOData->cRectl = cRects;
|
||||
return pRectl;
|
||||
}
|
||||
|
||||
static PBLTRECT _getBltRectArray(PVODATA pVOData, ULONG cRects)
|
||||
{
|
||||
PBLTRECT pBltRect;
|
||||
|
||||
if ( pVOData->cBltRect >= cRects )
|
||||
return pVOData->pBltRect;
|
||||
|
||||
pBltRect = SDL_realloc( pVOData->pBltRect, cRects * sizeof(BLTRECT) );
|
||||
if ( pBltRect == NULL )
|
||||
return NULL;
|
||||
|
||||
pVOData->pBltRect = pBltRect;
|
||||
pVOData->cBltRect = cRects;
|
||||
return pBltRect;
|
||||
}
|
||||
|
||||
|
||||
static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo)
|
||||
{
|
||||
ULONG ulRC;
|
||||
GDDMODEINFO sCurModeInfo;
|
||||
|
||||
if ( !_vmanInit() )
|
||||
return FALSE;
|
||||
|
||||
// Query current (desktop) mode.
|
||||
ulRC = pfnVMIEntry( 0, VMI_CMD_QUERYCURRENTMODE, NULL, &sCurModeInfo );
|
||||
if ( ulRC != RC_SUCCESS )
|
||||
{
|
||||
debug( "Could not query desktop video mode." );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pInfo->ulBPP = sCurModeInfo.ulBpp;
|
||||
pInfo->ulHorizResolution = sCurModeInfo.ulHorizResolution;
|
||||
pInfo->ulVertResolution = sCurModeInfo.ulVertResolution;
|
||||
pInfo->ulScanLineSize = sCurModeInfo.ulScanLineSize;
|
||||
pInfo->fccColorEncoding = sCurModeInfo.fccColorEncoding;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static PVODATA voOpen()
|
||||
{
|
||||
PVODATA pVOData;
|
||||
|
||||
if ( !_vmanInit() )
|
||||
return NULL;
|
||||
|
||||
pVOData = SDL_calloc( 1, sizeof(VODATA) );
|
||||
if ( pVOData == NULL )
|
||||
{
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pVOData;
|
||||
}
|
||||
|
||||
static VOID voClose(PVODATA pVOData)
|
||||
{
|
||||
if ( pVOData->pRectl != NULL )
|
||||
SDL_free( pVOData->pRectl );
|
||||
|
||||
if ( pVOData->pBltRect != NULL )
|
||||
SDL_free( pVOData->pBltRect );
|
||||
|
||||
voVideoBufFree( pVOData );
|
||||
}
|
||||
|
||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||
SDL_DisplayMode *pSDLDisplayMode,
|
||||
HRGN hrgnShape, BOOL fVisible)
|
||||
{
|
||||
HPS hps;
|
||||
BOOL fSuccess = FALSE;
|
||||
|
||||
hps = WinGetPS( hwnd );
|
||||
|
||||
if ( pVOData->hrgnVisible != NULLHANDLE )
|
||||
{
|
||||
GpiDestroyRegion( hps, pVOData->hrgnVisible );
|
||||
pVOData->hrgnVisible = NULLHANDLE;
|
||||
}
|
||||
|
||||
if ( fVisible )
|
||||
{
|
||||
// Query visible rectangles
|
||||
|
||||
pVOData->hrgnVisible = GpiCreateRegion( hps, 0, NULL );
|
||||
if ( pVOData->hrgnVisible == NULLHANDLE )
|
||||
{
|
||||
SDL_SetError( "GpiCreateRegion() failed" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( WinQueryVisibleRegion( hwnd, pVOData->hrgnVisible ) == RGN_ERROR )
|
||||
{
|
||||
GpiDestroyRegion( hps, pVOData->hrgnVisible );
|
||||
pVOData->hrgnVisible = NULLHANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( hrgnShape != NULLHANDLE )
|
||||
GpiCombineRegion( hps, pVOData->hrgnVisible, pVOData->hrgnVisible,
|
||||
hrgnShape, CRGN_AND );
|
||||
fSuccess = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
WinQueryWindowRect( hwnd, &pVOData->rectlWin );
|
||||
WinMapWindowPoints( hwnd, HWND_DESKTOP, (PPOINTL)&pVOData->rectlWin, 2 );
|
||||
|
||||
if ( pSDLDisplayMode != NULL )
|
||||
{
|
||||
pVOData->ulScreenHeight = pSDLDisplayMode->h;
|
||||
pVOData->ulScreenBytesPerLine =
|
||||
((PMODEDATA)pSDLDisplayMode->driverdata)->ulScanLineBytes;
|
||||
}
|
||||
}
|
||||
|
||||
WinReleasePS( hps );
|
||||
|
||||
return fSuccess;
|
||||
}
|
||||
|
||||
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||
ULONG ulBPP, ULONG fccColorEncoding,
|
||||
PULONG pulScanLineSize)
|
||||
{
|
||||
ULONG ulRC;
|
||||
ULONG ulScanLineSize = ulWidth * (ulBPP >> 3);
|
||||
|
||||
// Destroy previous buffer.
|
||||
voVideoBufFree( pVOData );
|
||||
|
||||
if ( ( ulWidth == 0 ) || ( ulHeight == 0 ) || ( ulBPP == 0 ) )
|
||||
return NULL;
|
||||
|
||||
// Bytes per line.
|
||||
ulScanLineSize = ( ulScanLineSize + 3 ) & ~3; /* 4-byte aligning */
|
||||
*pulScanLineSize = ulScanLineSize;
|
||||
|
||||
ulRC = DosAllocMem( &pVOData->pBuffer,
|
||||
(ulHeight * ulScanLineSize) + sizeof(ULONG),
|
||||
PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE );
|
||||
if ( ulRC != NO_ERROR )
|
||||
{
|
||||
debug( "DosAllocMem(), rc = %u", ulRC );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pVOData->ulBPP = ulBPP;
|
||||
pVOData->ulScanLineSize = ulScanLineSize;
|
||||
pVOData->ulWidth = ulWidth;
|
||||
pVOData->ulHeight = ulHeight;
|
||||
|
||||
return pVOData->pBuffer;
|
||||
}
|
||||
|
||||
static VOID voVideoBufFree(PVODATA pVOData)
|
||||
{
|
||||
ULONG ulRC;
|
||||
|
||||
if ( pVOData->pBuffer == NULL )
|
||||
return;
|
||||
|
||||
ulRC = DosFreeMem( pVOData->pBuffer );
|
||||
if ( ulRC != NO_ERROR )
|
||||
debug( "DosFreeMem(), rc = %u", ulRC );
|
||||
else
|
||||
pVOData->pBuffer = NULL;
|
||||
}
|
||||
|
||||
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||
ULONG cSDLRects)
|
||||
{
|
||||
PRECTL prectlDst, prectlScan;
|
||||
HPS hps;
|
||||
HRGN hrgnUpdate;
|
||||
RGNRECT rgnCtl;
|
||||
SDL_Rect stSDLRectDef;
|
||||
BMAPINFO bmiSrc;
|
||||
BMAPINFO bmiDst;
|
||||
PPOINTL pptlSrcOrg;
|
||||
PBLTRECT pbrDst;
|
||||
HWREQIN sHWReqIn;
|
||||
BITBLTINFO sBitbltInfo = { 0 };
|
||||
ULONG ulIdx;
|
||||
// RECTL rectlScreenUpdate;
|
||||
|
||||
if ( pVOData->pBuffer == NULL )
|
||||
return FALSE;
|
||||
|
||||
if ( pVOData->hrgnVisible == NULLHANDLE )
|
||||
return TRUE;
|
||||
|
||||
bmiSrc.ulLength = sizeof(BMAPINFO);
|
||||
bmiSrc.ulType = BMAP_MEMORY;
|
||||
bmiSrc.ulWidth = pVOData->ulWidth;
|
||||
bmiSrc.ulHeight = pVOData->ulHeight;
|
||||
bmiSrc.ulBpp = pVOData->ulBPP;
|
||||
bmiSrc.ulBytesPerLine = pVOData->ulScanLineSize;
|
||||
bmiSrc.pBits = (PBYTE)pVOData->pBuffer;
|
||||
|
||||
bmiDst.ulLength = sizeof(BMAPINFO);
|
||||
bmiDst.ulType = BMAP_VRAM;
|
||||
bmiDst.pBits = (PBYTE)ulVRAMAddress;
|
||||
bmiDst.ulWidth = bmiSrc.ulWidth;
|
||||
bmiDst.ulHeight = bmiSrc.ulHeight;
|
||||
bmiDst.ulBpp = bmiSrc.ulBpp;
|
||||
bmiDst.ulBytesPerLine = pVOData->ulScreenBytesPerLine;
|
||||
|
||||
// List of update rectangles. This is the intersection of requested
|
||||
// rectangles and visible rectangles.
|
||||
|
||||
if ( cSDLRects == 0 )
|
||||
{
|
||||
// Full update requested.
|
||||
stSDLRectDef.x = 0;
|
||||
stSDLRectDef.y = 0;
|
||||
stSDLRectDef.w = bmiSrc.ulWidth;
|
||||
stSDLRectDef.h = bmiSrc.ulHeight;
|
||||
pSDLRects = &stSDLRectDef;
|
||||
cSDLRects = 1;
|
||||
}
|
||||
|
||||
// Make list of destionation rectangles (prectlDst) list from the source
|
||||
// list (prectl).
|
||||
prectlDst = _getRectlArray( pVOData, cSDLRects );
|
||||
if ( prectlDst == NULL )
|
||||
{
|
||||
debug( "Not enough memory" );
|
||||
return FALSE;
|
||||
}
|
||||
prectlScan = prectlDst;
|
||||
for( ulIdx = 0; ulIdx < cSDLRects; ulIdx++, pSDLRects++, prectlScan++ )
|
||||
{
|
||||
prectlScan->xLeft = pSDLRects->x;
|
||||
prectlScan->yTop = pVOData->ulHeight - pSDLRects->y;
|
||||
prectlScan->xRight = prectlScan->xLeft + pSDLRects->w;
|
||||
prectlScan->yBottom = prectlScan->yTop - pSDLRects->h;
|
||||
}
|
||||
|
||||
hps = WinGetPS( hwnd );
|
||||
if ( hps == NULLHANDLE )
|
||||
return FALSE;
|
||||
|
||||
// Make destination region to update.
|
||||
hrgnUpdate = GpiCreateRegion( hps, cSDLRects, prectlDst );
|
||||
// "AND" on visible and destination regions, result is region to update.
|
||||
GpiCombineRegion( hps, hrgnUpdate, hrgnUpdate, pVOData->hrgnVisible,
|
||||
CRGN_AND );
|
||||
|
||||
// Get rectangles of the region to update.
|
||||
rgnCtl.ircStart = 1;
|
||||
rgnCtl.crc = 0;
|
||||
rgnCtl.ulDirection = 1;
|
||||
rgnCtl.crcReturned = 0;
|
||||
GpiQueryRegionRects( hps, hrgnUpdate, NULL, &rgnCtl, NULL );
|
||||
if ( rgnCtl.crcReturned == 0 )
|
||||
{
|
||||
GpiDestroyRegion( hps, hrgnUpdate );
|
||||
WinReleasePS( hps );
|
||||
return TRUE;
|
||||
}
|
||||
// We don't need prectlDst, use it again to store update regions.
|
||||
prectlDst = _getRectlArray( pVOData, rgnCtl.crcReturned );
|
||||
if ( prectlDst == NULL )
|
||||
{
|
||||
debug( "Not enough memory" );
|
||||
GpiDestroyRegion( hps, hrgnUpdate );
|
||||
WinReleasePS( hps );
|
||||
return FALSE;
|
||||
}
|
||||
rgnCtl.ircStart = 1;
|
||||
rgnCtl.crc = rgnCtl.crcReturned;
|
||||
rgnCtl.ulDirection = 1;
|
||||
GpiQueryRegionRects( hps, hrgnUpdate, NULL, &rgnCtl, prectlDst );
|
||||
GpiDestroyRegion( hps, hrgnUpdate );
|
||||
WinReleasePS( hps );
|
||||
cSDLRects = rgnCtl.crcReturned;
|
||||
// Now cRect/prectlDst is a list of regions in window (update && visible).
|
||||
|
||||
// Make lists for blitting from update regions.
|
||||
|
||||
pbrDst = _getBltRectArray( pVOData, cSDLRects );
|
||||
if ( pbrDst == NULL )
|
||||
{
|
||||
debug( "Not enough memory" );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
prectlScan = prectlDst;
|
||||
pptlSrcOrg = (PPOINTL)prectlDst; // Yes, this memory block will be used again.
|
||||
for( ulIdx = 0; ulIdx < cSDLRects; ulIdx++, prectlScan++, pptlSrcOrg++ )
|
||||
{
|
||||
pbrDst[ulIdx].ulXOrg = pVOData->rectlWin.xLeft + prectlScan->xLeft;
|
||||
pbrDst[ulIdx].ulYOrg = pVOData->ulScreenHeight -
|
||||
( pVOData->rectlWin.yBottom + prectlScan->yTop );
|
||||
pbrDst[ulIdx].ulXExt = prectlScan->xRight - prectlScan->xLeft;
|
||||
pbrDst[ulIdx].ulYExt = prectlScan->yTop - prectlScan->yBottom;
|
||||
pptlSrcOrg->x = prectlScan->xLeft;
|
||||
pptlSrcOrg->y = bmiSrc.ulHeight - prectlScan->yTop;
|
||||
}
|
||||
pptlSrcOrg = (PPOINTL)prectlDst;
|
||||
|
||||
// Request HW
|
||||
sHWReqIn.ulLength = sizeof(HWREQIN);
|
||||
sHWReqIn.ulFlags = REQUEST_HW;
|
||||
sHWReqIn.cScrChangeRects = 1;
|
||||
sHWReqIn.arectlScreen = &pVOData->rectlWin;
|
||||
if ( pfnVMIEntry( 0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL ) != RC_SUCCESS )
|
||||
{
|
||||
debug( "pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed" );
|
||||
sHWReqIn.cScrChangeRects = 0; // for fail signal only.
|
||||
}
|
||||
else
|
||||
{
|
||||
RECTL rclSrcBounds;
|
||||
|
||||
rclSrcBounds.xLeft = 0;
|
||||
rclSrcBounds.yBottom = 0;
|
||||
rclSrcBounds.xRight = bmiSrc.ulWidth;
|
||||
rclSrcBounds.yTop = bmiSrc.ulHeight;
|
||||
|
||||
sBitbltInfo.ulLength = sizeof(BITBLTINFO);
|
||||
sBitbltInfo.ulBltFlags = BF_DEFAULT_STATE | BF_ROP_INCL_SRC | BF_PAT_HOLLOW;
|
||||
sBitbltInfo.cBlits = cSDLRects;
|
||||
sBitbltInfo.ulROP = ROP_SRCCOPY;
|
||||
sBitbltInfo.pSrcBmapInfo = &bmiSrc;
|
||||
sBitbltInfo.pDstBmapInfo = &bmiDst;
|
||||
sBitbltInfo.prclSrcBounds = &rclSrcBounds;
|
||||
sBitbltInfo.prclDstBounds = &pVOData->rectlWin;
|
||||
sBitbltInfo.aptlSrcOrg = pptlSrcOrg;
|
||||
sBitbltInfo.abrDst = pbrDst;
|
||||
|
||||
// Screen update.
|
||||
if ( pfnVMIEntry( 0, VMI_CMD_BITBLT, &sBitbltInfo, NULL ) != RC_SUCCESS )
|
||||
{
|
||||
debug( "pfnVMIEntry(,VMI_CMD_BITBLT,,) failed" );
|
||||
sHWReqIn.cScrChangeRects = 0; // for fail signal only.
|
||||
}
|
||||
|
||||
// Release HW.
|
||||
sHWReqIn.ulFlags = 0;
|
||||
if ( pfnVMIEntry( 0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL ) != RC_SUCCESS )
|
||||
debug( "pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed" );
|
||||
}
|
||||
|
||||
return sHWReqIn.cScrChangeRects != 0;
|
||||
}
|
||||
Reference in New Issue
Block a user