Added S60 port.

--HG--
branch : SDL-1.2
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402375
This commit is contained in:
Ryan C. Gordon 2007-06-24 18:26:35 +00:00
parent 6fb707a2a2
commit 10ab421d01
40 changed files with 11434 additions and 15 deletions

32
README.Symbian Normal file
View file

@ -0,0 +1,32 @@
==============================================================================
Using the Simple DirectMedia Layer with S60 3.x / Symbian 9.x
==============================================================================
These instuctions are for people developing for S60 3.x. S60 3.x
uses Symbian OS so you need S60 SDK.
extract "symbian.zip" into this folder.
go to symbian folder
bldmake bldfiles
abld build
That produces WINSCW and ARMV5 versions of sdl.dll runtime library
and sdl.lib for development.
Eaudiolib.lib and dll are generated as well, and must be delivered
along SDL as it uses it for audio.
There are certain problems with GCC compiler when building for
target, it may compile or binaries are buggy - please use RVCT
compiler as it works and produces far more effient code.
Its likely that SDL application should be integrated into S60
work and behave well there. So there is CSDL class (sdlepocapi.h)
to make this easy. If you do porting from other system, then
implement a S60 application and use CSDL class, they you may
not need to modify original SDL code at all!

View file

@ -46,6 +46,9 @@ SDL 1.2.12 is a minor bug fix release.
<P>
Support for Nokia 9210 "EPOC" driver has been removed from the main SDL code.
</P>
<P>
Unofficial support for the S60/SymbianOS platform has been added.
</P>
</BLOCKQUOTE>
<H3> Unix Notes </H3>

View file

@ -32,6 +32,8 @@
#include "SDL_config_macos.h"
#elif defined(__MACOSX__)
#include "SDL_config_macosx.h"
#elif defined(__SYMBIAN32__)
#include "SDL_config_symbian.h" /* must be before win32! */
#elif defined(__WIN32__)
#include "SDL_config_win32.h"
#elif defined(__OS2__)

View file

@ -224,7 +224,6 @@
/* Enable various threading systems */
#undef SDL_THREAD_BEOS
#undef SDL_THREAD_DC
#undef SDL_THREAD_EPOC
#undef SDL_THREAD_OS2
#undef SDL_THREAD_PTH
#undef SDL_THREAD_PTHREAD
@ -237,7 +236,6 @@
#undef SDL_TIMER_BEOS
#undef SDL_TIMER_DC
#undef SDL_TIMER_DUMMY
#undef SDL_TIMER_EPOC
#undef SDL_TIMER_MACOS
#undef SDL_TIMER_MINT
#undef SDL_TIMER_OS2
@ -255,7 +253,6 @@
#undef SDL_VIDEO_DRIVER_DIRECTFB
#undef SDL_VIDEO_DRIVER_DRAWSPROCKET
#undef SDL_VIDEO_DRIVER_DUMMY
#undef SDL_VIDEO_DRIVER_EPOC
#undef SDL_VIDEO_DRIVER_FBCON
#undef SDL_VIDEO_DRIVER_GAPI
#undef SDL_VIDEO_DRIVER_GEM

View file

@ -0,0 +1,146 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
/*
Symbian version Markus Mertama
*/
#ifndef _SDL_CONFIG_SYMBIAN_H
#define _SDL_CONFIG_SYMBIAN_H
#include "SDL_platform.h"
/* This is the minimal configuration that can be used to build SDL */
#include <stdarg.h>
#include <stddef.h>
#ifdef __GCCE__
#define SYMBIAN32_GCCE
#endif
#ifndef _SIZE_T_DEFINED
typedef unsigned int size_t;
#endif
#ifndef _INTPTR_T_DECLARED
typedef unsigned int uintptr_t;
#endif
#ifndef _INT8_T_DECLARED
typedef signed char int8_t;
#endif
#ifndef _UINT8_T_DECLARED
typedef unsigned char uint8_t;
#endif
#ifndef _INT16_T_DECLARED
typedef signed short int16_t;
#endif
#ifndef _UINT16_T_DECLARED
typedef unsigned short uint16_t;
#endif
#ifndef _INT32_T_DECLARED
typedef signed int int32_t;
#endif
#ifndef _UINT32_T_DECLARED
typedef unsigned int uint32_t;
#endif
#ifndef _INT64_T_DECLARED
typedef signed long long int64_t;
#endif
#ifndef _UINT64_T_DECLARED
typedef unsigned long long uint64_t;
#endif
#define SDL_AUDIO_DRIVER_EPOCAUDIO 1
/* Enable the stub cdrom driver (src/cdrom/dummy/\*.c) */
#define SDL_CDROM_DISABLED 1
/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */
#define SDL_JOYSTICK_DISABLED 1
/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */
#define SDL_LOADSO_DISABLED 1
#define SDL_THREAD_SYMBIAN 1
#define SDL_VIDEO_DRIVER_EPOC 1
#define SDL_VIDEO_OPENGL 0
#define SDL_HAS_64BIT_TYPE 1
#define HAVE_LIBC 1
#define HAVE_STDIO_H 1
#define STDC_HEADERS 1
#define HAVE_STRING_H 1
#define HAVE_CTYPE_H 1
#define HAVE_MATH_H 1
#define HAVE_MALLOC 1
#define HAVE_CALLOC 1
#define HAVE_REALLOC 1
#define HAVE_FREE 1
//#define HAVE_ALLOCA 1
#define HAVE_QSORT 1
#define HAVE_ABS 1
#define HAVE_MEMSET 1
#define HAVE_MEMCPY 1
#define HAVE_MEMMOVE 1
#define HAVE_MEMCMP 1
#define HAVE_STRLEN 1
#define HAVE__STRUPR 1
#define HAVE_STRCHR 1
#define HAVE_STRRCHR 1
#define HAVE_STRSTR 1
#define HAVE_ITOA 1
#define HAVE_STRTOL 1
#define HAVE_STRTOUL 1
#define HAVE_STRTOLL 1
#define HAVE_STRTOD 1
#define HAVE_ATOI 1
#define HAVE_ATOF 1
#define HAVE_STRCMP 1
#define HAVE_STRNCMP 1
#define HAVE__STRICMP 1
#define HAVE__STRNICMP 1
#define HAVE_SSCANF 1
#define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1
#endif /* _SDL_CONFIG_SYMBIAN_H */

View file

