Added initial support for EPOC/Symbian OS (thanks Hannu!)
authorSam Lantinga <slouken@libsdl.org>
Tue, 11 Sep 2001 20:38:49 +0000
changeset 17383018110dce8
parent 172 37e3ca9254c7
child 174 da9a97f693a8
Added initial support for EPOC/Symbian OS (thanks Hannu!)
README.Epoc
docs.html
include/SDL_byteorder.h
include/SDL_main.h
include/SDL_types.h
include/begin_code.h
src/main/Makefile.am
src/main/epoc/SDL_main.cpp
src/thread/Makefile.am
src/thread/epoc/SDL_sysmutex.cpp
src/thread/epoc/SDL_syssem.cpp
src/thread/epoc/SDL_systhread.cpp
src/thread/epoc/SDL_systhread_c.h
src/timer/Makefile.am
src/timer/epoc/SDL_systimer.cpp
src/video/Makefile.am
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/epoc/SDL_epocevents.cpp
src/video/epoc/SDL_epocevents_c.h
src/video/epoc/SDL_epocvideo.cpp
src/video/epoc/SDL_epocvideo.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/README.Epoc	Tue Sep 11 20:38:49 2001 +0000
     1.3 @@ -0,0 +1,87 @@
     1.4 +31.8.2001 HJV
     1.5 +
     1.6 +SDL for EPOC/Symbian OS
     1.7 +=======================
     1.8 +
     1.9 +This is an Epoc port of SDL (1.2.0). It is not yet complete, but good enough for starting to port all those wonderful SDL based demos, games and other programs to Epoc! I have tested a bunch of demos and test programs in Nokia 9210 Communicator, which is a fancy device with combined PDA/GSM phone features, Symbian OS (Crystal), a full keyboard and a color screen (640x200x12bit).
    1.10 +
    1.11 +Btw. Also SDLDoom works over SDL Epoc port now (CDoom)!
    1.12 + 
    1.13 +
    1.14 +How to install to device
    1.15 +========================
    1.16 +
    1.17 +Extract binary packets of the demo and test programs and copy the files to N9210.
    1.18 +
    1.19 +
    1.20 +How to use
    1.21 +==========
    1.22 +
    1.23 +Run exe's from the File manager. The Caps lock key enables or disables the virtual cursor. 
    1.24 +The Esc key quits demo programs.
    1.25 +Function keys are mapped as follows: 
    1.26 +- F1=chr+q, F2=chr+w,..., F8=chr+i, 
    1.27 +- F9=chr+a,..., F12=chr+d.
    1.28 +
    1.29 +In Crystal, Exe programs do not appear in task list nor in Extras :-(
    1.30 +
    1.31 +
    1.32 +How to build
    1.33 +============
    1.34 +
    1.35 +Building SDL, SDL_IMAGE and tests & demos:
    1.36 +- Build files are in "\sdl\epoc\" and "\sdl_image\epoc\" directories
    1.37 +- Building as usual: "bldmake bldfiles" "abld build wins udeb" "abld build armi urel"
    1.38 +- Test and demos programs are build: "abld test build wins udeb" "abld test build armi urel" 
    1.39 +
    1.40 +
    1.41 +Building and sources
    1.42 +====================
    1.43 +Information about the Epoc implementation: 
    1.44 +- Made over SDL 1.2.0
    1.45 +- Ported sources: SDL, SDL_image, xflame, fire, warp, newvox, graywin, testalpha, SDLDoom(CDoom)
    1.46 +- Test programs do not have any major changes: usually only screen size and depth is 
    1.47 +  changed for 9210, if needed
    1.48 +- Like in all the other platform implementations, the Epoc specific code is in "Epoc" subdirectories. All build files for Epoc are in the directory \sdl\epoc\. Adding a new OS support requires always some changes also in generic files (search for "#ifdef __SYMBIAN32__").
    1.49 +- Currently, two resolutions and bit depths are supported: 320x200 and 640x200 with 8 or 12 bit color.
    1.50 +- I addition, two faked resolutions are supported: 640x400, 640x480. These are implemented by shrinking the screen vertically i.e. only every second scanline is drawn. This can be used for testing and for non-resource intensive programs. Thought, using faked resolutions is a waste of memory and cpu power! 
    1.51 +
    1.52 +Change history
    1.53 +==============
    1.54 +
    1.55 +31.8.2001 Alpha 0.2:
    1.56 +- Now you should build ARMI binaries instead of THUMB. It runs faster. 
    1.57 +- sdl_main.cpp: removed check for existing instance of sdlprogram
    1.58 +- sdl_error.h: Added debug macros under conditional compilation in Epoc
    1.59 +- sdl_epocevents.cpp: Added focus lost&gained event handling, added modifier handling, added a lot more key event handling (function keys and others). Function keys are mapped as follows: 
    1.60 +  F1=chr+q, F2=chr+w,..., F8=chr+i, F9=chr+a,..., F12=chr+d.
    1.61 +- sdl_epocvideo.h: Added EPOC_ScreenOffset variable. Added EPOC_IsWindowFocused variable (but not used for anything yet!). Added RedrawWindowL() function.
    1.62 +- sdl_epocvideo.cpp: Added debugging functions: Debug_AvailMem2() and Debug_AvailMem(). 
    1.63 +  Changed window to have white background. Centralize game screen if it is not full size. 
    1.64 +  Added RedrawWindowL() function. Force other windows to redraw if SDL window lost focus. This cleans up possible game graphics from screen. Redraw after getting focus again.
    1.65 +
    1.66 +
    1.67 +Todo
    1.68 +====
    1.69 +
    1.70 +This Epoc port is (of course;-) not thoroughly tested. For testing, I have compiled and run a couple of test programs and demos in N9210. Still, e.g. thread related functions have not been tested at all.
    1.71 +
    1.72 +Known bugs and unimplemented features:
    1.73 +- No sound
    1.74 +- No console output screen. Printing to stdout do not have any effect.
    1.75 +- Epoc do not allow static/global variables in DLL libraries. So I could only use static linking with SDL.
    1.76 +- Some test programs may take so much cpu in 9210 that e.g. SMS sending and receiving is not possible at a same time. Also screen may look awkward if there appear visible notes, dialogs etc. when an sdl program is active. SDL program runs in the lowest possible priority for minimum interference in the system. Unfortunately, this is always not enough.  Perhaps some Delay() commands are needed.
    1.77 +
    1.78 +P.s. I have ported also the SDL version of MirrorMagic puzzle game to Epoc. I will put the sources and binaries available as soon as I bother to clean the ported sources a bit... 
    1.79 +
    1.80 +
    1.81 +Open Source & "bazaar" style software development
    1.82 +=================================================
    1.83 +
    1.84 +You can take part in this porting project. This is Open Source software and you are very welcome to try it, test it, improve the code and implement the missing pieces. If you have any fix suggestions, improvements, code excerpts etc., contact me by email. Please start the mail subject with a string "EPOC SDL:".
    1.85 +
    1.86 +Cheers,
    1.87 +Hannu
    1.88 +
    1.89 +Mail:hannu.j.viitala@mbnet.fi
    1.90 +Homepage of SDL for Epoc: www.mbnet.fi/~haviital
     2.1 --- a/docs.html	Tue Sep 11 19:00:18 2001 +0000
     2.2 +++ b/docs.html	Tue Sep 11 20:38:49 2001 +0000
     2.3 @@ -16,6 +16,8 @@
     2.4  Major changes since SDL 1.0.0:
     2.5  </H2>
     2.6  <UL>
     2.7 +	<LI> 1.2.3: Added initial support for EPOC/Symbian OS (thanks Hannu!)
     2.8 +	<LI> 1.2.3: Improved MacOS X international keyboard handling
     2.9  	<LI> 1.2.3: Added support for DirectFB video on Linux (thanks Denis!)
    2.10  	<LI> 1.2.3: Fixed IDE and SCSI CD-ROM detection on BeOS (thanks Caz!)
    2.11  	<LI> 1.2.3: Fixed the system dependent SDL_WINDOWID hack on Windows
     3.1 --- a/include/SDL_byteorder.h	Tue Sep 11 19:00:18 2001 +0000
     3.2 +++ b/include/SDL_byteorder.h	Tue Sep 11 20:38:49 2001 +0000
     3.3 @@ -43,6 +43,7 @@
     3.4      (defined(__alpha__) || defined(__alpha)) || \
     3.5       defined(__arm__) || \
     3.6      (defined(__mips__) && defined(__MIPSEL__)) || \
     3.7 +     defined(__SYMBIAN32__) || \
     3.8       defined(__LITTLE_ENDIAN__)
     3.9  #define SDL_BYTEORDER	SDL_LIL_ENDIAN
    3.10  #else
     4.1 --- a/include/SDL_main.h	Tue Sep 11 19:00:18 2001 +0000
     4.2 +++ b/include/SDL_main.h	Tue Sep 11 20:38:49 2001 +0000
     4.3 @@ -31,7 +31,7 @@
     4.4  /* Redefine main() on Win32 and MacOS so that it is called by winmain.c */
     4.5  
     4.6  #if defined(WIN32) || (defined(__MWERKS__) && !defined(__BEOS__)) || \
     4.7 -    defined(macintosh) || defined(__APPLE__)
     4.8 +    defined(macintosh) || defined(__APPLE__) || defined(__SYMBIAN32__)
     4.9  
    4.10  #ifdef __cplusplus
    4.11  #define C_LINKAGE	"C"
     5.1 --- a/include/SDL_types.h	Tue Sep 11 19:00:18 2001 +0000
     5.2 +++ b/include/SDL_types.h	Tue Sep 11 20:38:49 2001 +0000
     5.3 @@ -54,6 +54,11 @@
     5.4  #endif
     5.5  #endif /* !__STRICT_ANSI__ */
     5.6  
     5.7 +/* The 64-bit type isn't available on EPOC/Symbian OS */
     5.8 +#ifdef __SYMBIAN32__
     5.9 +#undef SDL_HAS_64BIT_TYPE
    5.10 +#endif
    5.11 +
    5.12  /* The 64-bit datatype isn't supported on all platforms */
    5.13  #ifdef SDL_HAS_64BIT_TYPE
    5.14  typedef unsigned SDL_HAS_64BIT_TYPE Uint64;
     6.1 --- a/include/begin_code.h	Tue Sep 11 19:00:18 2001 +0000
     6.2 +++ b/include/begin_code.h	Tue Sep 11 20:38:49 2001 +0000
     6.3 @@ -48,6 +48,12 @@
     6.4  # endif
     6.5  #endif
     6.6  
     6.7 +/* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */
     6.8 +#ifdef __SYMBIAN32__ 
     6.9 +#undef DECLSPEC
    6.10 +#define DECLSPEC
    6.11 +#endif // __SYMBIAN32__
    6.12 +
    6.13  /* Force structure packing at 4 byte alignment.
    6.14     This is necessary if the header is included in code which has structure
    6.15     packing set to an alternate value, say for loading structures from disk.
     7.1 --- a/src/main/Makefile.am	Tue Sep 11 19:00:18 2001 +0000
     7.2 +++ b/src/main/Makefile.am	Tue Sep 11 20:38:49 2001 +0000
     7.3 @@ -6,8 +6,12 @@
     7.4  
     7.5  SUBDIRS = macosx
     7.6  
     7.7 -ARCH_SUBDIRS = $(srcdir)/beos $(srcdir)/linux \
     7.8 -               $(srcdir)/macos $(srcdir)/macosx $(srcdir)/win32
     7.9 +ARCH_SUBDIRS = $(srcdir)/beos \
    7.10 +               $(srcdir)/epoc \
    7.11 +               $(srcdir)/linux \
    7.12 +               $(srcdir)/macos \
    7.13 +               $(srcdir)/macosx \
    7.14 +               $(srcdir)/win32
    7.15  
    7.16  # Build a separate library containing the main() entry point.
    7.17  lib_LIBRARIES = libSDLmain.a
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/main/epoc/SDL_main.cpp	Tue Sep 11 20:38:49 2001 +0000
     8.3 @@ -0,0 +1,129 @@
     8.4 +/*
     8.5 +    SDL - Simple DirectMedia Layer
     8.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     8.7 +
     8.8 +    This library is free software; you can redistribute it and/or
     8.9 +    modify it under the terms of the GNU Library General Public
    8.10 +    License as published by the Free Software Foundation; either
    8.11 +    version 2 of the License, or (at your option) any later version.
    8.12 +
    8.13 +    This library is distributed in the hope that it will be useful,
    8.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.16 +    Library General Public License for more details.
    8.17 +
    8.18 +    You should have received a copy of the GNU Library General Public
    8.19 +    License along with this library; if not, write to the Free
    8.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.21 +
    8.22 +    Sam Lantinga
    8.23 +    slouken@devolution.com
    8.24 +*/
    8.25 +
    8.26 +/*
    8.27 +    SDL_main.cpp
    8.28 +    The Epoc executable startup functions 
    8.29 +
    8.30 +    Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
    8.31 +*/
    8.32 +
    8.33 +#include <e32std.h>
    8.34 +#include <e32def.h>
    8.35 +#include <e32svr.h>
    8.36 +#include <e32base.h>
    8.37 +#include <estlib.h>
    8.38 +#include <stdlib.h>
    8.39 +#include <stdio.h>
    8.40 +#include <w32std.h>
    8.41 +#include <apgtask.h>
    8.42 +
    8.43 +#include "SDL_error.h"
    8.44 +
    8.45 +#ifndef EXPORT_C
    8.46 +# ifdef __VC32__
    8.47 +#  define IMPORT_C __declspec(dllexport)
    8.48 +#  define EXPORT_C __declspec(dllexport)
    8.49 +# endif
    8.50 +# ifdef __GCC32__
    8.51 +#  define IMPORT_C
    8.52 +#  define EXPORT_C __declspec(dllexport)
    8.53 +# endif
    8.54 +#endif
    8.55 +
    8.56 +#if defined(__WINS__)
    8.57 +#include <estw32.h>
    8.58 +IMPORT_C void RegisterWsExe(const TDesC &aName);
    8.59 +#endif
    8.60 +
    8.61 +/* The prototype for the application's main() function */
    8.62 +#define main	SDL_main
    8.63 +extern "C" int main (int argc, char *argv[], char *envp[]);
    8.64 +extern "C" void exit (int ret);
    8.65 +
    8.66 +
    8.67 +/* Epoc main function */
    8.68 +
    8.69 +GLDEF_C TInt E32Main() 
    8.70 +    {
    8.71 +    /*  Get the clean-up stack */
    8.72 +	CTrapCleanup* cleanup = CTrapCleanup::New();
    8.73 +
    8.74 +    #if defined(__WINS__)
    8.75 +    /* arrange for access to Win32 stdin/stdout/stderr */
    8.76 +   	RWin32Stream::StartServer();	
    8.77 +    #endif
    8.78 +
    8.79 +    /* Arrange for multi-threaded operation */
    8.80 +	SpawnPosixServerThread();	
    8.81 +
    8.82 +    /* Get args and environment */
    8.83 +	int argc=0;
    8.84 +	char** argv=0;
    8.85 +	char** envp=0;
    8.86 +	__crt0(argc,argv,envp);	
    8.87 +
    8.88 +    #if defined(__WINS__)
    8.89 +	/* Cause the graphical Window Server to come into existence */
    8.90 +	RSemaphore sem;
    8.91 +	sem.CreateGlobal(_L("WsExeSem"),0);
    8.92 +	RegisterWsExe(sem.FullName());
    8.93 +    #endif
    8.94 +
    8.95 +
    8.96 +    /* Start the application! */
    8.97 +
    8.98 +    /* Create stdlib */
    8.99 +    _REENT;
   8.100 +
   8.101 +    /* Set process and thread priority */
   8.102 +    RThread currentThread;
   8.103 +
   8.104 +    currentThread.Rename(_L("SdlProgram"));
   8.105 +    currentThread.SetProcessPriority(EPriorityLow);
   8.106 +    currentThread.SetPriority(EPriorityMuchLess);
   8.107 +
   8.108 +    /* Call stdlib main */
   8.109 +    int ret = main(argc, argv, envp); /* !! process exits here if there is "exit()" in main! */	
   8.110 +
   8.111 +    /* Call exit */
   8.112 +    exit(ret); /* !! process exits here! */			
   8.113 +
   8.114 +    /* Free resources and return */
   8.115 +    CloseSTDLIB();
   8.116 +   	delete cleanup;									
   8.117 +    return(KErrNone);
   8.118 +    }
   8.119 +
   8.120 +/* Epoc dll entry point */
   8.121 +#if defined(__WINS__)
   8.122 +GLDEF_C TInt E32Dll(TDllReason)
   8.123 +	{
   8.124 +	return(KErrNone);
   8.125 +	}
   8.126 +
   8.127 +EXPORT_C TInt WinsMain(TAny *)
   8.128 +	{
   8.129 +    E32Main();
   8.130 +	return KErrNone;
   8.131 +	}
   8.132 +#endif
     9.1 --- a/src/thread/Makefile.am	Tue Sep 11 19:00:18 2001 +0000
     9.2 +++ b/src/thread/Makefile.am	Tue Sep 11 20:38:49 2001 +0000
     9.3 @@ -3,8 +3,13 @@
     9.4  
     9.5  noinst_LTLIBRARIES = libthread.la
     9.6  
     9.7 -ARCH_SUBDIRS = $(srcdir)/generic $(srcdir)/amigaos $(srcdir)/beos \
     9.8 -	$(srcdir)/irix $(srcdir)/linux $(srcdir)/win32
     9.9 +ARCH_SUBDIRS = $(srcdir)/generic \
    9.10 +               $(srcdir)/amigaos \
    9.11 +               $(srcdir)/beos \
    9.12 +               $(srcdir)/epoc \
    9.13 +               $(srcdir)/irix \
    9.14 +               $(srcdir)/linux \
    9.15 +               $(srcdir)/win32
    9.16  
    9.17  # Older versions of Linux require an asm clone() implementation
    9.18  if USE_CLONE
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/thread/epoc/SDL_sysmutex.cpp	Tue Sep 11 20:38:49 2001 +0000
    10.3 @@ -0,0 +1,112 @@
    10.4 +/*
    10.5 +    SDL - Simple DirectMedia Layer
    10.6 +    Copyright (C) 1997, 1998, 1999, 2000  Sam Lantinga
    10.7 +
    10.8 +    This library is free software; you can redistribute it and/or
    10.9 +    modify it under the terms of the GNU Library General Public
   10.10 +    License as published by the Free Software Foundation; either
   10.11 +    version 2 of the License, or (at your option) any later version.
   10.12 +
   10.13 +    This library is distributed in the hope that it will be useful,
   10.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   10.16 +    Library General Public License for more details.
   10.17 +
   10.18 +    You should have received a copy of the GNU Library General Public
   10.19 +    License along with this library; if not, write to the Free
   10.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   10.21 +
   10.22 +    Sam Lantinga
   10.23 +    slouken@devolution.com
   10.24 +*/
   10.25 +
   10.26 +/*
   10.27 +    SDL_sysmutex.cpp
   10.28 +
   10.29 +    Epoc version by Markus Mertama (w@iki.fi)
   10.30 +*/
   10.31 +
   10.32 +
   10.33 +#ifdef SAVE_RCSID
   10.34 +static char rcsid =
   10.35 + "@(#) $Id$";
   10.36 +#endif
   10.37 +
   10.38 +/* Mutex functions using the Win32 API */
   10.39 +
   10.40 +//#include <stdio.h>
   10.41 +//#include <stdlib.h>
   10.42 +
   10.43 +#include<e32std.h>
   10.44 +
   10.45 +#include "SDL_error.h"
   10.46 +#include "SDL_mutex.h"
   10.47 +
   10.48 +
   10.49 +
   10.50 +struct SDL_mutex
   10.51 +    {
   10.52 +    TInt handle;
   10.53 +    };
   10.54 +
   10.55 +extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
   10.56 +
   10.57 +TInt NewMutex(const TDesC& aName, TAny* aPtr1, TAny*)
   10.58 +    {
   10.59 +    return ((RMutex*)aPtr1)->CreateGlobal(aName);
   10.60 +    }
   10.61 +
   10.62 +/* Create a mutex */
   10.63 +SDL_mutex *SDL_CreateMutex(void)
   10.64 +{
   10.65 +    RMutex rmutex;
   10.66 +
   10.67 +    TInt status = CreateUnique(NewMutex, &rmutex, NULL);
   10.68 +	if(status != KErrNone)
   10.69 +	    {
   10.70 +			SDL_SetError("Couldn't create mutex");
   10.71 +		}
   10.72 +    SDL_mutex* mutex = new /*(ELeave)*/ SDL_mutex;
   10.73 +    mutex->handle = rmutex.Handle();
   10.74 +	return(mutex);
   10.75 +}
   10.76 +
   10.77 +/* Free the mutex */
   10.78 +void SDL_DestroyMutex(SDL_mutex *mutex)
   10.79 +{
   10.80 +	if ( mutex ) 
   10.81 +	{
   10.82 +    RMutex rmutex;
   10.83 +    rmutex.SetHandle(mutex->handle);
   10.84 +	rmutex.Signal();
   10.85 +	rmutex.Close();
   10.86 +	delete(mutex);
   10.87 +    mutex = NULL;
   10.88 +	}
   10.89 +}
   10.90 +
   10.91 +/* Lock the mutex */
   10.92 +int SDL_mutexP(SDL_mutex *mutex)
   10.93 +{
   10.94 +	if ( mutex == NULL ) {
   10.95 +		SDL_SetError("Passed a NULL mutex");
   10.96 +		return -1;
   10.97 +	}
   10.98 +    RMutex rmutex;
   10.99 +    rmutex.SetHandle(mutex->handle);
  10.100 +	rmutex.Wait(); 
  10.101 +	return(0);
  10.102 +}
  10.103 +
  10.104 +/* Unlock the mutex */
  10.105 +int SDL_mutexV(SDL_mutex *mutex)
  10.106 +{
  10.107 +	if ( mutex == NULL ) {
  10.108 +		SDL_SetError("Passed a NULL mutex");
  10.109 +		return -1;
  10.110 +	}
  10.111 +	RMutex rmutex;
  10.112 +    rmutex.SetHandle(mutex->handle);
  10.113 +	rmutex.Signal();
  10.114 +	return(0);
  10.115 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/thread/epoc/SDL_syssem.cpp	Tue Sep 11 20:38:49 2001 +0000
    11.3 @@ -0,0 +1,199 @@
    11.4 +/*
    11.5 +    SDL - Simple DirectMedia Layer
    11.6 +    Copyright (C) 1997, 1998, 1999, 2000  Sam Lantinga
    11.7 +
    11.8 +    This library is free software; you can redistribute it and/or
    11.9 +    modify it under the terms of the GNU Library General Public
   11.10 +    License as published by the Free Software Foundation; either
   11.11 +    version 2 of the License, or (at your option) any later version.
   11.12 +
   11.13 +    This library is distributed in the hope that it will be useful,
   11.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   11.16 +    Library General Public License for more details.
   11.17 +
   11.18 +    You should have received a copy of the GNU Library General Public
   11.19 +    License along with this library; if not, write to the Free
   11.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   11.21 +
   11.22 +    Sam Lantinga
   11.23 +    slouken@devolution.com
   11.24 +*/
   11.25 +
   11.26 +/*
   11.27 +    SDL_syssem.cpp
   11.28 +
   11.29 +    Epoc version by Markus Mertama  (w@iki.fi)
   11.30 +*/
   11.31 +
   11.32 +#ifdef SAVE_RCSID
   11.33 +static char rcsid =
   11.34 + "@(#) $Id$";
   11.35 +#endif
   11.36 +
   11.37 +/* Semaphore functions using the Win32 API */
   11.38 +
   11.39 +//#include <stdio.h>
   11.40 +//#include <stdlib.h>
   11.41 +#include <e32std.h>
   11.42 +
   11.43 +#include "SDL_error.h"
   11.44 +#include "SDL_thread.h"
   11.45 +
   11.46 +
   11.47 +#define SDL_MUTEX_TIMEOUT -2
   11.48 +
   11.49 +struct SDL_semaphore
   11.50 + {
   11.51 + TInt handle;
   11.52 + TInt count;
   11.53 + };
   11.54 +
   11.55 +extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
   11.56 +extern TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2);
   11.57 +
   11.58 +TInt NewSema(const TDesC& aName, TAny* aPtr1, TAny* aPtr2) 
   11.59 +    {
   11.60 +    TInt value = *((TInt*) aPtr2);
   11.61 +    return ((RSemaphore*)aPtr1)->CreateGlobal(aName, value);
   11.62 +    }
   11.63 +
   11.64 +/* Create a semaphore */
   11.65 +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
   11.66 +{
   11.67 +   RSemaphore s;
   11.68 +   TInt status = CreateUnique(NewSema, &s, &initial_value);
   11.69 +   if(status != KErrNone)
   11.70 +	 {
   11.71 +			SDL_SetError("Couldn't create semaphore");
   11.72 +	}
   11.73 +    SDL_semaphore* sem = new /*(ELeave)*/ SDL_semaphore;  
   11.74 +    sem->handle = s.Handle();
   11.75 +	sem->count = initial_value;
   11.76 +	return(sem);
   11.77 +}
   11.78 +
   11.79 +/* Free the semaphore */
   11.80 +void SDL_DestroySemaphore(SDL_sem *sem)
   11.81 +{
   11.82 +	if ( sem ) 
   11.83 +	{
   11.84 +    RSemaphore sema;
   11.85 +    sema.SetHandle(sem->handle);
   11.86 +	sema.Signal(sema.Count());
   11.87 +    sema.Close();
   11.88 +    delete sem;
   11.89 +	sem = NULL;
   11.90 +	}
   11.91 +}
   11.92 +
   11.93 +
   11.94 +  struct TInfo
   11.95 +    {
   11.96 +        TInfo(TInt aTime, TInt aHandle) : 
   11.97 +        iTime(aTime), iHandle(aHandle), iVal(0) {}
   11.98 +        TInt iTime;
   11.99 +        TInt iHandle;
  11.100 +        TInt iVal; 
  11.101 +    };
  11.102 +
  11.103 +TBool ThreadRun(TAny* aInfo)
  11.104 +    {
  11.105 +        TInfo* info = STATIC_CAST(TInfo*, aInfo);
  11.106 +        User::After(info->iTime);
  11.107 +        RSemaphore sema;
  11.108 +        sema.SetHandle(info->iHandle);
  11.109 +        sema.Signal();
  11.110 +        info->iVal = SDL_MUTEX_TIMEOUT;
  11.111 +        return 0;
  11.112 +    }
  11.113 +    
  11.114 +  
  11.115 +    
  11.116 +    
  11.117 +void _WaitAll(SDL_sem *sem)
  11.118 +    {
  11.119 +       //since SemTryWait may changed the counter.
  11.120 +       //this may not be atomic, but hopes it works.
  11.121 +    RSemaphore sema;
  11.122 +    sema.SetHandle(sem->handle);
  11.123 +    sema.Wait();
  11.124 +    while(sem->count < 0)
  11.125 +        {
  11.126 +        sema.Wait();
  11.127 +        }    
  11.128 +    }
  11.129 +
  11.130 +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
  11.131 +{
  11.132 +	if ( ! sem ) {
  11.133 +		SDL_SetError("Passed a NULL sem");
  11.134 +		return -1;
  11.135 +	}
  11.136 +
  11.137 +	if ( timeout == SDL_MUTEX_MAXWAIT )
  11.138 +	    {
  11.139 +	    _WaitAll(sem);
  11.140 +		return SDL_MUTEX_MAXWAIT;
  11.141 +	    } 
  11.142 +	
  11.143 +	
  11.144 +	RThread thread;
  11.145 +	
  11.146 +	TInfo* info = new (ELeave)TInfo(timeout, sem->handle);
  11.147 +	
  11.148 +    TInt status = CreateUnique(NewThread, &thread, info);
  11.149 +  
  11.150 +	if(status != KErrNone)
  11.151 +	    return status;
  11.152 +	
  11.153 +	thread.Resume();
  11.154 +	
  11.155 +	_WaitAll(sem);
  11.156 +	
  11.157 +	if(thread.ExitType() == EExitPending)
  11.158 +	    {
  11.159 +	        thread.Kill(SDL_MUTEX_TIMEOUT);
  11.160 +	    }
  11.161 +	
  11.162 +	thread.Close();
  11.163 +	
  11.164 +	return info->iVal;
  11.165 +}
  11.166 +
  11.167 +int SDL_SemTryWait(SDL_sem *sem)
  11.168 +{
  11.169 +    if(sem->count > 0)
  11.170 +        {
  11.171 +        sem->count--;
  11.172 +        }
  11.173 +    return SDL_MUTEX_TIMEOUT;
  11.174 +}
  11.175 +
  11.176 +int SDL_SemWait(SDL_sem *sem)
  11.177 +{
  11.178 +	return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
  11.179 +}
  11.180 +
  11.181 +/* Returns the current count of the semaphore */
  11.182 +Uint32 SDL_SemValue(SDL_sem *sem)
  11.183 +{
  11.184 +	if ( ! sem ) {
  11.185 +		SDL_SetError("Passed a NULL sem");
  11.186 +		return 0;
  11.187 +	}
  11.188 +	return sem->count;
  11.189 +}
  11.190 +
  11.191 +int SDL_SemPost(SDL_sem *sem)
  11.192 +{
  11.193 +	if ( ! sem ) {
  11.194 +		SDL_SetError("Passed a NULL sem");
  11.195 +		return -1;
  11.196 +	}
  11.197 +	sem->count++;
  11.198 +    RSemaphore sema;
  11.199 +    sema.SetHandle(sem->handle);
  11.200 +	sema.Signal();
  11.201 +	return 0;
  11.202 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/thread/epoc/SDL_systhread.cpp	Tue Sep 11 20:38:49 2001 +0000
    12.3 @@ -0,0 +1,127 @@
    12.4 +/*
    12.5 +    SDL - Simple DirectMedia Layer
    12.6 +    Copyright (C) 1997, 1998, 1999, 2000  Sam Lantinga
    12.7 +
    12.8 +    This library is free software; you can redistribute it and/or
    12.9 +    modify it under the terms of the GNU Library General Public
   12.10 +    License as published by the Free Software Foundation; either
   12.11 +    version 2 of the License, or (at your option) any later version.
   12.12 +
   12.13 +    This library is distributed in the hope that it will be useful,
   12.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12.16 +    Library General Public License for more details.
   12.17 +
   12.18 +    You should have received a copy of the GNU Library General Public
   12.19 +    License along with this library; if not, write to the Free
   12.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   12.21 +
   12.22 +    Sam Lantinga
   12.23 +    slouken@devolution.com
   12.24 +*/
   12.25 +
   12.26 +/*
   12.27 +    SDL_systhread.cpp
   12.28 +    Epoc thread management routines for SDL
   12.29 +
   12.30 +    Epoc version by Markus Mertama  (w@iki.fi)
   12.31 +*/
   12.32 +
   12.33 +
   12.34 +//#include <stdlib.h>
   12.35 +//#include <stdio.h>
   12.36 +
   12.37 +
   12.38 +extern "C" {
   12.39 +#undef NULL
   12.40 +#include "SDL_error.h"
   12.41 +#include "SDL_thread.h"
   12.42 +#include "SDL_systhread.h"
   12.43 +    };
   12.44 +
   12.45 +#include <e32std.h>
   12.46 +
   12.47 +
   12.48 +static int object_count;
   12.49 +
   12.50 +int RunThread(TAny* data)
   12.51 +{
   12.52 +	SDL_RunThread(data);
   12.53 +	return(0);
   12.54 +}
   12.55 +
   12.56 +
   12.57 +TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
   12.58 +    {
   12.59 +    return ((RThread*)(aPtr1))->Create(aName,
   12.60 +            RunThread,
   12.61 +            KDefaultStackSize,
   12.62 +            NULL,
   12.63 +            aPtr2);
   12.64 +    }
   12.65 +
   12.66 +int CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny* aPtr1, TAny* aPtr2)
   12.67 +    {
   12.68 +    TBuf<16> name;
   12.69 +    TInt status = KErrNone;
   12.70 +    do
   12.71 +        {
   12.72 +        object_count++;
   12.73 +        name.Format(_L("SDL_%x"), object_count);
   12.74 +        status = aFunc(name, aPtr1, aPtr2);
   12.75 +        }
   12.76 +        while(status == KErrAlreadyExists);
   12.77 +    return status;
   12.78 +    }
   12.79 +
   12.80 +
   12.81 +int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
   12.82 +{
   12.83 +    RThread rthread;
   12.84 +   
   12.85 +    TInt status = CreateUnique(NewThread, &rthread, args);
   12.86 +    if (status != KErrNone) 
   12.87 +    {
   12.88 +        delete(((RThread*)(thread->handle)));
   12.89 +        thread->handle = NULL;
   12.90 +		SDL_SetError("Not enough resources to create thread");
   12.91 +		return(-1);
   12.92 +	}
   12.93 +	rthread.Resume();
   12.94 +    thread->handle = rthread.Handle();
   12.95 +	return(0);
   12.96 +}
   12.97 +
   12.98 +void SDL_SYS_SetupThread(void)
   12.99 +{
  12.100 +	return;
  12.101 +}
  12.102 +
  12.103 +Uint32 SDL_ThreadID(void)
  12.104 +{
  12.105 +    RThread current;
  12.106 +    TThreadId id = current.Id();
  12.107 +	return id;
  12.108 +}
  12.109 +
  12.110 +void SDL_SYS_WaitThread(SDL_Thread *thread)
  12.111 +{
  12.112 +    RUndertaker taker;
  12.113 +    taker.Create();
  12.114 +    TRequestStatus status;
  12.115 +    taker.Logon(status, thread->handle);
  12.116 +    User::WaitForRequest(status);
  12.117 +    taker.Close();
  12.118 +}
  12.119 +
  12.120 +/* WARNING: This function is really a last resort.
  12.121 + * Threads should be signaled and then exit by themselves.
  12.122 + * TerminateThread() doesn't perform stack and DLL cleanup.
  12.123 + */
  12.124 +void SDL_SYS_KillThread(SDL_Thread *thread)
  12.125 +{
  12.126 +    RThread rthread;
  12.127 +    rthread.SetHandle(thread->handle);
  12.128 +	rthread.Kill(0);
  12.129 +	rthread.Close();
  12.130 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/thread/epoc/SDL_systhread_c.h	Tue Sep 11 20:38:49 2001 +0000
    13.3 @@ -0,0 +1,30 @@
    13.4 +/*
    13.5 +    SDL - Simple DirectMedia Layer
    13.6 +    Copyright (C) 1997, 1998, 1999, 2000  Sam Lantinga
    13.7 +
    13.8 +    This library is free software; you can redistribute it and/or
    13.9 +    modify it under the terms of the GNU Library General Public
   13.10 +    License as published by the Free Software Foundation; either
   13.11 +    version 2 of the License, or (at your option) any later version.
   13.12 +
   13.13 +    This library is distributed in the hope that it will be useful,
   13.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13.16 +    Library General Public License for more details.
   13.17 +
   13.18 +    You should have received a copy of the GNU Library General Public
   13.19 +    License along with this library; if not, write to the Free
   13.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   13.21 +
   13.22 +    Sam Lantinga
   13.23 +    slouken@devolution.com
   13.24 +*/
   13.25 +
   13.26 +/*
   13.27 +    SDL_systhread_c.h
   13.28 +
   13.29 +    Epoc version by Markus Mertama (w@iki.fi)
   13.30 +*/
   13.31 +
   13.32 +typedef int SYS_ThreadHandle;
   13.33 +
    14.1 --- a/src/timer/Makefile.am	Tue Sep 11 19:00:18 2001 +0000
    14.2 +++ b/src/timer/Makefile.am	Tue Sep 11 20:38:49 2001 +0000
    14.3 @@ -3,8 +3,12 @@
    14.4  
    14.5  noinst_LTLIBRARIES = libtimer.la
    14.6  
    14.7 -ARCH_SUBDIRS = $(srcdir)/amigaos $(srcdir)/beos $(srcdir)/linux \
    14.8 -	$(srcdir)/macos $(srcdir)/win32
    14.9 +ARCH_SUBDIRS = $(srcdir)/amigaos \
   14.10 +               $(srcdir)/beos \
   14.11 +               $(srcdir)/epoc \
   14.12 +               $(srcdir)/linux \
   14.13 +               $(srcdir)/macos \
   14.14 +               $(srcdir)/win32
   14.15  
   14.16  # Include the architecture-independent sources
   14.17  COMMON_SRCS = SDL_timer.c SDL_timer_c.h SDL_systimer.h
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/timer/epoc/SDL_systimer.cpp	Tue Sep 11 20:38:49 2001 +0000
    15.3 @@ -0,0 +1,111 @@
    15.4 +/*
    15.5 +    SDL - Simple DirectMedia Layer
    15.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
    15.7 +
    15.8 +    This library is free software; you can redistribute it and/or
    15.9 +    modify it under the terms of the GNU Library General Public
   15.10 +    License as published by the Free Software Foundation; either
   15.11 +    version 2 of the License, or (at your option) any later version.
   15.12 +
   15.13 +    This library is distributed in the hope that it will be useful,
   15.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15.16 +    Library General Public License for more details.
   15.17 +
   15.18 +    You should have received a copy of the GNU Library General Public
   15.19 +    License along with this library; if not, write to the Free
   15.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   15.21 +
   15.22 +    Sam Lantinga
   15.23 +    slouken@devolution.com
   15.24 +*/
   15.25 +
   15.26 +/*
   15.27 +    SDL_systimer.cpp
   15.28 +
   15.29 +    Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
   15.30 +*/
   15.31 +
   15.32 +#include <e32std.h>
   15.33 +#include <e32hal.h>
   15.34 +
   15.35 +extern "C" {
   15.36 +#include "SDL_error.h"
   15.37 +#include "SDL_thread.h"
   15.38 +#include "SDL_timer.h"
   15.39 +#include "SDL_timer_c.h"
   15.40 +
   15.41 +static TUint start = 0;
   15.42 +static TInt tickPeriodMilliSeconds;
   15.43 +
   15.44 +
   15.45 +void SDL_StartTicks(void)
   15.46 +{
   15.47 +	/* Set first ticks value */
   15.48 +    start = User::TickCount();
   15.49 +
   15.50 +    TTimeIntervalMicroSeconds32 period;
   15.51 +	TInt tmp = UserHal::TickPeriod(period);
   15.52 +    tickPeriodMilliSeconds = period.Int() / 1000;
   15.53 +}
   15.54 +
   15.55 +Uint32 SDL_GetTicks(void)
   15.56 +{
   15.57 +    TUint deltaTics = User::TickCount() - start;
   15.58 +	return(deltaTics * tickPeriodMilliSeconds); 
   15.59 +}
   15.60 +
   15.61 +void SDL_Delay(Uint32 ms)
   15.62 +{
   15.63 +     
   15.64 +    User::After(TTimeIntervalMicroSeconds32(ms*1000));
   15.65 +}
   15.66 +
   15.67 +/* Data to handle a single periodic alarm */
   15.68 +static int timer_alive = 0;
   15.69 +static SDL_Thread *timer = NULL;
   15.70 +
   15.71 +static int RunTimer(void *unused)
   15.72 +{
   15.73 +	Uint32 ms;
   15.74 +
   15.75 +	while ( timer_alive ) {
   15.76 +		if ( SDL_timer_running ) {
   15.77 +			SDL_ThreadedTimerCheck();
   15.78 +		}
   15.79 +		SDL_Delay(10);
   15.80 +	}
   15.81 +	return(0);
   15.82 +}
   15.83 +
   15.84 +/* This is only called if the event thread is not running */
   15.85 +int SDL_SYS_TimerInit(void)
   15.86 +{
   15.87 +	timer_alive = 1;
   15.88 +	timer = SDL_CreateThread(RunTimer, NULL);
   15.89 +	if ( timer == NULL )
   15.90 +		return(-1);
   15.91 +	return(SDL_SetTimerThreaded(1));
   15.92 +}
   15.93 +
   15.94 +void SDL_SYS_TimerQuit(void)
   15.95 +{
   15.96 +	timer_alive = 0;
   15.97 +	if ( timer ) {
   15.98 +		SDL_WaitThread(timer, NULL);
   15.99 +		timer = NULL;
  15.100 +	}
  15.101 +}
  15.102 +
  15.103 +int SDL_SYS_StartTimer(void)
  15.104 +{
  15.105 +	SDL_SetError("Internal logic error: Epoc uses threaded timer");
  15.106 +	return(-1);
  15.107 +}
  15.108 +
  15.109 +void SDL_SYS_StopTimer(void)
  15.110 +{
  15.111 +	return;
  15.112 +}
  15.113 +
  15.114 +}; // extern "C"
    16.1 --- a/src/video/Makefile.am	Tue Sep 11 19:00:18 2001 +0000
    16.2 +++ b/src/video/Makefile.am	Tue Sep 11 20:38:49 2001 +0000
    16.3 @@ -8,7 +8,7 @@
    16.4  DIST_SUBDIRS = dummy x11 dga nanox fbcon directfb vgl svga ggi aalib \
    16.5                 wincommon windib windx5 \
    16.6                 maccommon macdsp macrom quartz \
    16.7 -               bwindow ps2gs photon cybergfx
    16.8 +               bwindow ps2gs photon cybergfx epoc
    16.9  
   16.10  DRIVERS = @VIDEO_DRIVERS@
   16.11  
    17.1 --- a/src/video/SDL_sysvideo.h	Tue Sep 11 19:00:18 2001 +0000
    17.2 +++ b/src/video/SDL_sysvideo.h	Tue Sep 11 20:38:49 2001 +0000
    17.3 @@ -364,12 +364,6 @@
    17.4  #ifdef ENABLE_BWINDOW
    17.5  extern VideoBootStrap BWINDOW_bootstrap;
    17.6  #endif
    17.7 -#ifdef ENABLE_DUMMYVIDEO
    17.8 -extern VideoBootStrap DUMMY_bootstrap;
    17.9 -#endif
   17.10 -#ifdef ENABLE_PHOTON
   17.11 -extern VideoBootStrap ph_bootstrap;
   17.12 -#endif
   17.13  /* MacOS X gets the proper defines from configure */
   17.14  #if defined(macintosh) && !defined(MACOSX)
   17.15  #define ENABLE_TOOLBOX
   17.16 @@ -389,6 +383,15 @@
   17.17  #ifdef ENABLE_CYBERGRAPHICS
   17.18  extern VideoBootStrap CGX_bootstrap;
   17.19  #endif
   17.20 +#ifdef ENABLE_PHOTON
   17.21 +extern VideoBootStrap ph_bootstrap;
   17.22 +#endif
   17.23 +#ifdef ENABLE_EPOC
   17.24 +extern VideoBootStrap EPOC_bootstrap;
   17.25 +#endif
   17.26 +#ifdef ENABLE_DUMMYVIDEO
   17.27 +extern VideoBootStrap DUMMY_bootstrap;
   17.28 +#endif
   17.29  /* This is the current video device */
   17.30  extern SDL_VideoDevice *current_video;
   17.31  
    18.1 --- a/src/video/SDL_video.c	Tue Sep 11 19:00:18 2001 +0000
    18.2 +++ b/src/video/SDL_video.c	Tue Sep 11 20:38:49 2001 +0000
    18.3 @@ -96,14 +96,18 @@
    18.4  #ifdef ENABLE_CYBERGRAPHICS
    18.5  	&CGX_bootstrap,
    18.6  #endif
    18.7 +#ifdef ENABLE_PHOTON
    18.8 +	&ph_bootstrap,
    18.9 +#endif
   18.10 +#ifdef ENABLE_EPOC
   18.11 +	&EPOC_bootstrap,
   18.12 +#endif
   18.13  #ifdef ENABLE_DUMMYVIDEO
   18.14  	&DUMMY_bootstrap,
   18.15  #endif
   18.16 -#ifdef ENABLE_PHOTON
   18.17 -	&ph_bootstrap,
   18.18 -#endif
   18.19  	NULL
   18.20  };
   18.21 +
   18.22  SDL_VideoDevice *current_video = NULL;
   18.23  
   18.24  /* Various local functions */
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/video/epoc/SDL_epocevents.cpp	Tue Sep 11 20:38:49 2001 +0000
    19.3 @@ -0,0 +1,418 @@
    19.4 +/*
    19.5 +    SDL - Simple DirectMedia Layer
    19.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
    19.7 +
    19.8 +    This library is free software; you can redistribute it and/or
    19.9 +    modify it under the terms of the GNU Library General Public
   19.10 +    License as published by the Free Software Foundation; either
   19.11 +    version 2 of the License, or (at your option) any later version.
   19.12 +
   19.13 +    This library is distributed in the hope that it will be useful,
   19.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   19.16 +    Library General Public License for more details.
   19.17 +
   19.18 +    You should have received a copy of the GNU Library General Public
   19.19 +    License along with this library; if not, write to the Free
   19.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19.21 +
   19.22 +    Sam Lantinga
   19.23 +    slouken@devolution.com
   19.24 +*/
   19.25 +
   19.26 +/*
   19.27 +    SDL_epocevents.cpp
   19.28 +    Handle the event stream, converting Epoc events into SDL events
   19.29 +
   19.30 +    Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
   19.31 +*/
   19.32 +
   19.33 +
   19.34 +#include <stdio.h>
   19.35 +#undef NULL
   19.36 +
   19.37 +extern "C" {
   19.38 +#include "SDL_error.h"
   19.39 +#include "SDL_video.h"
   19.40 +#include "SDL_keysym.h"
   19.41 +#include "SDL_keyboard.h"
   19.42 +#include "SDL_events_c.h"
   19.43 +#include "SDL_timer.h"
   19.44 +}; /* extern "C" */
   19.45 +
   19.46 +#include "SDL_epocvideo.h"
   19.47 +#include "SDL_epocevents_c.h"
   19.48 +
   19.49 +#include <hal.h>
   19.50 +
   19.51 +extern "C" {
   19.52 +/* The translation tables from a console scancode to a SDL keysym */
   19.53 +static SDLKey keymap[MAX_SCANCODE];
   19.54 +static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym);
   19.55 +}; /* extern "C" */
   19.56 +
   19.57 +TBool isCursorVisible = ETrue;
   19.58 +
   19.59 +int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
   19.60 +{
   19.61 +    int posted = 0;
   19.62 +    SDL_keysym keysym;
   19.63 +
   19.64 +
   19.65 +    switch (aWsEvent.Type()) {
   19.66 +    
   19.67 +    case EEventPointer: /* Mouse pointer events */
   19.68 +    {
   19.69 +        const TPointerEvent* pointerEvent = aWsEvent.Pointer();
   19.70 +        TPoint mousePos = pointerEvent->iPosition;
   19.71 +
   19.72 +        //SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
   19.73 +
   19.74 +        if (Private->EPOC_ShrinkedHeight) {
   19.75 +            mousePos.iY <<= 1; /* Scale y coordinate to shrinked screen height */
   19.76 +        }
   19.77 +		posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
   19.78 +        if (pointerEvent->iType==TPointerEvent::EButton1Down) {
   19.79 +            posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
   19.80 +        }
   19.81 +        else if (pointerEvent->iType==TPointerEvent::EButton1Up) {
   19.82 +			posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
   19.83 +        }
   19.84 +        else if (pointerEvent->iType==TPointerEvent::EButton2Down) {
   19.85 +            posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
   19.86 +        }
   19.87 +        else if (pointerEvent->iType==TPointerEvent::EButton2Up) {
   19.88 +			posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
   19.89 +        }
   19.90 +	    //!!posted += SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(aWsEvent.Key()->iScanCode, &keysym));
   19.91 +        break;
   19.92 +    }
   19.93 +    
   19.94 +    case EEventKeyDown: /* Key events */
   19.95 +    {
   19.96 +       (void*)TranslateKey(aWsEvent.Key()->iScanCode, &keysym);
   19.97 +        
   19.98 +        /* Special handling */
   19.99 +        switch((int)keysym.sym) {
  19.100 +        case SDLK_CAPSLOCK:
  19.101 +            if (!isCursorVisible) {
  19.102 +                /* Enable virtual cursor */
  19.103 +	            HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
  19.104 +            }
  19.105 +            else {
  19.106 +                /* Disable virtual cursor */
  19.107 +                HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
  19.108 +            }
  19.109 +            isCursorVisible = !isCursorVisible;
  19.110 +            break;
  19.111 +        }
  19.112 +        
  19.113 +	    posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
  19.114 +        break;
  19.115 +	} 
  19.116 +
  19.117 +    case EEventKeyUp: /* Key events */
  19.118 +    {
  19.119 +	    posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(aWsEvent.Key()->iScanCode, &keysym));
  19.120 +        break;
  19.121 +	} 
  19.122 +    
  19.123 +    case EEventFocusGained: /* SDL window got focus */
  19.124 +    {
  19.125 +        //Private->EPOC_IsWindowFocused = ETrue;
  19.126 +        /* Draw window background and screen buffer */
  19.127 +        RedrawWindowL(_this);  
  19.128 +        break;
  19.129 +    }
  19.130 +
  19.131 +    case EEventFocusLost: /* SDL window lost focus */
  19.132 +    {
  19.133 +        //Private->EPOC_IsWindowFocused = EFalse;
  19.134 +
  19.135 +        // Wait and eat events until focus is gained again
  19.136 +        /*
  19.137 +	    while (ETrue) {
  19.138 +            Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
  19.139 +            User::WaitForRequest(Private->EPOC_WsEventStatus);
  19.140 +		    Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
  19.141 +            TInt eventType = Private->EPOC_WsEvent.Type();
  19.142 +		    Private->EPOC_WsEventStatus = KRequestPending;
  19.143 +		    //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
  19.144 +            if (eventType == EEventFocusGained) {
  19.145 +                RedrawWindowL(_this);
  19.146 +                break;
  19.147 +            }
  19.148 +	    }
  19.149 +        */
  19.150 +        break;
  19.151 +    }
  19.152 +
  19.153 +    case EEventModifiersChanged: 
  19.154 +    {
  19.155 +	    TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged();
  19.156 +        TUint modstate = KMOD_NONE;
  19.157 +        if (modEvent->iModifiers == EModifierLeftShift)
  19.158 +            modstate |= KMOD_LSHIFT;
  19.159 +        if (modEvent->iModifiers == EModifierRightShift)
  19.160 +            modstate |= KMOD_RSHIFT;
  19.161 +        if (modEvent->iModifiers == EModifierLeftCtrl)
  19.162 +            modstate |= KMOD_LCTRL;
  19.163 +        if (modEvent->iModifiers == EModifierRightCtrl)
  19.164 +            modstate |= KMOD_RCTRL;
  19.165 +        if (modEvent->iModifiers == EModifierLeftAlt)
  19.166 +            modstate |= KMOD_LALT;
  19.167 +        if (modEvent->iModifiers == EModifierRightAlt)
  19.168 +            modstate |= KMOD_RALT;
  19.169 +        if (modEvent->iModifiers == EModifierLeftFunc)
  19.170 +            modstate |= KMOD_LMETA;
  19.171 +        if (modEvent->iModifiers == EModifierRightFunc)
  19.172 +            modstate |= KMOD_RMETA;
  19.173 +        if (modEvent->iModifiers == EModifierCapsLock)
  19.174 +            modstate |= KMOD_CAPS;
  19.175 +        SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT)));
  19.176 +        break;
  19.177 +    }
  19.178 +    default:            
  19.179 +        break;
  19.180 +	} 
  19.181 +	
  19.182 +    return posted;
  19.183 +}
  19.184 +
  19.185 +extern "C" {
  19.186 +
  19.187 +void EPOC_PumpEvents(_THIS)
  19.188 +{
  19.189 +    int posted = 0; // !! Do we need this?
  19.190 +    //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
  19.191 +	while (Private->EPOC_WsEventStatus != KRequestPending) {
  19.192 +
  19.193 +		Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
  19.194 +		posted = EPOC_HandleWsEvent(_this, Private->EPOC_WsEvent);
  19.195 +		Private->EPOC_WsEventStatus = KRequestPending;
  19.196 +		Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
  19.197 +	}
  19.198 +}
  19.199 +
  19.200 +
  19.201 +void EPOC_InitOSKeymap(_THIS)
  19.202 +{
  19.203 +	int i;
  19.204 +
  19.205 +	/* Initialize the key translation table */
  19.206 +	for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
  19.207 +		keymap[i] = SDLK_UNKNOWN;
  19.208 +
  19.209 +
  19.210 +	/* Numbers */
  19.211 +	for ( i = 0; i<32; ++i ){
  19.212 +		keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
  19.213 +	}
  19.214 +	/* e.g. Alphabet keys */
  19.215 +	for ( i = 0; i<32; ++i ){
  19.216 +		keymap['A' + i] = (SDLKey)(SDLK_a+i);
  19.217 +	}
  19.218 +
  19.219 +	keymap[EStdKeyBackspace]    = SDLK_BACKSPACE;
  19.220 +	keymap[EStdKeyTab]          = SDLK_TAB;
  19.221 +	keymap[EStdKeyEnter]        = SDLK_RETURN;
  19.222 +	keymap[EStdKeyEscape]       = SDLK_ESCAPE;
  19.223 +   	keymap[EStdKeySpace]        = SDLK_SPACE;
  19.224 +   	keymap[EStdKeyPause]        = SDLK_PAUSE;
  19.225 +   	keymap[EStdKeyHome]         = SDLK_HOME;
  19.226 +   	keymap[EStdKeyEnd]          = SDLK_END;
  19.227 +   	keymap[EStdKeyPageUp]       = SDLK_PAGEUP;
  19.228 +   	keymap[EStdKeyPageDown]     = SDLK_PAGEDOWN;
  19.229 +	keymap[EStdKeyDelete]       = SDLK_DELETE;
  19.230 +	keymap[EStdKeyUpArrow]      = SDLK_UP;
  19.231 +	keymap[EStdKeyDownArrow]    = SDLK_DOWN;
  19.232 +	keymap[EStdKeyLeftArrow]    = SDLK_LEFT;
  19.233 +	keymap[EStdKeyRightArrow]   = SDLK_RIGHT;
  19.234 +	keymap[EStdKeyCapsLock]     = SDLK_CAPSLOCK;
  19.235 +	keymap[EStdKeyLeftShift]    = SDLK_LSHIFT;
  19.236 +	keymap[EStdKeyRightShift]   = SDLK_RSHIFT;
  19.237 +	keymap[EStdKeyLeftAlt]      = SDLK_LALT;
  19.238 +	keymap[EStdKeyRightAlt]     = SDLK_RALT;
  19.239 +	keymap[EStdKeyLeftCtrl]     = SDLK_LCTRL;
  19.240 +	keymap[EStdKeyRightCtrl]    = SDLK_RCTRL;
  19.241 +	keymap[EStdKeyLeftFunc]     = SDLK_LMETA;
  19.242 +	keymap[EStdKeyRightFunc]    = SDLK_RMETA;
  19.243 +	keymap[EStdKeyInsert]       = SDLK_INSERT;
  19.244 +	keymap[EStdKeyComma]        = SDLK_COMMA;
  19.245 +	keymap[EStdKeyFullStop]     = SDLK_PERIOD;
  19.246 +	keymap[EStdKeyForwardSlash] = SDLK_SLASH;
  19.247 +	keymap[EStdKeyBackSlash]    = SDLK_BACKSLASH;
  19.248 +	keymap[EStdKeySemiColon]    = SDLK_SEMICOLON;
  19.249 +	keymap[EStdKeySingleQuote]  = SDLK_QUOTE;
  19.250 +	keymap[EStdKeyHash]         = SDLK_HASH;
  19.251 +	keymap[EStdKeySquareBracketLeft]    = SDLK_LEFTBRACKET;
  19.252 +	keymap[EStdKeySquareBracketRight]   = SDLK_RIGHTBRACKET;
  19.253 +	keymap[EStdKeyMinus]        = SDLK_MINUS;
  19.254 +	keymap[EStdKeyEquals]       = SDLK_EQUALS;
  19.255 +
  19.256 +   	keymap[EStdKeyF1]          = SDLK_F1;  /* chr + q */
  19.257 +   	keymap[EStdKeyF2]          = SDLK_F2;  /* chr + w */
  19.258 +   	keymap[EStdKeyF3]          = SDLK_F3;  /* chr + e */
  19.259 +   	keymap[EStdKeyF4]          = SDLK_F4;  /* chr + r */
  19.260 +   	keymap[EStdKeyF5]          = SDLK_F5;  /* chr + t */
  19.261 +   	keymap[EStdKeyF6]          = SDLK_F6;  /* chr + y */
  19.262 +   	keymap[EStdKeyF7]          = SDLK_F7;  /* chr + i */
  19.263 +   	keymap[EStdKeyF8]          = SDLK_F8;  /* chr + o */
  19.264 +
  19.265 +   	keymap[EStdKeyF9]          = SDLK_F9;  /* chr + a */
  19.266 +   	keymap[EStdKeyF10]         = SDLK_F10; /* chr + s */
  19.267 +   	keymap[EStdKeyF11]         = SDLK_F11; /* chr + d */
  19.268 +   	keymap[EStdKeyF12]         = SDLK_F12; /* chr + f */
  19.269 +
  19.270 +    /* !!TODO
  19.271 +	EStdKeyNumLock=0x1b,
  19.272 +	EStdKeyScrollLock=0x1c,
  19.273 +
  19.274 +	EStdKeyNkpForwardSlash=0x84,
  19.275 +	EStdKeyNkpAsterisk=0x85,
  19.276 +	EStdKeyNkpMinus=0x86,
  19.277 +	EStdKeyNkpPlus=0x87,
  19.278 +	EStdKeyNkpEnter=0x88,
  19.279 +	EStdKeyNkp1=0x89,
  19.280 +	EStdKeyNkp2=0x8a,
  19.281 +	EStdKeyNkp3=0x8b,
  19.282 +	EStdKeyNkp4=0x8c,
  19.283 +	EStdKeyNkp5=0x8d,
  19.284 +	EStdKeyNkp6=0x8e,
  19.285 +	EStdKeyNkp7=0x8f,
  19.286 +	EStdKeyNkp8=0x90,
  19.287 +	EStdKeyNkp9=0x91,
  19.288 +	EStdKeyNkp0=0x92,
  19.289 +	EStdKeyNkpFullStop=0x93,
  19.290 +    EStdKeyMenu=0x94,
  19.291 +    EStdKeyBacklightOn=0x95,
  19.292 +    EStdKeyBacklightOff=0x96,
  19.293 +    EStdKeyBacklightToggle=0x97,
  19.294 +    EStdKeyIncContrast=0x98,
  19.295 +    EStdKeyDecContrast=0x99,
  19.296 +    EStdKeySliderDown=0x9a,
  19.297 +    EStdKeySliderUp=0x9b,
  19.298 +    EStdKeyDictaphonePlay=0x9c,
  19.299 +    EStdKeyDictaphoneStop=0x9d,
  19.300 +    EStdKeyDictaphoneRecord=0x9e,
  19.301 +    EStdKeyHelp=0x9f,
  19.302 +    EStdKeyOff=0xa0,
  19.303 +    EStdKeyDial=0xa1,
  19.304 +    EStdKeyIncVolume=0xa2,
  19.305 +    EStdKeyDecVolume=0xa3,
  19.306 +    EStdKeyDevice0=0xa4,
  19.307 +    EStdKeyDevice1=0xa5,
  19.308 +    EStdKeyDevice2=0xa6,
  19.309 +    EStdKeyDevice3=0xa7,
  19.310 +    EStdKeyDevice4=0xa8,
  19.311 +    EStdKeyDevice5=0xa9,
  19.312 +    EStdKeyDevice6=0xaa,
  19.313 +    EStdKeyDevice7=0xab,
  19.314 +    EStdKeyDevice8=0xac,
  19.315 +    EStdKeyDevice9=0xad,
  19.316 +    EStdKeyDeviceA=0xae,
  19.317 +    EStdKeyDeviceB=0xaf,
  19.318 +    EStdKeyDeviceC=0xb0,
  19.319 +    EStdKeyDeviceD=0xb1,
  19.320 +    EStdKeyDeviceE=0xb2,
  19.321 +    EStdKeyDeviceF=0xb3,
  19.322 +    EStdKeyApplication0=0xb4,
  19.323 +    EStdKeyApplication1=0xb5,
  19.324 +    EStdKeyApplication2=0xb6,
  19.325 +    EStdKeyApplication3=0xb7,
  19.326 +    EStdKeyApplication4=0xb8,
  19.327 +    EStdKeyApplication5=0xb9,
  19.328 +    EStdKeyApplication6=0xba,
  19.329 +    EStdKeyApplication7=0xbb,
  19.330 +    EStdKeyApplication8=0xbc,
  19.331 +    EStdKeyApplication9=0xbd,
  19.332 +    EStdKeyApplicationA=0xbe,
  19.333 +    EStdKeyApplicationB=0xbf,
  19.334 +    EStdKeyApplicationC=0xc0,
  19.335 +    EStdKeyApplicationD=0xc1,
  19.336 +    EStdKeyApplicationE=0xc2,
  19.337 +    EStdKeyApplicationF=0xc3,
  19.338 +    EStdKeyYes=0xc4,
  19.339 +    EStdKeyNo=0xc5,
  19.340 +    EStdKeyIncBrightness=0xc6,
  19.341 +    EStdKeyDecBrightness=0xc7, 
  19.342 +    EStdKeyCaseOpen=0xc8,
  19.343 +    EStdKeyCaseClose=0xc9
  19.344 +    */
  19.345 +
  19.346 +}
  19.347 +
  19.348 +
  19.349 +
  19.350 +static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
  19.351 +{
  19.352 +    char debug[256];
  19.353 +    //SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
  19.354 +
  19.355 +	/* Set the keysym information */ 
  19.356 +
  19.357 +	keysym->scancode = scancode;
  19.358 +
  19.359 +    if ((scancode >= MAX_SCANCODE) && 
  19.360 +        ((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) {
  19.361 +        SDL_SetError("Too big scancode");
  19.362 +        keysym->scancode = SDLK_UNKNOWN;
  19.363 +	    keysym->mod = KMOD_NONE; 
  19.364 +        return keysym;
  19.365 +    }
  19.366 +
  19.367 +	keysym->mod = SDL_GetModState(); //!!Is this right??
  19.368 +
  19.369 +    /* Handle function keys: F1, F2, F3 ... */
  19.370 +    if (keysym->mod & KMOD_META) {
  19.371 +        if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphapet keys */
  19.372 +            switch(scancode) {
  19.373 +                case 'Q': scancode = EStdKeyF1; break;
  19.374 +                case 'W': scancode = EStdKeyF2; break;
  19.375 +                case 'E': scancode = EStdKeyF3; break;
  19.376 +                case 'R': scancode = EStdKeyF4; break;
  19.377 +                case 'T': scancode = EStdKeyF5; break;
  19.378 +                case 'Y': scancode = EStdKeyF6; break;
  19.379 +                case 'U': scancode = EStdKeyF7; break;
  19.380 +                case 'I': scancode = EStdKeyF8; break;
  19.381 +                case 'A': scancode = EStdKeyF9; break;
  19.382 +                case 'S': scancode = EStdKeyF10; break;
  19.383 +                case 'D': scancode = EStdKeyF11; break;
  19.384 +                case 'F': scancode = EStdKeyF12; break;
  19.385 +            }
  19.386 +            keysym->sym = keymap[scancode];
  19.387 +        }
  19.388 +    }
  19.389 +
  19.390 +    if (scancode >= ENonCharacterKeyBase) {
  19.391 +        // Non character keys
  19.392 +	    keysym->sym = keymap[scancode - 
  19.393 +            ENonCharacterKeyBase + 0x0081]; // !!hard coded
  19.394 +    } else {
  19.395 +	    keysym->sym = keymap[scancode];
  19.396 +    }
  19.397 +
  19.398 +
  19.399 +	/* If UNICODE is on, get the UNICODE value for the key */
  19.400 +	keysym->unicode = 0;
  19.401 +
  19.402 +#if 0 // !!TODO:unicode
  19.403 +
  19.404 +	if ( SDL_TranslateUNICODE ) 
  19.405 +    {
  19.406 +		/* Populate the unicode field with the ASCII value */
  19.407 +		keysym->unicode = scancode;
  19.408 +	}
  19.409 +#endif
  19.410 +
  19.411 +    //!!
  19.412 +    //sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d",
  19.413 +    //    keysym->scancode, keysym->sym, keysym->mod);
  19.414 +    //SDL_TRACE(debug); //!!
  19.415 +
  19.416 +	return(keysym);
  19.417 +}
  19.418 +
  19.419 +}; /* extern "C" */
  19.420 +
  19.421 +
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/video/epoc/SDL_epocevents_c.h	Tue Sep 11 20:38:49 2001 +0000
    20.3 @@ -0,0 +1,50 @@
    20.4 +/*
    20.5 +    SDL - Simple DirectMedia Layer
    20.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
    20.7 +
    20.8 +    This library is free software; you can redistribute it and/or
    20.9 +    modify it under the terms of the GNU Library General Public
   20.10 +    License as published by the Free Software Foundation; either
   20.11 +    version 2 of the License, or (at your option) any later version.
   20.12 +
   20.13 +    This library is distributed in the hope that it will be useful,
   20.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   20.16 +    Library General Public License for more details.
   20.17 +
   20.18 +    You should have received a copy of the GNU Library General Public
   20.19 +    License along with this library; if not, write to the Free
   20.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   20.21 +
   20.22 +    Sam Lantinga
   20.23 +    slouken@devolution.com
   20.24 +*/
   20.25 +
   20.26 +/*
   20.27 +    SDL_epocevents_c.h
   20.28 +    Handle the event stream, converting Epoc events into SDL events
   20.29 +
   20.30 +    Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
   20.31 +*/
   20.32 +
   20.33 +
   20.34 +#ifdef SAVE_RCSID
   20.35 +static char rcsid =
   20.36 + "@(#) $Id$";
   20.37 +#endif
   20.38 +
   20.39 +extern "C" {
   20.40 +#include "SDL_sysvideo.h"
   20.41 +};
   20.42 +
   20.43 +#define MAX_SCANCODE 255
   20.44 +
   20.45 +/* Variables and functions exported by SDL_sysevents.c to other parts 
   20.46 +   of the native video subsystem (SDL_sysvideo.c)
   20.47 +*/
   20.48 +
   20.49 +extern "C" {
   20.50 +extern void EPOC_InitOSKeymap(_THIS);
   20.51 +extern void EPOC_PumpEvents(_THIS);
   20.52 +};
   20.53 +
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/src/video/epoc/SDL_epocvideo.cpp	Tue Sep 11 20:38:49 2001 +0000
    21.3 @@ -0,0 +1,700 @@
    21.4 +/*
    21.5 +    SDL - Simple DirectMedia Layer
    21.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
    21.7 +
    21.8 +    This library is free software; you can redistribute it and/or
    21.9 +    modify it under the terms of the GNU Library General Public
   21.10 +    License as published by the Free Software Foundation; either
   21.11 +    version 2 of the License, or (at your option) any later version.
   21.12 +
   21.13 +    This library is distributed in the hope that it will be useful,
   21.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   21.16 +    Library General Public License for more details.
   21.17 +
   21.18 +    You should have received a copy of the GNU Library General Public
   21.19 +    License along with this library; if not, write to the Free
   21.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   21.21 +
   21.22 +    Sam Lantinga
   21.23 +    slouken@devolution.com
   21.24 +*/
   21.25 +
   21.26 +/*
   21.27 +    SDL_epocvideo.cpp
   21.28 +    Epoc based SDL video driver implementation
   21.29 +
   21.30 +    Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
   21.31 +*/
   21.32 +
   21.33 +
   21.34 +
   21.35 +#include <stdlib.h>
   21.36 +#include <stdio.h>
   21.37 +#include <string.h>
   21.38 +
   21.39 +extern "C" {
   21.40 +#include "SDL_error.h"
   21.41 +#include "SDL_timer.h"
   21.42 +#include "SDL_video.h"
   21.43 +#undef NULL
   21.44 +#include "SDL_pixels_c.h"
   21.45 +};
   21.46 +
   21.47 +#include "SDL_epocvideo.h"
   21.48 +#include "SDL_epocevents_c.h"
   21.49 +
   21.50 +#include <hal.h>
   21.51 +#include <coedef.h>
   21.52 +
   21.53 +/* For debugging */
   21.54 +
   21.55 +void RDebug_Print_b(char* error_str, void* param)
   21.56 +    {
   21.57 +    TBuf8<128> error8((TUint8*)error_str);
   21.58 +    TBuf<128> error;
   21.59 +    error.Copy(error8);
   21.60 +    if (param) //!! Do not work if the parameter is really 0!!
   21.61 +        RDebug::Print(error, param);
   21.62 +    else 
   21.63 +        RDebug::Print(error);
   21.64 +    }
   21.65 +
   21.66 +extern "C" void RDebug_Print(char* error_str, void* param)
   21.67 +    {
   21.68 +    RDebug_Print_b(error_str, param);
   21.69 +    }
   21.70 +
   21.71 +
   21.72 +int Debug_AvailMem2()
   21.73 +    {
   21.74 +    //User::CompressAllHeaps();
   21.75 +    TMemoryInfoV1Buf membuf; 
   21.76 +    User::LeaveIfError(UserHal::MemoryInfo(membuf));
   21.77 +    TMemoryInfoV1 minfo = membuf();
   21.78 +	return(minfo.iFreeRamInBytes);
   21.79 +    }
   21.80 +
   21.81 +extern "C" int Debug_AvailMem()
   21.82 +    {
   21.83 +    return(Debug_AvailMem2());
   21.84 +    }
   21.85 +
   21.86 +
   21.87 +extern "C" {
   21.88 +
   21.89 +/* Initialization/Query functions */
   21.90 +
   21.91 +static int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat);
   21.92 +static SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
   21.93 +static SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
   21.94 +static int EPOC_SetColors(_THIS, int firstcolor, int ncolors,
   21.95 +			  SDL_Color *colors);
   21.96 +static void EPOC_VideoQuit(_THIS);
   21.97 +
   21.98 +/* Hardware surface functions */
   21.99 +
  21.100 +static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface);
  21.101 +static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface);
  21.102 +static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface);
  21.103 +static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface);
  21.104 +static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface);
  21.105 +static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
  21.106 +
  21.107 +static int EPOC_Available(void);
  21.108 +static SDL_VideoDevice *EPOC_CreateDevice(int devindex);
  21.109 +
  21.110 +/* Mouse functions */
  21.111 +
  21.112 +static WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
  21.113 +static void EPOC_FreeWMCursor(_THIS, WMcursor *cursor);
  21.114 +static int EPOC_ShowWMCursor(_THIS, WMcursor *cursor);
  21.115 +
  21.116 +
  21.117 +
  21.118 +/* !! Table for fast conversion from 8 bit to 12 bit */
  21.119 +static TUint16 EPOC_HWPalette_256_to_4k[256];
  21.120 +
  21.121 +VideoBootStrap EPOC_bootstrap = {
  21.122 +	"epoc", "EPOC system",
  21.123 +    EPOC_Available, EPOC_CreateDevice
  21.124 +};
  21.125 +
  21.126 +const TUint32 WindowClientHandle = 9210; //!!
  21.127 +
  21.128 +/* Epoc video driver bootstrap functions */
  21.129 +
  21.130 +static int EPOC_Available(void)
  21.131 +{
  21.132 +    return 1; /* Always available */
  21.133 +}
  21.134 +
  21.135 +static void EPOC_DeleteDevice(SDL_VideoDevice *device)
  21.136 +{
  21.137 +	free(device->hidden);
  21.138 +	free(device);
  21.139 +}
  21.140 +
  21.141 +static SDL_VideoDevice *EPOC_CreateDevice(int devindex)
  21.142 +{
  21.143 +	SDL_VideoDevice *device;
  21.144 +
  21.145 +	/* Allocate all variables that we free on delete */
  21.146 +	device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
  21.147 +	if ( device ) {
  21.148 +		memset(device, 0, (sizeof *device));
  21.149 +		device->hidden = (struct SDL_PrivateVideoData *)
  21.150 +				malloc((sizeof *device->hidden));
  21.151 +	}
  21.152 +	if ( (device == NULL) || (device->hidden == NULL) ) {
  21.153 +		SDL_OutOfMemory();
  21.154 +		if ( device ) {
  21.155 +			free(device);
  21.156 +		}
  21.157 +		return(0);
  21.158 +	}
  21.159 +	memset(device->hidden, 0, (sizeof *device->hidden));
  21.160 +
  21.161 +	/* Set the function pointers */
  21.162 +	device->VideoInit = EPOC_VideoInit;
  21.163 +	device->ListModes = EPOC_ListModes;
  21.164 +	device->SetVideoMode = EPOC_SetVideoMode;
  21.165 +	device->SetColors = EPOC_SetColors;
  21.166 +	device->UpdateRects = NULL;
  21.167 +	device->VideoQuit = EPOC_VideoQuit;
  21.168 +	device->AllocHWSurface = EPOC_AllocHWSurface;
  21.169 +	device->CheckHWBlit = NULL;
  21.170 +	device->FillHWRect = NULL;
  21.171 +	device->SetHWColorKey = NULL;
  21.172 +	device->SetHWAlpha = NULL;
  21.173 +	device->LockHWSurface = EPOC_LockHWSurface;
  21.174 +	device->UnlockHWSurface = EPOC_UnlockHWSurface;
  21.175 +	device->FlipHWSurface = EPOC_FlipHWSurface;
  21.176 +	device->FreeHWSurface = EPOC_FreeHWSurface;
  21.177 +	device->SetIcon = NULL;
  21.178 +	device->SetCaption = NULL;
  21.179 +	device->GetWMInfo = NULL;
  21.180 +	device->FreeWMCursor = EPOC_FreeWMCursor;
  21.181 +	device->CreateWMCursor = EPOC_CreateWMCursor;
  21.182 +	device->ShowWMCursor = EPOC_ShowWMCursor;
  21.183 +	device->WarpWMCursor = NULL;
  21.184 +	device->InitOSKeymap = EPOC_InitOSKeymap;
  21.185 +	device->PumpEvents = EPOC_PumpEvents;
  21.186 +	device->free = EPOC_DeleteDevice;
  21.187 +
  21.188 +	return device;
  21.189 +}
  21.190 +
  21.191 +
  21.192 +int GetBpp(TDisplayMode displaymode)
  21.193 +{
  21.194 +    TInt numColors = TDisplayModeUtils::NumDisplayModeColors(displaymode);
  21.195 +    TInt bitsPerPixel = 1;
  21.196 +    for (TInt32 i = 2; i < numColors; i <<= 1, bitsPerPixel++);
  21.197 +    return bitsPerPixel;    
  21.198 +}
  21.199 +
  21.200 +void ConstructWindowL(_THIS)
  21.201 +{
  21.202 +	TInt	error;
  21.203 +
  21.204 +	error = Private->EPOC_WsSession.Connect();
  21.205 +	User::LeaveIfError(error);
  21.206 +	Private->EPOC_WsScreen=new(ELeave) CWsScreenDevice(Private->EPOC_WsSession);
  21.207 +	User::LeaveIfError(Private->EPOC_WsScreen->Construct());
  21.208 +	User::LeaveIfError(Private->EPOC_WsScreen->CreateContext(Private->EPOC_WindowGc));
  21.209 +
  21.210 +	Private->EPOC_WsWindowGroup=RWindowGroup(Private->EPOC_WsSession);
  21.211 +	User::LeaveIfError(Private->EPOC_WsWindowGroup.Construct(WindowClientHandle));
  21.212 +	Private->EPOC_WsWindowGroup.SetOrdinalPosition(0);
  21.213 +
  21.214 +    //!!
  21.215 +    TBuf<32> winGroupName;
  21.216 +    winGroupName.Append(0);
  21.217 +    winGroupName.Append(0);
  21.218 +    winGroupName.Append(0);// uid
  21.219 +    winGroupName.Append(0);
  21.220 +    winGroupName.Append(_L("SDL")); // caption
  21.221 +    winGroupName.Append(0);
  21.222 +    winGroupName.Append(0); //doc name
  21.223 +	Private->EPOC_WsWindowGroup.SetName(winGroupName); //!!
  21.224 +
  21.225 +	Private->EPOC_WsWindow=RWindow(Private->EPOC_WsSession);
  21.226 +	User::LeaveIfError(Private->EPOC_WsWindow.Construct(Private->EPOC_WsWindowGroup,WindowClientHandle));
  21.227 +	Private->EPOC_WsWindow.SetBackgroundColor(KRgbWhite);
  21.228 +    Private->EPOC_WsWindow.Activate();
  21.229 +	Private->EPOC_WsWindow.SetSize(Private->EPOC_WsScreen->SizeInPixels()); 
  21.230 +	Private->EPOC_WsWindow.SetVisible(ETrue);
  21.231 +
  21.232 +    Private->EPOC_WsWindowGroupID = Private->EPOC_WsWindowGroup.Identifier();
  21.233 +    Private->EPOC_IsWindowFocused = EFalse;
  21.234 +}
  21.235 +
  21.236 +
  21.237 +int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat)
  21.238 +{
  21.239 +    // !!TODO:handle leave functions!
  21.240 +
  21.241 +    int i;
  21.242 +
  21.243 +	/* Initialize all variables that we clean on shutdown */   
  21.244 +
  21.245 +	for ( i=0; i<SDL_NUMMODES; ++i ) {
  21.246 +		Private->SDL_modelist[i] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
  21.247 +		Private->SDL_modelist[i]->x = Private->SDL_modelist[i]->y = 0;
  21.248 +	}
  21.249 +	/* Modes sorted largest to smallest !!TODO:sorting order??*/
  21.250 +	Private->SDL_modelist[0]->w = 640; Private->SDL_modelist[0]->h = 200; 
  21.251 +	Private->SDL_modelist[1]->w = 320; Private->SDL_modelist[1]->h = 200;
  21.252 +	Private->SDL_modelist[2]->w = 640; Private->SDL_modelist[2]->h = 400; 
  21.253 +	Private->SDL_modelist[3]->w = 640; Private->SDL_modelist[3]->h = 480;
  21.254 +	Private->SDL_modelist[4] = NULL;
  21.255 +
  21.256 +    /* Construct Epoc window */
  21.257 +
  21.258 +    ConstructWindowL(_this);
  21.259 +
  21.260 +    /* Initialise Epoc frame buffer */
  21.261 +
  21.262 +    TDisplayMode displayMode = Private->EPOC_WsScreen->DisplayMode();
  21.263 +
  21.264 +    #ifndef __WINS__
  21.265 +
  21.266 +    TScreenInfoV01 screenInfo;
  21.267 +	TPckg<TScreenInfoV01> sInfo(screenInfo);
  21.268 +	UserSvr::ScreenInfo(sInfo);
  21.269 +
  21.270 +	Private->EPOC_ScreenSize		= screenInfo.iScreenSize; 
  21.271 +	Private->EPOC_DisplayMode		= displayMode;
  21.272 +    Private->EPOC_HasFrameBuffer	= screenInfo.iScreenAddressValid;
  21.273 +	Private->EPOC_FrameBuffer		= Private->EPOC_HasFrameBuffer ? (TUint8*) screenInfo.iScreenAddress : NULL;
  21.274 +	Private->EPOC_BytesPerPixel	    = ((GetBpp(displayMode)-1) / 8) + 1;
  21.275 +	Private->EPOC_BytesPerScanLine	= screenInfo.iScreenSize.iWidth * Private->EPOC_BytesPerPixel;
  21.276 +
  21.277 +    /* It seems that in SA1100 machines for 8bpp displays there is a 512 palette table at the 
  21.278 +     * beginning of the frame buffer. E.g. Series 7 and Netbook.
  21.279 +     * In 12 bpp machines the table has 16 entries.
  21.280 +	 */
  21.281 +	if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 8)
  21.282 +		Private->EPOC_FrameBuffer += 512;
  21.283 +	if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 12)
  21.284 +		Private->EPOC_FrameBuffer += 16 * 2;
  21.285 +
  21.286 +    #else /* defined __WINS__ */
  21.287 +    
  21.288 +    /* Create bitmap, device and context for screen drawing */
  21.289 +    Private->EPOC_ScreenSize        = Private->EPOC_WsScreen->SizeInPixels();
  21.290 +
  21.291 +	Private->EPOC_Bitmap = new (ELeave) CWsBitmap(Private->EPOC_WsSession);
  21.292 +	Private->EPOC_Bitmap->Create(Private->EPOC_ScreenSize, displayMode);
  21.293 +
  21.294 +	Private->EPOC_DisplayMode	    = displayMode;
  21.295 +    Private->EPOC_HasFrameBuffer    = ETrue;
  21.296 +    Private->EPOC_FrameBuffer       = NULL; /* Private->EPOC_Bitmap->DataAddress() can change any time */
  21.297 +	Private->EPOC_BytesPerPixel	    = ((GetBpp(displayMode)-1) / 8) + 1;
  21.298 +	Private->EPOC_BytesPerScanLine  = Private->EPOC_WsScreen->SizeInPixels().iWidth * Private->EPOC_BytesPerPixel;
  21.299 +
  21.300 +    #endif /* __WINS__ */
  21.301 +
  21.302 +    /* The "best" video format should be returned to caller. */
  21.303 +
  21.304 +    vformat->BitsPerPixel       = /*!!GetBpp(displayMode) */ 8;
  21.305 +    vformat->BytesPerPixel      = /*!!Private->EPOC_BytesPerPixel*/ 1;
  21.306 +
  21.307 +    /* Activate events for me */
  21.308 +
  21.309 +	Private->EPOC_WsEventStatus = KRequestPending;
  21.310 +	Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
  21.311 +	Private->EPOC_RedrawEventStatus = KRequestPending;
  21.312 +	Private->EPOC_WsSession.RedrawReady(&Private->EPOC_RedrawEventStatus);
  21.313 +    Private->EPOC_WsWindow.PointerFilter(EPointerFilterDrag, 0); 
  21.314 +
  21.315 +    Private->EPOC_ScreenOffset = 0;
  21.316 +
  21.317 +    //!! TODO: error handling
  21.318 +    //if (ret != KErrNone)
  21.319 +    //    return(-1);
  21.320 +    //else
  21.321 +	    return(0);
  21.322 +}
  21.323 +
  21.324 +
  21.325 +SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
  21.326 +{
  21.327 +    if (format->BitsPerPixel == 12 || format->BitsPerPixel == 8)
  21.328 +        return Private->SDL_modelist;
  21.329 +    return NULL;
  21.330 +}
  21.331 +
  21.332 +int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
  21.333 +{
  21.334 +    for(int i = firstcolor; i < ncolors; i++) {
  21.335 +	    // 4k value: 000rgb
  21.336 +	    TUint16 color4K = 0;
  21.337 +        color4K |= (colors[i].r & 0x0000f0) << 4; 
  21.338 +	    color4K |= (colors[i].g & 0x0000f0);      
  21.339 +	    color4K |= (colors[i].b & 0x0000f0) >> 4;
  21.340 +        EPOC_HWPalette_256_to_4k[i] = color4K;
  21.341 +    }
  21.342 +	return(0);
  21.343 +}
  21.344 +
  21.345 +
  21.346 +SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current,
  21.347 +				int width, int height, int bpp, Uint32 flags)
  21.348 +{
  21.349 +    /* Check parameters */
  21.350 +    if (!((width == 640 && height == 200 && bpp == 12) ||
  21.351 +          (width == 640 && height == 400 && bpp == 12) || 
  21.352 +          (width == 640 && height == 480 && bpp == 12) || 
  21.353 +          (width == 320 && height == 200 && bpp == 12) || 
  21.354 +          (width == 640 && height == 200 && bpp == 8) ||
  21.355 +          (width == 640 && height == 400 && bpp == 8) || 
  21.356 +          (width == 640 && height == 480 && bpp == 8) || 
  21.357 +          (width == 320 && height == 200 && bpp == 8))) {
  21.358 +		SDL_SetError("Requested video mode is not supported");
  21.359 +        return NULL;
  21.360 +    }
  21.361 +
  21.362 +    if (current && current->pixels) {
  21.363 +        free(current->pixels);
  21.364 +        current->pixels = NULL;
  21.365 +    }
  21.366 +	if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
  21.367 +		return(NULL);
  21.368 +	}
  21.369 +
  21.370 +    /* Set up the new mode framebuffer */
  21.371 +    if (bpp == 8) 
  21.372 +	    current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC|SDL_HWPALETTE); 
  21.373 +    else // 12 bpp
  21.374 +	    current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC); 
  21.375 +	current->w = width;
  21.376 +	current->h = height;
  21.377 +    int numBytesPerPixel = ((bpp-1)>>3) + 1;   
  21.378 +	current->pitch = numBytesPerPixel * width; // Number of bytes in scanline 
  21.379 +	current->pixels = malloc(width * height * numBytesPerPixel);
  21.380 +	memset(current->pixels, 0, width * height * numBytesPerPixel);
  21.381 +
  21.382 +	/* Set the blit function */
  21.383 +	_this->UpdateRects = EPOC_DirectUpdate;
  21.384 +
  21.385 +    /* Must buffer height be shrinked to screen by 2 ? */
  21.386 +    if (current->h >= 400)
  21.387 +        Private->EPOC_ShrinkedHeight = ETrue;
  21.388 +
  21.389 +    /* Centralize game window on device screen  */
  21.390 +    Private->EPOC_ScreenOffset = (Private->EPOC_ScreenSize.iWidth - current->w) / 2;
  21.391 +
  21.392 +	/* We're done */
  21.393 +	return(current);
  21.394 +}
  21.395 +
  21.396 +void RedrawWindowL(_THIS)
  21.397 +{
  21.398 +    SDL_Rect fullScreen;
  21.399 +    fullScreen.x = 0;
  21.400 +    fullScreen.y = 0;
  21.401 +    fullScreen.w = _this->screen->w;
  21.402 +    fullScreen.h = _this->screen->h;
  21.403 +
  21.404 +#ifdef __WINS__
  21.405 +	    TBitmapUtil lock(Private->EPOC_Bitmap);	
  21.406 +        lock.Begin(TPoint(0,0)); // Lock bitmap heap
  21.407 +	    Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
  21.408 +#endif
  21.409 +
  21.410 +    if (fullScreen.w < Private->EPOC_ScreenSize.iWidth
  21.411 +        && fullScreen.w < Private->EPOC_ScreenSize.iWidth) {
  21.412 +        /* Draw blue stripes background */
  21.413 +#ifdef __WINS__
  21.414 +        TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress();
  21.415 +#else
  21.416 +        TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer;
  21.417 +#endif
  21.418 +        for (int y=0; y < Private->EPOC_ScreenSize.iHeight; y++) {
  21.419 +            for (int x=0; x < Private->EPOC_ScreenSize.iWidth; x++) {
  21.420 +                TUint16 color = ((x+y)>>1) & 0xf; /* Draw pattern */
  21.421 +                *screenBuffer++ = color;
  21.422 +            }
  21.423 +        }
  21.424 +    }
  21.425 +
  21.426 +
  21.427 +    /* Tell the system that something has been drawn */
  21.428 +	TRect  rect = TRect(Private->EPOC_WsWindow.Size());
  21.429 +  	Private->EPOC_WsWindow.Invalidate(rect);
  21.430 +
  21.431 +#ifdef __WINS__
  21.432 +	Private->EPOC_WsWindow.BeginRedraw(rect);
  21.433 +	Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap);
  21.434 +	Private->EPOC_WsWindow.EndRedraw();
  21.435 +	Private->EPOC_WindowGc->Deactivate();
  21.436 +    lock.End(); // Unlock bitmap heap
  21.437 +	Private->EPOC_WsSession.Flush();
  21.438 +#endif
  21.439 +
  21.440 +    /* Draw current buffer */
  21.441 +    EPOC_DirectUpdate(_this, 1, &fullScreen);
  21.442 +}
  21.443 +
  21.444 +
  21.445 +/* We don't actually allow hardware surfaces other than the main one */
  21.446 +static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface)
  21.447 +{
  21.448 +	return(-1);
  21.449 +}
  21.450 +static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface)
  21.451 +{
  21.452 +	return;
  21.453 +}
  21.454 +
  21.455 +static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface)
  21.456 +{
  21.457 +	return(0);
  21.458 +}
  21.459 +static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface)
  21.460 +{
  21.461 +	return;
  21.462 +}
  21.463 +
  21.464 +static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface)
  21.465 +{
  21.466 +	return(0);
  21.467 +}
  21.468 +
  21.469 +static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
  21.470 +{
  21.471 +    TInt focusWindowGroupId = Private->EPOC_WsSession.GetFocusWindowGroup();
  21.472 +    if (focusWindowGroupId != Private->EPOC_WsWindowGroupID) {
  21.473 +
  21.474 +        /* Force focus window to redraw again for cleaning away SDL screen graphics */
  21.475 +
  21.476 +  
  21.477 +        TInt pos = Private->EPOC_WsWindowGroup.OrdinalPosition();
  21.478 +        Private->EPOC_WsWindowGroup.SetOrdinalPosition(0, KMaxTInt);
  21.479 +       	TRect  rect = TRect(Private->EPOC_WsWindow.Size());
  21.480 +        Private->EPOC_WsWindow.Invalidate(rect);
  21.481 +        Private->EPOC_WsWindowGroup.SetOrdinalPosition(pos, ECoeWinPriorityNormal);
  21.482 +        
  21.483 +        /* If this is not the topmost window, wait here! Sleep for 1 second to give cpu to 
  21.484 +           multitasking and poll for being the topmost window.
  21.485 +        */
  21.486 +        while (Private->EPOC_WsSession.GetFocusWindowGroup() != Private->EPOC_WsWindowGroupID)
  21.487 +            SDL_Delay(1000);
  21.488 +
  21.489 +        RedrawWindowL(_this);  
  21.490 +    }
  21.491 +
  21.492 +	TInt i;
  21.493 +    TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1;   
  21.494 +    TInt targetNumBytesPerPixel = Private->EPOC_BytesPerPixel;   
  21.495 +    TInt fixedOffset = Private->EPOC_ScreenOffset;   
  21.496 +    TInt screenW = _this->screen->w;
  21.497 +    TInt screenH = _this->screen->h;
  21.498 +    TInt sourceScanlineLength = screenW;
  21.499 +    if (Private->EPOC_ShrinkedHeight) {  /* simulate 400 pixel height in 200 pixel screen */  
  21.500 +        sourceScanlineLength <<= 1; 
  21.501 +        screenH >>= 1;
  21.502 +    }
  21.503 +    TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth;
  21.504 +#ifdef __WINS__
  21.505 +	TBitmapUtil lock(Private->EPOC_Bitmap);	
  21.506 +    lock.Begin(TPoint(0,0)); // Lock bitmap heap
  21.507 +	Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
  21.508 +    TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress();
  21.509 +#else
  21.510 +    TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer;
  21.511 +#endif
  21.512 +
  21.513 +
  21.514 +	/* Render the rectangles in the list */
  21.515 +
  21.516 +	for ( i=0; i < numrects; ++i ) {
  21.517 +        SDL_Rect rect2;
  21.518 +        const SDL_Rect& currentRect = rects[i];
  21.519 +        rect2.x = currentRect.x;
  21.520 +        rect2.y = currentRect.y;
  21.521 +        rect2.w = currentRect.w;
  21.522 +        rect2.h = currentRect.h;
  21.523 +
  21.524 +        if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */
  21.525 +            continue;
  21.526 +
  21.527 +        if (Private->EPOC_ShrinkedHeight) {  /* simulate 400 pixel height in 200 pixel screen */        
  21.528 +            rect2.y >>= 1;
  21.529 +            if (!(rect2.h >>= 1)) 
  21.530 +                rect2.h = 1; // always at least 1 pixel height!
  21.531 +        }
  21.532 +
  21.533 +        /* All variables are measured in pixels */
  21.534 +
  21.535 +        /* Check rects validity, i.e. upper and lower bounds */
  21.536 +        TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1);
  21.537 +        TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1);
  21.538 +        if (maxX < 0 || maxY < 0) /* sanity check */
  21.539 +            continue;
  21.540 +        maxY = Min(maxY, 199); 
  21.541 +
  21.542 +        TInt sourceRectWidth = maxX - rect2.x + 1;
  21.543 +        TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel;
  21.544 +        TInt sourceRectHeight = maxY - rect2.y + 1;
  21.545 +        TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength;
  21.546 +        TInt targetStartOffset = fixedOffset + rect2.x + rect2.y * targetScanlineLength;   
  21.547 +        
  21.548 +        // !! Nokia9210 native mode: 12 bpp --> 12 bpp
  21.549 +        if (_this->screen->format->BitsPerPixel == 12) { 
  21.550 +	        TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset;
  21.551 +            TUint16* screenMemory = screenBuffer + targetStartOffset;
  21.552 +            for(TInt y = 0 ; y < sourceRectHeight ; y++) {
  21.553 +                __ASSERT_DEBUG(screenMemory < (screenBuffer 
  21.554 +                    + Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight), 
  21.555 +                    User::Panic(_L("SDL"), KErrCorrupt));
  21.556 +                __ASSERT_DEBUG(screenMemory >= screenBuffer, 
  21.557 +                    User::Panic(_L("SDL"), KErrCorrupt));
  21.558 +                __ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels + 
  21.559 +                    + (_this->screen->w * _this->screen->h)), 
  21.560 +                    User::Panic(_L("SDL"), KErrCorrupt));
  21.561 +                __ASSERT_DEBUG(bitmapLine >=  (TUint16*)_this->screen->pixels, 
  21.562 +                    User::Panic(_L("SDL"), KErrCorrupt));
  21.563 +		        Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes);
  21.564 +		        bitmapLine += sourceScanlineLength;
  21.565 +		        screenMemory += targetScanlineLength;
  21.566 +            }
  21.567 +        }
  21.568 +        // !! 256 color paletted mode: 8 bpp  --> 12 bpp
  21.569 +        else { 
  21.570 +	        TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset;
  21.571 +            TUint16* screenMemory = screenBuffer + targetStartOffset;
  21.572 +            for(TInt y = 0 ; y < sourceRectHeight ; y++) {
  21.573 +                TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
  21.574 +                TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
  21.575 +                /* Convert each pixel from 256 palette to 4k color values */
  21.576 +                for(TInt x = 0 ; x < sourceRectWidth ; x++) {
  21.577 +                    __ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer 
  21.578 +                        + (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)), 
  21.579 +                        User::Panic(_L("SDL"), KErrCorrupt));
  21.580 +                    __ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, 
  21.581 +                        User::Panic(_L("SDL"), KErrCorrupt));
  21.582 +                    __ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels + 
  21.583 +                        + (_this->screen->w * _this->screen->h)), 
  21.584 +                        User::Panic(_L("SDL"), KErrCorrupt));
  21.585 +                    __ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels, 
  21.586 +                        User::Panic(_L("SDL"), KErrCorrupt));
  21.587 +                    *screenMemoryLinePos = EPOC_HWPalette_256_to_4k[*bitmapPos];
  21.588 +                    bitmapPos++;
  21.589 +                    screenMemoryLinePos++;
  21.590 +                }
  21.591 +		        bitmapLine += sourceScanlineLength;
  21.592 +		        screenMemory += targetScanlineLength;
  21.593 +            }
  21.594 +	    }
  21.595 +
  21.596 +    }    
  21.597 +    
  21.598 +#ifdef __WINS__
  21.599 +
  21.600 +	TRect  rect = TRect(Private->EPOC_WsWindow.Size());
  21.601 +	Private->EPOC_WsWindow.Invalidate(rect);
  21.602 +	Private->EPOC_WsWindow.BeginRedraw(rect);
  21.603 +	Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap);
  21.604 +	Private->EPOC_WsWindow.EndRedraw();
  21.605 +	Private->EPOC_WindowGc->Deactivate();
  21.606 +    lock.End(); // Unlock bitmap heap
  21.607 +	Private->EPOC_WsSession.Flush();
  21.608 +
  21.609 +#endif
  21.610 +
  21.611 +    /* Update virtual cursor */
  21.612 +    //!!Private->EPOC_WsSession.SetPointerCursorPosition(Private->EPOC_WsSession.PointerCursorPosition());
  21.613 +
  21.614 +    return;
  21.615 +}
  21.616 +
  21.617 +
  21.618 +/* Note:  If we are terminated, this could be called in the middle of
  21.619 +   another SDL video routine -- notably UpdateRects.
  21.620 +*/
  21.621 +void EPOC_VideoQuit(_THIS)
  21.622 +{
  21.623 +	int i;
  21.624 +
  21.625 +	/* Free video mode lists */
  21.626 +	for ( i=0; i<SDL_NUMMODES; ++i ) {
  21.627 +		if ( Private->SDL_modelist[i] != NULL ) {
  21.628 +			free(Private->SDL_modelist[i]);
  21.629 +			Private->SDL_modelist[i] = NULL;
  21.630 +		}
  21.631 +	}
  21.632 +	
  21.633 +    if ( _this->screen && (_this->screen->flags & SDL_HWSURFACE) ) {
  21.634 +		/* Direct screen access, no memory buffer */
  21.635 +		_this->screen->pixels = NULL;
  21.636 +	}
  21.637 +
  21.638 +    if (_this->screen && _this->screen->pixels) {
  21.639 +        free(_this->screen->pixels);
  21.640 +        _this->screen->pixels = NULL;
  21.641 +    }
  21.642 +
  21.643 +    /* Free Epoc resources */
  21.644 +
  21.645 +    /* Disable events for me */
  21.646 +	if (Private->EPOC_WsEventStatus != KRequestPending)
  21.647 +		Private->EPOC_WsSession.EventReadyCancel();
  21.648 +	if (Private->EPOC_RedrawEventStatus != KRequestPending)
  21.649 +		Private->EPOC_WsSession.RedrawReadyCancel();
  21.650 +
  21.651 +    #ifdef __WINS__
  21.652 +	delete Private->EPOC_Bitmap;
  21.653 +	Private->EPOC_Bitmap = NULL;
  21.654 +    #endif
  21.655 +
  21.656 +	if (Private->EPOC_WsWindow.WsHandle())
  21.657 +		Private->EPOC_WsWindow.Close();
  21.658 +
  21.659 +	if (Private->EPOC_WsWindowGroup.WsHandle())
  21.660 +		Private->EPOC_WsWindowGroup.Close();
  21.661 +
  21.662 +	delete Private->EPOC_WindowGc;
  21.663 +	Private->EPOC_WindowGc = NULL;
  21.664 +
  21.665 +	delete Private->EPOC_WsScreen;
  21.666 +	Private->EPOC_WsScreen = NULL;
  21.667 +
  21.668 +	if (Private->EPOC_WsSession.WsHandle())
  21.669 +		Private->EPOC_WsSession.Close();
  21.670 +}
  21.671 +
  21.672 +
  21.673 +WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
  21.674 +{
  21.675 +	return (WMcursor *) 9210; // it's ok to return something unuseful but true
  21.676 +}
  21.677 +
  21.678 +void EPOC_FreeWMCursor(_THIS, WMcursor *cursor)
  21.679 +{
  21.680 +    /* Disable virtual cursor */
  21.681 +    HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
  21.682 +    Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone);
  21.683 +}
  21.684 +
  21.685 +int EPOC_ShowWMCursor(_THIS, WMcursor *cursor)
  21.686 +{
  21.687 +
  21.688 +    if (cursor ==  (WMcursor *)9210) {
  21.689 +        /* Enable virtual cursor */
  21.690 +	    HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
  21.691 +	    Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNormal);
  21.692 +    }
  21.693 +    else {
  21.694 +        /* Disable virtual cursor */
  21.695 +        HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
  21.696 +        Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone);
  21.697 +    }
  21.698 +
  21.699 +	return(1);
  21.700 +}
  21.701 +
  21.702 +}; // extern "C"
  21.703 +
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/src/video/epoc/SDL_epocvideo.h	Tue Sep 11 20:38:49 2001 +0000
    22.3 @@ -0,0 +1,89 @@
    22.4 +/*
    22.5 +    SDL - Simple DirectMedia Layer
    22.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
    22.7 +
    22.8 +    This library is free software; you can redistribute it and/or
    22.9 +    modify it under the terms of the GNU Library General Public
   22.10 +    License as published by the Free Software Foundation; either
   22.11 +    version 2 of the License, or (at your option) any later version.
   22.12 +
   22.13 +    This library is distributed in the hope that it will be useful,
   22.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   22.16 +    Library General Public License for more details.
   22.17 +
   22.18 +    You should have received a copy of the GNU Library General Public
   22.19 +    License along with this library; if not, write to the Free
   22.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   22.21 +
   22.22 +    Sam Lantinga
   22.23 +    slouken@devolution.com
   22.24 +*/
   22.25 +
   22.26 +/*
   22.27 +    SDL_epocvideo.h
   22.28 +    Epoc based SDL video driver implementation
   22.29 +
   22.30 +    Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
   22.31 +*/
   22.32 +
   22.33 +#ifndef _SDL_epocvideo_h
   22.34 +#define _SDL_epocvideo_h
   22.35 +
   22.36 +extern "C" {
   22.37 +#include "SDL_mouse.h"
   22.38 +#include "SDL_sysvideo.h"
   22.39 +};
   22.40 +
   22.41 +#include <e32std.h>
   22.42 +#include <bitdev.h> 
   22.43 +#include <w32std.h>
   22.44 +
   22.45 +/* Hidden "this" pointer for the video functions */
   22.46 +#define _THIS	SDL_VideoDevice *_this
   22.47 +#define Private	_this->hidden
   22.48 +
   22.49 +#define SDL_NUMMODES	4
   22.50 +
   22.51 +/* Private display data */
   22.52 +struct SDL_PrivateVideoData {
   22.53 +
   22.54 +    SDL_Rect            *SDL_modelist[SDL_NUMMODES+1];
   22.55 +
   22.56 +	/* Epoc window server info */
   22.57 +    
   22.58 +    RWsSession			EPOC_WsSession;
   22.59 +	RWindowGroup		EPOC_WsWindowGroup;
   22.60 +    TInt                EPOC_WsWindowGroupID;
   22.61 +	RWindow				EPOC_WsWindow;
   22.62 +	CWsScreenDevice*	EPOC_WsScreen;
   22.63 +	CWindowGc*			EPOC_WindowGc;
   22.64 +	TRequestStatus		EPOC_WsEventStatus;
   22.65 +	TRequestStatus		EPOC_RedrawEventStatus;
   22.66 +	TWsEvent			EPOC_WsEvent;
   22.67 +	TWsRedrawEvent		EPOC_RedrawEvent;
   22.68 +    #ifdef __WINS__
   22.69 +    CWsBitmap*          EPOC_Bitmap;
   22.70 +    #endif
   22.71 +    TBool               EPOC_IsWindowFocused; //!!Not used for anything yet!
   22.72 +
   22.73 +    /* Screen hardware frame buffer info */
   22.74 +
   22.75 +   	TBool				EPOC_HasFrameBuffer;
   22.76 +	TInt				EPOC_BytesPerPixel;
   22.77 +	TInt				EPOC_BytesPerScanLine;
   22.78 +	TDisplayMode		EPOC_DisplayMode;
   22.79 +	TSize				EPOC_ScreenSize;
   22.80 +	TUint8*				EPOC_FrameBuffer;		/* if NULL in HW we can't do direct screen access */
   22.81 +    TInt                EPOC_ScreenOffset;
   22.82 +
   22.83 +    /* Simulate double screen height */
   22.84 +    TBool               EPOC_ShrinkedHeight;
   22.85 +};
   22.86 +
   22.87 +extern "C" {
   22.88 +extern void RedrawWindowL(_THIS);
   22.89 +};
   22.90 +
   22.91 +
   22.92 +#endif /* _SDL_epocvideo_h */