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:
Ozkan Sezer 2020-10-15 21:37:30 +03:00
parent bdc5129f13
commit a90f0400a5
29 changed files with 3536 additions and 3806 deletions

View File

@ -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. */
} }

View File

@ -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_ */

View File

@ -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: */

View File

@ -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: */

View File

@ -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: */

View File

@ -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: */

View File

@ -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: */

View File

@ -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: */

View File

@ -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: */

View File

@ -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: */

View File

@ -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: */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

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

View File

@ -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: */

View File

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

View File

@ -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: */

View File

@ -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: */

View File

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

View File

@ -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: */

View File

@ -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: */