@ -91,7 +91,9 @@ typedef uint32_t Uint32;
#ifdef SDL_HAS_64BIT_TYPE
typedef int64_t Sint64;
#ifndef SYMBIAN32_GCCE
typedef uint64_t Uint64;
#endif
#else
/* This is really just a hack to prevent the compiler from complaining */
typedef struct {

View file

@ -45,7 +45,7 @@ struct SDL_Thread;
typedef struct SDL_Thread SDL_Thread;
/* Create a thread */
#if (defined(__WIN32__) && !defined(HAVE_LIBC)) || defined(__OS2__)
#if ((defined(__WIN32__) && !defined(HAVE_LIBC)) || defined(__OS2__)) && !defined(__SYMBIAN32__)
/*
We compile SDL into a DLL on OS/2. This means, that it's the DLL which
creates a new thread for the calling process with the SDL_CreateThread()

View file

@ -83,11 +83,15 @@
#endif
#endif /* SDLCALL */
/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */
#ifdef __SYMBIAN32__
#ifndef EKA2
#undef DECLSPEC
#define DECLSPEC
#endif /* __SYMBIAN32__ */
#elif !defined(__WINS__)
#undef DECLSPEC
#define DECLSPEC __declspec(dllexport)
#endif //EKA2
#endif //__SYMBIAN32__
/* Force structure packing at 4 byte alignment.
This is necessary if the header is included in code which has structure
@ -116,7 +120,7 @@
#if defined(_MSC_VER) || defined(__BORLANDC__) || \
defined(__DMC__) || defined(__SC__) || \
defined(__WATCOMC__) || defined(__LCC__) || \
defined(__DECC)
defined(__DECC) || defined(__EABI__)
#ifndef __inline__
#define __inline__ __inline
#endif

View file

@ -323,7 +323,7 @@ unsigned _System LibMain(unsigned hmod, unsigned termination)
}
#endif /* __WATCOMC__ */
#elif defined(__WIN32__)
#elif defined(__WIN32__) && !defined(__SYMBIAN32__)
#if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL))
/* Need to include DllMain() on Watcom C for some reason.. */

View file

@ -106,6 +106,9 @@ static AudioBootStrap *bootstrap[] = {
#endif
#if SDL_AUDIO_DRIVER_DART
&DART_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_EPOCAUDIO
&EPOCAudio_bootstrap,
#endif
NULL
};
@ -545,7 +548,7 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
switch (audio->opened) {
case 1:
/* Start the audio thread */
#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) && !defined(__SYMBIAN32__)
#undef SDL_CreateThread
audio->thread = SDL_CreateThread(SDL_RunAudio, audio, NULL, NULL);
#else

View file

@ -171,6 +171,9 @@ extern AudioBootStrap MMEAUDIO_bootstrap;
#if SDL_AUDIO_DRIVER_DART
extern AudioBootStrap DART_bootstrap;
#endif
#if SDL_AUDIO_DRIVER_EPOCAUDIO
extern AudioBootStrap EPOCAudio_bootstrap;
#endif
/* This is the current audio device */
extern SDL_AudioDevice *current_audio;

View file

@ -0,0 +1,614 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
/*
SDL_epocaudio.cpp
Epoc based SDL audio driver implementation
Markus Mertama
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_epocaudio.c,v 0.0.0.0 2001/06/19 17:19:56 hercules Exp $";
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include "epoc_sdl.h"
#include <e32hal.h>
extern "C" {
#include "SDL_audio.h"
#include "SDL_error.h"
#include "SDL_audiomem.h"
#include "SDL_audio_c.h"
#include "SDL_timer.h"
#include "SDL_audiodev_c.h"
}
#include "SDL_epocaudio.h"
#include "streamplayer.h"
//#define DEBUG_AUDIO
/* Audio driver functions */
static int EPOC_OpenAudio(SDL_AudioDevice *thisdevice, SDL_AudioSpec *spec);
static void EPOC_WaitAudio(SDL_AudioDevice *thisdevice);
static void EPOC_PlayAudio(SDL_AudioDevice *thisdevice);
static Uint8 *EPOC_GetAudioBuf(SDL_AudioDevice *thisdevice);
static void EPOC_CloseAudio(SDL_AudioDevice *thisdevice);
static void EPOC_ThreadInit(SDL_AudioDevice *thisdevice);
static int Audio_Available(void);
static SDL_AudioDevice *Audio_CreateDevice(int devindex);
static void Audio_DeleteDevice(SDL_AudioDevice *device);
//void sos_adump(SDL_AudioDevice* thisdevice, void* data, int len);
#ifdef __WINS__
#define DODUMP
#endif
#ifdef DODUMP
NONSHARABLE_CLASS(TDump)
{
public:
TInt Open();
void Close();
void Dump(const TDesC8& aDes);
private:
RFile iFile;
RFs iFs;
};
TInt TDump::Open()
{
TInt err = iFs.Connect();
if(err == KErrNone)
{
#ifdef __WINS__
_LIT(target, "C:\\sdlau.raw");
#else
_LIT(target, "E:\\sdlau.raw");
#endif
err = iFile.Replace(iFs, target, EFileWrite);
}
return err;
}
void TDump::Close()
{
iFile.Close();
iFs.Close();
}
void TDump::Dump(const TDesC8& aDes)
{
iFile.Write(aDes);
}
#endif
NONSHARABLE_CLASS(CSimpleWait) : public CTimer
{
public:
void Wait(TTimeIntervalMicroSeconds32 aWait);
static CSimpleWait* NewL();
private:
CSimpleWait();
void RunL();
};
CSimpleWait* CSimpleWait::NewL()
{
CSimpleWait* wait = new (ELeave) CSimpleWait();
CleanupStack::PushL(wait);
wait->ConstructL();
CleanupStack::Pop();
return wait;
}
void CSimpleWait::Wait(TTimeIntervalMicroSeconds32 aWait)
{
After(aWait);
CActiveScheduler::Start();
}
CSimpleWait::CSimpleWait() : CTimer(CActive::EPriorityStandard)
{
CActiveScheduler::Add(this);
}
void CSimpleWait::RunL()
{
CActiveScheduler::Stop();
}
const TInt KAudioBuffers(2);
NONSHARABLE_CLASS(CEpocAudio) : public CBase, public MStreamObs, public MStreamProvider
{
public:
static void* NewL(TInt BufferSize, TInt aFill);
inline static CEpocAudio& Current(SDL_AudioDevice* thisdevice);
static void Free(SDL_AudioDevice* thisdevice);
void Wait();
void Play();
// void SetBuffer(const TDesC8& aBuffer);
void ThreadInitL(TAny* aDevice);
void Open(TInt iRate, TInt iChannels, TUint32 aType, TInt aBytes);
~CEpocAudio();
TUint8* Buffer();
TBool SetPause(TBool aPause);
#ifdef DODUMP
void Dump(const TDesC8& aBuf) {iDump.Dump(aBuf);}
#endif
private:
CEpocAudio(TInt aBufferSize);
void Complete(TInt aState, TInt aError);
TPtrC8 Data();
void ConstructL(TInt aFill);
private:
TInt iBufferSize;
CStreamPlayer* iPlayer;
TInt iBufferRate;
TInt iRate;
TInt iChannels;
TUint32 iType;
TInt iPosition;
TThreadId iTid;
TUint8* iAudioPtr;
TUint8* iBuffer;
// TTimeIntervalMicroSeconds iStart;
TTime iStart;
TInt iTune;
CSimpleWait* iWait;
#ifdef DODUMP
TDump iDump;
#endif
};
inline CEpocAudio& CEpocAudio::Current(SDL_AudioDevice* thisdevice)
{
return *static_cast<CEpocAudio*>((void*)thisdevice->hidden);
}
/*
TBool EndSc(TAny*)
{
CActiveScheduler::Stop();
}
LOCAL_C void CleanScL()
{
CIdle* d = CIdle::NewLC(CActive:::EPriorityIdle);
d->Start(TCallBack(EndSc));
CActiveScheduler::Start();
}
*/
void CEpocAudio::Free(SDL_AudioDevice* thisdevice)
{
CEpocAudio* ea = static_cast<CEpocAudio*>((void*)thisdevice->hidden);
if(ea)
{
ASSERT(ea->iTid == RThread().Id());
delete ea;
thisdevice->hidden = NULL;
CActiveScheduler* as = CActiveScheduler::Current();
ASSERT(as->StackDepth() == 0);
delete as;
CActiveScheduler::Install(NULL);
}
ASSERT(thisdevice->hidden == NULL);
}
CEpocAudio::CEpocAudio(TInt aBufferSize) : iBufferSize(aBufferSize), iPosition(-1)
{
}
void* CEpocAudio::NewL(TInt aBufferSize, TInt aFill)
{
CEpocAudio* eAudioLib = new (ELeave) CEpocAudio(aBufferSize);
CleanupStack::PushL(eAudioLib);
eAudioLib->ConstructL(aFill);
CleanupStack::Pop();
return eAudioLib;
}
void CEpocAudio::ConstructL(TInt aFill)
{
iBuffer = (TUint8*) User::AllocL(KAudioBuffers * iBufferSize);
memset(iBuffer, aFill, KAudioBuffers * iBufferSize);
iAudioPtr = iBuffer;
}
TBool CEpocAudio::SetPause(TBool aPause)
{
if(aPause && iPosition >= 0)
{
iPosition = -1;
if(iPlayer != NULL)
iPlayer->Stop();
}
if(!aPause && iPosition < 0)
{
iPosition = 0;
if(iPlayer != NULL)
iPlayer->Start();
}
return iPosition < 0;
}
void CEpocAudio::ThreadInitL(TAny* aDevice)
{
iTid = RThread().Id();
CActiveScheduler* as = new (ELeave) CActiveScheduler();
CActiveScheduler::Install(as);
EpocSdlEnv::AppendCleanupItem(TSdlCleanupItem((TSdlCleanupOperation)EPOC_CloseAudio, aDevice));
iWait = CSimpleWait::NewL();
iPlayer = new (ELeave) CStreamPlayer(*this, *this);
iPlayer->ConstructL();
iPlayer->OpenStream(iRate, iChannels, iType);
#ifdef DODUMP
User::LeaveIfError(iDump.Open());
#endif
}
TUint8* CEpocAudio::Buffer()
{
iStart.UniversalTime();
// iStart = iPlayer->Position();
return iAudioPtr;
}
CEpocAudio::~CEpocAudio()
{
if(iWait != NULL)
iWait->Cancel();
delete iWait;
if(iPlayer != NULL)
iPlayer->Close();
delete iPlayer;
delete iBuffer;
}
void CEpocAudio::Complete(TInt aState, TInt aError)
{
if(aState == MStreamObs::EClose)
{
}
if(iPlayer->Closed())
return;
switch(aError)
{
case KErrUnderflow:
case KErrInUse:
iPlayer->Start();
break;
case KErrAbort:
iPlayer->Open();
}
}
void sos_adump(SDL_AudioDevice* thisdevice, void* data, int len)
{
#ifdef DODUMP
const TPtrC8 buf((TUint8*)data, len);
CEpocAudio::Current(thisdevice).Dump(buf);
#endif
}
const TInt KClip(256);
TPtrC8 CEpocAudio::Data()
{
if(iPosition < 0)
return KNullDesC8();
TPtrC8 data(iAudioPtr + iPosition, KClip);
#ifdef DODUMP
iDump.Dump(data);
#endif
iPosition += KClip;
if(iPosition >= iBufferSize)
{
/* if(iAudioPtr == iBuffer)
iAudioPtr = iBuffer + iBufferSize;
else
iAudioPtr = iBuffer;
*/
iAudioPtr += iBufferSize;
if((iAudioPtr - iBuffer) >= KAudioBuffers * iBufferSize)
iAudioPtr = iBuffer;
iPosition = -1;
if(iWait->IsActive())
{
iWait->Cancel();
CActiveScheduler::Stop();
}
}
return data;
}
void CEpocAudio::Play()
{
iPosition = 0;
}
void CEpocAudio::Wait()
{
if(iPosition >= 0 /*&& iPlayer->Playing()*/)
{
const TInt64 bufMs = TInt64(iBufferSize - KClip) * TInt64(1000000);
const TInt64 specTime = bufMs / TInt64(iRate * iChannels * 2);
iWait->After(specTime);
CActiveScheduler::Start();
TTime end;
end.UniversalTime();
const TTimeIntervalMicroSeconds delta = end.MicroSecondsFrom(iStart);
// const TTimeIntervalMicroSeconds end = iPlayer->Position();
const TInt diff = specTime - delta.Int64();
if(diff > 0 && diff < 200000)
{
User::After(diff);
}
}
else
{
User::After(10000);
// iWait->Wait(10000); //just give some time...
}
}
void CEpocAudio::Open(TInt aRate, TInt aChannels, TUint32 aType, TInt aBytes)
{
iRate = aRate;
iChannels = aChannels;
iType = aType;
iBufferRate = iRate * iChannels * aBytes; //1/x
}
/* Audio driver bootstrap functions */
AudioBootStrap EPOCAudio_bootstrap = {
"epoc\0\0\0",
"EPOC streaming audio\0\0\0",
Audio_Available,
Audio_CreateDevice
};
static SDL_AudioDevice *Audio_CreateDevice(int /*devindex*/)
{
SDL_AudioDevice *thisdevice;
/* Initialize all variables that we clean on shutdown */
thisdevice = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
if ( thisdevice ) {
memset(thisdevice, 0, (sizeof *thisdevice));
thisdevice->hidden = NULL; /*(struct SDL_PrivateAudioData *)
malloc((sizeof thisdevice->hidden)); */
}
if ( (thisdevice == NULL) /*|| (thisdevice->hidden == NULL) */) {
SDL_OutOfMemory();
if ( thisdevice ) {
free(thisdevice);
}
return(0);
}
// memset(thisdevice->hidden, 0, (sizeof *thisdevice->hidden));
/* Set the function pointers */
thisdevice->OpenAudio = EPOC_OpenAudio;
thisdevice->WaitAudio = EPOC_WaitAudio;
thisdevice->PlayAudio = EPOC_PlayAudio;
thisdevice->GetAudioBuf = EPOC_GetAudioBuf;
thisdevice->CloseAudio = EPOC_CloseAudio;
thisdevice->ThreadInit = EPOC_ThreadInit;
thisdevice->free = Audio_DeleteDevice;
return thisdevice;
}
static void Audio_DeleteDevice(SDL_AudioDevice *device)
{
//free(device->hidden);
free(device);
}
static int Audio_Available(void)
{
return(1); // Audio stream modules should be always there!
}
static int EPOC_OpenAudio(SDL_AudioDevice *thisdevice, SDL_AudioSpec *spec)
{
SDL_TRACE("SDL:EPOC_OpenAudio");
TUint32 type = KMMFFourCCCodePCM16;
TInt bytes = 2;
switch(spec->format)
{
case AUDIO_U16LSB:
type = KMMFFourCCCodePCMU16;
break;
case AUDIO_S16LSB:
type = KMMFFourCCCodePCM16;
break;
case AUDIO_U16MSB:
type = KMMFFourCCCodePCMU16B;
break;
case AUDIO_S16MSB:
type = KMMFFourCCCodePCM16B;
break;
//8 bit not supported!
case AUDIO_U8:
case AUDIO_S8:
default:
spec->format = AUDIO_S16LSB;
};
if(spec->channels > 2)
spec->channels = 2;
spec->freq = CStreamPlayer::ClosestSupportedRate(spec->freq);
/* Allocate mixing buffer */
const TInt buflen = spec->size;// * bytes * spec->channels;
// audiobuf = NULL;
TRAPD(err, thisdevice->hidden = static_cast<SDL_PrivateAudioData*>(CEpocAudio::NewL(buflen, spec->silence)));
if(err != KErrNone)
return -1;
CEpocAudio::Current(thisdevice).Open(spec->freq, spec->channels, type, bytes);
CEpocAudio::Current(thisdevice).SetPause(ETrue);
// isSDLAudioPaused = 1;
thisdevice->enabled = 0; /* enable only after audio engine has been initialized!*/
/* We're ready to rock and roll. :-) */
return(0);
}
static void EPOC_CloseAudio(SDL_AudioDevice* thisdevice)
{
#ifdef DEBUG_AUDIO
SDL_TRACE("Close audio\n");
#endif
CEpocAudio::Free(thisdevice);
}
static void EPOC_ThreadInit(SDL_AudioDevice *thisdevice)
{
SDL_TRACE("SDL:EPOC_ThreadInit");
CEpocAudio::Current(thisdevice).ThreadInitL(thisdevice);
RThread().SetPriority(EPriorityMore);
thisdevice->enabled = 1;
}
/* This function waits until it is possible to write a full sound buffer */
static void EPOC_WaitAudio(SDL_AudioDevice* thisdevice)
{
#ifdef DEBUG_AUDIO
SDL_TRACE1("wait %d audio\n", CEpocAudio::AudioLib().StreamPlayer(KSfxChannel).SyncTime());
TInt tics = User::TickCount();
#endif
CEpocAudio::Current(thisdevice).Wait();
#ifdef DEBUG_AUDIO
TInt ntics = User::TickCount() - tics;
SDL_TRACE1("audio waited %d\n", ntics);
SDL_TRACE1("audio at %d\n", tics);
#endif
}
static void EPOC_PlayAudio(SDL_AudioDevice* thisdevice)
{
if(CEpocAudio::Current(thisdevice).SetPause(SDL_GetAudioStatus() == SDL_AUDIO_PAUSED))
SDL_Delay(500); //hold on the busy loop
else
CEpocAudio::Current(thisdevice).Play();
#ifdef DEBUG_AUDIO
SDL_TRACE("buffer has audio data\n");
#endif
#ifdef DEBUG_AUDIO
SDL_TRACE1("Wrote %d bytes of audio data\n", buflen);
#endif
}
static Uint8 *EPOC_GetAudioBuf(SDL_AudioDevice* thisdevice)
{
return CEpocAudio::Current(thisdevice).Buffer();
}

View file

@ -0,0 +1,37 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_epocaudio.h,v 1.1.2.2 2001/02/10 07:20:03 hercules Exp $";
#endif
#ifndef _SDL_EPOCAUDIO_H
#define _SDL_EPOCAUDIO_H
extern "C" {
#include "SDL_sysaudio.h"
}
#endif /* _SDL_EPOCAUDIO_H */

View file

@ -0,0 +1,279 @@
#include "streamplayer.h"
#include<mda/common/audio.h>
const TInt KMaxVolume(256);
LOCAL_C TInt GetSampleRate(TInt aRate)
{
switch(aRate)
{
case 8000: return TMdaAudioDataSettings::ESampleRate8000Hz;
case 11025: return TMdaAudioDataSettings::ESampleRate11025Hz;
case 12000: return TMdaAudioDataSettings::ESampleRate12000Hz;
case 16000: return TMdaAudioDataSettings::ESampleRate16000Hz;
case 22050: return TMdaAudioDataSettings::ESampleRate22050Hz;
case 24000: return TMdaAudioDataSettings::ESampleRate24000Hz;
case 32000: return TMdaAudioDataSettings::ESampleRate32000Hz;
case 44100: return TMdaAudioDataSettings::ESampleRate44100Hz;
case 48000: return TMdaAudioDataSettings::ESampleRate48000Hz;
case 96000: return TMdaAudioDataSettings::ESampleRate96000Hz;
case 64000: return TMdaAudioDataSettings::ESampleRate64000Hz;
}
return KErrNotFound;
}
LOCAL_C TInt GetChannels(TInt aChannels)
{
switch(aChannels)
{
case 1: return TMdaAudioDataSettings::EChannelsMono;
case 2: return TMdaAudioDataSettings::EChannelsStereo;
}
return KErrNotFound;
}
TInt CStreamPlayer::ClosestSupportedRate(TInt aRate)
{
if(aRate > 96000)
return 96000;
TInt rate = aRate;
while(GetSampleRate(rate) == KErrNotFound)
{
++rate;
}
return rate;
}
CStreamPlayer::CStreamPlayer(MStreamProvider& aProvider, MStreamObs& aObs) :
iProvider(aProvider), iObs(aObs), iVolume(KMaxVolume)
{
}
CStreamPlayer::~CStreamPlayer()
{
iState |= EDied;
if(iState & EInited)
Close();
User::After(100000); //wait buffer to be flushed
ASSERT(iPtr.Length() == 0);
delete iStream;
}
void CStreamPlayer::ConstructL()
{
iStream = CMdaAudioOutputStream::NewL(*this, EMdaPriorityMax);
iSilence.SetMax();
iSilence.FillZ();
}
TInt CStreamPlayer::OpenStream(TInt aRate, TInt aChannels, TUint32 aType)
{
Close();
iType = aType;
iRate = GetSampleRate(aRate);
if(iRate == KErrNotFound)
return KErrNotSupported;
iChannels = GetChannels(aChannels);
if(iChannels == KErrNotFound)
return KErrNotSupported;
Open();
return KErrNone;
}
TInt CStreamPlayer::MaxVolume() const
{
return KMaxVolume;
}
void CStreamPlayer::SetVolume(TInt aNew)
{
const TInt maxi = MaxVolume();
if(aNew > maxi)
return;
if(aNew < 0)
return;
iVolume = aNew;
iState |= EVolumeChange;
}
TInt CStreamPlayer::Volume() const
{
return iVolume;
}
void CStreamPlayer::Open()
{
TMdaAudioDataSettings audioSettings;
audioSettings.Query();
audioSettings.iCaps = TMdaAudioDataSettings::ERealTime |
TMdaAudioDataSettings::ESampleRateFixed;
audioSettings.iSampleRate = iRate;
audioSettings.iChannels = iChannels;
audioSettings.iFlags = TMdaAudioDataSettings::ENoNetworkRouting;
audioSettings.iVolume = 0;
iState &= ~EStopped;
iStream->Open(&audioSettings);
}
void CStreamPlayer::Stop()
{
if(iState & (EStarted | EInited))
{
Close();
iState |= EStopped;
}
}
void CStreamPlayer::Start()
{
if(iPtr.Length() == 0)
{
iState |= EStarted;
if(iState & EInited)
{
Request();
}
else if(iState & EStopped)
{
Open();
}
}
}
void CStreamPlayer::Close()
{
iState &= ~EInited;
iStream->Stop();
iState &= ~EStarted;
}
void CStreamPlayer::Request()
{
if(iState & EInited)
{
iPtr.Set(KNullDesC8);
if(iState & EVolumeChange)
{
const TReal newVol = iVolume;
const TReal newMax = MaxVolume();
const TInt maxVol = iStream->MaxVolume();
const TReal max = static_cast<TReal>(maxVol);
const TReal newvolume = (newVol * max) / newMax;
const TInt vol = static_cast<TReal>(newvolume);
iStream->SetVolume(vol);
iState &= ~EVolumeChange;
}
if(iState & EStarted)
{
iPtr.Set(iProvider.Data());
}
if(iPtr.Length() == 0)
{
iPtr.Set(iSilence);
}
TRAPD(err, iStream->WriteL(iPtr));
if(err != KErrNone)
{
iObs.Complete(MStreamObs::EWrite, err);
}
/* else
{
iProvider.Written(iPtr.Length());
}*/
}
}
void CStreamPlayer::SetCapsL()
{
iStream->SetDataTypeL(iType);
iStream->SetAudioPropertiesL(iRate, iChannels);
}
void CStreamPlayer::MaoscOpenComplete(TInt aError)
{
if(aError == KErrNone)
{
TRAPD(err, SetCapsL());
if(err == KErrNone)
{
iStream->SetPriority(EPriorityNormal, EMdaPriorityPreferenceTime);
iState |= EInited;
SetVolume(Volume());
if(iState & EStarted)
{
Request();
}
}
aError = err;
}
if(!(iState & EDied))
iObs.Complete(MStreamObs::EInit, aError);
}
void CStreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/)
{
iPtr.Set(KNullDesC8);
if(aError == KErrNone)
{
if(iState & EInited)
Request();
else
iStream->Stop();
}
else if(!(iState & EDied))
iObs.Complete(MStreamObs::EPlay, aError);
}
void CStreamPlayer::MaoscPlayComplete(TInt aError)
{
iPtr.Set(KNullDesC8);
iState &= ~EStarted;
if(!(iState & EDied))
iObs.Complete(MStreamObs::EClose, aError);
}
TBool CStreamPlayer::Playing() const
{
return (iState & EInited) && (iState & EStarted);
}
TBool CStreamPlayer::Closed() const
{
return !(iState & EInited) && !(iState & EDied);
}
/*
void CStreamPlayer::Request()
{
SetActive();
TRequestStatus* s = &iStatus;
User::RequestComplete(s, KErrNone);
}
// iTimer.After(0);
*/

View file

@ -0,0 +1,89 @@
#ifndef STREAMPLAYER_H
#define STREAMPLAYER_H
#include<MdaAudioOutputStream.h>
const TInt KSilenceBuffer = 256;
class MStreamObs
{
public:
enum
{
EInit,
EPlay,
EWrite,
EClose,
};
virtual void Complete(TInt aState, TInt aError) = 0;
};
class MStreamProvider
{
public:
virtual TPtrC8 Data() = 0;
};
NONSHARABLE_CLASS(CStreamPlayer) : public CBase, public MMdaAudioOutputStreamCallback
{
public:
CStreamPlayer(MStreamProvider& aProvider, MStreamObs& aObs);
~CStreamPlayer();
void ConstructL();
static TInt ClosestSupportedRate(TInt aRate);
TInt OpenStream(TInt aRate, TInt aChannels, TUint32 aType = KMMFFourCCCodePCM16);
void SetVolume(TInt aNew);
TInt Volume() const;
TInt MaxVolume() const;
void Stop();
void Start();
void Open();
void Close();
TBool Playing() const;
TBool Closed() const;
private:
void MaoscOpenComplete(TInt aError) ;
void MaoscBufferCopied(TInt aError, const TDesC8& aBuffer);
void MaoscPlayComplete(TInt aError);
private:
void Request();
void SetCapsL();
private:
MStreamProvider& iProvider;
MStreamObs& iObs;
TInt iVolume;
CMdaAudioOutputStream* iStream;
TInt iRate;
TInt iChannels;
TUint32 iType;
enum
{
ENone = 0,
EInited = 0x1,
EStarted = 0x2,
EStopped = 0x4,
EVolumeChange = 0x8,
EDied = 0x10
};
TInt iState;
TBuf8<KSilenceBuffer> iSilence;
TPtrC8 iPtr;
};
#endif

View file

@ -169,7 +169,7 @@ static int SDL_StartEventThread(Uint32 flags)
/* The event thread will handle timers too */
SDL_SetTimerThreaded(2);
#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) && !defined(__SYMBIAN32__)
#undef SDL_CreateThread
SDL_EventThread = SDL_CreateThread(SDL_GobbleEvents, NULL, NULL, NULL);
#else

View file

@ -29,7 +29,7 @@
#include "SDL_rwops.h"
#if defined(__WIN32__)
#if defined(__WIN32__) && !defined(__SYMBIAN32__)
/* Functions to read/write Win32 API file pointers */
/* Will not use it on WinCE because stdio is buffered, it means
@ -372,7 +372,7 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode)
return NULL;
}
#if defined(__WIN32__)
#if defined(__WIN32__) && !defined(__SYMBIAN32__)
rwops = SDL_AllocRW();
if (!rwops)
return NULL; /* SDL_SetError already setup by SDL_AllocRW() */

View file

@ -0,0 +1,152 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
/*
SDL_main.cpp
The Epoc executable startup functions
Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
*/
#include <e32std.h>
#include <e32def.h>
#include <e32svr.h>
#include <e32base.h>
#include <estlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <w32std.h>
#include <apgtask.h>
#include "SDL_error.h"
#if defined(__WINS__)
#include <estw32.h>
IMPORT_C void RegisterWsExe(const TDesC &aName);
#endif
/* The prototype for the application's main() function */
#define main SDL_main
extern "C" int main (int argc, char *argv[], char *envp[]);
extern "C" void exit (int ret);
/* Epoc main function */
#ifdef __WINS__
void GetCmdLine(int& aArgc, char**& aArgv)
{
RChunk chunk;
if(chunk.OpenGlobal(RThread().Name(), ETrue) != KErrNone)
return;
TUint* ptr = (TUint*) chunk.Base();
if(ptr != NULL)
{
aArgc = (int) *(ptr); // count
aArgv = (char**) *(ptr + 1);
}
chunk.Close();
}
#endif
TInt E32Main()
{
/* Get the clean-up stack */
CTrapCleanup* cleanup = CTrapCleanup::New();
/* Arrange for multi-threaded operation */
SpawnPosixServerThread();
/* Get args and environment */
int argc=0;
char** argv=0;
char** envp=0;
#ifndef __WINS__
__crt0(argc,argv,envp);
#else
GetCmdLine(argc, argv);
#endif
/* Start the application! */
/* Create stdlib */
_REENT;
/* Set process and thread priority and name */
RThread currentThread;
RProcess thisProcess;
TParse exeName;
exeName.Set(thisProcess.FileName(), NULL, NULL);
currentThread.Rename(exeName.Name());
currentThread.SetProcessPriority(EPriorityLow);
currentThread.SetPriority(EPriorityMuchLess);
/* Call stdlib main */
int ret = main(argc, argv, envp); /* !! process exits here if there is "exit()" in main! */
/* Call exit */
//exit(ret); /* !! process exits here! */
//Markus: I do not understand above
//I commented it at let this function
//to return ret value - was it purpose
//that cleanup below is not called at all - why?
/* Free resources and return */
_cleanup(); //this is normally called at exit, I call it here, Markus
CloseSTDLIB();
delete cleanup;
#ifdef __WINS__
// User::Panic(_L("exit"), ret);
// RThread().Kill(ret); //Markus get rid of this thread
// RThread().RaiseException(EExcKill);
#endif
return ret;//Markus, or exit(ret); ??
//return(KErrNone);
}
#ifdef __WINS__
EXPORT_C TInt WinsMain()
{
return E32Main();
// return WinsMain(0, 0, 0);
}
#endif
/* Epoc dll entry point */
#if defined(__WINS__)
GLDEF_C TInt E32Dll(TDllReason)
{
return(KErrNone);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,809 @@
// INCLUDES
#include <aknapp.h>
#include <aknappui.h>
#include <eikdoc.h>
#include <sdlepocapi.h>
#include <bautils.h>
#include <eikstart.h>
#include <badesca.h>
#include <bautils.h>
#include <apgcli.h>
#include <sdlmain.h>
#include <eikedwin.h>
#include <eiklabel.h>
#include <sdlexe.rsg>
#include <aknglobalmsgquery.h>
#include <apgwgnam.h>
// FORWARD DECLARATIONS
class CApaDocument;
//const TUid KSDLUID = { 0xF01F605E };
LOCAL_C void MakeCCmdLineL(const TDesC8& aParam, CDesC8Array& aArray)
{
const TChar dq('\"');
TLex8 lex(aParam);
TBool in = EFalse;
lex.SkipSpaceAndMark();
while(!lex.Eos())
{
TPtrC8 ptr;
if(in)
{
const TPtrC8 rem = lex.RemainderFromMark();
const TInt pos = rem.Locate(dq);
if(pos > 0)
{
lex.Inc(pos);
ptr.Set(lex.MarkedToken());
lex.SkipAndMark(1);
}
else
{
ptr.Set(rem);
}
in = EFalse;
}
else
{
ptr.Set(lex.NextToken());
const TInt pos = ptr.Locate(dq);
if(pos == 0)
{
lex.UnGetToMark();
lex.SkipAndMark(1);
in = ETrue;
continue; // back to in brace
}
else
lex.SkipSpaceAndMark();
}
aArray.AppendL(ptr);
}
}
NONSHARABLE_CLASS(TVirtualCursor) : public MOverlay
{
public:
TVirtualCursor();
void Set(const TRect& aRect, CFbsBitmap* aBmp, CFbsBitmap* aAlpha);
void Move(TInt aX, TInt aY);
void MakeEvent(TWsEvent& aEvent, const TPoint& aBasePos) const;
void Toggle();
TBool IsOn() const;
private:
void Draw(CBitmapContext& aGc, const TRect& aTargetRect, const TSize& aSize);
private:
TRect iRect;
TPoint iInc;
TPoint iPos;
TBool iIsOn;
CFbsBitmap* iCBmp;
CFbsBitmap* iAlpha;
};
TVirtualCursor::TVirtualCursor() : iInc(0, 0), iIsOn(EFalse), iCBmp(NULL)
{
}
const TInt KMaxMove = 10;
void TVirtualCursor::Move(TInt aX, TInt aY)
{
if(aX > 0 && iInc.iX > 0)
++iInc.iX;
else if(aX < 0 && iInc.iX < 0)
--iInc.iX;
else
iInc.iX = aX;
if(aY > 0 && iInc.iY > 0)
++iInc.iY;
else if(aY < 0 && iInc.iY < 0)
--iInc.iY;
else
iInc.iY = aY;
iInc.iX = Min(KMaxMove, iInc.iX);
iInc.iX = Max(-KMaxMove, iInc.iX);
iInc.iY = Min(KMaxMove, iInc.iY);
iInc.iY =Max(-KMaxMove, iInc.iY);
const TPoint pos = iPos + iInc;
if(iRect.Contains(pos))
{
iPos = pos;
}
else
{
iInc = TPoint(0, 0);
}
}
void TVirtualCursor::Toggle()
{
iIsOn = !iIsOn;
}
TBool TVirtualCursor::IsOn() const
{
return iIsOn;
}
void TVirtualCursor::Set(const TRect& aRect, CFbsBitmap* aBmp, CFbsBitmap* aAlpha)
{
iRect = aRect;
iCBmp = aBmp;
iAlpha = aAlpha;
}
void TVirtualCursor::MakeEvent(TWsEvent& aEvent, const TPoint& aBasePos) const
{
aEvent.SetType(EEventPointer),
aEvent.SetTimeNow();
TPointerEvent& pointer = *aEvent.Pointer();
pointer.iType = TPointerEvent::EButton1Down;
pointer.iPosition = iPos;
pointer.iParentPosition = aBasePos;
}
void TVirtualCursor::Draw(CBitmapContext& aGc, const TRect& /*aTargetRect*/, const TSize& /*aSize*/)
{
if(iIsOn && iCBmp != NULL)
{
const TRect rect(TPoint(0, 0), iCBmp->SizeInPixels());
aGc.AlphaBlendBitmaps(iPos, iCBmp, rect, iAlpha, TPoint(0, 0));
}
}
NONSHARABLE_CLASS(TSdlClass)
{
public:
TSdlClass();
void SetMain(const TMainFunc& aFunc, TInt aFlags, MSDLMainObs* aObs, TInt aExeFlags);
TInt SdlFlags() const;
const TMainFunc& Main() const;
void SendEvent(TInt aEvent, TInt aParam, CSDL* aSDL);
TInt AppFlags() const;
void AppFlags(TInt aFlags);
private:
TMainFunc iFunc;
TInt iSdlFlags;
TInt iExeFlags;
MSDLMainObs* iObs;
};
void TSdlClass::AppFlags(TInt aFlags)
{
iExeFlags |= aFlags;
}
void TSdlClass::SendEvent(TInt aEvent, TInt aParam, CSDL* aSDL)
{
if(iObs != NULL)
iObs->SDLMainEvent(aEvent, aParam, aSDL);
}
TInt TSdlClass::AppFlags() const
{
return iExeFlags;
}
void TSdlClass::SetMain(const TMainFunc& aFunc, TInt aFlags, MSDLMainObs* aObs, TInt aExeFlags)
{
iFunc = aFunc;
iSdlFlags = aFlags;
iExeFlags = aExeFlags;
iObs = aObs;
}
const TMainFunc& TSdlClass::Main() const
{
return iFunc;
}
TInt TSdlClass::SdlFlags() const
{
return iSdlFlags;
}
TSdlClass::TSdlClass()
{
Mem::FillZ(this, sizeof(this));
}
TSdlClass gSDLClass;
////////////////////////////////////////////////////////////////
NONSHARABLE_CLASS(CSDLApplication) : public CAknApplication
{
public:
CSDLApplication();
private:
CApaDocument* CreateDocumentL();
TFileName ResourceFileName() const;
TUid AppDllUid() const;
void FindMeL();
TUid iUid;
};
NONSHARABLE_CLASS(CSDLDocument) : public CEikDocument
{
public:
CSDLDocument(CEikApplication& aApp);
private:
CEikAppUi* CreateAppUiL();
};
////////////////////////////////////////////////////////////////////
NONSHARABLE_CLASS(MExitWait)
{
public:
virtual void DoExit(TInt aErr) = 0;
};
/////////////////////////////////////////////////////////////////////////
NONSHARABLE_CLASS(CExitWait) : public CActive
{
public:
CExitWait(MExitWait& aWait);
~CExitWait();
private:
void RunL();
void DoCancel();
private:
MExitWait& iWait;
TRequestStatus* iStatusPtr;
};
////////////////////////////////////////////////////////////////////////
NONSHARABLE_CLASS(CSDLWin) : public CCoeControl
{
public:
void ConstructL(const TRect& aRect);
RWindow& GetWindow() const;
void SetNoDraw();
private:
void Draw(const TRect& aRect) const;
private:
TBool iNoDraw;
};
////////////////////////////////////////////////////////////////////////////
NONSHARABLE_CLASS(CSDLAppUi) : public CAknAppUi, public MExitWait, MSDLObserver
{
public:
~CSDLAppUi();
private: // New functions
void ConstructL();
void HandleCommandL(TInt aCommand);
void HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination);
void HandleResourceChangeL(TInt aType);
void DoExit(TInt aErr);
TInt SdlEvent(TInt aEvent, TInt aParam);
TInt SdlThreadEvent(TInt aEvent, TInt aParam);
void StartL();
static TBool StartL(TAny* aThis);
TBool ParamEditorL(TDes& aCheat);
TBool ProcessCommandParametersL(CApaCommandLine &aCommandLine);
void PrepareToExit();
void HandleConsoleWindowL();
void HandleConsoleWindow();
void HandleForegroundEventL(TBool aForeground);
static TBool IdleRequestL(TAny* aThis);
TBool HandleKeyL(const TWsEvent& aEvent);
private:
CExitWait* iWait;
CSDLWin* iSDLWin;
CSDL* iSdl;
CIdle* iStarter;
TBool iExitRequest;
CDesC8Array* iParams;
TInt iResOffset;
CIdle* iIdle;
TInt iStdOut;
TVirtualCursor iCursor;
CFbsBitmap* iCBmp;
CFbsBitmap* iAlpha;
// TTime iLastPress;
// CSDL::TOrientationMode iOrientation;
};
////////////////////////////////////////////////////////////////////////////////////////7
CApaDocument* CSDLApplication::CreateDocumentL()
{
return new (ELeave) CSDLDocument(*this);
}
TUid CSDLApplication::AppDllUid() const
{
return iUid;
}
CSDLApplication::CSDLApplication()
{
TRAPD(err, FindMeL());
ASSERT(err == KErrNone);
}
void CSDLApplication::FindMeL()
{
RApaLsSession apa;
User::LeaveIfError(apa.Connect());
CleanupClosePushL(apa);
User::LeaveIfError(apa.GetAllApps());
TFileName name = RProcess().FileName();
TApaAppInfo info;
while(apa.GetNextApp(info) == KErrNone)
{
if(info.iFullName.CompareF(name) == 0)
{
iUid = info.iUid;
break;
}
}
CleanupStack::PopAndDestroy();
}
TFileName CSDLApplication::ResourceFileName() const
{
return KNullDesC();
}
///////////////////////////////////////////////////////////////////////////////////////////
CExitWait::CExitWait(MExitWait& aWait) : CActive(CActive::EPriorityStandard), iWait(aWait)
{
CActiveScheduler::Add(this);
SetActive();
iStatusPtr = &iStatus;
}
CExitWait::~CExitWait()
{
Cancel();
}
void CExitWait::RunL()
{
if(iStatusPtr != NULL )
iWait.DoExit(iStatus.Int());
}
void CExitWait::DoCancel()
{
if(iStatusPtr != NULL )
User::RequestComplete(iStatusPtr , KErrCancel);
}
//////////////////////////////////////////////////////////////////////////////////////////////
CSDLDocument::CSDLDocument(CEikApplication& aApp) : CEikDocument(aApp)
{}
CEikAppUi* CSDLDocument::CreateAppUiL()
{
return new (ELeave) CSDLAppUi;
}
///////////////////////////////////////////////////////////////////////////
void CSDLWin:: ConstructL(const TRect& aRect)
{
CreateWindowL();
SetRect(aRect);
ActivateL();
}
RWindow& CSDLWin::GetWindow() const
{
return Window();
}
void CSDLWin::Draw(const TRect& /*aRect*/) const
{
if(!iNoDraw)
{
CWindowGc& gc = SystemGc();
gc.SetPenStyle(CGraphicsContext::ESolidPen);
gc.SetPenColor(KRgbGray);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.SetBrushColor(0xaaaaaa);
gc.DrawRect(Rect());
}
}
void CSDLWin::SetNoDraw()
{
iNoDraw = ETrue;
}
/////////////////////////////////////////////////////////////////////////
CSDLAppUi::~CSDLAppUi()
{
if(iIdle)
iIdle->Cancel();
delete iIdle;
if(iStarter != NULL)
iStarter->Cancel();
delete iStarter;
delete iWait;
delete iSdl;
delete iSDLWin;
delete iParams;
delete iCBmp;
delete iAlpha;
}
void CSDLAppUi::ConstructL()
{
BaseConstructL(ENoAppResourceFile | ENoScreenFurniture);
RLibrary lib;
User::LeaveIfError(lib.Load(_L("sdlexe.dll")));
TFileName name = lib.FileName();
lib.Close();
name.Replace(3, name.Length() - 3, _L("resource\\apps\\sdlexe.rsc"));
BaflUtils::NearestLanguageFile(iEikonEnv->FsSession(), name);
iResOffset = iCoeEnv->AddResourceFileL(name);
name.Replace(name.Length() - 3, 3, _L("mbm"));
TEntry e;
const TInt err = iEikonEnv->FsSession().Entry(name, e);
iCBmp = iEikonEnv->CreateBitmapL(name, 0);
iAlpha = iEikonEnv->CreateBitmapL(name, 1);
iIdle = CIdle::NewL(CActive::EPriorityIdle);
iSDLWin = new (ELeave) CSDLWin;
iSDLWin->ConstructL(ApplicationRect());
iSdl = CSDL::NewL(gSDLClass.SdlFlags());
gSDLClass.SendEvent(MSDLMainObs::ESDLCreated, 0, iSdl);
iSdl->SetObserver(this);
iSdl->DisableKeyBlocking(*this);
iSdl->SetContainerWindowL(
iSDLWin->GetWindow(),
iEikonEnv->WsSession(),
*iEikonEnv->ScreenDevice());
iSdl->AppendOverlay(iCursor, 0);
iCursor.Set(TRect(TPoint(0, 0), iSDLWin->Size()), iCBmp, iAlpha);
iStarter = CIdle::NewL(CActive::EPriorityLow);
iStarter->Start(TCallBack(StartL, this));
}
TBool CSDLAppUi::StartL(TAny* aThis)
{
static_cast<CSDLAppUi*>(aThis)->StartL();
return EFalse;
}
void CSDLAppUi::PrepareToExit()
{
CAknAppUiBase::PrepareToExit(); //aknappu::PrepareToExit crashes
iCoeEnv->DeleteResourceFile(iResOffset);
}
TBool CSDLAppUi::ProcessCommandParametersL(CApaCommandLine &aCommandLine)
{
const TPtrC8 cmdLine = aCommandLine.TailEnd();
iParams = new (ELeave) CDesC8ArrayFlat(8);
MakeCCmdLineL(cmdLine, *iParams);
return EFalse;
}
TBool CSDLAppUi::ParamEditorL(TDes& aCheat)
{
CAknTextQueryDialog* query = CAknTextQueryDialog::NewL(aCheat);
CleanupStack::PushL(query);
query->SetPromptL(_L("Enter parameters"));
CleanupStack::Pop();
return query->ExecuteLD(R_PARAMEDITOR);
}
void CSDLAppUi::StartL()
{
if(gSDLClass.AppFlags() & SDLEnv::EParamQuery)
{
TBuf8<256> cmd;
RFile file;
TInt err = file.Open(iEikonEnv->FsSession(), _L("sdl_param.txt"),EFileRead);
if(err == KErrNone)
{
file.Read(cmd);
file.Close();
MakeCCmdLineL(cmd, *iParams);
}
if(err != KErrNone || gSDLClass.AppFlags() & (SDLEnv::EParamQueryDialog ^ SDLEnv::EParamQuery))
{
TBuf<256> buffer;
if(ParamEditorL(buffer))
{
cmd.Copy(buffer);
MakeCCmdLineL(cmd, *iParams);
}
}
}
iWait = new (ELeave) CExitWait(*this);
iSdl->CallMainL(gSDLClass.Main(), &iWait->iStatus, iParams, CSDL::ENoParamFlags, 0xA000);
}
void CSDLAppUi::HandleCommandL(TInt aCommand)
{
switch(aCommand)
{
case EAknSoftkeyBack:
case EAknSoftkeyExit:
case EAknCmdExit:
case EEikCmdExit:
gSDLClass.AppFlags(SDLEnv::EAllowConsoleView);
if(iWait == NULL || !iWait->IsActive() || iSdl == NULL)
{
Exit();
}
else if(!iExitRequest)
{
iExitRequest = ETrue; //trick how SDL can be closed!
iSdl->Suspend();
}
break;
}
}
TBool CSDLAppUi::HandleKeyL(const TWsEvent& aEvent)
{
const TInt type = aEvent.Type();
if(!(type == EEventKey || type == EEventKeyUp || type == EEventKeyDown))
{
return ETrue;
}
const TKeyEvent& key = *aEvent.Key();
if((key.iScanCode == EStdKeyYes) && (gSDLClass.AppFlags() & SDLEnv::EVirtualMouse))
{
if(type == EEventKeyUp)
{
iCursor.Toggle();
iSdl->RedrawRequest();
}
return EFalse;
}
if(iCursor.IsOn())
{
switch(key.iScanCode)
{
case EStdKeyUpArrow:
iCursor.Move(0, -1);
break;
case EStdKeyDownArrow:
iCursor.Move(0, 1);
break;
case EStdKeyLeftArrow:
iCursor.Move(-1, 0);
break;
case EStdKeyRightArrow:
iCursor.Move(1, 0);
break;
case EStdKeyDevice3:
if(type == EEventKeyUp)
{
TWsEvent event;
iCursor.MakeEvent(event, iSDLWin->Position());
iSdl->AppendWsEvent(event);
}
return EFalse;
default:
return ETrue;
}
iSdl->RedrawRequest();
return EFalse;
}
return ETrue;
}
void CSDLAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl* aDestination)
{
if(iSdl && iWait && HandleKeyL(aEvent))
iSdl->AppendWsEvent(aEvent);
CAknAppUi::HandleWsEventL(aEvent, aDestination);
}
void CSDLAppUi::HandleResourceChangeL(TInt aType)
{
CAknAppUi::HandleResourceChangeL(aType);
if(aType == KEikDynamicLayoutVariantSwitch)
{
iSDLWin->SetRect(ApplicationRect());
iSdl->SetContainerWindowL(
iSDLWin->GetWindow(),
iEikonEnv->WsSession(),
*iEikonEnv->ScreenDevice());
}
}
void CSDLAppUi::DoExit(TInt/*Err*/)
{
iExitRequest = ETrue;
Exit();
}
TInt CSDLAppUi::SdlThreadEvent(TInt aEvent, TInt /*aParam*/)
{
switch(aEvent)
{
case MSDLObserver::EEventResume:
break;
case MSDLObserver::EEventSuspend:
if(iExitRequest)
return MSDLObserver::ESuspendNoSuspend;
break;
case MSDLObserver::EEventWindowReserved:
break;
case MSDLObserver::EEventWindowNotAvailable:
break;
case MSDLObserver::EEventScreenSizeChanged:
break;
}
return MSDLObserver::EParameterNone;
}
TInt CSDLAppUi::SdlEvent(TInt aEvent, TInt /*aParam*/)
{
switch(aEvent)
{
case MSDLObserver::EEventResume:
break;
case MSDLObserver::EEventSuspend:
if(iExitRequest)
return MSDLObserver::ESuspendNoSuspend;
break;
case MSDLObserver::EEventWindowReserved:
break;
case MSDLObserver::EEventWindowNotAvailable:
{
TRAP_IGNORE(HandleConsoleWindowL());
}
break;
case MSDLObserver::EEventScreenSizeChanged:
break;
case MSDLObserver::EEventKeyMapInit:
break;
case MSDLObserver::EEventMainExit:
if(iStdOut != 0)
{
gSDLClass.AppFlags(SDLEnv::EAllowConsoleView);
iEikonEnv->WsSession().SetWindowGroupOrdinalPosition(iStdOut, 0);
}
break;
}
return MSDLObserver::EParameterNone;
}
void CSDLAppUi::HandleForegroundEventL(TBool aForeground)
{
CAknAppUi::HandleForegroundEventL(aForeground);
if(!aForeground)
HandleConsoleWindow();
}
void CSDLAppUi::HandleConsoleWindow()
{
if(!iIdle->IsActive())
iIdle->Start(TCallBack(IdleRequestL, this));
}
TBool CSDLAppUi::IdleRequestL(TAny* aThis)
{
static_cast<CSDLAppUi*>(aThis)->HandleConsoleWindowL();
return EFalse;
}
void CSDLAppUi::HandleConsoleWindowL()
{
if(gSDLClass.AppFlags() & SDLEnv::EAllowConsoleView)
{
return;
}
RWsSession& ses = iEikonEnv->WsSession();
const TInt focus = ses.GetFocusWindowGroup();
CApaWindowGroupName* name = CApaWindowGroupName::NewLC(ses, focus);
const TPtrC caption = name->Caption();
if(0 == caption.CompareF(_L("STDOUT")))
{
iStdOut = focus;
ses.SetWindowGroupOrdinalPosition(iEikonEnv->RootWin().Identifier(), 0);
}
CleanupStack::PopAndDestroy(); //name
}
////////////////////////////////////////////////////////////////////////
CApaApplication* NewApplication()
{
return new CSDLApplication();
}
EXPORT_C TInt SDLEnv::SetMain(const TMainFunc& aFunc, TInt aSdlFlags, MSDLMainObs* aObs, TInt aSdlExeFlags)
{
gSDLClass.SetMain(aFunc, aSdlFlags, aObs, aSdlExeFlags);
return EikStart::RunApplication(NewApplication);
}
//////////////////////////////////////////////////////////////////////
TInt SDLUiPrint(const TDesC8& /*aInfo*/)
{
return KErrNotFound;
}

