mirror of https://github.com/encounter/SDL.git
os2: a _lot_ of coding style cleanup, sot that they match the SDL style.
also renamed the 'debug' macro to debug_os2: the former was dangerously a common name. the binary (dll) output is precisely the same as before.
This commit is contained in:
parent
bdc5129f13
commit
a90f0400a5
|
@ -34,443 +34,417 @@
|
||||||
/*
|
/*
|
||||||
void lockIncr(volatile int *piVal);
|
void lockIncr(volatile int *piVal);
|
||||||
#pragma aux lockIncr = \
|
#pragma aux lockIncr = \
|
||||||
" lock add [eax], 1 "\
|
" lock add [eax], 1 "\
|
||||||
parm [eax];
|
parm [eax];
|
||||||
|
|
||||||
void lockDecr(volatile int *piVal);
|
void lockDecr(volatile int *piVal);
|
||||||
#pragma aux lockDecr = \
|
#pragma aux lockDecr = \
|
||||||
" lock sub [eax], 1 "\
|
" lock sub [eax], 1 "\
|
||||||
parm [eax];
|
parm [eax];
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static ULONG _getEnvULong(PSZ pszName, ULONG ulMax, ULONG ulDefault)
|
static ULONG _getEnvULong(PSZ pszName, ULONG ulMax, ULONG ulDefault)
|
||||||
{
|
{
|
||||||
ULONG ulValue;
|
ULONG ulValue;
|
||||||
PCHAR pcEnd;
|
PCHAR pcEnd;
|
||||||
PSZ pszEnvVal = SDL_getenv( pszName );
|
PSZ pszEnvVal = SDL_getenv(pszName);
|
||||||
|
|
||||||
if ( pszEnvVal == NULL )
|
if (pszEnvVal == NULL)
|
||||||
return ulDefault;
|
return ulDefault;
|
||||||
|
|
||||||
ulValue = SDL_strtoul( (const char *)pszEnvVal, &pcEnd, 10 );
|
ulValue = SDL_strtoul((const char *)pszEnvVal, &pcEnd, 10);
|
||||||
return ( pcEnd == pszEnvVal ) || ( ulValue > ulMax ) ? ulDefault : ulMax;
|
return (pcEnd == pszEnvVal) || (ulValue > ulMax)? ulDefault : ulMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _MCIError(PSZ pszFunc, ULONG ulResult)
|
static int _MCIError(PSZ pszFunc, ULONG ulResult)
|
||||||
{
|
{
|
||||||
CHAR acBuf[128];
|
CHAR acBuf[128];
|
||||||
|
mciGetErrorString(ulResult, acBuf, sizeof(acBuf));
|
||||||
mciGetErrorString( ulResult, acBuf, sizeof(acBuf) );
|
return SDL_SetError("[%s] %s", pszFunc, acBuf);
|
||||||
return SDL_SetError( "[%s] %s", pszFunc, acBuf );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _mixIOError(PSZ pszFunction, ULONG ulRC)
|
static void _mixIOError(PSZ pszFunction, ULONG ulRC)
|
||||||
{
|
{
|
||||||
debug( "%s() - failed, rc = 0x%X (%s)",
|
debug_os2("%s() - failed, rc = 0x%X (%s)",
|
||||||
pszFunction, ulRC,
|
pszFunction, ulRC,
|
||||||
ulRC == MCIERR_INVALID_MODE ? "Mixer mode does not match request"
|
(ulRC == MCIERR_INVALID_MODE) ? "Mixer mode does not match request" :
|
||||||
: ulRC == MCIERR_INVALID_BUFFER ? "Caller sent an invalid buffer"
|
(ulRC == MCIERR_INVALID_BUFFER) ? "Caller sent an invalid buffer" : "unknown");
|
||||||
: "unknown" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
||||||
ULONG ulFlags)
|
ULONG ulFlags)
|
||||||
{
|
{
|
||||||
PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)pBuffer->ulUserParm;
|
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm;
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( ulFlags != MIX_WRITE_COMPLETE )
|
if (ulFlags != MIX_WRITE_COMPLETE) {
|
||||||
{
|
debug_os2("flags = 0x%X", ulFlags);
|
||||||
debug( "flags = 0x%X", ulFlags );
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// lockDecr( (int *)&pAData->ulQueuedBuf );
|
/*lockDecr((int *)&pAData->ulQueuedBuf);*/
|
||||||
ulRC = DosPostEventSem( pAData->hevBuf );
|
ulRC = DosPostEventSem(pAData->hevBuf);
|
||||||
if ( ( ulRC != NO_ERROR ) && ( ulRC != ERROR_ALREADY_POSTED ) )
|
if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
|
||||||
debug( "DosPostEventSem(), rc = %u", ulRC );
|
debug_os2("DosPostEventSem(), rc = %u", ulRC);
|
||||||
|
}
|
||||||
|
|
||||||
return 1; // It seems, return value is not matter.
|
return 1; // It seems, return value is not matter.
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
LONG APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
||||||
ULONG ulFlags)
|
ULONG ulFlags)
|
||||||
{
|
{
|
||||||
PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)pBuffer->ulUserParm;
|
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm;
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( ulFlags != MIX_READ_COMPLETE )
|
if (ulFlags != MIX_READ_COMPLETE) {
|
||||||
{
|
debug_os2("flags = 0x%X", ulFlags);
|
||||||
debug( "flags = 0x%X", ulFlags );
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pAData->stMCIMixSetup.pmixRead( pAData->stMCIMixSetup.ulMixHandle, pBuffer,
|
pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle, pBuffer, 1);
|
||||||
1 );
|
|
||||||
|
|
||||||
ulRC = DosPostEventSem( pAData->hevBuf );
|
ulRC = DosPostEventSem(pAData->hevBuf);
|
||||||
if ( ( ulRC != NO_ERROR ) && ( ulRC != ERROR_ALREADY_POSTED ) )
|
if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
|
||||||
debug( "DosPostEventSem(), rc = %u", ulRC );
|
debug_os2("DosPostEventSem(), rc = %u", ulRC);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void OS2_DetectDevices(void)
|
static void OS2_DetectDevices(void)
|
||||||
{
|
{
|
||||||
MCI_SYSINFO_PARMS stMCISysInfo;
|
MCI_SYSINFO_PARMS stMCISysInfo;
|
||||||
CHAR acBuf[256];
|
CHAR acBuf[256];
|
||||||
ULONG ulDevicesNum;
|
ULONG ulDevicesNum;
|
||||||
MCI_SYSINFO_LOGDEVICE stLogDevice;
|
MCI_SYSINFO_LOGDEVICE stLogDevice;
|
||||||
MCI_SYSINFO_PARMS stSysInfoParams;
|
MCI_SYSINFO_PARMS stSysInfoParams;
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
ULONG ulHandle = 0;
|
ULONG ulHandle = 0;
|
||||||
|
|
||||||
acBuf[0] = '\0';
|
acBuf[0] = '\0';
|
||||||
stMCISysInfo.pszReturn = acBuf;
|
stMCISysInfo.pszReturn = acBuf;
|
||||||
stMCISysInfo.ulRetSize = sizeof(acBuf);
|
stMCISysInfo.ulRetSize = sizeof(acBuf);
|
||||||
stMCISysInfo.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
|
stMCISysInfo.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
|
||||||
ulRC = mciSendCommand( 0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_QUANTITY,
|
ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_QUANTITY,
|
||||||
&stMCISysInfo, 0 );
|
&stMCISysInfo, 0);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug_os2("MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%X", ulRC);
|
||||||
debug( "MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%X", ulRC );
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ulDevicesNum = atol( stMCISysInfo.pszReturn );
|
|
||||||
|
|
||||||
for( stSysInfoParams.ulNumber = 0; stSysInfoParams.ulNumber < ulDevicesNum;
|
|
||||||
stSysInfoParams.ulNumber++ )
|
|
||||||
{
|
|
||||||
// Get device install name.
|
|
||||||
stSysInfoParams.pszReturn = acBuf;
|
|
||||||
stSysInfoParams.ulRetSize = sizeof( acBuf );
|
|
||||||
stSysInfoParams.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
|
|
||||||
ulRC = mciSendCommand( 0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_INSTALLNAME,
|
|
||||||
&stSysInfoParams, 0 );
|
|
||||||
if ( ulRC != NO_ERROR )
|
|
||||||
{
|
|
||||||
debug( "MCI_SYSINFO, MCI_SYSINFO_INSTALLNAME - failed, rc = 0x%X", ulRC );
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get textual product description.
|
ulDevicesNum = atol(stMCISysInfo.pszReturn);
|
||||||
stSysInfoParams.ulItem = MCI_SYSINFO_QUERY_DRIVER;
|
|
||||||
stSysInfoParams.pSysInfoParm = &stLogDevice;
|
|
||||||
strcpy( stLogDevice.szInstallName, stSysInfoParams.pszReturn );
|
|
||||||
ulRC = mciSendCommand( 0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM,
|
|
||||||
&stSysInfoParams, 0 );
|
|
||||||
if ( ulRC != NO_ERROR )
|
|
||||||
{
|
|
||||||
debug( "MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%X", ulRC );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ulHandle++;
|
for (stSysInfoParams.ulNumber = 0; stSysInfoParams.ulNumber < ulDevicesNum;
|
||||||
SDL_AddAudioDevice( 0, stLogDevice.szProductInfo, (void *)(ulHandle) );
|
stSysInfoParams.ulNumber++) {
|
||||||
ulHandle++;
|
/* Get device install name. */
|
||||||
SDL_AddAudioDevice( 1, stLogDevice.szProductInfo, (void *)(ulHandle) );
|
stSysInfoParams.pszReturn = acBuf;
|
||||||
}
|
stSysInfoParams.ulRetSize = sizeof(acBuf);
|
||||||
|
stSysInfoParams.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
|
||||||
|
ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_INSTALLNAME,
|
||||||
|
&stSysInfoParams, 0);
|
||||||
|
if (ulRC != NO_ERROR) {
|
||||||
|
debug_os2("MCI_SYSINFO, MCI_SYSINFO_INSTALLNAME - failed, rc = 0x%X", ulRC);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get textual product description. */
|
||||||
|
stSysInfoParams.ulItem = MCI_SYSINFO_QUERY_DRIVER;
|
||||||
|
stSysInfoParams.pSysInfoParm = &stLogDevice;
|
||||||
|
strcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn);
|
||||||
|
ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM,
|
||||||
|
&stSysInfoParams, 0);
|
||||||
|
if (ulRC != NO_ERROR) {
|
||||||
|
debug_os2("MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%X", ulRC);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulHandle++;
|
||||||
|
SDL_AddAudioDevice(0, stLogDevice.szProductInfo, (void *)(ulHandle));
|
||||||
|
ulHandle++;
|
||||||
|
SDL_AddAudioDevice(1, stLogDevice.szProductInfo, (void *)(ulHandle));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OS2_WaitDevice(_THIS)
|
static void OS2_WaitDevice(_THIS)
|
||||||
{
|
{
|
||||||
PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)this->hidden;
|
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)this->hidden;
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
/* Wait for an audio chunk to finish */
|
/* Wait for an audio chunk to finish */
|
||||||
ulRC = DosWaitEventSem( pAData->hevBuf, 5000 );
|
ulRC = DosWaitEventSem(pAData->hevBuf, 5000);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
debug( "DosWaitEventSem(), rc = %u", ulRC );
|
debug_os2("DosWaitEventSem(), rc = %u", ulRC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *OS2_GetDeviceBuf(_THIS)
|
static Uint8 *OS2_GetDeviceBuf(_THIS)
|
||||||
{
|
{
|
||||||
PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)this->hidden;
|
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)this->hidden;
|
||||||
|
return pAData->aMixBuffers[pAData->ulNextBuf].pBuffer;
|
||||||
return pAData->aMixBuffers[pAData->ulNextBuf].pBuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OS2_PlayDevice(_THIS)
|
static void OS2_PlayDevice(_THIS)
|
||||||
{
|
{
|
||||||
PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)this->hidden;
|
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)this->hidden;
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
PMCI_MIX_BUFFER pMixBuffer = &pAData->aMixBuffers[pAData->ulNextBuf];
|
PMCI_MIX_BUFFER pMixBuffer = &pAData->aMixBuffers[pAData->ulNextBuf];
|
||||||
|
|
||||||
/* Queue it up */
|
/* Queue it up */
|
||||||
// lockIncr( (int *)&pAData->ulQueuedBuf );
|
/*lockIncr((int *)&pAData->ulQueuedBuf);*/
|
||||||
ulRC = pAData->stMCIMixSetup.pmixWrite( pAData->stMCIMixSetup.ulMixHandle,
|
ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
|
||||||
pMixBuffer, 1 );
|
pMixBuffer, 1);
|
||||||
if ( ulRC != MCIERR_SUCCESS )
|
if (ulRC != MCIERR_SUCCESS) {
|
||||||
_mixIOError( "pmixWrite", ulRC );
|
_mixIOError("pmixWrite", ulRC);
|
||||||
else
|
} else {
|
||||||
pAData->ulNextBuf = (pAData->ulNextBuf + 1) % pAData->cMixBuffers;
|
pAData->ulNextBuf = (pAData->ulNextBuf + 1) % pAData->cMixBuffers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OS2_CloseDevice(_THIS)
|
static void OS2_CloseDevice(_THIS)
|
||||||
{
|
{
|
||||||
PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)this->hidden;
|
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)this->hidden;
|
||||||
MCI_GENERIC_PARMS sMCIGenericParms;
|
MCI_GENERIC_PARMS sMCIGenericParms;
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( pAData == NULL )
|
if (pAData == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Close up audio */
|
/* Close up audio */
|
||||||
if ( pAData->usDeviceId != (USHORT)~0 )
|
if (pAData->usDeviceId != (USHORT)~0) {
|
||||||
{
|
/* Device is open. */
|
||||||
// Device is open.
|
if (pAData->stMCIMixSetup.ulBitsPerSample != 0) {
|
||||||
if ( pAData->stMCIMixSetup.ulBitsPerSample != 0 )
|
/* Mixer was initialized. */
|
||||||
{
|
ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
|
||||||
// Mixer was initialized.
|
MCI_WAIT | MCI_MIXSETUP_DEINIT,
|
||||||
ulRC = mciSendCommand( pAData->usDeviceId, MCI_MIXSETUP,
|
&pAData->stMCIMixSetup, 0);
|
||||||
MCI_WAIT | MCI_MIXSETUP_DEINIT,
|
if (ulRC != MCIERR_SUCCESS) {
|
||||||
&pAData->stMCIMixSetup, 0 );
|
debug_os2("MCI_MIXSETUP, MCI_MIXSETUP_DEINIT - failed");
|
||||||
if ( ulRC != MCIERR_SUCCESS )
|
}
|
||||||
debug( "MCI_MIXSETUP, MCI_MIXSETUP_DEINIT - failed" );
|
}
|
||||||
|
|
||||||
|
if (pAData->cMixBuffers != 0) {
|
||||||
|
/* Buffers was allocated. */
|
||||||
|
MCI_BUFFER_PARMS stMCIBuffer;
|
||||||
|
|
||||||
|
stMCIBuffer.ulBufferSize = pAData->aMixBuffers[0].ulBufferLength;
|
||||||
|
stMCIBuffer.ulNumBuffers = pAData->cMixBuffers;
|
||||||
|
stMCIBuffer.pBufList = &pAData->aMixBuffers;
|
||||||
|
|
||||||
|
ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER,
|
||||||
|
MCI_WAIT | MCI_DEALLOCATE_MEMORY, &stMCIBuffer, 0);
|
||||||
|
if (ulRC != MCIERR_SUCCESS) {
|
||||||
|
debug_os2("MCI_BUFFER, MCI_DEALLOCATE_MEMORY - failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ulRC = mciSendCommand(pAData->usDeviceId, MCI_CLOSE, MCI_WAIT,
|
||||||
|
&sMCIGenericParms, 0);
|
||||||
|
if (ulRC != MCIERR_SUCCESS) {
|
||||||
|
debug_os2("MCI_CLOSE - failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pAData->cMixBuffers != 0 )
|
if (pAData->hevBuf != NULLHANDLE)
|
||||||
{
|
DosCloseEventSem(pAData->hevBuf);
|
||||||
// Buffers was allocated.
|
|
||||||
MCI_BUFFER_PARMS stMCIBuffer;
|
|
||||||
|
|
||||||
stMCIBuffer.ulBufferSize = pAData->aMixBuffers[0].ulBufferLength;
|
SDL_free(pAData);
|
||||||
stMCIBuffer.ulNumBuffers = pAData->cMixBuffers;
|
|
||||||
stMCIBuffer.pBufList = &pAData->aMixBuffers;
|
|
||||||
|
|
||||||
ulRC = mciSendCommand( pAData->usDeviceId, MCI_BUFFER,
|
|
||||||
MCI_WAIT | MCI_DEALLOCATE_MEMORY, &stMCIBuffer, 0 );
|
|
||||||
if ( ulRC != MCIERR_SUCCESS )
|
|
||||||
debug( "MCI_BUFFER, MCI_DEALLOCATE_MEMORY - failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
ulRC = mciSendCommand( pAData->usDeviceId, MCI_CLOSE, MCI_WAIT,
|
|
||||||
&sMCIGenericParms, 0 );
|
|
||||||
if ( ulRC != MCIERR_SUCCESS )
|
|
||||||
debug( "MCI_CLOSE - failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( pAData->hevBuf != NULLHANDLE )
|
|
||||||
DosCloseEventSem( pAData->hevBuf );
|
|
||||||
|
|
||||||
SDL_free( pAData );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
|
static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
|
||||||
int iscapture)
|
int iscapture)
|
||||||
{
|
{
|
||||||
PSDL_PrivateAudioData pAData;
|
SDL_PrivateAudioData *pAData;
|
||||||
SDL_AudioFormat SDLAudioFmt;
|
SDL_AudioFormat SDLAudioFmt;
|
||||||
MCI_AMP_OPEN_PARMS stMCIAmpOpen;
|
MCI_AMP_OPEN_PARMS stMCIAmpOpen;
|
||||||
MCI_BUFFER_PARMS stMCIBuffer;
|
MCI_BUFFER_PARMS stMCIBuffer;
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
ULONG ulIdx;
|
ULONG ulIdx;
|
||||||
BOOL new_freq;
|
BOOL new_freq;
|
||||||
|
|
||||||
new_freq = FALSE;
|
new_freq = FALSE;
|
||||||
SDL_zero(stMCIAmpOpen);
|
SDL_zero(stMCIAmpOpen);
|
||||||
SDL_zero(stMCIBuffer);
|
SDL_zero(stMCIBuffer);
|
||||||
|
|
||||||
for( SDLAudioFmt = SDL_FirstAudioFormat( this->spec.format );
|
for (SDLAudioFmt = SDL_FirstAudioFormat(this->spec.format);
|
||||||
SDLAudioFmt != 0; SDLAudioFmt = SDL_NextAudioFormat() )
|
SDLAudioFmt != 0; SDLAudioFmt = SDL_NextAudioFormat()) {
|
||||||
{
|
if (SDLAudioFmt == AUDIO_U8 || SDLAudioFmt == AUDIO_S16)
|
||||||
if ( ( SDLAudioFmt == AUDIO_U8 ) || ( SDLAudioFmt == AUDIO_S16 ) )
|
break;
|
||||||
break;
|
}
|
||||||
}
|
if (SDLAudioFmt == 0) {
|
||||||
|
debug_os2("Unsupported audio format, AUDIO_S16 used");
|
||||||
if ( SDLAudioFmt == 0 )
|
SDLAudioFmt = AUDIO_S16;
|
||||||
{
|
|
||||||
debug( "Unsupported audio format, AUDIO_S16 used" );
|
|
||||||
SDLAudioFmt = AUDIO_S16;
|
|
||||||
}
|
|
||||||
|
|
||||||
pAData = SDL_calloc( 1, sizeof(SDL_PrivateAudioData) );
|
|
||||||
if ( pAData == NULL )
|
|
||||||
return SDL_OutOfMemory();
|
|
||||||
this->hidden = pAData;
|
|
||||||
|
|
||||||
ulRC = DosCreateEventSem( NULL, &pAData->hevBuf, DCE_AUTORESET, TRUE );
|
|
||||||
if ( ulRC != NO_ERROR )
|
|
||||||
{
|
|
||||||
debug( "DosCreateEventSem() failed, rc = %u", ulRC );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open audio device
|
|
||||||
stMCIAmpOpen.usDeviceID = handle != NULL ? ( ((ULONG)handle) - 1 ) : 0;
|
|
||||||
stMCIAmpOpen.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
|
|
||||||
ulRC = mciSendCommand( 0, MCI_OPEN,
|
|
||||||
_getEnvULong( "SDL_AUDIO_SHARE", 1, 0 ) != 0
|
|
||||||
? MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE
|
|
||||||
: MCI_WAIT | MCI_OPEN_TYPE_ID,
|
|
||||||
&stMCIAmpOpen, 0 );
|
|
||||||
if ( ulRC != MCIERR_SUCCESS )
|
|
||||||
{
|
|
||||||
stMCIAmpOpen.usDeviceID = (USHORT)~0;
|
|
||||||
return _MCIError( "MCI_OPEN", ulRC );
|
|
||||||
}
|
|
||||||
pAData->usDeviceId = stMCIAmpOpen.usDeviceID;
|
|
||||||
|
|
||||||
if ( iscapture != 0 )
|
|
||||||
{
|
|
||||||
MCI_CONNECTOR_PARMS stMCIConnector;
|
|
||||||
MCI_AMP_SET_PARMS stMCIAmpSet;
|
|
||||||
BOOL fLineIn = _getEnvULong( "SDL_AUDIO_LINEIN", 1, 0 );
|
|
||||||
|
|
||||||
// Set particular connector.
|
|
||||||
SDL_zero(stMCIConnector);
|
|
||||||
stMCIConnector.ulConnectorType = fLineIn ? MCI_LINE_IN_CONNECTOR
|
|
||||||
: MCI_MICROPHONE_CONNECTOR;
|
|
||||||
mciSendCommand( stMCIAmpOpen.usDeviceID, MCI_CONNECTOR,
|
|
||||||
MCI_WAIT | MCI_ENABLE_CONNECTOR |
|
|
||||||
MCI_CONNECTOR_TYPE, &stMCIConnector, 0 );
|
|
||||||
|
|
||||||
// Disable monitor.
|
|
||||||
SDL_zero(stMCIAmpSet);
|
|
||||||
stMCIAmpSet.ulItem = MCI_AMP_SET_MONITOR;
|
|
||||||
mciSendCommand( stMCIAmpOpen.usDeviceID, MCI_SET,
|
|
||||||
MCI_WAIT | MCI_SET_OFF | MCI_SET_ITEM,
|
|
||||||
&stMCIAmpSet, 0 );
|
|
||||||
|
|
||||||
// Set record volume.
|
|
||||||
stMCIAmpSet.ulLevel = _getEnvULong( "SDL_AUDIO_RECVOL", 100, 90 );
|
|
||||||
stMCIAmpSet.ulItem = MCI_AMP_SET_AUDIO;
|
|
||||||
stMCIAmpSet.ulAudio = MCI_SET_AUDIO_ALL; // Both cnannels.
|
|
||||||
stMCIAmpSet.ulValue = fLineIn ? MCI_LINE_IN_CONNECTOR
|
|
||||||
: MCI_MICROPHONE_CONNECTOR ;
|
|
||||||
|
|
||||||
mciSendCommand( stMCIAmpOpen.usDeviceID, MCI_SET,
|
|
||||||
MCI_WAIT | MCI_SET_AUDIO | MCI_AMP_SET_GAIN,
|
|
||||||
&stMCIAmpSet, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
this->spec.format = SDLAudioFmt;
|
|
||||||
this->spec.channels = this->spec.channels > 1 ? 2 : 1;
|
|
||||||
if ( this->spec.freq < 8000 )
|
|
||||||
{
|
|
||||||
this->spec.freq = 8000;
|
|
||||||
new_freq = TRUE;
|
|
||||||
}
|
|
||||||
else if ( this->spec.freq > 48000 )
|
|
||||||
{
|
|
||||||
this->spec.freq = 48000;
|
|
||||||
new_freq = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup mixer.
|
|
||||||
pAData->stMCIMixSetup.ulFormatTag = MCI_WAVE_FORMAT_PCM;
|
|
||||||
pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE( SDLAudioFmt );
|
|
||||||
pAData->stMCIMixSetup.ulSamplesPerSec = this->spec.freq;
|
|
||||||
pAData->stMCIMixSetup.ulChannels = this->spec.channels;
|
|
||||||
pAData->stMCIMixSetup.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
|
|
||||||
if ( iscapture == 0 )
|
|
||||||
{
|
|
||||||
pAData->stMCIMixSetup.ulFormatMode = MCI_PLAY;
|
|
||||||
pAData->stMCIMixSetup.pmixEvent = cbAudioWriteEvent;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pAData->stMCIMixSetup.ulFormatMode = MCI_RECORD;
|
|
||||||
pAData->stMCIMixSetup.pmixEvent = cbAudioReadEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
ulRC = mciSendCommand( pAData->usDeviceId, MCI_MIXSETUP,
|
|
||||||
MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0 );
|
|
||||||
if ( ( ulRC != MCIERR_SUCCESS ) && ( this->spec.freq > 44100 ) )
|
|
||||||
{
|
|
||||||
new_freq = TRUE;
|
|
||||||
pAData->stMCIMixSetup.ulSamplesPerSec = 44100;
|
|
||||||
this->spec.freq = 44100;
|
|
||||||
ulRC = mciSendCommand( pAData->usDeviceId, MCI_MIXSETUP,
|
|
||||||
MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
debug( "Setup mixer [BPS: %u, Freq.: %u, Channels: %u]: %s",
|
|
||||||
pAData->stMCIMixSetup.ulBitsPerSample,
|
|
||||||
pAData->stMCIMixSetup.ulSamplesPerSec,
|
|
||||||
pAData->stMCIMixSetup.ulChannels,
|
|
||||||
ulRC == MCIERR_SUCCESS ? "SUCCESS" : "FAIL" );
|
|
||||||
|
|
||||||
if ( ulRC != MCIERR_SUCCESS )
|
|
||||||
{
|
|
||||||
pAData->stMCIMixSetup.ulBitsPerSample = 0;
|
|
||||||
return _MCIError( "MCI_MIXSETUP", ulRC );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->spec.samples == 0 || new_freq == TRUE) {
|
|
||||||
/* also see SDL_audio.c:prepare_audiospec() */
|
|
||||||
/* Pick a default of ~46 ms at desired frequency */
|
|
||||||
Uint32 samples = (this->spec.freq / 1000) * 46;
|
|
||||||
Uint32 power2 = 1;
|
|
||||||
while (power2 < samples) {
|
|
||||||
power2 <<= 1;
|
|
||||||
}
|
}
|
||||||
this->spec.samples = power2;
|
|
||||||
}
|
|
||||||
/* Update the fragment size as size in bytes */
|
|
||||||
SDL_CalculateAudioSpec( &this->spec );
|
|
||||||
|
|
||||||
// Allocate memory buffers
|
pAData = SDL_calloc(1, sizeof(SDL_PrivateAudioData));
|
||||||
|
if (pAData == NULL)
|
||||||
|
return SDL_OutOfMemory();
|
||||||
|
this->hidden = pAData;
|
||||||
|
|
||||||
stMCIBuffer.ulBufferSize = this->spec.size;// (this->spec.freq / 1000) * 100;
|
ulRC = DosCreateEventSem(NULL, &pAData->hevBuf, DCE_AUTORESET, TRUE);
|
||||||
stMCIBuffer.ulNumBuffers = NUM_BUFFERS;
|
if (ulRC != NO_ERROR) {
|
||||||
stMCIBuffer.pBufList = &pAData->aMixBuffers;
|
debug_os2("DosCreateEventSem() failed, rc = %u", ulRC);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ulRC = mciSendCommand( pAData->usDeviceId, MCI_BUFFER,
|
/* Open audio device */
|
||||||
MCI_WAIT | MCI_ALLOCATE_MEMORY, &stMCIBuffer, 0 );
|
stMCIAmpOpen.usDeviceID = (handle != NULL) ? ((ULONG)handle - 1) : 0;
|
||||||
if ( ulRC != MCIERR_SUCCESS )
|
stMCIAmpOpen.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
|
||||||
{
|
ulRC = mciSendCommand(0, MCI_OPEN,
|
||||||
return _MCIError( "MCI_BUFFER", ulRC );
|
(_getEnvULong("SDL_AUDIO_SHARE", 1, 0) != 0)?
|
||||||
}
|
MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE :
|
||||||
pAData->cMixBuffers = stMCIBuffer.ulNumBuffers;
|
MCI_WAIT | MCI_OPEN_TYPE_ID,
|
||||||
this->spec.size = stMCIBuffer.ulBufferSize;
|
&stMCIAmpOpen, 0);
|
||||||
|
if (ulRC != MCIERR_SUCCESS) {
|
||||||
|
stMCIAmpOpen.usDeviceID = (USHORT)~0;
|
||||||
|
return _MCIError("MCI_OPEN", ulRC);
|
||||||
|
}
|
||||||
|
pAData->usDeviceId = stMCIAmpOpen.usDeviceID;
|
||||||
|
|
||||||
// Fill all device buffers with data
|
if (iscapture != 0) {
|
||||||
|
MCI_CONNECTOR_PARMS stMCIConnector;
|
||||||
|
MCI_AMP_SET_PARMS stMCIAmpSet;
|
||||||
|
BOOL fLineIn = _getEnvULong("SDL_AUDIO_LINEIN", 1, 0);
|
||||||
|
|
||||||
for( ulIdx = 0; ulIdx < stMCIBuffer.ulNumBuffers; ulIdx++ )
|
/* Set particular connector. */
|
||||||
{
|
SDL_zero(stMCIConnector);
|
||||||
pAData->aMixBuffers[ulIdx].ulFlags = 0;
|
stMCIConnector.ulConnectorType = (fLineIn)? MCI_LINE_IN_CONNECTOR :
|
||||||
pAData->aMixBuffers[ulIdx].ulBufferLength = stMCIBuffer.ulBufferSize;
|
MCI_MICROPHONE_CONNECTOR;
|
||||||
pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)pAData;
|
mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_CONNECTOR,
|
||||||
|
MCI_WAIT | MCI_ENABLE_CONNECTOR |
|
||||||
|
MCI_CONNECTOR_TYPE, &stMCIConnector, 0);
|
||||||
|
|
||||||
memset( ((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
|
/* Disable monitor. */
|
||||||
this->spec.silence, stMCIBuffer.ulBufferSize );
|
SDL_zero(stMCIAmpSet);
|
||||||
}
|
stMCIAmpSet.ulItem = MCI_AMP_SET_MONITOR;
|
||||||
|
mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_SET,
|
||||||
|
MCI_WAIT | MCI_SET_OFF | MCI_SET_ITEM,
|
||||||
|
&stMCIAmpSet, 0);
|
||||||
|
|
||||||
// Write buffers to kick off the amp mixer
|
/* Set record volume. */
|
||||||
// pAData->ulQueuedBuf = 1;//stMCIBuffer.ulNumBuffers;
|
stMCIAmpSet.ulLevel = _getEnvULong("SDL_AUDIO_RECVOL", 100, 90);
|
||||||
ulRC = pAData->stMCIMixSetup.pmixWrite( pAData->stMCIMixSetup.ulMixHandle,
|
stMCIAmpSet.ulItem = MCI_AMP_SET_AUDIO;
|
||||||
&pAData->aMixBuffers,
|
stMCIAmpSet.ulAudio = MCI_SET_AUDIO_ALL; /* Both cnannels. */
|
||||||
1 );//stMCIBuffer.ulNumBuffers );
|
stMCIAmpSet.ulValue = (fLineIn) ? MCI_LINE_IN_CONNECTOR :
|
||||||
if ( ulRC != MCIERR_SUCCESS )
|
MCI_MICROPHONE_CONNECTOR ;
|
||||||
{
|
|
||||||
_mixIOError( "pmixWrite", ulRC );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_SET,
|
||||||
|
MCI_WAIT | MCI_SET_AUDIO | MCI_AMP_SET_GAIN,
|
||||||
|
&stMCIAmpSet, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->spec.format = SDLAudioFmt;
|
||||||
|
this->spec.channels = this->spec.channels > 1 ? 2 : 1;
|
||||||
|
if (this->spec.freq < 8000) {
|
||||||
|
this->spec.freq = 8000;
|
||||||
|
new_freq = TRUE;
|
||||||
|
} else if (this->spec.freq > 48000) {
|
||||||
|
this->spec.freq = 48000;
|
||||||
|
new_freq = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup mixer. */
|
||||||
|
pAData->stMCIMixSetup.ulFormatTag = MCI_WAVE_FORMAT_PCM;
|
||||||
|
pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE(SDLAudioFmt);
|
||||||
|
pAData->stMCIMixSetup.ulSamplesPerSec = this->spec.freq;
|
||||||
|
pAData->stMCIMixSetup.ulChannels = this->spec.channels;
|
||||||
|
pAData->stMCIMixSetup.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
|
||||||
|
if (iscapture == 0) {
|
||||||
|
pAData->stMCIMixSetup.ulFormatMode= MCI_PLAY;
|
||||||
|
pAData->stMCIMixSetup.pmixEvent = cbAudioWriteEvent;
|
||||||
|
} else {
|
||||||
|
pAData->stMCIMixSetup.ulFormatMode= MCI_RECORD;
|
||||||
|
pAData->stMCIMixSetup.pmixEvent = cbAudioReadEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
|
||||||
|
MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0);
|
||||||
|
if (ulRC != MCIERR_SUCCESS && this->spec.freq > 44100) {
|
||||||
|
new_freq = TRUE;
|
||||||
|
pAData->stMCIMixSetup.ulSamplesPerSec = 44100;
|
||||||
|
this->spec.freq = 44100;
|
||||||
|
ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
|
||||||
|
MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_os2("Setup mixer [BPS: %u, Freq.: %u, Channels: %u]: %s",
|
||||||
|
pAData->stMCIMixSetup.ulBitsPerSample,
|
||||||
|
pAData->stMCIMixSetup.ulSamplesPerSec,
|
||||||
|
pAData->stMCIMixSetup.ulChannels,
|
||||||
|
(ulRC == MCIERR_SUCCESS)? "SUCCESS" : "FAIL");
|
||||||
|
|
||||||
|
if (ulRC != MCIERR_SUCCESS) {
|
||||||
|
pAData->stMCIMixSetup.ulBitsPerSample = 0;
|
||||||
|
return _MCIError("MCI_MIXSETUP", ulRC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->spec.samples == 0 || new_freq == TRUE) {
|
||||||
|
/* also see SDL_audio.c:prepare_audiospec() */
|
||||||
|
/* Pick a default of ~46 ms at desired frequency */
|
||||||
|
Uint32 samples = (this->spec.freq / 1000) * 46;
|
||||||
|
Uint32 power2 = 1;
|
||||||
|
while (power2 < samples) {
|
||||||
|
power2 <<= 1;
|
||||||
|
}
|
||||||
|
this->spec.samples = power2;
|
||||||
|
}
|
||||||
|
/* Update the fragment size as size in bytes */
|
||||||
|
SDL_CalculateAudioSpec(&this->spec);
|
||||||
|
|
||||||
|
/* Allocate memory buffers */
|
||||||
|
stMCIBuffer.ulBufferSize = this->spec.size;/* (this->spec.freq / 1000) * 100 */
|
||||||
|
stMCIBuffer.ulNumBuffers = NUM_BUFFERS;
|
||||||
|
stMCIBuffer.pBufList = &pAData->aMixBuffers;
|
||||||
|
|
||||||
|
ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER,
|
||||||
|
MCI_WAIT | MCI_ALLOCATE_MEMORY, &stMCIBuffer, 0);
|
||||||
|
if (ulRC != MCIERR_SUCCESS) {
|
||||||
|
return _MCIError("MCI_BUFFER", ulRC);
|
||||||
|
}
|
||||||
|
pAData->cMixBuffers = stMCIBuffer.ulNumBuffers;
|
||||||
|
this->spec.size = stMCIBuffer.ulBufferSize;
|
||||||
|
|
||||||
|
/* Fill all device buffers with data */
|
||||||
|
for (ulIdx = 0; ulIdx < stMCIBuffer.ulNumBuffers; ulIdx++) {
|
||||||
|
pAData->aMixBuffers[ulIdx].ulFlags = 0;
|
||||||
|
pAData->aMixBuffers[ulIdx].ulBufferLength = stMCIBuffer.ulBufferSize;
|
||||||
|
pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)pAData;
|
||||||
|
|
||||||
|
memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
|
||||||
|
this->spec.silence, stMCIBuffer.ulBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write buffers to kick off the amp mixer */
|
||||||
|
/*pAData->ulQueuedBuf = 1;//stMCIBuffer.ulNumBuffers;*/
|
||||||
|
ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
|
||||||
|
&pAData->aMixBuffers,
|
||||||
|
1 /*stMCIBuffer.ulNumBuffers*/);
|
||||||
|
if (ulRC != MCIERR_SUCCESS) {
|
||||||
|
_mixIOError("pmixWrite", ulRC);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int OS2_Init(SDL_AudioDriverImpl * impl)
|
static int OS2_Init(SDL_AudioDriverImpl * impl)
|
||||||
{
|
{
|
||||||
/* Set the function pointers */
|
/* Set the function pointers */
|
||||||
impl->DetectDevices = OS2_DetectDevices;
|
impl->DetectDevices = OS2_DetectDevices;
|
||||||
impl->OpenDevice = OS2_OpenDevice;
|
impl->OpenDevice = OS2_OpenDevice;
|
||||||
impl->PlayDevice = OS2_PlayDevice;
|
impl->PlayDevice = OS2_PlayDevice;
|
||||||
impl->WaitDevice = OS2_WaitDevice;
|
impl->WaitDevice = OS2_WaitDevice;
|
||||||
impl->GetDeviceBuf = OS2_GetDeviceBuf;
|
impl->GetDeviceBuf = OS2_GetDeviceBuf;
|
||||||
impl->CloseDevice = OS2_CloseDevice;
|
impl->CloseDevice = OS2_CloseDevice;
|
||||||
|
|
||||||
// TODO: IMPLEMENT CAPTURE SUPPORT:
|
/* TODO: IMPLEMENT CAPTURE SUPPORT:
|
||||||
// impl->CaptureFromDevice = ;
|
impl->CaptureFromDevice = ;
|
||||||
// impl->FlushCapture = ;
|
impl->FlushCapture = ;
|
||||||
// impl->HasCaptureSupport = SDL_TRUE;
|
impl->HasCaptureSupport = SDL_TRUE;
|
||||||
|
*/
|
||||||
return 1; /* this audio target is available. */
|
return 1; /* this audio target is available. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,19 +35,19 @@
|
||||||
/* Hidden "this" pointer for the audio functions */
|
/* Hidden "this" pointer for the audio functions */
|
||||||
#define _THIS SDL_AudioDevice *this
|
#define _THIS SDL_AudioDevice *this
|
||||||
|
|
||||||
#define NUM_BUFFERS 3
|
#define NUM_BUFFERS 3
|
||||||
|
|
||||||
typedef struct SDL_PrivateAudioData
|
typedef struct SDL_PrivateAudioData
|
||||||
{
|
{
|
||||||
USHORT usDeviceId;
|
USHORT usDeviceId;
|
||||||
BYTE _pad[2];
|
BYTE _pad[2];
|
||||||
MCI_MIXSETUP_PARMS stMCIMixSetup;
|
MCI_MIXSETUP_PARMS stMCIMixSetup;
|
||||||
HEV hevBuf;
|
HEV hevBuf;
|
||||||
ULONG ulNextBuf;
|
ULONG ulNextBuf;
|
||||||
ULONG cMixBuffers;
|
ULONG cMixBuffers;
|
||||||
MCI_MIX_BUFFER aMixBuffers[NUM_BUFFERS];
|
MCI_MIX_BUFFER aMixBuffers[NUM_BUFFERS];
|
||||||
// ULONG ulQueuedBuf;
|
/* ULONG ulQueuedBuf;*/
|
||||||
} SDL_PrivateAudioData, *PSDL_PrivateAudioData;
|
} SDL_PrivateAudioData;
|
||||||
|
|
||||||
#endif /* SDL_os2mm_h_ */
|
#endif /* SDL_os2mm_h_ */
|
||||||
|
|
||||||
|
|
|
@ -18,19 +18,21 @@
|
||||||
misrepresented as being the original software.
|
misrepresented as being the original software.
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../../SDL_internal.h"
|
#include "../../SDL_internal.h"
|
||||||
|
|
||||||
#if defined(__OS2__)
|
#if defined(__OS2__)
|
||||||
|
|
||||||
#include "geniconv/geniconv.h"
|
#include "geniconv/geniconv.h"
|
||||||
|
|
||||||
// SDL_OS2Quit() will be called from SDL_QuitSubSystem().
|
/* SDL_OS2Quit() will be called from SDL_QuitSubSystem() */
|
||||||
|
void SDL_OS2Quit(void)
|
||||||
void SDL_OS2Quit()
|
|
||||||
{
|
{
|
||||||
// Unload DLL used for iconv. We can do it at any time and use iconv again -
|
/* Unload DLL used for iconv. We can do it at any time and use iconv again -
|
||||||
// dynamic library will be loaded on first call iconv_open() (see geniconv).
|
* dynamic library will be loaded on first call iconv_open() (see geniconv). */
|
||||||
libiconv_clean();
|
libiconv_clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -27,24 +27,26 @@
|
||||||
|
|
||||||
#ifdef OS2DEBUG
|
#ifdef OS2DEBUG
|
||||||
#if (OS2DEBUG-0 >= 2)
|
#if (OS2DEBUG-0 >= 2)
|
||||||
# define debug(s,...) SDL_LogDebug( SDL_LOG_CATEGORY_APPLICATION, \
|
# define debug_os2(s,...) SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, \
|
||||||
__func__"(): "##s, ##__VA_ARGS__ )
|
__func__ "(): " ##s, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
# define debug(s,...) printf( __func__"(): "##s"\n", ##__VA_ARGS__ )
|
# define debug_os2(s,...) printf(__func__ "(): " ##s "\n", ##__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else /* no debug */
|
||||||
|
|
||||||
# define debug(s,...)
|
# define debug_os2(s,...) do {} while (0)
|
||||||
|
|
||||||
#endif /* OS2DEBUG */
|
#endif /* OS2DEBUG */
|
||||||
|
|
||||||
|
|
||||||
/* StrUTF8New() - geniconv/sys2utf8.c */
|
/* StrUTF8New() - geniconv/sys2utf8.c */
|
||||||
#define OS2_SysToUTF8(S) StrUTF8New( 1, S, SDL_strlen( S ) + 1 )
|
#define OS2_SysToUTF8(S) StrUTF8New(1, (S), SDL_strlen((S)) + 1)
|
||||||
#define OS2_UTF8ToSys(S) StrUTF8New( 0, (char *)(S), SDL_strlen( S ) + 1 )
|
#define OS2_UTF8ToSys(S) StrUTF8New(0, (char *)(S), SDL_strlen((S)) + 1)
|
||||||
|
|
||||||
/* SDL_OS2Quit() will be called from SDL_QuitSubSystem() */
|
/* SDL_OS2Quit() will be called from SDL_QuitSubSystem() */
|
||||||
void SDL_OS2Quit();
|
void SDL_OS2Quit(void);
|
||||||
|
|
||||||
#endif /* SDL_os2_h_ */
|
#endif /* SDL_os2_h_ */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -25,38 +25,38 @@
|
||||||
Andrey Vasilkin, 2016.
|
Andrey Vasilkin, 2016.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INCL_DOSMODULEMGR /* Module Manager values */
|
#define INCL_DOSMODULEMGR /* Module Manager values */
|
||||||
#define INCL_DOSERRORS /* Error values */
|
#define INCL_DOSERRORS /* Error values */
|
||||||
#include <os2.h>
|
#include <os2.h>
|
||||||
|
|
||||||
#include "geniconv.h"
|
#include "geniconv.h"
|
||||||
|
|
||||||
//#define DEBUG
|
/*#define DEBUG*/
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# define debug(s,...) printf(__func__"(): "##s"\n" ,##__VA_ARGS__)
|
# define debug(s,...) printf(__func__"(): "##s"\n" ,##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
# define debug(s,...)
|
# define debug(s,...) do {} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Exports from os2iconv.c.
|
/* Exports from os2iconv.c */
|
||||||
extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode);
|
extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode);
|
||||||
extern size_t _System os2_iconv(iconv_t cd, char* * inbuf,
|
extern size_t _System os2_iconv(iconv_t cd, char* * inbuf,
|
||||||
size_t *inbytesleft, char* * outbuf,
|
size_t *inbytesleft, char* * outbuf,
|
||||||
size_t *outbytesleft);
|
size_t *outbytesleft);
|
||||||
extern int _System os2_iconv_close(iconv_t cd);
|
extern int _System os2_iconv_close(iconv_t cd);
|
||||||
|
|
||||||
// Functions pointers types.
|
/* Functions pointers types */
|
||||||
typedef iconv_t _System (*FNICONV_OPEN)(const char* tocode, const char* fromcode);
|
typedef iconv_t _System (*FNICONV_OPEN)(const char* tocode, const char* fromcode);
|
||||||
typedef size_t _System (*FNICONV)(iconv_t cd, char* * inbuf,
|
typedef size_t _System (*FNICONV)(iconv_t cd, char* * inbuf,
|
||||||
size_t *inbytesleft, char* * outbuf,
|
size_t *inbytesleft, char* * outbuf,
|
||||||
size_t *outbytesleft);
|
size_t *outbytesleft);
|
||||||
typedef int _System (*FNICONV_CLOSE)(iconv_t cd);
|
typedef int _System (*FNICONV_CLOSE)(iconv_t cd);
|
||||||
|
|
||||||
// Used DLL module handle.
|
/* Used DLL module handle */
|
||||||
static HMODULE hmIconv = NULLHANDLE;
|
static HMODULE hmIconv = NULLHANDLE;
|
||||||
// Functions pointers.
|
/* Functions pointers */
|
||||||
static FNICONV_OPEN fn_iconv_open = NULL;
|
static FNICONV_OPEN fn_iconv_open = NULL;
|
||||||
static FNICONV fn_iconv = NULL;
|
static FNICONV fn_iconv = NULL;
|
||||||
static FNICONV_CLOSE fn_iconv_close = NULL;
|
static FNICONV_CLOSE fn_iconv_close = NULL;
|
||||||
|
@ -65,100 +65,93 @@ static FNICONV_CLOSE fn_iconv_close = NULL;
|
||||||
static BOOL _loadDLL(PSZ pszName, PSZ pszIconvOpen, PSZ pszIconv,
|
static BOOL _loadDLL(PSZ pszName, PSZ pszIconvOpen, PSZ pszIconv,
|
||||||
PSZ pszIconvClose)
|
PSZ pszIconvClose)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
CHAR acError[256];
|
CHAR acError[256];
|
||||||
|
|
||||||
ulRC = DosLoadModule( acError, sizeof(acError), pszName, &hmIconv );
|
ulRC = DosLoadModule(acError, sizeof(acError), pszName, &hmIconv);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug("DLL not loaded: %s", &acError);
|
||||||
debug( "DLL not loaded: %s", &acError );
|
return FALSE;
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
ulRC = DosQueryProcAddr( hmIconv, 0, pszIconvOpen, (PFN *)&fn_iconv_open );
|
|
||||||
if ( ulRC != NO_ERROR )
|
|
||||||
{
|
|
||||||
debug( "Error: cannot find entry %s in %s", pszIconvOpen, pszName );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ulRC = DosQueryProcAddr( hmIconv, 0, pszIconv, (PFN *)&fn_iconv );
|
do {
|
||||||
if ( ulRC != NO_ERROR )
|
ulRC = DosQueryProcAddr(hmIconv, 0, pszIconvOpen, (PFN *)&fn_iconv_open);
|
||||||
{
|
if (ulRC != NO_ERROR) {
|
||||||
debug( "Error: cannot find entry %s in %s", pszIconv, pszName );
|
debug("Error: cannot find entry %s in %s", pszIconvOpen, pszName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulRC = DosQueryProcAddr( hmIconv, 0, pszIconvClose, (PFN *)&fn_iconv_close );
|
ulRC = DosQueryProcAddr(hmIconv, 0, pszIconv, (PFN *)&fn_iconv);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug("Error: cannot find entry %s in %s", pszIconv, pszName);
|
||||||
debug( "Error: cannot find entry %s in %s", pszIconvClose, pszName );
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
debug( "DLL %s used", pszName );
|
ulRC = DosQueryProcAddr(hmIconv, 0, pszIconvClose, (PFN *)&fn_iconv_close);
|
||||||
return TRUE;
|
if (ulRC != NO_ERROR) {
|
||||||
}
|
debug("Error: cannot find entry %s in %s", pszIconvClose, pszName);
|
||||||
while( FALSE );
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
DosFreeModule( hmIconv );
|
debug("DLL %s used", pszName);
|
||||||
hmIconv = NULLHANDLE;
|
return TRUE;
|
||||||
return FALSE;
|
} while (FALSE);
|
||||||
}
|
|
||||||
|
|
||||||
static void _init()
|
DosFreeModule(hmIconv);
|
||||||
{
|
|
||||||
if ( fn_iconv_open != NULL )
|
|
||||||
// Already was initialized.
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Try to load kiconv.dll, iconv2.dll or iconv.dll.
|
|
||||||
if ( !_loadDLL( "KICONV", "_libiconv_open", "_libiconv", "_libiconv_close" )
|
|
||||||
&& !_loadDLL( "ICONV2", "_libiconv_open", "_libiconv", "_libiconv_close" )
|
|
||||||
&& !_loadDLL( "ICONV", "_iconv_open", "_iconv", "_iconv_close" ) )
|
|
||||||
{
|
|
||||||
// No one DLL was loaded - use OS/2 conversion objects API.
|
|
||||||
|
|
||||||
debug( "Uni*() API used" );
|
|
||||||
fn_iconv_open = os2_iconv_open;
|
|
||||||
fn_iconv = os2_iconv;
|
|
||||||
fn_iconv_close = os2_iconv_close;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Public routines.
|
|
||||||
// ----------------
|
|
||||||
|
|
||||||
// Non-standard function for iconv to unload the used dynamic library.
|
|
||||||
void libiconv_clean()
|
|
||||||
{
|
|
||||||
if ( hmIconv != NULLHANDLE )
|
|
||||||
{
|
|
||||||
DosFreeModule( hmIconv );
|
|
||||||
hmIconv = NULLHANDLE;
|
hmIconv = NULLHANDLE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
fn_iconv_open = NULL;
|
static void _init(void)
|
||||||
fn_iconv = NULL;
|
{
|
||||||
fn_iconv_close = NULL;
|
if (fn_iconv_open != NULL) /* Already was initialized */
|
||||||
}
|
return;
|
||||||
|
|
||||||
|
/* Try to load kiconv.dll, iconv2.dll or iconv.dll */
|
||||||
|
if (!_loadDLL("KICONV", "_libiconv_open", "_libiconv", "_libiconv_close") &&
|
||||||
|
!_loadDLL("ICONV2", "_libiconv_open", "_libiconv", "_libiconv_close") &&
|
||||||
|
!_loadDLL("ICONV", "_iconv_open", "_iconv", "_iconv_close") ) {
|
||||||
|
/* No DLL was loaded - use OS/2 conversion objects API */
|
||||||
|
debug("Uni*() API used");
|
||||||
|
fn_iconv_open = os2_iconv_open;
|
||||||
|
fn_iconv = os2_iconv;
|
||||||
|
fn_iconv_close = os2_iconv_close;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Public routines.
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Non-standard function for iconv to unload the used dynamic library */
|
||||||
|
void libiconv_clean(void)
|
||||||
|
{
|
||||||
|
if (hmIconv != NULLHANDLE) {
|
||||||
|
DosFreeModule(hmIconv);
|
||||||
|
hmIconv = NULLHANDLE;
|
||||||
|
|
||||||
|
fn_iconv_open = NULL;
|
||||||
|
fn_iconv = NULL;
|
||||||
|
fn_iconv_close = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iconv_t libiconv_open(const char* tocode, const char* fromcode)
|
iconv_t libiconv_open(const char* tocode, const char* fromcode)
|
||||||
{
|
{
|
||||||
_init();
|
_init();
|
||||||
return fn_iconv_open( tocode, fromcode );
|
return fn_iconv_open(tocode, fromcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t libiconv(iconv_t cd, char* * inbuf, size_t *inbytesleft,
|
size_t libiconv(iconv_t cd, char* * inbuf, size_t *inbytesleft,
|
||||||
char* * outbuf, size_t *outbytesleft)
|
char* * outbuf, size_t *outbytesleft)
|
||||||
{
|
{
|
||||||
return fn_iconv( cd, inbuf, inbytesleft, outbuf, outbytesleft );
|
return fn_iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft);
|
||||||
}
|
}
|
||||||
|
|
||||||
int libiconv_close(iconv_t cd)
|
int libiconv_close(iconv_t cd)
|
||||||
{
|
{
|
||||||
return fn_iconv_close( cd );
|
return fn_iconv_close(cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -47,34 +47,39 @@
|
||||||
|
|
||||||
#define iconv_clean libiconv_clean
|
#define iconv_clean libiconv_clean
|
||||||
|
|
||||||
// Non-standard function for iconv to unload the used dynamic library.
|
/* Non-standard function for iconv to unload the used dynamic library */
|
||||||
void libiconv_clean();
|
void libiconv_clean(void);
|
||||||
|
|
||||||
iconv_t libiconv_open(const char* tocode, const char* fromcode);
|
iconv_t libiconv_open (const char *tocode, const char *fromcode);
|
||||||
size_t libiconv(iconv_t cd, char* * inbuf, size_t *inbytesleft,
|
int libiconv_close(iconv_t cd);
|
||||||
char* * outbuf, size_t *outbytesleft);
|
size_t libiconv (iconv_t cd, char **inbuf, size_t *inbytesleft,
|
||||||
int libiconv_close(iconv_t cd);
|
char **outbuf, size_t *outbytesleft);
|
||||||
|
|
||||||
// System codepage <-> UTF-8.
|
/* System codepage <-> UTF-8
|
||||||
|
*
|
||||||
// StrUTF8()
|
* StrUTF8()
|
||||||
// Coverts string from system cp to UTF-8 (fToUTF8 is not 0) or from UTF-8 to
|
* Coverts string from system cp to UTF-8 (fToUTF8 is not 0) or from UTF-8 to
|
||||||
// the system cp (fToUTF8 is 0). Converted ASCIIZ string will be placed at the
|
* the system cp (fToUTF8 is 0). Converted ASCIIZ string will be placed at the
|
||||||
// buffer pcDst, up to cbDst - 1 (for sys->utf8) or 2 (for utf8->sys) bytes.
|
* buffer pcDst, up to cbDst - 1 (for sys->utf8) or 2 (for utf8->sys) bytes.
|
||||||
// Returns the number of bytes written into pcDst, not counting the terminating
|
* Returns the number of bytes written into pcDst, not counting the terminating
|
||||||
// 0 byte(s) or -1 on error.
|
* 0 byte(s) or -1 on error.
|
||||||
|
*/
|
||||||
int StrUTF8(int fToUTF8, char *pcDst, int cbDst, char *pcSrc, int cbSrc);
|
int StrUTF8(int fToUTF8, char *pcDst, int cbDst, char *pcSrc, int cbSrc);
|
||||||
|
|
||||||
// StrUTF8New()
|
/* StrUTF8New()
|
||||||
// Coverts string from system cp to UTF-8 (fToUTF8 is not 0) or from UTF-8 to
|
* Coverts string from system cp to UTF-8 (fToUTF8 is not 0) or from UTF-8 to
|
||||||
// the system cp (fToUTF8 is 0). Memory for the new string is obtained by
|
* the system cp (fToUTF8 is 0). Memory for the new string is obtained by
|
||||||
// using libc malloc().
|
* using libc malloc().
|
||||||
// Returns converted string, terminating two bytes 0 is appended to the result.
|
* Returns converted string, terminating two bytes 0 is appended to the result.
|
||||||
// Returns null on error.
|
* Returns null on error.
|
||||||
|
*/
|
||||||
char *StrUTF8New(int fToUTF8, char *pcStr, int cbStr);
|
char *StrUTF8New(int fToUTF8, char *pcStr, int cbStr);
|
||||||
|
|
||||||
// StrUTF8Free()
|
/* StrUTF8Free()
|
||||||
// Deallocates the memory block located by StrUTF8New() (just libc free()).
|
* Deallocates the memory block located by StrUTF8New() (just libc free()).
|
||||||
|
*/
|
||||||
void StrUTF8Free(char *pszStr);
|
void StrUTF8Free(char *pszStr);
|
||||||
|
|
||||||
#endif // GENICONV_H
|
#endif /* GENICONV_H */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -28,17 +28,16 @@
|
||||||
#include "os2cp.h"
|
#include "os2cp.h"
|
||||||
|
|
||||||
typedef struct _CP2NAME {
|
typedef struct _CP2NAME {
|
||||||
ULONG ulCode;
|
ULONG ulCode;
|
||||||
PSZ pszName;
|
PSZ pszName;
|
||||||
} CP2NAME;
|
} CP2NAME;
|
||||||
|
|
||||||
typedef struct _NAME2CP {
|
typedef struct _NAME2CP {
|
||||||
PSZ pszName;
|
PSZ pszName;
|
||||||
ULONG ulCode;
|
ULONG ulCode;
|
||||||
} NAME2CP;
|
} NAME2CP;
|
||||||
|
|
||||||
static CP2NAME aCP2Name[] =
|
static CP2NAME aCP2Name[] = {
|
||||||
{
|
|
||||||
{367, "ANSI_X3.4-1968"},
|
{367, "ANSI_X3.4-1968"},
|
||||||
{813, "ECMA-118"},
|
{813, "ECMA-118"},
|
||||||
{819, "CP819"},
|
{819, "CP819"},
|
||||||
|
@ -85,8 +84,7 @@ static CP2NAME aCP2Name[] =
|
||||||
{62210, "HEBREW"}
|
{62210, "HEBREW"}
|
||||||
};
|
};
|
||||||
|
|
||||||
static NAME2CP aName2CP[] =
|
static NAME2CP aName2CP[] = {
|
||||||
{
|
|
||||||
{"850", 850},
|
{"850", 850},
|
||||||
{"862", 862},
|
{"862", 862},
|
||||||
{"866", 866},
|
{"866", 866},
|
||||||
|
@ -297,109 +295,107 @@ static NAME2CP aName2CP[] =
|
||||||
{"X0201", 896}
|
{"X0201", 896}
|
||||||
};
|
};
|
||||||
|
|
||||||
char * os2cpToName(unsigned long cp)
|
char *os2cpToName(unsigned long cp)
|
||||||
{
|
{
|
||||||
ULONG ulLo = 0;
|
ULONG ulLo = 0;
|
||||||
ULONG ulHi = ( sizeof(aCP2Name) / sizeof(struct _CP2NAME) ) - 1;
|
ULONG ulHi = (sizeof(aCP2Name) / sizeof(struct _CP2NAME)) - 1;
|
||||||
ULONG ulNext;
|
ULONG ulNext;
|
||||||
LONG lFound = -1;
|
LONG lFound = -1;
|
||||||
|
|
||||||
if ( cp == SYSTEM_CP )
|
if (cp == SYSTEM_CP) {
|
||||||
{
|
ULONG aulCP[3];
|
||||||
ULONG aulCP[3];
|
ULONG cCP;
|
||||||
ULONG cCP;
|
|
||||||
|
|
||||||
if ( DosQueryCp( sizeof(aulCP), aulCP, &cCP ) != NO_ERROR )
|
if (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cp = aulCP[0];
|
cp = aulCP[0];
|
||||||
}
|
|
||||||
|
|
||||||
if ( ( aCP2Name[0].ulCode > cp ) || ( aCP2Name[ulHi].ulCode < cp ) )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if ( aCP2Name[0].ulCode == cp )
|
|
||||||
return aCP2Name[0].pszName;
|
|
||||||
|
|
||||||
if ( aCP2Name[ulHi].ulCode == cp )
|
|
||||||
return aCP2Name[ulHi].pszName;
|
|
||||||
|
|
||||||
while( ( ulHi - ulLo ) > 1 )
|
|
||||||
{
|
|
||||||
ulNext = ( ulLo + ulHi ) / 2;
|
|
||||||
|
|
||||||
if ( aCP2Name[ulNext].ulCode < cp )
|
|
||||||
ulLo = ulNext;
|
|
||||||
else if ( aCP2Name[ulNext].ulCode > cp )
|
|
||||||
ulHi = ulNext;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lFound = ulNext;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return lFound == -1 ? NULL : aCP2Name[lFound].pszName;
|
if (aCP2Name[0].ulCode > cp || aCP2Name[ulHi].ulCode < cp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (aCP2Name[0].ulCode == cp)
|
||||||
|
return aCP2Name[0].pszName;
|
||||||
|
|
||||||
|
if (aCP2Name[ulHi].ulCode == cp)
|
||||||
|
return aCP2Name[ulHi].pszName;
|
||||||
|
|
||||||
|
while ((ulHi - ulLo) > 1) {
|
||||||
|
ulNext = (ulLo + ulHi) / 2;
|
||||||
|
|
||||||
|
if (aCP2Name[ulNext].ulCode < cp)
|
||||||
|
ulLo = ulNext;
|
||||||
|
else if (aCP2Name[ulNext].ulCode > cp)
|
||||||
|
ulHi = ulNext;
|
||||||
|
else {
|
||||||
|
lFound = ulNext;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (lFound == -1)? NULL : aCP2Name[lFound].pszName;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long os2cpFromName(char *cp)
|
unsigned long os2cpFromName(char *cp)
|
||||||
{
|
{
|
||||||
ULONG ulLo = 0;
|
ULONG ulLo = 0;
|
||||||
ULONG ulHi = ( sizeof(aName2CP) / sizeof(struct _NAME2CP) ) - 1;
|
ULONG ulHi = (sizeof(aName2CP) / sizeof(struct _NAME2CP)) - 1;
|
||||||
ULONG ulNext;
|
ULONG ulNext;
|
||||||
LONG lFound = -1;
|
LONG lFound = -1;
|
||||||
LONG lCmp;
|
LONG lCmp;
|
||||||
PCHAR pcEnd;
|
PCHAR pcEnd;
|
||||||
CHAR acBuf[64];
|
CHAR acBuf[64];
|
||||||
|
|
||||||
if ( cp == NULL )
|
if (cp == NULL) {
|
||||||
{
|
ULONG aulCP[3];
|
||||||
ULONG aulCP[3];
|
ULONG cCP;
|
||||||
ULONG cCP;
|
|
||||||
|
|
||||||
return DosQueryCp( sizeof(aulCP), aulCP, &cCP ) != NO_ERROR ? 0 : aulCP[0];
|
return (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR)? 0 : aulCP[0];
|
||||||
}
|
|
||||||
|
|
||||||
while( isspace( *cp ) ) cp++;
|
|
||||||
pcEnd = strchr( cp, ' ' );
|
|
||||||
if ( pcEnd == NULL )
|
|
||||||
pcEnd = strchr( cp, '\0' );
|
|
||||||
|
|
||||||
ulNext = pcEnd - cp;
|
|
||||||
if ( ulNext >= sizeof(acBuf) )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
memcpy( acBuf, cp, ulNext );
|
|
||||||
acBuf[ulNext] = '\0';
|
|
||||||
strupr( acBuf );
|
|
||||||
|
|
||||||
lCmp = strcmp( aName2CP[0].pszName, acBuf );
|
|
||||||
if ( lCmp > 0 )
|
|
||||||
return 0;
|
|
||||||
else if ( lCmp == 0 )
|
|
||||||
return aName2CP[0].ulCode;
|
|
||||||
|
|
||||||
lCmp = strcmp( aName2CP[ulHi].pszName, acBuf );
|
|
||||||
if ( lCmp < 0 )
|
|
||||||
return 0;
|
|
||||||
else if ( lCmp == 0 )
|
|
||||||
return aName2CP[ulHi].ulCode;
|
|
||||||
|
|
||||||
while( ( ulHi - ulLo ) > 1 )
|
|
||||||
{
|
|
||||||
ulNext = ( ulLo + ulHi ) / 2;
|
|
||||||
|
|
||||||
lCmp = strcmp( aName2CP[ulNext].pszName, acBuf );
|
|
||||||
if ( lCmp < 0 )
|
|
||||||
ulLo = ulNext;
|
|
||||||
else if ( lCmp > 0 )
|
|
||||||
ulHi = ulNext;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lFound = ulNext;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return lFound == -1 ? 0 : aName2CP[lFound].ulCode;
|
while (isspace(*cp))
|
||||||
|
cp++;
|
||||||
|
|
||||||
|
pcEnd = strchr(cp, ' ');
|
||||||
|
if (pcEnd == NULL)
|
||||||
|
pcEnd = strchr(cp, '\0');
|
||||||
|
|
||||||
|
ulNext = pcEnd - cp;
|
||||||
|
if (ulNext >= sizeof(acBuf))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memcpy(acBuf, cp, ulNext);
|
||||||
|
acBuf[ulNext] = '\0';
|
||||||
|
strupr(acBuf);
|
||||||
|
|
||||||
|
lCmp = strcmp(aName2CP[0].pszName, acBuf);
|
||||||
|
if (lCmp > 0)
|
||||||
|
return 0;
|
||||||
|
else if (lCmp == 0)
|
||||||
|
return aName2CP[0].ulCode;
|
||||||
|
|
||||||
|
lCmp = strcmp(aName2CP[ulHi].pszName, acBuf);
|
||||||
|
if (lCmp < 0)
|
||||||
|
return 0;
|
||||||
|
else if (lCmp == 0)
|
||||||
|
return aName2CP[ulHi].ulCode;
|
||||||
|
|
||||||
|
while ((ulHi - ulLo) > 1) {
|
||||||
|
ulNext = (ulLo + ulHi) / 2;
|
||||||
|
|
||||||
|
lCmp = strcmp(aName2CP[ulNext].pszName, acBuf);
|
||||||
|
if (lCmp < 0)
|
||||||
|
ulLo = ulNext;
|
||||||
|
else if (lCmp > 0)
|
||||||
|
ulHi = ulNext;
|
||||||
|
else {
|
||||||
|
lFound = ulNext;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (lFound == -1)? 0 : aName2CP[lFound].ulCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
|
|
||||||
#define SYSTEM_CP 0
|
#define SYSTEM_CP 0
|
||||||
|
|
||||||
char * os2cpToName(unsigned long cp);
|
char *os2cpToName(unsigned long cp);
|
||||||
unsigned long os2cpFromName(char *cp);
|
unsigned long os2cpFromName(char *cp);
|
||||||
|
|
||||||
#endif // OS2CP_H
|
#endif /* OS2CP_H */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "os2cp.h"
|
#include "os2cp.h"
|
||||||
|
|
||||||
#define MAX_CP_NAME_LEN 64
|
#define MAX_CP_NAME_LEN 64
|
||||||
|
|
||||||
typedef struct iuconv_obj {
|
typedef struct iuconv_obj {
|
||||||
UconvObject uo_tocode;
|
UconvObject uo_tocode;
|
||||||
|
@ -54,232 +54,211 @@ typedef struct iuconv_obj {
|
||||||
|
|
||||||
static int _createUconvObj(const char *code, UconvObject *uobj)
|
static int _createUconvObj(const char *code, UconvObject *uobj)
|
||||||
{
|
{
|
||||||
UniChar uc_code[MAX_CP_NAME_LEN];
|
UniChar uc_code[MAX_CP_NAME_LEN];
|
||||||
int i;
|
int i;
|
||||||
const char *ch = code;
|
const char *ch = code;
|
||||||
|
|
||||||
if ( code == NULL )
|
if (code == NULL)
|
||||||
uc_code[0] = 0;
|
uc_code[0] = 0;
|
||||||
else
|
else {
|
||||||
{
|
for (i = 0; i < MAX_CP_NAME_LEN; i++) {
|
||||||
for( i = 0; i < MAX_CP_NAME_LEN; i++ )
|
uc_code[i] = (unsigned short)*ch;
|
||||||
{
|
if (! (*ch))
|
||||||
uc_code[i] = (unsigned short)*ch;
|
break;
|
||||||
if ( !(*ch) ) break;
|
ch++;
|
||||||
ch++;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return UniCreateUconvObject( uc_code, uobj );
|
return UniCreateUconvObject(uc_code, uobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uconv_open(const char *code, UconvObject *uobj)
|
static int uconv_open(const char *code, UconvObject *uobj)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if ( !stricmp( code, "UTF-16" ) )
|
if (!stricmp(code, "UTF-16")) {
|
||||||
{
|
*uobj = NULL;
|
||||||
*uobj = NULL;
|
return ULS_SUCCESS;
|
||||||
return ULS_SUCCESS;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
rc = _createUconvObj( code, uobj );
|
rc = _createUconvObj(code, uobj);
|
||||||
if ( rc != ULS_SUCCESS )
|
if (rc != ULS_SUCCESS) {
|
||||||
{
|
unsigned long cp = os2cpFromName((char *)code);
|
||||||
unsigned long cp = os2cpFromName( (char *)code );
|
char cp_name[16];
|
||||||
char cp_name[16];
|
|
||||||
|
|
||||||
if ( cp != 0 && _snprintf( cp_name, sizeof(cp_name), "IBM-%u", cp ) > 0 )
|
if (cp != 0 && _snprintf(cp_name, sizeof(cp_name), "IBM-%u", cp) > 0)
|
||||||
rc = _createUconvObj( cp_name, uobj );
|
rc = _createUconvObj(cp_name, uobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode)
|
extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode)
|
||||||
{
|
{
|
||||||
UconvObject uo_tocode;
|
UconvObject uo_tocode;
|
||||||
UconvObject uo_fromcode;
|
UconvObject uo_fromcode;
|
||||||
int rc;
|
int rc;
|
||||||
iuconv_obj *iuobj;
|
iuconv_obj *iuobj;
|
||||||
|
|
||||||
if ( tocode == NULL )
|
if (tocode == NULL)
|
||||||
tocode = "";
|
tocode = "";
|
||||||
|
|
||||||
if ( fromcode == NULL )
|
if (fromcode == NULL)
|
||||||
fromcode = "";
|
fromcode = "";
|
||||||
|
|
||||||
if ( stricmp(tocode, fromcode) != 0 )
|
if (stricmp(tocode, fromcode) != 0) {
|
||||||
{
|
rc = uconv_open(fromcode, &uo_fromcode);
|
||||||
rc = uconv_open( fromcode, &uo_fromcode );
|
if (rc != ULS_SUCCESS) {
|
||||||
if ( rc != ULS_SUCCESS )
|
errno = EINVAL;
|
||||||
{
|
return (iconv_t)(-1);
|
||||||
errno = EINVAL;
|
}
|
||||||
return (iconv_t)(-1);
|
|
||||||
|
rc = uconv_open(tocode, &uo_tocode);
|
||||||
|
if (rc != ULS_SUCCESS) {
|
||||||
|
UniFreeUconvObject(uo_fromcode);
|
||||||
|
errno = EINVAL;
|
||||||
|
return (iconv_t)(-1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uo_tocode = NULL;
|
||||||
|
uo_fromcode = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = uconv_open( tocode, &uo_tocode );
|
iuobj = malloc(sizeof(iuconv_obj));
|
||||||
if ( rc != ULS_SUCCESS )
|
iuobj->uo_tocode = uo_tocode;
|
||||||
{
|
iuobj->uo_fromcode = uo_fromcode;
|
||||||
UniFreeUconvObject( uo_fromcode );
|
iuobj->buf_len = 0;
|
||||||
errno = EINVAL;
|
iuobj->buf = NULL;
|
||||||
return (iconv_t)(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uo_tocode = NULL;
|
|
||||||
uo_fromcode = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
iuobj = malloc( sizeof(iuconv_obj) );
|
|
||||||
iuobj->uo_tocode = uo_tocode;
|
|
||||||
iuobj->uo_fromcode = uo_fromcode;
|
|
||||||
iuobj->buf_len = 0;
|
|
||||||
iuobj->buf = NULL;
|
|
||||||
#ifdef ICONV_THREAD_SAFE
|
#ifdef ICONV_THREAD_SAFE
|
||||||
DosCreateMutexSem( NULL, &iuobj->hMtx, 0, FALSE );
|
DosCreateMutexSem(NULL, &iuobj->hMtx, 0, FALSE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return iuobj;
|
return iuobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern size_t _System os2_iconv(iconv_t cd, char* * inbuf,
|
extern size_t _System os2_iconv(iconv_t cd, char* * inbuf,
|
||||||
size_t *inbytesleft,
|
size_t *inbytesleft,
|
||||||
char* * outbuf, size_t *outbytesleft)
|
char* * outbuf, size_t *outbytesleft)
|
||||||
{
|
{
|
||||||
UconvObject uo_tocode = ((iuconv_obj *)(cd))->uo_tocode;
|
UconvObject uo_tocode = ((iuconv_obj *)(cd))->uo_tocode;
|
||||||
UconvObject uo_fromcode = ((iuconv_obj *)(cd))->uo_fromcode;
|
UconvObject uo_fromcode = ((iuconv_obj *)(cd))->uo_fromcode;
|
||||||
size_t nonIdenticalConv = 0;
|
size_t nonIdenticalConv = 0;
|
||||||
UniChar *uc_buf;
|
UniChar *uc_buf;
|
||||||
size_t uc_buf_len;
|
size_t uc_buf_len;
|
||||||
UniChar **uc_str;
|
UniChar **uc_str;
|
||||||
size_t *uc_str_len;
|
size_t *uc_str_len;
|
||||||
int rc;
|
int rc;
|
||||||
size_t ret = (size_t)(-1);
|
size_t ret = (size_t)(-1);
|
||||||
|
|
||||||
if ( uo_tocode == NULL && uo_fromcode == NULL )
|
if (uo_tocode == NULL && uo_fromcode == NULL) {
|
||||||
{
|
uc_buf_len = min(*inbytesleft, *outbytesleft);
|
||||||
uc_buf_len = min( *inbytesleft, *outbytesleft );
|
memcpy(*outbuf, *inbuf, uc_buf_len);
|
||||||
memcpy( *outbuf, *inbuf, uc_buf_len );
|
*inbytesleft -= uc_buf_len;
|
||||||
*inbytesleft -= uc_buf_len;
|
*outbytesleft -= uc_buf_len;
|
||||||
*outbytesleft -= uc_buf_len;
|
outbuf += uc_buf_len;
|
||||||
outbuf += uc_buf_len;
|
inbuf += uc_buf_len;
|
||||||
inbuf += uc_buf_len;
|
return uc_buf_len;
|
||||||
return uc_buf_len;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ICONV_THREAD_SAFE
|
#ifdef ICONV_THREAD_SAFE
|
||||||
DosRequestMutexSem( ((iuconv_obj *)(cd))->hMtx, SEM_INDEFINITE_WAIT );
|
DosRequestMutexSem(((iuconv_obj *)(cd))->hMtx, SEM_INDEFINITE_WAIT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( uo_tocode && uo_fromcode &&
|
if (uo_tocode && uo_fromcode &&
|
||||||
(( ((iuconv_obj *)(cd))->buf_len >> 1 ) < (*inbytesleft)) )
|
(((iuconv_obj *)cd)->buf_len >> 1) < *inbytesleft) {
|
||||||
{
|
if (((iuconv_obj *)cd)->buf != NULL)
|
||||||
if ( ( ((iuconv_obj *)(cd))->buf ) != NULL )
|
free(((iuconv_obj *)cd)->buf);
|
||||||
free( ((iuconv_obj *)(cd))->buf );
|
((iuconv_obj *)cd)->buf_len = *inbytesleft << 1;
|
||||||
((iuconv_obj *)(cd))->buf_len = *inbytesleft << 1;
|
((iuconv_obj *)cd)->buf = (UniChar *)malloc(((iuconv_obj *)cd)->buf_len);
|
||||||
((iuconv_obj *)(cd))->buf = (UniChar *)malloc( ((iuconv_obj *)(cd))->buf_len );
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ( uo_fromcode )
|
if (uo_fromcode) {
|
||||||
{
|
if (uo_tocode) {
|
||||||
if ( uo_tocode )
|
uc_buf = ((iuconv_obj *)cd)->buf;
|
||||||
{
|
uc_buf_len = ((iuconv_obj *)cd)->buf_len;
|
||||||
uc_buf = ((iuconv_obj *)(cd))->buf;
|
uc_str = &uc_buf;
|
||||||
uc_buf_len = ((iuconv_obj *)(cd))->buf_len;
|
} else {
|
||||||
uc_str = &uc_buf;
|
uc_str = (UniChar **)outbuf;
|
||||||
}
|
uc_buf_len = *outbytesleft;
|
||||||
else {
|
}
|
||||||
uc_str = (UniChar **)outbuf;
|
uc_buf_len = uc_buf_len >> 1;
|
||||||
uc_buf_len = *outbytesleft;
|
uc_str_len = &uc_buf_len;
|
||||||
}
|
rc = UniUconvToUcs(uo_fromcode, (void **)inbuf, inbytesleft,
|
||||||
uc_buf_len = uc_buf_len >> 1;
|
uc_str, uc_str_len, &nonIdenticalConv);
|
||||||
uc_str_len = &uc_buf_len;
|
uc_buf_len = uc_buf_len << 1;
|
||||||
rc = UniUconvToUcs( uo_fromcode, (void **)inbuf, inbytesleft,
|
if (!uo_tocode)
|
||||||
uc_str, uc_str_len, &nonIdenticalConv );
|
*outbytesleft = uc_buf_len;
|
||||||
uc_buf_len = uc_buf_len << 1;
|
|
||||||
if ( !uo_tocode )
|
|
||||||
*outbytesleft = uc_buf_len;
|
|
||||||
|
|
||||||
if ( rc != ULS_SUCCESS )
|
if (rc != ULS_SUCCESS) {
|
||||||
{
|
errno = EILSEQ;
|
||||||
errno = EILSEQ;
|
goto done;
|
||||||
goto done;
|
} else if (*inbytesleft && !*uc_str_len) {
|
||||||
|
errno = E2BIG;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uo_tocode)
|
||||||
|
return nonIdenticalConv;
|
||||||
|
|
||||||
|
uc_buf = ((iuconv_obj *)cd)->buf;
|
||||||
|
uc_buf_len = ((iuconv_obj *)cd)->buf_len - uc_buf_len;
|
||||||
|
uc_str = &uc_buf;
|
||||||
|
uc_str_len = &uc_buf_len;
|
||||||
|
} else {
|
||||||
|
uc_str = (UniChar **)inbuf;
|
||||||
|
uc_str_len = inbytesleft;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if ( *inbytesleft && !*uc_str_len )
|
*uc_str_len = *uc_str_len>>1;
|
||||||
{
|
rc = UniUconvFromUcs(uo_tocode, uc_str, uc_str_len, (void **)outbuf,
|
||||||
|
outbytesleft, &nonIdenticalConv);
|
||||||
|
if (rc != ULS_SUCCESS) {
|
||||||
|
switch (rc) {
|
||||||
|
case ULS_BUFFERFULL:
|
||||||
|
errno = E2BIG;
|
||||||
|
break;
|
||||||
|
case ULS_ILLEGALSEQUENCE:
|
||||||
|
errno = EILSEQ;
|
||||||
|
break;
|
||||||
|
case ULS_INVALID:
|
||||||
|
errno = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
} else if (*uc_str_len && !*outbytesleft) {
|
||||||
errno = E2BIG;
|
errno = E2BIG;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
if ( !uo_tocode )
|
|
||||||
return nonIdenticalConv;
|
|
||||||
|
|
||||||
uc_buf = ((iuconv_obj *)(cd))->buf;
|
|
||||||
uc_buf_len = ((iuconv_obj *)(cd))->buf_len - uc_buf_len;
|
|
||||||
uc_str = &uc_buf;
|
|
||||||
uc_str_len = &uc_buf_len;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uc_str = (UniChar **)inbuf;
|
|
||||||
uc_str_len = inbytesleft;
|
|
||||||
}
|
|
||||||
|
|
||||||
*uc_str_len = *uc_str_len>>1;
|
|
||||||
rc = UniUconvFromUcs( uo_tocode, uc_str, uc_str_len, (void **)outbuf,
|
|
||||||
outbytesleft, &nonIdenticalConv );
|
|
||||||
if ( rc != ULS_SUCCESS )
|
|
||||||
{
|
|
||||||
switch ( rc )
|
|
||||||
{
|
|
||||||
case ULS_BUFFERFULL:
|
|
||||||
errno = E2BIG;
|
|
||||||
break;
|
|
||||||
case ULS_ILLEGALSEQUENCE:
|
|
||||||
errno = EILSEQ;
|
|
||||||
break;
|
|
||||||
case ULS_INVALID:
|
|
||||||
errno = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if ( *uc_str_len && !*outbytesleft )
|
|
||||||
{
|
|
||||||
errno = E2BIG;
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = nonIdenticalConv;
|
ret = nonIdenticalConv;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
#ifdef ICONV_THREAD_SAFE
|
#ifdef ICONV_THREAD_SAFE
|
||||||
DosReleaseMutexSem( ((iuconv_obj *)(cd))->hMtx );
|
DosReleaseMutexSem(((iuconv_obj *)cd)->hMtx);
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int _System os2_iconv_close(iconv_t cd)
|
int _System os2_iconv_close(iconv_t cd)
|
||||||
{
|
{
|
||||||
if ( !cd )
|
if (!cd) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
#ifdef ICONV_THREAD_SAFE
|
#ifdef ICONV_THREAD_SAFE
|
||||||
DosCloseMutexSem( ((iuconv_obj *)(cd))->hMtx );
|
DosCloseMutexSem(((iuconv_obj *)cd)->hMtx);
|
||||||
#endif
|
#endif
|
||||||
if ( ((iuconv_obj *)(cd))->uo_tocode != NULL )
|
if (((iuconv_obj *)cd)->uo_tocode != NULL)
|
||||||
UniFreeUconvObject( ((iuconv_obj *)(cd))->uo_tocode );
|
UniFreeUconvObject(((iuconv_obj *)cd)->uo_tocode);
|
||||||
if ( ((iuconv_obj *)(cd))->uo_fromcode != NULL )
|
if (((iuconv_obj *)cd)->uo_fromcode != NULL)
|
||||||
UniFreeUconvObject( ((iuconv_obj *)(cd))->uo_fromcode );
|
UniFreeUconvObject(((iuconv_obj *)cd)->uo_fromcode);
|
||||||
|
|
||||||
if ( ( ((iuconv_obj *)(cd))->buf ) != NULL )
|
if (((iuconv_obj *)cd)->buf != NULL)
|
||||||
free( ((iuconv_obj *)(cd))->buf );
|
free(((iuconv_obj *)cd)->buf);
|
||||||
|
|
||||||
free(cd);
|
free(cd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -24,94 +24,84 @@
|
||||||
|
|
||||||
int StrUTF8(int fToUTF8, char *pcDst, int cbDst, char *pcSrc, int cbSrc)
|
int StrUTF8(int fToUTF8, char *pcDst, int cbDst, char *pcSrc, int cbSrc)
|
||||||
{
|
{
|
||||||
size_t rc;
|
size_t rc;
|
||||||
char *pcDstStart = pcDst;
|
char *pcDstStart = pcDst;
|
||||||
iconv_t cd;
|
iconv_t cd;
|
||||||
char *pszToCP, *pszFromCP;
|
char *pszToCP, *pszFromCP;
|
||||||
int fError = 0;
|
int fError = 0;
|
||||||
|
|
||||||
if ( cbDst < 4 )
|
if (cbDst < 4)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ( fToUTF8 )
|
if (fToUTF8) {
|
||||||
{
|
pszToCP = "UTF-8";
|
||||||
pszToCP = "UTF-8";
|
pszFromCP = "";
|
||||||
pszFromCP = "";
|
} else {
|
||||||
}
|
pszToCP = "";
|
||||||
else
|
pszFromCP = "UTF-8";
|
||||||
{
|
|
||||||
pszToCP = "";
|
|
||||||
pszFromCP = "UTF-8";
|
|
||||||
}
|
|
||||||
|
|
||||||
cd = iconv_open( pszToCP, pszFromCP );
|
|
||||||
if ( cd == (iconv_t)-1 )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while( cbSrc > 0 )
|
|
||||||
{
|
|
||||||
rc = iconv( cd, &pcSrc, (size_t *)&cbSrc, &pcDst, (size_t *)&cbDst );
|
|
||||||
if ( rc == (size_t)-1 )
|
|
||||||
{
|
|
||||||
if ( errno == EILSEQ )
|
|
||||||
{
|
|
||||||
// Try to skip invalid character.
|
|
||||||
pcSrc++;
|
|
||||||
cbSrc--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fError = 1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
iconv_close( cd );
|
cd = iconv_open(pszToCP, pszFromCP);
|
||||||
|
if (cd == (iconv_t)-1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
// Write trailing ZERO (1 byte for UTF-8, 2 bytes for the system cp).
|
while (cbSrc > 0) {
|
||||||
if ( fToUTF8 )
|
rc = iconv(cd, &pcSrc, (size_t *)&cbSrc, &pcDst, (size_t *)&cbDst);
|
||||||
{
|
if (rc == (size_t)-1) {
|
||||||
if ( cbDst < 1 )
|
if (errno == EILSEQ) {
|
||||||
{
|
/* Try to skip invalid character */
|
||||||
pcDst--;
|
pcSrc++;
|
||||||
fError = 1; // The destination buffer overflow.
|
cbSrc--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fError = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*pcDst = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( cbDst < 2 )
|
|
||||||
{
|
|
||||||
pcDst -= ( cbDst == 0 ) ? 2 : 1;
|
|
||||||
fError = 1; // The destination buffer overflow.
|
|
||||||
}
|
|
||||||
*((short *)pcDst) = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return fError ? -1 : ( pcDst - pcDstStart );
|
iconv_close(cd);
|
||||||
|
|
||||||
|
/* Write trailing ZERO (1 byte for UTF-8, 2 bytes for the system cp) */
|
||||||
|
if (fToUTF8) {
|
||||||
|
if (cbDst < 1) {
|
||||||
|
pcDst--;
|
||||||
|
fError = 1; /* The destination buffer overflow */
|
||||||
|
}
|
||||||
|
*pcDst = '\0';
|
||||||
|
} else {
|
||||||
|
if (cbDst < 2) {
|
||||||
|
pcDst -= (cbDst == 0)? 2 : 1;
|
||||||
|
fError = 1; /* The destination buffer overflow */
|
||||||
|
}
|
||||||
|
*((short *)pcDst) = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fError) ? -1 : (pcDst - pcDstStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *StrUTF8New(int fToUTF8, char *pcStr, int cbStr)
|
char *StrUTF8New(int fToUTF8, char *pcStr, int cbStr)
|
||||||
{
|
{
|
||||||
int cbNewStr = ( ( cbStr > 4 ? cbStr : 4 ) + 1 ) * 2;
|
int cbNewStr = (((cbStr > 4)? cbStr : 4) + 1) * 2;
|
||||||
char *pszNewStr = malloc( cbNewStr );
|
char *pszNewStr = malloc(cbNewStr);
|
||||||
|
|
||||||
if ( pszNewStr == NULL )
|
if (pszNewStr == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cbNewStr = StrUTF8(fToUTF8, pszNewStr, cbNewStr, pcStr, cbStr);
|
||||||
|
if (cbNewStr != -1) {
|
||||||
|
pcStr = realloc(pszNewStr, cbNewStr + ((fToUTF8)? 1 : sizeof(short)));
|
||||||
|
if (pcStr != NULL)
|
||||||
|
return pcStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pszNewStr);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cbNewStr = StrUTF8( fToUTF8, pszNewStr, cbNewStr, pcStr, cbStr );
|
|
||||||
if ( cbNewStr != -1 )
|
|
||||||
{
|
|
||||||
pcStr = realloc( pszNewStr, cbNewStr + ( fToUTF8 ? 1 : sizeof(short) ) );
|
|
||||||
if ( pcStr != NULL )
|
|
||||||
return pcStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
free( pszNewStr );
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StrUTF8Free(char *pszStr)
|
void StrUTF8Free(char *pszStr)
|
||||||
{
|
{
|
||||||
free( pszStr );
|
free(pszStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -26,43 +26,44 @@
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
char acBuf[128];
|
char acBuf[128];
|
||||||
char *inbuf = "ôÅÓÔ - ÐÒÏ×ÅÒËÁ"; // KOI8-R string.
|
char *inbuf = "ôÅÓÔ - ÐÒÏ×ÅÒËÁ"; /* KOI8-R string */
|
||||||
size_t inbytesleft = strlen( inbuf );
|
size_t inbytesleft = strlen(inbuf);
|
||||||
char *outbuf = &acBuf;
|
char *outbuf = acBuf;
|
||||||
size_t outbytesleft = sizeof( acBuf );
|
size_t outbytesleft = sizeof(acBuf);
|
||||||
iconv_t ic;
|
iconv_t ic;
|
||||||
|
|
||||||
// KOI8 -> system cp.
|
/* KOI8 -> system cp */
|
||||||
|
ic = iconv_open("", "KOI8-R");
|
||||||
|
if (ic == (iconv_t)(-1)) {
|
||||||
|
puts("iconv_open() fail");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
ic = iconv_open( "", "KOI8-R" );
|
iconv(ic, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
|
||||||
if ( ic == (iconv_t)(-1) )
|
printf("KOI8-R to system cp: %s\n", acBuf);
|
||||||
{
|
|
||||||
puts( "iconv_open() fail" );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
iconv( ic, &inbuf, &inbytesleft, &outbuf, &outbytesleft );
|
iconv_close(ic);
|
||||||
printf( "KOI8-R to system cp.: %s\n", &acBuf );
|
|
||||||
|
|
||||||
iconv_close( ic );
|
/* System cp -> UTF-8 -> system cp: */
|
||||||
|
|
||||||
// System cp. -> UTF-8 -> system cp.
|
/* System cp -> UTF-8 by StrUTF8New() */
|
||||||
|
inbuf = StrUTF8New(1, acBuf, strlen(acBuf));
|
||||||
|
|
||||||
// System cp. -> UTF-8 by StrUTF8New().
|
/* UTF-8 -> system cp. by StrUTF8() */
|
||||||
inbuf = StrUTF8New( 1, &acBuf, strlen( &acBuf ) );
|
if (StrUTF8(0, &acBuf, sizeof(acBuf), inbuf, strlen(inbuf)) == -1) {
|
||||||
|
puts("StrUTF8() failed");
|
||||||
|
} else {
|
||||||
|
printf("system cp. -> UTF-8 -> system cp.: %s\n", &acBuf);
|
||||||
|
}
|
||||||
|
|
||||||
// UTF-8 -> system cp. by StrUTF8().
|
free(inbuf);
|
||||||
if ( StrUTF8( 0, &acBuf, sizeof(acBuf), inbuf, strlen( inbuf ) ) == -1 )
|
|
||||||
puts( "StrUTF8() failed" );
|
|
||||||
else
|
|
||||||
printf( "system cp. -> UTF-8 -> system cp.: %s\n", &acBuf );
|
|
||||||
|
|
||||||
free( inbuf );
|
/* Unload used DLL */
|
||||||
|
iconv_clean();
|
||||||
|
|
||||||
// Unload used DLL.
|
puts("Done.");
|
||||||
iconv_clean();
|
return 0;
|
||||||
|
|
||||||
puts( "Done." );
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -38,90 +38,90 @@
|
||||||
char *
|
char *
|
||||||
SDL_GetBasePath(void)
|
SDL_GetBasePath(void)
|
||||||
{
|
{
|
||||||
PTIB tib;
|
PTIB tib;
|
||||||
PPIB pib;
|
PPIB pib;
|
||||||
ULONG ulRC = DosGetInfoBlocks(&tib, &pib);
|
ULONG ulRC = DosGetInfoBlocks(&tib, &pib);
|
||||||
PCHAR pcEnd;
|
PCHAR pcEnd;
|
||||||
ULONG cbResult;
|
ULONG cbResult;
|
||||||
CHAR acBuf[_MAX_PATH];
|
CHAR acBuf[_MAX_PATH];
|
||||||
|
|
||||||
if (ulRC != NO_ERROR) {
|
if (ulRC != NO_ERROR) {
|
||||||
debug("DosGetInfoBlocks() failed, rc = %u", ulRC);
|
debug_os2("DosGetInfoBlocks() failed, rc = %u", ulRC);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
pcEnd = SDL_strrchr(pib->pib_pchcmd, '\\');
|
|
||||||
if (pcEnd != NULL)
|
|
||||||
pcEnd++;
|
|
||||||
else {
|
|
||||||
if (pib->pib_pchcmd[1] == ':')
|
|
||||||
pcEnd = &pib->pib_pchcmd[2];
|
|
||||||
else {
|
|
||||||
SDL_SetError("No path in pib->pib_pchcmd");
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
cbResult = pcEnd - pib->pib_pchcmd;
|
pcEnd = SDL_strrchr(pib->pib_pchcmd, '\\');
|
||||||
SDL_memcpy(acBuf, pib->pib_pchcmd, cbResult);
|
if (pcEnd != NULL)
|
||||||
acBuf[cbResult] = '\0';
|
pcEnd++;
|
||||||
|
else {
|
||||||
|
if (pib->pib_pchcmd[1] == ':')
|
||||||
|
pcEnd = &pib->pib_pchcmd[2];
|
||||||
|
else {
|
||||||
|
SDL_SetError("No path in pib->pib_pchcmd");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return OS2_SysToUTF8(acBuf);
|
cbResult = pcEnd - pib->pib_pchcmd;
|
||||||
|
SDL_memcpy(acBuf, pib->pib_pchcmd, cbResult);
|
||||||
|
acBuf[cbResult] = '\0';
|
||||||
|
|
||||||
|
return OS2_SysToUTF8(acBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
SDL_GetPrefPath(const char *org, const char *app)
|
SDL_GetPrefPath(const char *org, const char *app)
|
||||||
{
|
{
|
||||||
PSZ pszPath;
|
PSZ pszPath;
|
||||||
CHAR acBuf[_MAX_PATH];
|
CHAR acBuf[_MAX_PATH];
|
||||||
int lPosApp, lPosOrg;
|
int lPosApp, lPosOrg;
|
||||||
PSZ pszApp, pszOrg;
|
PSZ pszApp, pszOrg;
|
||||||
|
|
||||||
if (!app) {
|
if (!app) {
|
||||||
SDL_InvalidParamError("app");
|
SDL_InvalidParamError("app");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pszPath = SDL_getenv( "HOME" );
|
pszPath = SDL_getenv("HOME");
|
||||||
if (!pszPath) {
|
|
||||||
pszPath = SDL_getenv( "ETC" );
|
|
||||||
if (!pszPath) {
|
if (!pszPath) {
|
||||||
SDL_SetError("HOME or ETC environment not set");
|
pszPath = SDL_getenv("ETC");
|
||||||
return NULL;
|
if (!pszPath) {
|
||||||
|
SDL_SetError("HOME or ETC environment not set");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!org) {
|
if (!org) {
|
||||||
lPosApp = SDL_snprintf(acBuf, sizeof(acBuf) - 1, "%s", pszPath);
|
lPosApp = SDL_snprintf(acBuf, sizeof(acBuf) - 1, "%s", pszPath);
|
||||||
} else {
|
} else {
|
||||||
pszOrg = OS2_UTF8ToSys(org);
|
pszOrg = OS2_UTF8ToSys(org);
|
||||||
if (!pszOrg) {
|
if (!pszOrg) {
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
lPosApp = SDL_snprintf(acBuf, sizeof(acBuf) - 1, "%s\\%s", pszPath, pszOrg);
|
||||||
|
SDL_free(pszOrg);
|
||||||
}
|
}
|
||||||
lPosApp = SDL_snprintf(acBuf, sizeof(acBuf) - 1, "%s\\%s", pszPath, pszOrg);
|
if (lPosApp < 0)
|
||||||
SDL_free(pszOrg);
|
return NULL;
|
||||||
}
|
|
||||||
if (lPosApp < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
DosCreateDir(acBuf, NULL);
|
DosCreateDir(acBuf, NULL);
|
||||||
|
|
||||||
pszApp = OS2_UTF8ToSys(app);
|
pszApp = OS2_UTF8ToSys(app);
|
||||||
if (!pszApp) {
|
if (!pszApp) {
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lPosOrg = SDL_snprintf(&acBuf[lPosApp], sizeof(acBuf) - lPosApp - 1, "\\%s", pszApp);
|
lPosOrg = SDL_snprintf(&acBuf[lPosApp], sizeof(acBuf) - lPosApp - 1, "\\%s", pszApp);
|
||||||
SDL_free(pszApp);
|
SDL_free(pszApp);
|
||||||
if (lPosOrg < 0)
|
if (lPosOrg < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
DosCreateDir(acBuf, NULL);
|
DosCreateDir(acBuf, NULL);
|
||||||
*((PUSHORT)&acBuf[lPosApp + lPosOrg]) = (USHORT)'\0\\';
|
*((PUSHORT)&acBuf[lPosApp + lPosOrg]) = (USHORT)'\0\\';
|
||||||
|
|
||||||
return OS2_SysToUTF8(acBuf);
|
return OS2_SysToUTF8(acBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_FILESYSTEM_OS2 */
|
#endif /* SDL_FILESYSTEM_OS2 */
|
||||||
|
|
|
@ -35,41 +35,42 @@
|
||||||
void *
|
void *
|
||||||
SDL_LoadObject(const char *sofile)
|
SDL_LoadObject(const char *sofile)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
HMODULE hModule;
|
HMODULE hModule;
|
||||||
PSZ pszModName = OS2_UTF8ToSys( sofile );
|
PSZ pszModName = OS2_UTF8ToSys(sofile);
|
||||||
CHAR acError[256];
|
CHAR acError[256];
|
||||||
|
|
||||||
ulRC = DosLoadModule(acError, sizeof(acError), pszModName, &hModule);
|
ulRC = DosLoadModule(acError, sizeof(acError), pszModName, &hModule);
|
||||||
SDL_free(pszModName);
|
SDL_free(pszModName);
|
||||||
if (ulRC != NO_ERROR) {
|
if (ulRC != NO_ERROR) {
|
||||||
SDL_SetError( "Failed loading %s (E%u)", acError, ulRC );
|
SDL_SetError("Failed loading %s (E%u)", acError, ulRC);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (void *)hModule;
|
return (void *)hModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
SDL_LoadFunction(void *handle, const char *name)
|
SDL_LoadFunction(void *handle, const char *name)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
PFN pFN;
|
PFN pFN;
|
||||||
|
|
||||||
ulRC = DosQueryProcAddr((HMODULE)handle, 0, name, &pFN);
|
ulRC = DosQueryProcAddr((HMODULE)handle, 0, name, &pFN);
|
||||||
if (ulRC != NO_ERROR) {
|
if (ulRC != NO_ERROR) {
|
||||||
SDL_SetError( "Failed loading procedure %s (E%u)", name, ulRC );
|
SDL_SetError("Failed loading procedure %s (E%u)", name, ulRC);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (void *)pFN;
|
return (void *)pFN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SDL_UnloadObject(void *handle)
|
SDL_UnloadObject(void *handle)
|
||||||
{
|
{
|
||||||
if (handle != NULL)
|
if (handle != NULL) {
|
||||||
DosFreeModule( (HMODULE)handle );
|
DosFreeModule((HMODULE)handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_LOADSO_OS2 */
|
#endif /* SDL_LOADSO_OS2 */
|
||||||
|
|
|
@ -32,99 +32,96 @@
|
||||||
#define INCL_DOSERRORS
|
#define INCL_DOSERRORS
|
||||||
#include <os2.h>
|
#include <os2.h>
|
||||||
|
|
||||||
struct SDL_mutex
|
struct SDL_mutex {
|
||||||
{
|
HMTX _handle;
|
||||||
ULONG ulHandle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Create a mutex */
|
/* Create a mutex */
|
||||||
SDL_mutex *
|
SDL_mutex *
|
||||||
SDL_CreateMutex(void)
|
SDL_CreateMutex(void)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
HMTX hMtx;
|
HMTX hMtx;
|
||||||
|
|
||||||
ulRC = DosCreateMutexSem( NULL, &hMtx, 0, FALSE );
|
ulRC = DosCreateMutexSem(NULL, &hMtx, 0, FALSE);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug_os2("DosCreateMutexSem(), rc = %u", ulRC);
|
||||||
debug( "DosCreateMutexSem(), rc = %u", ulRC );
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return (SDL_mutex *)hMtx;
|
return (SDL_mutex *)hMtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the mutex */
|
/* Free the mutex */
|
||||||
void
|
void
|
||||||
SDL_DestroyMutex(SDL_mutex * mutex)
|
SDL_DestroyMutex(SDL_mutex * mutex)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
HMTX hMtx = (HMTX)mutex;
|
HMTX hMtx = (HMTX)mutex;
|
||||||
|
|
||||||
ulRC = DosCloseMutexSem( hMtx );
|
ulRC = DosCloseMutexSem(hMtx);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
debug( "DosCloseMutexSem(), rc = %u", ulRC );
|
debug_os2("DosCloseMutexSem(), rc = %u", ulRC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock the mutex */
|
/* Lock the mutex */
|
||||||
int
|
int
|
||||||
SDL_LockMutex(SDL_mutex * mutex)
|
SDL_LockMutex(SDL_mutex * mutex)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
HMTX hMtx = (HMTX)mutex;
|
HMTX hMtx = (HMTX)mutex;
|
||||||
|
|
||||||
if ( hMtx == NULLHANDLE )
|
if (hMtx == NULLHANDLE)
|
||||||
return SDL_SetError( "Passed a NULL mutex" );
|
return SDL_SetError("Passed a NULL mutex");
|
||||||
|
|
||||||
ulRC = DosRequestMutexSem( hMtx, SEM_INDEFINITE_WAIT );
|
ulRC = DosRequestMutexSem(hMtx, SEM_INDEFINITE_WAIT);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug_os2("DosRequestMutexSem(), rc = %u", ulRC);
|
||||||
debug( "DosRequestMutexSem(), rc = %u", ulRC );
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try Lock the mutex */
|
/* try Lock the mutex */
|
||||||
int
|
int
|
||||||
SDL_TryLockMutex(SDL_mutex * mutex)
|
SDL_TryLockMutex(SDL_mutex * mutex)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
HMTX hMtx = (HMTX)mutex;
|
HMTX hMtx = (HMTX)mutex;
|
||||||
|
|
||||||
if ( hMtx == NULLHANDLE )
|
if (hMtx == NULLHANDLE)
|
||||||
return SDL_SetError( "Passed a NULL mutex" );
|
return SDL_SetError("Passed a NULL mutex");
|
||||||
|
|
||||||
ulRC = DosRequestMutexSem( hMtx, SEM_IMMEDIATE_RETURN );
|
ulRC = DosRequestMutexSem(hMtx, SEM_IMMEDIATE_RETURN);
|
||||||
|
|
||||||
if ( ulRC == ERROR_TIMEOUT )
|
if (ulRC == ERROR_TIMEOUT)
|
||||||
return SDL_MUTEX_TIMEDOUT;
|
return SDL_MUTEX_TIMEDOUT;
|
||||||
|
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug_os2("DosRequestMutexSem(), rc = %u", ulRC);
|
||||||
debug( "DosRequestMutexSem(), rc = %u", ulRC );
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
int
|
int
|
||||||
SDL_UnlockMutex(SDL_mutex * mutex)
|
SDL_UnlockMutex(SDL_mutex * mutex)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
HMTX hMtx = (HMTX)mutex;
|
HMTX hMtx = (HMTX)mutex;
|
||||||
|
|
||||||
if ( hMtx == NULLHANDLE )
|
if (hMtx == NULLHANDLE)
|
||||||
return SDL_SetError( "Passed a NULL mutex" );
|
return SDL_SetError("Passed a NULL mutex");
|
||||||
|
|
||||||
ulRC = DosReleaseMutexSem( hMtx );
|
ulRC = DosReleaseMutexSem(hMtx);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR)
|
||||||
return SDL_SetError( "DosReleaseMutexSem(), rc = %u", ulRC );
|
return SDL_SetError("DosReleaseMutexSem(), rc = %u", ulRC);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_THREAD_OS2 */
|
#endif /* SDL_THREAD_OS2 */
|
||||||
|
|
|
@ -33,162 +33,156 @@
|
||||||
#include <os2.h>
|
#include <os2.h>
|
||||||
|
|
||||||
struct SDL_semaphore {
|
struct SDL_semaphore {
|
||||||
HEV hEv;
|
HEV hEv;
|
||||||
HMTX hMtx;
|
HMTX hMtx;
|
||||||
ULONG cPost;
|
ULONG cPost;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
SDL_sem *
|
SDL_sem *
|
||||||
SDL_CreateSemaphore(Uint32 initial_value)
|
SDL_CreateSemaphore(Uint32 initial_value)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
SDL_sem *pSDLSem = SDL_malloc( sizeof(SDL_sem) );
|
SDL_sem *pSDLSem = SDL_malloc(sizeof(SDL_sem));
|
||||||
|
|
||||||
if ( pSDLSem == NULL )
|
if (pSDLSem == NULL) {
|
||||||
{
|
SDL_OutOfMemory();
|
||||||
SDL_OutOfMemory();
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ulRC = DosCreateEventSem( NULL, &pSDLSem->hEv, DCE_AUTORESET, FALSE );
|
ulRC = DosCreateEventSem(NULL, &pSDLSem->hEv, DCE_AUTORESET, FALSE);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug_os2("DosCreateEventSem(), rc = %u", ulRC);
|
||||||
debug( "DosCreateEventSem(), rc = %u", ulRC );
|
SDL_free(pSDLSem);
|
||||||
SDL_free( pSDLSem );
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ulRC = DosCreateMutexSem( NULL, &pSDLSem->hMtx, 0, FALSE );
|
ulRC = DosCreateMutexSem(NULL, &pSDLSem->hMtx, 0, FALSE);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug_os2("DosCreateMutexSem(), rc = %u", ulRC);
|
||||||
debug( "DosCreateMutexSem(), rc = %u", ulRC );
|
DosCloseEventSem(pSDLSem->hEv);
|
||||||
DosCloseEventSem( pSDLSem->hEv );
|
SDL_free(pSDLSem);
|
||||||
SDL_free( pSDLSem );
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pSDLSem->cPost = initial_value;
|
pSDLSem->cPost = initial_value;
|
||||||
|
|
||||||
return pSDLSem;
|
return pSDLSem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SDL_DestroySemaphore(SDL_sem * sem)
|
SDL_DestroySemaphore(SDL_sem * sem)
|
||||||
{
|
{
|
||||||
if ( sem == NULL )
|
if (!sem) return;
|
||||||
return;
|
|
||||||
|
|
||||||
DosCloseMutexSem( sem->hMtx );
|
DosCloseMutexSem(sem->hMtx);
|
||||||
DosCloseEventSem( sem->hEv );
|
DosCloseEventSem(sem->hEv);
|
||||||
SDL_free( sem );
|
SDL_free(sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
|
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
ULONG ulStartTime, ulCurTime;
|
ULONG ulStartTime, ulCurTime;
|
||||||
ULONG ulTimeout;
|
ULONG ulTimeout;
|
||||||
ULONG cPost;
|
ULONG cPost;
|
||||||
|
|
||||||
if ( sem == NULL )
|
if (sem == NULL)
|
||||||
return SDL_SetError( "Passed a NULL sem" );
|
return SDL_SetError("Passed a NULL sem");
|
||||||
|
|
||||||
if ( timeout != SEM_INDEFINITE_WAIT )
|
if (timeout != SEM_INDEFINITE_WAIT)
|
||||||
DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &ulStartTime, sizeof(ULONG) );
|
DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulStartTime, sizeof(ULONG));
|
||||||
|
|
||||||
while( TRUE )
|
while (TRUE) {
|
||||||
{
|
ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT);
|
||||||
ulRC = DosRequestMutexSem( sem->hMtx, SEM_INDEFINITE_WAIT );
|
if (ulRC != NO_ERROR)
|
||||||
if ( ulRC != NO_ERROR )
|
return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC);
|
||||||
return SDL_SetError( "DosRequestMutexSem() failed, rc = %u", ulRC );
|
|
||||||
|
|
||||||
cPost = sem->cPost;
|
|
||||||
if ( sem->cPost != 0 )
|
|
||||||
sem->cPost--;
|
|
||||||
|
|
||||||
DosReleaseMutexSem( sem->hMtx );
|
cPost = sem->cPost;
|
||||||
|
if (sem->cPost != 0)
|
||||||
|
sem->cPost--;
|
||||||
|
|
||||||
if ( cPost != 0 )
|
DosReleaseMutexSem(sem->hMtx);
|
||||||
break;
|
|
||||||
|
|
||||||
if ( timeout == SEM_INDEFINITE_WAIT )
|
if (cPost != 0)
|
||||||
ulTimeout = SEM_INDEFINITE_WAIT;
|
break;
|
||||||
else
|
|
||||||
{
|
if (timeout == SEM_INDEFINITE_WAIT)
|
||||||
DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &ulCurTime, sizeof(ULONG) );
|
ulTimeout = SEM_INDEFINITE_WAIT;
|
||||||
ulTimeout = ulCurTime - ulStartTime;
|
else {
|
||||||
if ( timeout < ulTimeout )
|
DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulCurTime, sizeof(ULONG));
|
||||||
return SDL_MUTEX_TIMEDOUT;
|
ulTimeout = ulCurTime - ulStartTime;
|
||||||
ulTimeout = timeout - ulTimeout;
|
if (timeout < ulTimeout)
|
||||||
|
return SDL_MUTEX_TIMEDOUT;
|
||||||
|
ulTimeout = timeout - ulTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulRC = DosWaitEventSem(sem->hEv, ulTimeout);
|
||||||
|
if (ulRC == ERROR_TIMEOUT)
|
||||||
|
return SDL_MUTEX_TIMEDOUT;
|
||||||
|
|
||||||
|
if (ulRC != NO_ERROR)
|
||||||
|
return SDL_SetError("DosWaitEventSem() failed, rc = %u", ulRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
ulRC = DosWaitEventSem( sem->hEv, ulTimeout );
|
return 0;
|
||||||
if ( ulRC == ERROR_TIMEOUT )
|
|
||||||
return SDL_MUTEX_TIMEDOUT;
|
|
||||||
|
|
||||||
if ( ulRC != NO_ERROR )
|
|
||||||
return SDL_SetError( "DosWaitEventSem() failed, rc = %u", ulRC );
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SDL_SemTryWait(SDL_sem * sem)
|
SDL_SemTryWait(SDL_sem * sem)
|
||||||
{
|
{
|
||||||
return SDL_SemWaitTimeout( sem, 0 );
|
return SDL_SemWaitTimeout(sem, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SDL_SemWait(SDL_sem * sem)
|
SDL_SemWait(SDL_sem * sem)
|
||||||
{
|
{
|
||||||
return SDL_SemWaitTimeout( sem, SDL_MUTEX_MAXWAIT );
|
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint32
|
Uint32
|
||||||
SDL_SemValue(SDL_sem * sem)
|
SDL_SemValue(SDL_sem * sem)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( sem == NULL )
|
if (sem == NULL) {
|
||||||
{
|
SDL_SetError("Passed a NULL sem");
|
||||||
SDL_SetError( "Passed a NULL sem" );
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ulRC = DosRequestMutexSem( sem->hMtx, SEM_INDEFINITE_WAIT );
|
ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR)
|
||||||
return SDL_SetError( "DosRequestMutexSem() failed, rc = %u", ulRC );
|
return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC);
|
||||||
|
|
||||||
ulRC = sem->cPost;
|
ulRC = sem->cPost;
|
||||||
DosReleaseMutexSem( sem->hMtx );
|
DosReleaseMutexSem(sem->hMtx);
|
||||||
|
|
||||||
return ulRC;
|
return ulRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SDL_SemPost(SDL_sem * sem)
|
SDL_SemPost(SDL_sem * sem)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( sem == NULL )
|
if (sem == NULL)
|
||||||
return SDL_SetError( "Passed a NULL sem" );
|
return SDL_SetError("Passed a NULL sem");
|
||||||
|
|
||||||
ulRC = DosRequestMutexSem( sem->hMtx, SEM_INDEFINITE_WAIT );
|
ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR)
|
||||||
return SDL_SetError( "DosRequestMutexSem() failed, rc = %u", ulRC );
|
return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC);
|
||||||
|
|
||||||
sem->cPost++;
|
sem->cPost++;
|
||||||
|
|
||||||
ulRC = DosPostEventSem( sem->hEv );
|
ulRC = DosPostEventSem(sem->hEv);
|
||||||
if ( ( ulRC != NO_ERROR ) && ( ulRC != ERROR_ALREADY_POSTED ) )
|
if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
|
||||||
debug( "DosPostEventSem() failed, rc = %u", ulRC );
|
debug_os2("DosPostEventSem() failed, rc = %u", ulRC);
|
||||||
|
}
|
||||||
|
|
||||||
DosReleaseMutexSem( sem->hMtx );
|
DosReleaseMutexSem(sem->hMtx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_THREAD_OS2 */
|
#endif /* SDL_THREAD_OS2 */
|
||||||
|
|
|
@ -42,16 +42,16 @@
|
||||||
|
|
||||||
static void RunThread(void *data)
|
static void RunThread(void *data)
|
||||||
{
|
{
|
||||||
SDL_Thread *thread = (SDL_Thread *) data;
|
SDL_Thread *thread = (SDL_Thread *) data;
|
||||||
pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc;
|
pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc;
|
||||||
|
|
||||||
if ( ppSDLTLSData != NULL )
|
if (ppSDLTLSData != NULL)
|
||||||
*ppSDLTLSData = NULL;
|
*ppSDLTLSData = NULL;
|
||||||
|
|
||||||
SDL_RunThread( thread );
|
SDL_RunThread(thread);
|
||||||
|
|
||||||
if ( pfnEndThread != NULL )
|
if (pfnEndThread != NULL)
|
||||||
pfnEndThread();
|
pfnEndThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -59,73 +59,73 @@ SDL_SYS_CreateThread(SDL_Thread * thread,
|
||||||
pfnSDL_CurrentBeginThread pfnBeginThread,
|
pfnSDL_CurrentBeginThread pfnBeginThread,
|
||||||
pfnSDL_CurrentEndThread pfnEndThread)
|
pfnSDL_CurrentEndThread pfnEndThread)
|
||||||
{
|
{
|
||||||
if (thread->stacksize == 0)
|
if (thread->stacksize == 0)
|
||||||
thread->stacksize = 65536;
|
thread->stacksize = 65536;
|
||||||
|
|
||||||
if (pfnBeginThread) {
|
if (pfnBeginThread) {
|
||||||
// Save the function which we will have to call to clear the RTL of calling app!
|
/* Save the function which we will have to call to clear the RTL of calling app! */
|
||||||
thread->endfunc = pfnEndThread;
|
thread->endfunc = pfnEndThread;
|
||||||
// Start the thread using the runtime library of calling app!
|
/* Start the thread using the runtime library of calling app! */
|
||||||
thread->handle = (SYS_ThreadHandle)
|
thread->handle = (SYS_ThreadHandle)
|
||||||
pfnBeginThread( RunThread, NULL, thread->stacksize, thread );
|
pfnBeginThread(RunThread, NULL, thread->stacksize, thread);
|
||||||
}
|
} else {
|
||||||
else {
|
thread->endfunc = _endthread;
|
||||||
thread->endfunc = _endthread;
|
thread->handle = (SYS_ThreadHandle)
|
||||||
thread->handle = (SYS_ThreadHandle)
|
_beginthread(RunThread, NULL, thread->stacksize, thread);
|
||||||
_beginthread( RunThread, NULL, thread->stacksize, thread );
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ( thread->handle == -1 )
|
if (thread->handle == -1)
|
||||||
return SDL_SetError( "Not enough resources to create thread" );
|
return SDL_SetError("Not enough resources to create thread");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SDL_SYS_SetupThread(const char *name)
|
SDL_SYS_SetupThread(const char *name)
|
||||||
{
|
{
|
||||||
return;
|
/* nothing. */
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_threadID
|
SDL_threadID
|
||||||
SDL_ThreadID(void)
|
SDL_ThreadID(void)
|
||||||
{
|
{
|
||||||
PTIB tib;
|
PTIB tib;
|
||||||
PPIB pib;
|
PPIB pib;
|
||||||
|
|
||||||
DosGetInfoBlocks( &tib, &pib );
|
DosGetInfoBlocks(&tib, &pib);
|
||||||
return tib->tib_ptib2->tib2_ultid;
|
return tib->tib_ptib2->tib2_ultid;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
|
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
ulRC = DosSetPriority( PRTYS_THREAD,
|
ulRC = DosSetPriority(PRTYS_THREAD,
|
||||||
(priority < SDL_THREAD_PRIORITY_NORMAL)? PRTYC_IDLETIME :
|
(priority < SDL_THREAD_PRIORITY_NORMAL)? PRTYC_IDLETIME :
|
||||||
(priority > SDL_THREAD_PRIORITY_NORMAL)? PRTYC_TIMECRITICAL :
|
(priority > SDL_THREAD_PRIORITY_NORMAL)? PRTYC_TIMECRITICAL :
|
||||||
PRTYC_REGULAR,
|
PRTYC_REGULAR,
|
||||||
0, 0 );
|
0, 0);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR)
|
||||||
return SDL_SetError( "DosSetPriority() failed, rc = %u", ulRC );
|
return SDL_SetError("DosSetPriority() failed, rc = %u", ulRC);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SDL_SYS_WaitThread(SDL_Thread * thread)
|
SDL_SYS_WaitThread(SDL_Thread * thread)
|
||||||
{
|
{
|
||||||
ULONG ulRC = DosWaitThread( (PTID)&thread->handle, DCWW_WAIT );
|
ULONG ulRC = DosWaitThread((PTID)&thread->handle, DCWW_WAIT);
|
||||||
|
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
debug( "DosWaitThread() failed, rc = %u", ulRC );
|
debug_os2("DosWaitThread() failed, rc = %u", ulRC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SDL_SYS_DetachThread(SDL_Thread * thread)
|
SDL_SYS_DetachThread(SDL_Thread * thread)
|
||||||
{
|
{
|
||||||
/* nothing. */
|
/* nothing. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_THREAD_OS2 */
|
#endif /* SDL_THREAD_OS2 */
|
||||||
|
|
|
@ -32,56 +32,56 @@
|
||||||
#define INCL_DOSERRORS
|
#define INCL_DOSERRORS
|
||||||
#include <os2.h>
|
#include <os2.h>
|
||||||
|
|
||||||
SDL_TLSData **ppSDLTLSData = NULL;
|
SDL_TLSData **ppSDLTLSData = NULL;
|
||||||
|
|
||||||
static ULONG cTLSAlloc = 0;
|
static ULONG cTLSAlloc = 0;
|
||||||
|
|
||||||
// SDL_OS2TLSAlloc() called from SDL_InitSubSystem()
|
/* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */
|
||||||
void SDL_OS2TLSAlloc()
|
void SDL_OS2TLSAlloc(void)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( ( cTLSAlloc == 0 ) || ( ppSDLTLSData == NULL ) )
|
if (cTLSAlloc == 0 || ppSDLTLSData == NULL) {
|
||||||
{
|
/* First call - allocate the thread local memory (1 DWORD) */
|
||||||
// First call - allocate the thread local memory (1 DWORD).
|
ulRC = DosAllocThreadLocalMemory(1, (PULONG *)&ppSDLTLSData);
|
||||||
ulRC = DosAllocThreadLocalMemory( 1, (PULONG *)&ppSDLTLSData );
|
if (ulRC != NO_ERROR) {
|
||||||
if ( ulRC != NO_ERROR )
|
debug_os2("DosAllocThreadLocalMemory() failed, rc = %u", ulRC);
|
||||||
debug( "DosAllocThreadLocalMemory() failed, rc = %u", ulRC );
|
}
|
||||||
}
|
}
|
||||||
cTLSAlloc++;
|
cTLSAlloc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SDL_OS2TLSFree() called from SDL_QuitSubSystem()
|
/* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */
|
||||||
void SDL_OS2TLSFree()
|
void SDL_OS2TLSFree(void)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( cTLSAlloc != 0 )
|
if (cTLSAlloc != 0)
|
||||||
cTLSAlloc--;
|
cTLSAlloc--;
|
||||||
|
|
||||||
if ( ( cTLSAlloc == 0 ) && ( ppSDLTLSData != NULL ) )
|
if (cTLSAlloc == 0 && ppSDLTLSData != NULL) {
|
||||||
{
|
/* Last call - free the thread local memory */
|
||||||
// Last call - free the thread local memory.
|
ulRC = DosFreeThreadLocalMemory((PULONG)ppSDLTLSData);
|
||||||
ulRC = DosFreeThreadLocalMemory( (PULONG)ppSDLTLSData );
|
if (ulRC != NO_ERROR) {
|
||||||
if ( ulRC != NO_ERROR )
|
debug_os2("DosFreeThreadLocalMemory() failed, rc = %u", ulRC);
|
||||||
debug( "DosFreeThreadLocalMemory() failed, rc = %u", ulRC );
|
} else {
|
||||||
else
|
ppSDLTLSData = NULL;
|
||||||
ppSDLTLSData = NULL;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_TLSData *SDL_SYS_GetTLSData()
|
SDL_TLSData *SDL_SYS_GetTLSData(void)
|
||||||
{
|
{
|
||||||
return ppSDLTLSData == NULL ? NULL : *ppSDLTLSData;
|
return (ppSDLTLSData == NULL)? NULL : *ppSDLTLSData;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SYS_SetTLSData(SDL_TLSData *data)
|
int SDL_SYS_SetTLSData(SDL_TLSData *data)
|
||||||
{
|
{
|
||||||
if ( ppSDLTLSData == NULL )
|
if (!ppSDLTLSData)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*ppSDLTLSData = data;
|
*ppSDLTLSData = data;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_THREAD_OS2 */
|
#endif /* SDL_THREAD_OS2 */
|
||||||
|
|
|
@ -25,13 +25,13 @@
|
||||||
|
|
||||||
#include "../SDL_thread_c.h"
|
#include "../SDL_thread_c.h"
|
||||||
|
|
||||||
extern SDL_TLSData **ppSDLTLSData;
|
extern SDL_TLSData **ppSDLTLSData;
|
||||||
|
|
||||||
// SDL_OS2TLSAlloc() called from SDL_InitSubSystem()
|
/* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */
|
||||||
void SDL_OS2TLSAlloc();
|
void SDL_OS2TLSAlloc(void);
|
||||||
|
|
||||||
// SDL_OS2TLSFree() called from SDL_QuitSubSystem()
|
/* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */
|
||||||
void SDL_OS2TLSFree();
|
void SDL_OS2TLSFree(void);
|
||||||
|
|
||||||
#endif /* SDL_THREAD_OS2 */
|
#endif /* SDL_THREAD_OS2 */
|
||||||
|
|
||||||
|
|
|
@ -34,37 +34,31 @@
|
||||||
#define INCL_DOSEXCEPTIONS
|
#define INCL_DOSEXCEPTIONS
|
||||||
#include <os2.h>
|
#include <os2.h>
|
||||||
|
|
||||||
// No need to switch priorities in SDL_Delay() for OS/2 versions > Warp3 fp 42.
|
/* No need to switch priorities in SDL_Delay() for OS/2 versions > Warp3 fp 42, */
|
||||||
//#define _SWITCH_PRIORITY
|
/*#define _SWITCH_PRIORITY*/
|
||||||
|
|
||||||
typedef unsigned long long ULLONG;
|
typedef unsigned long long ULLONG;
|
||||||
|
|
||||||
static ULONG ulTmrFreq = 0;
|
static ULONG ulTmrFreq = 0;
|
||||||
static ULLONG ullTmrStart;
|
static ULLONG ullTmrStart;
|
||||||
|
|
||||||
void
|
void
|
||||||
SDL_TicksInit(void)
|
SDL_TicksInit(void)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
ulRC = DosTmrQueryFreq( &ulTmrFreq );
|
ulRC = DosTmrQueryFreq(&ulTmrFreq);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug_os2("DosTmrQueryFreq() failed, rc = %u", ulRC);
|
||||||
debug( "DosTmrQueryFreq() failed, rc = %u", ulRC );
|
} else {
|
||||||
}
|
ulRC = DosTmrQueryTime((PQWORD)&ullTmrStart);
|
||||||
else
|
if (ulRC == NO_ERROR)
|
||||||
{
|
return;
|
||||||
ulRC = DosTmrQueryTime( (PQWORD)&ullTmrStart );
|
debug_os2("DosTmrQueryTime() failed, rc = %u", ulRC);
|
||||||
if ( ulRC == NO_ERROR )
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
debug( "DosTmrQueryTime() failed, rc = %u", ulRC );
|
ulTmrFreq = 0; /* Error - use DosQuerySysInfo() for timer. */
|
||||||
}
|
DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, (PULONG)&ullTmrStart, sizeof(ULONG));
|
||||||
|
|
||||||
ulTmrFreq = 0; // Error - use DosQuerySysInfo() for timer.
|
|
||||||
|
|
||||||
DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, (PULONG)&ullTmrStart,
|
|
||||||
sizeof(ULONG) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -75,113 +69,103 @@ SDL_TicksQuit(void)
|
||||||
Uint32
|
Uint32
|
||||||
SDL_GetTicks(void)
|
SDL_GetTicks(void)
|
||||||
{
|
{
|
||||||
ULONG ulResult;
|
ULONG ulResult;
|
||||||
ULLONG ullTmrNow;
|
ULLONG ullTmrNow;
|
||||||
|
|
||||||
if ( ulTmrFreq == 0 )
|
if (ulTmrFreq == 0) /* Was not initialized. */
|
||||||
// Was not initialized.
|
SDL_TicksInit();
|
||||||
SDL_TicksInit();
|
|
||||||
|
|
||||||
if ( ulTmrFreq != 0 )
|
if (ulTmrFreq != 0) {
|
||||||
{
|
DosTmrQueryTime((PQWORD)&ullTmrNow);
|
||||||
DosTmrQueryTime( (PQWORD)&ullTmrNow );
|
ulResult = (ullTmrNow - ullTmrStart) * 1000 / ulTmrFreq;
|
||||||
ulResult = ( ullTmrNow - ullTmrStart ) * 1000 / ulTmrFreq;
|
} else {
|
||||||
}
|
DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, (PULONG)&ullTmrNow, sizeof(ULONG));
|
||||||
else
|
ulResult = (ULONG)ullTmrNow - (ULONG)ullTmrStart;
|
||||||
{
|
}
|
||||||
DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, (PULONG)&ullTmrNow,
|
|
||||||
sizeof(ULONG) );
|
|
||||||
ulResult = (ULONG)ullTmrNow - (ULONG)ullTmrStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ulResult;
|
return ulResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint64
|
Uint64
|
||||||
SDL_GetPerformanceCounter(void)
|
SDL_GetPerformanceCounter(void)
|
||||||
{
|
{
|
||||||
QWORD qwTmrNow;
|
QWORD qwTmrNow;
|
||||||
|
|
||||||
if ( ( ulTmrFreq == 0 ) || ( DosTmrQueryTime( &qwTmrNow ) != NO_ERROR ) )
|
if (ulTmrFreq == 0 || (DosTmrQueryTime(&qwTmrNow) != NO_ERROR))
|
||||||
return SDL_GetTicks();
|
return SDL_GetTicks();
|
||||||
|
|
||||||
return *((Uint64 *)&qwTmrNow);
|
return *((Uint64 *)&qwTmrNow);
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint64
|
Uint64
|
||||||
SDL_GetPerformanceFrequency(void)
|
SDL_GetPerformanceFrequency(void)
|
||||||
{
|
{
|
||||||
return ulTmrFreq == 0 ? 1000 : (Uint64)ulTmrFreq;
|
return (ulTmrFreq == 0)? 1000 : (Uint64)ulTmrFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SDL_Delay(Uint32 ms)
|
SDL_Delay(Uint32 ms)
|
||||||
{
|
{
|
||||||
HTIMER hTimer = NULLHANDLE;
|
HTIMER hTimer = NULLHANDLE;
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
#ifdef _SWITCH_PRIORITY
|
#ifdef _SWITCH_PRIORITY
|
||||||
PPIB pib;
|
PPIB pib;
|
||||||
PTIB tib;
|
PTIB tib;
|
||||||
BOOL fSetPriority = ms < 50;
|
BOOL fSetPriority = ms < 50;
|
||||||
ULONG ulSavePriority;
|
ULONG ulSavePriority;
|
||||||
ULONG ulNesting;
|
ULONG ulNesting;
|
||||||
#endif
|
#endif
|
||||||
HEV hevTimer;
|
HEV hevTimer;
|
||||||
|
|
||||||
if ( ms == 0 )
|
if (ms == 0) {
|
||||||
{
|
DosSleep(0);
|
||||||
DosSleep( 0 );
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ulRC = DosCreateEventSem( NULL, &hevTimer, DC_SEM_SHARED, FALSE );
|
|
||||||
if ( ulRC != NO_ERROR )
|
|
||||||
{
|
|
||||||
debug( "DosAsyncTimer() failed, rc = %u", ulRC );
|
|
||||||
DosSleep( ms );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _SWITCH_PRIORITY
|
|
||||||
if ( fSetPriority )
|
|
||||||
{
|
|
||||||
if ( DosGetInfoBlocks( &tib, &pib ) != NO_ERROR )
|
|
||||||
fSetPriority = FALSE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ulSavePriority = tib->tib_ptib2->tib2_ulpri;
|
|
||||||
if ( ( (ulSavePriority & 0xFF00) == 0x0300 ) || // already have high pr.
|
|
||||||
( DosEnterMustComplete( &ulNesting ) != NO_ERROR ) )
|
|
||||||
fSetPriority = FALSE;
|
|
||||||
else
|
|
||||||
DosSetPriority( PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0 );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DosResetEventSem( hevTimer, &ulRC );
|
ulRC = DosCreateEventSem(NULL, &hevTimer, DC_SEM_SHARED, FALSE);
|
||||||
ulRC = DosAsyncTimer( ms, (HSEM)hevTimer, &hTimer );
|
if (ulRC != NO_ERROR) {
|
||||||
|
debug_os2("DosAsyncTimer() failed, rc = %u", ulRC);
|
||||||
|
DosSleep(ms);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _SWITCH_PRIORITY
|
#ifdef _SWITCH_PRIORITY
|
||||||
if ( fSetPriority )
|
if (fSetPriority) {
|
||||||
{
|
if (DosGetInfoBlocks(&tib, &pib) != NO_ERROR)
|
||||||
if ( DosSetPriority( PRTYS_THREAD, (ulSavePriority >> 8) & 0xFF, 0, 0 ) ==
|
fSetPriority = FALSE;
|
||||||
NO_ERROR )
|
else {
|
||||||
DosSetPriority( PRTYS_THREAD, 0, ulSavePriority & 0xFF, 0 );
|
ulSavePriority = tib->tib_ptib2->tib2_ulpri;
|
||||||
|
if (((ulSavePriority & 0xFF00) == 0x0300) || /* already have high pr. */
|
||||||
DosExitMustComplete( &ulNesting );
|
(DosEnterMustComplete( &ulNesting) != NO_ERROR))
|
||||||
}
|
fSetPriority = FALSE;
|
||||||
|
else {
|
||||||
|
DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( ulRC != NO_ERROR )
|
DosResetEventSem(hevTimer, &ulRC);
|
||||||
debug( "DosAsyncTimer() failed, rc = %u", ulRC );
|
ulRC = DosAsyncTimer(ms, (HSEM)hevTimer, &hTimer);
|
||||||
else
|
|
||||||
DosWaitEventSem( hevTimer, SEM_INDEFINITE_WAIT );
|
|
||||||
|
|
||||||
if ( ulRC != NO_ERROR )
|
#ifdef _SWITCH_PRIORITY
|
||||||
DosSleep( ms );
|
if (fSetPriority) {
|
||||||
|
if (DosSetPriority(PRTYS_THREAD, (ulSavePriority >> 8) & 0xFF, 0, 0) == NO_ERROR)
|
||||||
|
DosSetPriority(PRTYS_THREAD, 0, ulSavePriority & 0xFF, 0);
|
||||||
|
DosExitMustComplete(&ulNesting);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
DosCloseEventSem( hevTimer );
|
if (ulRC != NO_ERROR) {
|
||||||
|
debug_os2("DosAsyncTimer() failed, rc = %u", ulRC);
|
||||||
|
} else {
|
||||||
|
DosWaitEventSem(hevTimer, SEM_INDEFINITE_WAIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ulRC != NO_ERROR)
|
||||||
|
DosSleep(ms);
|
||||||
|
|
||||||
|
DosCloseEventSem(hevTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_TIMER_OS2 */
|
#endif /* SDL_TIMER_OS2 */
|
||||||
|
|
|
@ -32,17 +32,17 @@
|
||||||
#include "SDL_os2output.h"
|
#include "SDL_os2output.h"
|
||||||
|
|
||||||
typedef struct _VODATA {
|
typedef struct _VODATA {
|
||||||
HDIVE hDive;
|
HDIVE hDive;
|
||||||
PVOID pBuffer;
|
PVOID pBuffer;
|
||||||
ULONG ulDIVEBufNum;
|
ULONG ulDIVEBufNum;
|
||||||
FOURCC fccColorEncoding;
|
FOURCC fccColorEncoding;
|
||||||
ULONG ulWidth;
|
ULONG ulWidth;
|
||||||
ULONG ulHeight;
|
ULONG ulHeight;
|
||||||
BOOL fBlitterReady;
|
BOOL fBlitterReady;
|
||||||
} VODATA;
|
} VODATA;
|
||||||
|
|
||||||
static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo);
|
static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo);
|
||||||
static PVODATA voOpen();
|
static PVODATA voOpen(void);
|
||||||
static VOID voClose(PVODATA pVOData);
|
static VOID voClose(PVODATA pVOData);
|
||||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||||
SDL_DisplayMode *pSDLDisplayMode,
|
SDL_DisplayMode *pSDLDisplayMode,
|
||||||
|
@ -55,294 +55,275 @@ static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||||
ULONG cSDLRects);
|
ULONG cSDLRects);
|
||||||
|
|
||||||
OS2VIDEOOUTPUT voDive = {
|
OS2VIDEOOUTPUT voDive = {
|
||||||
voQueryInfo,
|
voQueryInfo,
|
||||||
voOpen,
|
voOpen,
|
||||||
voClose,
|
voClose,
|
||||||
voSetVisibleRegion,
|
voSetVisibleRegion,
|
||||||
voVideoBufAlloc,
|
voVideoBufAlloc,
|
||||||
voVideoBufFree,
|
voVideoBufFree,
|
||||||
voUpdate
|
voUpdate
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo)
|
static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo)
|
||||||
{
|
{
|
||||||
DIVE_CAPS sDiveCaps = { 0 };
|
DIVE_CAPS sDiveCaps = { 0 };
|
||||||
FOURCC fccFormats[100] = { 0 };
|
FOURCC fccFormats[100] = { 0 };
|
||||||
|
|
||||||
// Query information about display hardware from DIVE.
|
/* Query information about display hardware from DIVE. */
|
||||||
|
sDiveCaps.pFormatData = fccFormats;
|
||||||
|
sDiveCaps.ulFormatLength = 100;
|
||||||
|
sDiveCaps.ulStructLen = sizeof(DIVE_CAPS);
|
||||||
|
|
||||||
sDiveCaps.pFormatData = fccFormats;
|
if (DiveQueryCaps(&sDiveCaps, DIVE_BUFFER_SCREEN)) {
|
||||||
sDiveCaps.ulFormatLength = 100;
|
debug_os2("DiveQueryCaps() failed.");
|
||||||
sDiveCaps.ulStructLen = sizeof(DIVE_CAPS);
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ( DiveQueryCaps( &sDiveCaps, DIVE_BUFFER_SCREEN ) )
|
if (sDiveCaps.ulDepth < 8) {
|
||||||
{
|
debug_os2("Not enough screen colors to run DIVE. "
|
||||||
debug( "DiveQueryCaps() failed." );
|
"Must be at least 256 colors.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( sDiveCaps.ulDepth < 8 )
|
pInfo->ulBPP = sDiveCaps.ulDepth;
|
||||||
{
|
pInfo->fccColorEncoding = sDiveCaps.fccColorEncoding;
|
||||||
debug( "Not enough screen colors to run DIVE. "
|
pInfo->ulScanLineSize = sDiveCaps.ulScanLineBytes;
|
||||||
"Must be at least 256 colors." );
|
pInfo->ulHorizResolution = sDiveCaps.ulHorizontalResolution;
|
||||||
return FALSE;
|
pInfo->ulVertResolution = sDiveCaps.ulVerticalResolution;
|
||||||
}
|
|
||||||
|
|
||||||
pInfo->ulBPP = sDiveCaps.ulDepth;
|
return TRUE;
|
||||||
pInfo->fccColorEncoding = sDiveCaps.fccColorEncoding;
|
|
||||||
pInfo->ulScanLineSize = sDiveCaps.ulScanLineBytes;
|
|
||||||
pInfo->ulHorizResolution = sDiveCaps.ulHorizontalResolution;
|
|
||||||
pInfo->ulVertResolution = sDiveCaps.ulVerticalResolution;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PVODATA voOpen()
|
PVODATA voOpen(void)
|
||||||
{
|
{
|
||||||
PVODATA pVOData = SDL_calloc( 1, sizeof(VODATA) );
|
PVODATA pVOData = SDL_calloc(1, sizeof(VODATA));
|
||||||
|
|
||||||
if ( pVOData == NULL )
|
if (pVOData == NULL) {
|
||||||
{
|
SDL_OutOfMemory();
|
||||||
SDL_OutOfMemory();
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ( DiveOpen( &pVOData->hDive, FALSE, NULL ) != DIVE_SUCCESS )
|
if (DiveOpen(&pVOData->hDive, FALSE, NULL) != DIVE_SUCCESS) {
|
||||||
{
|
SDL_free(pVOData);
|
||||||
SDL_free( pVOData );
|
SDL_SetError("DIVE: A display engine instance open failed");
|
||||||
SDL_SetError( "DIVE: A display engine instance open failed" );
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return pVOData;
|
return pVOData;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID voClose(PVODATA pVOData)
|
static VOID voClose(PVODATA pVOData)
|
||||||
{
|
{
|
||||||
voVideoBufFree( pVOData );
|
voVideoBufFree(pVOData);
|
||||||
DiveClose( pVOData->hDive );
|
DiveClose(pVOData->hDive);
|
||||||
SDL_free( pVOData );
|
SDL_free(pVOData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||||
SDL_DisplayMode *pSDLDisplayMode,
|
SDL_DisplayMode *pSDLDisplayMode,
|
||||||
HRGN hrgnShape, BOOL fVisible)
|
HRGN hrgnShape, BOOL fVisible)
|
||||||
{
|
{
|
||||||
HPS hps;
|
HPS hps;
|
||||||
HRGN hrgn;
|
HRGN hrgn;
|
||||||
RGNRECT rgnCtl;
|
RGNRECT rgnCtl;
|
||||||
PRECTL prectl = NULL;
|
PRECTL prectl = NULL;
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( !fVisible )
|
if (!fVisible) {
|
||||||
{
|
if (pVOData->fBlitterReady) {
|
||||||
if ( pVOData->fBlitterReady )
|
pVOData->fBlitterReady = FALSE;
|
||||||
{
|
DiveSetupBlitter(pVOData->hDive, 0);
|
||||||
pVOData->fBlitterReady = FALSE;
|
debug_os2("DIVE blitter is tuned off");
|
||||||
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SetError( "DiveSetupBlitter(), rc = 0x%X", ulRC );
|
/* Query visible rectangles */
|
||||||
} // if ( prectl != NULL )
|
hps = WinGetPS(hwnd);
|
||||||
} // if ( hrgn == NULLHANDLE ) else
|
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);
|
||||||
|
|
||||||
pVOData->fBlitterReady = FALSE;
|
rgnCtl.ircStart = 1;
|
||||||
DiveSetupBlitter( pVOData->hDive, 0 );
|
rgnCtl.crc = 0;
|
||||||
return FALSE;
|
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_os2("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,
|
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||||
ULONG ulBPP, FOURCC fccColorEncoding,
|
ULONG ulBPP, FOURCC fccColorEncoding,
|
||||||
PULONG pulScanLineSize)
|
PULONG pulScanLineSize)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
ULONG ulScanLineSize = ulWidth * (ulBPP >> 3);
|
ULONG ulScanLineSize = ulWidth * (ulBPP >> 3);
|
||||||
|
|
||||||
// Destroy previous buffer.
|
/* Destroy previous buffer. */
|
||||||
voVideoBufFree( pVOData );
|
voVideoBufFree(pVOData);
|
||||||
|
|
||||||
if ( ( ulWidth == 0 ) || ( ulHeight == 0 ) || ( ulBPP == 0 ) )
|
if (ulWidth == 0 || ulHeight == 0 || ulBPP == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Bytes per line.
|
/* Bytes per line. */
|
||||||
ulScanLineSize = ( ulScanLineSize + 3 ) & ~3; /* 4-byte aligning */
|
ulScanLineSize = (ulScanLineSize + 3) & ~3; /* 4-byte aligning */
|
||||||
*pulScanLineSize = ulScanLineSize;
|
*pulScanLineSize = ulScanLineSize;
|
||||||
|
|
||||||
ulRC = DosAllocMem( &pVOData->pBuffer,
|
ulRC = DosAllocMem(&pVOData->pBuffer,
|
||||||
(ulHeight * ulScanLineSize) + sizeof(ULONG),
|
(ulHeight * ulScanLineSize) + sizeof(ULONG),
|
||||||
PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE );
|
PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug_os2("DosAllocMem(), rc = %u", ulRC);
|
||||||
debug( "DosAllocMem(), rc = %u", ulRC );
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ulRC = DiveAllocImageBuffer( pVOData->hDive, &pVOData->ulDIVEBufNum,
|
ulRC = DiveAllocImageBuffer(pVOData->hDive, &pVOData->ulDIVEBufNum,
|
||||||
fccColorEncoding, ulWidth, ulHeight,
|
fccColorEncoding, ulWidth, ulHeight,
|
||||||
ulScanLineSize, pVOData->pBuffer );
|
ulScanLineSize, pVOData->pBuffer);
|
||||||
if ( ulRC != DIVE_SUCCESS )
|
if (ulRC != DIVE_SUCCESS) {
|
||||||
{
|
debug_os2("DiveAllocImageBuffer(), rc = 0x%X", ulRC);
|
||||||
debug( "DiveAllocImageBuffer(), rc = 0x%X", ulRC );
|
DosFreeMem(pVOData->pBuffer);
|
||||||
DosFreeMem( pVOData->pBuffer );
|
pVOData->pBuffer = NULL;
|
||||||
pVOData->pBuffer = NULL;
|
pVOData->ulDIVEBufNum = 0;
|
||||||
pVOData->ulDIVEBufNum = 0;
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pVOData->fccColorEncoding = fccColorEncoding;
|
pVOData->fccColorEncoding = fccColorEncoding;
|
||||||
pVOData->ulWidth = ulWidth;
|
pVOData->ulWidth = ulWidth;
|
||||||
pVOData->ulHeight = ulHeight;
|
pVOData->ulHeight = ulHeight;
|
||||||
|
|
||||||
debug( "buffer: 0x%P, DIVE buffer number: %u",
|
debug_os2("buffer: 0x%P, DIVE buffer number: %u",
|
||||||
pVOData->pBuffer, pVOData->ulDIVEBufNum );
|
pVOData->pBuffer, pVOData->ulDIVEBufNum);
|
||||||
|
|
||||||
return pVOData->pBuffer;
|
return pVOData->pBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID voVideoBufFree(PVODATA pVOData)
|
static VOID voVideoBufFree(PVODATA pVOData)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( pVOData->ulDIVEBufNum != 0 )
|
if (pVOData->ulDIVEBufNum != 0) {
|
||||||
{
|
ulRC = DiveFreeImageBuffer(pVOData->hDive, pVOData->ulDIVEBufNum);
|
||||||
ulRC = DiveFreeImageBuffer( pVOData->hDive, pVOData->ulDIVEBufNum );
|
if (ulRC != DIVE_SUCCESS) {
|
||||||
if ( ulRC != DIVE_SUCCESS )
|
debug_os2("DiveFreeImageBuffer(,%u), rc = %u", pVOData->ulDIVEBufNum, ulRC);
|
||||||
debug( "DiveFreeImageBuffer(,%u), rc = %u", pVOData->ulDIVEBufNum, ulRC );
|
} else {
|
||||||
else
|
debug_os2("DIVE buffer %u destroyed", pVOData->ulDIVEBufNum);
|
||||||
debug( "DIVE buffer %u destroyed", pVOData->ulDIVEBufNum );
|
}
|
||||||
|
pVOData->ulDIVEBufNum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
pVOData->ulDIVEBufNum = 0;
|
if (pVOData->pBuffer != NULL) {
|
||||||
}
|
ulRC = DosFreeMem(pVOData->pBuffer);
|
||||||
|
if (ulRC != NO_ERROR) {
|
||||||
if ( pVOData->pBuffer != NULL )
|
debug_os2("DosFreeMem(), rc = %u", ulRC);
|
||||||
{
|
}
|
||||||
ulRC = DosFreeMem( pVOData->pBuffer );
|
pVOData->pBuffer = NULL;
|
||||||
if ( ulRC != NO_ERROR )
|
}
|
||||||
debug( "DosFreeMem(), rc = %u", ulRC );
|
|
||||||
|
|
||||||
pVOData->pBuffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||||
ULONG cSDLRects)
|
ULONG cSDLRects)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( !pVOData->fBlitterReady || ( pVOData->ulDIVEBufNum == 0 ) )
|
if (!pVOData->fBlitterReady || (pVOData->ulDIVEBufNum == 0)) {
|
||||||
{
|
debug_os2("DIVE blitter is not ready");
|
||||||
debug( "DIVE blitter is not ready" );
|
return FALSE;
|
||||||
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++ )
|
if (pSDLRects != 0) {
|
||||||
memset( &pbLineMask[pSDLRects->y], 1, pSDLRects->h );
|
PBYTE pbLineMask;
|
||||||
|
|
||||||
ulRC = DiveBlitImageLines( pVOData->hDive, pVOData->ulDIVEBufNum,
|
pbLineMask = SDL_stack_alloc(BYTE, pVOData->ulHeight);
|
||||||
DIVE_BUFFER_SCREEN, pbLineMask );
|
if (pbLineMask == NULL) {
|
||||||
SDL_stack_free( pbLineMask );
|
debug_os2("Not enough stack size");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
memset(pbLineMask, 0, pVOData->ulHeight);
|
||||||
|
|
||||||
if ( ulRC != DIVE_SUCCESS )
|
for ( ; ((LONG)cSDLRects) > 0; cSDLRects--, pSDLRects++) {
|
||||||
debug( "DiveBlitImageLines(), rc = 0x%X", ulRC );
|
memset(&pbLineMask[pSDLRects->y], 1, pSDLRects->h);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ulRC = DiveBlitImage( pVOData->hDive, pVOData->ulDIVEBufNum,
|
|
||||||
DIVE_BUFFER_SCREEN );
|
|
||||||
if ( ulRC != DIVE_SUCCESS )
|
|
||||||
debug( "DiveBlitImage(), rc = 0x%X", ulRC );
|
|
||||||
}
|
|
||||||
|
|
||||||
return ulRC == DIVE_SUCCESS;
|
ulRC = DiveBlitImageLines(pVOData->hDive, pVOData->ulDIVEBufNum,
|
||||||
|
DIVE_BUFFER_SCREEN, pbLineMask);
|
||||||
|
SDL_stack_free(pbLineMask);
|
||||||
|
|
||||||
|
if (ulRC != DIVE_SUCCESS) {
|
||||||
|
debug_os2("DiveBlitImageLines(), rc = 0x%X", ulRC);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ulRC = DiveBlitImage(pVOData->hDive, pVOData->ulDIVEBufNum,
|
||||||
|
DIVE_BUFFER_SCREEN);
|
||||||
|
if (ulRC != DIVE_SUCCESS) {
|
||||||
|
debug_os2("DiveBlitImage(), rc = 0x%X", ulRC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulRC == DIVE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,46 +26,43 @@
|
||||||
#include "../../events/SDL_mouse_c.h"
|
#include "../../events/SDL_mouse_c.h"
|
||||||
#include "SDL_os2util.h"
|
#include "SDL_os2util.h"
|
||||||
|
|
||||||
HPOINTER hptrCursor = NULLHANDLE;
|
HPOINTER hptrCursor = NULLHANDLE;
|
||||||
|
|
||||||
static SDL_Cursor* OS2_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
static SDL_Cursor* OS2_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
||||||
{
|
{
|
||||||
ULONG ulMaxW = WinQuerySysValue( HWND_DESKTOP, SV_CXPOINTER );
|
ULONG ulMaxW = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER);
|
||||||
ULONG ulMaxH = WinQuerySysValue( HWND_DESKTOP, SV_CYPOINTER );
|
ULONG ulMaxH = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER);
|
||||||
HPOINTER hptr;
|
HPOINTER hptr;
|
||||||
SDL_Cursor *pSDLCursor;
|
SDL_Cursor* pSDLCursor;
|
||||||
|
|
||||||
if ( ( surface->w > ulMaxW ) || ( surface->h > ulMaxH ) )
|
if (surface->w > ulMaxW || surface->h > ulMaxH) {
|
||||||
{
|
debug_os2("Given image size is %u x %u, maximum allowed size is %u x %u",
|
||||||
debug( "Given image size is %u x %u, maximum allowed size is %u x %u",
|
surface->w, surface->h, ulMaxW, ulMaxH);
|
||||||
surface->w, surface->h, ulMaxW, ulMaxH );
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hptr = utilCreatePointer( surface, hot_x, ulMaxH - hot_y - 1 );
|
hptr = utilCreatePointer(surface, hot_x, ulMaxH - hot_y - 1);
|
||||||
if ( hptr == NULLHANDLE )
|
if (hptr == NULLHANDLE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pSDLCursor = SDL_calloc( 1, sizeof(SDL_Cursor) );
|
pSDLCursor = SDL_calloc(1, sizeof(SDL_Cursor));
|
||||||
if ( pSDLCursor == NULL )
|
if (pSDLCursor == NULL) {
|
||||||
{
|
WinDestroyPointer(hptr);
|
||||||
WinDestroyPointer( hptr );
|
SDL_OutOfMemory();
|
||||||
SDL_OutOfMemory();
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pSDLCursor->driverdata = (void *)hptr;
|
pSDLCursor->driverdata = (void *)hptr;
|
||||||
return pSDLCursor;
|
return pSDLCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_Cursor* OS2_CreateSystemCursor(SDL_SystemCursor id)
|
static SDL_Cursor* OS2_CreateSystemCursor(SDL_SystemCursor id)
|
||||||
{
|
{
|
||||||
SDL_Cursor* pSDLCursor;
|
SDL_Cursor* pSDLCursor;
|
||||||
LONG lSysId;
|
LONG lSysId;
|
||||||
HPOINTER hptr;
|
HPOINTER hptr;
|
||||||
|
|
||||||
switch( id )
|
switch (id) {
|
||||||
{
|
|
||||||
case SDL_SYSTEM_CURSOR_ARROW: lSysId = SPTR_ARROW; break;
|
case SDL_SYSTEM_CURSOR_ARROW: lSysId = SPTR_ARROW; break;
|
||||||
case SDL_SYSTEM_CURSOR_IBEAM: lSysId = SPTR_TEXT; break;
|
case SDL_SYSTEM_CURSOR_IBEAM: lSysId = SPTR_TEXT; break;
|
||||||
case SDL_SYSTEM_CURSOR_WAIT: lSysId = SPTR_WAIT; break;
|
case SDL_SYSTEM_CURSOR_WAIT: lSysId = SPTR_WAIT; break;
|
||||||
|
@ -79,124 +76,119 @@ static SDL_Cursor* OS2_CreateSystemCursor(SDL_SystemCursor id)
|
||||||
case SDL_SYSTEM_CURSOR_NO: lSysId = SPTR_ILLEGAL; break;
|
case SDL_SYSTEM_CURSOR_NO: lSysId = SPTR_ILLEGAL; break;
|
||||||
case SDL_SYSTEM_CURSOR_HAND: lSysId = SPTR_ARROW; break;
|
case SDL_SYSTEM_CURSOR_HAND: lSysId = SPTR_ARROW; break;
|
||||||
default:
|
default:
|
||||||
debug( "Unknown cursor id: %u", id );
|
debug_os2("Unknown cursor id: %u", id);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On eCS SPTR_WAIT for last paramether fCopy=TRUE/FALSE gives different
|
/* On eCS SPTR_WAIT for last paramether fCopy=TRUE/FALSE gives different
|
||||||
// "wait" icons. -=8( )
|
* "wait" icons. -=8( ) */
|
||||||
hptr = WinQuerySysPointer( HWND_DESKTOP, lSysId,
|
hptr = WinQuerySysPointer(HWND_DESKTOP, lSysId,
|
||||||
id == SDL_SYSTEM_CURSOR_WAIT );
|
id == SDL_SYSTEM_CURSOR_WAIT);
|
||||||
if ( hptr == NULLHANDLE )
|
if (hptr == NULLHANDLE) {
|
||||||
{
|
debug_os2("Cannot load OS/2 system pointer %u for SDL cursor id %u",
|
||||||
debug( "Cannot load OS/2 system pointer %u for SDL cursor id %u",
|
lSysId, id);
|
||||||
lSysId, id );
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pSDLCursor = SDL_calloc( 1, sizeof(SDL_Cursor) );
|
pSDLCursor = SDL_calloc(1, sizeof(SDL_Cursor));
|
||||||
if ( pSDLCursor == NULL )
|
if (pSDLCursor == NULL) {
|
||||||
{
|
WinDestroyPointer(hptr);
|
||||||
WinDestroyPointer( hptr );
|
SDL_OutOfMemory();
|
||||||
SDL_OutOfMemory();
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pSDLCursor->driverdata = (void *)hptr;
|
pSDLCursor->driverdata = (void *)hptr;
|
||||||
return pSDLCursor;
|
return pSDLCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OS2_FreeCursor(SDL_Cursor *cursor)
|
static void OS2_FreeCursor(SDL_Cursor *cursor)
|
||||||
{
|
{
|
||||||
HPOINTER hptr = (HPOINTER)cursor->driverdata;
|
HPOINTER hptr = (HPOINTER)cursor->driverdata;
|
||||||
|
|
||||||
WinDestroyPointer( hptr );
|
WinDestroyPointer(hptr);
|
||||||
SDL_free( cursor );
|
SDL_free(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int OS2_ShowCursor(SDL_Cursor *cursor)
|
static int OS2_ShowCursor(SDL_Cursor *cursor)
|
||||||
{
|
{
|
||||||
hptrCursor = cursor != NULL ? (HPOINTER)cursor->driverdata : NULLHANDLE;
|
hptrCursor = (cursor != NULL)? (HPOINTER)cursor->driverdata : NULLHANDLE;
|
||||||
|
return ((SDL_GetMouseFocus() == NULL) ||
|
||||||
return ( ( SDL_GetMouseFocus() == NULL ) ||
|
WinSetPointer(HWND_DESKTOP, hptrCursor))? 0 : -1;
|
||||||
WinSetPointer( HWND_DESKTOP, hptrCursor ) ) ? 0 : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OS2_WarpMouse(SDL_Window * window, int x, int y)
|
static void OS2_WarpMouse(SDL_Window * window, int x, int y)
|
||||||
{
|
{
|
||||||
PWINDATA pWinData = (PWINDATA)window->driverdata;
|
WINDATA *pWinData = (WINDATA *)window->driverdata;
|
||||||
POINTL pointl;
|
POINTL pointl;
|
||||||
|
|
||||||
pointl.x = x;
|
pointl.x = x;
|
||||||
pointl.y = window->h - y;
|
pointl.y = window->h - y;
|
||||||
WinMapWindowPoints( pWinData->hwnd, HWND_DESKTOP, &pointl, 1 );
|
WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1);
|
||||||
// pWinData->lSkipWMMouseMove++; ???
|
/* pWinData->lSkipWMMouseMove++; ???*/
|
||||||
WinSetPointerPos( HWND_DESKTOP, pointl.x, pointl.y );
|
WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int OS2_WarpMouseGlobal(int x, int y)
|
static int OS2_WarpMouseGlobal(int x, int y)
|
||||||
{
|
{
|
||||||
WinSetPointerPos( HWND_DESKTOP, x,
|
WinSetPointerPos(HWND_DESKTOP, x,
|
||||||
WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - y );
|
WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - y);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int OS2_CaptureMouse(SDL_Window *window)
|
static int OS2_CaptureMouse(SDL_Window *window)
|
||||||
{
|
{
|
||||||
return WinSetCapture( HWND_DESKTOP,
|
return WinSetCapture(HWND_DESKTOP, (window == NULL)? NULLHANDLE :
|
||||||
window == NULL ? NULLHANDLE
|
((WINDATA *)window->driverdata)->hwnd)? 0 : -1;
|
||||||
: ((PWINDATA)window->driverdata)->hwnd )
|
|
||||||
? 0 : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint32 OS2_GetGlobalMouseState(int *x, int *y)
|
static Uint32 OS2_GetGlobalMouseState(int *x, int *y)
|
||||||
{
|
{
|
||||||
POINTL pointl;
|
POINTL pointl;
|
||||||
ULONG ulRes;
|
ULONG ulRes;
|
||||||
|
|
||||||
WinQueryPointerPos( HWND_DESKTOP, &pointl );
|
WinQueryPointerPos(HWND_DESKTOP, &pointl);
|
||||||
*x = pointl.x;
|
*x = pointl.x;
|
||||||
*y = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - pointl.y - 1;
|
*y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - pointl.y - 1;
|
||||||
|
|
||||||
ulRes = WinGetKeyState( HWND_DESKTOP, VK_BUTTON1 ) & 0x8000
|
ulRes = (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)? SDL_BUTTON_LMASK : 0;
|
||||||
? SDL_BUTTON_LMASK : 0;
|
if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
|
||||||
if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON2 ) & 0x8000 )
|
ulRes |= SDL_BUTTON_RMASK;
|
||||||
ulRes |= SDL_BUTTON_RMASK;
|
if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
|
||||||
if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON3 ) & 0x8000 )
|
ulRes |= SDL_BUTTON_MMASK;
|
||||||
ulRes |= SDL_BUTTON_MMASK;
|
|
||||||
|
|
||||||
return ulRes;
|
return ulRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OS2_InitMouse(_THIS, ULONG hab)
|
void OS2_InitMouse(_THIS, ULONG hab)
|
||||||
{
|
{
|
||||||
SDL_Mouse *pSDLMouse = SDL_GetMouse();
|
SDL_Mouse *pSDLMouse = SDL_GetMouse();
|
||||||
|
|
||||||
pSDLMouse->CreateCursor = OS2_CreateCursor;
|
pSDLMouse->CreateCursor = OS2_CreateCursor;
|
||||||
pSDLMouse->CreateSystemCursor = OS2_CreateSystemCursor;
|
pSDLMouse->CreateSystemCursor = OS2_CreateSystemCursor;
|
||||||
pSDLMouse->ShowCursor = OS2_ShowCursor;
|
pSDLMouse->ShowCursor = OS2_ShowCursor;
|
||||||
pSDLMouse->FreeCursor = OS2_FreeCursor;
|
pSDLMouse->FreeCursor = OS2_FreeCursor;
|
||||||
pSDLMouse->WarpMouse = OS2_WarpMouse;
|
pSDLMouse->WarpMouse = OS2_WarpMouse;
|
||||||
pSDLMouse->WarpMouseGlobal = OS2_WarpMouseGlobal;
|
pSDLMouse->WarpMouseGlobal = OS2_WarpMouseGlobal;
|
||||||
pSDLMouse->CaptureMouse = OS2_CaptureMouse;
|
pSDLMouse->CaptureMouse = OS2_CaptureMouse;
|
||||||
pSDLMouse->GetGlobalMouseState = OS2_GetGlobalMouseState;
|
pSDLMouse->GetGlobalMouseState = OS2_GetGlobalMouseState;
|
||||||
|
|
||||||
SDL_SetDefaultCursor( OS2_CreateSystemCursor( SDL_SYSTEM_CURSOR_ARROW ) );
|
SDL_SetDefaultCursor(OS2_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW));
|
||||||
if ( hptrCursor == NULLHANDLE )
|
if (hptrCursor == NULLHANDLE)
|
||||||
hptrCursor = WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, TRUE );
|
hptrCursor = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OS2_QuitMouse(_THIS)
|
void OS2_QuitMouse(_THIS)
|
||||||
{
|
{
|
||||||
SDL_Mouse *pSDLMouse = SDL_GetMouse();
|
SDL_Mouse *pSDLMouse = SDL_GetMouse();
|
||||||
|
|
||||||
if ( pSDLMouse->def_cursor != NULL )
|
if (pSDLMouse->def_cursor != NULL) {
|
||||||
{
|
SDL_free(pSDLMouse->def_cursor);
|
||||||
SDL_free( pSDLMouse->def_cursor );
|
pSDLMouse->def_cursor = NULL;
|
||||||
pSDLMouse->def_cursor = NULL;
|
pSDLMouse->cur_cursor = NULL;
|
||||||
pSDLMouse->cur_cursor = NULL;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#ifndef SDL_os2mouse_h_
|
#ifndef SDL_os2mouse_h_
|
||||||
#define SDL_os2mouse_h_
|
#define SDL_os2mouse_h_
|
||||||
|
|
||||||
extern HPOINTER hptrCursor;
|
extern HPOINTER hptrCursor;
|
||||||
|
|
||||||
extern void OS2_InitMouse(_THIS, ULONG hab);
|
extern void OS2_InitMouse(_THIS, ULONG hab);
|
||||||
extern void OS2_QuitMouse(_THIS);
|
extern void OS2_QuitMouse(_THIS);
|
||||||
|
|
|
@ -26,29 +26,34 @@
|
||||||
typedef struct _VODATA *PVODATA;
|
typedef struct _VODATA *PVODATA;
|
||||||
|
|
||||||
typedef struct _VIDEOOUTPUTINFO {
|
typedef struct _VIDEOOUTPUTINFO {
|
||||||
ULONG ulBPP;
|
ULONG ulBPP;
|
||||||
ULONG fccColorEncoding;
|
ULONG fccColorEncoding;
|
||||||
ULONG ulScanLineSize;
|
ULONG ulScanLineSize;
|
||||||
ULONG ulHorizResolution;
|
ULONG ulHorizResolution;
|
||||||
ULONG ulVertResolution;
|
ULONG ulVertResolution;
|
||||||
} VIDEOOUTPUTINFO, *PVIDEOOUTPUTINFO;
|
} VIDEOOUTPUTINFO;
|
||||||
|
|
||||||
typedef struct _OS2VIDEOOUTPUT {
|
typedef struct _OS2VIDEOOUTPUT {
|
||||||
BOOL (*QueryInfo)(PVIDEOOUTPUTINFO pInfo);
|
BOOL (*QueryInfo)(VIDEOOUTPUTINFO *pInfo);
|
||||||
PVODATA (*Open)();
|
PVODATA (*Open)();
|
||||||
VOID (*Close)(PVODATA pVOData);
|
VOID (*Close)(PVODATA pVOData);
|
||||||
BOOL (*SetVisibleRegion)(PVODATA pVOData, HWND hwnd,
|
|
||||||
SDL_DisplayMode *pSDLDisplayMode, HRGN hrgnShape,
|
BOOL (*SetVisibleRegion)(PVODATA pVOData, HWND hwnd,
|
||||||
BOOL fVisible);
|
SDL_DisplayMode *pSDLDisplayMode, HRGN hrgnShape,
|
||||||
PVOID (*VideoBufAlloc)(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
BOOL fVisible);
|
||||||
ULONG ulBPP, ULONG fccColorEncoding,
|
|
||||||
PULONG pulScanLineSize);
|
PVOID (*VideoBufAlloc)(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||||
VOID (*VideoBufFree)(PVODATA pVOData);
|
ULONG ulBPP, ULONG fccColorEncoding,
|
||||||
BOOL (*Update)(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
PULONG pulScanLineSize);
|
||||||
ULONG cSDLRects);
|
|
||||||
} OS2VIDEOOUTPUT, *POS2VIDEOOUTPUT;
|
VOID (*VideoBufFree)(PVODATA pVOData);
|
||||||
|
BOOL (*Update)(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||||
|
ULONG cSDLRects);
|
||||||
|
} OS2VIDEOOUTPUT;
|
||||||
|
|
||||||
extern OS2VIDEOOUTPUT voDive;
|
extern OS2VIDEOOUTPUT voDive;
|
||||||
extern OS2VIDEOOUTPUT voVMan;
|
extern OS2VIDEOOUTPUT voVMan;
|
||||||
|
|
||||||
#endif /* SDL_os2output_ */
|
#endif /* SDL_os2output_ */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -24,95 +24,88 @@
|
||||||
|
|
||||||
#include "SDL_os2util.h"
|
#include "SDL_os2util.h"
|
||||||
|
|
||||||
|
|
||||||
HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY)
|
HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY)
|
||||||
{
|
{
|
||||||
HBITMAP hbm;
|
HBITMAP hbm;
|
||||||
BITMAPINFOHEADER2 bmih = { 0 };
|
BITMAPINFOHEADER2 bmih = { 0 };
|
||||||
BITMAPINFO bmi = { 0 };
|
BITMAPINFO bmi = { 0 };
|
||||||
HPS hps;
|
HPS hps;
|
||||||
PULONG pulBitmap;
|
PULONG pulBitmap;
|
||||||
PULONG pulDst, pulSrc, pulDstMask;
|
PULONG pulDst, pulSrc, pulDstMask;
|
||||||
ULONG ulY, ulX;
|
ULONG ulY, ulX;
|
||||||
HPOINTER hptr = NULLHANDLE;
|
HPOINTER hptr = NULLHANDLE;
|
||||||
|
|
||||||
if ( surface->format->format != SDL_PIXELFORMAT_ARGB8888 )
|
if (surface->format->format != SDL_PIXELFORMAT_ARGB8888) {
|
||||||
{
|
debug_os2("Image format should be SDL_PIXELFORMAT_ARGB8888");
|
||||||
debug( "Image format should be SDL_PIXELFORMAT_ARGB8888" );
|
return NULLHANDLE;
|
||||||
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
|
|
||||||
pulDst = &pulBitmap[ (surface->h - 1) * surface->w ];
|
|
||||||
// pulDstMask - last line of mask part of the result bitmap
|
|
||||||
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
|
pulBitmap = SDL_malloc(surface->h * surface->w * 4 * 2);
|
||||||
pulDst -= surface->w;
|
if (pulBitmap == NULL) {
|
||||||
pulDstMask -= surface->w;
|
SDL_OutOfMemory();
|
||||||
// Set source image pointer to the next line
|
return NULLHANDLE;
|
||||||
pulSrc = (PULONG)( ((PCHAR)pulSrc) + surface->pitch );
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Create system bitmap object.
|
/* pulDst - last line of surface (image) part of the result bitmap */
|
||||||
|
pulDst = &pulBitmap[ (surface->h - 1) * surface->w ];
|
||||||
|
/* pulDstMask - last line of mask part of the result bitmap */
|
||||||
|
pulDstMask = &pulBitmap[ (2 * surface->h - 1) * surface->w ];
|
||||||
|
/* pulSrc - first line of source image */
|
||||||
|
pulSrc = (PULONG)surface->pixels;
|
||||||
|
|
||||||
bmih.cbFix = sizeof(BITMAPINFOHEADER2);
|
for (ulY = 0; ulY < surface->h; ulY++) {
|
||||||
bmih.cx = surface->w;
|
for (ulX = 0; ulX < surface->w; ulX++) {
|
||||||
bmih.cy = 2 * surface->h;
|
if ((pulSrc[ulX] & 0xFF000000) == 0) {
|
||||||
bmih.cPlanes = 1;
|
pulDst[ulX] = 0;
|
||||||
bmih.cBitCount = 32;
|
pulDstMask[ulX] = 0xFFFFFFFF;
|
||||||
bmih.ulCompression = BCA_UNCOMP;
|
} else {
|
||||||
bmih.cbImage = bmih.cx * bmih.cy * 4;
|
pulDst[ulX] = pulSrc[ulX] & 0xFFFFFF;
|
||||||
|
pulDstMask[ulX] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bmi.cbFix = sizeof(BITMAPINFOHEADER);
|
/* Set image and mask pointers on one line up */
|
||||||
bmi.cx = bmih.cx;
|
pulDst -= surface->w;
|
||||||
bmi.cy = bmih.cy;
|
pulDstMask -= surface->w;
|
||||||
bmi.cPlanes = 1;
|
/* Set source image pointer to the next line */
|
||||||
bmi.cBitCount = 32;
|
pulSrc = (PULONG) (((PCHAR)pulSrc) + surface->pitch);
|
||||||
|
}
|
||||||
|
|
||||||
hps = WinGetPS( HWND_DESKTOP );
|
/* Create system bitmap object. */
|
||||||
hbm = GpiCreateBitmap( hps, (PBITMAPINFOHEADER2)&bmih, CBM_INIT,
|
bmih.cbFix = sizeof(BITMAPINFOHEADER2);
|
||||||
(PBYTE)pulBitmap, (PBITMAPINFO2)&bmi );
|
bmih.cx = surface->w;
|
||||||
if ( hbm == GPI_ERROR )
|
bmih.cy = 2 * surface->h;
|
||||||
debug( "GpiCreateBitmap() failed" );
|
bmih.cPlanes = 1;
|
||||||
else
|
bmih.cBitCount = 32;
|
||||||
{
|
bmih.ulCompression = BCA_UNCOMP;
|
||||||
// Create a system pointer object.
|
bmih.cbImage = bmih.cx * bmih.cy * 4;
|
||||||
hptr = WinCreatePointer( HWND_DESKTOP, hbm, TRUE, ulHotX, ulHotY );
|
|
||||||
if ( hptr == NULLHANDLE )
|
|
||||||
debug( "WinCreatePointer() failed" );
|
|
||||||
}
|
|
||||||
GpiDeleteBitmap( hbm );
|
|
||||||
|
|
||||||
WinReleasePS( hps );
|
bmi.cbFix = sizeof(BITMAPINFOHEADER);
|
||||||
SDL_free( pulBitmap );
|
bmi.cx = bmih.cx;
|
||||||
|
bmi.cy = bmih.cy;
|
||||||
|
bmi.cPlanes = 1;
|
||||||
|
bmi.cBitCount = 32;
|
||||||
|
|
||||||
return hptr;
|
hps = WinGetPS(HWND_DESKTOP);
|
||||||
|
hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2)&bmih, CBM_INIT,
|
||||||
|
(PBYTE)pulBitmap, (PBITMAPINFO2)&bmi);
|
||||||
|
if (hbm == GPI_ERROR) {
|
||||||
|
debug_os2("GpiCreateBitmap() failed");
|
||||||
|
} else {
|
||||||
|
/* Create a system pointer object. */
|
||||||
|
hptr = WinCreatePointer(HWND_DESKTOP, hbm, TRUE, ulHotX, ulHotY);
|
||||||
|
if (hptr == NULLHANDLE) {
|
||||||
|
debug_os2("WinCreatePointer() failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GpiDeleteBitmap(hbm);
|
||||||
|
|
||||||
|
WinReleasePS(hps);
|
||||||
|
SDL_free(pulBitmap);
|
||||||
|
|
||||||
|
return hptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -33,3 +33,6 @@
|
||||||
HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY);
|
HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY);
|
||||||
|
|
||||||
#endif /* SDL_os2util_h_ */
|
#endif /* SDL_os2util_h_ */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,43 +39,44 @@
|
||||||
#include "SDL_os2output.h"
|
#include "SDL_os2output.h"
|
||||||
|
|
||||||
typedef struct SDL_VideoData {
|
typedef struct SDL_VideoData {
|
||||||
HAB hab;
|
HAB hab;
|
||||||
HMQ hmq;
|
HMQ hmq;
|
||||||
POS2VIDEOOUTPUT pOutput; // Video output routines.
|
OS2VIDEOOUTPUT *pOutput; /* Video output routines */
|
||||||
} SDL_VideoData, *PSDL_VideoData;
|
} SDL_VideoData;
|
||||||
|
|
||||||
typedef struct _WINDATA {
|
typedef struct _WINDATA {
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
POS2VIDEOOUTPUT pOutput; // Video output routines.
|
OS2VIDEOOUTPUT *pOutput; /* Video output routines */
|
||||||
HWND hwndFrame;
|
HWND hwndFrame;
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
PFNWP fnUserWndProc;
|
PFNWP fnUserWndProc;
|
||||||
PFNWP fnWndFrameProc;
|
PFNWP fnWndFrameProc;
|
||||||
|
|
||||||
PVODATA pVOData; // Video output data.
|
PVODATA pVOData; /* Video output data */
|
||||||
|
|
||||||
HRGN hrgnShape;
|
HRGN hrgnShape;
|
||||||
HPOINTER hptrIcon;
|
HPOINTER hptrIcon;
|
||||||
RECTL rectlBeforeFS;
|
RECTL rectlBeforeFS;
|
||||||
|
|
||||||
LONG lSkipWMSize;
|
LONG lSkipWMSize;
|
||||||
LONG lSkipWMMove;
|
LONG lSkipWMMove;
|
||||||
LONG lSkipWMMouseMove;
|
LONG lSkipWMMouseMove;
|
||||||
LONG lSkipWMVRNEnabled;
|
LONG lSkipWMVRNEnabled;
|
||||||
LONG lSkipWMAdjustFramePos;
|
LONG lSkipWMAdjustFramePos;
|
||||||
} WINDATA, *PWINDATA;
|
} WINDATA;
|
||||||
|
|
||||||
typedef struct _DISPLAYDATA {
|
typedef struct _DISPLAYDATA {
|
||||||
ULONG ulDPIHor;
|
ULONG ulDPIHor;
|
||||||
ULONG ulDPIVer;
|
ULONG ulDPIVer;
|
||||||
ULONG ulDPIDiag;
|
ULONG ulDPIDiag;
|
||||||
} DISPLAYDATA, *PDISPLAYDATA;
|
} DISPLAYDATA;
|
||||||
|
|
||||||
typedef struct _MODEDATA {
|
typedef struct _MODEDATA {
|
||||||
ULONG ulDepth;
|
ULONG ulDepth;
|
||||||
ULONG fccColorEncoding;
|
ULONG fccColorEncoding;
|
||||||
ULONG ulScanLineBytes;
|
ULONG ulScanLineBytes;
|
||||||
} MODEDATA, *PMODEDATA;
|
} MODEDATA;
|
||||||
|
|
||||||
|
|
||||||
#endif /* SDL_os2video_h_ */
|
#endif /* SDL_os2video_h_ */
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -34,23 +34,23 @@
|
||||||
#include "my_gradd.h"
|
#include "my_gradd.h"
|
||||||
|
|
||||||
typedef struct _VODATA {
|
typedef struct _VODATA {
|
||||||
PVOID pBuffer;
|
PVOID pBuffer;
|
||||||
HRGN hrgnVisible;
|
HRGN hrgnVisible;
|
||||||
ULONG ulBPP;
|
ULONG ulBPP;
|
||||||
ULONG ulScanLineSize;
|
ULONG ulScanLineSize;
|
||||||
ULONG ulWidth;
|
ULONG ulWidth;
|
||||||
ULONG ulHeight;
|
ULONG ulHeight;
|
||||||
ULONG ulScreenHeight;
|
ULONG ulScreenHeight;
|
||||||
ULONG ulScreenBytesPerLine;
|
ULONG ulScreenBytesPerLine;
|
||||||
RECTL rectlWin;
|
RECTL rectlWin;
|
||||||
|
|
||||||
PRECTL pRectl;
|
PRECTL pRectl;
|
||||||
ULONG cRectl;
|
ULONG cRectl;
|
||||||
PBLTRECT pBltRect;
|
PBLTRECT pBltRect;
|
||||||
ULONG cBltRect;
|
ULONG cBltRect;
|
||||||
} VODATA;
|
} VODATA;
|
||||||
|
|
||||||
static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo);
|
static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo);
|
||||||
static PVODATA voOpen();
|
static PVODATA voOpen();
|
||||||
static VOID voClose(PVODATA pVOData);
|
static VOID voClose(PVODATA pVOData);
|
||||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||||
|
@ -64,448 +64,421 @@ static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||||
ULONG cSDLRects);
|
ULONG cSDLRects);
|
||||||
|
|
||||||
OS2VIDEOOUTPUT voVMan = {
|
OS2VIDEOOUTPUT voVMan = {
|
||||||
voQueryInfo,
|
voQueryInfo,
|
||||||
voOpen,
|
voOpen,
|
||||||
voClose,
|
voClose,
|
||||||
voSetVisibleRegion,
|
voSetVisibleRegion,
|
||||||
voVideoBufAlloc,
|
voVideoBufAlloc,
|
||||||
voVideoBufFree,
|
voVideoBufFree,
|
||||||
voUpdate
|
voUpdate
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static HMODULE hmodVMan = NULLHANDLE;
|
static HMODULE hmodVMan = NULLHANDLE;
|
||||||
static FNVMIENTRY *pfnVMIEntry = NULL;
|
static FNVMIENTRY *pfnVMIEntry = NULL;
|
||||||
static ULONG ulVRAMAddress = 0;
|
static ULONG ulVRAMAddress = 0;
|
||||||
|
|
||||||
VOID APIENTRY ExitVMan(VOID)
|
VOID APIENTRY ExitVMan(VOID)
|
||||||
{
|
{
|
||||||
if ( ( ulVRAMAddress != 0 ) && ( hmodVMan != NULLHANDLE ) )
|
if (ulVRAMAddress != 0 && hmodVMan != NULLHANDLE) {
|
||||||
{
|
pfnVMIEntry(0, VMI_CMD_TERMPROC, NULL, NULL);
|
||||||
pfnVMIEntry( 0, VMI_CMD_TERMPROC, NULL, NULL );
|
DosFreeModule(hmodVMan);
|
||||||
DosFreeModule( hmodVMan );
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DosExitList( EXLST_EXIT, (PFNEXITLIST)NULL );
|
DosExitList(EXLST_EXIT, (PFNEXITLIST)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL _vmanInit()
|
static BOOL _vmanInit(void)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
CHAR acBuf[255];
|
CHAR acBuf[255];
|
||||||
INITPROCOUT stInitProcOut;
|
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_os2("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_os2("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_os2("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_os2("DosExitList() failed");
|
||||||
|
}
|
||||||
|
|
||||||
if ( hmodVMan != NULLHANDLE )
|
|
||||||
// Already was initialized.
|
|
||||||
return TRUE;
|
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)
|
static PRECTL _getRectlArray(PVODATA pVOData, ULONG cRects)
|
||||||
{
|
{
|
||||||
PRECTL pRectl;
|
PRECTL pRectl;
|
||||||
|
|
||||||
if ( pVOData->cRectl >= cRects )
|
if (pVOData->cRectl >= cRects)
|
||||||
return pVOData->pRectl;
|
return pVOData->pRectl;
|
||||||
|
|
||||||
pRectl = SDL_realloc( pVOData->pRectl, cRects * sizeof(RECTL) );
|
pRectl = SDL_realloc(pVOData->pRectl, cRects * sizeof(RECTL));
|
||||||
if ( pRectl == NULL )
|
if (pRectl == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pVOData->pRectl = pRectl;
|
pVOData->pRectl = pRectl;
|
||||||
pVOData->cRectl = cRects;
|
pVOData->cRectl = cRects;
|
||||||
return pRectl;
|
return pRectl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PBLTRECT _getBltRectArray(PVODATA pVOData, ULONG cRects)
|
static PBLTRECT _getBltRectArray(PVODATA pVOData, ULONG cRects)
|
||||||
{
|
{
|
||||||
PBLTRECT pBltRect;
|
PBLTRECT pBltRect;
|
||||||
|
|
||||||
if ( pVOData->cBltRect >= cRects )
|
if (pVOData->cBltRect >= cRects)
|
||||||
return pVOData->pBltRect;
|
return pVOData->pBltRect;
|
||||||
|
|
||||||
pBltRect = SDL_realloc( pVOData->pBltRect, cRects * sizeof(BLTRECT) );
|
pBltRect = SDL_realloc(pVOData->pBltRect, cRects * sizeof(BLTRECT));
|
||||||
if ( pBltRect == NULL )
|
if (pBltRect == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pVOData->pBltRect = pBltRect;
|
pVOData->pBltRect = pBltRect;
|
||||||
pVOData->cBltRect = cRects;
|
pVOData->cBltRect = cRects;
|
||||||
return pBltRect;
|
return pBltRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo)
|
static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
GDDMODEINFO sCurModeInfo;
|
GDDMODEINFO sCurModeInfo;
|
||||||
|
|
||||||
if ( !_vmanInit() )
|
if (!_vmanInit())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// Query current (desktop) mode.
|
/* Query current (desktop) mode */
|
||||||
ulRC = pfnVMIEntry( 0, VMI_CMD_QUERYCURRENTMODE, NULL, &sCurModeInfo );
|
ulRC = pfnVMIEntry(0, VMI_CMD_QUERYCURRENTMODE, NULL, &sCurModeInfo);
|
||||||
if ( ulRC != RC_SUCCESS )
|
if (ulRC != RC_SUCCESS) {
|
||||||
{
|
debug_os2("Could not query desktop video mode.");
|
||||||
debug( "Could not query desktop video mode." );
|
return FALSE;
|
||||||
return FALSE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pInfo->ulBPP = sCurModeInfo.ulBpp;
|
pInfo->ulBPP = sCurModeInfo.ulBpp;
|
||||||
pInfo->ulHorizResolution = sCurModeInfo.ulHorizResolution;
|
pInfo->ulHorizResolution = sCurModeInfo.ulHorizResolution;
|
||||||
pInfo->ulVertResolution = sCurModeInfo.ulVertResolution;
|
pInfo->ulVertResolution = sCurModeInfo.ulVertResolution;
|
||||||
pInfo->ulScanLineSize = sCurModeInfo.ulScanLineSize;
|
pInfo->ulScanLineSize = sCurModeInfo.ulScanLineSize;
|
||||||
pInfo->fccColorEncoding = sCurModeInfo.fccColorEncoding;
|
pInfo->fccColorEncoding = sCurModeInfo.fccColorEncoding;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PVODATA voOpen()
|
static PVODATA voOpen(void)
|
||||||
{
|
{
|
||||||
PVODATA pVOData;
|
PVODATA pVOData;
|
||||||
|
|
||||||
if ( !_vmanInit() )
|
if (!_vmanInit())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pVOData = SDL_calloc( 1, sizeof(VODATA) );
|
pVOData = SDL_calloc(1, sizeof(VODATA));
|
||||||
if ( pVOData == NULL )
|
if (pVOData == NULL) {
|
||||||
{
|
SDL_OutOfMemory();
|
||||||
SDL_OutOfMemory();
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return pVOData;
|
return pVOData;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID voClose(PVODATA pVOData)
|
static VOID voClose(PVODATA pVOData)
|
||||||
{
|
{
|
||||||
if ( pVOData->pRectl != NULL )
|
if (pVOData->pRectl != NULL)
|
||||||
SDL_free( pVOData->pRectl );
|
SDL_free(pVOData->pRectl);
|
||||||
|
|
||||||
if ( pVOData->pBltRect != NULL )
|
if (pVOData->pBltRect != NULL)
|
||||||
SDL_free( pVOData->pBltRect );
|
SDL_free(pVOData->pBltRect);
|
||||||
|
|
||||||
voVideoBufFree( pVOData );
|
voVideoBufFree(pVOData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||||
SDL_DisplayMode *pSDLDisplayMode,
|
SDL_DisplayMode *pSDLDisplayMode,
|
||||||
HRGN hrgnShape, BOOL fVisible)
|
HRGN hrgnShape, BOOL fVisible)
|
||||||
{
|
{
|
||||||
HPS hps;
|
HPS hps;
|
||||||
BOOL fSuccess = FALSE;
|
BOOL fSuccess = FALSE;
|
||||||
|
|
||||||
hps = WinGetPS( hwnd );
|
hps = WinGetPS(hwnd);
|
||||||
|
|
||||||
if ( pVOData->hrgnVisible != NULLHANDLE )
|
if (pVOData->hrgnVisible != NULLHANDLE) {
|
||||||
{
|
GpiDestroyRegion(hps, pVOData->hrgnVisible);
|
||||||
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;
|
pVOData->hrgnVisible = NULLHANDLE;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( hrgnShape != NULLHANDLE )
|
|
||||||
GpiCombineRegion( hps, pVOData->hrgnVisible, pVOData->hrgnVisible,
|
|
||||||
hrgnShape, CRGN_AND );
|
|
||||||
fSuccess = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WinQueryWindowRect( hwnd, &pVOData->rectlWin );
|
if (fVisible) {
|
||||||
WinMapWindowPoints( hwnd, HWND_DESKTOP, (PPOINTL)&pVOData->rectlWin, 2 );
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( pSDLDisplayMode != NULL )
|
WinQueryWindowRect(hwnd, &pVOData->rectlWin);
|
||||||
{
|
WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL)&pVOData->rectlWin, 2);
|
||||||
pVOData->ulScreenHeight = pSDLDisplayMode->h;
|
|
||||||
pVOData->ulScreenBytesPerLine =
|
if (pSDLDisplayMode != NULL) {
|
||||||
((PMODEDATA)pSDLDisplayMode->driverdata)->ulScanLineBytes;
|
pVOData->ulScreenHeight = pSDLDisplayMode->h;
|
||||||
|
pVOData->ulScreenBytesPerLine =
|
||||||
|
((MODEDATA *)pSDLDisplayMode->driverdata)->ulScanLineBytes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
WinReleasePS( hps );
|
WinReleasePS(hps);
|
||||||
|
|
||||||
return fSuccess;
|
return fSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||||
ULONG ulBPP, ULONG fccColorEncoding,
|
ULONG ulBPP, ULONG fccColorEncoding,
|
||||||
PULONG pulScanLineSize)
|
PULONG pulScanLineSize)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
ULONG ulScanLineSize = ulWidth * (ulBPP >> 3);
|
ULONG ulScanLineSize = ulWidth * (ulBPP >> 3);
|
||||||
|
|
||||||
// Destroy previous buffer.
|
/* Destroy previous buffer */
|
||||||
voVideoBufFree( pVOData );
|
voVideoBufFree(pVOData);
|
||||||
|
|
||||||
if ( ( ulWidth == 0 ) || ( ulHeight == 0 ) || ( ulBPP == 0 ) )
|
if (ulWidth == 0 || ulHeight == 0 || ulBPP == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Bytes per line.
|
/* Bytes per line */
|
||||||
ulScanLineSize = ( ulScanLineSize + 3 ) & ~3; /* 4-byte aligning */
|
ulScanLineSize = (ulScanLineSize + 3) & ~3; /* 4-byte aligning */
|
||||||
*pulScanLineSize = ulScanLineSize;
|
*pulScanLineSize = ulScanLineSize;
|
||||||
|
|
||||||
ulRC = DosAllocMem( &pVOData->pBuffer,
|
ulRC = DosAllocMem(&pVOData->pBuffer,
|
||||||
(ulHeight * ulScanLineSize) + sizeof(ULONG),
|
(ulHeight * ulScanLineSize) + sizeof(ULONG),
|
||||||
PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE );
|
PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
{
|
debug_os2("DosAllocMem(), rc = %u", ulRC);
|
||||||
debug( "DosAllocMem(), rc = %u", ulRC );
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pVOData->ulBPP = ulBPP;
|
pVOData->ulBPP = ulBPP;
|
||||||
pVOData->ulScanLineSize = ulScanLineSize;
|
pVOData->ulScanLineSize = ulScanLineSize;
|
||||||
pVOData->ulWidth = ulWidth;
|
pVOData->ulWidth = ulWidth;
|
||||||
pVOData->ulHeight = ulHeight;
|
pVOData->ulHeight = ulHeight;
|
||||||
|
|
||||||
return pVOData->pBuffer;
|
return pVOData->pBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID voVideoBufFree(PVODATA pVOData)
|
static VOID voVideoBufFree(PVODATA pVOData)
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
|
|
||||||
if ( pVOData->pBuffer == NULL )
|
if (pVOData->pBuffer == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ulRC = DosFreeMem( pVOData->pBuffer );
|
ulRC = DosFreeMem(pVOData->pBuffer);
|
||||||
if ( ulRC != NO_ERROR )
|
if (ulRC != NO_ERROR) {
|
||||||
debug( "DosFreeMem(), rc = %u", ulRC );
|
debug_os2("DosFreeMem(), rc = %u", ulRC);
|
||||||
else
|
} else {
|
||||||
pVOData->pBuffer = NULL;
|
pVOData->pBuffer = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||||
ULONG cSDLRects)
|
ULONG cSDLRects)
|
||||||
{
|
{
|
||||||
PRECTL prectlDst, prectlScan;
|
PRECTL prectlDst, prectlScan;
|
||||||
HPS hps;
|
HPS hps;
|
||||||
HRGN hrgnUpdate;
|
HRGN hrgnUpdate;
|
||||||
RGNRECT rgnCtl;
|
RGNRECT rgnCtl;
|
||||||
SDL_Rect stSDLRectDef;
|
SDL_Rect stSDLRectDef;
|
||||||
BMAPINFO bmiSrc;
|
BMAPINFO bmiSrc;
|
||||||
BMAPINFO bmiDst;
|
BMAPINFO bmiDst;
|
||||||
PPOINTL pptlSrcOrg;
|
PPOINTL pptlSrcOrg;
|
||||||
PBLTRECT pbrDst;
|
PBLTRECT pbrDst;
|
||||||
HWREQIN sHWReqIn;
|
HWREQIN sHWReqIn;
|
||||||
BITBLTINFO sBitbltInfo = { 0 };
|
BITBLTINFO sBitbltInfo = { 0 };
|
||||||
ULONG ulIdx;
|
ULONG ulIdx;
|
||||||
// RECTL rectlScreenUpdate;
|
/* RECTL rectlScreenUpdate;*/
|
||||||
|
|
||||||
if ( pVOData->pBuffer == NULL )
|
if (pVOData->pBuffer == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ( pVOData->hrgnVisible == NULLHANDLE )
|
if (pVOData->hrgnVisible == NULLHANDLE)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
bmiSrc.ulLength = sizeof(BMAPINFO);
|
bmiSrc.ulLength = sizeof(BMAPINFO);
|
||||||
bmiSrc.ulType = BMAP_MEMORY;
|
bmiSrc.ulType = BMAP_MEMORY;
|
||||||
bmiSrc.ulWidth = pVOData->ulWidth;
|
bmiSrc.ulWidth = pVOData->ulWidth;
|
||||||
bmiSrc.ulHeight = pVOData->ulHeight;
|
bmiSrc.ulHeight = pVOData->ulHeight;
|
||||||
bmiSrc.ulBpp = pVOData->ulBPP;
|
bmiSrc.ulBpp = pVOData->ulBPP;
|
||||||
bmiSrc.ulBytesPerLine = pVOData->ulScanLineSize;
|
bmiSrc.ulBytesPerLine = pVOData->ulScanLineSize;
|
||||||
bmiSrc.pBits = (PBYTE)pVOData->pBuffer;
|
bmiSrc.pBits = (PBYTE)pVOData->pBuffer;
|
||||||
|
|
||||||
bmiDst.ulLength = sizeof(BMAPINFO);
|
bmiDst.ulLength = sizeof(BMAPINFO);
|
||||||
bmiDst.ulType = BMAP_VRAM;
|
bmiDst.ulType = BMAP_VRAM;
|
||||||
bmiDst.pBits = (PBYTE)ulVRAMAddress;
|
bmiDst.pBits = (PBYTE)ulVRAMAddress;
|
||||||
bmiDst.ulWidth = bmiSrc.ulWidth;
|
bmiDst.ulWidth = bmiSrc.ulWidth;
|
||||||
bmiDst.ulHeight = bmiSrc.ulHeight;
|
bmiDst.ulHeight = bmiSrc.ulHeight;
|
||||||
bmiDst.ulBpp = bmiSrc.ulBpp;
|
bmiDst.ulBpp = bmiSrc.ulBpp;
|
||||||
bmiDst.ulBytesPerLine = pVOData->ulScreenBytesPerLine;
|
bmiDst.ulBytesPerLine = pVOData->ulScreenBytesPerLine;
|
||||||
|
|
||||||
// List of update rectangles. This is the intersection of requested
|
/* List of update rectangles. This is the intersection of requested
|
||||||
// rectangles and visible rectangles.
|
* rectangles and visible rectangles. */
|
||||||
|
if (cSDLRects == 0) {
|
||||||
if ( cSDLRects == 0 )
|
/* Full update requested */
|
||||||
{
|
stSDLRectDef.x = 0;
|
||||||
// Full update requested.
|
stSDLRectDef.y = 0;
|
||||||
stSDLRectDef.x = 0;
|
stSDLRectDef.w = bmiSrc.ulWidth;
|
||||||
stSDLRectDef.y = 0;
|
stSDLRectDef.h = bmiSrc.ulHeight;
|
||||||
stSDLRectDef.w = bmiSrc.ulWidth;
|
pSDLRects = &stSDLRectDef;
|
||||||
stSDLRectDef.h = bmiSrc.ulHeight;
|
cSDLRects = 1;
|
||||||
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.
|
/* Make list of destination rectangles (prectlDst) list from the source
|
||||||
sHWReqIn.ulFlags = 0;
|
* list (prectl). */
|
||||||
if ( pfnVMIEntry( 0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL ) != RC_SUCCESS )
|
prectlDst = _getRectlArray(pVOData, cSDLRects);
|
||||||
debug( "pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed" );
|
if (prectlDst == NULL) {
|
||||||
}
|
debug_os2("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;
|
||||||
|
}
|
||||||
|
|
||||||
return sHWReqIn.cScrChangeRects != 0;
|
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_os2("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_os2("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_os2("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_os2("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_os2("pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sHWReqIn.cScrChangeRects != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
Loading…
Reference in New Issue