mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-10-26 12:27:44 +00:00 
			
		
		
		
	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:
		| @@ -34,443 +34,417 @@ | ||||
| /* | ||||
| void lockIncr(volatile int *piVal); | ||||
| #pragma aux lockIncr = \ | ||||
| " lock add [eax], 1 "\ | ||||
| parm [eax];  | ||||
|   " lock add [eax], 1 "\ | ||||
|   parm [eax]; | ||||
|  | ||||
| void lockDecr(volatile int *piVal); | ||||
| #pragma aux lockDecr = \ | ||||
| " lock sub [eax], 1 "\ | ||||
| parm [eax]; | ||||
|   " lock sub [eax], 1 "\ | ||||
|   parm [eax]; | ||||
| */ | ||||
|  | ||||
|  | ||||
| static ULONG _getEnvULong(PSZ pszName, ULONG ulMax, ULONG ulDefault) | ||||
| { | ||||
|   ULONG      ulValue; | ||||
|   PCHAR      pcEnd; | ||||
|   PSZ        pszEnvVal = SDL_getenv( pszName ); | ||||
|     ULONG   ulValue; | ||||
|     PCHAR   pcEnd; | ||||
|     PSZ     pszEnvVal = SDL_getenv(pszName); | ||||
|  | ||||
|   if ( pszEnvVal == NULL ) | ||||
|     return ulDefault; | ||||
|     if (pszEnvVal == NULL) | ||||
|         return ulDefault; | ||||
|  | ||||
|   ulValue = SDL_strtoul( (const char *)pszEnvVal, &pcEnd, 10 ); | ||||
|   return ( pcEnd == pszEnvVal ) || ( ulValue > ulMax ) ? ulDefault : ulMax; | ||||
|     ulValue = SDL_strtoul((const char *)pszEnvVal, &pcEnd, 10); | ||||
|     return (pcEnd == pszEnvVal) || (ulValue > ulMax)? ulDefault : ulMax; | ||||
| } | ||||
|  | ||||
| static int _MCIError(PSZ pszFunc, ULONG ulResult) | ||||
| { | ||||
|   CHAR			acBuf[128]; | ||||
|  | ||||
|   mciGetErrorString( ulResult, acBuf, sizeof(acBuf) ); | ||||
|   return SDL_SetError( "[%s] %s", pszFunc, acBuf ); | ||||
|     CHAR    acBuf[128]; | ||||
|     mciGetErrorString(ulResult, acBuf, sizeof(acBuf)); | ||||
|     return SDL_SetError("[%s] %s", pszFunc, acBuf); | ||||
| } | ||||
|  | ||||
| static void _mixIOError(PSZ pszFunction, ULONG ulRC) | ||||
| { | ||||
|   debug( "%s() - failed, rc = 0x%X (%s)", | ||||
|          pszFunction, ulRC, | ||||
|          ulRC == MCIERR_INVALID_MODE ? "Mixer mode does not match request" | ||||
|          : ulRC == MCIERR_INVALID_BUFFER ? "Caller sent an invalid buffer" | ||||
|          : "unknown" ); | ||||
|     debug_os2("%s() - failed, rc = 0x%X (%s)", | ||||
|               pszFunction, ulRC, | ||||
|               (ulRC == MCIERR_INVALID_MODE)   ? "Mixer mode does not match request" : | ||||
|               (ulRC == MCIERR_INVALID_BUFFER) ? "Caller sent an invalid buffer"     : "unknown"); | ||||
| } | ||||
|  | ||||
| LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, | ||||
|                                 ULONG ulFlags) | ||||
| { | ||||
|   PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)pBuffer->ulUserParm; | ||||
|   ULONG                 ulRC; | ||||
|     SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm; | ||||
|     ULONG   ulRC; | ||||
|  | ||||
|   if ( ulFlags != MIX_WRITE_COMPLETE ) | ||||
|   { | ||||
|     debug( "flags = 0x%X", ulFlags ); | ||||
|     return 0; | ||||
|   } | ||||
|     if (ulFlags != MIX_WRITE_COMPLETE) { | ||||
|         debug_os2("flags = 0x%X", ulFlags); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
| //  lockDecr( (int *)&pAData->ulQueuedBuf ); | ||||
|   ulRC = DosPostEventSem( pAData->hevBuf ); | ||||
|   if ( ( ulRC != NO_ERROR ) && ( ulRC != ERROR_ALREADY_POSTED ) ) | ||||
|     debug( "DosPostEventSem(), rc = %u", ulRC ); | ||||
|     /*lockDecr((int *)&pAData->ulQueuedBuf);*/ | ||||
|     ulRC = DosPostEventSem(pAData->hevBuf); | ||||
|     if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) { | ||||
|         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, | ||||
|                                ULONG ulFlags) | ||||
| { | ||||
|   PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)pBuffer->ulUserParm; | ||||
|   ULONG                 ulRC; | ||||
|     SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm; | ||||
|     ULONG   ulRC; | ||||
|  | ||||
|   if ( ulFlags != MIX_READ_COMPLETE ) | ||||
|   { | ||||
|     debug( "flags = 0x%X", ulFlags ); | ||||
|     return 0; | ||||
|   } | ||||
|     if (ulFlags != MIX_READ_COMPLETE) { | ||||
|         debug_os2("flags = 0x%X", ulFlags); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|   pAData->stMCIMixSetup.pmixRead( pAData->stMCIMixSetup.ulMixHandle, pBuffer, | ||||
|                                   1 ); | ||||
|     pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle, pBuffer, 1); | ||||
|  | ||||
|   ulRC = DosPostEventSem( pAData->hevBuf ); | ||||
|   if ( ( ulRC != NO_ERROR ) && ( ulRC != ERROR_ALREADY_POSTED ) ) | ||||
|     debug( "DosPostEventSem(), rc = %u", ulRC ); | ||||
|     ulRC = DosPostEventSem(pAData->hevBuf); | ||||
|     if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) { | ||||
|         debug_os2("DosPostEventSem(), rc = %u", ulRC); | ||||
|     } | ||||
|  | ||||
|   return 1; | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void OS2_DetectDevices(void) | ||||
| { | ||||
|   MCI_SYSINFO_PARMS      stMCISysInfo; | ||||
|   CHAR                   acBuf[256]; | ||||
|   ULONG                  ulDevicesNum; | ||||
|   MCI_SYSINFO_LOGDEVICE  stLogDevice; | ||||
|   MCI_SYSINFO_PARMS      stSysInfoParams; | ||||
|   ULONG                  ulRC; | ||||
|   ULONG                  ulHandle = 0; | ||||
|     MCI_SYSINFO_PARMS       stMCISysInfo; | ||||
|     CHAR                    acBuf[256]; | ||||
|     ULONG                   ulDevicesNum; | ||||
|     MCI_SYSINFO_LOGDEVICE   stLogDevice; | ||||
|     MCI_SYSINFO_PARMS       stSysInfoParams; | ||||
|     ULONG                   ulRC; | ||||
|     ULONG                   ulHandle = 0; | ||||
|  | ||||
|   acBuf[0] = '\0'; | ||||
|   stMCISysInfo.pszReturn    = acBuf; | ||||
|   stMCISysInfo.ulRetSize    = sizeof(acBuf); | ||||
|   stMCISysInfo.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX; | ||||
|   ulRC = mciSendCommand( 0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_QUANTITY, | ||||
|                          &stMCISysInfo, 0 ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%X", ulRC ); | ||||
|     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; | ||||
|     acBuf[0] = '\0'; | ||||
|     stMCISysInfo.pszReturn    = acBuf; | ||||
|     stMCISysInfo.ulRetSize    = sizeof(acBuf); | ||||
|     stMCISysInfo.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX; | ||||
|     ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_QUANTITY, | ||||
|                           &stMCISysInfo, 0); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%X", ulRC); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     // 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( "MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%X", ulRC ); | ||||
|       continue; | ||||
|     } | ||||
|     ulDevicesNum = atol(stMCISysInfo.pszReturn); | ||||
|  | ||||
|     ulHandle++; | ||||
|     SDL_AddAudioDevice( 0, stLogDevice.szProductInfo, (void *)(ulHandle) ); | ||||
|     ulHandle++; | ||||
|     SDL_AddAudioDevice( 1, stLogDevice.szProductInfo, (void *)(ulHandle) ); | ||||
|   } | ||||
|     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_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) | ||||
| { | ||||
|   PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)this->hidden; | ||||
|   ULONG                 ulRC; | ||||
|     SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)this->hidden; | ||||
|     ULONG   ulRC; | ||||
|  | ||||
|   /* Wait for an audio chunk to finish */ | ||||
|   ulRC = DosWaitEventSem( pAData->hevBuf, 5000 ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|     debug( "DosWaitEventSem(), rc = %u", ulRC ); | ||||
|     /* Wait for an audio chunk to finish */ | ||||
|     ulRC = DosWaitEventSem(pAData->hevBuf, 5000); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosWaitEventSem(), rc = %u", ulRC); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static Uint8 *OS2_GetDeviceBuf(_THIS) | ||||
| { | ||||
|   PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)this->hidden; | ||||
|  | ||||
|   return pAData->aMixBuffers[pAData->ulNextBuf].pBuffer; | ||||
|     SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)this->hidden; | ||||
|     return pAData->aMixBuffers[pAData->ulNextBuf].pBuffer; | ||||
| } | ||||
|  | ||||
| static void OS2_PlayDevice(_THIS) | ||||
| { | ||||
|   PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)this->hidden; | ||||
|   ULONG                 ulRC; | ||||
|   PMCI_MIX_BUFFER       pMixBuffer = &pAData->aMixBuffers[pAData->ulNextBuf]; | ||||
|     SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)this->hidden; | ||||
|     ULONG                 ulRC; | ||||
|     PMCI_MIX_BUFFER       pMixBuffer = &pAData->aMixBuffers[pAData->ulNextBuf]; | ||||
|  | ||||
|   /* Queue it up */ | ||||
| //  lockIncr( (int *)&pAData->ulQueuedBuf ); | ||||
|   ulRC = pAData->stMCIMixSetup.pmixWrite( pAData->stMCIMixSetup.ulMixHandle, | ||||
|                                           pMixBuffer, 1 ); | ||||
|   if ( ulRC != MCIERR_SUCCESS ) | ||||
|     _mixIOError( "pmixWrite", ulRC ); | ||||
|   else | ||||
|     pAData->ulNextBuf = (pAData->ulNextBuf + 1) % pAData->cMixBuffers; | ||||
|     /* Queue it up */ | ||||
|     /*lockIncr((int *)&pAData->ulQueuedBuf);*/ | ||||
|     ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle, | ||||
|                                            pMixBuffer, 1); | ||||
|     if (ulRC != MCIERR_SUCCESS) { | ||||
|         _mixIOError("pmixWrite", ulRC); | ||||
|     } else { | ||||
|         pAData->ulNextBuf = (pAData->ulNextBuf + 1) % pAData->cMixBuffers; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void OS2_CloseDevice(_THIS) | ||||
| { | ||||
|   PSDL_PrivateAudioData pAData = (PSDL_PrivateAudioData)this->hidden; | ||||
|   MCI_GENERIC_PARMS     sMCIGenericParms; | ||||
|   ULONG                 ulRC; | ||||
|     SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)this->hidden; | ||||
|     MCI_GENERIC_PARMS     sMCIGenericParms; | ||||
|     ULONG                 ulRC; | ||||
|  | ||||
|   if ( pAData == NULL ) | ||||
|     return; | ||||
|     if (pAData == NULL) | ||||
|         return; | ||||
|  | ||||
|   /* Close up audio */ | ||||
|   if ( pAData->usDeviceId != (USHORT)~0 ) | ||||
|   { | ||||
|     // Device is open. | ||||
|     if ( pAData->stMCIMixSetup.ulBitsPerSample != 0 ) | ||||
|     { | ||||
|       // Mixer was initialized. | ||||
|       ulRC = mciSendCommand( pAData->usDeviceId, MCI_MIXSETUP, | ||||
|                              MCI_WAIT | MCI_MIXSETUP_DEINIT, | ||||
|                              &pAData->stMCIMixSetup, 0 ); | ||||
|       if ( ulRC != MCIERR_SUCCESS ) | ||||
|         debug( "MCI_MIXSETUP, MCI_MIXSETUP_DEINIT - failed" ); | ||||
|     /* Close up audio */ | ||||
|     if (pAData->usDeviceId != (USHORT)~0) { | ||||
|         /* Device is open. */ | ||||
|         if (pAData->stMCIMixSetup.ulBitsPerSample != 0) { | ||||
|             /* Mixer was initialized. */ | ||||
|             ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP, | ||||
|                                   MCI_WAIT | MCI_MIXSETUP_DEINIT, | ||||
|                                   &pAData->stMCIMixSetup, 0); | ||||
|             if (ulRC != MCIERR_SUCCESS) { | ||||
|                 debug_os2("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 ) | ||||
|     { | ||||
|       // Buffers was allocated. | ||||
|       MCI_BUFFER_PARMS             stMCIBuffer; | ||||
|     if (pAData->hevBuf != NULLHANDLE) | ||||
|         DosCloseEventSem(pAData->hevBuf); | ||||
|  | ||||
|       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( "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 ); | ||||
|     SDL_free(pAData); | ||||
| } | ||||
|  | ||||
| static int OS2_OpenDevice(_THIS, void *handle, const char *devname, | ||||
|                           int iscapture) | ||||
| { | ||||
|   PSDL_PrivateAudioData pAData; | ||||
|   SDL_AudioFormat       SDLAudioFmt; | ||||
|   MCI_AMP_OPEN_PARMS    stMCIAmpOpen; | ||||
|   MCI_BUFFER_PARMS      stMCIBuffer; | ||||
|   ULONG                 ulRC; | ||||
|   ULONG                 ulIdx; | ||||
|   BOOL                  new_freq; | ||||
|     SDL_PrivateAudioData *pAData; | ||||
|     SDL_AudioFormat       SDLAudioFmt; | ||||
|     MCI_AMP_OPEN_PARMS    stMCIAmpOpen; | ||||
|     MCI_BUFFER_PARMS      stMCIBuffer; | ||||
|     ULONG                 ulRC; | ||||
|     ULONG                 ulIdx; | ||||
|     BOOL                  new_freq; | ||||
|  | ||||
|   new_freq = FALSE; | ||||
|   SDL_zero(stMCIAmpOpen); | ||||
|   SDL_zero(stMCIBuffer); | ||||
|     new_freq = FALSE; | ||||
|     SDL_zero(stMCIAmpOpen); | ||||
|     SDL_zero(stMCIBuffer); | ||||
|  | ||||
|   for( SDLAudioFmt = SDL_FirstAudioFormat( this->spec.format ); | ||||
|        SDLAudioFmt != 0; SDLAudioFmt = SDL_NextAudioFormat() ) | ||||
|   { | ||||
|     if ( ( SDLAudioFmt == AUDIO_U8 ) || ( SDLAudioFmt == AUDIO_S16 ) ) | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   if ( SDLAudioFmt == 0 ) | ||||
|   { | ||||
|     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; | ||||
|     for (SDLAudioFmt = SDL_FirstAudioFormat(this->spec.format); | ||||
|          SDLAudioFmt != 0; SDLAudioFmt = SDL_NextAudioFormat()) { | ||||
|         if (SDLAudioFmt == AUDIO_U8 || SDLAudioFmt == AUDIO_S16) | ||||
|             break; | ||||
|     } | ||||
|     if (SDLAudioFmt == 0) { | ||||
|         debug_os2("Unsupported audio format, AUDIO_S16 used"); | ||||
|         SDLAudioFmt = AUDIO_S16; | ||||
|     } | ||||
|     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; | ||||
|   stMCIBuffer.ulNumBuffers = NUM_BUFFERS; | ||||
|   stMCIBuffer.pBufList     = &pAData->aMixBuffers; | ||||
|     ulRC = DosCreateEventSem(NULL, &pAData->hevBuf, DCE_AUTORESET, TRUE); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosCreateEventSem() failed, rc = %u", ulRC); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|   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; | ||||
|     /* 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; | ||||
|  | ||||
|   // 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++ ) | ||||
|   { | ||||
|     pAData->aMixBuffers[ulIdx].ulFlags        = 0; | ||||
|     pAData->aMixBuffers[ulIdx].ulBufferLength = stMCIBuffer.ulBufferSize; | ||||
|     pAData->aMixBuffers[ulIdx].ulUserParm     = (ULONG)pAData; | ||||
|         /* 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); | ||||
|  | ||||
|     memset( ((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer, | ||||
|             this->spec.silence, stMCIBuffer.ulBufferSize ); | ||||
|   } | ||||
|         /* 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); | ||||
|  | ||||
|   // 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; | ||||
|   } | ||||
|         /* 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 ; | ||||
|  | ||||
|   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) | ||||
| { | ||||
|   /* Set the function pointers */ | ||||
|   impl->DetectDevices = OS2_DetectDevices; | ||||
|   impl->OpenDevice    = OS2_OpenDevice; | ||||
|   impl->PlayDevice    = OS2_PlayDevice; | ||||
|   impl->WaitDevice    = OS2_WaitDevice; | ||||
|   impl->GetDeviceBuf  = OS2_GetDeviceBuf; | ||||
|   impl->CloseDevice   = OS2_CloseDevice; | ||||
|     /* Set the function pointers */ | ||||
|     impl->DetectDevices = OS2_DetectDevices; | ||||
|     impl->OpenDevice    = OS2_OpenDevice; | ||||
|     impl->PlayDevice    = OS2_PlayDevice; | ||||
|     impl->WaitDevice    = OS2_WaitDevice; | ||||
|     impl->GetDeviceBuf  = OS2_GetDeviceBuf; | ||||
|     impl->CloseDevice   = OS2_CloseDevice; | ||||
|  | ||||
| // TODO: IMPLEMENT CAPTURE SUPPORT: | ||||
| //  impl->CaptureFromDevice = ; | ||||
| //  impl->FlushCapture = ; | ||||
| //  impl->HasCaptureSupport = SDL_TRUE; | ||||
|  | ||||
|   return 1;   /* this audio target is available. */ | ||||
|     /* TODO: IMPLEMENT CAPTURE SUPPORT: | ||||
|     impl->CaptureFromDevice = ; | ||||
|     impl->FlushCapture = ; | ||||
|     impl->HasCaptureSupport = SDL_TRUE; | ||||
|     */ | ||||
|     return 1; /* this audio target is available. */ | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -35,19 +35,19 @@ | ||||
| /* Hidden "this" pointer for the audio functions */ | ||||
| #define _THIS   SDL_AudioDevice *this | ||||
|  | ||||
| #define NUM_BUFFERS    3 | ||||
| #define NUM_BUFFERS     3 | ||||
|  | ||||
| typedef struct SDL_PrivateAudioData | ||||
| { | ||||
|   USHORT               usDeviceId; | ||||
|   BYTE                 _pad[2]; | ||||
|   MCI_MIXSETUP_PARMS   stMCIMixSetup; | ||||
|   HEV                  hevBuf; | ||||
|   ULONG                ulNextBuf; | ||||
|   ULONG                cMixBuffers; | ||||
|   MCI_MIX_BUFFER       aMixBuffers[NUM_BUFFERS]; | ||||
| //  ULONG                ulQueuedBuf; | ||||
| } SDL_PrivateAudioData, *PSDL_PrivateAudioData; | ||||
|     USHORT              usDeviceId; | ||||
|     BYTE                _pad[2]; | ||||
|     MCI_MIXSETUP_PARMS  stMCIMixSetup; | ||||
|     HEV                 hevBuf; | ||||
|     ULONG               ulNextBuf; | ||||
|     ULONG               cMixBuffers; | ||||
|     MCI_MIX_BUFFER      aMixBuffers[NUM_BUFFERS]; | ||||
| /*  ULONG               ulQueuedBuf;*/ | ||||
| } SDL_PrivateAudioData; | ||||
|  | ||||
| #endif /* SDL_os2mm_h_ */ | ||||
|  | ||||
|   | ||||
| @@ -18,19 +18,21 @@ | ||||
|      misrepresented as being the original software. | ||||
|   3. This notice may not be removed or altered from any source distribution. | ||||
| */ | ||||
|  | ||||
| #include "../../SDL_internal.h" | ||||
|  | ||||
| #if defined(__OS2__) | ||||
|  | ||||
| #include "geniconv/geniconv.h" | ||||
|  | ||||
| // SDL_OS2Quit() will be called from SDL_QuitSubSystem(). | ||||
|  | ||||
| void SDL_OS2Quit() | ||||
| /* SDL_OS2Quit() will be called from SDL_QuitSubSystem() */ | ||||
| void SDL_OS2Quit(void) | ||||
| { | ||||
|   // 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). | ||||
|   libiconv_clean(); | ||||
|     /* 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). */ | ||||
|     libiconv_clean(); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -27,24 +27,26 @@ | ||||
|  | ||||
| #ifdef OS2DEBUG | ||||
| #if (OS2DEBUG-0 >= 2) | ||||
| # define debug(s,...) SDL_LogDebug( SDL_LOG_CATEGORY_APPLICATION, \ | ||||
|                                     __func__"(): "##s, ##__VA_ARGS__ ) | ||||
| # define debug_os2(s,...) SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION,    \ | ||||
|                                  __func__ "(): " ##s,      ##__VA_ARGS__) | ||||
| #else | ||||
| # define debug(s,...) printf( __func__"(): "##s"\n", ##__VA_ARGS__ ) | ||||
| # define debug_os2(s,...) printf(__func__ "(): " ##s "\n", ##__VA_ARGS__) | ||||
| #endif | ||||
|  | ||||
| #else | ||||
| #else /* no debug */ | ||||
|  | ||||
| # define debug(s,...) | ||||
| # define debug_os2(s,...) do {} while (0) | ||||
|  | ||||
| #endif /* OS2DEBUG */ | ||||
|  | ||||
|  | ||||
| /* StrUTF8New() - geniconv/sys2utf8.c */ | ||||
| #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_SysToUTF8(S) StrUTF8New(1,         (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() */ | ||||
| void SDL_OS2Quit(); | ||||
| void SDL_OS2Quit(void); | ||||
|  | ||||
| #endif /* SDL_os2_h_ */ | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -25,38 +25,38 @@ | ||||
|   Andrey Vasilkin, 2016. | ||||
| */ | ||||
|  | ||||
| #define INCL_DOSMODULEMGR     /* Module Manager values */ | ||||
| #define INCL_DOSERRORS        /* Error values */ | ||||
| #define INCL_DOSMODULEMGR   /* Module Manager values */ | ||||
| #define INCL_DOSERRORS      /* Error values */ | ||||
| #include <os2.h> | ||||
|  | ||||
| #include "geniconv.h" | ||||
|  | ||||
| //#define DEBUG | ||||
| /*#define DEBUG*/ | ||||
|  | ||||
| #ifdef DEBUG | ||||
| # include <stdio.h> | ||||
| # define debug(s,...) printf(__func__"(): "##s"\n" ,##__VA_ARGS__) | ||||
| #else | ||||
| # define debug(s,...) | ||||
| # define debug(s,...) do {} while (0) | ||||
| #endif | ||||
|  | ||||
| // Exports from os2iconv.c. | ||||
| /* Exports from os2iconv.c */ | ||||
| extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode); | ||||
| extern size_t _System os2_iconv(iconv_t cd, char* * inbuf, | ||||
|                                 size_t *inbytesleft, char* * outbuf, | ||||
|                                 size_t *outbytesleft); | ||||
| 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 size_t _System (*FNICONV)(iconv_t cd, char* * inbuf, | ||||
|                                   size_t *inbytesleft, char* * outbuf, | ||||
|                                   size_t *outbytesleft); | ||||
| typedef int _System (*FNICONV_CLOSE)(iconv_t cd); | ||||
|  | ||||
| // Used DLL module handle. | ||||
| /* Used DLL module handle */ | ||||
| static HMODULE         hmIconv = NULLHANDLE; | ||||
| // Functions pointers. | ||||
| /* Functions pointers */ | ||||
| static FNICONV_OPEN    fn_iconv_open = NULL; | ||||
| static FNICONV         fn_iconv = 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, | ||||
|                      PSZ pszIconvClose) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   CHAR       acError[256]; | ||||
|     ULONG ulRC; | ||||
|     CHAR  acError[256]; | ||||
|  | ||||
|   ulRC = DosLoadModule( acError, sizeof(acError), pszName, &hmIconv ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "DLL not loaded: %s", &acError ); | ||||
|     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 = DosLoadModule(acError, sizeof(acError), pszName, &hmIconv); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug("DLL not loaded: %s", &acError); | ||||
|         return FALSE; | ||||
|     } | ||||
|  | ||||
|     ulRC = DosQueryProcAddr( hmIconv, 0, pszIconv, (PFN *)&fn_iconv ); | ||||
|     if ( ulRC != NO_ERROR ) | ||||
|     { | ||||
|       debug( "Error: cannot find entry %s in %s", pszIconv, pszName ); | ||||
|       break; | ||||
|     } | ||||
|     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, pszIconvClose, (PFN *)&fn_iconv_close ); | ||||
|     if ( ulRC != NO_ERROR ) | ||||
|     { | ||||
|       debug( "Error: cannot find entry %s in %s", pszIconvClose, pszName ); | ||||
|       break; | ||||
|     } | ||||
|         ulRC = DosQueryProcAddr(hmIconv, 0, pszIconv, (PFN *)&fn_iconv); | ||||
|         if (ulRC != NO_ERROR) { | ||||
|             debug("Error: cannot find entry %s in %s", pszIconv, pszName); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|     debug( "DLL %s used", pszName ); | ||||
|     return TRUE; | ||||
|   } | ||||
|   while( FALSE ); | ||||
|         ulRC = DosQueryProcAddr(hmIconv, 0, pszIconvClose, (PFN *)&fn_iconv_close); | ||||
|         if (ulRC != NO_ERROR) { | ||||
|             debug("Error: cannot find entry %s in %s", pszIconvClose, pszName); | ||||
|           break; | ||||
|         } | ||||
|  | ||||
|   DosFreeModule( hmIconv ); | ||||
|   hmIconv = NULLHANDLE; | ||||
|   return FALSE; | ||||
| } | ||||
|         debug("DLL %s used", pszName); | ||||
|         return TRUE; | ||||
|     } while (FALSE); | ||||
|  | ||||
| static void _init() | ||||
| { | ||||
|   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 ); | ||||
|     DosFreeModule(hmIconv); | ||||
|     hmIconv = NULLHANDLE; | ||||
|     return FALSE; | ||||
| } | ||||
|  | ||||
|     fn_iconv_open  = NULL; | ||||
|     fn_iconv       = NULL; | ||||
|     fn_iconv_close = NULL; | ||||
|   } | ||||
| static void _init(void) | ||||
| { | ||||
|     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) | ||||
| { | ||||
|   _init(); | ||||
|   return fn_iconv_open( tocode, fromcode ); | ||||
|     _init(); | ||||
|     return fn_iconv_open(tocode, fromcode); | ||||
| } | ||||
|  | ||||
| size_t libiconv(iconv_t cd, char* * inbuf, size_t *inbytesleft, | ||||
|                 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) | ||||
| { | ||||
|   return fn_iconv_close( cd ); | ||||
|     return fn_iconv_close(cd); | ||||
| } | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -47,34 +47,39 @@ | ||||
|  | ||||
| #define iconv_clean libiconv_clean | ||||
|  | ||||
| // Non-standard function for iconv to unload the used dynamic library. | ||||
| void libiconv_clean(); | ||||
| /* Non-standard function for iconv to unload the used dynamic library */ | ||||
| void libiconv_clean(void); | ||||
|  | ||||
| iconv_t libiconv_open(const char* tocode, const char* fromcode); | ||||
| size_t libiconv(iconv_t cd, char* * inbuf, size_t *inbytesleft, | ||||
|                  char* * outbuf, size_t *outbytesleft); | ||||
| int libiconv_close(iconv_t cd); | ||||
| iconv_t libiconv_open (const char *tocode, const char *fromcode); | ||||
| int     libiconv_close(iconv_t cd); | ||||
| size_t  libiconv      (iconv_t cd, char **inbuf, size_t *inbytesleft, | ||||
|                        char **outbuf, size_t *outbytesleft); | ||||
|  | ||||
| // System codepage <-> UTF-8. | ||||
|  | ||||
| // StrUTF8() | ||||
| // 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 | ||||
| // 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 | ||||
| // 0 byte(s) or -1 on error. | ||||
| /* System codepage <-> UTF-8 | ||||
|  * | ||||
|  * StrUTF8() | ||||
|  * 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 | ||||
|  * 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 | ||||
|  * 0 byte(s) or -1 on error. | ||||
|  */ | ||||
| int StrUTF8(int fToUTF8, char *pcDst, int cbDst, char *pcSrc, int cbSrc); | ||||
|  | ||||
| // StrUTF8New() | ||||
| // 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 | ||||
| // using libc malloc(). | ||||
| // Returns converted string, terminating two bytes 0 is appended to the result. | ||||
| // Returns null on error. | ||||
| /* StrUTF8New() | ||||
|  * 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 | ||||
|  * using libc malloc(). | ||||
|  * Returns converted string, terminating two bytes 0 is appended to the result. | ||||
|  * Returns null on error. | ||||
|  */ | ||||
| char *StrUTF8New(int fToUTF8, char *pcStr, int cbStr); | ||||
|  | ||||
| // StrUTF8Free() | ||||
| // Deallocates the memory block located by StrUTF8New() (just libc free()). | ||||
| /* StrUTF8Free() | ||||
|  * Deallocates the memory block located by StrUTF8New() (just libc free()). | ||||
|  */ | ||||
| void StrUTF8Free(char *pszStr); | ||||
|  | ||||
| #endif // GENICONV_H | ||||
| #endif /* GENICONV_H */ | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -28,17 +28,16 @@ | ||||
| #include "os2cp.h" | ||||
|  | ||||
| typedef struct _CP2NAME { | ||||
|   ULONG		ulCode; | ||||
|   PSZ		pszName; | ||||
|   ULONG ulCode; | ||||
|   PSZ  pszName; | ||||
| } CP2NAME; | ||||
|  | ||||
| typedef struct _NAME2CP { | ||||
|   PSZ		pszName; | ||||
|   ULONG		ulCode; | ||||
|   PSZ  pszName; | ||||
|   ULONG ulCode; | ||||
| } NAME2CP; | ||||
|  | ||||
| static CP2NAME		aCP2Name[] = | ||||
| { | ||||
| static CP2NAME aCP2Name[] = { | ||||
|   {367, "ANSI_X3.4-1968"}, | ||||
|   {813, "ECMA-118"}, | ||||
|   {819, "CP819"}, | ||||
| @@ -85,8 +84,7 @@ static CP2NAME		aCP2Name[] = | ||||
|   {62210, "HEBREW"} | ||||
| }; | ||||
|  | ||||
| static NAME2CP		aName2CP[] = | ||||
| { | ||||
| static NAME2CP aName2CP[] = { | ||||
|   {"850", 850}, | ||||
|   {"862", 862}, | ||||
|   {"866", 866}, | ||||
| @@ -297,109 +295,107 @@ static NAME2CP		aName2CP[] = | ||||
|   {"X0201", 896} | ||||
| }; | ||||
|  | ||||
| char * os2cpToName(unsigned long cp) | ||||
| char *os2cpToName(unsigned long cp) | ||||
| { | ||||
|   ULONG		ulLo = 0; | ||||
|   ULONG		ulHi = ( sizeof(aCP2Name) / sizeof(struct _CP2NAME) ) - 1; | ||||
|   ULONG		ulNext; | ||||
|   LONG		lFound = -1; | ||||
|     ULONG ulLo = 0; | ||||
|     ULONG ulHi = (sizeof(aCP2Name) / sizeof(struct _CP2NAME)) - 1; | ||||
|     ULONG ulNext; | ||||
|     LONG  lFound = -1; | ||||
|  | ||||
|   if ( cp == SYSTEM_CP ) | ||||
|   { | ||||
|     ULONG	aulCP[3]; | ||||
|     ULONG	cCP; | ||||
|     if (cp == SYSTEM_CP) { | ||||
|         ULONG aulCP[3]; | ||||
|         ULONG cCP; | ||||
|  | ||||
|     if ( DosQueryCp( sizeof(aulCP), aulCP, &cCP ) != NO_ERROR ) | ||||
|       return NULL; | ||||
|         if (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR) | ||||
|             return NULL; | ||||
|  | ||||
|     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; | ||||
|         cp = aulCP[0]; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   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) | ||||
| { | ||||
|   ULONG		ulLo = 0; | ||||
|   ULONG		ulHi = ( sizeof(aName2CP) / sizeof(struct _NAME2CP) ) - 1; | ||||
|   ULONG		ulNext; | ||||
|   LONG		lFound = -1; | ||||
|   LONG		lCmp; | ||||
|   PCHAR		pcEnd; | ||||
|   CHAR		acBuf[64]; | ||||
|     ULONG ulLo = 0; | ||||
|     ULONG ulHi = (sizeof(aName2CP) / sizeof(struct _NAME2CP)) - 1; | ||||
|     ULONG ulNext; | ||||
|     LONG  lFound = -1; | ||||
|     LONG  lCmp; | ||||
|     PCHAR pcEnd; | ||||
|     CHAR  acBuf[64]; | ||||
|  | ||||
|   if ( cp == NULL ) | ||||
|   { | ||||
|     ULONG	aulCP[3]; | ||||
|     ULONG	cCP; | ||||
|     if (cp == NULL) { | ||||
|         ULONG aulCP[3]; | ||||
|         ULONG cCP; | ||||
|  | ||||
|     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 (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR)? 0 : aulCP[0]; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return lFound == -1 ? 0 : aName2CP[lFound].ulCode; | ||||
|     while (isspace(*cp)) | ||||
|         cp++; | ||||
|  | ||||
|     pcEnd = strchr(cp, ' '); | ||||
|     if (pcEnd == NULL) | ||||
|         pcEnd = strchr(cp, '\0'); | ||||
|  | ||||
|     ulNext = pcEnd - cp; | ||||
|     if (ulNext >= sizeof(acBuf)) | ||||
|         return 0; | ||||
|  | ||||
|     memcpy(acBuf, cp, ulNext); | ||||
|     acBuf[ulNext] = '\0'; | ||||
|     strupr(acBuf); | ||||
|  | ||||
|     lCmp = strcmp(aName2CP[0].pszName, acBuf); | ||||
|     if (lCmp > 0) | ||||
|         return 0; | ||||
|     else if (lCmp == 0) | ||||
|         return aName2CP[0].ulCode; | ||||
|  | ||||
|     lCmp = strcmp(aName2CP[ulHi].pszName, acBuf); | ||||
|     if (lCmp < 0) | ||||
|         return 0; | ||||
|     else if (lCmp == 0) | ||||
|         return aName2CP[ulHi].ulCode; | ||||
|  | ||||
|     while ((ulHi - ulLo) > 1) { | ||||
|         ulNext = (ulLo + ulHi) / 2; | ||||
|  | ||||
|         lCmp = strcmp(aName2CP[ulNext].pszName, acBuf); | ||||
|         if (lCmp < 0) | ||||
|             ulLo = ulNext; | ||||
|         else if (lCmp > 0) | ||||
|             ulHi = ulNext; | ||||
|         else { | ||||
|             lFound = ulNext; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return (lFound == -1)? 0 : aName2CP[lFound].ulCode; | ||||
| } | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -24,7 +24,9 @@ | ||||
|  | ||||
| #define SYSTEM_CP	0 | ||||
|  | ||||
| char * os2cpToName(unsigned long cp); | ||||
| char *os2cpToName(unsigned long cp); | ||||
| unsigned long os2cpFromName(char *cp); | ||||
|  | ||||
| #endif // OS2CP_H | ||||
| #endif /* OS2CP_H */ | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -39,7 +39,7 @@ | ||||
| #endif | ||||
| #include "os2cp.h" | ||||
|  | ||||
| #define		MAX_CP_NAME_LEN		64 | ||||
| #define MAX_CP_NAME_LEN 64 | ||||
|  | ||||
| typedef struct iuconv_obj { | ||||
|   UconvObject	uo_tocode; | ||||
| @@ -54,232 +54,211 @@ typedef struct iuconv_obj { | ||||
|  | ||||
| static int _createUconvObj(const char *code, UconvObject *uobj) | ||||
| { | ||||
|   UniChar	uc_code[MAX_CP_NAME_LEN]; | ||||
|   int		i; | ||||
|   const char	*ch = code; | ||||
|     UniChar uc_code[MAX_CP_NAME_LEN]; | ||||
|     int i; | ||||
|     const char *ch = code; | ||||
|  | ||||
|   if ( code == NULL ) | ||||
|     uc_code[0] = 0; | ||||
|   else | ||||
|   { | ||||
|     for( i = 0; i < MAX_CP_NAME_LEN; i++ ) | ||||
|     { | ||||
|       uc_code[i] = (unsigned short)*ch; | ||||
|       if ( !(*ch) ) break; | ||||
|       ch++; | ||||
|     if (code == NULL) | ||||
|         uc_code[0] = 0; | ||||
|     else { | ||||
|         for (i = 0; i < MAX_CP_NAME_LEN; i++) { | ||||
|             uc_code[i] = (unsigned short)*ch; | ||||
|             if (! (*ch)) | ||||
|                 break; | ||||
|             ch++; | ||||
|         } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return UniCreateUconvObject( uc_code, uobj ); | ||||
|     return UniCreateUconvObject(uc_code, uobj); | ||||
| } | ||||
|  | ||||
| static int uconv_open(const char *code, UconvObject *uobj) | ||||
| { | ||||
|   int		rc; | ||||
|     int rc; | ||||
|  | ||||
|   if ( !stricmp( code, "UTF-16" ) ) | ||||
|   { | ||||
|     *uobj = NULL; | ||||
|     return ULS_SUCCESS; | ||||
|   } | ||||
|     if (!stricmp(code, "UTF-16")) { | ||||
|         *uobj = NULL; | ||||
|         return ULS_SUCCESS; | ||||
|     } | ||||
|  | ||||
|   rc = _createUconvObj( code, uobj ); | ||||
|   if ( rc != ULS_SUCCESS ) | ||||
|   { | ||||
|     unsigned long	cp = os2cpFromName( (char *)code ); | ||||
|     char		cp_name[16]; | ||||
|     rc = _createUconvObj(code, uobj); | ||||
|     if (rc != ULS_SUCCESS) { | ||||
|         unsigned long cp = os2cpFromName((char *)code); | ||||
|         char cp_name[16]; | ||||
|  | ||||
|     if ( cp != 0 && _snprintf( cp_name, sizeof(cp_name), "IBM-%u", cp ) > 0 ) | ||||
|       rc = _createUconvObj( cp_name, uobj ); | ||||
|   } | ||||
|         if (cp != 0 && _snprintf(cp_name, sizeof(cp_name), "IBM-%u", cp) > 0) | ||||
|             rc = _createUconvObj(cp_name, uobj); | ||||
|     } | ||||
|  | ||||
|   return rc; | ||||
|     return rc; | ||||
| } | ||||
|  | ||||
|  | ||||
| extern iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode) | ||||
| { | ||||
|   UconvObject	uo_tocode; | ||||
|   UconvObject	uo_fromcode; | ||||
|   int		rc; | ||||
|   iuconv_obj	*iuobj; | ||||
|     UconvObject uo_tocode; | ||||
|     UconvObject uo_fromcode; | ||||
|     int rc; | ||||
|     iuconv_obj *iuobj; | ||||
|  | ||||
|   if ( tocode == NULL ) | ||||
|     tocode = ""; | ||||
|     if (tocode == NULL) | ||||
|         tocode = ""; | ||||
|  | ||||
|   if ( fromcode == NULL ) | ||||
|     fromcode = ""; | ||||
|     if (fromcode == NULL) | ||||
|         fromcode = ""; | ||||
|  | ||||
|   if ( stricmp(tocode, fromcode) != 0 ) | ||||
|   { | ||||
|     rc = uconv_open( fromcode, &uo_fromcode ); | ||||
|     if ( rc != ULS_SUCCESS ) | ||||
|     { | ||||
|       errno = EINVAL; | ||||
|       return (iconv_t)(-1); | ||||
|     if (stricmp(tocode, fromcode) != 0) { | ||||
|         rc = uconv_open(fromcode, &uo_fromcode); | ||||
|         if (rc != ULS_SUCCESS) { | ||||
|             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 ); | ||||
|     if ( rc != ULS_SUCCESS ) | ||||
|     { | ||||
|       UniFreeUconvObject( uo_fromcode ); | ||||
|       errno = EINVAL; | ||||
|       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; | ||||
|     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 | ||||
|   DosCreateMutexSem( NULL, &iuobj->hMtx, 0, FALSE ); | ||||
|     DosCreateMutexSem(NULL, &iuobj->hMtx, 0, FALSE); | ||||
| #endif | ||||
|  | ||||
|   return iuobj; | ||||
|     return iuobj; | ||||
| } | ||||
|  | ||||
| extern size_t _System os2_iconv(iconv_t cd, char* * inbuf, | ||||
|                                 size_t *inbytesleft, | ||||
|                                 char* * outbuf, size_t *outbytesleft) | ||||
| { | ||||
|   UconvObject	uo_tocode = ((iuconv_obj *)(cd))->uo_tocode; | ||||
|   UconvObject	uo_fromcode = ((iuconv_obj *)(cd))->uo_fromcode; | ||||
|   size_t	nonIdenticalConv = 0;   | ||||
|   UniChar	*uc_buf; | ||||
|   size_t	uc_buf_len; | ||||
|   UniChar	**uc_str; | ||||
|   size_t	*uc_str_len; | ||||
|   int		rc; | ||||
|   size_t	ret = (size_t)(-1); | ||||
|     UconvObject uo_tocode = ((iuconv_obj *)(cd))->uo_tocode; | ||||
|     UconvObject uo_fromcode = ((iuconv_obj *)(cd))->uo_fromcode; | ||||
|     size_t nonIdenticalConv = 0; | ||||
|     UniChar *uc_buf; | ||||
|     size_t uc_buf_len; | ||||
|     UniChar **uc_str; | ||||
|     size_t *uc_str_len; | ||||
|     int rc; | ||||
|     size_t ret = (size_t)(-1); | ||||
|  | ||||
|   if ( uo_tocode == NULL && uo_fromcode == NULL ) | ||||
|   { | ||||
|     uc_buf_len = min( *inbytesleft, *outbytesleft ); | ||||
|     memcpy( *outbuf, *inbuf, uc_buf_len ); | ||||
|     *inbytesleft -= uc_buf_len; | ||||
|     *outbytesleft -= uc_buf_len; | ||||
|     outbuf += uc_buf_len; | ||||
|     inbuf += uc_buf_len; | ||||
|     return uc_buf_len; | ||||
|   } | ||||
|     if (uo_tocode == NULL && uo_fromcode == NULL) { | ||||
|         uc_buf_len = min(*inbytesleft, *outbytesleft); | ||||
|         memcpy(*outbuf, *inbuf, uc_buf_len); | ||||
|         *inbytesleft -= uc_buf_len; | ||||
|         *outbytesleft -= uc_buf_len; | ||||
|         outbuf += uc_buf_len; | ||||
|         inbuf += uc_buf_len; | ||||
|         return uc_buf_len; | ||||
|     } | ||||
|  | ||||
| #ifdef ICONV_THREAD_SAFE | ||||
|   DosRequestMutexSem( ((iuconv_obj *)(cd))->hMtx, SEM_INDEFINITE_WAIT ); | ||||
|     DosRequestMutexSem(((iuconv_obj *)(cd))->hMtx, SEM_INDEFINITE_WAIT); | ||||
| #endif | ||||
|  | ||||
|   if ( uo_tocode && uo_fromcode &&  | ||||
|        (( ((iuconv_obj *)(cd))->buf_len >> 1 ) < (*inbytesleft)) ) | ||||
|   { | ||||
|     if ( ( ((iuconv_obj *)(cd))->buf ) != NULL ) | ||||
|       free( ((iuconv_obj *)(cd))->buf ); | ||||
|     ((iuconv_obj *)(cd))->buf_len = *inbytesleft << 1; | ||||
|     ((iuconv_obj *)(cd))->buf = (UniChar *)malloc( ((iuconv_obj *)(cd))->buf_len ); | ||||
|   } | ||||
|     if (uo_tocode && uo_fromcode && | ||||
|         (((iuconv_obj *)cd)->buf_len >> 1) < *inbytesleft) { | ||||
|         if (((iuconv_obj *)cd)->buf != NULL) | ||||
|             free(((iuconv_obj *)cd)->buf); | ||||
|         ((iuconv_obj *)cd)->buf_len = *inbytesleft << 1; | ||||
|         ((iuconv_obj *)cd)->buf = (UniChar *)malloc(((iuconv_obj *)cd)->buf_len); | ||||
|     } | ||||
|  | ||||
|   if ( uo_fromcode ) | ||||
|   { | ||||
|     if ( uo_tocode ) | ||||
|     { | ||||
|       uc_buf = ((iuconv_obj *)(cd))->buf; | ||||
|       uc_buf_len = ((iuconv_obj *)(cd))->buf_len; | ||||
|       uc_str = &uc_buf; | ||||
|     } | ||||
|     else { | ||||
|       uc_str = (UniChar **)outbuf; | ||||
|       uc_buf_len = *outbytesleft; | ||||
|     } | ||||
|     uc_buf_len = uc_buf_len >> 1; | ||||
|     uc_str_len = &uc_buf_len; | ||||
|     rc = UniUconvToUcs( uo_fromcode, (void **)inbuf, inbytesleft,  | ||||
|                         uc_str, uc_str_len, &nonIdenticalConv ); | ||||
|     uc_buf_len = uc_buf_len << 1; | ||||
|     if ( !uo_tocode ) | ||||
|       *outbytesleft = uc_buf_len; | ||||
|     if (uo_fromcode) { | ||||
|         if (uo_tocode) { | ||||
|             uc_buf = ((iuconv_obj *)cd)->buf; | ||||
|             uc_buf_len = ((iuconv_obj *)cd)->buf_len; | ||||
|             uc_str = &uc_buf; | ||||
|         } else { | ||||
|             uc_str = (UniChar **)outbuf; | ||||
|             uc_buf_len = *outbytesleft; | ||||
|         } | ||||
|         uc_buf_len = uc_buf_len >> 1; | ||||
|         uc_str_len = &uc_buf_len; | ||||
|         rc = UniUconvToUcs(uo_fromcode, (void **)inbuf, inbytesleft, | ||||
|                            uc_str, uc_str_len, &nonIdenticalConv); | ||||
|         uc_buf_len = uc_buf_len << 1; | ||||
|         if (!uo_tocode) | ||||
|             *outbytesleft = uc_buf_len; | ||||
|  | ||||
|     if ( rc != ULS_SUCCESS ) | ||||
|     { | ||||
|       errno = EILSEQ; | ||||
|       goto done; | ||||
|         if (rc != ULS_SUCCESS) { | ||||
|             errno = EILSEQ; | ||||
|             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; | ||||
|         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: | ||||
|  | ||||
| #ifdef ICONV_THREAD_SAFE | ||||
|   DosReleaseMutexSem( ((iuconv_obj *)(cd))->hMtx ); | ||||
|     DosReleaseMutexSem(((iuconv_obj *)cd)->hMtx); | ||||
| #endif | ||||
|   return ret; | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| extern int _System os2_iconv_close(iconv_t cd) | ||||
| int _System os2_iconv_close(iconv_t cd) | ||||
| { | ||||
|   if ( !cd ) | ||||
|     return 0; | ||||
|     if (!cd) return 0; | ||||
|  | ||||
| #ifdef ICONV_THREAD_SAFE | ||||
|   DosCloseMutexSem( ((iuconv_obj *)(cd))->hMtx ); | ||||
|     DosCloseMutexSem(((iuconv_obj *)cd)->hMtx); | ||||
| #endif | ||||
|   if ( ((iuconv_obj *)(cd))->uo_tocode != NULL ) | ||||
|     UniFreeUconvObject( ((iuconv_obj *)(cd))->uo_tocode ); | ||||
|   if ( ((iuconv_obj *)(cd))->uo_fromcode != NULL ) | ||||
|     UniFreeUconvObject( ((iuconv_obj *)(cd))->uo_fromcode ); | ||||
|     if (((iuconv_obj *)cd)->uo_tocode != NULL) | ||||
|         UniFreeUconvObject(((iuconv_obj *)cd)->uo_tocode); | ||||
|     if (((iuconv_obj *)cd)->uo_fromcode != NULL) | ||||
|         UniFreeUconvObject(((iuconv_obj *)cd)->uo_fromcode); | ||||
|  | ||||
|   if ( ( ((iuconv_obj *)(cd))->buf ) != NULL ) | ||||
|     free( ((iuconv_obj *)(cd))->buf ); | ||||
|     if (((iuconv_obj *)cd)->buf != NULL) | ||||
|         free(((iuconv_obj *)cd)->buf); | ||||
|  | ||||
|   free(cd); | ||||
|     free(cd); | ||||
|  | ||||
|   return 0; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -24,94 +24,84 @@ | ||||
|  | ||||
| int StrUTF8(int fToUTF8, char *pcDst, int cbDst, char *pcSrc, int cbSrc) | ||||
| { | ||||
|   size_t     rc; | ||||
|   char       *pcDstStart = pcDst; | ||||
|   iconv_t    cd; | ||||
|   char       *pszToCP, *pszFromCP; | ||||
|   int        fError = 0; | ||||
|     size_t  rc; | ||||
|     char   *pcDstStart = pcDst; | ||||
|     iconv_t cd; | ||||
|     char   *pszToCP, *pszFromCP; | ||||
|     int     fError = 0; | ||||
|  | ||||
|   if ( cbDst < 4 ) | ||||
|     return -1; | ||||
|     if (cbDst < 4) | ||||
|         return -1; | ||||
|  | ||||
|   if ( fToUTF8 ) | ||||
|   { | ||||
|     pszToCP   = "UTF-8"; | ||||
|     pszFromCP = ""; | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     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; | ||||
|     if (fToUTF8) { | ||||
|         pszToCP   = "UTF-8"; | ||||
|         pszFromCP = ""; | ||||
|     } else { | ||||
|         pszToCP   = ""; | ||||
|         pszFromCP = "UTF-8"; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   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). | ||||
|   if ( fToUTF8 ) | ||||
|   { | ||||
|     if ( cbDst < 1 ) | ||||
|     { | ||||
|       pcDst--; | ||||
|       fError = 1;      // The destination buffer overflow. | ||||
|     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; | ||||
|         } | ||||
|     } | ||||
|     *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) | ||||
| { | ||||
|   int        cbNewStr = ( ( cbStr > 4 ? cbStr : 4 ) + 1 ) * 2; | ||||
|   char       *pszNewStr = malloc( cbNewStr ); | ||||
|     int   cbNewStr = (((cbStr > 4)? cbStr : 4) + 1) * 2; | ||||
|     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; | ||||
|  | ||||
|   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) | ||||
| { | ||||
|   free( pszStr ); | ||||
|     free(pszStr); | ||||
| } | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -26,43 +26,44 @@ | ||||
|  | ||||
| int main(void) | ||||
| { | ||||
|   char       acBuf[128]; | ||||
|   char       *inbuf = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"; // KOI8-R string. | ||||
|   size_t     inbytesleft = strlen( inbuf ); | ||||
|   char       *outbuf = &acBuf; | ||||
|   size_t     outbytesleft = sizeof( acBuf ); | ||||
|   iconv_t    ic; | ||||
|     char    acBuf[128]; | ||||
|     char   *inbuf = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"; /* KOI8-R string */ | ||||
|     size_t  inbytesleft = strlen(inbuf); | ||||
|     char   *outbuf = acBuf; | ||||
|     size_t  outbytesleft = sizeof(acBuf); | ||||
|     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" ); | ||||
|   if ( ic == (iconv_t)(-1) ) | ||||
|   { | ||||
|     puts( "iconv_open() fail" ); | ||||
|     return 1; | ||||
|   } | ||||
|     iconv(ic, &inbuf, &inbytesleft, &outbuf, &outbytesleft); | ||||
|     printf("KOI8-R to system cp: %s\n", acBuf); | ||||
|  | ||||
|   iconv( ic, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); | ||||
|   printf( "KOI8-R to system cp.: %s\n", &acBuf ); | ||||
|     iconv_close(ic); | ||||
|  | ||||
|   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(). | ||||
|   inbuf = StrUTF8New( 1, &acBuf, strlen( &acBuf ) ); | ||||
|     /* UTF-8 -> system cp. by StrUTF8() */ | ||||
|     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(). | ||||
|   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); | ||||
|  | ||||
|   free( inbuf ); | ||||
|     /* Unload used DLL */ | ||||
|     iconv_clean(); | ||||
|  | ||||
|   // Unload used DLL. | ||||
|   iconv_clean(); | ||||
|  | ||||
|   puts( "Done." ); | ||||
|   return 0; | ||||
|     puts("Done."); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -38,90 +38,90 @@ | ||||
| char * | ||||
| SDL_GetBasePath(void) | ||||
| { | ||||
|   PTIB       tib; | ||||
|   PPIB       pib; | ||||
|   ULONG      ulRC = DosGetInfoBlocks(&tib, &pib); | ||||
|   PCHAR      pcEnd; | ||||
|   ULONG      cbResult; | ||||
|   CHAR       acBuf[_MAX_PATH]; | ||||
|     PTIB    tib; | ||||
|     PPIB    pib; | ||||
|     ULONG   ulRC = DosGetInfoBlocks(&tib, &pib); | ||||
|     PCHAR   pcEnd; | ||||
|     ULONG   cbResult; | ||||
|     CHAR    acBuf[_MAX_PATH]; | ||||
|  | ||||
|   if (ulRC != NO_ERROR) { | ||||
|     debug("DosGetInfoBlocks() failed, rc = %u", ulRC); | ||||
|     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; | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosGetInfoBlocks() failed, rc = %u", ulRC); | ||||
|         return NULL; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   cbResult = pcEnd - pib->pib_pchcmd; | ||||
|   SDL_memcpy(acBuf, pib->pib_pchcmd, cbResult); | ||||
|   acBuf[cbResult] = '\0'; | ||||
|     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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   return OS2_SysToUTF8(acBuf); | ||||
|     cbResult = pcEnd - pib->pib_pchcmd; | ||||
|     SDL_memcpy(acBuf, pib->pib_pchcmd, cbResult); | ||||
|     acBuf[cbResult] = '\0'; | ||||
|  | ||||
|     return OS2_SysToUTF8(acBuf); | ||||
| } | ||||
|  | ||||
| char * | ||||
| SDL_GetPrefPath(const char *org, const char *app) | ||||
| { | ||||
|   PSZ        pszPath; | ||||
|   CHAR       acBuf[_MAX_PATH]; | ||||
|   int        lPosApp, lPosOrg; | ||||
|   PSZ        pszApp, pszOrg; | ||||
|     PSZ     pszPath; | ||||
|     CHAR    acBuf[_MAX_PATH]; | ||||
|     int     lPosApp, lPosOrg; | ||||
|     PSZ     pszApp, pszOrg; | ||||
|  | ||||
|   if (!app) { | ||||
|       SDL_InvalidParamError("app"); | ||||
|       return NULL; | ||||
|   } | ||||
|     if (!app) { | ||||
|         SDL_InvalidParamError("app"); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   pszPath = SDL_getenv( "HOME" ); | ||||
|   if (!pszPath) { | ||||
|     pszPath = SDL_getenv( "ETC" ); | ||||
|     pszPath = SDL_getenv("HOME"); | ||||
|     if (!pszPath) { | ||||
|       SDL_SetError("HOME or ETC environment not set"); | ||||
|       return NULL; | ||||
|         pszPath = SDL_getenv("ETC"); | ||||
|         if (!pszPath) { | ||||
|             SDL_SetError("HOME or ETC environment not set"); | ||||
|             return NULL; | ||||
|         } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (!org) { | ||||
|     lPosApp = SDL_snprintf(acBuf, sizeof(acBuf) - 1, "%s", pszPath); | ||||
|   } else { | ||||
|     pszOrg = OS2_UTF8ToSys(org); | ||||
|     if (!pszOrg) { | ||||
|       SDL_OutOfMemory(); | ||||
|       return NULL; | ||||
|     if (!org) { | ||||
|         lPosApp = SDL_snprintf(acBuf, sizeof(acBuf) - 1, "%s", pszPath); | ||||
|     } else { | ||||
|         pszOrg = OS2_UTF8ToSys(org); | ||||
|         if (!pszOrg) { | ||||
|             SDL_OutOfMemory(); | ||||
|             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); | ||||
|     SDL_free(pszOrg); | ||||
|   } | ||||
|   if (lPosApp < 0) | ||||
|     return NULL; | ||||
|     if (lPosApp < 0) | ||||
|         return NULL; | ||||
|  | ||||
|   DosCreateDir(acBuf, NULL); | ||||
|     DosCreateDir(acBuf, NULL); | ||||
|  | ||||
|   pszApp = OS2_UTF8ToSys(app); | ||||
|   if (!pszApp) { | ||||
|     SDL_OutOfMemory(); | ||||
|     return NULL; | ||||
|   } | ||||
|     pszApp = OS2_UTF8ToSys(app); | ||||
|     if (!pszApp) { | ||||
|         SDL_OutOfMemory(); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   lPosOrg = SDL_snprintf(&acBuf[lPosApp], sizeof(acBuf) - lPosApp - 1, "\\%s", pszApp); | ||||
|   SDL_free(pszApp); | ||||
|   if (lPosOrg < 0) | ||||
|     return NULL; | ||||
|     lPosOrg = SDL_snprintf(&acBuf[lPosApp], sizeof(acBuf) - lPosApp - 1, "\\%s", pszApp); | ||||
|     SDL_free(pszApp); | ||||
|     if (lPosOrg < 0) | ||||
|         return NULL; | ||||
|  | ||||
|   DosCreateDir(acBuf, NULL); | ||||
|   *((PUSHORT)&acBuf[lPosApp + lPosOrg]) = (USHORT)'\0\\'; | ||||
|     DosCreateDir(acBuf, NULL); | ||||
|     *((PUSHORT)&acBuf[lPosApp + lPosOrg]) = (USHORT)'\0\\'; | ||||
|  | ||||
|   return OS2_SysToUTF8(acBuf); | ||||
|     return OS2_SysToUTF8(acBuf); | ||||
| } | ||||
|  | ||||
| #endif /* SDL_FILESYSTEM_OS2 */ | ||||
|   | ||||
| @@ -35,41 +35,42 @@ | ||||
| void * | ||||
| SDL_LoadObject(const char *sofile) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   HMODULE    hModule; | ||||
|   PSZ        pszModName = OS2_UTF8ToSys( sofile ); | ||||
|   CHAR       acError[256]; | ||||
|     ULONG   ulRC; | ||||
|     HMODULE hModule; | ||||
|     PSZ     pszModName = OS2_UTF8ToSys(sofile); | ||||
|     CHAR    acError[256]; | ||||
|  | ||||
|   ulRC = DosLoadModule(acError, sizeof(acError), pszModName, &hModule); | ||||
|   SDL_free(pszModName); | ||||
|   if (ulRC != NO_ERROR) { | ||||
|     SDL_SetError( "Failed loading %s (E%u)", acError, ulRC ); | ||||
|     return NULL; | ||||
|   } | ||||
|     ulRC = DosLoadModule(acError, sizeof(acError), pszModName, &hModule); | ||||
|     SDL_free(pszModName); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         SDL_SetError("Failed loading %s (E%u)", acError, ulRC); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   return (void *)hModule; | ||||
|     return (void *)hModule; | ||||
| } | ||||
|  | ||||
| void * | ||||
| SDL_LoadFunction(void *handle, const char *name) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   PFN        pFN; | ||||
|     ULONG   ulRC; | ||||
|     PFN     pFN; | ||||
|  | ||||
|   ulRC = DosQueryProcAddr((HMODULE)handle, 0, name, &pFN); | ||||
|   if (ulRC != NO_ERROR) { | ||||
|     SDL_SetError( "Failed loading procedure %s (E%u)", name, ulRC ); | ||||
|     return NULL; | ||||
|   } | ||||
|     ulRC = DosQueryProcAddr((HMODULE)handle, 0, name, &pFN); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         SDL_SetError("Failed loading procedure %s (E%u)", name, ulRC); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   return (void *)pFN; | ||||
|     return (void *)pFN; | ||||
| } | ||||
|  | ||||
| void | ||||
| SDL_UnloadObject(void *handle) | ||||
| { | ||||
|   if (handle != NULL) | ||||
|     DosFreeModule( (HMODULE)handle ); | ||||
|     if (handle != NULL) { | ||||
|         DosFreeModule((HMODULE)handle); | ||||
|     } | ||||
| } | ||||
|  | ||||
| #endif /* SDL_LOADSO_OS2 */ | ||||
|   | ||||
| @@ -32,99 +32,96 @@ | ||||
| #define INCL_DOSERRORS | ||||
| #include <os2.h> | ||||
|  | ||||
| struct SDL_mutex | ||||
| { | ||||
|   ULONG      ulHandle; | ||||
| struct SDL_mutex { | ||||
|     HMTX  _handle; | ||||
| }; | ||||
|  | ||||
| /* Create a mutex */ | ||||
| SDL_mutex * | ||||
| SDL_CreateMutex(void) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   HMTX       hMtx; | ||||
|     ULONG ulRC; | ||||
|     HMTX  hMtx; | ||||
|  | ||||
|   ulRC = DosCreateMutexSem( NULL, &hMtx, 0, FALSE ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "DosCreateMutexSem(), rc = %u", ulRC ); | ||||
|     return NULL; | ||||
|   } | ||||
|     ulRC = DosCreateMutexSem(NULL, &hMtx, 0, FALSE); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosCreateMutexSem(), rc = %u", ulRC); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   return (SDL_mutex *)hMtx; | ||||
|     return (SDL_mutex *)hMtx; | ||||
| } | ||||
|  | ||||
| /* Free the mutex */ | ||||
| void | ||||
| SDL_DestroyMutex(SDL_mutex * mutex) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   HMTX       hMtx = (HMTX)mutex; | ||||
|     ULONG ulRC; | ||||
|     HMTX  hMtx = (HMTX)mutex; | ||||
|  | ||||
|   ulRC = DosCloseMutexSem( hMtx ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|     debug( "DosCloseMutexSem(), rc = %u", ulRC ); | ||||
|     ulRC = DosCloseMutexSem(hMtx); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosCloseMutexSem(), rc = %u", ulRC); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* Lock the mutex */ | ||||
| int | ||||
| SDL_LockMutex(SDL_mutex * mutex) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   HMTX       hMtx = (HMTX)mutex; | ||||
|     ULONG ulRC; | ||||
|     HMTX  hMtx = (HMTX)mutex; | ||||
|  | ||||
|   if ( hMtx == NULLHANDLE ) | ||||
|     return SDL_SetError( "Passed a NULL mutex" ); | ||||
|     if (hMtx == NULLHANDLE) | ||||
|         return SDL_SetError("Passed a NULL mutex"); | ||||
|  | ||||
|   ulRC = DosRequestMutexSem( hMtx, SEM_INDEFINITE_WAIT ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "DosRequestMutexSem(), rc = %u", ulRC ); | ||||
|     return -1; | ||||
|   } | ||||
|     ulRC = DosRequestMutexSem(hMtx, SEM_INDEFINITE_WAIT); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|       debug_os2("DosRequestMutexSem(), rc = %u", ulRC); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   return 0; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* try Lock the mutex */ | ||||
| int | ||||
| SDL_TryLockMutex(SDL_mutex * mutex) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   HMTX       hMtx = (HMTX)mutex; | ||||
|     ULONG ulRC; | ||||
|     HMTX  hMtx = (HMTX)mutex; | ||||
|  | ||||
|   if ( hMtx == NULLHANDLE ) | ||||
|     return SDL_SetError( "Passed a NULL mutex" ); | ||||
|     if (hMtx == NULLHANDLE) | ||||
|         return SDL_SetError("Passed a NULL mutex"); | ||||
|  | ||||
|   ulRC = DosRequestMutexSem( hMtx, SEM_IMMEDIATE_RETURN ); | ||||
|     ulRC = DosRequestMutexSem(hMtx, SEM_IMMEDIATE_RETURN); | ||||
|  | ||||
|   if ( ulRC == ERROR_TIMEOUT ) | ||||
|     return SDL_MUTEX_TIMEDOUT; | ||||
|     if (ulRC == ERROR_TIMEOUT) | ||||
|         return SDL_MUTEX_TIMEDOUT; | ||||
|  | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "DosRequestMutexSem(), rc = %u", ulRC ); | ||||
|     return -1; | ||||
|   } | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosRequestMutexSem(), rc = %u", ulRC); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|   return 0; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /* Unlock the mutex */ | ||||
| int | ||||
| SDL_UnlockMutex(SDL_mutex * mutex) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   HMTX       hMtx = (HMTX)mutex; | ||||
|     ULONG ulRC; | ||||
|     HMTX  hMtx = (HMTX)mutex; | ||||
|  | ||||
|   if ( hMtx == NULLHANDLE ) | ||||
|     return SDL_SetError( "Passed a NULL mutex" ); | ||||
|     if (hMtx == NULLHANDLE) | ||||
|         return SDL_SetError("Passed a NULL mutex"); | ||||
|  | ||||
|   ulRC = DosReleaseMutexSem( hMtx ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|     return SDL_SetError( "DosReleaseMutexSem(), rc = %u", ulRC ); | ||||
|     ulRC = DosReleaseMutexSem(hMtx); | ||||
|     if (ulRC != NO_ERROR) | ||||
|         return SDL_SetError("DosReleaseMutexSem(), rc = %u", ulRC); | ||||
|  | ||||
|   return 0; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #endif /* SDL_THREAD_OS2 */ | ||||
|   | ||||
| @@ -33,162 +33,156 @@ | ||||
| #include <os2.h> | ||||
|  | ||||
| struct SDL_semaphore { | ||||
|   HEV        hEv; | ||||
|   HMTX       hMtx; | ||||
|   ULONG      cPost; | ||||
|     HEV     hEv; | ||||
|     HMTX    hMtx; | ||||
|     ULONG   cPost; | ||||
| }; | ||||
|  | ||||
|  | ||||
| SDL_sem * | ||||
| SDL_CreateSemaphore(Uint32 initial_value) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   SDL_sem    *pSDLSem = SDL_malloc( sizeof(SDL_sem) ); | ||||
|     ULONG ulRC; | ||||
|     SDL_sem *pSDLSem = SDL_malloc(sizeof(SDL_sem)); | ||||
|  | ||||
|   if ( pSDLSem == NULL ) | ||||
|   { | ||||
|     SDL_OutOfMemory(); | ||||
|     return NULL; | ||||
|   } | ||||
|     if (pSDLSem == NULL) { | ||||
|         SDL_OutOfMemory(); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   ulRC = DosCreateEventSem( NULL, &pSDLSem->hEv, DCE_AUTORESET, FALSE ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "DosCreateEventSem(), rc = %u", ulRC ); | ||||
|     SDL_free( pSDLSem ); | ||||
|     return NULL; | ||||
|   } | ||||
|     ulRC = DosCreateEventSem(NULL, &pSDLSem->hEv, DCE_AUTORESET, FALSE); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosCreateEventSem(), rc = %u", ulRC); | ||||
|         SDL_free(pSDLSem); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   ulRC = DosCreateMutexSem( NULL, &pSDLSem->hMtx, 0, FALSE ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "DosCreateMutexSem(), rc = %u", ulRC ); | ||||
|     DosCloseEventSem( pSDLSem->hEv ); | ||||
|     SDL_free( pSDLSem ); | ||||
|     return NULL; | ||||
|   } | ||||
|     ulRC = DosCreateMutexSem(NULL, &pSDLSem->hMtx, 0, FALSE); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosCreateMutexSem(), rc = %u", ulRC); | ||||
|         DosCloseEventSem(pSDLSem->hEv); | ||||
|         SDL_free(pSDLSem); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   pSDLSem->cPost = initial_value; | ||||
|     pSDLSem->cPost = initial_value; | ||||
|  | ||||
|   return pSDLSem; | ||||
|     return pSDLSem; | ||||
| } | ||||
|  | ||||
| void | ||||
| SDL_DestroySemaphore(SDL_sem * sem) | ||||
| { | ||||
|   if ( sem == NULL ) | ||||
|     return; | ||||
|     if (!sem) return; | ||||
|  | ||||
|   DosCloseMutexSem( sem->hMtx ); | ||||
|   DosCloseEventSem( sem->hEv ); | ||||
|   SDL_free( sem ); | ||||
|     DosCloseMutexSem(sem->hMtx); | ||||
|     DosCloseEventSem(sem->hEv); | ||||
|     SDL_free(sem); | ||||
| } | ||||
|  | ||||
| int | ||||
| SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   ULONG      ulStartTime, ulCurTime; | ||||
|   ULONG      ulTimeout; | ||||
|   ULONG      cPost; | ||||
|     ULONG ulRC; | ||||
|     ULONG ulStartTime, ulCurTime; | ||||
|     ULONG ulTimeout; | ||||
|     ULONG cPost; | ||||
|  | ||||
|   if ( sem == NULL ) | ||||
|     return SDL_SetError( "Passed a NULL sem" ); | ||||
|     if (sem == NULL) | ||||
|         return SDL_SetError("Passed a NULL sem"); | ||||
|  | ||||
|   if ( timeout != SEM_INDEFINITE_WAIT ) | ||||
|     DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &ulStartTime, sizeof(ULONG) ); | ||||
|     if (timeout != SEM_INDEFINITE_WAIT) | ||||
|         DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulStartTime, sizeof(ULONG)); | ||||
|  | ||||
|   while( TRUE ) | ||||
|   { | ||||
|     ulRC = DosRequestMutexSem( sem->hMtx, SEM_INDEFINITE_WAIT ); | ||||
|     if ( ulRC != NO_ERROR ) | ||||
|       return SDL_SetError( "DosRequestMutexSem() failed, rc = %u", ulRC ); | ||||
|    | ||||
|     cPost = sem->cPost; | ||||
|     if ( sem->cPost != 0 ) | ||||
|       sem->cPost--; | ||||
|     while (TRUE) { | ||||
|         ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT); | ||||
|         if (ulRC != NO_ERROR) | ||||
|             return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC); | ||||
|  | ||||
|     DosReleaseMutexSem( sem->hMtx ); | ||||
|         cPost = sem->cPost; | ||||
|         if (sem->cPost != 0) | ||||
|             sem->cPost--; | ||||
|  | ||||
|     if ( cPost != 0 ) | ||||
|       break; | ||||
|         DosReleaseMutexSem(sem->hMtx); | ||||
|  | ||||
|     if ( timeout == SEM_INDEFINITE_WAIT ) | ||||
|       ulTimeout = SEM_INDEFINITE_WAIT; | ||||
|     else | ||||
|     { | ||||
|       DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &ulCurTime, sizeof(ULONG) ); | ||||
|       ulTimeout = ulCurTime - ulStartTime; | ||||
|       if ( timeout < ulTimeout ) | ||||
|         return SDL_MUTEX_TIMEDOUT; | ||||
|       ulTimeout = timeout - ulTimeout; | ||||
|         if (cPost != 0) | ||||
|             break; | ||||
|  | ||||
|         if (timeout == SEM_INDEFINITE_WAIT) | ||||
|             ulTimeout = SEM_INDEFINITE_WAIT; | ||||
|         else { | ||||
|             DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulCurTime, sizeof(ULONG)); | ||||
|             ulTimeout = ulCurTime - ulStartTime; | ||||
|             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 ); | ||||
|     if ( ulRC == ERROR_TIMEOUT ) | ||||
|       return SDL_MUTEX_TIMEDOUT; | ||||
|  | ||||
|     if ( ulRC != NO_ERROR ) | ||||
|       return SDL_SetError( "DosWaitEventSem() failed, rc = %u", ulRC ); | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| SDL_SemTryWait(SDL_sem * sem) | ||||
| { | ||||
|   return SDL_SemWaitTimeout( sem, 0 ); | ||||
|     return SDL_SemWaitTimeout(sem, 0); | ||||
| } | ||||
|  | ||||
| int | ||||
| SDL_SemWait(SDL_sem * sem) | ||||
| { | ||||
|   return SDL_SemWaitTimeout( sem, SDL_MUTEX_MAXWAIT ); | ||||
|     return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); | ||||
| } | ||||
|  | ||||
| Uint32 | ||||
| SDL_SemValue(SDL_sem * sem) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|     ULONG ulRC; | ||||
|  | ||||
|   if ( sem == NULL ) | ||||
|   { | ||||
|     SDL_SetError( "Passed a NULL sem" ); | ||||
|     return 0; | ||||
|   } | ||||
|     if (sem == NULL) { | ||||
|         SDL_SetError("Passed a NULL sem"); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|   ulRC = DosRequestMutexSem( sem->hMtx, SEM_INDEFINITE_WAIT ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|     return SDL_SetError( "DosRequestMutexSem() failed, rc = %u", ulRC ); | ||||
|     ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT); | ||||
|     if (ulRC != NO_ERROR) | ||||
|         return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC); | ||||
|  | ||||
|   ulRC = sem->cPost; | ||||
|   DosReleaseMutexSem( sem->hMtx ); | ||||
|     ulRC = sem->cPost; | ||||
|     DosReleaseMutexSem(sem->hMtx); | ||||
|  | ||||
|   return ulRC; | ||||
|     return ulRC; | ||||
| } | ||||
|  | ||||
| int | ||||
| SDL_SemPost(SDL_sem * sem) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|     ULONG ulRC; | ||||
|  | ||||
|   if ( sem == NULL ) | ||||
|     return SDL_SetError( "Passed a NULL sem" ); | ||||
|     if (sem == NULL) | ||||
|         return SDL_SetError("Passed a NULL sem"); | ||||
|  | ||||
|   ulRC = DosRequestMutexSem( sem->hMtx, SEM_INDEFINITE_WAIT ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|     return SDL_SetError( "DosRequestMutexSem() failed, rc = %u", ulRC ); | ||||
|     ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT); | ||||
|     if (ulRC != NO_ERROR) | ||||
|         return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC); | ||||
|  | ||||
|   sem->cPost++; | ||||
|     sem->cPost++; | ||||
|  | ||||
|   ulRC = DosPostEventSem( sem->hEv ); | ||||
|   if ( ( ulRC != NO_ERROR ) && ( ulRC != ERROR_ALREADY_POSTED ) ) | ||||
|     debug( "DosPostEventSem() failed, rc = %u", ulRC ); | ||||
|     ulRC = DosPostEventSem(sem->hEv); | ||||
|     if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) { | ||||
|         debug_os2("DosPostEventSem() failed, rc = %u", ulRC); | ||||
|     } | ||||
|  | ||||
|   DosReleaseMutexSem( sem->hMtx ); | ||||
|     DosReleaseMutexSem(sem->hMtx); | ||||
|  | ||||
|   return 0; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #endif /* SDL_THREAD_OS2 */ | ||||
|   | ||||
| @@ -42,16 +42,16 @@ | ||||
|  | ||||
| static void RunThread(void *data) | ||||
| { | ||||
|   SDL_Thread                  *thread = (SDL_Thread *) data; | ||||
|   pfnSDL_CurrentEndThread     pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc; | ||||
|     SDL_Thread *thread = (SDL_Thread *) data; | ||||
|     pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc; | ||||
|  | ||||
|   if ( ppSDLTLSData != NULL ) | ||||
|     *ppSDLTLSData = NULL; | ||||
|     if (ppSDLTLSData != NULL) | ||||
|         *ppSDLTLSData = NULL; | ||||
|  | ||||
|   SDL_RunThread( thread ); | ||||
|     SDL_RunThread(thread); | ||||
|  | ||||
|   if ( pfnEndThread != NULL ) | ||||
|     pfnEndThread(); | ||||
|     if (pfnEndThread != NULL) | ||||
|         pfnEndThread(); | ||||
| } | ||||
|  | ||||
| int | ||||
| @@ -59,73 +59,73 @@ SDL_SYS_CreateThread(SDL_Thread * thread, | ||||
|                      pfnSDL_CurrentBeginThread pfnBeginThread, | ||||
|                      pfnSDL_CurrentEndThread pfnEndThread) | ||||
| { | ||||
|   if (thread->stacksize == 0) | ||||
|     thread->stacksize = 65536; | ||||
|     if (thread->stacksize == 0) | ||||
|         thread->stacksize = 65536; | ||||
|  | ||||
|   if (pfnBeginThread) { | ||||
|     // Save the function which we will have to call to clear the RTL of calling app! | ||||
|     thread->endfunc = pfnEndThread; | ||||
|     // Start the thread using the runtime library of calling app! | ||||
|     thread->handle = (SYS_ThreadHandle) | ||||
|       pfnBeginThread( RunThread, NULL, thread->stacksize, thread ); | ||||
|   } | ||||
|   else { | ||||
|     thread->endfunc = _endthread; | ||||
|     thread->handle = (SYS_ThreadHandle) | ||||
|       _beginthread( RunThread, NULL, thread->stacksize, thread ); | ||||
|   } | ||||
|     if (pfnBeginThread) { | ||||
|         /* Save the function which we will have to call to clear the RTL of calling app! */ | ||||
|         thread->endfunc = pfnEndThread; | ||||
|         /* Start the thread using the runtime library of calling app! */ | ||||
|         thread->handle = (SYS_ThreadHandle) | ||||
|                             pfnBeginThread(RunThread, NULL, thread->stacksize, thread); | ||||
|     } else { | ||||
|         thread->endfunc = _endthread; | ||||
|         thread->handle = (SYS_ThreadHandle) | ||||
|                             _beginthread(RunThread, NULL, thread->stacksize, thread); | ||||
|     } | ||||
|  | ||||
|   if ( thread->handle == -1 ) | ||||
|       return SDL_SetError( "Not enough resources to create thread" ); | ||||
|     if (thread->handle == -1) | ||||
|         return SDL_SetError("Not enough resources to create thread"); | ||||
|  | ||||
|   return 0; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void | ||||
| SDL_SYS_SetupThread(const char *name) | ||||
| { | ||||
|     return; | ||||
|     /* nothing. */ | ||||
| } | ||||
|  | ||||
| SDL_threadID | ||||
| SDL_ThreadID(void) | ||||
| { | ||||
|   PTIB       tib; | ||||
|   PPIB       pib; | ||||
|     PTIB  tib; | ||||
|     PPIB  pib; | ||||
|  | ||||
|   DosGetInfoBlocks( &tib, &pib ); | ||||
|   return tib->tib_ptib2->tib2_ultid; | ||||
|     DosGetInfoBlocks(&tib, &pib); | ||||
|     return tib->tib_ptib2->tib2_ultid; | ||||
| } | ||||
|  | ||||
| int | ||||
| SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|     ULONG ulRC; | ||||
|  | ||||
|   ulRC = DosSetPriority( PRTYS_THREAD, | ||||
|                          (priority < SDL_THREAD_PRIORITY_NORMAL)? PRTYC_IDLETIME : | ||||
|     ulRC = DosSetPriority(PRTYS_THREAD, | ||||
|                           (priority < SDL_THREAD_PRIORITY_NORMAL)? PRTYC_IDLETIME : | ||||
|                            (priority > SDL_THREAD_PRIORITY_NORMAL)? PRTYC_TIMECRITICAL : | ||||
|                              PRTYC_REGULAR, | ||||
|                          0, 0 ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|     return SDL_SetError( "DosSetPriority() failed, rc = %u", ulRC ); | ||||
|                             PRTYC_REGULAR, | ||||
|                           0, 0); | ||||
|     if (ulRC != NO_ERROR) | ||||
|         return SDL_SetError("DosSetPriority() failed, rc = %u", ulRC); | ||||
|  | ||||
|   return 0; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void | ||||
| 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 ) | ||||
|     debug( "DosWaitThread() failed, rc = %u", ulRC ); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosWaitThread() failed, rc = %u", ulRC); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| SDL_SYS_DetachThread(SDL_Thread * thread) | ||||
| { | ||||
|   /* nothing. */ | ||||
|     /* nothing. */ | ||||
| } | ||||
|  | ||||
| #endif /* SDL_THREAD_OS2 */ | ||||
|   | ||||
| @@ -32,56 +32,56 @@ | ||||
| #define INCL_DOSERRORS | ||||
| #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() | ||||
| void SDL_OS2TLSAlloc() | ||||
| /* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */ | ||||
| void SDL_OS2TLSAlloc(void) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|     ULONG ulRC; | ||||
|  | ||||
|   if ( ( cTLSAlloc == 0 ) || ( ppSDLTLSData == NULL ) ) | ||||
|   { | ||||
|     // First call - allocate the thread local memory (1 DWORD). | ||||
|     ulRC = DosAllocThreadLocalMemory( 1, (PULONG *)&ppSDLTLSData ); | ||||
|     if ( ulRC != NO_ERROR ) | ||||
|       debug( "DosAllocThreadLocalMemory() failed, rc = %u", ulRC ); | ||||
|   } | ||||
|   cTLSAlloc++; | ||||
|     if (cTLSAlloc == 0 || ppSDLTLSData == NULL) { | ||||
|         /* First call - allocate the thread local memory (1 DWORD) */ | ||||
|         ulRC = DosAllocThreadLocalMemory(1, (PULONG *)&ppSDLTLSData); | ||||
|         if (ulRC != NO_ERROR) { | ||||
|             debug_os2("DosAllocThreadLocalMemory() failed, rc = %u", ulRC); | ||||
|         } | ||||
|     } | ||||
|     cTLSAlloc++; | ||||
| } | ||||
|  | ||||
| // SDL_OS2TLSFree() called from SDL_QuitSubSystem() | ||||
| void SDL_OS2TLSFree() | ||||
| /* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */ | ||||
| void SDL_OS2TLSFree(void) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|     ULONG ulRC; | ||||
|  | ||||
|   if ( cTLSAlloc != 0 ) | ||||
|     cTLSAlloc--; | ||||
|     if (cTLSAlloc != 0) | ||||
|         cTLSAlloc--; | ||||
|  | ||||
|   if ( ( cTLSAlloc == 0 ) && ( ppSDLTLSData != NULL ) ) | ||||
|   { | ||||
|     // Last call - free the thread local memory. | ||||
|     ulRC = DosFreeThreadLocalMemory( (PULONG)ppSDLTLSData ); | ||||
|     if ( ulRC != NO_ERROR ) | ||||
|       debug( "DosFreeThreadLocalMemory() failed, rc = %u", ulRC ); | ||||
|     else | ||||
|       ppSDLTLSData = NULL; | ||||
|   } | ||||
|     if (cTLSAlloc == 0 && ppSDLTLSData != NULL) { | ||||
|         /* Last call - free the thread local memory */ | ||||
|         ulRC = DosFreeThreadLocalMemory((PULONG)ppSDLTLSData); | ||||
|         if (ulRC != NO_ERROR) { | ||||
|             debug_os2("DosFreeThreadLocalMemory() failed, rc = %u", ulRC); | ||||
|         } else { | ||||
|             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) | ||||
| { | ||||
|   if ( ppSDLTLSData == NULL ) | ||||
|     return -1; | ||||
|     if (!ppSDLTLSData) | ||||
|         return -1; | ||||
|  | ||||
|   *ppSDLTLSData = data; | ||||
|   return 0; | ||||
|     *ppSDLTLSData = data; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #endif /* SDL_THREAD_OS2 */ | ||||
|   | ||||
| @@ -25,13 +25,13 @@ | ||||
|  | ||||
| #include "../SDL_thread_c.h" | ||||
|  | ||||
| extern SDL_TLSData     **ppSDLTLSData; | ||||
| extern SDL_TLSData **ppSDLTLSData; | ||||
|  | ||||
| // SDL_OS2TLSAlloc() called from SDL_InitSubSystem() | ||||
| void SDL_OS2TLSAlloc(); | ||||
| /* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */ | ||||
| void SDL_OS2TLSAlloc(void); | ||||
|  | ||||
| // SDL_OS2TLSFree() called from SDL_QuitSubSystem() | ||||
| void SDL_OS2TLSFree(); | ||||
| /* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */ | ||||
| void SDL_OS2TLSFree(void); | ||||
|  | ||||
| #endif /* SDL_THREAD_OS2 */ | ||||
|  | ||||
|   | ||||
| @@ -34,37 +34,31 @@ | ||||
| #define INCL_DOSEXCEPTIONS | ||||
| #include <os2.h> | ||||
|  | ||||
| // No need to switch priorities in SDL_Delay() for OS/2 versions > Warp3 fp 42. | ||||
| //#define _SWITCH_PRIORITY | ||||
| /* No need to switch priorities in SDL_Delay() for OS/2 versions > Warp3 fp 42, */ | ||||
| /*#define _SWITCH_PRIORITY*/ | ||||
|  | ||||
| typedef unsigned long long       ULLONG; | ||||
| typedef unsigned long long  ULLONG; | ||||
|  | ||||
| static ULONG           ulTmrFreq = 0; | ||||
| static ULLONG          ullTmrStart; | ||||
| static ULONG    ulTmrFreq = 0; | ||||
| static ULLONG   ullTmrStart; | ||||
|  | ||||
| void | ||||
| SDL_TicksInit(void) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|     ULONG   ulRC; | ||||
|  | ||||
|   ulRC = DosTmrQueryFreq( &ulTmrFreq ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "DosTmrQueryFreq() failed, rc = %u", ulRC ); | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     ulRC = DosTmrQueryTime( (PQWORD)&ullTmrStart ); | ||||
|     if ( ulRC == NO_ERROR ) | ||||
|       return; | ||||
|     ulRC = DosTmrQueryFreq(&ulTmrFreq); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosTmrQueryFreq() failed, rc = %u", ulRC); | ||||
|     } else { | ||||
|         ulRC = DosTmrQueryTime((PQWORD)&ullTmrStart); | ||||
|         if (ulRC == NO_ERROR) | ||||
|             return; | ||||
|         debug_os2("DosTmrQueryTime() failed, rc = %u", ulRC); | ||||
|     } | ||||
|  | ||||
|     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 | ||||
| @@ -75,113 +69,103 @@ SDL_TicksQuit(void) | ||||
| Uint32 | ||||
| SDL_GetTicks(void) | ||||
| { | ||||
|   ULONG      ulResult; | ||||
|   ULLONG     ullTmrNow; | ||||
|     ULONG   ulResult; | ||||
|     ULLONG  ullTmrNow; | ||||
|  | ||||
|   if ( ulTmrFreq == 0 ) | ||||
|     // Was not initialized. | ||||
|     SDL_TicksInit(); | ||||
|     if (ulTmrFreq == 0) /* Was not initialized. */ | ||||
|         SDL_TicksInit(); | ||||
|  | ||||
|   if ( ulTmrFreq != 0 ) | ||||
|   { | ||||
|     DosTmrQueryTime( (PQWORD)&ullTmrNow ); | ||||
|     ulResult = ( ullTmrNow - ullTmrStart ) * 1000 / ulTmrFreq; | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, (PULONG)&ullTmrNow, | ||||
|                      sizeof(ULONG) ); | ||||
|     ulResult = (ULONG)ullTmrNow - (ULONG)ullTmrStart; | ||||
|   } | ||||
|     if (ulTmrFreq != 0) { | ||||
|         DosTmrQueryTime((PQWORD)&ullTmrNow); | ||||
|         ulResult = (ullTmrNow - ullTmrStart) * 1000 / ulTmrFreq; | ||||
|     } else { | ||||
|         DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, (PULONG)&ullTmrNow, sizeof(ULONG)); | ||||
|         ulResult = (ULONG)ullTmrNow - (ULONG)ullTmrStart; | ||||
|     } | ||||
|  | ||||
|   return ulResult; | ||||
|     return ulResult; | ||||
| } | ||||
|  | ||||
| Uint64 | ||||
| SDL_GetPerformanceCounter(void) | ||||
| { | ||||
|   QWORD      qwTmrNow; | ||||
|     QWORD   qwTmrNow; | ||||
|  | ||||
|   if ( ( ulTmrFreq == 0 ) || ( DosTmrQueryTime( &qwTmrNow ) != NO_ERROR ) ) | ||||
|     return SDL_GetTicks(); | ||||
|     if (ulTmrFreq == 0 || (DosTmrQueryTime(&qwTmrNow) != NO_ERROR)) | ||||
|         return SDL_GetTicks(); | ||||
|  | ||||
|   return *((Uint64 *)&qwTmrNow); | ||||
|     return *((Uint64 *)&qwTmrNow); | ||||
| } | ||||
|  | ||||
| Uint64 | ||||
| SDL_GetPerformanceFrequency(void) | ||||
| { | ||||
|   return ulTmrFreq == 0 ? 1000 : (Uint64)ulTmrFreq; | ||||
|     return (ulTmrFreq == 0)? 1000 : (Uint64)ulTmrFreq; | ||||
| } | ||||
|  | ||||
| void | ||||
| SDL_Delay(Uint32 ms) | ||||
| { | ||||
|   HTIMER     hTimer = NULLHANDLE; | ||||
|   ULONG      ulRC; | ||||
|     HTIMER  hTimer = NULLHANDLE; | ||||
|     ULONG   ulRC; | ||||
| #ifdef _SWITCH_PRIORITY | ||||
|   PPIB       pib; | ||||
|   PTIB       tib; | ||||
|   BOOL       fSetPriority = ms < 50; | ||||
|   ULONG      ulSavePriority; | ||||
|   ULONG      ulNesting; | ||||
|     PPIB    pib; | ||||
|     PTIB    tib; | ||||
|     BOOL    fSetPriority = ms < 50; | ||||
|     ULONG   ulSavePriority; | ||||
|     ULONG   ulNesting; | ||||
| #endif | ||||
|   HEV        hevTimer; | ||||
|     HEV     hevTimer; | ||||
|  | ||||
|   if ( ms == 0 ) | ||||
|   { | ||||
|     DosSleep( 0 ); | ||||
|     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 ); | ||||
|     if (ms == 0) { | ||||
|       DosSleep(0); | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   DosResetEventSem( hevTimer, &ulRC ); | ||||
|   ulRC = DosAsyncTimer( ms, (HSEM)hevTimer, &hTimer ); | ||||
|     ulRC = DosCreateEventSem(NULL, &hevTimer, DC_SEM_SHARED, FALSE); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosAsyncTimer() failed, rc = %u", ulRC); | ||||
|         DosSleep(ms); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
| #ifdef _SWITCH_PRIORITY | ||||
|   if ( fSetPriority ) | ||||
|   { | ||||
|     if ( DosSetPriority( PRTYS_THREAD, (ulSavePriority >> 8) & 0xFF, 0, 0 ) == | ||||
|            NO_ERROR ) | ||||
|       DosSetPriority( PRTYS_THREAD, 0, ulSavePriority & 0xFF, 0 ); | ||||
|  | ||||
|     DosExitMustComplete( &ulNesting ); | ||||
|   } | ||||
|     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 | ||||
|  | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|     debug( "DosAsyncTimer() failed, rc = %u", ulRC ); | ||||
|   else | ||||
|     DosWaitEventSem( hevTimer, SEM_INDEFINITE_WAIT ); | ||||
|     DosResetEventSem(hevTimer, &ulRC); | ||||
|     ulRC = DosAsyncTimer(ms, (HSEM)hevTimer, &hTimer); | ||||
|  | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|     DosSleep( ms ); | ||||
| #ifdef _SWITCH_PRIORITY | ||||
|     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 */ | ||||
|   | ||||
| @@ -32,17 +32,17 @@ | ||||
| #include "SDL_os2output.h" | ||||
|  | ||||
| typedef struct _VODATA { | ||||
|   HDIVE      hDive; | ||||
|   PVOID      pBuffer; | ||||
|   ULONG      ulDIVEBufNum; | ||||
|   FOURCC     fccColorEncoding; | ||||
|   ULONG      ulWidth; | ||||
|   ULONG      ulHeight; | ||||
|   BOOL       fBlitterReady; | ||||
|   HDIVE    hDive; | ||||
|   PVOID    pBuffer; | ||||
|   ULONG    ulDIVEBufNum; | ||||
|   FOURCC   fccColorEncoding; | ||||
|   ULONG    ulWidth; | ||||
|   ULONG    ulHeight; | ||||
|   BOOL     fBlitterReady; | ||||
| } VODATA; | ||||
|  | ||||
| static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo); | ||||
| static PVODATA voOpen(); | ||||
| static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo); | ||||
| static PVODATA voOpen(void); | ||||
| static VOID voClose(PVODATA pVOData); | ||||
| static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd, | ||||
|                                SDL_DisplayMode *pSDLDisplayMode, | ||||
| @@ -55,294 +55,275 @@ static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, | ||||
|                      ULONG cSDLRects); | ||||
|  | ||||
| OS2VIDEOOUTPUT voDive = { | ||||
|   voQueryInfo, | ||||
|   voOpen, | ||||
|   voClose, | ||||
|   voSetVisibleRegion, | ||||
|   voVideoBufAlloc, | ||||
|   voVideoBufFree, | ||||
|   voUpdate | ||||
|     voQueryInfo, | ||||
|     voOpen, | ||||
|     voClose, | ||||
|     voSetVisibleRegion, | ||||
|     voVideoBufAlloc, | ||||
|     voVideoBufFree, | ||||
|     voUpdate | ||||
| }; | ||||
|  | ||||
|  | ||||
| static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo) | ||||
| static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo) | ||||
| { | ||||
|   DIVE_CAPS            sDiveCaps = { 0 }; | ||||
|   FOURCC               fccFormats[100] = { 0 }; | ||||
|     DIVE_CAPS sDiveCaps = { 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; | ||||
|   sDiveCaps.ulFormatLength = 100; | ||||
|   sDiveCaps.ulStructLen    = sizeof(DIVE_CAPS); | ||||
|     if (DiveQueryCaps(&sDiveCaps, DIVE_BUFFER_SCREEN)) { | ||||
|         debug_os2("DiveQueryCaps() failed."); | ||||
|         return FALSE; | ||||
|     } | ||||
|  | ||||
|   if ( DiveQueryCaps( &sDiveCaps, DIVE_BUFFER_SCREEN ) ) | ||||
|   { | ||||
|     debug( "DiveQueryCaps() failed." ); | ||||
|     return FALSE; | ||||
|   } | ||||
|     if (sDiveCaps.ulDepth < 8) { | ||||
|         debug_os2("Not enough screen colors to run DIVE. " | ||||
|                   "Must be at least 256 colors."); | ||||
|         return FALSE; | ||||
|     } | ||||
|  | ||||
|   if ( sDiveCaps.ulDepth < 8 ) | ||||
|   { | ||||
|     debug( "Not enough screen colors to run DIVE. " | ||||
|            "Must be at least 256 colors." ); | ||||
|     return FALSE; | ||||
|   } | ||||
|     pInfo->ulBPP             = sDiveCaps.ulDepth; | ||||
|     pInfo->fccColorEncoding  = sDiveCaps.fccColorEncoding; | ||||
|     pInfo->ulScanLineSize    = sDiveCaps.ulScanLineBytes; | ||||
|     pInfo->ulHorizResolution = sDiveCaps.ulHorizontalResolution; | ||||
|     pInfo->ulVertResolution  = sDiveCaps.ulVerticalResolution; | ||||
|  | ||||
|   pInfo->ulBPP             = sDiveCaps.ulDepth; | ||||
|   pInfo->fccColorEncoding  = sDiveCaps.fccColorEncoding; | ||||
|   pInfo->ulScanLineSize    = sDiveCaps.ulScanLineBytes; | ||||
|   pInfo->ulHorizResolution = sDiveCaps.ulHorizontalResolution; | ||||
|   pInfo->ulVertResolution  = sDiveCaps.ulVerticalResolution; | ||||
|  | ||||
|   return TRUE; | ||||
|     return TRUE; | ||||
| } | ||||
|  | ||||
| PVODATA voOpen() | ||||
| PVODATA voOpen(void) | ||||
| { | ||||
|   PVODATA    pVOData = SDL_calloc( 1, sizeof(VODATA) ); | ||||
|     PVODATA pVOData = SDL_calloc(1, sizeof(VODATA)); | ||||
|  | ||||
|   if ( pVOData == NULL ) | ||||
|   { | ||||
|     SDL_OutOfMemory(); | ||||
|     return NULL; | ||||
|   } | ||||
|     if (pVOData == NULL) { | ||||
|         SDL_OutOfMemory(); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   if ( DiveOpen( &pVOData->hDive, FALSE, NULL ) != DIVE_SUCCESS ) | ||||
|   { | ||||
|     SDL_free( pVOData ); | ||||
|     SDL_SetError( "DIVE: A display engine instance open failed" ); | ||||
|     return NULL; | ||||
|   } | ||||
|     if (DiveOpen(&pVOData->hDive, FALSE, NULL) != DIVE_SUCCESS) { | ||||
|         SDL_free(pVOData); | ||||
|         SDL_SetError("DIVE: A display engine instance open failed"); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   return pVOData; | ||||
|     return pVOData; | ||||
| } | ||||
|  | ||||
| static VOID voClose(PVODATA pVOData) | ||||
| { | ||||
|   voVideoBufFree( pVOData ); | ||||
|   DiveClose( pVOData->hDive ); | ||||
|   SDL_free( pVOData ); | ||||
|     voVideoBufFree(pVOData); | ||||
|     DiveClose(pVOData->hDive); | ||||
|     SDL_free(pVOData); | ||||
| } | ||||
|  | ||||
| static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd, | ||||
|                                SDL_DisplayMode *pSDLDisplayMode, | ||||
|                                HRGN hrgnShape, BOOL fVisible) | ||||
| { | ||||
|   HPS        hps; | ||||
|   HRGN       hrgn; | ||||
|   RGNRECT    rgnCtl; | ||||
|   PRECTL     prectl = NULL; | ||||
|   ULONG      ulRC; | ||||
|     HPS     hps; | ||||
|     HRGN    hrgn; | ||||
|     RGNRECT rgnCtl; | ||||
|     PRECTL  prectl = NULL; | ||||
|     ULONG   ulRC; | ||||
|  | ||||
|   if ( !fVisible ) | ||||
|   { | ||||
|     if ( pVOData->fBlitterReady ) | ||||
|     { | ||||
|       pVOData->fBlitterReady = FALSE; | ||||
|       DiveSetupBlitter( pVOData->hDive, 0 ); | ||||
|       debug( "DIVE blitter is tuned off" ); | ||||
|     } | ||||
|     return TRUE; | ||||
|   } | ||||
|  | ||||
|   // Query visible rectangles | ||||
|  | ||||
|   hps = WinGetPS( hwnd ); | ||||
|   hrgn = GpiCreateRegion( hps, 0, NULL ); | ||||
|   if ( hrgn == NULLHANDLE ) | ||||
|   { | ||||
|     WinReleasePS( hps ); | ||||
|     SDL_SetError( "GpiCreateRegion() failed" ); | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     WinQueryVisibleRegion( hwnd, hrgn ); | ||||
|     if ( hrgnShape != NULLHANDLE ) | ||||
|       GpiCombineRegion( hps, hrgn, hrgn, hrgnShape, CRGN_AND ); | ||||
|  | ||||
|     rgnCtl.ircStart     = 1; | ||||
|     rgnCtl.crc          = 0; | ||||
|     rgnCtl.ulDirection  = 1; | ||||
|     GpiQueryRegionRects( hps, hrgn, NULL, &rgnCtl, NULL ); | ||||
|     if ( rgnCtl.crcReturned != 0 ) | ||||
|     { | ||||
|       prectl = SDL_malloc( rgnCtl.crcReturned * sizeof(RECTL) ); | ||||
|       if ( prectl != NULL ) | ||||
|       { | ||||
|         rgnCtl.ircStart     = 1; | ||||
|         rgnCtl.crc          = rgnCtl.crcReturned; | ||||
|         rgnCtl.ulDirection  = 1; | ||||
|         GpiQueryRegionRects( hps, hrgn, NULL, &rgnCtl, prectl ); | ||||
|       } | ||||
|       else | ||||
|         SDL_OutOfMemory(); | ||||
|     } | ||||
|     GpiDestroyRegion( hps, hrgn ); | ||||
|     WinReleasePS( hps ); | ||||
|  | ||||
|     if ( prectl != NULL ) | ||||
|     { | ||||
|       // Setup DIVE blitter. | ||||
|       SETUP_BLITTER      sSetupBlitter; | ||||
|       SWP                swp; | ||||
|       POINTL             pointl = { 0 }; | ||||
|  | ||||
|       WinQueryWindowPos( hwnd, &swp ); | ||||
|       WinMapWindowPoints( hwnd, HWND_DESKTOP, &pointl, 1 ); | ||||
|  | ||||
|       sSetupBlitter.ulStructLen       = sizeof(SETUP_BLITTER); | ||||
|       sSetupBlitter.fccSrcColorFormat = pVOData->fccColorEncoding; | ||||
|       sSetupBlitter.fInvert           = FALSE; | ||||
|       sSetupBlitter.ulSrcWidth        = pVOData->ulWidth; | ||||
|       sSetupBlitter.ulSrcHeight       = pVOData->ulHeight; | ||||
|       sSetupBlitter.ulSrcPosX         = 0; | ||||
|       sSetupBlitter.ulSrcPosY         = 0; | ||||
|       sSetupBlitter.ulDitherType      = 0; | ||||
|       sSetupBlitter.fccDstColorFormat = FOURCC_SCRN; | ||||
|       sSetupBlitter.ulDstWidth        = swp.cx; | ||||
|       sSetupBlitter.ulDstHeight       = swp.cy; | ||||
|       sSetupBlitter.lDstPosX          = 0; | ||||
|       sSetupBlitter.lDstPosY          = 0; | ||||
|       sSetupBlitter.lScreenPosX       = pointl.x; | ||||
|       sSetupBlitter.lScreenPosY       = pointl.y; | ||||
|  | ||||
|       sSetupBlitter.ulNumDstRects     = rgnCtl.crcReturned; | ||||
|       sSetupBlitter.pVisDstRects      = prectl; | ||||
|  | ||||
|       ulRC = DiveSetupBlitter( pVOData->hDive, &sSetupBlitter ); | ||||
|       SDL_free( prectl ); | ||||
|  | ||||
|       if ( ulRC == DIVE_SUCCESS ) | ||||
|       { | ||||
|         pVOData->fBlitterReady = TRUE; | ||||
|         WinInvalidateRect( hwnd, NULL, TRUE ); | ||||
|         debug( "DIVE blitter is ready now." ); | ||||
|     if (!fVisible) { | ||||
|         if (pVOData->fBlitterReady) { | ||||
|             pVOData->fBlitterReady = FALSE; | ||||
|             DiveSetupBlitter(pVOData->hDive, 0); | ||||
|             debug_os2("DIVE blitter is tuned off"); | ||||
|         } | ||||
|         return TRUE; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|       SDL_SetError( "DiveSetupBlitter(), rc = 0x%X", ulRC ); | ||||
|     } // if ( prectl != NULL ) | ||||
|   } // if ( hrgn == NULLHANDLE ) else | ||||
|     /* 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); | ||||
|  | ||||
|   pVOData->fBlitterReady = FALSE; | ||||
|   DiveSetupBlitter( pVOData->hDive, 0 ); | ||||
|   return FALSE; | ||||
|         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_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, | ||||
|                              ULONG ulBPP, FOURCC fccColorEncoding, | ||||
|                              PULONG pulScanLineSize) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   ULONG      ulScanLineSize = ulWidth * (ulBPP >> 3); | ||||
|     ULONG   ulRC; | ||||
|     ULONG   ulScanLineSize = ulWidth * (ulBPP >> 3); | ||||
|  | ||||
|   // Destroy previous buffer. | ||||
|   voVideoBufFree( pVOData ); | ||||
|     /* Destroy previous buffer. */ | ||||
|     voVideoBufFree(pVOData); | ||||
|  | ||||
|   if ( ( ulWidth == 0 ) || ( ulHeight == 0 ) || ( ulBPP == 0 ) ) | ||||
|     return NULL; | ||||
|     if (ulWidth == 0 || ulHeight == 0 || ulBPP == 0) | ||||
|         return NULL; | ||||
|  | ||||
|   // Bytes per line. | ||||
|   ulScanLineSize = ( ulScanLineSize + 3 ) & ~3;	/* 4-byte aligning */ | ||||
|   *pulScanLineSize = ulScanLineSize; | ||||
|     /* Bytes per line. */ | ||||
|     ulScanLineSize  = (ulScanLineSize + 3) & ~3; /* 4-byte aligning */ | ||||
|     *pulScanLineSize = ulScanLineSize; | ||||
|  | ||||
|   ulRC = DosAllocMem( &pVOData->pBuffer, | ||||
|                       (ulHeight * ulScanLineSize) + sizeof(ULONG), | ||||
|                       PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "DosAllocMem(), rc = %u", ulRC ); | ||||
|     return NULL; | ||||
|   } | ||||
|     ulRC = DosAllocMem(&pVOData->pBuffer, | ||||
|                        (ulHeight * ulScanLineSize) + sizeof(ULONG), | ||||
|                        PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosAllocMem(), rc = %u", ulRC); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   ulRC = DiveAllocImageBuffer( pVOData->hDive, &pVOData->ulDIVEBufNum, | ||||
|                                fccColorEncoding, ulWidth, ulHeight, | ||||
|                                ulScanLineSize, pVOData->pBuffer ); | ||||
|   if ( ulRC != DIVE_SUCCESS ) | ||||
|   { | ||||
|     debug( "DiveAllocImageBuffer(), rc = 0x%X", ulRC ); | ||||
|     DosFreeMem( pVOData->pBuffer ); | ||||
|     pVOData->pBuffer = NULL; | ||||
|     pVOData->ulDIVEBufNum = 0; | ||||
|     return NULL; | ||||
|   } | ||||
|     ulRC = DiveAllocImageBuffer(pVOData->hDive, &pVOData->ulDIVEBufNum, | ||||
|                                 fccColorEncoding, ulWidth, ulHeight, | ||||
|                                 ulScanLineSize, pVOData->pBuffer); | ||||
|     if (ulRC != DIVE_SUCCESS) { | ||||
|         debug_os2("DiveAllocImageBuffer(), rc = 0x%X", ulRC); | ||||
|         DosFreeMem(pVOData->pBuffer); | ||||
|         pVOData->pBuffer = NULL; | ||||
|         pVOData->ulDIVEBufNum = 0; | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   pVOData->fccColorEncoding = fccColorEncoding; | ||||
|   pVOData->ulWidth = ulWidth; | ||||
|   pVOData->ulHeight = ulHeight; | ||||
|     pVOData->fccColorEncoding = fccColorEncoding; | ||||
|     pVOData->ulWidth = ulWidth; | ||||
|     pVOData->ulHeight = ulHeight; | ||||
|  | ||||
|   debug( "buffer: 0x%P, DIVE buffer number: %u", | ||||
|          pVOData->pBuffer, pVOData->ulDIVEBufNum ); | ||||
|     debug_os2("buffer: 0x%P, DIVE buffer number: %u", | ||||
|               pVOData->pBuffer, pVOData->ulDIVEBufNum); | ||||
|  | ||||
|   return pVOData->pBuffer; | ||||
|     return pVOData->pBuffer; | ||||
| } | ||||
|  | ||||
| static VOID voVideoBufFree(PVODATA pVOData) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|     ULONG   ulRC; | ||||
|  | ||||
|   if ( pVOData->ulDIVEBufNum != 0 ) | ||||
|   { | ||||
|     ulRC = DiveFreeImageBuffer( pVOData->hDive, pVOData->ulDIVEBufNum ); | ||||
|     if ( ulRC != DIVE_SUCCESS ) | ||||
|       debug( "DiveFreeImageBuffer(,%u), rc = %u", pVOData->ulDIVEBufNum, ulRC ); | ||||
|     else | ||||
|       debug( "DIVE buffer %u destroyed", pVOData->ulDIVEBufNum ); | ||||
|     if (pVOData->ulDIVEBufNum != 0) { | ||||
|         ulRC = DiveFreeImageBuffer(pVOData->hDive, pVOData->ulDIVEBufNum); | ||||
|         if (ulRC != DIVE_SUCCESS) { | ||||
|             debug_os2("DiveFreeImageBuffer(,%u), rc = %u", pVOData->ulDIVEBufNum, ulRC); | ||||
|         } else { | ||||
|             debug_os2("DIVE buffer %u destroyed", pVOData->ulDIVEBufNum); | ||||
|         } | ||||
|         pVOData->ulDIVEBufNum = 0; | ||||
|     } | ||||
|  | ||||
|     pVOData->ulDIVEBufNum = 0; | ||||
|   } | ||||
|  | ||||
|   if ( pVOData->pBuffer != NULL ) | ||||
|   { | ||||
|     ulRC = DosFreeMem( pVOData->pBuffer ); | ||||
|     if ( ulRC != NO_ERROR ) | ||||
|       debug( "DosFreeMem(), rc = %u", ulRC ); | ||||
|  | ||||
|     pVOData->pBuffer = NULL; | ||||
|   } | ||||
|     if (pVOData->pBuffer != NULL) { | ||||
|         ulRC = DosFreeMem(pVOData->pBuffer); | ||||
|         if (ulRC != NO_ERROR) { | ||||
|             debug_os2("DosFreeMem(), rc = %u", ulRC); | ||||
|         } | ||||
|         pVOData->pBuffer = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, | ||||
|                      ULONG cSDLRects) | ||||
| { | ||||
|   ULONG                ulRC; | ||||
|     ULONG   ulRC; | ||||
|  | ||||
|   if ( !pVOData->fBlitterReady || ( pVOData->ulDIVEBufNum == 0 ) ) | ||||
|   { | ||||
|     debug( "DIVE blitter is not ready" ); | ||||
|     return FALSE; | ||||
|   } | ||||
|  | ||||
|   if ( pSDLRects != 0 ) | ||||
|   { | ||||
|     PBYTE              pbLineMask; | ||||
|  | ||||
|     pbLineMask = SDL_stack_alloc( BYTE, pVOData->ulHeight ); | ||||
|     if ( pbLineMask == NULL ) | ||||
|     { | ||||
|       debug( "Not enough stack size" ); | ||||
|       return FALSE; | ||||
|     if (!pVOData->fBlitterReady || (pVOData->ulDIVEBufNum == 0)) { | ||||
|         debug_os2("DIVE blitter is not ready"); | ||||
|         return FALSE; | ||||
|     } | ||||
|     memset( pbLineMask, 0, pVOData->ulHeight ); | ||||
|  | ||||
|     for( ; ((LONG)cSDLRects) > 0; cSDLRects--, pSDLRects++ ) | ||||
|       memset( &pbLineMask[pSDLRects->y], 1, pSDLRects->h ); | ||||
|     if (pSDLRects != 0) { | ||||
|         PBYTE   pbLineMask; | ||||
|  | ||||
|     ulRC = DiveBlitImageLines( pVOData->hDive, pVOData->ulDIVEBufNum, | ||||
|                                DIVE_BUFFER_SCREEN, pbLineMask ); | ||||
|     SDL_stack_free( pbLineMask ); | ||||
|         pbLineMask = SDL_stack_alloc(BYTE, pVOData->ulHeight); | ||||
|         if (pbLineMask == NULL) { | ||||
|             debug_os2("Not enough stack size"); | ||||
|             return FALSE; | ||||
|         } | ||||
|         memset(pbLineMask, 0, pVOData->ulHeight); | ||||
|  | ||||
|     if ( ulRC != DIVE_SUCCESS ) | ||||
|       debug( "DiveBlitImageLines(), rc = 0x%X", ulRC ); | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     ulRC = DiveBlitImage( pVOData->hDive, pVOData->ulDIVEBufNum, | ||||
|                           DIVE_BUFFER_SCREEN ); | ||||
|     if ( ulRC != DIVE_SUCCESS ) | ||||
|       debug( "DiveBlitImage(), rc = 0x%X", ulRC ); | ||||
|   } | ||||
|         for ( ; ((LONG)cSDLRects) > 0; cSDLRects--, pSDLRects++) { | ||||
|             memset(&pbLineMask[pSDLRects->y], 1, pSDLRects->h); | ||||
|         } | ||||
|  | ||||
|   return ulRC == DIVE_SUCCESS; | ||||
|         ulRC = DiveBlitImageLines(pVOData->hDive, pVOData->ulDIVEBufNum, | ||||
|                                   DIVE_BUFFER_SCREEN, pbLineMask); | ||||
|         SDL_stack_free(pbLineMask); | ||||
|  | ||||
|         if (ulRC != DIVE_SUCCESS) { | ||||
|             debug_os2("DiveBlitImageLines(), rc = 0x%X", ulRC); | ||||
|         } | ||||
|     } else { | ||||
|         ulRC = DiveBlitImage(pVOData->hDive, pVOData->ulDIVEBufNum, | ||||
|                              DIVE_BUFFER_SCREEN); | ||||
|         if (ulRC != DIVE_SUCCESS) { | ||||
|             debug_os2("DiveBlitImage(), rc = 0x%X", ulRC); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return ulRC == DIVE_SUCCESS; | ||||
| } | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -26,46 +26,43 @@ | ||||
| #include "../../events/SDL_mouse_c.h" | ||||
| #include "SDL_os2util.h" | ||||
|  | ||||
| HPOINTER              hptrCursor = NULLHANDLE; | ||||
| HPOINTER    hptrCursor = NULLHANDLE; | ||||
|  | ||||
| static SDL_Cursor* OS2_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) | ||||
| { | ||||
|   ULONG                ulMaxW = WinQuerySysValue( HWND_DESKTOP, SV_CXPOINTER ); | ||||
|   ULONG                ulMaxH = WinQuerySysValue( HWND_DESKTOP, SV_CYPOINTER ); | ||||
|   HPOINTER             hptr; | ||||
|   SDL_Cursor           *pSDLCursor; | ||||
|     ULONG       ulMaxW = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER); | ||||
|     ULONG       ulMaxH = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER); | ||||
|     HPOINTER    hptr; | ||||
|     SDL_Cursor* pSDLCursor; | ||||
|  | ||||
|   if ( ( surface->w > ulMaxW ) || ( surface->h > ulMaxH ) ) | ||||
|   { | ||||
|     debug( "Given image size is %u x %u, maximum allowed size is %u x %u", | ||||
|            surface->w, surface->h, ulMaxW, ulMaxH ); | ||||
|     return NULL; | ||||
|   } | ||||
|     if (surface->w > ulMaxW || surface->h > ulMaxH) { | ||||
|         debug_os2("Given image size is %u x %u, maximum allowed size is %u x %u", | ||||
|                   surface->w, surface->h, ulMaxW, ulMaxH); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   hptr = utilCreatePointer( surface, hot_x, ulMaxH - hot_y - 1 ); | ||||
|   if ( hptr == NULLHANDLE ) | ||||
|     return NULL; | ||||
|     hptr = utilCreatePointer(surface, hot_x, ulMaxH - hot_y - 1); | ||||
|     if (hptr == NULLHANDLE) | ||||
|         return NULL; | ||||
|  | ||||
|   pSDLCursor = SDL_calloc( 1, sizeof(SDL_Cursor) ); | ||||
|   if ( pSDLCursor == NULL ) | ||||
|   { | ||||
|     WinDestroyPointer( hptr ); | ||||
|     SDL_OutOfMemory(); | ||||
|     return NULL; | ||||
|   } | ||||
|     pSDLCursor = SDL_calloc(1, sizeof(SDL_Cursor)); | ||||
|     if (pSDLCursor == NULL) { | ||||
|         WinDestroyPointer(hptr); | ||||
|         SDL_OutOfMemory(); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   pSDLCursor->driverdata = (void *)hptr; | ||||
|   return pSDLCursor; | ||||
|     pSDLCursor->driverdata = (void *)hptr; | ||||
|     return pSDLCursor; | ||||
| } | ||||
|  | ||||
| static SDL_Cursor* OS2_CreateSystemCursor(SDL_SystemCursor id) | ||||
| { | ||||
|   SDL_Cursor*          pSDLCursor; | ||||
|   LONG                 lSysId; | ||||
|   HPOINTER             hptr; | ||||
|     SDL_Cursor* pSDLCursor; | ||||
|     LONG        lSysId; | ||||
|     HPOINTER    hptr; | ||||
|  | ||||
|   switch( id ) | ||||
|   { | ||||
|     switch (id) { | ||||
|     case SDL_SYSTEM_CURSOR_ARROW:     lSysId = SPTR_ARROW;    break; | ||||
|     case SDL_SYSTEM_CURSOR_IBEAM:     lSysId = SPTR_TEXT;     break; | ||||
|     case SDL_SYSTEM_CURSOR_WAIT:      lSysId = SPTR_WAIT;     break; | ||||
| @@ -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_HAND:      lSysId = SPTR_ARROW;    break; | ||||
|     default: | ||||
|       debug( "Unknown cursor id: %u", id ); | ||||
|       return NULL; | ||||
|   } | ||||
|         debug_os2("Unknown cursor id: %u", id); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   // On eCS SPTR_WAIT for last paramether fCopy=TRUE/FALSE gives different | ||||
|   // "wait" icons. -=8( ) | ||||
|   hptr = WinQuerySysPointer( HWND_DESKTOP, lSysId, | ||||
|                              id == SDL_SYSTEM_CURSOR_WAIT ); | ||||
|   if ( hptr == NULLHANDLE ) | ||||
|   { | ||||
|     debug( "Cannot load OS/2 system pointer %u for SDL cursor id %u", | ||||
|            lSysId, id ); | ||||
|     return NULL; | ||||
|   } | ||||
|     /* On eCS SPTR_WAIT for last paramether fCopy=TRUE/FALSE gives different | ||||
|      * "wait" icons. -=8( ) */ | ||||
|     hptr = WinQuerySysPointer(HWND_DESKTOP, lSysId, | ||||
|                               id == SDL_SYSTEM_CURSOR_WAIT); | ||||
|     if (hptr == NULLHANDLE) { | ||||
|         debug_os2("Cannot load OS/2 system pointer %u for SDL cursor id %u", | ||||
|                   lSysId, id); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   pSDLCursor = SDL_calloc( 1, sizeof(SDL_Cursor) ); | ||||
|   if ( pSDLCursor == NULL ) | ||||
|   { | ||||
|     WinDestroyPointer( hptr ); | ||||
|     SDL_OutOfMemory(); | ||||
|     return NULL; | ||||
|   } | ||||
|     pSDLCursor = SDL_calloc(1, sizeof(SDL_Cursor)); | ||||
|     if (pSDLCursor == NULL) { | ||||
|         WinDestroyPointer(hptr); | ||||
|         SDL_OutOfMemory(); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   pSDLCursor->driverdata = (void *)hptr; | ||||
|   return pSDLCursor; | ||||
|     pSDLCursor->driverdata = (void *)hptr; | ||||
|     return pSDLCursor; | ||||
| } | ||||
|  | ||||
| static void OS2_FreeCursor(SDL_Cursor *cursor) | ||||
| { | ||||
|   HPOINTER             hptr = (HPOINTER)cursor->driverdata; | ||||
|     HPOINTER    hptr = (HPOINTER)cursor->driverdata; | ||||
|  | ||||
|   WinDestroyPointer( hptr ); | ||||
|   SDL_free( cursor ); | ||||
|     WinDestroyPointer(hptr); | ||||
|     SDL_free(cursor); | ||||
| } | ||||
|  | ||||
| static int OS2_ShowCursor(SDL_Cursor *cursor) | ||||
| { | ||||
|   hptrCursor = cursor != NULL ? (HPOINTER)cursor->driverdata : NULLHANDLE; | ||||
|  | ||||
|   return ( ( SDL_GetMouseFocus() == NULL ) || | ||||
|            WinSetPointer( HWND_DESKTOP, hptrCursor ) ) ? 0 : -1; | ||||
|     hptrCursor = (cursor != NULL)? (HPOINTER)cursor->driverdata : NULLHANDLE; | ||||
|     return ((SDL_GetMouseFocus() == NULL) || | ||||
|              WinSetPointer(HWND_DESKTOP, hptrCursor))? 0 : -1; | ||||
| } | ||||
|  | ||||
| static void OS2_WarpMouse(SDL_Window * window, int x, int y) | ||||
| { | ||||
|   PWINDATA             pWinData = (PWINDATA)window->driverdata; | ||||
|   POINTL               pointl; | ||||
|     WINDATA    *pWinData = (WINDATA *)window->driverdata; | ||||
|     POINTL      pointl; | ||||
|  | ||||
|   pointl.x = x; | ||||
|   pointl.y = window->h - y; | ||||
|   WinMapWindowPoints( pWinData->hwnd, HWND_DESKTOP, &pointl, 1 ); | ||||
| //  pWinData->lSkipWMMouseMove++; ??? | ||||
|   WinSetPointerPos( HWND_DESKTOP, pointl.x, pointl.y ); | ||||
|     pointl.x = x; | ||||
|     pointl.y = window->h - y; | ||||
|     WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1); | ||||
| /*  pWinData->lSkipWMMouseMove++; ???*/ | ||||
|     WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y); | ||||
| } | ||||
|  | ||||
| static int OS2_WarpMouseGlobal(int x, int y) | ||||
| { | ||||
|   WinSetPointerPos( HWND_DESKTOP, x, | ||||
|                     WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - y ); | ||||
|   return 0; | ||||
|     WinSetPointerPos(HWND_DESKTOP, x, | ||||
|                      WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - y); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int OS2_CaptureMouse(SDL_Window *window) | ||||
| { | ||||
|   return WinSetCapture( HWND_DESKTOP, | ||||
|                     window == NULL ? NULLHANDLE | ||||
|                                    : ((PWINDATA)window->driverdata)->hwnd ) | ||||
|            ? 0 : -1; | ||||
|     return WinSetCapture(HWND_DESKTOP, (window == NULL)? NULLHANDLE : | ||||
|                                          ((WINDATA *)window->driverdata)->hwnd)? 0 : -1; | ||||
| } | ||||
|  | ||||
| static Uint32 OS2_GetGlobalMouseState(int *x, int *y) | ||||
| { | ||||
|   POINTL               pointl; | ||||
|   ULONG                ulRes; | ||||
|     POINTL  pointl; | ||||
|     ULONG   ulRes; | ||||
|  | ||||
|   WinQueryPointerPos( HWND_DESKTOP, &pointl ); | ||||
|   *x = pointl.x; | ||||
|   *y = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - pointl.y - 1; | ||||
|     WinQueryPointerPos(HWND_DESKTOP, &pointl); | ||||
|     *x = pointl.x; | ||||
|     *y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - pointl.y - 1; | ||||
|  | ||||
|   ulRes = WinGetKeyState( HWND_DESKTOP, VK_BUTTON1 ) & 0x8000 | ||||
|             ? SDL_BUTTON_LMASK : 0; | ||||
|   if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON2 ) & 0x8000 ) | ||||
|     ulRes |= SDL_BUTTON_RMASK; | ||||
|   if ( WinGetKeyState( HWND_DESKTOP, VK_BUTTON3 ) & 0x8000 ) | ||||
|     ulRes |= SDL_BUTTON_MMASK; | ||||
|     ulRes = (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)? SDL_BUTTON_LMASK : 0; | ||||
|     if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000) | ||||
|         ulRes |= SDL_BUTTON_RMASK; | ||||
|     if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000) | ||||
|         ulRes |= SDL_BUTTON_MMASK; | ||||
|  | ||||
|   return ulRes; | ||||
|     return ulRes; | ||||
| } | ||||
|  | ||||
|  | ||||
| void OS2_InitMouse(_THIS, ULONG hab) | ||||
| { | ||||
|   SDL_Mouse            *pSDLMouse = SDL_GetMouse(); | ||||
|     SDL_Mouse   *pSDLMouse = SDL_GetMouse(); | ||||
|  | ||||
|   pSDLMouse->CreateCursor         = OS2_CreateCursor; | ||||
|   pSDLMouse->CreateSystemCursor   = OS2_CreateSystemCursor; | ||||
|   pSDLMouse->ShowCursor           = OS2_ShowCursor; | ||||
|   pSDLMouse->FreeCursor           = OS2_FreeCursor; | ||||
|   pSDLMouse->WarpMouse            = OS2_WarpMouse; | ||||
|   pSDLMouse->WarpMouseGlobal      = OS2_WarpMouseGlobal; | ||||
|   pSDLMouse->CaptureMouse         = OS2_CaptureMouse; | ||||
|   pSDLMouse->GetGlobalMouseState  = OS2_GetGlobalMouseState; | ||||
|     pSDLMouse->CreateCursor         = OS2_CreateCursor; | ||||
|     pSDLMouse->CreateSystemCursor   = OS2_CreateSystemCursor; | ||||
|     pSDLMouse->ShowCursor           = OS2_ShowCursor; | ||||
|     pSDLMouse->FreeCursor           = OS2_FreeCursor; | ||||
|     pSDLMouse->WarpMouse            = OS2_WarpMouse; | ||||
|     pSDLMouse->WarpMouseGlobal      = OS2_WarpMouseGlobal; | ||||
|     pSDLMouse->CaptureMouse         = OS2_CaptureMouse; | ||||
|     pSDLMouse->GetGlobalMouseState  = OS2_GetGlobalMouseState; | ||||
|  | ||||
|   SDL_SetDefaultCursor( OS2_CreateSystemCursor( SDL_SYSTEM_CURSOR_ARROW ) ); | ||||
|   if ( hptrCursor == NULLHANDLE ) | ||||
|     hptrCursor = WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, TRUE ); | ||||
|     SDL_SetDefaultCursor(OS2_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW)); | ||||
|     if (hptrCursor == NULLHANDLE) | ||||
|         hptrCursor = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE); | ||||
| } | ||||
|  | ||||
| void OS2_QuitMouse(_THIS) | ||||
| { | ||||
|   SDL_Mouse            *pSDLMouse = SDL_GetMouse(); | ||||
|     SDL_Mouse   *pSDLMouse = SDL_GetMouse(); | ||||
|  | ||||
|   if ( pSDLMouse->def_cursor != NULL ) | ||||
|   { | ||||
|     SDL_free( pSDLMouse->def_cursor ); | ||||
|     pSDLMouse->def_cursor = NULL; | ||||
|     pSDLMouse->cur_cursor = NULL; | ||||
|   } | ||||
|     if (pSDLMouse->def_cursor != NULL) { | ||||
|         SDL_free(pSDLMouse->def_cursor); | ||||
|         pSDLMouse->def_cursor = NULL; | ||||
|         pSDLMouse->cur_cursor = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #endif /* SDL_VIDEO_DRIVER_OS2 */ | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
| #ifndef SDL_os2mouse_h_ | ||||
| #define SDL_os2mouse_h_ | ||||
|  | ||||
| extern HPOINTER        hptrCursor; | ||||
| extern HPOINTER hptrCursor; | ||||
|  | ||||
| extern void OS2_InitMouse(_THIS, ULONG hab); | ||||
| extern void OS2_QuitMouse(_THIS); | ||||
|   | ||||
| @@ -26,29 +26,34 @@ | ||||
| typedef struct _VODATA *PVODATA; | ||||
|  | ||||
| typedef struct _VIDEOOUTPUTINFO { | ||||
|   ULONG      ulBPP; | ||||
|   ULONG      fccColorEncoding; | ||||
|   ULONG      ulScanLineSize; | ||||
|   ULONG      ulHorizResolution; | ||||
|   ULONG      ulVertResolution; | ||||
| } VIDEOOUTPUTINFO, *PVIDEOOUTPUTINFO; | ||||
|     ULONG     ulBPP; | ||||
|     ULONG     fccColorEncoding; | ||||
|     ULONG     ulScanLineSize; | ||||
|     ULONG     ulHorizResolution; | ||||
|     ULONG     ulVertResolution; | ||||
| } VIDEOOUTPUTINFO; | ||||
|  | ||||
| typedef struct _OS2VIDEOOUTPUT { | ||||
|   BOOL (*QueryInfo)(PVIDEOOUTPUTINFO pInfo); | ||||
|   PVODATA (*Open)(); | ||||
|   VOID (*Close)(PVODATA pVOData); | ||||
|   BOOL (*SetVisibleRegion)(PVODATA pVOData, HWND hwnd, | ||||
|                            SDL_DisplayMode *pSDLDisplayMode, HRGN hrgnShape, | ||||
|                            BOOL fVisible); | ||||
|   PVOID (*VideoBufAlloc)(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight, | ||||
|                         ULONG ulBPP, ULONG fccColorEncoding, | ||||
|                         PULONG pulScanLineSize); | ||||
|   VOID (*VideoBufFree)(PVODATA pVOData); | ||||
|   BOOL (*Update)(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, | ||||
|                  ULONG cSDLRects); | ||||
| } OS2VIDEOOUTPUT, *POS2VIDEOOUTPUT; | ||||
|     BOOL (*QueryInfo)(VIDEOOUTPUTINFO *pInfo); | ||||
|     PVODATA (*Open)(); | ||||
|     VOID (*Close)(PVODATA pVOData); | ||||
|  | ||||
|     BOOL (*SetVisibleRegion)(PVODATA pVOData, HWND hwnd, | ||||
|                              SDL_DisplayMode *pSDLDisplayMode, HRGN hrgnShape, | ||||
|                              BOOL fVisible); | ||||
|  | ||||
|     PVOID (*VideoBufAlloc)(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight, | ||||
|                            ULONG ulBPP, ULONG fccColorEncoding, | ||||
|                            PULONG pulScanLineSize); | ||||
|  | ||||
|     VOID (*VideoBufFree)(PVODATA pVOData); | ||||
|     BOOL (*Update)(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, | ||||
|                    ULONG cSDLRects); | ||||
| } OS2VIDEOOUTPUT; | ||||
|  | ||||
| extern OS2VIDEOOUTPUT voDive; | ||||
| extern OS2VIDEOOUTPUT voVMan; | ||||
|  | ||||
| #endif /* SDL_os2output_ */ | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -24,95 +24,88 @@ | ||||
|  | ||||
| #include "SDL_os2util.h" | ||||
|  | ||||
|  | ||||
| HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY) | ||||
| { | ||||
|   HBITMAP              hbm; | ||||
|   BITMAPINFOHEADER2    bmih = { 0 }; | ||||
|   BITMAPINFO           bmi = { 0 }; | ||||
|   HPS                  hps; | ||||
|   PULONG               pulBitmap; | ||||
|   PULONG               pulDst, pulSrc, pulDstMask; | ||||
|   ULONG                ulY, ulX; | ||||
|   HPOINTER             hptr = NULLHANDLE; | ||||
|     HBITMAP             hbm; | ||||
|     BITMAPINFOHEADER2   bmih = { 0 }; | ||||
|     BITMAPINFO          bmi = { 0 }; | ||||
|     HPS                 hps; | ||||
|     PULONG              pulBitmap; | ||||
|     PULONG              pulDst, pulSrc, pulDstMask; | ||||
|     ULONG               ulY, ulX; | ||||
|     HPOINTER            hptr = NULLHANDLE; | ||||
|  | ||||
|   if ( surface->format->format != SDL_PIXELFORMAT_ARGB8888 ) | ||||
|   { | ||||
|     debug( "Image format should be SDL_PIXELFORMAT_ARGB8888" ); | ||||
|     return NULLHANDLE; | ||||
|   } | ||||
|  | ||||
|   pulBitmap = SDL_malloc( surface->h * surface->w * 4 * 2 ); | ||||
|   if ( pulBitmap == NULL ) | ||||
|   { | ||||
|     SDL_OutOfMemory(); | ||||
|     return NULLHANDLE; | ||||
|   } | ||||
|  | ||||
|   // pulDst - last line of surface (image) part of the result bitmap | ||||
|   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; | ||||
|       } | ||||
|     if (surface->format->format != SDL_PIXELFORMAT_ARGB8888) { | ||||
|         debug_os2("Image format should be SDL_PIXELFORMAT_ARGB8888"); | ||||
|         return NULLHANDLE; | ||||
|     } | ||||
|  | ||||
|     // Set image and mask pointers on one line up | ||||
|     pulDst -= surface->w; | ||||
|     pulDstMask -= surface->w; | ||||
|     // Set source image pointer to the next line | ||||
|     pulSrc = (PULONG)( ((PCHAR)pulSrc) + surface->pitch ); | ||||
|   } | ||||
|     pulBitmap = SDL_malloc(surface->h * surface->w * 4 * 2); | ||||
|     if (pulBitmap == NULL) { | ||||
|         SDL_OutOfMemory(); | ||||
|         return NULLHANDLE; | ||||
|     } | ||||
|  | ||||
|   // 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); | ||||
|   bmih.cx              = surface->w; | ||||
|   bmih.cy              = 2 * surface->h; | ||||
|   bmih.cPlanes         = 1; | ||||
|   bmih.cBitCount       = 32; | ||||
|   bmih.ulCompression   = BCA_UNCOMP; | ||||
|   bmih.cbImage         = bmih.cx * bmih.cy * 4; | ||||
|     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; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   bmi.cbFix            = sizeof(BITMAPINFOHEADER); | ||||
|   bmi.cx               = bmih.cx; | ||||
|   bmi.cy               = bmih.cy; | ||||
|   bmi.cPlanes          = 1; | ||||
|   bmi.cBitCount        = 32; | ||||
|         /* Set image and mask pointers on one line up */ | ||||
|         pulDst -= surface->w; | ||||
|         pulDstMask -= surface->w; | ||||
|         /* Set source image pointer to the next line */ | ||||
|         pulSrc = (PULONG) (((PCHAR)pulSrc) + surface->pitch); | ||||
|     } | ||||
|  | ||||
|   hps = WinGetPS( HWND_DESKTOP ); | ||||
|   hbm = GpiCreateBitmap( hps, (PBITMAPINFOHEADER2)&bmih, CBM_INIT, | ||||
|                          (PBYTE)pulBitmap, (PBITMAPINFO2)&bmi ); | ||||
|   if ( hbm == GPI_ERROR ) | ||||
|     debug( "GpiCreateBitmap() failed" ); | ||||
|   else | ||||
|   { | ||||
|     // Create a system pointer object. | ||||
|     hptr = WinCreatePointer( HWND_DESKTOP, hbm, TRUE, ulHotX, ulHotY ); | ||||
|     if ( hptr == NULLHANDLE ) | ||||
|       debug( "WinCreatePointer() failed" ); | ||||
|   } | ||||
|   GpiDeleteBitmap( hbm ); | ||||
|     /* Create system bitmap object. */ | ||||
|     bmih.cbFix          = sizeof(BITMAPINFOHEADER2); | ||||
|     bmih.cx             = surface->w; | ||||
|     bmih.cy             = 2 * surface->h; | ||||
|     bmih.cPlanes        = 1; | ||||
|     bmih.cBitCount      = 32; | ||||
|     bmih.ulCompression  = BCA_UNCOMP; | ||||
|     bmih.cbImage        = bmih.cx * bmih.cy * 4; | ||||
|  | ||||
|   WinReleasePS( hps ); | ||||
|   SDL_free( pulBitmap ); | ||||
|     bmi.cbFix           = sizeof(BITMAPINFOHEADER); | ||||
|     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 */ | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -33,3 +33,6 @@ | ||||
| HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY); | ||||
|  | ||||
| #endif /* SDL_os2util_h_ */ | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|  | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -39,43 +39,44 @@ | ||||
| #include "SDL_os2output.h" | ||||
|  | ||||
| typedef struct SDL_VideoData { | ||||
|   HAB                  hab; | ||||
|   HMQ                  hmq; | ||||
|   POS2VIDEOOUTPUT      pOutput;            // Video output routines. | ||||
| } SDL_VideoData, *PSDL_VideoData; | ||||
|     HAB             hab; | ||||
|     HMQ             hmq; | ||||
|     OS2VIDEOOUTPUT *pOutput; /* Video output routines */ | ||||
| } SDL_VideoData; | ||||
|  | ||||
| typedef struct _WINDATA { | ||||
|   SDL_Window           *window; | ||||
|   POS2VIDEOOUTPUT      pOutput;            // Video output routines. | ||||
|   HWND                 hwndFrame; | ||||
|   HWND                 hwnd; | ||||
|   PFNWP                fnUserWndProc; | ||||
|   PFNWP                fnWndFrameProc; | ||||
|     SDL_Window     *window; | ||||
|     OS2VIDEOOUTPUT *pOutput; /* Video output routines */ | ||||
|     HWND            hwndFrame; | ||||
|     HWND            hwnd; | ||||
|     PFNWP           fnUserWndProc; | ||||
|     PFNWP           fnWndFrameProc; | ||||
|  | ||||
|   PVODATA              pVOData;            // Video output data. | ||||
|     PVODATA         pVOData; /* Video output data */ | ||||
|  | ||||
|   HRGN                 hrgnShape; | ||||
|   HPOINTER             hptrIcon; | ||||
|   RECTL                rectlBeforeFS; | ||||
|     HRGN            hrgnShape; | ||||
|     HPOINTER        hptrIcon; | ||||
|     RECTL           rectlBeforeFS; | ||||
|  | ||||
|   LONG                 lSkipWMSize; | ||||
|   LONG                 lSkipWMMove; | ||||
|   LONG                 lSkipWMMouseMove; | ||||
|   LONG                 lSkipWMVRNEnabled; | ||||
|   LONG                 lSkipWMAdjustFramePos; | ||||
| } WINDATA, *PWINDATA; | ||||
|     LONG            lSkipWMSize; | ||||
|     LONG            lSkipWMMove; | ||||
|     LONG            lSkipWMMouseMove; | ||||
|     LONG            lSkipWMVRNEnabled; | ||||
|     LONG            lSkipWMAdjustFramePos; | ||||
| } WINDATA; | ||||
|  | ||||
| typedef struct _DISPLAYDATA { | ||||
|   ULONG                ulDPIHor; | ||||
|   ULONG                ulDPIVer; | ||||
|   ULONG                ulDPIDiag; | ||||
| } DISPLAYDATA, *PDISPLAYDATA; | ||||
|     ULONG           ulDPIHor; | ||||
|     ULONG           ulDPIVer; | ||||
|     ULONG           ulDPIDiag; | ||||
| } DISPLAYDATA; | ||||
|  | ||||
| typedef struct _MODEDATA { | ||||
|   ULONG                ulDepth; | ||||
|   ULONG                fccColorEncoding; | ||||
|   ULONG                ulScanLineBytes; | ||||
| } MODEDATA, *PMODEDATA; | ||||
|  | ||||
|     ULONG           ulDepth; | ||||
|     ULONG           fccColorEncoding; | ||||
|     ULONG           ulScanLineBytes; | ||||
| } MODEDATA; | ||||
|  | ||||
| #endif /* SDL_os2video_h_ */ | ||||
|  | ||||
| /* vi: set ts=4 sw=4 expandtab: */ | ||||
|   | ||||
| @@ -34,23 +34,23 @@ | ||||
| #include "my_gradd.h" | ||||
|  | ||||
| typedef struct _VODATA { | ||||
|   PVOID      pBuffer; | ||||
|   HRGN       hrgnVisible; | ||||
|   ULONG      ulBPP; | ||||
|   ULONG      ulScanLineSize; | ||||
|   ULONG      ulWidth; | ||||
|   ULONG      ulHeight; | ||||
|   ULONG      ulScreenHeight; | ||||
|   ULONG      ulScreenBytesPerLine; | ||||
|   RECTL      rectlWin; | ||||
|   PVOID    pBuffer; | ||||
|   HRGN     hrgnVisible; | ||||
|   ULONG    ulBPP; | ||||
|   ULONG    ulScanLineSize; | ||||
|   ULONG    ulWidth; | ||||
|   ULONG    ulHeight; | ||||
|   ULONG    ulScreenHeight; | ||||
|   ULONG    ulScreenBytesPerLine; | ||||
|   RECTL    rectlWin; | ||||
|  | ||||
|   PRECTL     pRectl; | ||||
|   ULONG      cRectl; | ||||
|   PBLTRECT   pBltRect; | ||||
|   ULONG      cBltRect; | ||||
|   PRECTL   pRectl; | ||||
|   ULONG    cRectl; | ||||
|   PBLTRECT pBltRect; | ||||
|   ULONG    cBltRect; | ||||
| } VODATA; | ||||
|  | ||||
| static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo); | ||||
| static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo); | ||||
| static PVODATA voOpen(); | ||||
| static VOID voClose(PVODATA pVOData); | ||||
| static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd, | ||||
| @@ -64,448 +64,421 @@ static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, | ||||
|                      ULONG cSDLRects); | ||||
|  | ||||
| OS2VIDEOOUTPUT voVMan = { | ||||
|   voQueryInfo, | ||||
|   voOpen, | ||||
|   voClose, | ||||
|   voSetVisibleRegion, | ||||
|   voVideoBufAlloc, | ||||
|   voVideoBufFree, | ||||
|   voUpdate | ||||
|     voQueryInfo, | ||||
|     voOpen, | ||||
|     voClose, | ||||
|     voSetVisibleRegion, | ||||
|     voVideoBufAlloc, | ||||
|     voVideoBufFree, | ||||
|     voUpdate | ||||
| }; | ||||
|  | ||||
|  | ||||
| static HMODULE         hmodVMan = NULLHANDLE; | ||||
| static FNVMIENTRY      *pfnVMIEntry = NULL; | ||||
| static ULONG           ulVRAMAddress = 0; | ||||
| static HMODULE  hmodVMan = NULLHANDLE; | ||||
| static FNVMIENTRY *pfnVMIEntry = NULL; | ||||
| static ULONG        ulVRAMAddress = 0; | ||||
|  | ||||
| VOID APIENTRY ExitVMan(VOID) | ||||
| { | ||||
|   if ( ( ulVRAMAddress != 0 ) && ( hmodVMan != NULLHANDLE ) ) | ||||
|   { | ||||
|     pfnVMIEntry( 0, VMI_CMD_TERMPROC, NULL, NULL ); | ||||
|     DosFreeModule( hmodVMan ); | ||||
|   } | ||||
|     if (ulVRAMAddress != 0 && hmodVMan != NULLHANDLE) { | ||||
|         pfnVMIEntry(0, VMI_CMD_TERMPROC, NULL, NULL); | ||||
|         DosFreeModule(hmodVMan); | ||||
|     } | ||||
|  | ||||
|   DosExitList( EXLST_EXIT, (PFNEXITLIST)NULL ); | ||||
|     DosExitList(EXLST_EXIT, (PFNEXITLIST)NULL); | ||||
| } | ||||
|  | ||||
| static BOOL _vmanInit() | ||||
| static BOOL _vmanInit(void) | ||||
| { | ||||
|   ULONG                ulRC; | ||||
|   CHAR                 acBuf[255]; | ||||
|   INITPROCOUT          stInitProcOut; | ||||
|     ULONG       ulRC; | ||||
|     CHAR        acBuf[255]; | ||||
|     INITPROCOUT stInitProcOut; | ||||
|  | ||||
|     if (hmodVMan != NULLHANDLE) /* Already was initialized */ | ||||
|         return TRUE; | ||||
|  | ||||
|     /* Load vman.dll */ | ||||
|     ulRC = DosLoadModule(acBuf, sizeof(acBuf), "VMAN", &hmodVMan); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_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; | ||||
|  | ||||
|   // Load vman.dll | ||||
|   ulRC = DosLoadModule( acBuf, sizeof(acBuf), "VMAN", &hmodVMan ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "Could not load VMAN.DLL, rc = %u : %s", ulRC, &acBuf ); | ||||
|     hmodVMan = NULLHANDLE; | ||||
|     return FALSE; | ||||
|   } | ||||
|  | ||||
|   // Get VMIEntry. | ||||
|   ulRC = DosQueryProcAddr( hmodVMan, 0L, "VMIEntry", (PFN *)&pfnVMIEntry ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "Could not query address of pfnVMIEntry func. of VMAN.DLL, " | ||||
|            "rc = %u", ulRC ); | ||||
|     DosFreeModule( hmodVMan ); | ||||
|     hmodVMan = NULLHANDLE; | ||||
|     return FALSE; | ||||
|   } | ||||
|  | ||||
|   // VMAN initialization. | ||||
|   stInitProcOut.ulLength = sizeof(stInitProcOut); | ||||
|   ulRC = pfnVMIEntry( 0, VMI_CMD_INITPROC, NULL, &stInitProcOut ); | ||||
|   if ( ulRC != RC_SUCCESS ) | ||||
|   { | ||||
|     debug( "Could not initialize VMAN for this process" ); | ||||
|     pfnVMIEntry = NULL; | ||||
|     DosFreeModule( hmodVMan ); | ||||
|     hmodVMan = NULLHANDLE; | ||||
|     return FALSE; | ||||
|   } | ||||
|  | ||||
|   // Store video memory virtual address. | ||||
|   ulVRAMAddress = stInitProcOut.ulVRAMVirt; | ||||
|   // We use exit list for VMI_CMD_TERMPROC. | ||||
|   if ( DosExitList( EXLST_ADD | 0x00001000, (PFNEXITLIST)ExitVMan ) | ||||
|        != NO_ERROR ) | ||||
|     debug( "DosExitList() failed" ); | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| static PRECTL _getRectlArray(PVODATA pVOData, ULONG cRects) | ||||
| { | ||||
|   PRECTL     pRectl; | ||||
|     PRECTL  pRectl; | ||||
|  | ||||
|   if ( pVOData->cRectl >= cRects ) | ||||
|     return pVOData->pRectl; | ||||
|     if (pVOData->cRectl >= cRects) | ||||
|         return pVOData->pRectl; | ||||
|  | ||||
|   pRectl = SDL_realloc( pVOData->pRectl, cRects * sizeof(RECTL) ); | ||||
|   if ( pRectl == NULL ) | ||||
|     return NULL; | ||||
|     pRectl = SDL_realloc(pVOData->pRectl, cRects * sizeof(RECTL)); | ||||
|     if (pRectl == NULL) | ||||
|         return NULL; | ||||
|  | ||||
|   pVOData->pRectl = pRectl; | ||||
|   pVOData->cRectl = cRects; | ||||
|   return pRectl; | ||||
|     pVOData->pRectl = pRectl; | ||||
|     pVOData->cRectl = cRects; | ||||
|     return pRectl; | ||||
| } | ||||
|  | ||||
| static PBLTRECT _getBltRectArray(PVODATA pVOData, ULONG cRects) | ||||
| { | ||||
|   PBLTRECT   pBltRect; | ||||
|     PBLTRECT    pBltRect; | ||||
|  | ||||
|   if ( pVOData->cBltRect >= cRects ) | ||||
|     return pVOData->pBltRect; | ||||
|     if (pVOData->cBltRect >= cRects) | ||||
|         return pVOData->pBltRect; | ||||
|  | ||||
|   pBltRect = SDL_realloc( pVOData->pBltRect, cRects * sizeof(BLTRECT) ); | ||||
|   if ( pBltRect == NULL ) | ||||
|     return NULL; | ||||
|     pBltRect = SDL_realloc(pVOData->pBltRect, cRects * sizeof(BLTRECT)); | ||||
|     if (pBltRect == NULL) | ||||
|         return NULL; | ||||
|  | ||||
|   pVOData->pBltRect = pBltRect; | ||||
|   pVOData->cBltRect = cRects; | ||||
|   return pBltRect; | ||||
|     pVOData->pBltRect = pBltRect; | ||||
|     pVOData->cBltRect = cRects; | ||||
|     return pBltRect; | ||||
| } | ||||
|  | ||||
|  | ||||
| static BOOL voQueryInfo(PVIDEOOUTPUTINFO pInfo) | ||||
| static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo) | ||||
| { | ||||
|   ULONG                ulRC; | ||||
|   GDDMODEINFO          sCurModeInfo; | ||||
|     ULONG       ulRC; | ||||
|     GDDMODEINFO sCurModeInfo; | ||||
|  | ||||
|   if ( !_vmanInit() ) | ||||
|     return FALSE; | ||||
|     if (!_vmanInit()) | ||||
|         return FALSE; | ||||
|  | ||||
|   // Query current (desktop) mode. | ||||
|   ulRC = pfnVMIEntry( 0, VMI_CMD_QUERYCURRENTMODE, NULL, &sCurModeInfo ); | ||||
|   if ( ulRC != RC_SUCCESS ) | ||||
|   { | ||||
|     debug( "Could not query desktop video mode." ); | ||||
|     return FALSE; | ||||
|   } | ||||
|     /* Query current (desktop) mode */ | ||||
|     ulRC = pfnVMIEntry(0, VMI_CMD_QUERYCURRENTMODE, NULL, &sCurModeInfo); | ||||
|     if (ulRC != RC_SUCCESS) { | ||||
|         debug_os2("Could not query desktop video mode."); | ||||
|         return FALSE; | ||||
|     } | ||||
|  | ||||
|   pInfo->ulBPP             = sCurModeInfo.ulBpp; | ||||
|   pInfo->ulHorizResolution = sCurModeInfo.ulHorizResolution; | ||||
|   pInfo->ulVertResolution  = sCurModeInfo.ulVertResolution; | ||||
|   pInfo->ulScanLineSize    = sCurModeInfo.ulScanLineSize; | ||||
|   pInfo->fccColorEncoding  = sCurModeInfo.fccColorEncoding; | ||||
|     pInfo->ulBPP             = sCurModeInfo.ulBpp; | ||||
|     pInfo->ulHorizResolution = sCurModeInfo.ulHorizResolution; | ||||
|     pInfo->ulVertResolution  = sCurModeInfo.ulVertResolution; | ||||
|     pInfo->ulScanLineSize    = sCurModeInfo.ulScanLineSize; | ||||
|     pInfo->fccColorEncoding  = sCurModeInfo.fccColorEncoding; | ||||
|  | ||||
|   return TRUE; | ||||
|     return TRUE; | ||||
| } | ||||
|  | ||||
| static PVODATA voOpen() | ||||
| static PVODATA voOpen(void) | ||||
| { | ||||
|   PVODATA              pVOData; | ||||
|     PVODATA pVOData; | ||||
|  | ||||
|   if ( !_vmanInit() ) | ||||
|     return NULL; | ||||
|     if (!_vmanInit()) | ||||
|         return NULL; | ||||
|  | ||||
|   pVOData = SDL_calloc( 1, sizeof(VODATA) ); | ||||
|   if ( pVOData == NULL ) | ||||
|   { | ||||
|     SDL_OutOfMemory(); | ||||
|     return NULL; | ||||
|   } | ||||
|     pVOData = SDL_calloc(1, sizeof(VODATA)); | ||||
|     if (pVOData == NULL) { | ||||
|         SDL_OutOfMemory(); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   return pVOData; | ||||
|     return pVOData; | ||||
| } | ||||
|  | ||||
| static VOID voClose(PVODATA pVOData) | ||||
| { | ||||
|   if ( pVOData->pRectl != NULL ) | ||||
|     SDL_free( pVOData->pRectl ); | ||||
|     if (pVOData->pRectl != NULL) | ||||
|         SDL_free(pVOData->pRectl); | ||||
|  | ||||
|   if ( pVOData->pBltRect != NULL ) | ||||
|     SDL_free( pVOData->pBltRect ); | ||||
|     if (pVOData->pBltRect != NULL) | ||||
|         SDL_free(pVOData->pBltRect); | ||||
|  | ||||
|   voVideoBufFree( pVOData ); | ||||
|     voVideoBufFree(pVOData); | ||||
| } | ||||
|  | ||||
| static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd, | ||||
|                                SDL_DisplayMode *pSDLDisplayMode, | ||||
|                                HRGN hrgnShape, BOOL fVisible) | ||||
| { | ||||
|   HPS        hps; | ||||
|   BOOL       fSuccess = FALSE; | ||||
|     HPS   hps; | ||||
|     BOOL  fSuccess = FALSE; | ||||
|  | ||||
|   hps = WinGetPS( hwnd ); | ||||
|     hps = WinGetPS(hwnd); | ||||
|  | ||||
|   if ( pVOData->hrgnVisible != NULLHANDLE ) | ||||
|   { | ||||
|     GpiDestroyRegion( hps, pVOData->hrgnVisible ); | ||||
|     pVOData->hrgnVisible = NULLHANDLE; | ||||
|   } | ||||
|  | ||||
|   if ( fVisible ) | ||||
|   { | ||||
|     // Query visible rectangles | ||||
|  | ||||
|     pVOData->hrgnVisible = GpiCreateRegion( hps, 0, NULL ); | ||||
|     if ( pVOData->hrgnVisible == NULLHANDLE ) | ||||
|     { | ||||
|       SDL_SetError( "GpiCreateRegion() failed" ); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       if ( WinQueryVisibleRegion( hwnd, pVOData->hrgnVisible ) == RGN_ERROR ) | ||||
|       { | ||||
|         GpiDestroyRegion( hps, pVOData->hrgnVisible ); | ||||
|     if (pVOData->hrgnVisible != NULLHANDLE) { | ||||
|         GpiDestroyRegion(hps, pVOData->hrgnVisible); | ||||
|         pVOData->hrgnVisible = NULLHANDLE; | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         if ( hrgnShape != NULLHANDLE ) | ||||
|           GpiCombineRegion( hps, pVOData->hrgnVisible, pVOData->hrgnVisible, | ||||
|                             hrgnShape, CRGN_AND ); | ||||
|         fSuccess = TRUE; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     WinQueryWindowRect( hwnd, &pVOData->rectlWin ); | ||||
|     WinMapWindowPoints( hwnd, HWND_DESKTOP, (PPOINTL)&pVOData->rectlWin, 2 ); | ||||
|     if (fVisible) { | ||||
|         /* Query visible rectangles */ | ||||
|         pVOData->hrgnVisible = GpiCreateRegion(hps, 0, NULL); | ||||
|         if (pVOData->hrgnVisible == NULLHANDLE) { | ||||
|             SDL_SetError("GpiCreateRegion() failed"); | ||||
|         } else { | ||||
|             if (WinQueryVisibleRegion(hwnd, pVOData->hrgnVisible) == RGN_ERROR) { | ||||
|                 GpiDestroyRegion(hps, pVOData->hrgnVisible); | ||||
|                 pVOData->hrgnVisible = NULLHANDLE; | ||||
|             } else { | ||||
|                 if (hrgnShape != NULLHANDLE) | ||||
|                     GpiCombineRegion(hps, pVOData->hrgnVisible, pVOData->hrgnVisible, | ||||
|                                      hrgnShape, CRGN_AND); | ||||
|                 fSuccess = TRUE; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     if ( pSDLDisplayMode != NULL ) | ||||
|     { | ||||
|       pVOData->ulScreenHeight = pSDLDisplayMode->h; | ||||
|       pVOData->ulScreenBytesPerLine = | ||||
|                      ((PMODEDATA)pSDLDisplayMode->driverdata)->ulScanLineBytes; | ||||
|         WinQueryWindowRect(hwnd, &pVOData->rectlWin); | ||||
|         WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL)&pVOData->rectlWin, 2); | ||||
|  | ||||
|         if (pSDLDisplayMode != NULL) { | ||||
|             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, | ||||
|                              ULONG ulBPP, ULONG fccColorEncoding, | ||||
|                              PULONG pulScanLineSize) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|   ULONG      ulScanLineSize = ulWidth * (ulBPP >> 3); | ||||
|     ULONG ulRC; | ||||
|     ULONG ulScanLineSize = ulWidth * (ulBPP >> 3); | ||||
|  | ||||
|   // Destroy previous buffer. | ||||
|   voVideoBufFree( pVOData ); | ||||
|     /* Destroy previous buffer */ | ||||
|     voVideoBufFree(pVOData); | ||||
|  | ||||
|   if ( ( ulWidth == 0 ) || ( ulHeight == 0 ) || ( ulBPP == 0 ) ) | ||||
|     return NULL; | ||||
|     if (ulWidth == 0 || ulHeight == 0 || ulBPP == 0) | ||||
|         return NULL; | ||||
|  | ||||
|   // Bytes per line. | ||||
|   ulScanLineSize = ( ulScanLineSize + 3 ) & ~3;	/* 4-byte aligning */ | ||||
|   *pulScanLineSize = ulScanLineSize; | ||||
|     /* Bytes per line */ | ||||
|     ulScanLineSize  = (ulScanLineSize + 3) & ~3; /* 4-byte aligning */ | ||||
|     *pulScanLineSize = ulScanLineSize; | ||||
|  | ||||
|   ulRC = DosAllocMem( &pVOData->pBuffer, | ||||
|                       (ulHeight * ulScanLineSize) + sizeof(ULONG), | ||||
|                       PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|   { | ||||
|     debug( "DosAllocMem(), rc = %u", ulRC ); | ||||
|     return NULL; | ||||
|   } | ||||
|     ulRC = DosAllocMem(&pVOData->pBuffer, | ||||
|                        (ulHeight * ulScanLineSize) + sizeof(ULONG), | ||||
|                        PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosAllocMem(), rc = %u", ulRC); | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|   pVOData->ulBPP          = ulBPP; | ||||
|   pVOData->ulScanLineSize = ulScanLineSize; | ||||
|   pVOData->ulWidth        = ulWidth; | ||||
|   pVOData->ulHeight       = ulHeight; | ||||
|     pVOData->ulBPP          = ulBPP; | ||||
|     pVOData->ulScanLineSize = ulScanLineSize; | ||||
|     pVOData->ulWidth        = ulWidth; | ||||
|     pVOData->ulHeight       = ulHeight; | ||||
|  | ||||
|   return pVOData->pBuffer; | ||||
|     return pVOData->pBuffer; | ||||
| } | ||||
|  | ||||
| static VOID voVideoBufFree(PVODATA pVOData) | ||||
| { | ||||
|   ULONG      ulRC; | ||||
|     ULONG ulRC; | ||||
|  | ||||
|   if ( pVOData->pBuffer == NULL ) | ||||
|     return; | ||||
|     if (pVOData->pBuffer == NULL) | ||||
|         return; | ||||
|  | ||||
|   ulRC = DosFreeMem( pVOData->pBuffer ); | ||||
|   if ( ulRC != NO_ERROR ) | ||||
|     debug( "DosFreeMem(), rc = %u", ulRC ); | ||||
|   else | ||||
|     pVOData->pBuffer = NULL; | ||||
|     ulRC = DosFreeMem(pVOData->pBuffer); | ||||
|     if (ulRC != NO_ERROR) { | ||||
|         debug_os2("DosFreeMem(), rc = %u", ulRC); | ||||
|     } else { | ||||
|         pVOData->pBuffer = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, | ||||
|                      ULONG cSDLRects) | ||||
| { | ||||
|   PRECTL               prectlDst, prectlScan; | ||||
|   HPS                  hps; | ||||
|   HRGN                 hrgnUpdate; | ||||
|   RGNRECT              rgnCtl; | ||||
|   SDL_Rect             stSDLRectDef; | ||||
|   BMAPINFO             bmiSrc; | ||||
|   BMAPINFO             bmiDst; | ||||
|   PPOINTL              pptlSrcOrg; | ||||
|   PBLTRECT             pbrDst; | ||||
|   HWREQIN              sHWReqIn; | ||||
|   BITBLTINFO           sBitbltInfo = { 0 }; | ||||
|   ULONG                ulIdx; | ||||
| //  RECTL                rectlScreenUpdate; | ||||
|     PRECTL      prectlDst, prectlScan; | ||||
|     HPS         hps; | ||||
|     HRGN        hrgnUpdate; | ||||
|     RGNRECT     rgnCtl; | ||||
|     SDL_Rect    stSDLRectDef; | ||||
|     BMAPINFO    bmiSrc; | ||||
|     BMAPINFO    bmiDst; | ||||
|     PPOINTL     pptlSrcOrg; | ||||
|     PBLTRECT    pbrDst; | ||||
|     HWREQIN     sHWReqIn; | ||||
|     BITBLTINFO  sBitbltInfo = { 0 }; | ||||
|     ULONG       ulIdx; | ||||
| /*  RECTL       rectlScreenUpdate;*/ | ||||
|  | ||||
|   if ( pVOData->pBuffer == NULL ) | ||||
|     return FALSE; | ||||
|     if (pVOData->pBuffer == NULL) | ||||
|         return FALSE; | ||||
|  | ||||
|   if ( pVOData->hrgnVisible == NULLHANDLE ) | ||||
|     return TRUE; | ||||
|     if (pVOData->hrgnVisible == NULLHANDLE) | ||||
|         return TRUE; | ||||
|  | ||||
|   bmiSrc.ulLength = sizeof(BMAPINFO); | ||||
|   bmiSrc.ulType = BMAP_MEMORY; | ||||
|   bmiSrc.ulWidth = pVOData->ulWidth; | ||||
|   bmiSrc.ulHeight = pVOData->ulHeight; | ||||
|   bmiSrc.ulBpp = pVOData->ulBPP; | ||||
|   bmiSrc.ulBytesPerLine = pVOData->ulScanLineSize; | ||||
|   bmiSrc.pBits = (PBYTE)pVOData->pBuffer; | ||||
|     bmiSrc.ulLength = sizeof(BMAPINFO); | ||||
|     bmiSrc.ulType = BMAP_MEMORY; | ||||
|     bmiSrc.ulWidth = pVOData->ulWidth; | ||||
|     bmiSrc.ulHeight = pVOData->ulHeight; | ||||
|     bmiSrc.ulBpp = pVOData->ulBPP; | ||||
|     bmiSrc.ulBytesPerLine = pVOData->ulScanLineSize; | ||||
|     bmiSrc.pBits = (PBYTE)pVOData->pBuffer; | ||||
|  | ||||
|   bmiDst.ulLength = sizeof(BMAPINFO); | ||||
|   bmiDst.ulType = BMAP_VRAM; | ||||
|   bmiDst.pBits = (PBYTE)ulVRAMAddress; | ||||
|   bmiDst.ulWidth = bmiSrc.ulWidth; | ||||
|   bmiDst.ulHeight = bmiSrc.ulHeight; | ||||
|   bmiDst.ulBpp = bmiSrc.ulBpp; | ||||
|   bmiDst.ulBytesPerLine = pVOData->ulScreenBytesPerLine; | ||||
|     bmiDst.ulLength = sizeof(BMAPINFO); | ||||
|     bmiDst.ulType = BMAP_VRAM; | ||||
|     bmiDst.pBits = (PBYTE)ulVRAMAddress; | ||||
|     bmiDst.ulWidth = bmiSrc.ulWidth; | ||||
|     bmiDst.ulHeight = bmiSrc.ulHeight; | ||||
|     bmiDst.ulBpp = bmiSrc.ulBpp; | ||||
|     bmiDst.ulBytesPerLine = pVOData->ulScreenBytesPerLine; | ||||
|  | ||||
|   // List of update rectangles. This is the intersection of requested | ||||
|   // rectangles and visible rectangles. | ||||
|  | ||||
|   if ( cSDLRects == 0 ) | ||||
|   { | ||||
|     // Full update requested. | ||||
|     stSDLRectDef.x = 0; | ||||
|     stSDLRectDef.y = 0; | ||||
|     stSDLRectDef.w = bmiSrc.ulWidth; | ||||
|     stSDLRectDef.h = bmiSrc.ulHeight; | ||||
|     pSDLRects = &stSDLRectDef; | ||||
|     cSDLRects = 1; | ||||
|   } | ||||
|  | ||||
|   // Make list of destionation rectangles (prectlDst) list from the source | ||||
|   // list (prectl). | ||||
|   prectlDst = _getRectlArray( pVOData, cSDLRects ); | ||||
|   if ( prectlDst == NULL ) | ||||
|   { | ||||
|     debug( "Not enough memory" ); | ||||
|     return FALSE; | ||||
|   } | ||||
|   prectlScan = prectlDst; | ||||
|   for( ulIdx = 0; ulIdx < cSDLRects; ulIdx++, pSDLRects++, prectlScan++ ) | ||||
|   { | ||||
|     prectlScan->xLeft   = pSDLRects->x; | ||||
|     prectlScan->yTop    = pVOData->ulHeight - pSDLRects->y; | ||||
|     prectlScan->xRight  = prectlScan->xLeft + pSDLRects->w; | ||||
|     prectlScan->yBottom = prectlScan->yTop - pSDLRects->h; | ||||
|   } | ||||
|  | ||||
|   hps = WinGetPS( hwnd ); | ||||
|   if ( hps == NULLHANDLE ) | ||||
|     return FALSE; | ||||
|  | ||||
|   // Make destination region to update. | ||||
|   hrgnUpdate = GpiCreateRegion( hps, cSDLRects, prectlDst ); | ||||
|   // "AND" on visible and destination regions, result is region to update. | ||||
|   GpiCombineRegion( hps, hrgnUpdate, hrgnUpdate, pVOData->hrgnVisible, | ||||
|                     CRGN_AND ); | ||||
|  | ||||
|   // Get rectangles of the region to update. | ||||
|   rgnCtl.ircStart     = 1; | ||||
|   rgnCtl.crc          = 0; | ||||
|   rgnCtl.ulDirection  = 1; | ||||
|   rgnCtl.crcReturned  = 0; | ||||
|   GpiQueryRegionRects( hps, hrgnUpdate, NULL, &rgnCtl, NULL ); | ||||
|   if ( rgnCtl.crcReturned == 0 ) | ||||
|   { | ||||
|     GpiDestroyRegion( hps, hrgnUpdate ); | ||||
|     WinReleasePS( hps ); | ||||
|     return TRUE; | ||||
|   } | ||||
|   // We don't need prectlDst, use it again to store update regions. | ||||
|   prectlDst = _getRectlArray( pVOData, rgnCtl.crcReturned ); | ||||
|   if ( prectlDst == NULL ) | ||||
|   { | ||||
|     debug( "Not enough memory" ); | ||||
|     GpiDestroyRegion( hps, hrgnUpdate ); | ||||
|     WinReleasePS( hps ); | ||||
|     return FALSE; | ||||
|   } | ||||
|   rgnCtl.ircStart     = 1; | ||||
|   rgnCtl.crc          = rgnCtl.crcReturned; | ||||
|   rgnCtl.ulDirection  = 1; | ||||
|   GpiQueryRegionRects( hps, hrgnUpdate, NULL, &rgnCtl, prectlDst ); | ||||
|   GpiDestroyRegion( hps, hrgnUpdate ); | ||||
|   WinReleasePS( hps ); | ||||
|   cSDLRects = rgnCtl.crcReturned; | ||||
|   // Now cRect/prectlDst is a list of regions in window (update && visible). | ||||
|  | ||||
|   // Make lists for blitting from update regions. | ||||
|  | ||||
|   pbrDst = _getBltRectArray( pVOData, cSDLRects ); | ||||
|   if ( pbrDst == NULL ) | ||||
|   { | ||||
|     debug( "Not enough memory" ); | ||||
|     return FALSE; | ||||
|   } | ||||
|  | ||||
|   prectlScan = prectlDst; | ||||
|   pptlSrcOrg = (PPOINTL)prectlDst; // Yes, this memory block will be used again. | ||||
|   for( ulIdx = 0; ulIdx < cSDLRects; ulIdx++, prectlScan++, pptlSrcOrg++ ) | ||||
|   { | ||||
|     pbrDst[ulIdx].ulXOrg = pVOData->rectlWin.xLeft + prectlScan->xLeft; | ||||
|     pbrDst[ulIdx].ulYOrg = pVOData->ulScreenHeight - | ||||
|                            ( pVOData->rectlWin.yBottom + prectlScan->yTop ); | ||||
|     pbrDst[ulIdx].ulXExt = prectlScan->xRight - prectlScan->xLeft; | ||||
|     pbrDst[ulIdx].ulYExt = prectlScan->yTop - prectlScan->yBottom; | ||||
|     pptlSrcOrg->x = prectlScan->xLeft; | ||||
|     pptlSrcOrg->y = bmiSrc.ulHeight - prectlScan->yTop; | ||||
|   } | ||||
|   pptlSrcOrg = (PPOINTL)prectlDst; | ||||
|  | ||||
|   // Request HW | ||||
|   sHWReqIn.ulLength = sizeof(HWREQIN); | ||||
|   sHWReqIn.ulFlags = REQUEST_HW; | ||||
|   sHWReqIn.cScrChangeRects = 1; | ||||
|   sHWReqIn.arectlScreen = &pVOData->rectlWin; | ||||
|   if ( pfnVMIEntry( 0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL ) != RC_SUCCESS ) | ||||
|   { | ||||
|     debug( "pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed" ); | ||||
|     sHWReqIn.cScrChangeRects = 0; // for fail signal only. | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     RECTL rclSrcBounds; | ||||
|  | ||||
|     rclSrcBounds.xLeft = 0; | ||||
|     rclSrcBounds.yBottom = 0; | ||||
|     rclSrcBounds.xRight = bmiSrc.ulWidth; | ||||
|     rclSrcBounds.yTop = bmiSrc.ulHeight; | ||||
|  | ||||
|     sBitbltInfo.ulLength = sizeof(BITBLTINFO); | ||||
|     sBitbltInfo.ulBltFlags = BF_DEFAULT_STATE | BF_ROP_INCL_SRC | BF_PAT_HOLLOW; | ||||
|     sBitbltInfo.cBlits = cSDLRects; | ||||
|     sBitbltInfo.ulROP = ROP_SRCCOPY; | ||||
|     sBitbltInfo.pSrcBmapInfo = &bmiSrc; | ||||
|     sBitbltInfo.pDstBmapInfo = &bmiDst; | ||||
|     sBitbltInfo.prclSrcBounds = &rclSrcBounds; | ||||
|     sBitbltInfo.prclDstBounds = &pVOData->rectlWin; | ||||
|     sBitbltInfo.aptlSrcOrg = pptlSrcOrg; | ||||
|     sBitbltInfo.abrDst = pbrDst; | ||||
|  | ||||
|     // Screen update. | ||||
|     if ( pfnVMIEntry( 0, VMI_CMD_BITBLT, &sBitbltInfo, NULL ) != RC_SUCCESS ) | ||||
|     { | ||||
|       debug( "pfnVMIEntry(,VMI_CMD_BITBLT,,) failed" ); | ||||
|       sHWReqIn.cScrChangeRects = 0; // for fail signal only. | ||||
|     /* List of update rectangles. This is the intersection of requested | ||||
|      * rectangles and visible rectangles.  */ | ||||
|     if (cSDLRects == 0) { | ||||
|         /* Full update requested */ | ||||
|         stSDLRectDef.x = 0; | ||||
|         stSDLRectDef.y = 0; | ||||
|         stSDLRectDef.w = bmiSrc.ulWidth; | ||||
|         stSDLRectDef.h = bmiSrc.ulHeight; | ||||
|         pSDLRects = &stSDLRectDef; | ||||
|         cSDLRects = 1; | ||||
|     } | ||||
|  | ||||
|     // Release HW. | ||||
|     sHWReqIn.ulFlags = 0; | ||||
|     if ( pfnVMIEntry( 0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL ) != RC_SUCCESS ) | ||||
|       debug( "pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed" ); | ||||
|   } | ||||
|     /* Make list of destination rectangles (prectlDst) list from the source | ||||
|      * list (prectl).  */ | ||||
|     prectlDst = _getRectlArray(pVOData, cSDLRects); | ||||
|     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: */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Ozkan Sezer
					Ozkan Sezer