View file

@ -0,0 +1,12 @@
#include<eikstart.h>
#include<sdlmain.h>
#include<sdlepocapi.h>
GLREF_C TInt E32Main()
{
return SDLEnv::SetMain(SDL_main, CSDL::EEnableFocusStop | CSDL::EAllowImageResize,
NULL, SDLEnv::EParamQuery | SDLEnv::EVirtualMouse);
}

View file

@ -0,0 +1,62 @@
/*
vectorbuffer.cpp
yet another circle buffer
Markus Mertama
*/
#include"vectorbuffer.h"
void VectorPanic(TInt aErr, TInt aLine)
{
TBuf<64> b;
b.Format(_L("vector buffer at % d "), aLine);
User::Panic(b, aErr);
}
void TNodeBuffer::TNode::Terminator(TNodeBuffer::TNode* aNode)
{
Mem::Copy(iSucc, &aNode, sizeof(TNode*));
}
TInt TNodeBuffer::TNode::Size() const
{
return reinterpret_cast<const TUint8*>(iSucc) - Ptr();
}
const TUint8* TNodeBuffer::TNode::Ptr() const
{
return reinterpret_cast<const TUint8*>(this) + sizeof(TNode);
}
TNodeBuffer::TNode* TNodeBuffer::TNode::Empty(TUint8* aBuffer)
{
TNode* node = reinterpret_cast<TNode*>(aBuffer);
node->iSucc = node + 1;
return node;
}
TNodeBuffer::TNode* TNodeBuffer::TNode::New(TNode* aPred, const TDesC8& aData)
{
TNode* node = aPred->Size() == 0 ? aPred : aPred->iSucc;
TUint8* start = reinterpret_cast<TUint8*>(node) + sizeof(TNode);
node->iSucc = reinterpret_cast<TNode*>(start + aData.Size());
node->iSucc->iSucc = NULL; //terminator
__ASSERT_DEBUG(node->Size() == aData.Size(), VECPANIC(KErrCorrupt));
Mem::Copy(start, aData.Ptr(), aData.Size());
return node;
}

View file

@ -0,0 +1,240 @@
/*
vectorbuffer.cpp
yet another circle buffer
Markus Mertama
*/
#ifndef __VECTORBUFFER_H__
#define __VECTORBUFFER_H__
#include<e32std.h>
#define VLOG(x)
#define VECPANIC(x) VectorPanic(x, __LINE__)
void VectorPanic(TInt, TInt);
//int DEBUG_INT;
NONSHARABLE_CLASS(TNodeBuffer)
{
public:
protected:
NONSHARABLE_CLASS(TNode)
{
public:
static TNode* Empty(TUint8* iBuffer);
static TNode* New(TNode* aPrev, const TDesC8& aData);
const TUint8* Ptr() const;
TInt Size() const;
inline TNode* Succ();
static void SetSucc(TNode*& aNode);
void Terminator(TNode* aNode);
private:
TNode* iSucc;
};
};
inline TNodeBuffer::TNode* TNodeBuffer::TNode::Succ()
{
return iSucc;
}
template <TInt C>
NONSHARABLE_CLASS(TVectorBuffer) : public TNodeBuffer
{
public:
TVectorBuffer();
TInt Append(const TDesC8& aData);
// TInt AppendOverwrite(const TDesC8& aData);
TPtrC8 Shift();
TPtrC8 operator[](TInt aIndex) const;
TInt Size() const;
private:
TInt GetRoom(TInt aSize) const;
TInt Unreserved() const;
private:
TNode* iTop;
TNode* iBottom;
TInt iSize;
TUint8 iBuffer[C];
};
template <TInt C>
TVectorBuffer<C>::TVectorBuffer() : iSize(0)
{
Mem::FillZ(iBuffer, C);
iTop = TNode::Empty(iBuffer); //these points to buffer
iBottom = TNode::Empty(iBuffer);
}
template<TInt C >
TInt TVectorBuffer<C>::Unreserved() const
{
__ASSERT_DEBUG(iBottom < iBottom->Succ(), VECPANIC(KErrCorrupt));
const TInt bytesbetween =
reinterpret_cast<const TUint8*>(iBottom->Succ()) -
reinterpret_cast<const TUint8*>(iTop);
const TInt topsize = sizeof(TNode);
if(bytesbetween > 0) //bytesbetween is room between bottom and top
{ //therefore free room is subracted from free space
const TInt room = C - bytesbetween - topsize;
return room;
}
if(bytesbetween == 0)
{
if(Size() > 0)
return 0;
else
return C - topsize;
}
const TInt room = -bytesbetween - topsize; //free is space between pointers
return room;
}
template <TInt C>
TInt TVectorBuffer<C>::GetRoom(TInt aSize) const
{
const TInt bytesnew = sizeof(TNode) + aSize;
const TInt room = Unreserved() - bytesnew;
return room;
}
template <TInt C>
TInt TVectorBuffer<C>::Append(const TDesC8& aData) //ei ole ok!
{
const TInt len = aData.Length();
if(GetRoom(len) < 0)
{
return KErrOverflow;
}
if(iBottom->Succ()->Ptr() - iBuffer > (C - (len + TInt(sizeof(TNode)))))
{
VLOG("rc");
// RDebug::Print(_L("vector: append"));
TNode* p = TNode::Empty(iBuffer);
iBottom->Terminator(p);
iBottom = p;
return Append(aData);
// Append();
// iBottom = TNode::New(p, aData); //just append something into end
}
//DEBUG_INT++;
iBottom = TNode::New(iBottom, aData);
iSize += len;
return KErrNone;
}
/*
template <TInt C>
TInt TVectorBuffer<C>::AppendOverwrite(const TDesC8& aData) //ei ole ok!
{
while(Append(aData) == KErrOverflow)
{
if(iTop->Succ() == NULL)
{
return KErrUnderflow;
}
//Shift(); //data is lost
}
return KErrNone;
}
*/
template <TInt C>
TPtrC8 TVectorBuffer<C>::Shift()
{
__ASSERT_ALWAYS(iTop->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom
TNode* node = iTop;
iTop = iTop->Succ();
if(iTop > node)
{
// DEBUG_INT--;
iSize -= node->Size();
return TPtrC8(node->Ptr(), node->Size());
}
else
{
// RDebug::Print(_L("vector: shift"));
return Shift(); //this happens when buffer is terminated, and data lies in next
}
}
template <TInt C>
TInt TVectorBuffer<C>::Size() const
{
return iSize;
}
template <TInt C>
TPtrC8 TVectorBuffer<C>::operator[](TInt aIndex) const
{
TInt index = 0;
TNode* t = iTop->Size() > 0 ? iTop : iTop->Succ(); //eliminate terminator
while(index < aIndex)
{
TNode* nt = t->Succ();
if(nt < t)
{
nt = nt->Succ();
}
t = nt;
if(t->Size() > 0)
index++;
__ASSERT_ALWAYS(t->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom
}
return t->Ptr();
}
template <class T, TInt C>
NONSHARABLE_CLASS(TVector) : public TVectorBuffer<C * sizeof(T)>
{
public:
TVector();
TInt Append(const T& aData);
const T& Shift();
TInt Size() const;
const T& operator[](TInt aIndex) const;
};
template <class T, TInt C>
TVector<T, C>::TVector() : TVectorBuffer<C * sizeof(T)>()
{
}
template <class T, TInt C>
TInt TVector<T, C>::Append(const T& aData)
{
const TPckgC<T> data(aData);
return TVectorBuffer<C * sizeof(T)>::Append(data);
}
template <class T, TInt C>
const T& TVector<T, C>::Shift()
{
const TPtrC8 ptr = TVectorBuffer<C * sizeof(T)>::Shift();
return *(reinterpret_cast<const T*>(ptr.Ptr()));
}
template <class T, TInt C>
TInt TVector<T, C>::Size() const
{
return TVectorBuffer<C * sizeof(T)>::Size() / sizeof(T);
}
template <class T, TInt C>
const T& TVector<T, C>::operator[](TInt aIndex) const
{
const TPtrC8 ptr = TVectorBuffer<C * sizeof(T)>::operator[](aIndex);
return *(reinterpret_cast<const T*>(ptr.Ptr()));
}
#endif

View file

@ -25,7 +25,7 @@
#ifndef HAVE_GETENV
#if defined(__WIN32__) && !defined(_WIN32_WCE)
#if defined(__WIN32__) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

View file

@ -31,8 +31,6 @@
#include "beos/SDL_systhread_c.h"
#elif SDL_THREAD_DC
#include "dc/SDL_systhread_c.h"
#elif SDL_THREAD_EPOC
#include "epoc/SDL_systhread_c.h"
#elif SDL_THREAD_OS2
#include "os2/SDL_systhread_c.h"
#elif SDL_THREAD_PTH
@ -43,6 +41,8 @@
#include "irix/SDL_systhread_c.h"
#elif SDL_THREAD_WIN32
#include "win32/SDL_systhread_c.h"
#elif SDL_THREAD_SYMBIAN
#include "symbian/SDL_systhread_c.h"
#else
#error Need thread implementation for this platform
#include "generic/SDL_systhread_c.h"

View file

@ -0,0 +1,130 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
/*
SDL_sysmutex.cpp
Epoc version by Markus Mertama (w@iki.fi)
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_sysmutex.c,v 1.1.2.3 2000/06/22 15:25:23 hercules Exp $";
#endif
/* Mutex functions using the Win32 API */
//#include <stdio.h>
//#include <stdlib.h>
#include <e32std.h>
#include "epoc_sdl.h"
#include "SDL_error.h"
#include "SDL_mutex.h"
#ifdef EKA2 //???
struct SDL_mutex
{
TInt handle;
};
#else
struct _SDL_mutex
{
TInt handle;
};
#endif
extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
TInt NewMutex(const TDesC& aName, TAny* aPtr1, TAny*)
{
return ((RMutex*)aPtr1)->CreateGlobal(aName);
}
void DeleteMutex(TAny* aMutex)
{
SDL_DestroyMutex ((SDL_mutex*) aMutex);
}
/* Create a mutex */
SDL_mutex *SDL_CreateMutex(void)
{
RMutex rmutex;
TInt status = CreateUnique(NewMutex, &rmutex, NULL);
if(status != KErrNone)
{
SDL_SetError("Couldn't create mutex");
}
SDL_mutex* mutex = new /*(ELeave)*/ SDL_mutex;
mutex->handle = rmutex.Handle();
EpocSdlEnv::AppendCleanupItem(TSdlCleanupItem(DeleteMutex, mutex));
return(mutex);
}
/* Free the mutex */
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if ( mutex )
{
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
if(rmutex.IsHeld())
{
rmutex.Signal();
}
rmutex.Close();
EpocSdlEnv::RemoveCleanupItem(mutex);
delete(mutex);
mutex = NULL;
}
}
/* Lock the mutex */
int SDL_mutexP(SDL_mutex *mutex)
{
if ( mutex == NULL ) {
SDL_SetError("Passed a NULL mutex");
return -1;
}
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Wait();
return(0);
}
/* Unlock the mutex */
int SDL_mutexV(SDL_mutex *mutex)
{
if ( mutex == NULL ) {
SDL_SetError("Passed a NULL mutex");
return -1;
}
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Signal();
return(0);
}

View file

@ -0,0 +1,214 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
/*
SDL_syssem.cpp
Epoc version by Markus Mertama (w@iki.fi)
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_syssem.c,v 1.1.2.4 2000/06/22 15:24:48 hercules Exp $";
#endif
/* Semaphore functions using the Win32 API */
//#include <stdio.h>
//#include <stdlib.h>
#include <e32std.h>
#include "SDL_error.h"
#include "SDL_thread.h"
#define SDL_MUTEX_TIMEOUT -2
struct SDL_semaphore
{
TInt handle;
TInt count;
};
extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
#ifndef EKA2
extern TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2);
#endif
TInt NewSema(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
{
TInt value = *((TInt*) aPtr2);
return ((RSemaphore*)aPtr1)->CreateGlobal(aName, value);
}
/* Create a semaphore */
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
RSemaphore s;
TInt status = CreateUnique(NewSema, &s, &initial_value);
if(status != KErrNone)
{
SDL_SetError("Couldn't create semaphore");
}
SDL_semaphore* sem = new /*(ELeave)*/ SDL_semaphore;
sem->handle = s.Handle();
sem->count = initial_value;
return(sem);
}
/* Free the semaphore */
void SDL_DestroySemaphore(SDL_sem *sem)
{
if ( sem )
{
RSemaphore sema;
sema.SetHandle(sem->handle);
while(--sem->count)
sema.Signal();
sema.Close();
delete sem;
sem = NULL;
}
}
#ifndef EKA2
struct TInfo
{
TInfo(TInt aTime, TInt aHandle) :
iTime(aTime), iHandle(aHandle), iVal(0) {}
TInt iTime;
TInt iHandle;
TInt iVal;
};
TBool ThreadRun(TAny* aInfo)
{
TInfo* info = STATIC_CAST(TInfo*, aInfo);
User::After(info->iTime);
RSemaphore sema;
sema.SetHandle(info->iHandle);
sema.Signal();
info->iVal = SDL_MUTEX_TIMEOUT;
return 0;
}
#endif
void _WaitAll(SDL_sem *sem)
{
//since SemTryWait may changed the counter.
//this may not be atomic, but hopes it works.
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Wait();
while(sem->count < 0)
{
sema.Wait();
}
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
if ( ! sem ) {
SDL_SetError("Passed a NULL sem");
return -1;
}
if ( timeout == SDL_MUTEX_MAXWAIT )
{
_WaitAll(sem);
return SDL_MUTEX_MAXWAIT;
}
#ifdef EKA2
RSemaphore sema;
sema.SetHandle(sem->handle);
if(KErrNone == sema.Wait(timeout))
return 0;
return -1;
#else
RThread thread;
TInfo* info = new (ELeave)TInfo(timeout, sem->handle);
TInt status = CreateUnique(NewThread, &thread, info);
if(status != KErrNone)
return status;
thread.Resume();
_WaitAll(sem);
if(thread.ExitType() == EExitPending)
{
thread.Kill(SDL_MUTEX_TIMEOUT);
}
thread.Close();
return info->iVal;
#endif
}
int SDL_SemTryWait(SDL_sem *sem)
{
if(sem->count > 0)
{
sem->count--;
}
return SDL_MUTEX_TIMEOUT;
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
/* Returns the current count of the semaphore */
Uint32 SDL_SemValue(SDL_sem *sem)
{
if ( ! sem ) {
SDL_SetError("Passed a NULL sem");
return 0;
}
return sem->count;
}
int SDL_SemPost(SDL_sem *sem)
{
if ( ! sem ) {
SDL_SetError("Passed a NULL sem");
return -1;
}
sem->count++;
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Signal();
return 0;
}

View file

@ -0,0 +1,146 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
/*
SDL_systhread.cpp
Epoc thread management routines for SDL
Epoc version by Markus Mertama (w@iki.fi)
*/
#include "epoc_sdl.h"
//#include <stdlib.h>
//#include <stdio.h>
extern "C" {
#undef NULL
#include "SDL_error.h"
#include "SDL_thread.h"
#include "SDL_systhread.h"
#include "SDL_thread_c.h"
}
#include <e32std.h>
#include "epoc_sdl.h"
static int object_count;
int RunThread(TAny* data)
{
CTrapCleanup* cleanup = CTrapCleanup::New();
TRAPD(err, SDL_RunThread(data));
EpocSdlEnv::CleanupItems();
delete cleanup;
return(err);
}
TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
{
return ((RThread*)(aPtr1))->Create(aName,
RunThread,
KDefaultStackSize,
NULL,
aPtr2);
}
int CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny* aPtr1, TAny* aPtr2)
{
TBuf<16> name;
TInt status = KErrNone;
do
{
object_count++;
name.Format(_L("SDL_%x"), object_count);
status = aFunc(name, aPtr1, aPtr2);
}
while(status == KErrAlreadyExists);
return status;
}
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
RThread rthread;
const TInt status = CreateUnique(NewThread, &rthread, args);
if (status != KErrNone)
{
delete(((RThread*)(thread->handle)));
thread->handle = NULL;
SDL_SetError("Not enough resources to create thread");
return(-1);
}
rthread.Resume();
thread->handle = rthread.Handle();
return(0);
}
void SDL_SYS_SetupThread(void)
{
return;
}
Uint32 SDL_ThreadID(void)
{
RThread current;
const TThreadId id = current.Id();
return id;
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
SDL_TRACE1("Close thread", thread);
RThread t;
const TInt err = t.Open(thread->threadid);
if(err == KErrNone && t.ExitType() == EExitPending)
{
TRequestStatus status;
t.Logon(status);
User::WaitForRequest(status);
}
t.Close();
/* RUndertaker taker;
taker.Create();
TRequestStatus status;
taker.Logon(status, thread->handle);
User::WaitForRequest(status);
taker.Close();*/
SDL_TRACE1("Closed thread", thread);
}
/* WARNING: This function is really a last resort.
* Threads should be signaled and then exit by themselves.
* TerminateThread() doesn't perform stack and DLL cleanup.
*/
void SDL_SYS_KillThread(SDL_Thread *thread)
{
RThread rthread;
rthread.SetHandle(thread->handle);
rthread.Kill(0);
rthread.Close();
}

View file

@ -0,0 +1,30 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
/*
SDL_systhread_c.h
Epoc version by Markus Mertama (w@iki.fi)
*/
typedef int SYS_ThreadHandle;

View file

@ -0,0 +1,114 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
/*
SDL_systimer.cpp
Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
Markus Mertama
*/
#include <e32std.h>
#include <e32hal.h>
extern "C" {
#include "SDL_error.h"
#include "SDL_thread.h"
#include "SDL_timer.h"
#include "SDL_timer_c.h"
static TUint start = 0;
static TInt tickPeriodMilliSeconds;
void SDL_StartTicks(void)
{
/* Set first ticks value */
start = User::TickCount();
TTimeIntervalMicroSeconds32 period;
TInt tmp = UserHal::TickPeriod(period);
tickPeriodMilliSeconds = period.Int() / 1000;
}
Uint32 SDL_GetTicks(void)
{
TUint deltaTics = User::TickCount() - start;
return(deltaTics * tickPeriodMilliSeconds);
}
void SDL_Delay(Uint32 ms)
{
User::After(TTimeIntervalMicroSeconds32(ms*1000));
}
/* Data to handle a single periodic alarm */
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int RunTimer(void *unused)
{
while ( timer_alive )
{
if (SDL_timer_running)
{
SDL_ThreadedTimerCheck();
}
SDL_Delay(10);
}
return(0);
}
/* This is only called if the event thread is not running */
int SDL_SYS_TimerInit(void)
{
if(timer != NULL)
return (-1);
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if ( timer == NULL )
return(-1);
return(SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if ( timer )
{
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: Epoc uses threaded timer");
return(-1);
}
void SDL_SYS_StopTimer(void)
{
return;
}
} // extern "C"

View file

@ -0,0 +1,626 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
/*
SDL_epocevents.cpp
Handle the event stream, converting Epoc events into SDL events
Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
*/
#include <stdio.h>
#undef NULL
extern "C" {
//#define DEBUG_TRACE_ENABLED
#include "SDL_error.h"
#include "SDL_video.h"
#include "SDL_keysym.h"
#include "SDL_keyboard.h"
#include "SDL_events_c.h"
#include "SDL_timer.h"
}; /* extern "C" */
#include "SDL_epocvideo.h"
#include "SDL_epocevents_c.h"
#include<linereader.h>
#include<bautils.h>
#include <hal.h>
extern "C" {
/* The translation tables from a console scancode to a SDL keysym */
static SDLKey keymap[MAX_SCANCODE];
static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
void DisableKeyBlocking(_THIS);
}; /* extern "C" */
TBool isCursorVisible = EFalse;
int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
{
int posted = 0;
SDL_keysym keysym;
// SDL_TRACE1("hws %d", aWsEvent.Type());
switch (aWsEvent.Type())
{
case EEventPointer: /* Mouse pointer events */
{
const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode();
if(mode == EPointerCursorNone)
{
return 0; //TODO: Find out why events are get despite of cursor should be off
}
const TPointerEvent* pointerEvent = aWsEvent.Pointer();
TPoint mousePos = pointerEvent->iPosition;
/*!! TODO Pointer do not yet work properly
//SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
if (Private->EPOC_ShrinkedHeight) {
mousePos.iY <<= 1; // Scale y coordinate to shrinked screen height
}
if (Private->EPOC_ShrinkedWidth) {
mousePos.iX <<= 1; // Scale x coordinate to shrinked screen width
}
*/
posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
switch (pointerEvent->iType)
{
case TPointerEvent::EButton1Down:
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
break;
case TPointerEvent::EButton1Up:
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
break;
case TPointerEvent::EButton2Down:
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
break;
case TPointerEvent::EButton2Up:
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
break;
case TPointerEvent::EButton3Down:
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0);
break;
case TPointerEvent::EButton3Up:
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);
break;
} // switch
break;
}
case EEventKeyDown: /* Key events */
{
#ifdef SYMBIAN_CRYSTAL
// special case: 9300/9500 rocker down, simulate left mouse button
if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
{
const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode();
if(mode != EPointerCursorNone)
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
}
#endif
(void*)TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym);
#ifndef DISABLE_JOYSTICK
/* Special handling */
switch((int)keysym.sym) {
case SDLK_CAPSLOCK:
if (!isCursorVisible) {
/* Enable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
}
else {
/* Disable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
}
isCursorVisible = !isCursorVisible;
break;
}
#endif
posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
break;
}
case EEventKeyUp: /* Key events */
{
#ifdef SYMBIAN_CRYSTAL
// special case: 9300/9500 rocker up, simulate left mouse button
if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
{
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
}
#endif
posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym));
break;
}
case EEventFocusGained: /* SDL window got focus */
{
Private->EPOC_IsWindowFocused = ETrue;
posted += SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
/* Draw window background and screen buffer */
DisableKeyBlocking(_this); //Markus: guess why:-)
RedrawWindowL(_this);
break;
}
case EEventFocusLost: /* SDL window lost focus */
{
/*
CFbsBitmap* bmp = new (ELeave) CFbsBitmap();
bmp->Create(Private->EPOC_ScreenSize, Private->EPOC_DisplayMode);
Private->EPOC_WsScreen->CopyScreenToBitmap(bmp);
Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
Private->EPOC_WsWindow.BeginRedraw(TRect(Private->EPOC_WsWindow.Size()));
Private->EPOC_WindowGc->BitBlt(TPoint(0, 0), bmp);
Private->EPOC_WsWindow.EndRedraw();
Private->EPOC_WindowGc->Deactivate();
bmp->Save(_L("C:\\scr.mbm"));
delete bmp;
*/
Private->EPOC_IsWindowFocused = EFalse;
posted += SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
RWsSession s;
s.Connect();
RWindowGroup g(s);
g.Construct(TUint32(&g), EFalse);
g.EnableReceiptOfFocus(EFalse);
RWindow w(s);
w.Construct(g, TUint32(&w));
w.SetExtent(TPoint(0, 0), Private->EPOC_WsWindow.Size());
w.SetOrdinalPosition(0);
w.Activate();
w.Close();
g.Close();
s.Close();
/*
Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(Private->EPOC_WsWindowGroupID, -1);
SDL_Delay(500);
TInt focus = -1;
while(focus < 0)
{
const TInt curr = Private->EPOC_WsSession.GetFocusWindowGroup();
if(curr != Private->EPOC_WsWindowGroupID)
focus = curr;
else
SDL_Delay(500);
}
if(1 < Private->EPOC_WsSession.GetWindowGroupOrdinalPriority(Private->EPOC_WsWindowGroupID))
{
Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(focus, -1);
SDL_Delay(500);
Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(focus, 0);
}
*/
/*//and the request redraw
TRawEvent redrawEvent;
redrawEvent.Set(TRawEvent::ERedraw);
Private->EPOC_WsSession.SimulateRawEvent(redrawEvent);
Private->EPOC_WsSession.Flush();*/
#if 0
//!! Not used
// Wait and eat events until focus is gained again
while (ETrue) {
Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
User::WaitForRequest(Private->EPOC_WsEventStatus);
Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
TInt eventType = Private->EPOC_WsEvent.Type();
Private->EPOC_WsEventStatus = KRequestPending;
//Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
if (eventType == EEventFocusGained) {
RedrawWindowL(_this);
break;
}
}
#endif
break;
}
case EEventModifiersChanged:
{
TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged();
TUint modstate = KMOD_NONE;
if (modEvent->iModifiers == EModifierLeftShift)
modstate |= KMOD_LSHIFT;
if (modEvent->iModifiers == EModifierRightShift)
modstate |= KMOD_RSHIFT;
if (modEvent->iModifiers == EModifierLeftCtrl)
modstate |= KMOD_LCTRL;
if (modEvent->iModifiers == EModifierRightCtrl)
modstate |= KMOD_RCTRL;
if (modEvent->iModifiers == EModifierLeftAlt)
modstate |= KMOD_LALT;
if (modEvent->iModifiers == EModifierRightAlt)
modstate |= KMOD_RALT;
if (modEvent->iModifiers == EModifierLeftFunc)
modstate |= KMOD_LMETA;
if (modEvent->iModifiers == EModifierRightFunc)
modstate |= KMOD_RMETA;
if (modEvent->iModifiers == EModifierCapsLock)
modstate |= KMOD_CAPS;
SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT)));
break;
}
default:
break;
}
return posted;
}
extern "C" {
void EPOC_PumpEvents(_THIS)
{
int posted = 0; // !! Do we need this?
//Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
while (Private->EPOC_WsEventStatus != KRequestPending) {
Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
posted = EPOC_HandleWsEvent(_this, Private->EPOC_WsEvent);
Private->EPOC_WsEventStatus = KRequestPending;
Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
}
}
_LIT(KMapFileName, "C:\\sdl_info\\sdlkeymap.cfg");
LOCAL_C void ReadL(RFs& aFs, RArray<TInt>& aArray)
{
TInt drive = -1;
TFileName name(KMapFileName);
for(TInt i = 'z'; drive < 0 && i >= 'a'; i--)
{
name[0] = (TUint16)i;
if(BaflUtils::FileExists(aFs, name))
drive = i;
}
if(drive < 0)
return;
CLineReader* reader = CLineReader::NewLC(aFs, name);
while(reader->NextL())
{
TPtrC ln = reader->Current();
TLex line(ln);
TInt n = 0;
for(;;)
{
const TPtrC token = line.NextToken();
if(token.Length() == 0)
break;
if((n & 1) != 0)
{
TInt value;
TLex lex(token);
User::LeaveIfError(lex.Val(value));
User::LeaveIfError(aArray.Append(value));
}
n++;
}
}
CleanupStack::PopAndDestroy();
}
void EPOC_InitOSKeymap(_THIS)
{
int i;
/* Initialize the key translation table */
for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
keymap[i] = SDLK_UNKNOWN;
/* Numbers */
for ( i = 0; i<32; ++i ){
keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
}
/* e.g. Alphabet keys */
for ( i = 0; i<32; ++i ){
keymap['A' + i] = (SDLKey)(SDLK_a+i);
}
keymap[EStdKeyBackspace] = SDLK_BACKSPACE;
keymap[EStdKeyTab] = SDLK_TAB;
keymap[EStdKeyEnter] = SDLK_RETURN;
keymap[EStdKeyEscape] = SDLK_ESCAPE;
keymap[EStdKeySpace] = SDLK_SPACE;
keymap[EStdKeyPause] = SDLK_PAUSE;
keymap[EStdKeyHome] = SDLK_HOME;
keymap[EStdKeyEnd] = SDLK_END;
keymap[EStdKeyPageUp] = SDLK_PAGEUP;
keymap[EStdKeyPageDown] = SDLK_PAGEDOWN;
keymap[EStdKeyDelete] = SDLK_DELETE;
keymap[EStdKeyUpArrow] = SDLK_UP;
keymap[EStdKeyDownArrow] = SDLK_DOWN;
keymap[EStdKeyLeftArrow] = SDLK_LEFT;
keymap[EStdKeyRightArrow] = SDLK_RIGHT;
keymap[EStdKeyCapsLock] = SDLK_CAPSLOCK;
keymap[EStdKeyLeftShift] = SDLK_LSHIFT;
keymap[EStdKeyRightShift] = SDLK_RSHIFT;
keymap[EStdKeyLeftAlt] = SDLK_LALT;
keymap[EStdKeyRightAlt] = SDLK_RALT;
keymap[EStdKeyLeftCtrl] = SDLK_LCTRL;
keymap[EStdKeyRightCtrl] = SDLK_RCTRL;
keymap[EStdKeyLeftFunc] = SDLK_LMETA;
keymap[EStdKeyRightFunc] = SDLK_RMETA;
keymap[EStdKeyInsert] = SDLK_INSERT;
keymap[EStdKeyComma] = SDLK_COMMA;
keymap[EStdKeyFullStop] = SDLK_PERIOD;
keymap[EStdKeyForwardSlash] = SDLK_SLASH;
keymap[EStdKeyBackSlash] = SDLK_BACKSLASH;
keymap[EStdKeySemiColon] = SDLK_SEMICOLON;
keymap[EStdKeySingleQuote] = SDLK_QUOTE;
keymap[EStdKeyHash] = SDLK_HASH;
keymap[EStdKeySquareBracketLeft] = SDLK_LEFTBRACKET;
keymap[EStdKeySquareBracketRight] = SDLK_RIGHTBRACKET;
keymap[EStdKeyMinus] = SDLK_MINUS;
keymap[EStdKeyEquals] = SDLK_EQUALS;
keymap[EStdKeyF1] = SDLK_F1; /* chr + q */
keymap[EStdKeyF2] = SDLK_F2; /* chr + w */
keymap[EStdKeyF3] = SDLK_F3; /* chr + e */
keymap[EStdKeyF4] = SDLK_F4; /* chr + r */
keymap[EStdKeyF5] = SDLK_F5; /* chr + t */
keymap[EStdKeyF6] = SDLK_F6; /* chr + y */
keymap[EStdKeyF7] = SDLK_F7; /* chr + i */
keymap[EStdKeyF8] = SDLK_F8; /* chr + o */
keymap[EStdKeyF9] = SDLK_F9; /* chr + a */
keymap[EStdKeyF10] = SDLK_F10; /* chr + s */
keymap[EStdKeyF11] = SDLK_F11; /* chr + d */
keymap[EStdKeyF12] = SDLK_F12; /* chr + f */
#ifndef SYMBIAN_CRYSTAL
//!!7650 additions
#ifdef __WINS__
keymap[EStdKeyXXX] = SDLK_RETURN; /* "fire" key */
#else
keymap[EStdKeyDevice3] = SDLK_RETURN; /* "fire" key */
#endif
keymap[EStdKeyNkpAsterisk] = SDLK_ASTERISK;
keymap[EStdKeyYes] = SDLK_HOME; /* "call" key */
keymap[EStdKeyNo] = SDLK_END; /* "end call" key */
keymap[EStdKeyDevice0] = SDLK_SPACE; /* right menu key */
keymap[EStdKeyDevice1] = SDLK_ESCAPE; /* left menu key */
keymap[EStdKeyDevice2] = SDLK_POWER; /* power key */
#endif
#ifdef SYMBIAN_CRYSTAL
keymap[EStdKeyMenu] = SDLK_ESCAPE; // menu key
keymap[EStdKeyDevice6] = SDLK_LEFT; // Rocker (joystick) left
keymap[EStdKeyDevice7] = SDLK_RIGHT; // Rocker (joystick) right
keymap[EStdKeyDevice8] = SDLK_UP; // Rocker (joystick) up
keymap[EStdKeyDevice9] = SDLK_DOWN; // Rocker (joystick) down
keymap[EStdKeyLeftFunc] = SDLK_LALT; //chr?
keymap[EStdKeyRightFunc] = SDLK_RALT;
keymap[EStdKeyDeviceA] = SDLK_RETURN; /* "fire" key */
#endif
///////////////////////////////////////////////////////////
RFs fs;
if(KErrNone == fs.Connect())
{
RArray<TInt> array;
TRAPD(err, ReadL(fs, array));
if(err == KErrNone && array.Count() > 0)
{
SDLKey temp[MAX_SCANCODE];
Mem::Copy(temp, keymap, MAX_SCANCODE * sizeof(SDLKey));
for(TInt k = 0; k < array.Count(); k+= 2)
{
const TInt oldval = array[k];
const TInt newval = array[k + 1];
if(oldval >= 0 && oldval < MAX_SCANCODE && newval >= 0 && newval < MAX_SCANCODE)
{
keymap[oldval] = temp[newval];
}
}
}
array.Close();
}
fs.Close();
///////////////////////////////////////////////////////////
/* !!TODO
EStdKeyNumLock=0x1b,
EStdKeyScrollLock=0x1c,
EStdKeyNkpForwardSlash=0x84,
EStdKeyNkpAsterisk=0x85,
EStdKeyNkpMinus=0x86,
EStdKeyNkpPlus=0x87,
EStdKeyNkpEnter=0x88,
EStdKeyNkp1=0x89,
EStdKeyNkp2=0x8a,
EStdKeyNkp3=0x8b,
EStdKeyNkp4=0x8c,
EStdKeyNkp5=0x8d,
EStdKeyNkp6=0x8e,
EStdKeyNkp7=0x8f,
EStdKeyNkp8=0x90,
EStdKeyNkp9=0x91,
EStdKeyNkp0=0x92,
EStdKeyNkpFullStop=0x93,
EStdKeyMenu=0x94,
EStdKeyBacklightOn=0x95,
EStdKeyBacklightOff=0x96,
EStdKeyBacklightToggle=0x97,
EStdKeyIncContrast=0x98,
EStdKeyDecContrast=0x99,
EStdKeySliderDown=0x9a,
EStdKeySliderUp=0x9b,
EStdKeyDictaphonePlay=0x9c,
EStdKeyDictaphoneStop=0x9d,
EStdKeyDictaphoneRecord=0x9e,
EStdKeyHelp=0x9f,
EStdKeyOff=0xa0,
EStdKeyDial=0xa1,
EStdKeyIncVolume=0xa2,
EStdKeyDecVolume=0xa3,
EStdKeyDevice0=0xa4,
EStdKeyDevice1=0xa5,
EStdKeyDevice2=0xa6,
EStdKeyDevice3=0xa7,
EStdKeyDevice4=0xa8,
EStdKeyDevice5=0xa9,
EStdKeyDevice6=0xaa,
EStdKeyDevice7=0xab,
EStdKeyDevice8=0xac,
EStdKeyDevice9=0xad,
EStdKeyDeviceA=0xae,
EStdKeyDeviceB=0xaf,
EStdKeyDeviceC=0xb0,
EStdKeyDeviceD=0xb1,
EStdKeyDeviceE=0xb2,
EStdKeyDeviceF=0xb3,
EStdKeyApplication0=0xb4,
EStdKeyApplication1=0xb5,
EStdKeyApplication2=0xb6,
EStdKeyApplication3=0xb7,
EStdKeyApplication4=0xb8,
EStdKeyApplication5=0xb9,
EStdKeyApplication6=0xba,
EStdKeyApplication7=0xbb,
EStdKeyApplication8=0xbc,
EStdKeyApplication9=0xbd,
EStdKeyApplicationA=0xbe,
EStdKeyApplicationB=0xbf,
EStdKeyApplicationC=0xc0,
EStdKeyApplicationD=0xc1,
EStdKeyApplicationE=0xc2,
EStdKeyApplicationF=0xc3,
EStdKeyYes=0xc4,
EStdKeyNo=0xc5,
EStdKeyIncBrightness=0xc6,
EStdKeyDecBrightness=0xc7,
EStdKeyCaseOpen=0xc8,
EStdKeyCaseClose=0xc9
*/
}
static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym)
{
// char debug[256];
//SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
/* Set the keysym information */
keysym->scancode = scancode;
if ((scancode >= MAX_SCANCODE) &&
((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) {
SDL_SetError("Too big scancode");
keysym->scancode = SDLK_UNKNOWN;
keysym->mod = KMOD_NONE;
return keysym;
}
keysym->mod = SDL_GetModState();
/* Handle function keys: F1, F2, F3 ... */
if (keysym->mod & KMOD_META) {
if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */
switch(scancode) {
case 'Q': scancode = EStdKeyF1; break;
case 'W': scancode = EStdKeyF2; break;
case 'E': scancode = EStdKeyF3; break;
case 'R': scancode = EStdKeyF4; break;
case 'T': scancode = EStdKeyF5; break;
case 'Y': scancode = EStdKeyF6; break;
case 'U': scancode = EStdKeyF7; break;
case 'I': scancode = EStdKeyF8; break;
case 'A': scancode = EStdKeyF9; break;
case 'S': scancode = EStdKeyF10; break;
case 'D': scancode = EStdKeyF11; break;
case 'F': scancode = EStdKeyF12; break;
}
keysym->sym = keymap[scancode];
}
}
if (scancode >= ENonCharacterKeyBase) {
// Non character keys
keysym->sym = keymap[scancode -
ENonCharacterKeyBase + 0x0081]; // !!hard coded
} else {
keysym->sym = keymap[scancode];
}
/* Remap the arrow keys if the device is rotated */
if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) {
switch(keysym->sym) {
case SDLK_UP: keysym->sym = SDLK_LEFT; break;
case SDLK_DOWN: keysym->sym = SDLK_RIGHT; break;
case SDLK_LEFT: keysym->sym = SDLK_DOWN; break;
case SDLK_RIGHT:keysym->sym = SDLK_UP; break;
}
}
/* If UNICODE is on, get the UNICODE value for the key */
keysym->unicode = 0;
#if 0 // !!TODO:unicode
if ( SDL_TranslateUNICODE )
{
/* Populate the unicode field with the ASCII value */
keysym->unicode = scancode;
}
#endif
//!!
//sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d",
// keysym->scancode, keysym->sym, keysym->mod);
//SDL_TRACE(debug); //!!
return(keysym);
}
}; /* extern "C" */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,34 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
#ifndef _SDL_epocvideo_h
#define _SDL_epocvideo_h
#ifndef EKA2
#include"SDL_epocvideo_org.h"
#else
#include"SDL_epocvideo2.h"
#endif
#endif

View file

@ -0,0 +1,521 @@
#include "epoc_sdl.h"
#include <stdio.h>
#undef NULL
extern "C" {
//#define DEBUG_TRACE_ENABLED
#include "SDL_error.h"
#include "SDL_video.h"
#include "SDL_keysym.h"
#include "SDL_keyboard.h"
#include "SDL_events_c.h"
#include "SDL_timer.h"
} /* extern "C" */
#include "SDL_epocvideo.h"
#include "SDL_epocevents_c.h"
#include "sdlepocapi.h"
#include <eikenv.h>
#include<bautils.h>
extern "C"
{
static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
}
//extern "C" {
/* The translation tables from a console scancode to a SDL keysym */
static SDLKey keymap[MAX_SCANCODE];
static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
void DisableKeyBlocking(_THIS);
//} /* extern "C" */
SDLKey* KeyMap()
{
return keymap;
}
TBool isCursorVisible = EFalse;
void ResetKeyMap()
{
int i;
/* Initialize the key translation table */
for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
keymap[i] = SDLK_UNKNOWN;
/* Numbers */
for ( i = 0; i<32; ++i ){
keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
}
/* e.g. Alphabet keys */
for ( i = 0; i<32; ++i ){
keymap['A' + i] = (SDLKey)(SDLK_a+i);
}
keymap[EStdKeyBackspace] = SDLK_BACKSPACE;
keymap[EStdKeyTab] = SDLK_TAB;
keymap[EStdKeyEnter] = SDLK_RETURN;
keymap[EStdKeyEscape] = SDLK_ESCAPE;
keymap[EStdKeySpace] = SDLK_SPACE;
keymap[EStdKeyPause] = SDLK_PAUSE;
keymap[EStdKeyHome] = SDLK_HOME;
keymap[EStdKeyEnd] = SDLK_END;
keymap[EStdKeyPageUp] = SDLK_PAGEUP;
keymap[EStdKeyPageDown] = SDLK_PAGEDOWN;
keymap[EStdKeyDelete] = SDLK_DELETE;
keymap[EStdKeyUpArrow] = SDLK_UP;
keymap[EStdKeyDownArrow] = SDLK_DOWN;
keymap[EStdKeyLeftArrow] = SDLK_LEFT;
keymap[EStdKeyRightArrow] = SDLK_RIGHT;
keymap[EStdKeyCapsLock] = SDLK_CAPSLOCK;
keymap[EStdKeyLeftShift] = SDLK_LSHIFT;
keymap[EStdKeyRightShift] = SDLK_RSHIFT;
keymap[EStdKeyLeftAlt] = SDLK_LALT;
keymap[EStdKeyRightAlt] = SDLK_RALT;
keymap[EStdKeyLeftCtrl] = SDLK_LCTRL;
keymap[EStdKeyRightCtrl] = SDLK_RCTRL;
keymap[EStdKeyLeftFunc] = SDLK_LMETA;
keymap[EStdKeyRightFunc] = SDLK_RMETA;
keymap[EStdKeyInsert] = SDLK_INSERT;
keymap[EStdKeyComma] = SDLK_COMMA;
keymap[EStdKeyFullStop] = SDLK_PERIOD;
keymap[EStdKeyForwardSlash] = SDLK_SLASH;
keymap[EStdKeyBackSlash] = SDLK_BACKSLASH;
keymap[EStdKeySemiColon] = SDLK_SEMICOLON;
keymap[EStdKeySingleQuote] = SDLK_QUOTE;
keymap[EStdKeyHash] = SDLK_HASH;
keymap[EStdKeySquareBracketLeft] = SDLK_LEFTBRACKET;
keymap[EStdKeySquareBracketRight] = SDLK_RIGHTBRACKET;
keymap[EStdKeyMinus] = SDLK_MINUS;
keymap[EStdKeyEquals] = SDLK_EQUALS;
keymap[EStdKeyF1] = SDLK_F1;
keymap[EStdKeyF2] = SDLK_F2;
keymap[EStdKeyF3] = SDLK_F3;
keymap[EStdKeyF4] = SDLK_F4;
keymap[EStdKeyF5] = SDLK_F5;
keymap[EStdKeyF6] = SDLK_F6;
keymap[EStdKeyF7] = SDLK_F7;
keymap[EStdKeyF8] = SDLK_F8;
keymap[EStdKeyF9] = SDLK_F9;
keymap[EStdKeyF10] = SDLK_F10;
keymap[EStdKeyF11] = SDLK_F11;
keymap[EStdKeyF12] = SDLK_F12;
keymap[EStdKeyXXX] = SDLK_RETURN; /* "fire" key */
keymap[EStdKeyDevice3] = SDLK_RETURN; /* "fire" key */
keymap[EStdKeyNkpAsterisk] = SDLK_ASTERISK;
keymap[EStdKeyYes] = SDLK_HOME; /* "call" key */
keymap[EStdKeyNo] = SDLK_END; /* "end call" key */
keymap[EStdKeyDevice0] = SDLK_SPACE; /* right menu key */
keymap[EStdKeyDevice1] = SDLK_ESCAPE; /* left menu key */
keymap[EStdKeyDevice2] = SDLK_POWER; /* power key */
keymap[EStdKeyMenu] = SDLK_MENU; // menu key
keymap[EStdKeyDevice6] = SDLK_LEFT; // Rocker (joystick) left
keymap[EStdKeyDevice7] = SDLK_RIGHT; // Rocker (joystick) right
keymap[EStdKeyDevice8] = SDLK_UP; // Rocker (joystick) up
keymap[EStdKeyDevice9] = SDLK_DOWN; // Rocker (joystick) down
keymap[EStdKeyLeftFunc] = SDLK_LALT; //chr?
keymap[EStdKeyRightFunc] = SDLK_RALT;
keymap[EStdKeyDeviceA] = SDLK_RETURN; /* "fire" key */
///////////////////////////////////////////////////////////
/*
RFs fs;
if(KErrNone == fs.Connect())
{
RArray<TInt> array;
TRAPD(err, ReadL(fs, array));
if(err == KErrNone && array.Count() > 0)
{
SDLKey temp[MAX_SCANCODE];
Mem::Copy(temp, keymap, MAX_SCANCODE * sizeof(SDLKey));
for(TInt k = 0; k < array.Count(); k+= 2)
{
const TInt oldval = array[k];
const TInt newval = array[k + 1];
if(oldval >= 0 && oldval < MAX_SCANCODE && newval >= 0 && newval < MAX_SCANCODE)
{
keymap[oldval] = temp[newval];
}
}
}
array.Close();
}
fs.Close();*/
///////////////////////////////////////////////////////////
keymap[EStdKeyNumLock] = SDLK_NUMLOCK;
keymap[EStdKeyScrollLock] = SDLK_SCROLLOCK;
keymap[EStdKeyNkpForwardSlash] = SDLK_KP_DIVIDE;
keymap[EStdKeyNkpAsterisk] = SDLK_KP_MULTIPLY;
keymap[EStdKeyNkpMinus] = SDLK_KP_MINUS;
keymap[EStdKeyNkpPlus] = SDLK_KP_PLUS;
keymap[EStdKeyNkpEnter] = SDLK_KP_ENTER;
keymap[EStdKeyNkp1] = SDLK_KP1;
keymap[EStdKeyNkp2] = SDLK_KP2;
keymap[EStdKeyNkp3] = SDLK_KP3;
keymap[EStdKeyNkp4] = SDLK_KP4;
keymap[EStdKeyNkp5] = SDLK_KP5;
keymap[EStdKeyNkp6] = SDLK_KP6;
keymap[EStdKeyNkp7] = SDLK_KP7;
keymap[EStdKeyNkp8] = SDLK_KP8;
keymap[EStdKeyNkp9] = SDLK_KP9;
keymap[EStdKeyNkp0] = SDLK_KP0;
keymap[EStdKeyNkpFullStop] = SDLK_KP_PERIOD;
/*
keymap[EStdKeyMenu] = SDLK_MENU; should be, but not yet
keymap[EStdKeyBacklightOn] =
keymap[EStdKeyBacklightOff] =
keymap[EStdKeyBacklightToggle] =
keymap[EStdKeyIncContrast] =
keymap[EStdKeyDecContrast] =
keymap[EStdKeySliderDown] =
keymap[EStdKeySliderUp] =
keymap[EStdKeyDictaphonePlay] =
keymap[EStdKeyDictaphoneStop] =
keymap[EStdKeyDictaphoneRecord] =
keymap[EStdKeyHelp] =
keymap[EStdKeyOff] =
keymap[EStdKeyDial] =
keymap[EStdKeyIncVolume] =
keymap[EStdKeyDecVolume] =
keymap[EStdKeyDevice0] =
keymap[EStdKeyDevice1] =
keymap[EStdKeyDevice2] =
keymap[EStdKeyDevice3] =
keymap[EStdKeyDevice4] =
keymap[EStdKeyDevice5] =
keymap[EStdKeyDevice6] =
keymap[EStdKeyDevice7] =
keymap[EStdKeyDevice8] =
keymap[EStdKeyDevice9] =
keymap[EStdKeyDeviceA] =
keymap[EStdKeyDeviceB] =
keymap[EStdKeyDeviceC] =
keymap[EStdKeyDeviceD] =
keymap[EStdKeyDeviceE] =
keymap[EStdKeyDeviceF] =
keymap[EStdKeyApplication0] =
keymap[EStdKeyApplication1] =
keymap[EStdKeyApplication2] =
keymap[EStdKeyApplication3] =
keymap[EStdKeyApplication4] =
keymap[EStdKeyApplication5] =
keymap[EStdKeyApplication6] =
keymap[EStdKeyApplication7] =
keymap[EStdKeyApplication8] =
keymap[EStdKeyApplication9] =
keymap[EStdKeyApplicationA] =
keymap[EStdKeyApplicationB] =
keymap[EStdKeyApplicationC] =
keymap[EStdKeyApplicationD] =
keymap[EStdKeyApplicationE] =
keymap[EStdKeyApplicationF] =
keymap[EStdKeyYes] =
keymap[EStdKeyNo] =
keymap[EStdKeyIncBrightness] =
keymap[EStdKeyDecBrightness] =
keymap[EStdKeyCaseOpen] =
keymap[EStdKeyCaseClose] = */
}
int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
{
int posted = 0;
SDL_keysym keysym;
// SDL_TRACE1("hws %d", aWsEvent.Type());
switch (aWsEvent.Type())
{
case EEventPointer: /* Mouse pointer events */
{
/* const TPointerCursorMode mode = EpocSdlEnv::PointerMode();
if(mode == EPointerCursorNone)
{
return 0; //TODO: Find out why events are get despite of cursor should be off
}
*/
const TPointerEvent* pointerEvent = aWsEvent.Pointer();
const TPoint mousePos = EpocSdlEnv::WindowCoordinates(pointerEvent->iPosition);
/*!! TODO Pointer do not yet work properly
//SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
if (Private->EPOC_ShrinkedHeight) {
mousePos.iY <<= 1; // Scale y coordinate to shrinked screen height
}
if (Private->EPOC_ShrinkedWidth) {
mousePos.iX <<= 1; // Scale x coordinate to shrinked screen width
}
*/
posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
switch (pointerEvent->iType)
{
case TPointerEvent::EButton1Down:
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
break;
case TPointerEvent::EButton1Up:
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
break;
case TPointerEvent::EButton2Down:
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
break;
case TPointerEvent::EButton2Up:
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
break;
case TPointerEvent::EButton3Down:
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0);
break;
case TPointerEvent::EButton3Up:
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);
break;
} // switch
break;
}
case EEventKeyDown: /* Key events */
{
#ifdef SYMBIAN_CRYSTAL
// special case: 9300/9500 rocker down, simulate left mouse button
if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
{
const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode();
if(mode != EPointerCursorNone)
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
}
#endif
(void*)TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym);
#ifndef DISABLE_JOYSTICK
/* Special handling */
switch((int)keysym.sym) {
case SDLK_CAPSLOCK:
if (!isCursorVisible) {
/* Enable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
}
else {
/* Disable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
}
isCursorVisible = !isCursorVisible;
break;
}
#endif
posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
break;
}
case EEventKeyUp: /* Key events */
{
#ifdef SYMBIAN_CRYSTAL
// special case: 9300/9500 rocker up, simulate left mouse button
if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
{
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
}
#endif
posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym));
break;
}
case EEventFocusGained: /* SDL window got focus */
{
Private->iIsWindowFocused = ETrue;
posted += SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
/* Draw window background and screen buffer */
DisableKeyBlocking(_this); //Markus: guess why:-)
//RedrawWindowL(_this);
break;
}
case EEventFocusLost: /* SDL window lost focus */
{
Private->iIsWindowFocused = EFalse;
posted += SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
break;
}
case EEventModifiersChanged:
{
TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged();
TUint modstate = KMOD_NONE;
if (modEvent->iModifiers == EModifierLeftShift)
modstate |= KMOD_LSHIFT;
if (modEvent->iModifiers == EModifierRightShift)
modstate |= KMOD_RSHIFT;
if (modEvent->iModifiers == EModifierLeftCtrl)
modstate |= KMOD_LCTRL;
if (modEvent->iModifiers == EModifierRightCtrl)
modstate |= KMOD_RCTRL;
if (modEvent->iModifiers == EModifierLeftAlt)
modstate |= KMOD_LALT;
if (modEvent->iModifiers == EModifierRightAlt)
modstate |= KMOD_RALT;
if (modEvent->iModifiers == EModifierLeftFunc)
modstate |= KMOD_LMETA;
if (modEvent->iModifiers == EModifierRightFunc)
modstate |= KMOD_RMETA;
if (modEvent->iModifiers == EModifierCapsLock)
modstate |= KMOD_CAPS;
SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT)));
break;
}
case EEventScreenDeviceChanged:
{
EpocSdlEnv::WaitDeviceChange();
}
break;
default:
break;
}
return posted;
}
extern "C" {
void EPOC_PumpEvents(_THIS)
{
MEventQueue& events = EpocSdlEnv::EventQueue();
while(events.HasData())
{
events.Lock();
//there have to be a copy, so we can release
//lock immediately. HandleWsEvent may cause
//deadlock otherwise.
const TWsEvent event = events.Shift();
events.Unlock();
// const TWsEvent& event = events.Top();
EPOC_HandleWsEvent(_this, event);
// events.Shift();
}
}
void EPOC_InitOSKeymap(_THIS)
{
ResetKeyMap();
EpocSdlEnv::ObserverEvent(MSDLObserver::EEventKeyMapInit ,0);
}
static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym)
{
// char debug[256];
//SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
/* Set the keysym information */
keysym->scancode = scancode;
if ((scancode >= MAX_SCANCODE) &&
((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) {
SDL_SetError("Too big scancode");
keysym->scancode = SDLK_UNKNOWN;
keysym->mod = KMOD_NONE;
return keysym;
}
keysym->mod = SDL_GetModState();
/* Handle function keys: F1, F2, F3 ... */
if (keysym->mod & KMOD_META) {
if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */
switch(scancode) {
case 'Q': scancode = EStdKeyF1; break;
case 'W': scancode = EStdKeyF2; break;
case 'E': scancode = EStdKeyF3; break;
case 'R': scancode = EStdKeyF4; break;
case 'T': scancode = EStdKeyF5; break;
case 'Y': scancode = EStdKeyF6; break;
case 'U': scancode = EStdKeyF7; break;
case 'I': scancode = EStdKeyF8; break;
case 'A': scancode = EStdKeyF9; break;
case 'S': scancode = EStdKeyF10; break;
case 'D': scancode = EStdKeyF11; break;
case 'F': scancode = EStdKeyF12; break;
}
keysym->sym = keymap[scancode];
}
}
if (scancode >= ENonCharacterKeyBase) {
// Non character keys
keysym->sym = keymap[scancode -
ENonCharacterKeyBase + 0x0081]; // !!hard coded
} else {
keysym->sym = keymap[scancode];
}
/* Remap the arrow keys if the device is rotated */
/*
if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) {
switch(keysym->sym) {
case SDLK_UP: keysym->sym = SDLK_LEFT; break;
case SDLK_DOWN: keysym->sym = SDLK_RIGHT; break;
case SDLK_LEFT: keysym->sym = SDLK_DOWN; break;
case SDLK_RIGHT:keysym->sym = SDLK_UP; break;
}
}
*/
/* If UNICODE is on, get the UNICODE value for the key */
keysym->unicode = 0;
#if 0 // !!TODO:unicode
if ( SDL_TranslateUNICODE )
{
/* Populate the unicode field with the ASCII value */
keysym->unicode = scancode;
}
#endif
//!!
//sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d",
// keysym->scancode, keysym->sym, keysym->mod);
//SDL_TRACE(debug); //!!
return(keysym);
}
} /* extern "C" */

View file

@ -0,0 +1,594 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
/*
SDL_epocvideo.cpp
Epoc based SDL video driver implementation
Markus Mertama
*/
#include "epoc_sdl.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
extern "C" {
#include "SDL_error.h"
#include "SDL_timer.h"
#include "SDL_video.h"
#undef NULL
#include "SDL_pixels_c.h"
#include "SDL.h"
#include "SDL_mouse.h"
}
#include "SDL_epocvideo.h"
#include "SDL_epocevents_c.h"
#include <coedef.h>
#include <flogger.h>
#include <eikenv.h>
#include <eikappui.h>
#include <eikapp.h>
#include "sdlepocapi.h"
////////////////////////////////////////////////////////////////
_LIT(KLibName, "SDL");
void RDebug_Print_b(char* error_str, void* param)
{
TBuf8<128> error8((TUint8*)error_str);
TBuf<128> error;
error.Copy(error8);
#ifndef TRACE_TO_FILE
if (param) //!! Do not work if the parameter is really 0!!
RDebug::Print(error, param);
else
RDebug::Print(error);
#else
if (param) //!! Do not work if the parameter is really 0!!
RFileLogger::WriteFormat(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error, param);
else
RFileLogger::Write(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error);
#endif
}
extern "C" void RDebug_Print(char* error_str, void* param)
{
RDebug_Print_b(error_str, param);
}
/*
int Debug_AvailMem2()
{
//User::CompressAllHeaps();
TMemoryInfoV1Buf membuf;
User::LeaveIfError(UserHal::MemoryInfo(membuf));
TMemoryInfoV1 minfo = membuf();
return(minfo.iFreeRamInBytes);
}
extern "C" int Debug_AvailMem()
{
return(Debug_AvailMem2());
}
*/
extern "C" {
/* Initialization/Query functions */
static int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
static SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
static int EPOC_SetColors(_THIS, int firstcolor, int ncolors,
SDL_Color *colors);
static void EPOC_VideoQuit(_THIS);
/* Hardware surface functions */
static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface);
static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface);
static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface);
static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface);
static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
static int EPOC_Available(void);
static SDL_VideoDevice *EPOC_CreateDevice(int devindex);
void DrawBackground(_THIS);
void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer);
void DirectDrawRotated(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer);
/* Mouse functions */
static WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
static void EPOC_FreeWMCursor(_THIS, WMcursor *cursor);
static int EPOC_ShowWMCursor(_THIS, WMcursor *cursor);
}
extern "C"
{
struct WMcursor
{
};
}
/* Epoc video driver bootstrap functions */
static int EPOC_Available(void)
{
return 1; /* Always available */
}
static void EPOC_DeleteDevice(SDL_VideoDevice *device)
{
User::Free(device->hidden);
User::Free(device);
}
static SDL_VideoDevice *EPOC_CreateDevice(int /*devindex*/)
{
SDL_VideoDevice *device;
SDL_TRACE("SDL:EPOC_CreateDevice");
/* Allocate all variables that we free on delete */
device = static_cast<SDL_VideoDevice*>(User::Alloc(sizeof(SDL_VideoDevice)));
if ( device )
{
Mem::FillZ(device, (sizeof *device));
device->hidden = static_cast<struct SDL_PrivateVideoData*>
(User::Alloc((sizeof *device->hidden)));
}
if ( (device == NULL) || (device->hidden == NULL) )
{
SDL_OutOfMemory();
if ( device ) {
User::Free(device);
}
return(0);
}
Mem::FillZ(device->hidden, (sizeof *device->hidden));
/* Set the function pointers */
device->VideoInit = EPOC_VideoInit;
device->ListModes = EPOC_ListModes;
device->SetVideoMode = EPOC_SetVideoMode;
device->SetColors = EPOC_SetColors;
device->UpdateRects = NULL;
device->VideoQuit = EPOC_VideoQuit;
device->AllocHWSurface = EPOC_AllocHWSurface;
device->CheckHWBlit = NULL;
device->FillHWRect = NULL;
device->SetHWColorKey = NULL;
device->SetHWAlpha = NULL;
device->LockHWSurface = EPOC_LockHWSurface;
device->UnlockHWSurface = EPOC_UnlockHWSurface;
device->FlipHWSurface = EPOC_FlipHWSurface;
device->FreeHWSurface = EPOC_FreeHWSurface;
device->SetIcon = NULL;
device->SetCaption = NULL;
device->GetWMInfo = NULL;
device->FreeWMCursor = EPOC_FreeWMCursor;
device->CreateWMCursor = EPOC_CreateWMCursor;
device->ShowWMCursor = EPOC_ShowWMCursor;
device->WarpWMCursor = NULL;
device->InitOSKeymap = EPOC_InitOSKeymap;
device->PumpEvents = EPOC_PumpEvents;
device->free = EPOC_DeleteDevice;
return device;
}
VideoBootStrap EPOC_bootstrap = {
"epoc\0\0\0", "EPOC system",
EPOC_Available, EPOC_CreateDevice
};
void DisableKeyBlocking(_THIS)
{
EpocSdlEnv::Request(EpocSdlEnv::EDisableKeyBlocking);
}
void ConstructWindowL(_THIS)
{
SDL_TRACE("SDL:ConstructWindowL");
DisableKeyBlocking(_this); //disable key blocking
}
int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
/* Construct Epoc window */
ConstructWindowL(_this);
/* Initialise Epoc frame buffer */
const TDisplayMode displayMode = EpocSdlEnv::DisplayMode();
/* The "best" video format should be returned to caller. */
vformat->BitsPerPixel = TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode);
vformat->BytesPerPixel = TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) / 8;
//?? Private->iWindow->PointerFilter(EPointerFilterDrag, 0);
Private->iScreenPos = TPoint(0, 0);
Private->iRect.x = Private->iScreenPos.iX;
Private->iRect.y = Private->iScreenPos.iY;
const TSize sz = EpocSdlEnv::WindowSize();
Private->iRect.w = sz.iWidth;
Private->iRect.h = sz.iHeight;
Private->iRectPtr = &Private->iRect;
return(0);
}
SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
if(flags & SDL_HWSURFACE)
{
if(format->BytesPerPixel != 4) //in HW only full color is supported
return NULL;
}
if(flags & SDL_FULLSCREEN)
{
return &Private->iRectPtr;
}
return (SDL_Rect **)(-1); //everythingisok, unless too small shoes
}
int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{
if ((firstcolor+ncolors) > 256)
return -1;
TUint32 palette[256];
const TDisplayMode mode = EpocSdlEnv::DisplayMode();
if(TDisplayModeUtils::NumDisplayModeColors(mode) == 4096)
{
// Set 12 bit palette
for(int i = firstcolor; i < ncolors; i++)
{
// 4k value: 0000 rrrr gggg bbbb
TUint32 color4K = (colors[i].r & 0x0000f0) << 4;
color4K |= (colors[i].g & 0x0000f0);
color4K |= (colors[i].b & 0x0000f0) >> 4;
palette[i] = color4K;
}
}
else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 65536)
{
for(int i = firstcolor; i < ncolors; i++)
{
// 64k-colour displays effectively support RGB values
// with 5 bits allocated to red, 6 to green and 5 to blue
// 64k value: rrrr rggg gggb bbbb
TUint32 color64K = (colors[i].r & 0x0000f8) << 8;
color64K |= (colors[i].g & 0x0000fc) << 3;
color64K |= (colors[i].b & 0x0000f8) >> 3;
palette[i] = color64K;
}
}
else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 16777216)
{
for(int i = firstcolor; i < ncolors; i++)
{
// 16M-colour
//0000 0000 rrrr rrrr gggg gggg bbbb bbbb
TUint32 color16M = colors[i].r << 16;
color16M |= colors[i].g << 8;
color16M |= colors[i].b;
palette[i] = color16M;
}
}
else
{
return -2;
}
if(EpocSdlEnv::SetPalette(firstcolor, ncolors, palette) == KErrNone)
return 0;
return -1;
}
/*
void AllocHWSurfaceL(CFbsBitmap*& aBitmap, const TDisplayMode& aMode, const TSize& aSize)
{
aBitmap = new (ELeave) CFbsBitmap();
if(KErrNone != aBitmap->CreateHardwareBitmap(aSize, aMode,
EpocSdlEnv::EikonEnv().EikAppUi()->Application()->AppDllUid()))
//...if it fails - should we use wsbitmaps???
{//the good reason to use hw bitmaps is that they wont need lock heap
PANIC_IF_ERROR(aBitmap->Create(aSize, aMode));
}
}
int CreateSurfaceL(_THIS, SDL_Surface* surface)
{
__ASSERT_ALWAYS(Private->iFrame == NULL, PANIC(KErrAlreadyExists));
;
TInt dmode = EColorLast;
TDisplayMode displayMode;
EpocSdlEnv::GetDiplayMode(displayMode);
if(
TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode)
== surface->format->BitsPerPixel)
{
dmode = displayMode;
}
else
{
--dmode;
while(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)) &&
TDisplayModeUtils::NumDisplayModeBitsPerPixel(TDisplayMode(dmode)) !=
surface->format->BitsPerPixel)
--dmode;
}
__ASSERT_ALWAYS(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)), PANIC(KErrNotSupported));
TRAPD(err, AllocHWSurfaceL(Private->iFrame, TDisplayMode(dmode), TSize(surface->w, surface->h)));
return err == KErrNone ? 0 : -1;
}
*/
TDisplayMode GetDisplayMode(TInt aBitsPerPixel)
{
const TDisplayMode displayMode = EpocSdlEnv::DisplayMode();
TInt dmode = EColorLast;
if(
TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode)
== aBitsPerPixel)
{
dmode = displayMode;
}
else
{
--dmode;
while(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)) &&
TDisplayModeUtils::NumDisplayModeBitsPerPixel(TDisplayMode(dmode)) !=
aBitsPerPixel)
--dmode;
}
return TDisplayMode(dmode);
}
SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current,
int width, int height, int bpp, Uint32 flags)
{
const TSize screenSize = EpocSdlEnv::WindowSize(TSize(width, height));
if(width > screenSize.iWidth || height > screenSize.iHeight)
{
if(flags & SDL_FULLSCREEN)
{
width = screenSize.iWidth;
height = screenSize.iHeight;
}
else
return NULL;
}
if(current && current->pixels)
{
// free(current->pixels);
current->pixels = NULL;
}
if(!SDL_ReallocFormat(current, bpp, 0, 0, 0, 0))
{
return(NULL);
}
current->flags = 0;
if(width == screenSize.iWidth && height == screenSize.iHeight)
current->flags |= SDL_FULLSCREEN;
const int numBytesPerPixel = ((bpp-1)>>3) + 1;
current->pitch = numBytesPerPixel * width; // Number of bytes in scanline
/* Set up the new mode framebuffer */
current->flags |= SDL_PREALLOC;
if(bpp <= 8)
current->flags |= SDL_HWPALETTE;
User::Free(Private->iSwSurface);
current->pixels = NULL;
Private->iSwSurface = NULL;
if(flags & SDL_HWSURFACE)
{
current->flags |= SDL_HWSURFACE;
// current->pixels = NULL;
// Private->iSwSurface = NULL;
}
else
{
current->flags |= SDL_SWSURFACE;
const TInt surfacesize = width * height * numBytesPerPixel;
Private->iSwSurfaceSize = TSize(width, height);
delete Private->iSwSurface;
Private->iSwSurface = NULL;
current->pixels = (TUint8*) User::AllocL(surfacesize);
Private->iSwSurface = (TUint8*) current->pixels;
const TInt err = EpocSdlEnv::AllocSwSurface
(TSize(width, height), GetDisplayMode(current->format->BitsPerPixel));
if(err != KErrNone)
return NULL;
}
current->w = width;
current->h = height;
/* Set the blit function */
_this->UpdateRects = EPOC_DirectUpdate;
/*
* Logic for getting suitable screen dimensions, offset, scaling and orientation
*/
/* Centralize game window on device screen */
Private->iScreenPos.iX = Max(0, (screenSize.iWidth - width) / 2);
Private->iScreenPos.iY = Max(0, (screenSize.iHeight - height) / 2);
// delete (Private->iFrame);
// Private->iFrame = NULL;
// TRAPD(err, CreateSurfaceL(_this, current));
// PANIC_IF_ERROR(err);
SDL_TRACE1("View width %d", width);
SDL_TRACE1("View height %d", height);
SDL_TRACE1("View bmode %d", bpp);
SDL_TRACE1("View x %d", Private->iScreenPos.iX);
SDL_TRACE1("View y %d", Private->iScreenPos.iY);
EpocSdlEnv::LockPalette(EFalse);
/* We're done */
return(current);
}
static int EPOC_AllocHWSurface(_THIS, SDL_Surface* surface)
{
return KErrNone == EpocSdlEnv::AllocHwSurface(TSize(surface->w, surface->h), GetDisplayMode(surface->format->BitsPerPixel));
}
static void EPOC_FreeHWSurface(_THIS, SDL_Surface* /*surface*/)
{
}
static int EPOC_LockHWSurface(_THIS, SDL_Surface* surface)
{
if(EpocSdlEnv::IsDsaAvailable())
{
TUint8* address = EpocSdlEnv::LockHwSurface();
if(address != NULL)
{
surface->pixels = address;
return 1;
}
}
return 0;
}
static void EPOC_UnlockHWSurface(_THIS, SDL_Surface* /*surface*/)
{
EpocSdlEnv::UnlockHwSurface();
}
static int EPOC_FlipHWSurface(_THIS, SDL_Surface* /*surface*/)
{
return(0);
}
static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
{
if(EpocSdlEnv::IsDsaAvailable())
{
if(Private->iSwSurface)
{
const TRect target(Private->iScreenPos, Private->iSwSurfaceSize);
for(TInt i = 0; i < numrects ;i++)
{
const TRect rect(TPoint(rects[i].x, rects[i].y),
TSize(rects[i].w, rects[i].h));
if(!EpocSdlEnv::AddUpdateRect(Private->iSwSurface, rect, target))
return; //not succesful
}
EpocSdlEnv::UpdateSwSurface();
}
SDL_PauseAudio(0);
}
else
{
SDL_PauseAudio(1);
EpocSdlEnv::WaitDsaAvailable();
}
}
/* Note: If we are terminated, this could be called in the middle of
another SDL video routine -- notably UpdateRects.
*/
void EPOC_VideoQuit(_THIS)
{
// delete Private->iFrame;
// Private->iFrame = NULL;
User::Free(Private->iSwSurface);
Private->iSwSurface = NULL;
EpocSdlEnv::FreeSurface();
}
WMcursor *EPOC_CreateWMCursor(_THIS, Uint8* /*data*/, Uint8* /*mask*/, int /*w*/, int /*h*/, int /*hot_x*/, int /*hot_y*/)
{
return (WMcursor*) 1; //hii! prevents SDL to view a std cursor
}
void EPOC_FreeWMCursor(_THIS, WMcursor* /*cursor*/)
{
}
int EPOC_ShowWMCursor(_THIS, WMcursor *cursor)
{
return true;
}

View file

@ -0,0 +1,51 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
#ifndef EPOCVIDEO_H
#define EPOCVIDEO_H
#include<w32std.h>
/* Hidden "this" pointer for the video functions */
#define _THIS SDL_VideoDevice *_this
#define Private _this->hidden
class CFbsBitmap;
struct SDL_VideoDevice;
void DisableKeyBlocking(SDL_VideoDevice*);
struct SDL_PrivateVideoData
{
TPoint iScreenPos;
TBool iIsWindowFocused;
TSize iSwSurfaceSize;
TUint8* iSwSurface;
SDL_Rect iRect; //same info in SDL format
SDL_Rect* iRectPtr;
};
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,60 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@devolution.com
*/
/*
SDL_epocevents_c.h
Handle the event stream, converting Epoc events into SDL events
Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi) and Markus Mertama
*/
#ifdef SAVE_RCSID
static char rcsid =
"@(#) $Id: SDL_aaevents_c.h,v 1.1.2.2 2000/03/16 15:20:39 hercules Exp $";
#endif
extern "C" {
#include "SDL_sysvideo.h"
//#include "SDL_epocvideo.h"
}
#define MAX_SCANCODE 255
/* Variables and functions exported by SDL_sysevents.c to other parts
of the native video subsystem (SDL_sysvideo.c)
*/
/* Hidden "this" pointer for the video functions */
#define _THIS SDL_VideoDevice *_this
#define Private _this->hidden
extern "C" {
extern void EPOC_InitOSKeymap(_THIS);
extern void EPOC_PumpEvents(_THIS);
}
extern TBool isCursorVisible;