Mercurial > sdl-ios-xcode
changeset 3269:a67a961e2171
Removed outdated OS/2 support
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 19 Sep 2009 06:43:45 +0000 |
parents | 82ce350be859 |
children | fb9b6b2924ba |
files | README README.OS2 Watcom-OS2.zip docs.html include/SDL.h include/SDL_config.h.default include/SDL_config.h.in include/SDL_config_os2.h include/SDL_thread.h include/begin_code.h src/SDL.c src/audio/dart/SDL_dart.c src/audio/dart/SDL_dart.h src/events/SDL_events.c src/events/SDL_sysevents.h src/joystick/os2/SDL_sysjoystick.c src/joystick/os2/joyos2.h src/loadso/os2/SDL_sysloadso.c src/power/SDL_power.c src/power/os2/SDL_syspower.c src/thread/SDL_thread_c.h src/thread/os2/SDL_syscond.c src/thread/os2/SDL_syscond_c.h src/thread/os2/SDL_sysmutex.c src/thread/os2/SDL_syssem.c src/thread/os2/SDL_systhread.c src/thread/os2/SDL_systhread_c.h src/timer/os2/SDL_systimer.c src/video/SDL_sysvideo.h src/video/SDL_video.c src/video/os2fslib/SDL_os2fslib.c src/video/os2fslib/SDL_os2fslib.h src/video/os2fslib/SDL_vkeys.h |
diffstat | 33 files changed, 8 insertions(+), 6358 deletions(-) [+] |
line wrap: on
line diff
--- a/README Sat Sep 19 06:24:07 2009 +0000 +++ b/README Sat Sep 19 06:43:45 2009 +0000 @@ -15,7 +15,7 @@ The current version supports Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. The code contains support for Dreamcast, Atari, AIX, OSF/Tru64, -RISC OS, SymbianOS, and OS/2, but these are not officially supported. +RISC OS, SymbianOS, but these are not officially supported. SDL is written in C, but works with C++ natively, and has bindings to several other languages, including Ada, C#, Eiffel, Erlang, Euphoria,
--- a/README.OS2 Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,278 +0,0 @@ - -=========== -SDL on OS/2 -=========== - -Last updated on May. 1, 2006. - - -1. How to compile? ------------------- - -To compile this, you'll need the followings installed: -- The OS/2 Developer's Toolkit -- The OpenWatcom compiler - (http://www.openwatcom.org) -- The FSLib library - (ftp://ftp.netlabs.org/pub/SDL) - -First of all, you have to unzip the Watcom-OS2.zip file. This will result in a -file called "makefile" and a file called "setvars.cmd" in this folder (and some -more files...). - -Please edit the second, fourth and fifth lines of setvars.cmd file -to set the folders where the toolkit, the OW compiler and the FSLib are. -You won't need NASM yet (The Netwide Assembler), you can leave that line. -Run setvars.cmd, and you should get a shell in which you can -compile SDL. - -Check the "makefile" file. There is a line in there which determines if the -resulting SDL.DLL will be a 'debug' or a 'release' build. The 'debug' version -is full of printf()'s, so if something goes wrong, its output can help a lot -for debugging. - -Then run "wmake". -This should create the SDL.DLL and the corresponding SDL.LIB file here. - -To test applications, it's a good idea to use the 'debug' build of SDL, and -redirect the standard output and standard error output to files, to see what -happens internally in SDL. -(like: testsprite >stdout.txt 2>stderr.txt) - -To rebuild SDL, use the following commands in this folder: -wmake clean -wmake - - - -2. How to compile the testapps? -------------------------------- - -Once you have SDL.DLL compiled, navigate into the 'test' folder, copy in there -the newly built SDL.DLL, and copy in there FSLib.DLL. - -Then run "wmake" in there to compile some of the testapps. - - - -3. What is missing? -------------------- - -The following things are missing from this SDL implementation: -- MMX, SSE and 3DNOW! optimized video blitters? -- HW Video surfaces -- OpenGL support - - - -4. Special Keys / Full-Screen support -------------------------------------- - -There are two special hot-keys implemented: -- Alt+Home switches between fullscreen and windowed mode -- Alt+End simulates closing the window (can be used as a Panic key) -Only the LEFT Alt key will work. - - - -5. Joysticks on SDL/2 ---------------------- - -The Joystick detection only works for standard joysticks (2 buttons, 2 axes -and the like). Therefore, if you use a non-standard joystick, you should -specify its features in the SDL_OS2_JOYSTICK environment variable in a batch -file or CONFIG.SYS, so SDL applications can provide full capability to your -device. The syntax is: - -SET SDL_OS2_JOYSTICK=[JOYSTICK_NAME] [AXES] [BUTTONS] [HATS] [BALLS] - -So, it you have a Gravis GamePad with 4 axes, 2 buttons, 2 hats and 0 balls, -the line should be: - -SET SDL_OS2_JOYSTICK=Gravis_GamePad 4 2 2 0 - -If you want to add spaces in your joystick name, just surround it with -quotes or double-quotes: - -SET SDL_OS2_JOYSTICK='Gravis GamePad' 4 2 2 0 - -or - -SET SDL_OS2_JOYSTICK="Gravis GamePad" 4 2 2 0 - - Notive However that Balls and Hats are not supported under OS/2, and the -value will be ignored... but it is wise to define these correctly because -in the future those can be supported. - Also the number of buttons is limited to 2 when using two joysticks, -4 when using one joystick with 4 axes, 6 when using a joystick with 3 axes -and 8 when using a joystick with 2 axes. Notice however these are limitations -of the Joystick Port hardware, not OS/2. - - - -6. Proportional windows ------------------------ - -For some SDL applications it can be handy to have proportional windows, so -the windows will keep their aspect ratio when resized. -This can be achieved in two ways: - -- Before starting the given SDL application, set the - SDL_USE_PROPORTIONAL_WINDOW environment variable to something, e.g.: - - SET SDL_USE_PROPORTIONAL_WINDOW=1 - dosbox.exe - -- If you have a HOME environment variable set, then SDL will look for a file - in there called ".sdl.proportionals". If that file contains the name of the - currently running SDL executable, then that process will have proportional - windows automatically. - - Please note that this file is created automatically with default values - at the first run. - - - -7. Audio in SDL applications ----------------------------- - -Audio effects are one of the most important features in games. Creating audio -effects in sync with the game and without hickups and pauses in the audio are -very important things. - -However there are multithreaded SDL applications that have tight loops as their -main logic loop. This kills performance in OS/2, and takes too much CPU from -other threads in the same process, for example from the thread to create the -sound effects. - -For this reason, the OS/2 port of SDL can be instructed to run the audio thread -in high priority, which makes sure that there will be enough time for the -processing of the audio data. - -At default, SDL/2 runs the audio thread at ForegroundServer+0 priority. Well -written and well behaving SDL applications should work well in this mode. -For other applications, you can tell SDL/2 to run the audio thread at -TimeCritical priority by setting an env.variable before starting the SDL app: - - SET SDL_USE_TIMECRITICAL_AUDIO=1 - -Please note that this is a bit risky, because if the SDL application runs a -tight infinite loop in this thread, this will make the whole system -unresponsive, so use it with care, and only for applications that need it! - - - -8. Next steps... ----------------- - -Things to do: -- Implement missing stuffs (look for 'TODO' string in source code!) -- Finish video driver (the 'wincommon' can be a good example for missing - things like application icon and so on...) -- Enable MMX/SSE/SSE2 acceleration functions - - - -9. Contacts ------------ - - You can contact the developers for bugs: - - Area Developer email - General (Audio/Video/System) Doodle doodle@scenergy.dfmk.hu - CDROM and Joystick Caetano daniel@caetano.eng.br - - Notice however that SDL/2 is 'in development' stage so ... if you want to help, -please, be our guest and contact us! - - - -10. Changelog of the OS/2 port ------------------------------- - -Version 1.2 - 2006-05-01 - Doodle - - Modified makefile system to have only one makefile - - Included FSLib headers, DLL and LIB file - -Version 1.2 - 2006-02-26 - Doodle - - Updated the official SDL version with the OS/2 specific changes. - - Added support for real unicode keycode conversion. - -Version 1.2.7 - 2006-01-20 - Doodle - - Added support for selectively using timecritical priority for - audio threads by SDL_USE_TIMECRITICAL_AUDIO environment variable. - (e.g.: - SET SDL_USE_TIMECRITICAL_AUDIO=1 - dosbox.exe - ) - -Version 1.2.7 - 2005-12-22 - Doodle - - Added support for proportional SDL windows. - There are two ways to have proportional (aspect-keeping) windows for - a given SDL application: Either set the SDL_USE_PROPORTIONAL_WINDOW - environment variable to something before starting the application - (e.g.: - SET SDL_USE_PROPORTIONAL_WINDOW=1 - dosbox.exe - ) - or, if you have the HOME environment variable set, then SDL.DLL will - create a file in that directory called .sdl.proportionals, and you can - put there the name of executable files that will be automatically made - proportional. - -Version 1.2.7 - 2005-10-14 - Doodle - - Enabled Exception handler code in FSLib to be able to restore original - desktop video mode in case the application crashes. - - Added the missing FSLib_Uninitialize() call into SDL. - (The lack of it did not cause problems, but it's cleaner this way.) - - Fixed a mouse problem in Fullscreen mode where any mouse click - re-centered the mouse. - -Version 1.2.7 - 2005-10-09 - Doodle - - Implemented window icon support - -Version 1.2.7 - 2005-10-03 - Doodle - - Reworked semaphore support again - - Tuned thread priorities - -Version 1.2.7 - 2005-10-02 - Doodle - - Added support for custom mouse pointers - - Fixed WM_CLOSE processing: give a chance to SDL app to ask user... - - Added support for MMX-accelerated audio mixers - - Other small fixes - -Version 1.2.7 - 2005-09-12 - Doodle - - Small fixes for DosBox incorporated into public release - - Fixed semaphore support (SDL_syssem.c) - - Fixed FSLib to have good clipping in scaled window mode, - and to prevent occasional desktop freezes. - -Version 1.2.7 - 2004-09-08a - Caetano - - Improved joystick support (general verifications about hardware). - - Added support up to 8 buttons in 2 axes joysticks and 6 buttons in 3 axes joysticks. - - Added support to environment variable SDL_OS2_JOYSTICK to specify a joystick. - - Improved Joystick test to handle every type of joystick and display only relevant information. - - Merged with Doodle 2004-09-08 - - Little tid up in README.OS2 - - Added explanation about SDL_OS2_JOYSTICK environment variable on README.OS2 - -Version 1.2.7 - 2004-09-07 - Caetano - - Merged with changes in headers for GCC compiling. - - Added Joystick support using basic IBM GAME$ support, allowing it to work with all joystick drivers since OS/2 2.1. - - Improved joystick detection (hacked!). OS/2 do not allow real joystick detection, so... - - Modified makefile in test to compile "testjoystick". Anyway, it's useless, since it seems to cause a lot of trouble in OS/2 (because os video routines, not Joystick support). - - Created separated Joystick test program to test only joystick functions. - - Improved joystick auto-centering. - - Improved the coordinate correction routine to use two scale factors for each axis. - -Version 1.2.7 - 2004-07-05 - Caetano - - Corrected the time returned by status in CDROM support (it was incorrect) - - Added the testcdrom.c and corrected the linking directive (it was causing an error) - -Version 1.2.7 - 2004-07-02a - Caetano - - Corrected a little problem in a comment at SDL-1.2.7\test\torturethread.c, line 18 (missing */, nested comment) - - Added CDROM support to tree (SDL-1.2.7\src\cdrom\os2\SDL_syscdrom.c) - - Modified makefile (SDL-1.2.7\src\makefiles.wat and SDL-1.2.7\watcom.mif) to build with CDROM support - - Added the "extra" SDL_types.h forgotten in 2004-07-02 version. - -<End-Of-File>
--- a/docs.html Sat Sep 19 06:24:07 2009 +0000 +++ b/docs.html Sat Sep 19 06:43:45 2009 +0000 @@ -163,13 +163,6 @@ Icons set with SDL_WM_SetIcon() now have the proper colors on Intel Macs. </BLOCKQUOTE> -<H3> OS/2 Notes </H3> - -<BLOCKQUOTE> -<P> - Projects for building SDL on OS/2 with OpenWatcom have been contributed by Doodle. See the file README.OS2 in the SDL source distribution for details. -</BLOCKQUOTE> - <IMG SRC="docs/images/rainbow.gif" ALT="[separator]" WIDTH="100%"> </BODY>
--- a/include/SDL.h Sat Sep 19 06:24:07 2009 +0000 +++ b/include/SDL.h Sat Sep 19 06:43:45 2009 +0000 @@ -39,7 +39,7 @@ The current version supports Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX. The code contains support for Dreamcast, Atari, AIX, OSF/Tru64, -RISC OS, SymbianOS, and OS/2, but these are not officially supported. +RISC OS, SymbianOS, but these are not officially supported. SDL is written in C, but works with C++ natively, and has bindings to several other languages, including Ada, C#, Eiffel, Erlang, Euphoria,
--- a/include/SDL_config.h.default Sat Sep 19 06:24:07 2009 +0000 +++ b/include/SDL_config.h.default Sat Sep 19 06:43:45 2009 +0000 @@ -36,8 +36,6 @@ #include "SDL_config_macosx.h" #elif defined(__WIN32__) #include "SDL_config_win32.h" -#elif defined(__OS2__) -#include "SDL_config_os2.h" #else #include "SDL_config_minimal.h" #endif /* platform config */
--- a/include/SDL_config.h.in Sat Sep 19 06:24:07 2009 +0000 +++ b/include/SDL_config.h.in Sat Sep 19 06:43:45 2009 +0000 @@ -214,7 +214,6 @@ #undef SDL_JOYSTICK_LINUX #undef SDL_JOYSTICK_MINT #undef SDL_JOYSTICK_NDS -#undef SDL_JOYSTICK_OS2 #undef SDL_JOYSTICK_RISCOS #undef SDL_JOYSTICK_WINMM #undef SDL_JOYSTICK_USBHID @@ -230,14 +229,12 @@ #undef SDL_LOADSO_DLOPEN #undef SDL_LOADSO_DUMMY #undef SDL_LOADSO_LDG -#undef SDL_LOADSO_OS2 #undef SDL_LOADSO_WIN32 /* Enable various threading systems */ #undef SDL_THREAD_BEOS #undef SDL_THREAD_DC #undef SDL_THREAD_NDS -#undef SDL_THREAD_OS2 #undef SDL_THREAD_PTH #undef SDL_THREAD_PTHREAD #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX @@ -251,7 +248,6 @@ #undef SDL_TIMER_DUMMY #undef SDL_TIMER_MINT #undef SDL_TIMER_NDS -#undef SDL_TIMER_OS2 #undef SDL_TIMER_RISCOS #undef SDL_TIMER_UNIX #undef SDL_TIMER_WIN32 @@ -268,7 +264,6 @@ #undef SDL_VIDEO_DRIVER_GEM #undef SDL_VIDEO_DRIVER_NANOX #undef SDL_VIDEO_DRIVER_NDS -#undef SDL_VIDEO_DRIVER_OS2FS #undef SDL_VIDEO_DRIVER_PHOTON #undef SDL_VIDEO_DRIVER_QNXGF #undef SDL_VIDEO_DRIVER_PS2GS @@ -315,7 +310,6 @@ #undef SDL_POWER_LINUX #undef SDL_POWER_WINDOWS #undef SDL_POWER_MACOSX -#undef SDL_POWER_OS2 #undef SDL_POWER_BEOS #undef SDL_POWER_NINTENDODS #undef SDL_POWER_HARDWIRED
--- a/include/SDL_config_os2.h Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ - -#ifndef _SDL_config_os2_h -#define _SDL_config_os2_h - -#include "SDL_platform.h" - -/* This is a set of defines to configure the SDL features */ - -#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef signed short int16_t; -typedef unsigned short uint16_t; -typedef signed int int32_t; -typedef unsigned int uint32_t; -typedef unsigned int size_t; -typedef unsigned long uintptr_t; -typedef signed long long int64_t; -typedef unsigned long long uint64_t; -#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ - -#define SIZEOF_VOIDP 4 -#define SDL_HAS_64BIT_TYPE 1 - -/* Use Watcom's LIBC */ -#define HAVE_LIBC 1 - -/* Useful headers */ -#define HAVE_SYS_TYPES_H 1 -#define HAVE_STDIO_H 1 -#define STDC_HEADERS 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STDARG_H 1 -#define HAVE_MALLOC_H 1 -#define HAVE_MEMORY_H 1 -#define HAVE_STRING_H 1 -#define HAVE_STRINGS_H 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_STDINT_H 1 -#define HAVE_CTYPE_H 1 -#define HAVE_MATH_H 1 -#define HAVE_SIGNAL_H 1 - -/* C library functions */ -#define HAVE_MALLOC 1 -#define HAVE_CALLOC 1 -#define HAVE_REALLOC 1 -#define HAVE_FREE 1 -#define HAVE_ALLOCA 1 -#define HAVE_GETENV 1 -#define HAVE_PUTENV 1 -#define HAVE_UNSETENV 1 -#define HAVE_QSORT 1 -#define HAVE_ABS 1 -#define HAVE_BCOPY 1 -#define HAVE_MEMSET 1 -#define HAVE_MEMCPY 1 -#define HAVE_MEMMOVE 1 -#define HAVE_MEMCMP 1 -#define HAVE_STRLEN 1 -#define HAVE_STRLCPY 1 -#define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 -#define HAVE__STRREV 1 -#define HAVE__STRUPR 1 -#define HAVE__STRLWR 1 -#define HAVE_INDEX 1 -#define HAVE_RINDEX 1 -#define HAVE_STRCHR 1 -#define HAVE_STRRCHR 1 -#define HAVE_STRSTR 1 -#define HAVE_ITOA 1 -#define HAVE__LTOA 1 -#define HAVE__UITOA 1 -#define HAVE__ULTOA 1 -#define HAVE_STRTOL 1 -#define HAVE__I64TOA 1 -#define HAVE__UI64TOA 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_STRCASECMP 1 -#define HAVE_SSCANF 1 -#define HAVE_SNPRINTF 1 -#define HAVE_VSNPRINTF 1 -#define HAVE_SETJMP 1 -#define HAVE_CLOCK_GETTIME 1 - -/* Enable various audio drivers */ -#define SDL_AUDIO_DRIVER_DART 1 -#define SDL_AUDIO_DRIVER_DISK 1 -#define SDL_AUDIO_DRIVER_DUMMY 1 - -/* Enable various input drivers */ -#define SDL_JOYSTICK_OS2 1 -#define SDL_HAPTIC_DUMMY 1 - -/* Enable various shared object loading systems */ -#define SDL_LOADSO_OS2 1 - -/* Enable various threading systems */ -#define SDL_THREAD_OS2 1 - -/* Enable various timer systems */ -#define SDL_TIMER_OS2 1 - -/* Enable various video drivers */ -#define SDL_VIDEO_DRIVER_DUMMY 1 -#define SDL_VIDEO_DRIVER_OS2FS 1 - -/* Enable OpenGL support */ -/* Nothing here yet for OS/2... :( */ - -/* Enable system power support */ -#define SDL_POWER_OS2 1 - -/* Enable assembly routines where available */ -#define SDL_ASSEMBLY_ROUTINES 1 - -#endif /* _SDL_config_os2_h */
--- a/include/SDL_thread.h Sat Sep 19 06:24:07 2009 +0000 +++ b/include/SDL_thread.h Sat Sep 19 06:43:45 2009 +0000 @@ -48,9 +48,9 @@ typedef struct SDL_Thread SDL_Thread; /* Create a thread */ -#if (defined(__WIN32__) && !defined(HAVE_LIBC)) || defined(__OS2__) +#if defined(__WIN32__) && !defined(HAVE_LIBC) /* - We compile SDL into a DLL on OS/2. This means, that it's the DLL which + We compile SDL into a DLL. This means, that it's the DLL which creates a new thread for the calling process with the SDL_CreateThread() API. There is a problem with this, that only the RTL of the SDL.DLL will be initialized for those threads, and not the RTL of the calling application! @@ -67,11 +67,7 @@ #include <process.h> /* This has _beginthread() and _endthread() defined! */ #endif -#ifdef __OS2__ -typedef int (*pfnSDL_CurrentBeginThread) (void (*func) (void *), void *, - unsigned, void *arg); -typedef void (*pfnSDL_CurrentEndThread) (void); -#elif __GNUC__ +#ifdef __GNUC__ typedef unsigned long (__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, unsigned (__stdcall * @@ -96,9 +92,7 @@ pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); -#ifdef __OS2__ -#define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthread, _endthread) -#elif defined(_WIN32_WCE) +#if defined(_WIN32_WCE) #define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, NULL, NULL) #else #define SDL_CreateThread(fn, data) SDL_CreateThread(fn, data, _beginthreadex, _endthreadex)
--- a/include/begin_code.h Sat Sep 19 06:24:07 2009 +0000 +++ b/include/begin_code.h Sat Sep 19 06:43:45 2009 +0000 @@ -49,16 +49,6 @@ # else # define DECLSPEC __declspec(dllexport) # endif -# elif defined(__OS2__) -# ifdef __WATCOMC__ -# ifdef BUILD_SDL -# define DECLSPEC __declspec(dllexport) -# else -# define DECLSPEC -# endif -# else -# define DECLSPEC -# endif # else # if defined(__GNUC__) && __GNUC__ >= 4 # define DECLSPEC __attribute__ ((visibility("default"))) @@ -73,14 +63,8 @@ #if defined(__WIN32__) && !defined(__GNUC__) #define SDLCALL __cdecl #else -#ifdef __OS2__ -/* But on OS/2, we use the _System calling convention */ -/* to be compatible with every compiler */ -#define SDLCALL _System -#else #define SDLCALL #endif -#endif #endif /* SDLCALL */ /* Removed DECLSPEC on Symbian OS because SDL cannot be a DLL in EPOC */
--- a/src/SDL.c Sat Sep 19 06:24:07 2009 +0000 +++ b/src/SDL.c Sat Sep 19 06:43:45 2009 +0000 @@ -277,76 +277,7 @@ return SDL_REVISION; } -#if defined(__OS2__) -/* Building for OS/2 */ -#ifdef __WATCOMC__ - -#define INCL_DOSERRORS -#define INCL_DOSEXCEPTIONS -#include <os2.h> - -/* Exception handler to prevent the Audio thread hanging, making a zombie process! */ -ULONG _System -SDL_Main_ExceptionHandler(PEXCEPTIONREPORTRECORD pERepRec, - PEXCEPTIONREGISTRATIONRECORD pERegRec, - PCONTEXTRECORD pCtxRec, PVOID p) -{ - if (pERepRec->fHandlerFlags & EH_EXIT_UNWIND) - return XCPT_CONTINUE_SEARCH; - if (pERepRec->fHandlerFlags & EH_UNWINDING) - return XCPT_CONTINUE_SEARCH; - if (pERepRec->fHandlerFlags & EH_NESTED_CALL) - return XCPT_CONTINUE_SEARCH; - - /* Do cleanup at every fatal exception! */ - if (((pERepRec->ExceptionNum & XCPT_SEVERITY_CODE) == - XCPT_FATAL_EXCEPTION) && (pERepRec->ExceptionNum != XCPT_BREAKPOINT) - && (pERepRec->ExceptionNum != XCPT_SINGLE_STEP)) { - if (SDL_initialized & SDL_INIT_AUDIO) { - /* This removes the zombie audio thread in case of emergency. */ -#ifdef DEBUG_BUILD - printf - ("[SDL_Main_ExceptionHandler] : Calling SDL_CloseAudio()!\n"); -#endif - SDL_CloseAudio(); - } - } - return (XCPT_CONTINUE_SEARCH); -} - - -EXCEPTIONREGISTRATIONRECORD SDL_Main_xcpthand = - { 0, SDL_Main_ExceptionHandler }; - -/* The main DLL entry for DLL Initialization and Uninitialization: */ -unsigned _System -LibMain(unsigned hmod, unsigned termination) -{ - if (termination) { -#ifdef DEBUG_BUILD -/* printf("[SDL DLL Unintialization] : Removing exception handler\n"); */ -#endif - DosUnsetExceptionHandler(&SDL_Main_xcpthand); - return 1; - } else { -#ifdef DEBUG_BUILD - /* Make stdout and stderr unbuffered! */ - setbuf(stdout, NULL); - setbuf(stderr, NULL); -#endif - /* Fire up exception handler */ -#ifdef DEBUG_BUILD -/* printf("[SDL DLL Initialization] : Setting exception handler\n"); */ -#endif - /* Set exception handler */ - DosSetExceptionHandler(&SDL_Main_xcpthand); - - return 1; - } -} -#endif /* __WATCOMC__ */ - -#elif defined(__WIN32__) +#if defined(__WIN32__) #if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL)) /* Need to include DllMain() on Watcom C for some reason.. */ @@ -368,6 +299,6 @@ } #endif /* building DLL with Watcom C */ -#endif /* OS/2 elif __WIN32__ */ +#endif /* __WIN32__ */ /* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dart/SDL_dart.c Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,448 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" - -/* Allow access to a raw mixing buffer */ - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "SDL_dart.h" - -// Buffer states: -#define BUFFER_EMPTY 0 -#define BUFFER_USED 1 - -typedef struct _tMixBufferDesc -{ - int iBufferUsage; // BUFFER_EMPTY or BUFFER_USED - SDL_AudioDevice *pSDLAudioDevice; -} tMixBufferDesc, *pMixBufferDesc; - - -//--------------------------------------------------------------------- -// DARTEventFunc -// -// This function is called by DART, when an event occurs, like end of -// playback of a buffer, etc... -//--------------------------------------------------------------------- -static LONG APIENTRY -DARTEventFunc(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags) -{ - if (ulFlags && MIX_WRITE_COMPLETE) { // Playback of buffer completed! - - // Get pointer to buffer description - pMixBufferDesc pBufDesc; - - if (pBuffer) { - pBufDesc = (pMixBufferDesc) (*pBuffer).ulUserParm; - - if (pBufDesc) { - SDL_AudioDevice *pSDLAudioDevice = pBufDesc->pSDLAudioDevice; - // Set the buffer to be empty - pBufDesc->iBufferUsage = BUFFER_EMPTY; - // And notify DART feeder thread that it will have to work a bit. - if (pSDLAudioDevice) - DosPostEventSem(pSDLAudioDevice-> - hidden->hevAudioBufferPlayed); - } - } - } - return TRUE; -} - - -static int -DART_OpenDevice(_THIS, const char *devname, int iscapture) -{ - SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format); - int valid_datatype = 0; - MCI_AMP_OPEN_PARMS AmpOpenParms; - int iDeviceOrd = 0; // Default device to be used - int bOpenShared = 1; // Try opening it shared - int iBits = 16; // Default is 16 bits signed - int iFreq = 44100; // Default is 44KHz - int iChannels = 2; // Default is 2 channels (Stereo) - int iNumBufs = 2; // Number of audio buffers: 2 - int iBufSize; - int iOpenMode; - int iSilence; - int rc; - - /* Initialize all variables that we clean on shutdown */ - _this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *_this->hidden)); - if (_this->hidden == NULL) { - SDL_OutOfMemory(); - return 0; - } - SDL_memset(_this->hidden, 0, (sizeof *_this->hidden)); - - // First thing is to try to open a given DART device! - SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS)); - // pszDeviceType should contain the device type in low word, and device ordinal in high word! - AmpOpenParms.pszDeviceType = - (PSZ) (MCI_DEVTYPE_AUDIO_AMPMIX | (iDeviceOrd << 16)); - - iOpenMode = MCI_WAIT | MCI_OPEN_TYPE_ID; - if (bOpenShared) - iOpenMode |= MCI_OPEN_SHAREABLE; - - rc = mciSendCommand(0, MCI_OPEN, iOpenMode, (PVOID) & AmpOpenParms, 0); - if (rc != MCIERR_SUCCESS) { // No audio available?? - DART_CloseDevice(_this); - SDL_SetError("DART: Couldn't open audio device."); - return 0; - } - // Save the device ID we got from DART! - // We will use this in the next calls! - _this->hidden->iCurrDeviceOrd = iDeviceOrd = AmpOpenParms.usDeviceID; - - // Determine the audio parameters from the AudioSpec - if (_this->spec.channels > 4) - _this->spec.channels = 4; - - while ((!valid_datatype) && (test_format)) { - _this->spec.format = test_format; - valid_datatype = 1; - switch (test_format) { - case AUDIO_U8: - // Unsigned 8 bit audio data - iSilence = 0x80; - _this->hidden->iCurrBits = iBits = 8; - break; - - case AUDIO_S16LSB: - // Signed 16 bit audio data - iSilence = 0x00; - _this->hidden->iCurrBits = iBits = 16; - break; - - // !!! FIXME: int32? - - default: - valid_datatype = 0; - test_format = SDL_NextAudioFormat(); - break; - } - } - - if (!valid_datatype) { // shouldn't happen, but just in case... - // Close DART, and exit with error code! - DART_CloseDevice(_this); - SDL_SetError("Unsupported audio format"); - return 0; - } - - _this->hidden->iCurrFreq = iFreq = _this->spec.freq; - _this->hidden->iCurrChannels = iChannels = _this->spec.channels; - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&_this->spec); - _this->hidden->iCurrBufSize = iBufSize = _this->spec.size; - - // Now query this device if it supports the given freq/bits/channels! - SDL_memset(&(_this->hidden->MixSetupParms), 0, - sizeof(MCI_MIXSETUP_PARMS)); - _this->hidden->MixSetupParms.ulBitsPerSample = iBits; - _this->hidden->MixSetupParms.ulFormatTag = MCI_WAVE_FORMAT_PCM; - _this->hidden->MixSetupParms.ulSamplesPerSec = iFreq; - _this->hidden->MixSetupParms.ulChannels = iChannels; - _this->hidden->MixSetupParms.ulFormatMode = MCI_PLAY; - _this->hidden->MixSetupParms.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; - _this->hidden->MixSetupParms.pmixEvent = DARTEventFunc; - rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP, - MCI_WAIT | MCI_MIXSETUP_QUERYMODE, - &(_this->hidden->MixSetupParms), 0); - if (rc != MCIERR_SUCCESS) { // The device cannot handle this format! - // Close DART, and exit with error code! - DART_CloseDevice(_this); - SDL_SetError("Audio device doesn't support requested audio format"); - return 0; - } - // The device can handle this format, so initialize! - rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP, - MCI_WAIT | MCI_MIXSETUP_INIT, - &(_this->hidden->MixSetupParms), 0); - if (rc != MCIERR_SUCCESS) { // The device could not be opened! - // Close DART, and exit with error code! - DART_CloseDevice(_this); - SDL_SetError("Audio device could not be set up"); - return 0; - } - // Ok, the device is initialized. - // Now we should allocate buffers. For this, we need a place where - // the buffer descriptors will be: - _this->hidden->pMixBuffers = - (MCI_MIX_BUFFER *) SDL_malloc(sizeof(MCI_MIX_BUFFER) * iNumBufs); - if (!(_this->hidden->pMixBuffers)) { // Not enough memory! - // Close DART, and exit with error code! - DART_CloseDevice(_this); - SDL_OutOfMemory(); - return 0; - } - // Now that we have the place for buffer list, we can ask DART for the - // buffers! - _this->hidden->BufferParms.ulNumBuffers = iNumBufs; // Number of buffers - _this->hidden->BufferParms.ulBufferSize = iBufSize; // each with this size - _this->hidden->BufferParms.pBufList = _this->hidden->pMixBuffers; // getting descriptorts into this list - // Allocate buffers! - rc = mciSendCommand(iDeviceOrd, MCI_BUFFER, - MCI_WAIT | MCI_ALLOCATE_MEMORY, - &(_this->hidden->BufferParms), 0); - if ((rc != MCIERR_SUCCESS) - || (iNumBufs != _this->hidden->BufferParms.ulNumBuffers) - || (_this->hidden->BufferParms.ulBufferSize == 0)) { // Could not allocate memory! - // Close DART, and exit with error code! - DART_CloseDevice(_this); - SDL_SetError("DART could not allocate buffers"); - return 0; - } - _this->hidden->iCurrNumBufs = iNumBufs; - - // Ok, we have all the buffers allocated, let's mark them! - { - int i; - for (i = 0; i < iNumBufs; i++) { - pMixBufferDesc pBufferDesc = - (pMixBufferDesc) SDL_malloc(sizeof(tMixBufferDesc));; - // Check if this buffer was really allocated by DART - if ((!(_this->hidden->pMixBuffers[i].pBuffer)) - || (!pBufferDesc)) { // Wrong buffer! - DART_CloseDevice(_this); - SDL_SetError("Error at internal buffer check"); - return 0; - } - pBufferDesc->iBufferUsage = BUFFER_EMPTY; - pBufferDesc->pSDLAudioDevice = _this; - - _this->hidden->pMixBuffers[i].ulBufferLength = - _this->hidden->BufferParms.ulBufferSize; - _this->hidden->pMixBuffers[i].ulUserParm = (ULONG) pBufferDesc; // User parameter: Description of buffer - _this->hidden->pMixBuffers[i].ulFlags = 0; // Some stuff should be flagged here for DART, like end of - // audio data, but as we will continously send - // audio data, there will be no end.:) - SDL_memset(_this->hidden->pMixBuffers[i].pBuffer, iSilence, - iBufSize); - } - } - _this->hidden->iNextFreeBuffer = 0; - _this->hidden->iLastPlayedBuf = -1; - // Create event semaphore - if (DosCreateEventSem - (NULL, &(_this->hidden->hevAudioBufferPlayed), 0, FALSE) != NO_ERROR) - { - DART_CloseDevice(_this); - SDL_SetError("Could not create event semaphore"); - return 0; - } - - return 1; -} - -static void -DART_ThreadInit(_THIS) -{ - /* Increase the priority of this thread to make sure that - the audio will be continuous all the time! */ -#ifdef USE_DOSSETPRIORITY - if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) { -#ifdef DEBUG_BUILD - printf - ("[DART_ThreadInit] : Setting priority to TimeCritical+0! (TID%d)\n", - SDL_ThreadID()); -#endif - DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); - } else { -#ifdef DEBUG_BUILD - printf - ("[DART_ThreadInit] : Setting priority to ForegroundServer+0! (TID%d)\n", - SDL_ThreadID()); -#endif - DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0); - } -#endif -} - -/* This function waits until it is possible to write a full sound buffer */ -static void -DART_WaitDevice(_THIS) -{ - int i; - pMixBufferDesc pBufDesc; - ULONG ulPostCount; - - DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount); - // If there is already an empty buffer, then return now! - for (i = 0; i < _this->hidden->iCurrNumBufs; i++) { - pBufDesc = (pMixBufferDesc) _this->hidden->pMixBuffers[i].ulUserParm; - if (pBufDesc->iBufferUsage == BUFFER_EMPTY) - return; - } - // If there is no empty buffer, wait for one to be empty! - DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // Wait max 1 sec!!! Important! - return; -} - -static void -DART_PlayDevice(_THIS) -{ - int iFreeBuf = _this->hidden->iNextFreeBuffer; - pMixBufferDesc pBufDesc; - - pBufDesc = - (pMixBufferDesc) _this->hidden->pMixBuffers[iFreeBuf].ulUserParm; - pBufDesc->iBufferUsage = BUFFER_USED; - // Send it to DART to be queued - _this->hidden->MixSetupParms.pmixWrite(_this->hidden-> - MixSetupParms.ulMixHandle, - &(_this-> - hidden->pMixBuffers[iFreeBuf]), - 1); - - _this->hidden->iLastPlayedBuf = iFreeBuf; - iFreeBuf = (iFreeBuf + 1) % _this->hidden->iCurrNumBufs; - _this->hidden->iNextFreeBuffer = iFreeBuf; -} - -static Uint8 * -DART_GetDeviceBuf(_THIS) -{ - int iFreeBuf; - Uint8 *pResult; - pMixBufferDesc pBufDesc; - - if (_this) { - if (_this->hidden) { - iFreeBuf = _this->hidden->iNextFreeBuffer; - pBufDesc = - (pMixBufferDesc) _this->hidden-> - pMixBuffers[iFreeBuf].ulUserParm; - - if (pBufDesc) { - if (pBufDesc->iBufferUsage == BUFFER_EMPTY) { - pResult = _this->hidden->pMixBuffers[iFreeBuf].pBuffer; - return pResult; - } - } else - printf("[DART_GetDeviceBuf] : ERROR! pBufDesc = %p\n", - pBufDesc); - } else - printf("[DART_GetDeviceBuf] : ERROR! _this->hidden = %p\n", - _this->hidden); - } else - printf("[DART_GetDeviceBuf] : ERROR! _this = %p\n", _this); - return NULL; -} - -static void -DART_WaitDone(_THIS) -{ - pMixBufferDesc pBufDesc; - ULONG ulPostCount = 0; - APIRET rc = NO_ERROR; - - pBufDesc = (pMixBufferDesc) - _this->hidden->pMixBuffers[_this->hidden->iLastPlayedBuf].ulUserParm; - - while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc == NO_ERROR)) { - DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount); - rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // 1 sec timeout! Important! - } -} - -static void -DART_CloseDevice(_THIS) -{ - MCI_GENERIC_PARMS GenericParms; - int rc; - int i; - - if (_this->hidden != NULL) { - // Stop DART playback - if (_this->hidden->iCurrDeviceOrd) { - rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP, - MCI_WAIT, &GenericParms, 0); -#ifdef SFX_DEBUG_BUILD - if (rc != MCIERR_SUCCESS) { - printf("Could not stop DART playback!\n"); - fflush(stdout); - } -#endif - } - // Close event semaphore - if (_this->hidden->hevAudioBufferPlayed) { - DosCloseEventSem(_this->hidden->hevAudioBufferPlayed); - _this->hidden->hevAudioBufferPlayed = 0; - } - // Free memory of buffer descriptions - for (i = 0; i < _this->hidden->iCurrNumBufs; i++) { - SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm)); - _this->hidden->pMixBuffers[i].ulUserParm = 0; - } - _this->hidden->iCurrNumBufs = 0; - - // Deallocate buffers - if (_this->hidden->iCurrDeviceOrd) { - rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER, - MCI_WAIT | MCI_DEALLOCATE_MEMORY, - &(_this->hidden->BufferParms), 0); - } - // Free bufferlist - if (_this->hidden->pMixBuffers != NULL) { - SDL_free(_this->hidden->pMixBuffers); - _this->hidden->pMixBuffers = NULL; - } - // Close dart - if (_this->hidden->iCurrDeviceOrd) { - rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE, - MCI_WAIT, &(GenericParms), 0); - } - _this->hidden->iCurrDeviceOrd = 0; - - SDL_free(_this->hidden); - _this->hidden = NULL; - } -} - - -static int -DART_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->OpenDevice = DART_OpenDevice; - impl->ThreadInit = DART_ThreadInit; - impl->WaitDevice = DART_WaitDevice; - impl->GetDeviceBuf = DART_GetDeviceBuf; - impl->PlayDevice = DART_PlayDevice; - impl->WaitDone = DART_WaitDone; - impl->CloseDevice = DART_CloseDevice; - impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: is this right? */ - - return 1; -} - - -AudioBootStrap DART_bootstrap = { - "dart", "OS/2 Direct Audio RouTines (DART)", DART_Init, 0 -}; - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dart/SDL_dart.h Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" - -#ifndef _SDL_dart_h -#define _SDL_dart_h - -#define INCL_TYPES -#define INCL_DOSSEMAPHORES -#define INCL_DOSRESOURCES -#define INCL_DOSMISC -#define INCL_DOSERRORS -#define INCL_DOSPROCESS - -#define INCL_OS2MM -#define INCL_MMIOOS2 -#define INCL_MCIOS2 -#include <os2.h> -#include <os2me.h> // DART stuff and MMIO stuff - -#include "../SDL_sysaudio.h" - -/* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *_this - -/* The DirectSound objects */ -struct SDL_PrivateAudioData -{ - int iCurrDeviceOrd; - int iCurrFreq; - int iCurrBits; - int iCurrChannels; - int iCurrNumBufs; - int iCurrBufSize; - - int iLastPlayedBuf; - int iNextFreeBuffer; - - MCI_BUFFER_PARMS BufferParms; // Sound buffer parameters - MCI_MIX_BUFFER *pMixBuffers; // Sound buffers - MCI_MIXSETUP_PARMS MixSetupParms; // Mixer setup parameters - HEV hevAudioBufferPlayed; // Event semaphore to indicate that an audio buffer has been played by DART -}; - -#endif /* _SDL_dart_h */ - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/events/SDL_events.c Sat Sep 19 06:24:07 2009 +0000 +++ b/src/events/SDL_events.c Sat Sep 19 06:43:45 2009 +0000 @@ -84,29 +84,11 @@ } } -#ifdef __OS2__ -/* - * We'll increase the priority of GobbleEvents thread, so it will process - * events in time for sure! For this, we need the DosSetPriority() API - * from the os2.h include file. - */ -#define INCL_DOSPROCESS -#include <os2.h> -#include <time.h> -#endif - static int SDLCALL SDL_GobbleEvents(void *unused) { event_thread = SDL_ThreadID(); -#ifdef __OS2__ -#ifdef USE_DOSSETPRIORITY - /* Increase thread priority, so it will process events in time for sure! */ - DosSetPriority(PRTYS_THREAD, PRTYC_REGULAR, +16, 0); -#endif -#endif - while (SDL_EventQ.active) { SDL_VideoDevice *_this = SDL_GetVideoDevice();
--- a/src/events/SDL_sysevents.h Sat Sep 19 06:24:07 2009 +0000 +++ b/src/events/SDL_sysevents.h Sat Sep 19 06:43:45 2009 +0000 @@ -33,8 +33,4 @@ #define CANT_THREAD_EVENTS #endif -#ifdef __OS2__ /* The OS/2 event loop runs in a separate thread */ -#define MUST_THREAD_EVENTS -#endif - /* vi: set ts=4 sw=4 expandtab: */
--- a/src/joystick/os2/SDL_sysjoystick.c Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,698 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" - -#ifdef SDL_JOYSTICK_OS2 - -/* OS/2 Joystick driver, contributed by Daniel Caetano */ - -#include <mem.h> - -#define INCL_DOSDEVICES -#define INCL_DOSDEVIOCTL -#define INCL_DOSMEMMGR -#include <os2.h> -#include "joyos2.h" - -#include "SDL_joystick.h" -#include "SDL_events.h" -#include "../SDL_sysjoystick.h" -#include "../SDL_joystick_c.h" - -HFILE hJoyPort = NULL; /* Joystick GAME$ Port Address */ -#define MAX_JOYSTICKS 2 /* Maximum of two joysticks */ -#define MAX_AXES 4 /* each joystick can have up to 4 axes */ -#define MAX_BUTTONS 8 /* 8 buttons */ -#define MAX_HATS 0 /* 0 hats - OS/2 doesn't support it */ -#define MAX_BALLS 0 /* and 0 balls - OS/2 doesn't support it */ -#define AXIS_MIN -32768 /* minimum value for axes coordinate */ -#define AXIS_MAX 32767 /* maximum value for axes coordinate */ -#define MAX_JOYNAME 128 /* Joystick name may have 128 characters */ -/* limit axes to 256 possible positions to filter out noise */ -#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/256) -/* Calc Button Flag for buttons A to D */ -#define JOY_BUTTON_FLAG(n) (1<<n) - -/* Joystick data... hold information about detected devices */ -typedef struct SYS_JoyData_s -{ - Sint8 id; // Device ID - char szDeviceName[MAX_JOYNAME]; // Device Name - char axes; // Number of axes - char buttons; // Number of buttons - char hats; // Number of buttons - char balls; // Number of buttons - int axes_min[MAX_AXES]; // minimum callibration value for axes - int axes_med[MAX_AXES]; // medium callibration value for axes - int axes_max[MAX_AXES]; // maximum callibration value for axes - int buttoncalc[4]; // Used for buttons 5, 6, 7 and 8. -} SYS_JoyData_t, *SYS_JoyData_p; - -SYS_JoyData_t SYS_JoyData[MAX_JOYSTICKS]; - - -/* Structure used to convert data from OS/2 driver format to SDL format */ -struct joystick_hwdata -{ - Sint8 id; - struct _transaxes - { - int offset; /* Center Offset */ - float scale1; /* Center to left/up Scale */ - float scale2; /* Center to right/down Scale */ - } transaxes[MAX_AXES]; -}; - -/* Structure used to get values from Joystick Environment Variable */ -struct _joycfg -{ - char name[MAX_JOYNAME]; - unsigned int axes; - unsigned int buttons; - unsigned int hats; - unsigned int balls; -}; - -/* OS/2 Implementation Function Prototypes */ -APIRET joyPortOpen(HFILE * hGame); -void joyPortClose(HFILE * hGame); -int joyGetData(char *joyenv, char *name, char stopchar, size_t maxchars); -int joyGetEnv(struct _joycfg *joydata); - - - -/************************************************************************/ -/* Function to scan the system for joysticks. */ -/* This function should set SDL_numjoysticks to the number of available */ -/* joysticks. Joystick 0 should be the system default joystick. */ -/* It should return 0, or -1 on an unrecoverable fatal error. */ -/************************************************************************/ -int -SDL_SYS_JoystickInit(void) -{ - APIRET rc; /* Generic OS/2 return code */ - GAME_PORT_STRUCT stJoyStatus; /* Joystick Status Structure */ - GAME_PARM_STRUCT stGameParms; /* Joystick Parameter Structure */ - GAME_CALIB_STRUCT stGameCalib; /* Calibration Struct */ - ULONG ulDataLen; /* Size of data */ - ULONG ulLastTick; /* Tick Counter for timing operations */ - Uint8 maxdevs; /* Maximum number of devices */ - Uint8 numdevs; /* Number of present devices */ - Uint8 maxbut; /* Maximum number of buttons... */ - Uint8 i; /* Temporary Count Vars */ - Uint8 ucNewJoystickMask; /* Mask for Joystick Detection */ - struct _joycfg joycfg; /* Joy Configuration from envvar */ - - -/* Get Max Number of Devices */ - rc = joyPortOpen(&hJoyPort); /* Open GAME$ port */ - if (rc != 0) - return 0; /* Cannot open... report no joystick */ - ulDataLen = sizeof(stGameParms); - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_PARMS, NULL, 0, NULL, &stGameParms, ulDataLen, &ulDataLen); /* Ask device info */ - if (rc != 0) { - joyPortClose(&hJoyPort); - SDL_SetError("Could not read joystick port."); - return -1; - } - if (stGameParms.useA != 0) - maxdevs++; - if (stGameParms.useB != 0) - maxdevs++; - if (maxdevs > MAX_JOYSTICKS) - maxdevs = MAX_JOYSTICKS; - -/* Defines min/max axes values (callibration) */ - ulDataLen = sizeof(stGameCalib); - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_CALIB, - NULL, 0, NULL, &stGameCalib, ulDataLen, &ulDataLen); - if (rc != 0) { - joyPortClose(&hJoyPort); - SDL_SetError("Could not read callibration data."); - return -1; - } - -/* Determine how many joysticks are active */ - numdevs = 0; /* Points no device */ - ucNewJoystickMask = 0x0F; /* read all 4 joystick axis */ - ulDataLen = sizeof(ucNewJoystickMask); - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_RESET, - &ucNewJoystickMask, ulDataLen, &ulDataLen, NULL, 0, - NULL); - if (rc == 0) { - ulDataLen = sizeof(stJoyStatus); - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, - NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen); - if (rc != 0) { - joyPortClose(&hJoyPort); - SDL_SetError("Could not call joystick port."); - return -1; - } - ulLastTick = stJoyStatus.ulJs_Ticks; - while (stJoyStatus.ulJs_Ticks == ulLastTick) { - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, - NULL, 0, NULL, &stJoyStatus, ulDataLen, - &ulDataLen); - } - if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) - numdevs++; - if (((stJoyStatus.ucJs_JoyStickMask >> 2) & 0x03) > 0) - numdevs++; - } - - if (numdevs > maxdevs) - numdevs = maxdevs; - -/* If *any* joystick was detected... Let's configure SDL for them */ - if (numdevs > 0) { - /* Verify if it is a "user defined" joystick */ - if (joyGetEnv(&joycfg)) { - GAME_3POS_STRUCT *axis[4]; - axis[0] = &stGameCalib.Ax; - axis[1] = &stGameCalib.Ay; - axis[2] = &stGameCalib.Bx; - axis[3] = &stGameCalib.By; - /* Say it has one device only (user defined is always one device only) */ - numdevs = 1; - /* Define Device 0 as... */ - SYS_JoyData[0].id = 0; - /* Define Number of Axes... up to 4 */ - if (joycfg.axes > MAX_AXES) - joycfg.axes = MAX_AXES; - SYS_JoyData[0].axes = joycfg.axes; - /* Define number of buttons... 8 if 2 axes, 6 if 3 axes and 4 if 4 axes */ - maxbut = MAX_BUTTONS; - if (joycfg.axes > 2) - maxbut -= ((joycfg.axes - 2) << 1); /* MAX_BUTTONS - 2*(axes-2) */ - if (joycfg.buttons > maxbut) - joycfg.buttons = maxbut; - SYS_JoyData[0].buttons = joycfg.buttons; - /* Define number of hats */ - if (joycfg.hats > MAX_HATS) - joycfg.hats = MAX_HATS; - SYS_JoyData[0].hats = joycfg.hats; - /* Define number of balls */ - if (joycfg.balls > MAX_BALLS) - joycfg.balls = MAX_BALLS; - SYS_JoyData[0].balls = joycfg.balls; - /* Initialize Axes Callibration Values */ - for (i = 0; i < joycfg.axes; i++) { - SYS_JoyData[0].axes_min[i] = axis[i]->lower; - SYS_JoyData[0].axes_med[i] = axis[i]->centre; - SYS_JoyData[0].axes_max[i] = axis[i]->upper; - } - /* Initialize Buttons 5 to 8 structures */ - if (joycfg.buttons >= 5) - SYS_JoyData[0].buttoncalc[0] = - ((axis[2]->lower + axis[3]->centre) >> 1); - if (joycfg.buttons >= 6) - SYS_JoyData[0].buttoncalc[1] = - ((axis[3]->lower + axis[3]->centre) >> 1); - if (joycfg.buttons >= 7) - SYS_JoyData[0].buttoncalc[2] = - ((axis[2]->upper + axis[3]->centre) >> 1); - if (joycfg.buttons >= 8) - SYS_JoyData[0].buttoncalc[3] = - ((axis[3]->upper + axis[3]->centre) >> 1); - /* Intialize Joystick Name */ - SDL_strlcpy(SYS_JoyData[0].szDeviceName, joycfg.name, - SDL_arraysize(SYS_JoyData[0].szDeviceName)); - } - /* Default Init ... autoconfig */ - else { - /* if two devices were detected... configure as Joy1 4 axis and Joy2 2 axis */ - if (numdevs == 2) { - /* Define Device 0 as 4 axes, 4 buttons */ - SYS_JoyData[0].id = 0; - SYS_JoyData[0].axes = 4; - SYS_JoyData[0].buttons = 4; - SYS_JoyData[0].hats = 0; - SYS_JoyData[0].balls = 0; - SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; - SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; - SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; - SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; - SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; - SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; - SYS_JoyData[0].axes_min[2] = stGameCalib.Bx.lower; - SYS_JoyData[0].axes_med[2] = stGameCalib.Bx.centre; - SYS_JoyData[0].axes_max[2] = stGameCalib.Bx.upper; - SYS_JoyData[0].axes_min[3] = stGameCalib.By.lower; - SYS_JoyData[0].axes_med[3] = stGameCalib.By.centre; - SYS_JoyData[0].axes_max[3] = stGameCalib.By.upper; - /* Define Device 1 as 2 axes, 2 buttons */ - SYS_JoyData[1].id = 1; - SYS_JoyData[1].axes = 2; - SYS_JoyData[1].buttons = 2; - SYS_JoyData[1].hats = 0; - SYS_JoyData[1].balls = 0; - SYS_JoyData[1].axes_min[0] = stGameCalib.Bx.lower; - SYS_JoyData[1].axes_med[0] = stGameCalib.Bx.centre; - SYS_JoyData[1].axes_max[0] = stGameCalib.Bx.upper; - SYS_JoyData[1].axes_min[1] = stGameCalib.By.lower; - SYS_JoyData[1].axes_med[1] = stGameCalib.By.centre; - SYS_JoyData[1].axes_max[1] = stGameCalib.By.upper; - } - /* One joystick only? */ - else { - /* If it is joystick A... */ - if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) { - /* Define Device 0 as 2 axes, 4 buttons */ - SYS_JoyData[0].id = 0; - SYS_JoyData[0].axes = 2; - SYS_JoyData[0].buttons = 4; - SYS_JoyData[0].hats = 0; - SYS_JoyData[0].balls = 0; - SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; - SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; - SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; - SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; - SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; - SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; - } - /* If not, it is joystick B */ - else { - /* Define Device 1 as 2 axes, 2 buttons */ - SYS_JoyData[0].id = 1; - SYS_JoyData[0].axes = 2; - SYS_JoyData[0].buttons = 2; - SYS_JoyData[0].hats = 0; - SYS_JoyData[0].balls = 0; - SYS_JoyData[0].axes_min[0] = stGameCalib.Bx.lower; - SYS_JoyData[0].axes_med[0] = stGameCalib.Bx.centre; - SYS_JoyData[0].axes_max[0] = stGameCalib.Bx.upper; - SYS_JoyData[0].axes_min[1] = stGameCalib.By.lower; - SYS_JoyData[0].axes_med[1] = stGameCalib.By.centre; - SYS_JoyData[0].axes_max[1] = stGameCalib.By.upper; - } - } - /* Hack to define Joystick Port Names */ - if (numdevs > maxdevs) - numdevs = maxdevs; - for (i = 0; i < numdevs; i++) - SDL_snprintf(SYS_JoyData[i].szDeviceName, - SDL_arraysize(SYS_JoyData[i].szDeviceName), - "Default Joystick %c", 'A' + SYS_JoyData[i].id); - - } - } -/* Return the number of devices found */ - return (numdevs); -} - - -/***********************************************************/ -/* Function to get the device-dependent name of a joystick */ -/***********************************************************/ -const char * -SDL_SYS_JoystickName(int index) -{ -/* No need to verify if device exists, already done in upper layer */ - return (SYS_JoyData[index].szDeviceName); -} - - - -/******************************************************************************/ -/* Function to open a joystick for use. */ -/* The joystick to open is specified by the index field of the joystick. */ -/* This should fill the nbuttons and naxes fields of the joystick structure. */ -/* It returns 0, or -1 if there is an error. */ -/******************************************************************************/ -int -SDL_SYS_JoystickOpen(SDL_Joystick * joystick) -{ - int index; /* Index shortcut for index in joystick structure */ - int i; /* Generic Counter */ - -/* allocate memory for system specific hardware data */ - joystick->hwdata = - (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata)); - if (joystick->hwdata == NULL) { - SDL_OutOfMemory(); - return (-1); - } -/* Reset Hardware Data */ - SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); - -/* ShortCut Pointer */ - index = joystick->index; -/* Define offsets and scales for all axes */ - joystick->hwdata->id = SYS_JoyData[index].id; - for (i = 0; i < MAX_AXES; ++i) { - if ((i < 2) || i < SYS_JoyData[index].axes) { - joystick->hwdata->transaxes[i].offset = - ((AXIS_MAX + AXIS_MIN) >> 1) - SYS_JoyData[index].axes_med[i]; - //joystick->hwdata->transaxes[i].scale = (float)((AXIS_MAX - AXIS_MIN)/(SYS_JoyData[index].axes_max[i]-SYS_JoyData[index].axes_min[i])); - joystick->hwdata->transaxes[i].scale1 = - (float) abs((AXIS_MIN / SYS_JoyData[index].axes_min[i])); - joystick->hwdata->transaxes[i].scale2 = - (float) abs((AXIS_MAX / SYS_JoyData[index].axes_max[i])); - } else { - joystick->hwdata->transaxes[i].offset = 0; - //joystick->hwdata->transaxes[i].scale = 1.0; /* Just in case */ - joystick->hwdata->transaxes[i].scale1 = 1.0; /* Just in case */ - joystick->hwdata->transaxes[i].scale2 = 1.0; /* Just in case */ - } - } - -/* fill nbuttons, naxes, and nhats fields */ - joystick->nbuttons = SYS_JoyData[index].buttons; - joystick->naxes = SYS_JoyData[index].axes; -/* joystick->nhats = SYS_JoyData[index].hats; */ - joystick->nhats = 0; /* No support for hats at this time */ -/* joystick->nballs = SYS_JoyData[index].balls; */ - joystick->nballs = 0; /* No support for balls at this time */ - return 0; -} - - - -/***************************************************************************/ -/* Function to update the state of a joystick - called as a device poll. */ -/* This function shouldn't update the joystick structure directly, */ -/* but instead should call SDL_PrivateJoystick*() to deliver events */ -/* and update joystick device state. */ -/***************************************************************************/ -void -SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) -{ - APIRET rc; /* Generic OS/2 return code */ - int index; /* index shortcurt to joystick index */ - int i; /* Generic counter */ - int normbut; /* Number of buttons reported by joystick */ - int corr; /* Correction for button names */ - Sint16 value, change; /* Values used to update axis values */ - struct _transaxes *transaxes; /* Shortcut for Correction structure */ - Uint32 pos[MAX_AXES]; /* Vector to inform the Axis status */ - ULONG ulDataLen; /* Size of data */ - GAME_STATUS_STRUCT stGameStatus; /* Joystick Status Structure */ - - ulDataLen = sizeof(stGameStatus); - rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_STATUS, - NULL, 0, NULL, &stGameStatus, ulDataLen, &ulDataLen); - if (rc != 0) { - SDL_SetError("Could not read joystick status."); - return; /* Could not read data */ - } - -/* Shortcut pointer */ - index = joystick->index; -/* joystick motion events */ - - if (SYS_JoyData[index].id == 0) { - pos[0] = stGameStatus.curdata.A.x; - pos[1] = stGameStatus.curdata.A.y; - if (SYS_JoyData[index].axes >= 3) - pos[2] = stGameStatus.curdata.B.x; - else - pos[2] = 0; - if (SYS_JoyData[index].axes >= 4) - pos[3] = stGameStatus.curdata.B.y; - else - pos[3] = 0; - pos[4] = 0; /* OS/2 basic drivers do not support more than 4 axes joysticks */ - pos[5] = 0; - } else if (SYS_JoyData[index].id == 1) { - pos[0] = stGameStatus.curdata.B.x; - pos[1] = stGameStatus.curdata.B.y; - pos[2] = 0; - pos[3] = 0; - pos[4] = 0; - pos[5] = 0; - } - -/* Corrects the movements using the callibration */ - transaxes = joystick->hwdata->transaxes; - for (i = 0; i < joystick->naxes; i++) { - value = pos[i] + transaxes[i].offset; - if (value < 0) { - value *= transaxes[i].scale1; - if (value > 0) - value = AXIS_MIN; - } else { - value *= transaxes[i].scale2; - if (value < 0) - value = AXIS_MAX; - } - change = (value - joystick->axes[i]); - if ((change < -JOY_AXIS_THRESHOLD) || (change > JOY_AXIS_THRESHOLD)) { - SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value); - } - } - -/* joystick button A to D events */ - if (SYS_JoyData[index].id == 1) - corr = 2; - else - corr = 0; - normbut = 4; /* Number of normal buttons */ - if (joystick->nbuttons < normbut) - normbut = joystick->nbuttons; - for (i = corr; (i - corr) < normbut; ++i) { - /* - Button A: 1110 0000 - Button B: 1101 0000 - Button C: 1011 0000 - Button D: 0111 0000 - */ - if ((~stGameStatus.curdata.butMask) >> 4 & JOY_BUTTON_FLAG(i)) { - if (!joystick->buttons[i - corr]) { - SDL_PrivateJoystickButton(joystick, (Uint8) (i - corr), - SDL_PRESSED); - } - } else { - if (joystick->buttons[i - corr]) { - SDL_PrivateJoystickButton(joystick, (Uint8) (i - corr), - SDL_RELEASED); - } - } - } - -/* Joystick button E to H buttons */ - /* - Button E: Axis 2 X Left - Button F: Axis 2 Y Up - Button G: Axis 2 X Right - Button H: Axis 2 Y Down - */ - if (joystick->nbuttons >= 5) { - if (stGameStatus.curdata.B.x < SYS_JoyData[index].buttoncalc[0]) - SDL_PrivateJoystickButton(joystick, (Uint8) 4, SDL_PRESSED); - else - SDL_PrivateJoystickButton(joystick, (Uint8) 4, SDL_RELEASED); - } - if (joystick->nbuttons >= 6) { - if (stGameStatus.curdata.B.y < SYS_JoyData[index].buttoncalc[1]) - SDL_PrivateJoystickButton(joystick, (Uint8) 5, SDL_PRESSED); - else - SDL_PrivateJoystickButton(joystick, (Uint8) 5, SDL_RELEASED); - } - if (joystick->nbuttons >= 7) { - if (stGameStatus.curdata.B.x > SYS_JoyData[index].buttoncalc[2]) - SDL_PrivateJoystickButton(joystick, (Uint8) 6, SDL_PRESSED); - else - SDL_PrivateJoystickButton(joystick, (Uint8) 6, SDL_RELEASED); - } - if (joystick->nbuttons >= 8) { - if (stGameStatus.curdata.B.y > SYS_JoyData[index].buttoncalc[3]) - SDL_PrivateJoystickButton(joystick, (Uint8) 7, SDL_PRESSED); - else - SDL_PrivateJoystickButton(joystick, (Uint8) 7, SDL_RELEASED); - } - -/* joystick hat events */ -/* Not Supported under OS/2 */ -/* joystick ball events */ -/* Not Supported under OS/2 */ -} - - - -/******************************************/ -/* Function to close a joystick after use */ -/******************************************/ -void -SDL_SYS_JoystickClose(SDL_Joystick * joystick) -{ - if (joystick->hwdata != NULL) { - /* free system specific hardware data */ - SDL_free(joystick->hwdata); - } -} - - - -/********************************************************************/ -/* Function to perform any system-specific joystick related cleanup */ -/********************************************************************/ -void -SDL_SYS_JoystickQuit(void) -{ - joyPortClose(&hJoyPort); -} - - - -/************************/ -/************************/ -/* OS/2 Implementations */ -/************************/ -/************************/ - - -/*****************************************/ -/* Open Joystick Port, if not opened yet */ -/*****************************************/ -APIRET -joyPortOpen(HFILE * hGame) -{ - APIRET rc; /* Generic Return Code */ - ULONG ulAction; /* ? */ - ULONG ulVersion; /* Version of joystick driver */ - ULONG ulDataLen; /* Size of version data */ - -/* Verifies if joyport is not already open... */ - if (*hGame != NULL) - return 0; -/* Open GAME$ for read */ - rc = DosOpen((PSZ) GAMEPDDNAME, hGame, &ulAction, 0, FILE_READONLY, - FILE_OPEN, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, NULL); - if (rc != 0) { - SDL_SetError("Could not open Joystick Port."); - return -1; - } - -/* Get Joystick Driver Version... must be 2.0 or higher */ - ulVersion = 0; - ulDataLen = sizeof(ulVersion); - rc = DosDevIOCtl(*hGame, IOCTL_CAT_USER, GAME_GET_VERSION, - NULL, 0, NULL, &ulVersion, ulDataLen, &ulDataLen); - if (rc != 0) { - joyPortClose(hGame); - SDL_SetError("Could not get Joystick Driver version."); - return -1; - } - if (ulVersion < GAME_VERSION) { - joyPortClose(hGame); - SDL_SetError - ("Driver too old. At least IBM driver version 2.0 required."); - return -1; - } - return 0; -} - - - -/****************************/ -/* Close JoyPort, if opened */ -/****************************/ -void -joyPortClose(HFILE * hGame) -{ - if (*hGame != NULL) - DosClose(*hGame); - *hGame = NULL; -} - - - -/***************************/ -/* Get SDL Joystick EnvVar */ -/***************************/ -int -joyGetEnv(struct _joycfg *joydata) -{ - char *joyenv; /* Pointer to tested character */ - char tempnumber[5]; /* Temporary place to put numeric texts */ - - joyenv = SDL_getenv("SDL_OS2_JOYSTICK"); - if (joyenv == NULL) - return 0; -/* Joystick Environment is defined! */ - while (*joyenv == ' ' && *joyenv != 0) - joyenv++; /* jump spaces... */ -/* If the string name starts with '... get if fully */ - if (*joyenv == '\'') - joyenv += - joyGetData(++joyenv, joydata->name, '\'', sizeof(joydata->name)); -/* If not, get it until the next space */ - else if (*joyenv == '\"') - joyenv += - joyGetData(++joyenv, joydata->name, '\"', sizeof(joydata->name)); - else - joyenv += - joyGetData(joyenv, joydata->name, ' ', sizeof(joydata->name)); -/* Now get the number of axes */ - while (*joyenv == ' ' && *joyenv != 0) - joyenv++; /* jump spaces... */ - joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber)); - joydata->axes = atoi(tempnumber); -/* Now get the number of buttons */ - while (*joyenv == ' ' && *joyenv != 0) - joyenv++; /* jump spaces... */ - joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber)); - joydata->buttons = atoi(tempnumber); -/* Now get the number of hats */ - while (*joyenv == ' ' && *joyenv != 0) - joyenv++; /* jump spaces... */ - joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber)); - joydata->hats = atoi(tempnumber); -/* Now get the number of balls */ - while (*joyenv == ' ' && *joyenv != 0) - joyenv++; /* jump spaces... */ - joyenv += joyGetData(joyenv, tempnumber, ' ', sizeof(tempnumber)); - joydata->balls = atoi(tempnumber); - return 1; -} - - - -/************************************************************************/ -/* Get a text from in the string starting in joyenv until it finds */ -/* the stopchar or maxchars is reached. The result is placed in name. */ -/************************************************************************/ -int -joyGetData(char *joyenv, char *name, char stopchar, size_t maxchars) -{ - char *nameptr; /* Pointer to the selected character */ - int chcnt = 0; /* Count how many characters where copied */ - - nameptr = name; - while (*joyenv != stopchar && *joyenv != 0) { - if (nameptr < (name + (maxchars - 1))) { - *nameptr = *joyenv; /* Only copy if smaller than maximum */ - nameptr++; - } - chcnt++; - joyenv++; - } - if (*joyenv == stopchar) { - joyenv++; /* Jump stopchar */ - chcnt++; - } - *nameptr = 0; /* Mark last byte */ - return chcnt; -} - -#endif /* SDL_JOYSTICK_OS2 */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/joystick/os2/joyos2.h Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -/*****************************************************************************/ -/* */ -/* COPYRIGHT Copyright (C) 1995 IBM Corporation */ -/* */ -/* The following IBM OS/2 source code is provided to you solely for */ -/* the purpose of assisting you in your development of OS/2 device */ -/* drivers. You may use this code in accordance with the IBM License */ -/* Agreement provided in the IBM Device Driver Source Kit for OS/2. This */ -/* Copyright statement may not be removed. */ -/* */ -/*****************************************************************************/ -#ifndef JOYOS2_H -#define JOYOS2_H - -/****** GAMEPORT.SYS joystick definitions, start *****************************/ -#define GAME_VERSION 0x20 /* 2.0 First IBM version */ -#define GAMEPDDNAME "GAME$ " -#define IOCTL_CAT_USER 0x80 -#define GAME_PORT_GET 0x20 /* read GAMEPORT.SYS values */ -#define GAME_PORT_RESET 0x60 /* reset joystick mask with given value */ - -#pragma pack(1) /* pack structure size is 1 byte */ -typedef struct -{ /* GAMEPORT.SYS structure */ - USHORT usJs_AxCnt; /* Joystick_A X position */ - USHORT usJs_AyCnt; /* Joystick_A Y position */ - USHORT usJs_BxCnt; /* Joystick_B X position */ - USHORT usJs_ByCnt; /* Joystick_B Y position */ - USHORT usJs_ButtonA1Cnt; /* button A1 press count */ - USHORT usJs_ButtonA2Cnt; /* button A2 press count */ - USHORT usJs_ButtonB1Cnt; /* button B1 press count */ - USHORT usJs_ButtonB2Cnt; /* button B2 press count */ - UCHAR ucJs_JoyStickMask; /* mask of connected joystick pots */ - UCHAR ucJs_ButtonStatus; /* bits of switches down */ - ULONG ulJs_Ticks; /* joystick clock ticks */ -} GAME_PORT_STRUCT; -#pragma pack() /*reset to normal pack size */ -/****** GAMEPORT.SYS joystick definitions, end *******************************/ - - -/****************************************************************************/ -#define GAME_GET_VERSION 0x01 -#define GAME_GET_PARMS 0x02 -#define GAME_SET_PARMS 0x03 -#define GAME_GET_CALIB 0x04 -#define GAME_SET_CALIB 0x05 -#define GAME_GET_DIGSET 0x06 -#define GAME_SET_DIGSET 0x07 -#define GAME_GET_STATUS 0x10 -#define GAME_GET_STATUS_BUTWAIT 0x11 -#define GAME_GET_STATUS_SAMPWAIT 0x12 -/****************************************************************************/ - -/****************************************************************************/ -// bit masks for each axis -#define JOY_AX_BIT 0x01 -#define JOY_AY_BIT 0x02 -#define JOY_A_BITS (JOY_AX_BIT|JOY_AY_BIT) -#define JOY_BX_BIT 0x04 -#define JOY_BY_BIT 0x08 -#define JOY_B_BITS (JOY_BX_BIT|JOY_BY_BIT) -#define JOY_ALLPOS_BITS (JOY_A_BITS|JOY_B_BITS) - -// bit masks for each button -#define JOY_BUT1_BIT 0x10 -#define JOY_BUT2_BIT 0x20 -#define JOY_BUT3_BIT 0x40 -#define JOY_BUT4_BIT 0x80 -#define JOY_ALL_BUTS (JOY_BUT1_BIT|JOY_BUT2_BIT|JOY_BUT3_BIT|JOY_BUT4_BIT) -/****************************************************************************/ - -/****************************************************************************/ -// 1-D position struct used for each axis -typedef SHORT GAME_POS; /* some data formats require signed values */ - -// simple 2-D position for each joystick -typedef struct -{ - GAME_POS x; - GAME_POS y; -} -GAME_2DPOS_STRUCT; - -// struct defining the instantaneous state of both sticks and all buttons -typedef struct -{ - GAME_2DPOS_STRUCT A; - GAME_2DPOS_STRUCT B; - USHORT butMask; -} -GAME_DATA_STRUCT; - -// struct to be used for calibration and digital response on each axis -typedef struct -{ - GAME_POS lower; - GAME_POS centre; - GAME_POS upper; -} -GAME_3POS_STRUCT; -/****************************************************************************/ - -/****************************************************************************/ -// status struct returned to OS/2 applications: -// current data for all sticks as well as button counts since last read -typedef struct -{ - GAME_DATA_STRUCT curdata; - USHORT b1cnt; - USHORT b2cnt; - USHORT b3cnt; - USHORT b4cnt; -} -GAME_STATUS_STRUCT; -/****************************************************************************/ - -/****************************************************************************/ -/* in use bitmasks originating in 0.2b */ -#define GAME_USE_BOTH_OLDMASK 0x01 /* for backward compat with bool */ -#define GAME_USE_X_NEWMASK 0x02 -#define GAME_USE_Y_NEWMASK 0x04 -#define GAME_USE_X_EITHERMASK (GAME_USE_X_NEWMASK|GAME_USE_BOTH_OLDMASK) -#define GAME_USE_Y_EITHERMASK (GAME_USE_Y_NEWMASK|GAME_USE_BOTH_OLDMASK) -#define GAME_USE_BOTH_NEWMASK (GAME_USE_X_NEWMASK|GAME_USE_Y_NEWMASK) - -/* only timed sampling implemented in version 1.0 */ -#define GAME_MODE_TIMED 1 /* timed sampling */ -#define GAME_MODE_REQUEST 2 /* request driven sampling */ - -/* only raw implemented in version 1.0 */ -#define GAME_DATA_FORMAT_RAW 1 /* [l,c,r] */ -#define GAME_DATA_FORMAT_SIGNED 2 /* [-l,0,+r] */ -#define GAME_DATA_FORMAT_BINARY 3 /* {-1,0,+1} */ -#define GAME_DATA_FORMAT_SCALED 4 /* [-10,+10] */ - -// parameters defining the operation of the driver -typedef struct -{ - USHORT useA; /* new bitmasks: see above */ - USHORT useB; - USHORT mode; /* see consts above */ - USHORT format; /* see consts above */ - USHORT sampDiv; /* samp freq = 32 / n */ - USHORT scale; /* scaling factor */ - USHORT res1; /* must be 0 */ - USHORT res2; /* must be 0 */ -} -GAME_PARM_STRUCT; -/****************************************************************************/ - -/****************************************************************************/ -// calibration values for each axis: -// - upper limit on value to be considered in lower range -// - centre value -// - lower limit on value to be considered in upper range -typedef struct -{ - GAME_3POS_STRUCT Ax; - GAME_3POS_STRUCT Ay; - GAME_3POS_STRUCT Bx; - GAME_3POS_STRUCT By; -} -GAME_CALIB_STRUCT; -/****************************************************************************/ - -/****************************************************************************/ -// struct defining the digital response values for all axes -typedef struct -{ - GAME_3POS_STRUCT Ax; - GAME_3POS_STRUCT Ay; - GAME_3POS_STRUCT Bx; - GAME_3POS_STRUCT By; -} -GAME_DIGSET_STRUCT; -/****************************************************************************/ - -#endif -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/loadso/os2/SDL_sysloadso.c Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" - -#ifdef SDL_LOADSO_OS2 - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* System dependent library loading routines */ - -#include <stdio.h> -#define INCL_DOSERRORS -#define INCL_DOSMODULEMGR -#include <os2.h> - -#include "SDL_loadso.h" - -void * -SDL_LoadObject(const char *sofile) -{ - HMODULE handle = NULL; - char buf[512]; - APIRET ulrc = DosLoadModule(buf, sizeof(buf), (char *) sofile, &handle); - - /* Generate an error message if all loads failed */ - if ((ulrc != NO_ERROR) || (handle == NULL)) - SDL_SetError("Failed loading %s: %s", sofile, buf); - - return ((void *) handle); -} - -void * -SDL_LoadFunction(void *handle, const char *name) -{ - const char *loaderror = "Unknown error"; - void *symbol = NULL; - APIRET ulrc = - DosQueryProcAddr((HMODULE) handle, 0, (char *) name, &symbol); - if (ulrc == ERROR_INVALID_HANDLE) - loaderror = "Invalid module handle"; - else if (ulrc == ERROR_INVALID_NAME) - loaderror = "Symbol not found"; - - if (symbol == NULL) - SDL_SetError("Failed loading %s: %s", name, loaderror); - - return (symbol); -} - -void -SDL_UnloadObject(void *handle) -{ - if (handle != NULL) - DosFreeModule((HMODULE) handle); -} - -#endif /* SDL_LOADSO_OS2 */ - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/power/SDL_power.c Sat Sep 19 06:24:07 2009 +0000 +++ b/src/power/SDL_power.c Sat Sep 19 06:43:45 2009 +0000 @@ -34,7 +34,6 @@ SDL_bool SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_Windows(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_MacOSX(SDL_PowerState *, int *, int *); -SDL_bool SDL_GetPowerInfo_OS2(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_BeOS(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_NintendoDS(SDL_PowerState *, int *, int *); @@ -65,9 +64,6 @@ #ifdef SDL_POWER_MACOSX /* handles Mac OS X, Darwin, iPhone. */ SDL_GetPowerInfo_MacOSX, #endif -#ifdef SDL_POWER_OS2 /* handles OS/2, Warp, eComStation. */ - SDL_GetPowerInfo_OS2, -#endif #ifdef SDL_POWER_NINTENDODS /* handles Nintendo DS. */ SDL_GetPowerInfo_NintendoDS, #endif
--- a/src/power/os2/SDL_syspower.c Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" - -/* !!! FIXME: - * Please note that this code has not been tested (or even compiled!). It - * should, in theory, run on any version of OS/2, and work with any system - * that has APM.SYS loaded. I don't know if ACPI.SYS works. - */ - -#ifndef SDL_POWER_DISABLED -#ifdef SDL_POWER_OS2 - -#define INCL_DOSFILEMGR -#define INCL_DOSDEVICES -#define INCL_DOSDEVIOCTL -#define INCL_DOSERRORS -#include <os2.h> - -#include "SDL_power.h" - -typedef struct -{ - USHORT len; - USHORT flags; - UCHAR ac_status; - UCHAR battery_status; - UCHAR battery_life; - UCHAR battery_time_form; - USHORT battery_time; - UCHAR battery_flags; -} PowerStatus; -extern int CompilerAssertPowerStatus[(sizeof(PowerStatus) == 10) ? 1 : -1]; - - -SDL_bool -SDL_GetPowerInfo_OS2(SDL_PowerState * state, int *seconds, int *percent) -{ - PowerStatus status; - HFILE hfile = 0; - ULONG action = 0; - APIRET rc = 0; - - *state = SDL_POWERSTATE_UNKNOWN; - *percent = -1; - *seconds = -1; - - /* open the power management device */ - rc = DosOpen("APM$", &hfile, &action, 0, FILE_NORMAL, FILE_OPEN, - OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0); - - if (rc == NO_ERROR) { - USHORT iorc = 0; - ULONG iorclen = sizeof(iorc); - ULONG statuslen = sizeof(status); - - SDL_memset(&status, '\0', sizeof(status)); - status.len = sizeof(status); - - rc = DosDevIOCtl(hfile, IOCTL_POWER, POWER_GETPOWERSTATUS, &status, - statuslen, &statuslen, &iorc, iorclen, &iorclen); - DosClose(hfile); - - /* (status.flags & 0x1) == power subsystem enabled. */ - if ((rc == NO_ERROR) && (status.flags & 0x1)) { - if (statuslen == 7) { /* older OS/2 APM driver? Less fields. */ - status.battery_time_form = 0xFF; - status.battery_time = 0; - if (status.battery_status == 0xFF) { - status.battery_flags = 0xFF; - } else { - status.battery_flags = (1 << status.battery_status); - } - } - - if (status.battery_flags == 0xFF) { /* unknown state */ - *state = SDL_POWERSTATE_UNKNOWN; - } else if (status.battery_flags & (1 << 7)) { /* no battery */ - *state = SDL_POWERSTATE_NO_BATTERY; - } else if (status.battery_flags & (1 << 3)) { /* charging */ - *state = SDL_POWERSTATE_CHARGING; - need_details = SDL_TRUE; - } else if (status.ac_status == 1) { - *state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */ - need_details = SDL_TRUE; - } else { - *state = SDL_POWERSTATE_ON_BATTERY; /* not on AC. */ - need_details = SDL_TRUE; - } - - if (need_details) { - const int pct = (int) status.battery_life; - const int secs = (int) status.battery_time; - - if (pct != 0xFF) { /* 255 == unknown */ - *percent = (pct > 100) ? 100 : pct; - } - - if (status.battery_time_form == 0xFF) { /* unknown */ - *seconds = -1; - } else if (status.battery_time_form == 1) { /* minutes */ - *seconds = secs * 60; - } else { - *seconds = secs; - } - } - } - } - - return SDL_TRUE; /* always the definitive answer on OS/2. */ -} - -#endif /* SDL_POWER_OS2 */ -#endif /* SDL_POWER_DISABLED */ - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/thread/SDL_thread_c.h Sat Sep 19 06:24:07 2009 +0000 +++ b/src/thread/SDL_thread_c.h Sat Sep 19 06:43:45 2009 +0000 @@ -33,8 +33,6 @@ #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 #include "pth/SDL_systhread_c.h" #elif SDL_THREAD_PTHREAD
--- a/src/thread/os2/SDL_syscond.c Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,223 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" - -/* An implementation of condition variables using semaphores and mutexes */ -/* - This implementation borrows heavily from the BeOS condition variable - implementation, written by Christopher Tate and Owen Smith. Thanks! - */ - -#include "SDL_thread.h" - -struct SDL_cond -{ - SDL_mutex *lock; - int waiting; - int signals; - SDL_sem *wait_sem; - SDL_sem *wait_done; -}; - -/* Create a condition variable */ -DECLSPEC SDL_cond *SDLCALL -SDL_CreateCond(void) -{ - SDL_cond *cond; - - cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond)); - if (cond) { - cond->lock = SDL_CreateMutex(); - cond->wait_sem = SDL_CreateSemaphore(0); - cond->wait_done = SDL_CreateSemaphore(0); - cond->waiting = cond->signals = 0; - if (!cond->lock || !cond->wait_sem || !cond->wait_done) { - SDL_DestroyCond(cond); - cond = NULL; - } - } else { - SDL_OutOfMemory(); - } - return (cond); -} - -/* Destroy a condition variable */ -DECLSPEC void SDLCALL -SDL_DestroyCond(SDL_cond * cond) -{ - if (cond) { - if (cond->wait_sem) { - SDL_DestroySemaphore(cond->wait_sem); - } - if (cond->wait_done) { - SDL_DestroySemaphore(cond->wait_done); - } - if (cond->lock) { - SDL_DestroyMutex(cond->lock); - } - SDL_free(cond); - } -} - -/* Restart one of the threads that are waiting on the condition variable */ -DECLSPEC int SDLCALL -SDL_CondSignal(SDL_cond * cond) -{ - if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; - } - - /* If there are waiting threads not already signalled, then - signal the condition and wait for the thread to respond. - */ - SDL_LockMutex(cond->lock); - if (cond->waiting > cond->signals) { - ++cond->signals; - SDL_SemPost(cond->wait_sem); - SDL_UnlockMutex(cond->lock); - SDL_SemWait(cond->wait_done); - } else { - SDL_UnlockMutex(cond->lock); - } - - return 0; -} - -/* Restart all threads that are waiting on the condition variable */ -DECLSPEC int SDLCALL -SDL_CondBroadcast(SDL_cond * cond) -{ - if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; - } - - /* If there are waiting threads not already signalled, then - signal the condition and wait for the thread to respond. - */ - SDL_LockMutex(cond->lock); - if (cond->waiting > cond->signals) { - int i, num_waiting; - - num_waiting = (cond->waiting - cond->signals); - cond->signals = cond->waiting; - for (i = 0; i < num_waiting; ++i) { - SDL_SemPost(cond->wait_sem); - } - /* Now all released threads are blocked here, waiting for us. - Collect them all (and win fabulous prizes!) :-) - */ - SDL_UnlockMutex(cond->lock); - for (i = 0; i < num_waiting; ++i) { - SDL_SemWait(cond->wait_done); - } - } else { - SDL_UnlockMutex(cond->lock); - } - - return 0; -} - -/* Wait on the condition variable for at most 'ms' milliseconds. - The mutex must be locked before entering this function! - The mutex is unlocked during the wait, and locked again after the wait. - -Typical use: - -Thread A: - SDL_LockMutex(lock); - while ( ! condition ) { - SDL_CondWait(cond); - } - SDL_UnlockMutex(lock); - -Thread B: - SDL_LockMutex(lock); - ... - condition = true; - ... - SDL_UnlockMutex(lock); - */ -DECLSPEC int SDLCALL -SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) -{ - int retval; - - if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; - } - - /* Obtain the protection mutex, and increment the number of waiters. - This allows the signal mechanism to only perform a signal if there - are waiting threads. - */ - SDL_LockMutex(cond->lock); - ++cond->waiting; - SDL_UnlockMutex(cond->lock); - - /* Unlock the mutex, as is required by condition variable semantics */ - SDL_UnlockMutex(mutex); - - /* Wait for a signal */ - if (ms == SDL_MUTEX_MAXWAIT) { - retval = SDL_SemWait(cond->wait_sem); - } else { - retval = SDL_SemWaitTimeout(cond->wait_sem, ms); - } - - /* Let the signaler know we have completed the wait, otherwise - the signaler can race ahead and get the condition semaphore - if we are stopped between the mutex unlock and semaphore wait, - giving a deadlock. See the following URL for details: - http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html - */ - SDL_LockMutex(cond->lock); - if (cond->signals > 0) { - /* If we timed out, we need to eat a condition signal */ - if (retval > 0) { - SDL_SemWait(cond->wait_sem); - } - /* We always notify the signal thread that we are done */ - SDL_SemPost(cond->wait_done); - - /* Signal handshake complete */ - --cond->signals; - } - --cond->waiting; - SDL_UnlockMutex(cond->lock); - - /* Lock the mutex, as is required by condition variable semantics */ - SDL_LockMutex(mutex); - - return retval; -} - -/* Wait on the condition variable forever */ -DECLSPEC int SDLCALL -SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) -{ - return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/thread/os2/SDL_syscond_c.h Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/thread/os2/SDL_sysmutex.c Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" - -/* Mutex functions using the OS/2 API */ - -#define INCL_DOSERRORS -#define INCL_DOSSEMAPHORES -#include <os2.h> - -#include "SDL_mutex.h" - - -struct SDL_mutex -{ - HMTX hmtxID; -}; - -/* Create a mutex */ -DECLSPEC SDL_mutex *SDLCALL -SDL_CreateMutex(void) -{ - SDL_mutex *mutex; - APIRET ulrc; - - /* Allocate mutex memory */ - mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); - if (mutex) { - /* Create the mutex, with initial value signaled */ - ulrc = DosCreateMutexSem(NULL, // Create unnamed semaphore - &(mutex->hmtxID), // Pointer to handle - 0L, // Flags: create it private (not shared) - FALSE); // Initial value: unowned - if (ulrc != NO_ERROR) { - SDL_SetError("Couldn't create mutex"); - SDL_free(mutex); - mutex = NULL; - } - } else { - SDL_OutOfMemory(); - } - return (mutex); -} - -/* Free the mutex */ -DECLSPEC void SDLCALL -SDL_DestroyMutex(SDL_mutex * mutex) -{ - if (mutex) { - if (mutex->hmtxID) { - DosCloseMutexSem(mutex->hmtxID); - mutex->hmtxID = 0; - } - SDL_free(mutex); - } -} - -/* Lock the mutex */ -DECLSPEC int SDLCALL -SDL_mutexP(SDL_mutex * mutex) -{ - if (mutex == NULL) { - SDL_SetError("Passed a NULL mutex"); - return -1; - } - if (DosRequestMutexSem(mutex->hmtxID, SEM_INDEFINITE_WAIT) != NO_ERROR) { - SDL_SetError("Couldn't wait on mutex"); - return -1; - } - return (0); -} - -/* Unlock the mutex */ -DECLSPEC int SDLCALL -SDL_mutexV(SDL_mutex * mutex) -{ - if (mutex == NULL) { - SDL_SetError("Passed a NULL mutex"); - return -1; - } - if (DosReleaseMutexSem(mutex->hmtxID) != NO_ERROR) { - SDL_SetError("Couldn't release mutex"); - return -1; - } - return (0); -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/thread/os2/SDL_syssem.c Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" - -/* Semaphore functions using the OS/2 API */ - -#define INCL_DOS -#define INCL_DOSERRORS -#define INCL_DOSSEMAPHORES -#include <os2.h> - -#include "SDL_thread.h" -#include "SDL_timer.h" - - -struct SDL_semaphore -{ - HMTX id; - HEV changed; - Uint32 value; -}; - - -/* Create a semaphore */ -DECLSPEC SDL_sem *SDLCALL -SDL_CreateSemaphore(Uint32 initial_value) -{ - SDL_sem *sem; - ULONG ulrc; - - /* Allocate sem memory */ - sem = (SDL_sem *) SDL_malloc(sizeof(*sem)); - if (sem) { - /* Create the mutex semaphore */ - ulrc = DosCreateMutexSem(NULL, &(sem->id), 0, TRUE); - if (ulrc) { - SDL_SetError("Couldn't create semaphore"); - SDL_free(sem); - sem = NULL; - } else { - DosCreateEventSem(NULL, &(sem->changed), 0, FALSE); - sem->value = initial_value; - DosReleaseMutexSem(sem->id); - } - } else { - SDL_OutOfMemory(); - } - return (sem); -} - -/* Free the semaphore */ -DECLSPEC void SDLCALL -SDL_DestroySemaphore(SDL_sem * sem) -{ - if (sem) { - if (sem->id) { - DosCloseEventSem(sem->changed); - DosCloseMutexSem(sem->id); - sem->id = 0; - } - SDL_free(sem); - } -} - -DECLSPEC int SDLCALL -SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) -{ - ULONG ulrc; - - if (!sem) { - SDL_SetError("Passed a NULL sem"); - return -1; - } - - if (timeout == SDL_MUTEX_MAXWAIT) { - while (1) { - ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT); - if (ulrc) { - /* if error waiting mutex */ - SDL_SetError("DosRequestMutexSem() failed"); - return -1; - } else if (sem->value) { - sem->value--; - DosReleaseMutexSem(sem->id); - return 0; - } else { - ULONG ulPostCount; - DosResetEventSem(sem->changed, &ulPostCount); - DosReleaseMutexSem(sem->id); - /* continue waiting until somebody posts the semaphore */ - DosWaitEventSem(sem->changed, SEM_INDEFINITE_WAIT); - } - } - } else if (timeout == 0) { - ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT); - if (ulrc == NO_ERROR) { - if (sem->value) { - sem->value--; - DosReleaseMutexSem(sem->id); - return 0; - } else { - DosReleaseMutexSem(sem->id); - return SDL_MUTEX_TIMEDOUT; - } - } else { - SDL_SetError("DosRequestMutexSem() failed"); - return -1; - } - } else { - ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT); - if (ulrc) { - /* if error waiting mutex */ - SDL_SetError("DosRequestMutexSem() failed"); - return -1; - } else if (sem->value) { - sem->value--; - DosReleaseMutexSem(sem->id); - return 0; - } else { - ULONG ulPostCount; - DosResetEventSem(sem->changed, &ulPostCount); - DosReleaseMutexSem(sem->id); - /* continue waiting until somebody posts the semaphore */ - ulrc = DosWaitEventSem(sem->changed, timeout); - if (ulrc == NO_ERROR) - return 0; - else - return SDL_MUTEX_TIMEDOUT; - } - } - /* never reached */ - return -1; -} - -DECLSPEC int SDLCALL -SDL_SemTryWait(SDL_sem * sem) -{ - return SDL_SemWaitTimeout(sem, 0); -} - -DECLSPEC int SDLCALL -SDL_SemWait(SDL_sem * sem) -{ - return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); -} - -/* Returns the current count of the semaphore */ -DECLSPEC Uint32 SDLCALL -SDL_SemValue(SDL_sem * sem) -{ - if (!sem) { - SDL_SetError("Passed a NULL sem"); - return 0; - } - return sem->value; -} - -DECLSPEC int SDLCALL -SDL_SemPost(SDL_sem * sem) -{ - if (!sem) { - SDL_SetError("Passed a NULL sem"); - return -1; - } - if (DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT)) { - SDL_SetError("DosRequestMutexSem() failed"); - return -1; - } - sem->value++; - DosPostEventSem(sem->changed); - DosReleaseMutexSem(sem->id); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/thread/os2/SDL_systhread.c Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" - -/* OS/2 thread management routines for SDL */ - -#include <process.h> -#define INCL_DOSERRORS -#define INCL_DOSPROCESS -#include <os2.h> - -#include "SDL_thread.h" -#include "../SDL_systhread.h" -#include "../SDL_thread_c.h" - -typedef struct ThreadStartParms -{ - void *args; - pfnSDL_CurrentEndThread pfnCurrentEndThread; -} tThreadStartParms, *pThreadStartParms; - -static void -threadfunc(void *pparm) -{ - pThreadStartParms pThreadParms = pparm; - pfnSDL_CurrentEndThread pfnCurrentEndThread = NULL; - - // Call the thread function! - SDL_RunThread(pThreadParms->args); - - // Get the current endthread we have to use! - if (pThreadParms) { - pfnCurrentEndThread = pThreadParms->pfnCurrentEndThread; - SDL_free(pThreadParms); - } - // Call endthread! - if (pfnCurrentEndThread) - (*pfnCurrentEndThread) (); -} - -int -SDL_SYS_CreateThread(SDL_Thread * thread, void *args, - pfnSDL_CurrentBeginThread pfnBeginThread, - pfnSDL_CurrentEndThread pfnEndThread) -{ - pThreadStartParms pThreadParms = SDL_malloc(sizeof(tThreadStartParms)); - if (!pThreadParms) { - SDL_SetError("Not enough memory to create thread"); - return (-1); - } - // Save the function which we will have to call to clear the RTL of calling app! - pThreadParms->pfnCurrentEndThread = pfnEndThread; - // Also save the real parameters we have to pass to thread function - pThreadParms->args = args; - // Start the thread using the runtime library of calling app! - thread->threadid = thread->handle = - (*pfnBeginThread) (threadfunc, NULL, 512 * 1024, pThreadParms); - if ((int) thread->threadid <= 0) { - SDL_SetError("Not enough resources to create thread"); - return (-1); - } - return (0); -} - -void -SDL_SYS_SetupThread(void) -{ - return; -} - -DECLSPEC Uint32 SDLCALL -SDL_ThreadID(void) -{ - PTIB tib; - DosGetInfoBlocks(&tib, NULL); - return ((Uint32) (tib->tib_ptib2->tib2_ultid)); -} - -void -SDL_SYS_WaitThread(SDL_Thread * thread) -{ - TID tid = thread->handle; - DosWaitThread(&tid, DCWW_WAIT); -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/thread/os2/SDL_systhread_c.h Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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@libsdl.org -*/ -#include "SDL_config.h" - -#define INCL_DOSPROCESS -#include <os2.h> - -typedef TID SYS_ThreadHandle; -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/timer/os2/SDL_systimer.c Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ -#include "SDL_config.h" - -#ifdef SDL_TIMER_OS2 - -#define INCL_DOSMISC -#define INCL_DOSERRORS -#define INCL_DOSSEMAPHORES -#define INCL_DOSDATETIME -#define INCL_DOSPROCESS -#define INCL_DOSPROFILE -#define INCL_DOSEXCEPTIONS -#include <os2.h> - -#include "SDL_thread.h" -#include "SDL_timer.h" -#include "../SDL_timer_c.h" - - -#define TIME_WRAP_VALUE (~(DWORD)0) - -/* The first high-resolution ticks value of the application */ -static long long hires_start_ticks; -/* The number of ticks per second of the high-resolution performance counter */ -static ULONG hires_ticks_per_second; - -void -SDL_StartTicks(void) -{ - DosTmrQueryFreq(&hires_ticks_per_second); - DosTmrQueryTime((PQWORD) & hires_start_ticks); -} - -DECLSPEC Uint32 SDLCALL -SDL_GetTicks(void) -{ - long long hires_now; - ULONG ticks = ticks; - - DosTmrQueryTime((PQWORD) & hires_now); -/* - hires_now -= hires_start_ticks; - hires_now *= 1000; - hires_now /= hires_ticks_per_second; -*/ - /* inline asm to avoid runtime inclusion */ - /* *INDENT-OFF* */ - _asm { - push edx - push eax - mov eax, dword ptr hires_now - mov edx, dword ptr hires_now + 4 - sub eax, dword ptr hires_start_ticks - sbb edx, dword ptr hires_start_ticks + 4 - mov ebx, 1000 - mov ecx, edx - mul ebx - push eax - push edx - mov eax, ecx - mul ebx - pop eax - add edx, eax - pop eax - mov ebx, dword ptr hires_ticks_per_second - div ebx - mov dword ptr ticks, eax - pop edx - pop eax - } - /* *INDENT-ON* */ - - return ticks; - -} - -/* High resolution sleep, originally made by Ilya Zakharevich */ -DECLSPEC void SDLCALL -SDL_Delay(Uint32 ms) -{ - /* This is similar to DosSleep(), but has 8ms granularity in time-critical - threads even on Warp3. */ - HEV hevEvent1 = 0; /* Event semaphore handle */ - HTIMER htimerEvent1 = 0; /* Timer handle */ - APIRET rc = NO_ERROR; /* Return code */ - int ret = 1; - ULONG priority = 0, nesting; /* Shut down the warnings */ - PPIB pib; - PTIB tib; - char *e = NULL; - APIRET badrc; - int switch_priority = 50; - - DosCreateEventSem(NULL, /* Unnamed */ - &hevEvent1, /* Handle of semaphore returned */ - DC_SEM_SHARED, /* Shared needed for DosAsyncTimer */ - FALSE); /* Semaphore is in RESET state */ - - if (ms >= switch_priority) - switch_priority = 0; - if (switch_priority) { - if (DosGetInfoBlocks(&tib, &pib) != NO_ERROR) - switch_priority = 0; - else { - /* In Warp3, to switch scheduling to 8ms step, one needs to do - DosAsyncTimer() in time-critical thread. On laters versions, - more and more cases of wait-for-something are covered. - - It turns out that on Warp3fp42 it is the priority at the time - of DosAsyncTimer() which matters. Let's hope that this works - with later versions too... XXXX - */ - priority = (tib->tib_ptib2->tib2_ulpri); - if ((priority & 0xFF00) == 0x0300) /* already time-critical */ - switch_priority = 0; - /* Make us time-critical. Just modifying TIB is not enough... */ - /* tib->tib_ptib2->tib2_ulpri = 0x0300; */ - /* We do not want to run at high priority if a signal causes us - to longjmp() out of this section... */ - if (DosEnterMustComplete(&nesting)) - switch_priority = 0; - else - DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); - } - } - - if ((badrc = DosAsyncTimer(ms, (HSEM) hevEvent1, /* Semaphore to post */ - &htimerEvent1))) /* Timer handler (returned) */ - e = "DosAsyncTimer"; - - if (switch_priority && tib->tib_ptib2->tib2_ulpri == 0x0300) { - /* Nobody switched priority while we slept... Ignore errors... */ - /* tib->tib_ptib2->tib2_ulpri = priority; *//* Get back... */ - if (! - (rc = DosSetPriority(PRTYS_THREAD, (priority >> 8) & 0xFF, 0, 0))) - rc = DosSetPriority(PRTYS_THREAD, 0, priority & 0xFF, 0); - } - if (switch_priority) - rc = DosExitMustComplete(&nesting); /* Ignore errors */ - - /* The actual blocking call is made with "normal" priority. This way we - should not bother with DosSleep(0) etc. to compensate for us interrupting - higher-priority threads. The goal is to prohibit the system spending too - much time halt()ing, not to run us "no matter what". */ - if (!e) /* Wait for AsyncTimer event */ - badrc = DosWaitEventSem(hevEvent1, SEM_INDEFINITE_WAIT); - - if (e); /* Do nothing */ - else if (badrc == ERROR_INTERRUPT) - ret = 0; - else if (badrc) - e = "DosWaitEventSem"; - if ((rc = DosCloseEventSem(hevEvent1)) && !e) { /* Get rid of semaphore */ - e = "DosCloseEventSem"; - badrc = rc; - } - if (e) { - SDL_SetError("[SDL_Delay] : Had error in %s(), rc is 0x%x\n", e, - badrc); - } -} - -/* Data to handle a single periodic alarm */ -static int timer_alive = 0; -static SDL_Thread *timer = NULL; - -static int SDLCALL -RunTimer(void *unused) -{ - DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); - 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) -{ - 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: OS/2 uses threaded timer"); - return (-1); -} - -void -SDL_SYS_StopTimer(void) -{ - return; -} - -#endif /* SDL_TIMER_OS2 */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/SDL_sysvideo.h Sat Sep 19 06:24:07 2009 +0000 +++ b/src/video/SDL_sysvideo.h Sat Sep 19 06:43:45 2009 +0000 @@ -395,9 +395,6 @@ #if SDL_VIDEO_DRIVER_RISCOS extern VideoBootStrap RISCOS_bootstrap; #endif -#if SDL_VIDEO_DRIVER_OS2FS -extern VideoBootStrap OS2FSLib_bootstrap; -#endif #if SDL_VIDEO_DRIVER_UIKIT extern VideoBootStrap UIKIT_bootstrap; #endif
--- a/src/video/SDL_video.c Sat Sep 19 06:24:07 2009 +0000 +++ b/src/video/SDL_video.c Sat Sep 19 06:43:45 2009 +0000 @@ -109,9 +109,6 @@ #if SDL_VIDEO_DRIVER_RISCOS &RISCOS_bootstrap, #endif -#if SDL_VIDEO_DRIVER_OS2FS - &OS2FSLib_bootstrap, -#endif #if SDL_VIDEO_DRIVER_NDS &NDS_bootstrap, #endif
--- a/src/video/os2fslib/SDL_os2fslib.c Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3122 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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@libsdl.org -*/ -#include "SDL_config.h" - -#define _ULS_CALLCONV_ -#define CALLCONV _System -#include <unidef.h> // Unicode API -#include <uconv.h> // Unicode API (codepage conversion) - -#include <process.h> -#include <time.h> - -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "../../events/SDL_events_c.h" - -#include "SDL_os2fslib.h" - -static ULONG ulFCFToUse = - FCF_TITLEBAR | - FCF_SYSMENU | - FCF_MINBUTTON | - FCF_MAXBUTTON | FCF_NOBYTEALIGN | FCF_SIZEBORDER | FCF_TASKLIST; - -static int bMouseCaptured = 0; -static int bMouseCapturable = 0; -static HPOINTER hptrGlobalPointer = NULL; -static HPOINTER hptrCurrentIcon = NULL; -static int iWindowSizeX = 320; -static int iWindowSizeY = 200; -static int bWindowResized = 0; - -#pragma pack(1) -typedef struct BMPINFO -{ - BITMAPINFO; - RGB clr; -} BMPINFO, *PBMPINFO; -#pragma pack() - - -// Backdoors: -DECLSPEC void SDLCALL -SDL_OS2FSLIB_SetFCFToUse(ULONG ulFCF) -{ - ulFCFToUse = ulFCF; -} - -// Configuration defines: - -// We have to report empty alpha mask, otherwise SDL will select -// alpha blitters, and this will have unwanted results, as we don't -// support alpha channel in FSLib yet. -#define REPORT_EMPTY_ALPHA_MASK - -// Experimental: Move every FSLib_BitBlt() call into window message -// processing function. -// This may fix dirt left on desktop. Or not. -//#define BITBLT_IN_WINMESSAGEPROC - -// Experimental-2: Use WinLockWindowUpdate() in around bitblts! -// This is not enabled, because it seems to cause more problems -// than good. -//#define USE_WINLOCKWINDOWUPDATE_AROUND_BITBLTS - -// Use the following to show resized image instead of black stuff -// even if the surface is resizable. -//#define RESIZE_EVEN_IF_RESIZABLE - -/* The translation table from a VK keysym to a SDL keysym */ -static SDLKey HWScanKeyMap[256]; -static SDL_keysym *TranslateKey(int vkey, int chcode, int scancode, - SDL_keysym * keysym, int iPressed); -static int iShiftIsPressed; - -#ifdef BITBLT_IN_WINMESSAGEPROC -#define WM_UPDATERECTSREQUEST WM_USER+50 -#endif - -#ifdef USE_WINLOCKWINDOWUPDATE_AROUND_BITBLTS -#define FSLIB_BITBLT(hwnd, buffer, top, left, width, height) \ - { \ - WinLockWindowUpdate(HWND_DESKTOP, HWND_DESKTOP); \ - FSLib_BitBlt(hwnd, buffer, top, left, width, height); \ - WinLockWindowUpdate(HWND_DESKTOP, NULL); \ - } -#else -#define FSLIB_BITBLT(hwnd, buffer, top, left, width, height) \ - FSLib_BitBlt(hwnd, buffer, top, left, width, height); -#endif - -///////////////////////////////////////////////////////////////////// -// -// SetAccessableWindowPos -// -// Same as WinSetWindowPos(), but takes care for the window to be -// always on the screen, the titlebar will be accessable everytime. -// -///////////////////////////////////////////////////////////////////// -static BOOL -SetAccessableWindowPos(HWND hwnd, HWND hwndInsertBehind, - LONG x, LONG y, LONG cx, LONG cy, ULONG fl) -{ - SWP swpDesktop, swp; - // Get desktop area - WinQueryWindowPos(HWND_DESKTOP, &swpDesktop); - - if ((fl & SWP_MOVE) && (fl & SWP_SIZE)) { - // If both moving and sizing, then change size and pos now!! - if (x + cx > swpDesktop.cx) - x = swpDesktop.cx - cx; - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (y + cy > swpDesktop.cy) - y = swpDesktop.cy - cy; - return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl); - } else if (fl & SWP_MOVE) { - // Just moving - WinQueryWindowPos(hwnd, &swp); - if (x + swp.cx > swpDesktop.cx) - x = swpDesktop.cx - swp.cx; - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (y + swp.cy > swpDesktop.cy) - y = swpDesktop.cy - swp.cy; - return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl); - } else if (fl & SWP_SIZE) { - // Just sizing - WinQueryWindowPos(hwnd, &swp); - x = swp.x; - y = swp.y; - if (x + cx > swpDesktop.cx) - x = swpDesktop.cx - cx; - if (x < 0) - x = 0; - if (y < 0) - y = 0; - if (y + cy > swpDesktop.cy) - y = swpDesktop.cy - cy; - return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, - fl | SWP_MOVE); - } else - return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl); -} - -static UniChar -NativeCharToUniChar(int chcode) -{ - UniChar ucResult = (UniChar) chcode; - int rc; - UconvObject ucoTemp; - char achFrom[2]; - char *pchFrom; - size_t iFromCount; - UniChar aucTo[10]; - UniChar *pucTo; - size_t iToCount; - size_t iNonIdentical; - - // Create unicode convert object - rc = UniCreateUconvObject(L"", &ucoTemp); - if (rc != ULS_SUCCESS) { - // Could not create convert object! - return ucResult; - } - // Convert language code string to unicode string - achFrom[0] = (char) chcode; - achFrom[1] = 0; - iFromCount = sizeof(char) * 2; - iToCount = sizeof(UniChar) * 2; - pucTo = &(aucTo[0]); - pchFrom = &(achFrom[0]); - - rc = UniUconvToUcs(ucoTemp, - &pchFrom, - &iFromCount, &pucTo, &iToCount, &iNonIdentical); - - if (rc != ULS_SUCCESS) { - // Could not convert language code to UCS string! - UniFreeUconvObject(ucoTemp); - return ucResult; - } - - UniFreeUconvObject(ucoTemp); - -#ifdef DEBUG_BUILD - printf("%02x converted to %02x\n", (int) chcode, (int) (aucTo[0])); -#endif - - return aucTo[0]; -} - -///////////////////////////////////////////////////////////////////// -// -// TranslateKey -// -// This creates SDL Keycodes from VK_ and hardware scan codes -// -///////////////////////////////////////////////////////////////////// -static SDL_keysym * -TranslateKey(int vkey, int chcode, int scancode, SDL_keysym * keysym, - int iPressed) -{ - keysym->scancode = (unsigned char) scancode; - keysym->mod = KMOD_NONE; - keysym->unicode = 0; - - if (iPressed && SDL_TranslateUNICODE) { - if (chcode) - keysym->unicode = NativeCharToUniChar(chcode); - else - keysym->unicode = vkey; - } - - keysym->sym = HWScanKeyMap[scancode]; - - // Now stuffs based on state of shift key(s)! - if (vkey == VK_SHIFT) { - iShiftIsPressed = iPressed; - } - - if ((iShiftIsPressed) && (SDL_TranslateUNICODE)) { - // Change syms, if Unicode stuff is required - // I think it's silly, but it's SDL... - switch (keysym->sym) { - case SDLK_BACKQUOTE: - keysym->sym = '~'; - break; - case SDLK_1: - keysym->sym = SDLK_EXCLAIM; - break; - case SDLK_2: - keysym->sym = SDLK_AT; - break; - case SDLK_3: - keysym->sym = SDLK_HASH; - break; - case SDLK_4: - keysym->sym = SDLK_DOLLAR; - break; - case SDLK_5: - keysym->sym = '%'; - break; - case SDLK_6: - keysym->sym = SDLK_CARET; - break; - case SDLK_7: - keysym->sym = SDLK_AMPERSAND; - break; - case SDLK_8: - keysym->sym = SDLK_ASTERISK; - break; - case SDLK_9: - keysym->sym = SDLK_LEFTPAREN; - break; - case SDLK_0: - keysym->sym = SDLK_RIGHTPAREN; - break; - case SDLK_MINUS: - keysym->sym = SDLK_UNDERSCORE; - break; - case SDLK_PLUS: - keysym->sym = SDLK_EQUALS; - break; - - case SDLK_LEFTBRACKET: - keysym->sym = '{'; - break; - case SDLK_RIGHTBRACKET: - keysym->sym = '}'; - break; - - case SDLK_SEMICOLON: - keysym->sym = SDLK_COLON; - break; - case SDLK_QUOTE: - keysym->sym = SDLK_QUOTEDBL; - break; - case SDLK_BACKSLASH: - keysym->sym = '|'; - break; - - case SDLK_COMMA: - keysym->sym = SDLK_LESS; - break; - case SDLK_PERIOD: - keysym->sym = SDLK_GREATER; - break; - case SDLK_SLASH: - keysym->sym = SDLK_QUESTION; - break; - - default: - break; - } - } - return keysym; -} - -#define CONVERTMOUSEPOSITION() \ - /* We have to inverse the mouse position, because every non-os/2 system */ \ - /* has a coordinate system where the (0;0) is the top-left corner, */ \ - /* while on os/2 it's the bottom left corner! */ \ - if (FSLib_QueryFSMode(hwnd)) \ - { \ - /* We're in FS mode! */ \ - /* In FS mode our window is as big as fullscreen mode, but not necessary as */ \ - /* big as the source buffer (can be bigger) */ \ - /* So, limit mouse pos to source buffer size! */ \ - if (ppts->x<0) ppts->x = 0; \ - if (ppts->y<0) ppts->y = 0; \ - if (ppts->x>=pVideo->hidden->SrcBufferDesc.uiXResolution) ppts->x = pVideo->hidden->SrcBufferDesc.uiXResolution-1; \ - if (ppts->y>=pVideo->hidden->SrcBufferDesc.uiYResolution) ppts->y = pVideo->hidden->SrcBufferDesc.uiYResolution-1; \ - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ \ - ptl.x = ppts->x; ptl.y = ppts->y; \ - WinMapWindowPoints(pVideo->hidden->hwndClient, HWND_DESKTOP, &ptl, 1); \ - WinSetPointerPos(HWND_DESKTOP, ptl.x, ptl.y); \ - /* Then convert OS/2 position to SDL position */ \ - ppts->y = pVideo->hidden->SrcBufferDesc.uiYResolution - ppts->y - 1; \ - } else \ - { \ - SWP swpClient; \ - /* We're in windowed mode! */ \ - WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient); \ - /* Convert OS/2 mouse position to SDL position, and also scale it! */ \ - (ppts->x) = (ppts->x) * pVideo->hidden->SrcBufferDesc.uiXResolution / swpClient.cx; \ - (ppts->y) = (ppts->y) * pVideo->hidden->SrcBufferDesc.uiYResolution / swpClient.cy; \ - (ppts->y) = pVideo->hidden->SrcBufferDesc.uiYResolution - (ppts->y) - 1; \ - } - - - -///////////////////////////////////////////////////////////////////// -// -// WndProc -// -// This is the message processing window procedure for the -// SDLWindowClass, which is the client window in our application. -// It handles switching back and away from the app (taking care of -// going out and back to and from fullscreen mode), sending keystrokes -// and mouse events to where it has to be sent, etc... -// -///////////////////////////////////////////////////////////////////// -static MRESULT EXPENTRY -WndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) -{ - HPS ps; - RECTL rcl; - SDL_VideoDevice *pVideo = NULL; - - switch (msg) { - case WM_CHAR: // Keypress notification -#ifdef DEBUG_BUILD -// printf("WM_CHAR\n"); fflush(stdout); -#endif - pVideo = WinQueryWindowPtr(hwnd, 0); - if (pVideo) { - /* - // We skip repeated keys: - if (CHARMSG(&msg)->cRepeat>1) - { - #ifdef DEBUG_BUILD - // printf("Repeated key (%d), skipping...\n", CHARMSG(&msg)->cRepeat); fflush(stdout); - #endif - return (MRESULT) TRUE; - } - */ - - // If it's not repeated, then let's see if its pressed or released! - if (SHORT1FROMMP(mp1) & KC_KEYUP) { - // A key has been released - SDL_keysym keysym; - -#ifdef DEBUG_BUILD -// printf("WM_CHAR, keyup, code is [0x%0x]\n", CHAR4FROMMP(mp1)); // HW scan code -#endif - - // One problem is with F1, which gets only the keyup message because - // it is a system key. - // So, when we get keyup message, we simulate keydown too! - // UPDATE: - // This problem should be solved now, that the accelerator keys are - // disabled for this window! - /* - if (SHORT2FROMMP(mp2)==VK_F1) - { - SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code - SHORT1FROMMP(mp2), // Character code - CHAR4FROMMP(mp1), // HW Scan code - &keysym,0)); - } */ - - SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code - SHORT1FROMMP(mp2), // Character code - CHAR4FROMMP(mp1), // HW Scan code - &keysym, 0)); - - } else { - // A key has been pressed - SDL_keysym keysym; - -#ifdef DEBUG_BUILD -// printf("WM_CHAR, keydown, code is [0x%0x]\n", CHAR4FROMMP(mp1)); // HW scan code -#endif - // Check for fastkeys: ALT+HOME to toggle FS mode - // ALT+END to close app - if ((SHORT1FROMMP(mp1) & KC_ALT) && - (SHORT2FROMMP(mp2) == VK_HOME)) { -#ifdef DEBUG_BUILD - printf(" Pressed ALT+HOME!\n"); - fflush(stdout); -#endif - // Only switch between fullscreen and back if it's not - // a resizable mode! - if ((!pVideo->hidden->pSDLSurface) || - ((pVideo->hidden->pSDLSurface) - && - ((pVideo->hidden-> - pSDLSurface->flags & SDL_RESIZABLE) == 0))) - FSLib_ToggleFSMode(hwnd, !FSLib_QueryFSMode(hwnd)); -#ifdef DEBUG_BUILD - else - printf(" Resizable mode, so discarding ALT+HOME!\n"); - fflush(stdout); -#endif - } else if ((SHORT1FROMMP(mp1) & KC_ALT) && - (SHORT2FROMMP(mp2) == VK_END)) { -#ifdef DEBUG_BUILD - printf(" Pressed ALT+END!\n"); - fflush(stdout); -#endif - // Close window, and get out of loop! - // Also send event to SDL application, but we won't - // wait for it to be processed! - SDL_PrivateQuit(); - WinPostMsg(hwnd, WM_QUIT, 0, 0); - } else { - - SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code - SHORT1FROMMP(mp2), // Character code - CHAR4FROMMP(mp1), // HW Scan code - &keysym, - 1)); - - } - } - } - return (MRESULT) TRUE; - - case WM_TRANSLATEACCEL: - { - PQMSG pqmsg; - pqmsg = (PQMSG) mp1; - if (mp1) { - if (pqmsg->msg == WM_CHAR) { - // WM_CHAR message! - // Let's filter the ALT keypress and all other acceleration keys! - return (MRESULT) FALSE; - } - } - break; // Default processing (pass to parent until frame control) - } - - case WM_PAINT: // Window redraw! -#ifdef DEBUG_BUILD - printf("WM_PAINT (0x%x)\n", hwnd); - fflush(stdout); -#endif - ps = WinBeginPaint(hwnd, 0, &rcl); - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - if (!pVideo->hidden->pSDLSurface) { - RECTL rclRect; - // So, don't blit now! -#ifdef DEBUG_BUILD - printf("WM_PAINT : Skipping blit while resizing (Pre!)!\n"); - fflush(stdout); -#endif - WinQueryWindowRect(hwnd, &rclRect); - // Fill with black - WinFillRect(ps, &rclRect, CLR_BLACK); - } else { - if (DosRequestMutexSem - (pVideo->hidden->hmtxUseSrcBuffer, 1000) == NO_ERROR) { - int iTop, iLeft, iWidth, iHeight; - int iXScaleError, iYScaleError; - int iXScaleError2, iYScaleError2; - SWP swp; - - // Re-blit the modified area! - // For this, we have to calculate the points, scaled! - WinQueryWindowPos(hwnd, &swp); -#ifdef DEBUG_BUILD - printf - ("WM_PAINT : WinSize: %d %d, BufSize: %d %d\n", - swp.cx, swp.cy, - pVideo->hidden->SrcBufferDesc.uiXResolution, - pVideo->hidden->SrcBufferDesc.uiYResolution); - fflush(stdout); -#endif - -#ifndef RESIZE_EVEN_IF_RESIZABLE - // But only blit if the window is not resizable, or if - // the window is resizable and the source buffer size is the - // same as the destination buffer size! - if ((!pVideo->hidden->pSDLSurface) || - ((pVideo->hidden->pSDLSurface) && - (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE) - && - ((swp.cx != - pVideo->hidden->SrcBufferDesc.uiXResolution) - || (swp.cy != - pVideo->hidden->SrcBufferDesc.uiYResolution)) - && (!FSLib_QueryFSMode(hwnd)))) { - RECTL rclRect; - // Resizable surface and in resizing! - // So, don't blit now! -#ifdef DEBUG_BUILD - printf("WM_PAINT : Skipping blit while resizing!\n"); - fflush(stdout); -#endif - WinQueryWindowRect(hwnd, &rclRect); - // Fill with black - WinFillRect(ps, &rclRect, CLR_BLACK); - } else -#endif - { - - iXScaleError = - (pVideo->hidden->SrcBufferDesc.uiXResolution - - 1) / swp.cx; - iYScaleError = - (pVideo->hidden->SrcBufferDesc.uiYResolution - - 1) / swp.cy; - if (iXScaleError < 0) - iXScaleError = 0; - if (iYScaleError < 0) - iYScaleError = 0; - iXScaleError2 = - (swp.cx - - 1) / - (pVideo->hidden->SrcBufferDesc.uiXResolution); - iYScaleError2 = - (swp.cy - - 1) / - (pVideo->hidden->SrcBufferDesc.uiYResolution); - if (iXScaleError2 < 0) - iXScaleError2 = 0; - if (iYScaleError2 < 0) - iYScaleError2 = 0; - - iTop = - (swp.cy - - rcl.yTop) * - pVideo->hidden->SrcBufferDesc.uiYResolution / - swp.cy - iYScaleError; - iLeft = - rcl.xLeft * - pVideo->hidden->SrcBufferDesc.uiXResolution / - swp.cx - iXScaleError; - iWidth = - ((rcl.xRight - - rcl.xLeft) * - pVideo->hidden->SrcBufferDesc.uiXResolution + - swp.cx - 1) / swp.cx + 2 * iXScaleError; - iHeight = - ((rcl.yTop - - rcl.yBottom) * - pVideo->hidden->SrcBufferDesc.uiYResolution + - swp.cy - 1) / swp.cy + 2 * iYScaleError; - - iWidth += iXScaleError2; - iHeight += iYScaleError2; - - if (iTop < 0) - iTop = 0; - if (iLeft < 0) - iLeft = 0; - if (iTop + iHeight > - pVideo->hidden->SrcBufferDesc.uiYResolution) - iHeight = - pVideo->hidden->SrcBufferDesc.uiYResolution - - iTop; - if (iLeft + iWidth > - pVideo->hidden->SrcBufferDesc.uiXResolution) - iWidth = - pVideo->hidden->SrcBufferDesc.uiXResolution - - iLeft; - -#ifdef DEBUG_BUILD - printf - ("WM_PAINT : BitBlt: %d %d -> %d %d (Buf %d x %d)\n", - iTop, iLeft, iWidth, iHeight, - pVideo->hidden->SrcBufferDesc.uiXResolution, - pVideo->hidden->SrcBufferDesc.uiYResolution); - fflush(stdout); -#endif - - FSLIB_BITBLT(hwnd, - pVideo->hidden->pchSrcBuffer, - iTop, iLeft, iWidth, iHeight); - } - - DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer); - } - } - } -#ifdef DEBUG_BUILD - else { - printf("WM_PAINT : No pVideo!\n"); - fflush(stdout); - } -#endif - WinEndPaint(ps); -#ifdef DEBUG_BUILD - printf("WM_PAINT : Done.\n"); - fflush(stdout); -#endif - return 0; - - case WM_SIZE: - { -#ifdef DEBUG_BUILD - printf("WM_SIZE : (%d %d)\n", - SHORT1FROMMP(mp2), SHORT2FROMMP(mp2)); - fflush(stdout); -#endif - iWindowSizeX = SHORT1FROMMP(mp2); - iWindowSizeY = SHORT2FROMMP(mp2); - bWindowResized = 1; - - // Make sure the window will be redrawn - WinInvalidateRegion(hwnd, NULL, TRUE); - } - break; - - case WM_FSLIBNOTIFICATION: -#ifdef DEBUG_BUILD - printf("WM_FSLIBNOTIFICATION\n"); - fflush(stdout); -#endif - if ((int) mp1 == FSLN_TOGGLEFSMODE) { - // FS mode changed, reblit image! - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - if (!pVideo->hidden->pSDLSurface) { - // Resizable surface and in resizing! - // So, don't blit now! -#ifdef DEBUG_BUILD - printf - ("WM_FSLIBNOTIFICATION : Can not blit if there is no surface, doing nothing.\n"); - fflush(stdout); -#endif - } else { - if (DosRequestMutexSem - (pVideo->hidden->hmtxUseSrcBuffer, - 1000) == NO_ERROR) { - if (pVideo->hidden->pSDLSurface) { -#ifndef RESIZE_EVEN_IF_RESIZABLE - SWP swp; - - // But only blit if the window is not resizable, or if - // the window is resizable and the source buffer size is the - // same as the destination buffer size! - WinQueryWindowPos(hwnd, &swp); - if ((!pVideo->hidden->pSDLSurface) || - ((pVideo->hidden->pSDLSurface) && - (pVideo->hidden-> - pSDLSurface->flags & SDL_RESIZABLE) - && - ((swp.cx != - pVideo->hidden-> - SrcBufferDesc.uiXResolution) - || (swp.cy != - pVideo->hidden->SrcBufferDesc. - uiYResolution)) - && (!FSLib_QueryFSMode(hwnd)))) { - // Resizable surface and in resizing! - // So, don't blit now! -#ifdef DEBUG_BUILD - printf - ("WM_FSLIBNOTIFICATION : Cannot blit while resizing, doing nothing.\n"); - fflush(stdout); -#endif - } else -#endif - { -#ifdef DEBUG_BUILD - printf("WM_FSLIBNOTIFICATION : Blitting!\n"); - fflush(stdout); -#endif - FSLIB_BITBLT(hwnd, - pVideo->hidden->pchSrcBuffer, 0, - 0, - pVideo->hidden-> - SrcBufferDesc.uiXResolution, - pVideo->hidden->SrcBufferDesc. - uiYResolution); - } - } -#ifdef DEBUG_BUILD - else - printf - ("WM_FSLIBNOTIFICATION : No public surface!\n"); - fflush(stdout); -#endif - - DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer); - } - } - } - } - return (MPARAM) 1; - - case WM_ACTIVATE: -#ifdef DEBUG_BUILD - printf("WM_ACTIVATE\n"); - fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - pVideo->hidden->fInFocus = (int) mp1; - if (pVideo->hidden->fInFocus) { - // Went into focus - if ((pVideo->hidden->iMouseVisible) - && (!bMouseCaptured)) - WinSetPointer(HWND_DESKTOP, - WinQuerySysPointer(HWND_DESKTOP, - SPTR_ARROW, FALSE)); - else - WinSetPointer(HWND_DESKTOP, NULL); - - if (bMouseCapturable) { - // Re-capture the mouse, if we captured it before! - WinSetCapture(HWND_DESKTOP, hwnd); - bMouseCaptured = 1; - { - SWP swpClient; - POINTL ptl; - // Center the mouse to the middle of the window! - WinQueryWindowPos(pVideo->hidden->hwndClient, - &swpClient); - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(pVideo->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } - } - } else { - // Went out of focus - WinSetPointer(HWND_DESKTOP, - WinQuerySysPointer(HWND_DESKTOP, - SPTR_ARROW, FALSE)); - - if (bMouseCaptured) { - // Release the mouse - WinSetCapture(HWND_DESKTOP, hwnd); - bMouseCaptured = 0; - } - } - } -#ifdef DEBUG_BUILD - printf("WM_ACTIVATE done\n"); - fflush(stdout); -#endif - - break; - - case WM_BUTTON1DOWN: -#ifdef DEBUG_BUILD - printf("WM_BUTTON1DOWN\n"); - fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0); // Don't report mouse movement! - - if (bMouseCapturable) { - // We should capture the mouse! - if (!bMouseCaptured) { - WinSetCapture(HWND_DESKTOP, hwnd); - WinSetPointer(HWND_DESKTOP, NULL); - bMouseCaptured = 1; - { - SWP swpClient; - POINTL ptl; - // Center the mouse to the middle of the window! - WinQueryWindowPos(pVideo->hidden->hwndClient, - &swpClient); - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(pVideo->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } - } - } - } - break; - case WM_BUTTON1UP: -#ifdef DEBUG_BUILD - printf("WM_BUTTON1UP\n"); - fflush(stdout); -#endif - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0); // Don't report mouse movement! - break; - case WM_BUTTON2DOWN: -#ifdef DEBUG_BUILD - printf("WM_BUTTON2DOWN\n"); - fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0); // Don't report mouse movement! - - if (bMouseCapturable) { - // We should capture the mouse! - if (!bMouseCaptured) { - WinSetCapture(HWND_DESKTOP, hwnd); - WinSetPointer(HWND_DESKTOP, NULL); - bMouseCaptured = 1; - { - SWP swpClient; - POINTL ptl; - // Center the mouse to the middle of the window! - WinQueryWindowPos(pVideo->hidden->hwndClient, - &swpClient); - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(pVideo->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } - } - } - - } - break; - case WM_BUTTON2UP: -#ifdef DEBUG_BUILD - printf("WM_BUTTON2UP\n"); - fflush(stdout); -#endif - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0); // Don't report mouse movement! - break; - case WM_BUTTON3DOWN: -#ifdef DEBUG_BUILD - printf("WM_BUTTON3DOWN\n"); - fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0); // Don't report mouse movement! - - if (bMouseCapturable) { - // We should capture the mouse! - if (!bMouseCaptured) { - WinSetCapture(HWND_DESKTOP, hwnd); - WinSetPointer(HWND_DESKTOP, NULL); - bMouseCaptured = 1; - { - SWP swpClient; - POINTL ptl; - // Center the mouse to the middle of the window! - WinQueryWindowPos(pVideo->hidden->hwndClient, - &swpClient); - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(pVideo->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } - } - } - } - break; - case WM_BUTTON3UP: -#ifdef DEBUG_BUILD - printf("WM_BUTTON3UP\n"); - fflush(stdout); -#endif - SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0); // Don't report mouse movement! - break; - case WM_MOUSEMOVE: -#ifdef DEBUG_BUILD -// printf("WM_MOUSEMOVE\n"); fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - if (pVideo->hidden->iSkipWMMOUSEMOVE) { - pVideo->hidden->iSkipWMMOUSEMOVE--; - } else { - POINTS *ppts = (POINTS *) (&mp1); - POINTL ptl; - - if (bMouseCaptured) { - SWP swpClient; - - WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient); - - // Send relative mouse position, and re-center the mouse - // Reposition the mouse to the center of the screen/window - SDL_PrivateMouseMotion(0, // Buttons not changed - 1, // Relative position - ppts->x - - (swpClient.cx / 2), - (swpClient.cy / 2) - ppts->y); - - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(pVideo->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - // Center the mouse to the middle of the window! - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } else { - CONVERTMOUSEPOSITION(); - - // Send absolute mouse position - SDL_PrivateMouseMotion(0, // Buttons not changed - 0, // Absolute position - ppts->x, ppts->y); - } - } - if ((pVideo->hidden->iMouseVisible) && (!bMouseCaptured)) { -#ifdef DEBUG_BUILD -// printf("WM_MOUSEMOVE : ptr = %p\n", hptrGlobalPointer); fflush(stdout); -#endif - - if (hptrGlobalPointer) - WinSetPointer(HWND_DESKTOP, hptrGlobalPointer); - else - WinSetPointer(HWND_DESKTOP, - WinQuerySysPointer(HWND_DESKTOP, - SPTR_ARROW, FALSE)); - } else { - WinSetPointer(HWND_DESKTOP, NULL); - } - } -#ifdef DEBUG_BUILD -// printf("WM_MOUSEMOVE done\n"); fflush(stdout); -#endif - - return (MRESULT) FALSE; - case WM_CLOSE: // Window close -#ifdef DEBUG_BUILD - printf("WM_CLOSE\n"); - fflush(stdout); -#endif - - pVideo = FSLib_GetUserParm(hwnd); - if (pVideo) { - // Send Quit message to the SDL application! - SDL_PrivateQuit(); - return 0; - } - break; - -#ifdef BITBLT_IN_WINMESSAGEPROC - case WM_UPDATERECTSREQUEST: - pVideo = FSLib_GetUserParm(hwnd); - if ((pVideo) && (pVideo->hidden->pSDLSurface)) { - if (DosRequestMutexSem - (pVideo->hidden->hmtxUseSrcBuffer, - SEM_INDEFINITE_WAIT) == NO_ERROR) { - int numrects; - SDL_Rect *rects; - int i; - SWP swp; - - numrects = (int) mp1; - rects = (SDL_Rect *) mp2; - - WinQueryWindowPos(hwnd, &swp); -#ifndef RESIZE_EVEN_IF_RESIZABLE - if ((!pVideo->hidden->pSDLSurface) || - ((pVideo->hidden->pSDLSurface) && - (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE) - && - ((swp.cx != pVideo->hidden->SrcBufferDesc.uiXResolution) - || (swp.cy != - pVideo->hidden->SrcBufferDesc.uiYResolution)) - && (!FSLib_QueryFSMode(hwnd)))) { - // Resizable surface and in resizing! - // So, don't blit now! -#ifdef DEBUG_BUILD - printf - ("[WM_UPDATERECTSREQUEST] : Skipping blit while resizing!\n"); - fflush(stdout); -#endif - } else -#endif - { -#ifdef DEBUG_BUILD - printf("[WM_UPDATERECTSREQUEST] : Blitting!\n"); - fflush(stdout); -#endif - - // Blit the changed areas - for (i = 0; i < numrects; i++) - FSLIB_BITBLT(hwnd, - pVideo->hidden->pchSrcBuffer, - rects[i].y, rects[i].x, - rects[i].w, rects[i].h); - } - DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer); - } - } - return 0; -#endif - - default: -#ifdef DEBUG_BUILD - printf("Unhandled: %x\n", msg); - fflush(stdout); -#endif - - break; - } - // Run the default window procedure for unhandled stuffs - return WinDefWindowProc(hwnd, msg, mp1, mp2); -} - -///////////////////////////////////////////////////////////////////// -// -// FrameWndProc -// -// This is the message processing window procedure for the -// frame window of SDLWindowClass. -// -///////////////////////////////////////////////////////////////////// -static MRESULT EXPENTRY -FrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) -{ - PFNWP pOldFrameProc; - MRESULT result; - PTRACKINFO ti; - int cx, cy, ncx, ncy; - RECTL rclTemp; - PSWP pswpTemp; - - SDL_VideoDevice *pVideo = NULL; - - pVideo = (SDL_VideoDevice *) WinQueryWindowULong(hwnd, QWL_USER); - - pOldFrameProc = pVideo->hidden->pfnOldFrameProc; - - if ((pVideo->hidden->bProportionalResize) && - (msg == WM_ADJUSTWINDOWPOS) && - (!FSLib_QueryFSMode(pVideo->hidden->hwndClient))) { - pswpTemp = (PSWP) mp1; - - /* Resizing? */ - if (pswpTemp->fl & SWP_SIZE) { - /* Calculate client size */ - rclTemp.xLeft = pswpTemp->x; - rclTemp.xRight = pswpTemp->x + pswpTemp->cx; - rclTemp.yBottom = pswpTemp->y; - rclTemp.yTop = pswpTemp->y + pswpTemp->cy; - WinCalcFrameRect(hwnd, &rclTemp, TRUE); - - ncx = cx = rclTemp.xRight - rclTemp.xLeft; - ncy = cy = rclTemp.yTop - rclTemp.yBottom; - - /* Calculate new size to keep it proportional */ - - if ((pVideo->hidden->ulResizingFlag & TF_LEFT) - || (pVideo->hidden->ulResizingFlag & TF_RIGHT)) { - /* The window is resized horizontally */ - ncy = - pVideo->hidden->SrcBufferDesc.uiYResolution * cx / - pVideo->hidden->SrcBufferDesc.uiXResolution; - } else if ((pVideo->hidden->ulResizingFlag & TF_TOP) - || (pVideo->hidden->ulResizingFlag & TF_BOTTOM)) { - /* The window is resized vertically */ - ncx = - pVideo->hidden->SrcBufferDesc.uiXResolution * cy / - pVideo->hidden->SrcBufferDesc.uiYResolution; - } - - /* Calculate back frame coordinates */ - rclTemp.xLeft = pswpTemp->x; - rclTemp.xRight = pswpTemp->x + ncx; - rclTemp.yBottom = pswpTemp->y; - rclTemp.yTop = pswpTemp->y + ncy; - WinCalcFrameRect(hwnd, &rclTemp, FALSE); - - /* Store new size/position info */ - pswpTemp->cx = rclTemp.xRight - rclTemp.xLeft; - - if (!(pVideo->hidden->ulResizingFlag & TF_TOP)) { - pswpTemp->y = - pswpTemp->y + pswpTemp->cy - (rclTemp.yTop - - rclTemp.yBottom); - pswpTemp->cy = rclTemp.yTop - rclTemp.yBottom; - } else { - pswpTemp->cy = rclTemp.yTop - rclTemp.yBottom; - } - } - } - - result = (*pOldFrameProc) (hwnd, msg, mp1, mp2); - - if ((pVideo->hidden->bProportionalResize) && (msg == WM_QUERYTRACKINFO)) { - ti = (PTRACKINFO) mp2; - - /* Store the direction of resizing */ - if ((ti->fs & TF_LEFT) || (ti->fs & TF_RIGHT) || - (ti->fs & TF_TOP) || (ti->fs & TF_BOTTOM)) - pVideo->hidden->ulResizingFlag = ti->fs; - } - - return result; -} - -///////////////////////////////////////////////////////////////////// -// -// PMThreadFunc -// -// This function implements the PM-Thread, which initializes the -// application window itself, the DIVE, and start message processing. -// -///////////////////////////////////////////////////////////////////// -int iNumOfPMThreadInstances = 0; // Global! -static void -PMThreadFunc(void *pParm) -{ - SDL_VideoDevice *pVideo = pParm; - HAB hab; - HMQ hmq; - QMSG msg; - ULONG fcf; - -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : Starting\n"); - fflush(stdout); -#endif - - iNumOfPMThreadInstances++; - - // Initialize PM, create a message queue. - - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - if (hmq == 0) { -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : Could not create message queue!\n"); - printf - (" It might be that the application using SDL is not a PM app!\n"); - fflush(stdout); -#endif - pVideo->hidden->iPMThreadStatus = 2; - } else { - int rc; - RECTL rectl; - - fcf = ulFCFToUse; // Get from global setting - -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : FSLib_CreateWindow()!\n"); - fflush(stdout); -#endif - - rc = FSLib_CreateWindow(HWND_DESKTOP, 0, &fcf, - "SDL Application", - NULLHANDLE, 0, - &(pVideo->hidden->SrcBufferDesc), - WndProc, - &(pVideo->hidden->hwndClient), - &(pVideo->hidden->hwndFrame)); - -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : FSLib_CreateWindow() rc = %d\n", rc); - fflush(stdout); -#endif - - if (!rc) { -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : Could not create FSLib window!\n"); - fflush(stdout); -#endif - pVideo->hidden->iPMThreadStatus = 3; - } else { -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : FSLib_AddUserParm()!\n"); - fflush(stdout); -#endif - - // Store pVideo pointer in window data for client window, so - // it will know the instance to which it belongs to. - FSLib_AddUserParm(pVideo->hidden->hwndClient, pVideo); - - // Now set default image width height and fourcc! -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : SetWindowPos()!\n"); - fflush(stdout); -#endif - - // Set the position and size of the main window, - // and make it visible! - // Calculate frame window size from client window size - rectl.xLeft = 0; - rectl.yBottom = 0; - rectl.xRight = pVideo->hidden->SrcBufferDesc.uiXResolution; // Noninclusive - rectl.yTop = pVideo->hidden->SrcBufferDesc.uiYResolution; // Noninclusive - WinCalcFrameRect(pVideo->hidden->hwndFrame, &rectl, FALSE); - - SetAccessableWindowPos(pVideo->hidden->hwndFrame, - HWND_TOP, - (WinQuerySysValue - (HWND_DESKTOP, - SV_CXSCREEN) - (rectl.xRight - - rectl.xLeft)) / 2, - (WinQuerySysValue - (HWND_DESKTOP, - SV_CYSCREEN) - (rectl.yTop - - rectl.yBottom)) / 2, - (rectl.xRight - rectl.xLeft), - (rectl.yTop - rectl.yBottom), - SWP_SIZE | SWP_ACTIVATE | SWP_SHOW | - SWP_MOVE); - - // Subclass frame procedure and store old window proc address - pVideo->hidden->pfnOldFrameProc = - WinSubclassWindow(pVideo->hidden->hwndFrame, FrameWndProc); - WinSetWindowULong(pVideo->hidden->hwndFrame, QWL_USER, - (ULONG) pVideo); - -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : Entering message loop\n"); - fflush(stdout); -#endif - pVideo->hidden->iPMThreadStatus = 1; - - while (WinGetMsg(hab, (PQMSG) & msg, 0, 0, 0)) - WinDispatchMsg(hab, (PQMSG) & msg); - -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : Leaving message loop\n"); - fflush(stdout); -#endif - // We should release the captured the mouse! - if (bMouseCaptured) { - WinSetCapture(HWND_DESKTOP, NULLHANDLE); - bMouseCaptured = 0; - } - // Destroy our window - WinDestroyWindow(pVideo->hidden->hwndFrame); - pVideo->hidden->hwndFrame = NULL; - // Show pointer to make sure it will not be left hidden. - WinSetPointer(HWND_DESKTOP, - WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, - FALSE)); - WinShowPointer(HWND_DESKTOP, TRUE); - } - // Uninitialize PM - WinDestroyMsgQueue(hmq); - // All done! - pVideo->hidden->iPMThreadStatus = 0; - } - WinTerminate(hab); - /* Commented out, should not be needed anymore, because we send it - from WM_CLOSE. - // Notify SDL that it should really die now... - SDL_PrivateQuit(); SDL_PrivateQuit(); SDL_PrivateQuit(); //... :)) - */ -#ifdef DEBUG_BUILD - printf("[PMThreadFunc] : End, status is %d!\n", - pVideo->hidden->iPMThreadStatus); - fflush(stdout); -#endif - - iNumOfPMThreadInstances--; - - // HACK to prevent zombie and hanging SDL applications, which does not take - // care of closing the window for some reason: - // There are some apps which do not process messages, so do a lot of things - // without noticing that the application should close. To close these, - // I've thought about the following: - // If the window is closed (the execution came here), I wait a bit to - // give time to the app to finish its execution. If it does not, I kill it - // using DosExit(). Brute force, but should work. - if (pVideo->hidden->iPMThreadStatus == 0) { - DosSleep(5000); // Wait 5 secs - // If a new PM thread has been spawned (reinitializing video mode), then all right. - // Otherwise, we have a problem, the app doesn't want to stop. Kill! - if (iNumOfPMThreadInstances == 0) { -#ifdef DEBUG_BUILD - printf - ("[PMThreadFunc] : It seems that the application haven't terminated itself\n"); - fflush(stdout); - printf - ("[PMThreadFunc] : in the last 5 seconds, so we go berserk.\n"); - fflush(stdout); - printf - ("[PMThreadFunc] : Brute force mode. :) Killing process! Dieeeee...\n"); - fflush(stdout); -#endif - DosExit(EXIT_PROCESS, -1); - } - } - _endthread(); -} - -struct WMcursor -{ - HBITMAP hbm; - HPOINTER hptr; - char *pchData; -}; - -/* Free a window manager cursor */ -void -os2fslib_FreeWMCursor(_THIS, WMcursor * cursor) -{ - if (cursor) { - GpiDeleteBitmap(cursor->hbm); - WinDestroyPointer(cursor->hptr); - SDL_free(cursor->pchData); - SDL_free(cursor); - } -} - -/* Local functions to convert the SDL cursor mask into OS/2 format */ -static void -memnot(Uint8 * dst, Uint8 * src, int len) -{ - while (len-- > 0) - *dst++ = ~*src++; -} - -static void -memxor(Uint8 * dst, Uint8 * src1, Uint8 * src2, int len) -{ - while (len-- > 0) - *dst++ = (*src1++) ^ (*src2++); -} - -/* Create a black/white window manager cursor */ -WMcursor * -os2fslib_CreateWMCursor_Win(_THIS, Uint8 * data, Uint8 * mask, - int w, int h, int hot_x, int hot_y) -{ - HPOINTER hptr; - HBITMAP hbm; - BITMAPINFOHEADER bmih; - BMPINFO bmi; - HPS hps; - char *pchTemp; - char *xptr, *aptr; - int maxx, maxy; - int i, run, pad; - WMcursor *pResult; - - maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER); - maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER); - - // Check for max size! - if ((w > maxx) || (h > maxy)) - return (WMcursor *) NULL; - - pResult = (WMcursor *) SDL_malloc(sizeof(WMcursor)); - if (!pResult) - return (WMcursor *) NULL; - - pchTemp = (char *) SDL_malloc((maxx + 7) / 8 * maxy * 2); - if (!pchTemp) { - SDL_free(pResult); - return (WMcursor *) NULL; - } - - SDL_memset(pchTemp, 0, (maxx + 7) / 8 * maxy * 2); - - hps = WinGetPS(_this->hidden->hwndClient); - - bmi.cbFix = sizeof(BITMAPINFOHEADER); - bmi.cx = maxx; - bmi.cy = 2 * maxy; - bmi.cPlanes = 1; - bmi.cBitCount = 1; - bmi.argbColor[0].bBlue = 0x00; - bmi.argbColor[0].bGreen = 0x00; - bmi.argbColor[0].bRed = 0x00; - bmi.argbColor[1].bBlue = 0x00; - bmi.argbColor[1].bGreen = 0x00; - bmi.argbColor[1].bRed = 0xff; - - SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); - bmih.cbFix = sizeof(BITMAPINFOHEADER); - bmih.cx = maxx; - bmih.cy = 2 * maxy; - bmih.cPlanes = 1; - bmih.cBitCount = 1; - - run = (w + 7) / 8; - pad = (maxx + 7) / 8 - run; - - for (i = 0; i < h; i++) { - xptr = pchTemp + (maxx + 7) / 8 * (maxy - 1 - i); - aptr = pchTemp + (maxx + 7) / 8 * (maxy + maxy - 1 - i); - memxor(xptr, data, mask, run); - xptr += run; - data += run; - memnot(aptr, mask, run); - mask += run; - aptr += run; - SDL_memset(xptr, 0, pad); - xptr += pad; - SDL_memset(aptr, ~0, pad); - aptr += pad; - } - pad += run; - for (i = h; i < maxy; i++) { - xptr = pchTemp + (maxx + 7) / 8 * (maxy - 1 - i); - aptr = pchTemp + (maxx + 7) / 8 * (maxy + maxy - 1 - i); - - SDL_memset(xptr, 0, (maxx + 7) / 8); - xptr += (maxx + 7) / 8; - SDL_memset(aptr, ~0, (maxx + 7) / 8); - aptr += (maxx + 7) / 8; - } - - hbm = - GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) & bmih, CBM_INIT, - (PBYTE) pchTemp, (PBITMAPINFO2) & bmi); - hptr = WinCreatePointer(HWND_DESKTOP, hbm, TRUE, hot_x, maxy - hot_y - 1); - -#ifdef DEBUG_BUILD - printf("HotSpot : %d ; %d\n", hot_x, hot_y); - printf("HPS returned : %x\n", (ULONG) hps); - printf("HBITMAP returned : %x\n", (ULONG) hbm); - printf("HPOINTER returned: %x\n", (ULONG) hptr); -#endif - - WinReleasePS(hps); - -#ifdef DEBUG_BUILD - printf("[CreateWMCursor] : ptr = %p\n", hptr); - fflush(stdout); -#endif - - pResult->hptr = hptr; - pResult->hbm = hbm; - pResult->pchData = pchTemp; - -#ifdef DEBUG_BUILD - printf("[CreateWMCursor] : ptr = %p return.\n", hptr); - fflush(stdout); -#endif - - return (WMcursor *) pResult; -} - -WMcursor * -os2fslib_CreateWMCursor_FS(_THIS, Uint8 * data, Uint8 * mask, - int w, int h, int hot_x, int hot_y) -{ -#ifdef DEBUG_BUILD - printf("[CreateWMCursor_FS] : returning pointer NULL\n"); - fflush(stdout); -#endif - - // In FS mode we'll use software cursor - return (WMcursor *) NULL; -} - -/* Show the specified cursor, or hide if cursor is NULL */ -int -os2fslib_ShowWMCursor(_THIS, WMcursor * cursor) -{ -#ifdef DEBUG_BUILD - printf("[ShowWMCursor] : ptr = %p\n", cursor); - fflush(stdout); -#endif - - if (cursor) { - WinSetPointer(HWND_DESKTOP, cursor->hptr); - hptrGlobalPointer = cursor->hptr; - _this->hidden->iMouseVisible = 1; - } else { - WinSetPointer(HWND_DESKTOP, FALSE); - hptrGlobalPointer = NULL; - _this->hidden->iMouseVisible = 0; - } - -#ifdef DEBUG_BUILD - printf("[ShowWMCursor] : ptr = %p, DONE\n", cursor); - fflush(stdout); -#endif - - return 1; -} - -/* Warp the window manager cursor to (x,y) - If NULL, a mouse motion event is posted internally. - */ -void -os2fslib_WarpWMCursor(_THIS, Uint16 x, Uint16 y) -{ - LONG lx, ly; - SWP swpClient; - POINTL ptlPoints; - WinQueryWindowPos(_this->hidden->hwndClient, &swpClient); - ptlPoints.x = swpClient.x; - ptlPoints.y = swpClient.y; - WinMapWindowPoints(_this->hidden->hwndFrame, HWND_DESKTOP, &ptlPoints, 1); - lx = ptlPoints.x + - (x * swpClient.cx) / _this->hidden->SrcBufferDesc.uiXResolution; - ly = ptlPoints.y + swpClient.cy - - ((y * swpClient.cy) / _this->hidden->SrcBufferDesc.uiYResolution) - 1; - - SDL_PrivateMouseMotion(0, // Buttons not changed - 0, // Absolute position - x, y); - - WinSetPointerPos(HWND_DESKTOP, lx, ly); - -} - -/* If not NULL, this is called when a mouse motion event occurs */ -void -os2fslib_MoveWMCursor(_THIS, int x, int y) -{ - /* - SDL_Rect rect; - - #ifdef DEBUG_BUILD - printf("[MoveWMCursor] : at %d ; %d\n", x, y); fflush(stdout); - #endif - - rect.x = x; - rect.y = y; - rect.w = 32; - rect.h = 32; - os2fslib_UpdateRects(_this, 1, &rect); - // TODO! - */ -} - -/* Determine whether the mouse should be in relative mode or not. - This function is called when the input grab state or cursor - visibility state changes. - If the cursor is not visible, and the input is grabbed, the - driver can place the mouse in relative mode, which may result - in higher accuracy sampling of the pointer motion. - */ -void -os2fslib_CheckMouseMode(_THIS) -{ -} - -static void -os2fslib_PumpEvents(_THIS) -{ - // Notify SDL that if window has been resized! - if ((_this->hidden->pSDLSurface) && - (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) && - ((_this->hidden->SrcBufferDesc.uiXResolution != iWindowSizeX) || - (_this->hidden->SrcBufferDesc.uiYResolution != iWindowSizeY)) && - (iWindowSizeX > 0) && (iWindowSizeY > 0)) { - static time_t prev_time; - time_t curr_time; - - curr_time = time(NULL); - if ((difftime(curr_time, prev_time) >= 0.25) || (bWindowResized)) { - // Make sure we won't flood the event queue with resize events, - // only send them at 250 msecs! - // (or when the window is resized) -#ifdef DEBUG_BUILD - printf - ("[os2fslib_PumpEvents] : Calling PrivateResize (%d %d).\n", - iWindowSizeX, iWindowSizeY); - fflush(stdout); -#endif - // Tell SDL the new size - SDL_PrivateResize(iWindowSizeX, iWindowSizeY); - prev_time = curr_time; - bWindowResized = 0; - } - } -} - -/* We don't actually allow hardware surfaces other than the main one */ -static int -os2fslib_AllocHWSurface(_THIS, SDL_Surface * surface) -{ - return (-1); -} - -static void -os2fslib_FreeHWSurface(_THIS, SDL_Surface * surface) -{ - return; -} - -/* We need to wait for vertical retrace on page flipped displays */ -static int -os2fslib_LockHWSurface(_THIS, SDL_Surface * surface) -{ - return (0); -} - -static void -os2fslib_UnlockHWSurface(_THIS, SDL_Surface * surface) -{ - return; -} - -static int -os2fslib_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors) -{ - printf("[os2fslib_SetColors] : TODO!\n"); - fflush(stdout); - // TODO: Implement paletted modes - return (1); -} - -static void -os2fslib_DestroyIcon(HWND hwndFrame) -{ - if (hptrCurrentIcon) { - WinDestroyPointer(hptrCurrentIcon); - hptrCurrentIcon = NULL; - - WinSendMsg(hwndFrame, WM_SETICON, NULL, NULL); - } - -} - -/* Set the window icon image */ -void -os2fslib_SetIcon(_THIS, SDL_Surface * icon, Uint8 * mask) -{ - HWND hwndFrame; - SDL_Surface *icon_rgb; - HPOINTER hptrIcon; - HBITMAP hbm; - BITMAPINFOHEADER bmih; - BMPINFO bmi; - HPS hps; - char *pchTemp; - char *pptr, *mptr, *dptr, *dmptr; - int maxx, maxy, w, h, x, y; - SDL_Rect bounds; - -#ifdef DEBUG_BUILD - printf("[os2fslib_SetIcon] : Creating and setting new icon\n"); - fflush(stdout); -#endif - - hwndFrame = WinQueryWindow(_this->hidden->hwndClient, QW_PARENT); - - // Make sure the old icon resource will be free'd! - os2fslib_DestroyIcon(hwndFrame); - - if ((!icon) || (!mask)) - return; - - w = icon->w; - h = icon->h; - - maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXICON); - maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYICON); - - // Check for max size! - if ((w > maxx) || (h > maxy)) - return; - - pchTemp = (char *) SDL_malloc(w * h * 2 * 4); - if (!pchTemp) - return; - - SDL_memset(pchTemp, 0, w * h * 2 * 4); - - // Convert surface to RGB, if it's not RGB yet! - icon_rgb = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h, - 32, 0, 0, 0, 0); - if (icon_rgb == NULL) { - SDL_free(pchTemp); - return; - } - bounds.x = 0; - bounds.y = 0; - bounds.w = icon->w; - bounds.h = icon->h; - if (SDL_LowerBlit(icon, &bounds, icon_rgb, &bounds) < 0) { - SDL_FreeSurface(icon_rgb); - SDL_free(pchTemp); - return; - } - - /* Copy pixels upside-down from RGB surface into BMP, masked with the icon mask */ - - // Pixels - pptr = (char *) (icon_rgb->pixels); - // Mask - mptr = mask; - - for (y = 0; y < h; y++) { - unsigned char uchMaskByte; - - // Destination - dptr = pchTemp + w * 4 * (h - y - 1); - // Destination mask - dmptr = pchTemp + w * h * 4 + w * 4 * (h - y - 1); - - for (x = 0; x < w; x++) { - if (x % 8 == 0) { - uchMaskByte = (unsigned char) (*mptr); - mptr++; - } else - uchMaskByte <<= 1; - - if (uchMaskByte & 0x80) { - // Copy RGB - *dptr++ = *pptr++; - *dptr++ = *pptr++; - *dptr++ = *pptr++; - *dptr++ = *pptr++; - - *dmptr++ = 0; - *dmptr++ = 0; - *dmptr++ = 0; - *dmptr++ = 0; - } else { - // Set pixels to fully transparent - *dptr++ = 0; - pptr++; - *dptr++ = 0; - pptr++; - *dptr++ = 0; - pptr++; - *dptr++ = 0; - pptr++; - - *dmptr++ = 255; - *dmptr++ = 255; - *dmptr++ = 255; - *dmptr++ = 255; - } - } - } - - // There is no more need for the RGB surface - SDL_FreeSurface(icon_rgb); - - hps = WinGetPS(_this->hidden->hwndClient); - - bmi.cbFix = sizeof(BITMAPINFOHEADER); - bmi.cx = w; - bmi.cy = 2 * h; - bmi.cPlanes = 1; - bmi.cBitCount = 32; - - SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); - bmih.cbFix = sizeof(BITMAPINFOHEADER); - bmih.cx = w; - bmih.cy = 2 * h; - bmih.cPlanes = 1; - bmih.cBitCount = 32; - - hbm = - GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) & bmih, CBM_INIT, - (PBYTE) pchTemp, (PBITMAPINFO2) & bmi); - hptrIcon = WinCreatePointer(HWND_DESKTOP, hbm, FALSE, 0, 0); - - WinReleasePS(hps); - - // Free pixel array - SDL_free(pchTemp); - - // Change icon in frame window - WinSendMsg(hwndFrame, WM_SETICON, (MPARAM) hptrIcon, NULL); - - /* - // Change icon in switchlist - // Seems like it's not needed, the WM_SETICON already does it. - { - PID pidFrame; - HSWITCH hswitchFrame; - SWCNTRL swctl; - - WinQueryWindowProcess(hwndFrame, &pidFrame, NULL); - hswitchFrame = WinQuerySwitchHandle(hwndFrame, pidFrame); - WinQuerySwitchEntry(hswitchFrame, &swctl); - - swctl.hwndIcon = hptrIcon; - - WinChangeSwitchEntry(hswitchFrame, &swctl); - } - */ - - // Store icon handle in global variable - hptrCurrentIcon = hptrIcon; -} - -// ------------------------ REAL FUNCTIONS ----------------- - - -static void -os2fslib_SetCursorManagementFunctions(_THIS, int iForWindowedMode) -{ - if (iForWindowedMode) { - _this->FreeWMCursor = os2fslib_FreeWMCursor; - _this->CreateWMCursor = os2fslib_CreateWMCursor_Win; - _this->ShowWMCursor = os2fslib_ShowWMCursor; - _this->WarpWMCursor = os2fslib_WarpWMCursor; - _this->MoveWMCursor = os2fslib_MoveWMCursor; - _this->CheckMouseMode = NULL; //os2fslib_CheckMouseMode; - } else { - // We'll have software mouse cursor in FS mode! - _this->FreeWMCursor = os2fslib_FreeWMCursor; - _this->CreateWMCursor = os2fslib_CreateWMCursor_FS; - _this->ShowWMCursor = os2fslib_ShowWMCursor; - _this->WarpWMCursor = os2fslib_WarpWMCursor; - _this->MoveWMCursor = os2fslib_MoveWMCursor; - _this->CheckMouseMode = NULL; //os2fslib_CheckMouseMode; - } -} - -static void -os2fslib_InitOSKeymap(_THIS) -{ - int i; - - iShiftIsPressed = 0; - - /* Map the VK and CH keysyms */ - for (i = 0; i <= 255; ++i) - HWScanKeyMap[i] = SDLK_UNKNOWN; - - // First line of keyboard: - HWScanKeyMap[0x1] = SDLK_ESCAPE; - HWScanKeyMap[0x3b] = SDLK_F1; - HWScanKeyMap[0x3c] = SDLK_F2; - HWScanKeyMap[0x3d] = SDLK_F3; - HWScanKeyMap[0x3e] = SDLK_F4; - HWScanKeyMap[0x3f] = SDLK_F5; - HWScanKeyMap[0x40] = SDLK_F6; - HWScanKeyMap[0x41] = SDLK_F7; - HWScanKeyMap[0x42] = SDLK_F8; - HWScanKeyMap[0x43] = SDLK_F9; - HWScanKeyMap[0x44] = SDLK_F10; - HWScanKeyMap[0x57] = SDLK_F11; - HWScanKeyMap[0x58] = SDLK_F12; - HWScanKeyMap[0x5d] = SDLK_PRINT; - HWScanKeyMap[0x46] = SDLK_SCROLLOCK; - HWScanKeyMap[0x5f] = SDLK_PAUSE; - - // Second line of keyboard: - HWScanKeyMap[0x29] = SDLK_BACKQUOTE; - HWScanKeyMap[0x2] = SDLK_1; - HWScanKeyMap[0x3] = SDLK_2; - HWScanKeyMap[0x4] = SDLK_3; - HWScanKeyMap[0x5] = SDLK_4; - HWScanKeyMap[0x6] = SDLK_5; - HWScanKeyMap[0x7] = SDLK_6; - HWScanKeyMap[0x8] = SDLK_7; - HWScanKeyMap[0x9] = SDLK_8; - HWScanKeyMap[0xa] = SDLK_9; - HWScanKeyMap[0xb] = SDLK_0; - HWScanKeyMap[0xc] = SDLK_MINUS; - HWScanKeyMap[0xd] = SDLK_EQUALS; - HWScanKeyMap[0xe] = SDLK_BACKSPACE; - HWScanKeyMap[0x68] = SDLK_INSERT; - HWScanKeyMap[0x60] = SDLK_HOME; - HWScanKeyMap[0x62] = SDLK_PAGEUP; - HWScanKeyMap[0x45] = SDLK_NUMLOCK; - HWScanKeyMap[0x5c] = SDLK_KP_DIVIDE; - HWScanKeyMap[0x37] = SDLK_KP_MULTIPLY; - HWScanKeyMap[0x4a] = SDLK_KP_MINUS; - - // Third line of keyboard: - HWScanKeyMap[0xf] = SDLK_TAB; - HWScanKeyMap[0x10] = SDLK_q; - HWScanKeyMap[0x11] = SDLK_w; - HWScanKeyMap[0x12] = SDLK_e; - HWScanKeyMap[0x13] = SDLK_r; - HWScanKeyMap[0x14] = SDLK_t; - HWScanKeyMap[0x15] = SDLK_y; - HWScanKeyMap[0x16] = SDLK_u; - HWScanKeyMap[0x17] = SDLK_i; - HWScanKeyMap[0x18] = SDLK_o; - HWScanKeyMap[0x19] = SDLK_p; - HWScanKeyMap[0x1a] = SDLK_LEFTBRACKET; - HWScanKeyMap[0x1b] = SDLK_RIGHTBRACKET; - HWScanKeyMap[0x1c] = SDLK_RETURN; - HWScanKeyMap[0x69] = SDLK_DELETE; - HWScanKeyMap[0x65] = SDLK_END; - HWScanKeyMap[0x67] = SDLK_PAGEDOWN; - HWScanKeyMap[0x47] = SDLK_KP7; - HWScanKeyMap[0x48] = SDLK_KP8; - HWScanKeyMap[0x49] = SDLK_KP9; - HWScanKeyMap[0x4e] = SDLK_KP_PLUS; - - // Fourth line of keyboard: - HWScanKeyMap[0x3a] = SDLK_CAPSLOCK; - HWScanKeyMap[0x1e] = SDLK_a; - HWScanKeyMap[0x1f] = SDLK_s; - HWScanKeyMap[0x20] = SDLK_d; - HWScanKeyMap[0x21] = SDLK_f; - HWScanKeyMap[0x22] = SDLK_g; - HWScanKeyMap[0x23] = SDLK_h; - HWScanKeyMap[0x24] = SDLK_j; - HWScanKeyMap[0x25] = SDLK_k; - HWScanKeyMap[0x26] = SDLK_l; - HWScanKeyMap[0x27] = SDLK_SEMICOLON; - HWScanKeyMap[0x28] = SDLK_QUOTE; - HWScanKeyMap[0x2b] = SDLK_BACKSLASH; - HWScanKeyMap[0x4b] = SDLK_KP4; - HWScanKeyMap[0x4c] = SDLK_KP5; - HWScanKeyMap[0x4d] = SDLK_KP6; - - // Fifth line of keyboard: - HWScanKeyMap[0x2a] = SDLK_LSHIFT; - HWScanKeyMap[0x56] = SDLK_WORLD_1; // Code 161, letter i' on hungarian keyboard - HWScanKeyMap[0x2c] = SDLK_z; - HWScanKeyMap[0x2d] = SDLK_x; - HWScanKeyMap[0x2e] = SDLK_c; - HWScanKeyMap[0x2f] = SDLK_v; - HWScanKeyMap[0x30] = SDLK_b; - HWScanKeyMap[0x31] = SDLK_n; - HWScanKeyMap[0x32] = SDLK_m; - HWScanKeyMap[0x33] = SDLK_COMMA; - HWScanKeyMap[0x34] = SDLK_PERIOD; - HWScanKeyMap[0x35] = SDLK_SLASH; - HWScanKeyMap[0x36] = SDLK_RSHIFT; - HWScanKeyMap[0x61] = SDLK_UP; - HWScanKeyMap[0x4f] = SDLK_KP1; - HWScanKeyMap[0x50] = SDLK_KP2; - HWScanKeyMap[0x51] = SDLK_KP3; - HWScanKeyMap[0x5a] = SDLK_KP_ENTER; - - // Sixth line of keyboard: - HWScanKeyMap[0x1d] = SDLK_LCTRL; - HWScanKeyMap[0x7e] = SDLK_LSUPER; // Windows key - HWScanKeyMap[0x38] = SDLK_LALT; - HWScanKeyMap[0x39] = SDLK_SPACE; - HWScanKeyMap[0x5e] = SDLK_RALT; // Actually, altgr on my keyboard... - HWScanKeyMap[0x7f] = SDLK_RSUPER; - HWScanKeyMap[0x7c] = SDLK_MENU; - HWScanKeyMap[0x5b] = SDLK_RCTRL; - HWScanKeyMap[0x63] = SDLK_LEFT; - HWScanKeyMap[0x66] = SDLK_DOWN; - HWScanKeyMap[0x64] = SDLK_RIGHT; - HWScanKeyMap[0x52] = SDLK_KP0; - HWScanKeyMap[0x53] = SDLK_KP_PERIOD; -} - - -/* Iconify the window. - This function returns 1 if there is a window manager and the - window was actually iconified, it returns 0 otherwise. - */ -int -os2fslib_IconifyWindow(_THIS) -{ - HAB hab; - HMQ hmq; - ERRORID hmqerror; - - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return 0; - - // Cannot do anything in fullscreen mode! - if (FSLib_QueryFSMode(_this->hidden->hwndClient)) - return 0; - - // Make sure this thread is prepared for using the Presentation Manager! - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - // Remember if there was an error at WinCreateMsgQueue(), because we don't - // want to destroy somebody else's queue later. :) - hmqerror = WinGetLastError(hab); - - WinSetWindowPos(_this->hidden->hwndFrame, HWND_TOP, - 0, 0, 0, 0, SWP_MINIMIZE); - - // Now destroy the message queue, if we've created it! - if (ERRORIDERROR(hmqerror) == 0) - WinDestroyMsgQueue(hmq); - - return 1; -} - -static SDL_GrabMode -os2fslib_GrabInput(_THIS, SDL_GrabMode mode) -{ - HAB hab; - HMQ hmq; - ERRORID hmqerror; - - - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return SDL_GRAB_OFF; - - // Make sure this thread is prepared for using the Presentation Manager! - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - // Remember if there was an error at WinCreateMsgQueue(), because we don't - // want to destroy somebody else's queue later. :) - hmqerror = WinGetLastError(hab); - - - if (mode == SDL_GRAB_OFF) { -#ifdef DEBUG_BUILD - printf("[os2fslib_GrabInput] : Releasing mouse\n"); - fflush(stdout); -#endif - - // Release the mouse - bMouseCapturable = 0; - if (bMouseCaptured) { - WinSetCapture(HWND_DESKTOP, NULLHANDLE); - bMouseCaptured = 0; - } - } else { -#ifdef DEBUG_BUILD - printf("[os2fslib_GrabInput] : Capturing mouse\n"); - fflush(stdout); -#endif - - // Capture the mouse - bMouseCapturable = 1; - if (WinQueryFocus(HWND_DESKTOP) == _this->hidden->hwndClient) { - WinSetCapture(HWND_DESKTOP, _this->hidden->hwndClient); - bMouseCaptured = 1; - { - SWP swpClient; - POINTL ptl; - // Center the mouse to the middle of the window! - WinQueryWindowPos(_this->hidden->hwndClient, &swpClient); - ptl.x = 0; - ptl.y = 0; - WinMapWindowPoints(_this->hidden->hwndClient, - HWND_DESKTOP, &ptl, 1); - _this->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ - WinSetPointerPos(HWND_DESKTOP, - ptl.x + swpClient.cx / 2, - ptl.y + swpClient.cy / 2); - } - } - } - - // Now destroy the message queue, if we've created it! - if (ERRORIDERROR(hmqerror) == 0) - WinDestroyMsgQueue(hmq); - - return mode; -} - -/* Set the title and icon text */ -static void -os2fslib_SetCaption(_THIS, const char *title, const char *icon) -{ - HAB hab; - HMQ hmq; - ERRORID hmqerror; - - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return; - - // Make sure this thread is prepared for using the Presentation Manager! - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - // Remember if there was an error at WinCreateMsgQueue(), because we don't - // want to destroy somebody else's queue later. :) - hmqerror = WinGetLastError(hab); - - WinSetWindowText(_this->hidden->hwndFrame, (char *) title); - - // Now destroy the message queue, if we've created it! - if (ERRORIDERROR(hmqerror) == 0) - WinDestroyMsgQueue(hmq); -} - -static int -os2fslib_ToggleFullScreen(_THIS, int on) -{ -#ifdef DEBUG_BUILD - printf("[os2fslib_ToggleFullScreen] : %d\n", on); - fflush(stdout); -#endif - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return 0; - - FSLib_ToggleFSMode(_this->hidden->hwndClient, on); - /* Cursor manager functions to Windowed/FS mode */ - os2fslib_SetCursorManagementFunctions(_this, !on); - return 1; -} - -/* This is called after the video mode has been set, to get the - initial mouse state. It should queue events as necessary to - properly represent the current mouse focus and position. - */ -static void -os2fslib_UpdateMouse(_THIS) -{ - POINTL ptl; - HAB hab; - HMQ hmq; - ERRORID hmqerror; - SWP swpClient; - - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return; - - - // Make sure this thread is prepared for using the Presentation Manager! - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - // Remember if there was an error at WinCreateMsgQueue(), because we don't - // want to destroy somebody else's queue later. :) - hmqerror = WinGetLastError(hab); - - - - if (_this->hidden->fInFocus) { - // If our app is in focus - SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); - SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); - SDL_PrivateAppActive(1, SDL_APPACTIVE); - WinQueryPointerPos(HWND_DESKTOP, &ptl); - WinMapWindowPoints(HWND_DESKTOP, _this->hidden->hwndClient, &ptl, 1); - WinQueryWindowPos(_this->hidden->hwndClient, &swpClient); - // Convert OS/2 mouse position to SDL position, and also scale it! - ptl.x = - ptl.x * _this->hidden->SrcBufferDesc.uiXResolution / swpClient.cx; - ptl.y = - ptl.y * _this->hidden->SrcBufferDesc.uiYResolution / swpClient.cy; - ptl.y = _this->hidden->SrcBufferDesc.uiYResolution - ptl.y - 1; - SDL_PrivateMouseMotion(0, 0, (Sint16) (ptl.x), (Sint16) (ptl.y)); - } else { - // If we're not in focus - SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); - SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); - SDL_PrivateAppActive(0, SDL_APPACTIVE); - SDL_PrivateMouseMotion(0, 0, (Sint16) - 1, (Sint16) - 1); - } - - // Now destroy the message queue, if we've created it! - if (ERRORIDERROR(hmqerror) == 0) - WinDestroyMsgQueue(hmq); - -} - -/* This pointer should exist in the native video subsystem and should - point to an appropriate update function for the current video mode - */ -static void -os2fslib_UpdateRects(_THIS, int numrects, SDL_Rect * rects) -{ - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return; - -#ifdef BITBLT_IN_WINMESSAGEPROC - WinSendMsg(_this->hidden->hwndClient, - WM_UPDATERECTSREQUEST, (MPARAM) numrects, (MPARAM) rects); -#else - if (DosRequestMutexSem - (_this->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT) == NO_ERROR) { - int i; - - if (_this->hidden->pSDLSurface) { -#ifndef RESIZE_EVEN_IF_RESIZABLE - SWP swp; - // But only blit if the window is not resizable, or if - // the window is resizable and the source buffer size is the - // same as the destination buffer size! - WinQueryWindowPos(_this->hidden->hwndClient, &swp); - if ((_this->hidden->pSDLSurface) && - (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) && - ((swp.cx != _this->hidden->SrcBufferDesc.uiXResolution) || - (swp.cy != _this->hidden->SrcBufferDesc.uiYResolution)) - && (!FSLib_QueryFSMode(_this->hidden->hwndClient))) { - // Resizable surface and in resizing! - // So, don't blit now! -#ifdef DEBUG_BUILD - printf("[UpdateRects] : Skipping blit while resizing!\n"); - fflush(stdout); -#endif - } else -#endif - { - /* - // Blit the whole window - FSLIB_BITBLT(_this->hidden->hwndClient, _this->hidden->pchSrcBuffer, - 0, 0, - _this->hidden->SrcBufferDesc.uiXResolution, - _this->hidden->SrcBufferDesc.uiYResolution); - */ -#ifdef DEBUG_BUILD - printf("[os2fslib_UpdateRects] : Blitting!\n"); - fflush(stdout); -#endif - - // Blit the changed areas - for (i = 0; i < numrects; i++) - FSLIB_BITBLT(_this->hidden->hwndClient, - _this->hidden->pchSrcBuffer, - rects[i].y, rects[i].x, rects[i].w, - rects[i].h); - } - } -#ifdef DEBUG_BUILD - else - printf("[os2fslib_UpdateRects] : No public surface!\n"); - fflush(stdout); -#endif - DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer); - } -#ifdef DEBUG_BUILD - else - printf("[os2fslib_UpdateRects] : Error in mutex!\n"); - fflush(stdout); -#endif -#endif -} - - -/* Reverse the effects VideoInit() -- called if VideoInit() fails - or if the application is shutting down the video subsystem. - */ -static void -os2fslib_VideoQuit(_THIS) -{ -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoQuit]\n"); - fflush(stdout); -#endif - // Close PM stuff if running! - if (_this->hidden->iPMThreadStatus == 1) { - int iTimeout; - WinPostMsg(_this->hidden->hwndFrame, WM_QUIT, (MPARAM) 0, (MPARAM) 0); - // HACK: We had this line before: - //DosWaitThread((TID *) &(_this->hidden->tidPMThread), DCWW_WAIT); - // We don't use it, because the PMThread will never stop, or if it stops, - // it will kill the whole process as a emergency fallback. - // So, we only check for the iPMThreadStatus stuff! -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoQuit] : Waiting for PM thread to die\n"); - fflush(stdout); -#endif - - iTimeout = 0; - while ((_this->hidden->iPMThreadStatus == 1) && (iTimeout < 100)) { - iTimeout++; - DosSleep(64); - } - -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoQuit] : End of wait.\n"); - fflush(stdout); -#endif - - if (_this->hidden->iPMThreadStatus == 1) { -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoQuit] : Killing PM thread!\n"); - fflush(stdout); -#endif - - _this->hidden->iPMThreadStatus = 0; - DosKillThread(_this->hidden->tidPMThread); - - if (_this->hidden->hwndFrame) { -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoQuit] : Destroying PM window!\n"); - fflush(stdout); -#endif - - WinDestroyWindow(_this->hidden->hwndFrame); - _this->hidden->hwndFrame = NULL; - } - } - - } - // Free result of an old ListModes() call, because there is - // no FreeListModes() call in SDL! - if (_this->hidden->pListModesResult) { - SDL_free(_this->hidden->pListModesResult); - _this->hidden->pListModesResult = NULL; - } - // Free list of available fullscreen modes - if (_this->hidden->pAvailableFSLibVideoModes) { - FSLib_FreeVideoModeList(_this->hidden->pAvailableFSLibVideoModes); - _this->hidden->pAvailableFSLibVideoModes = NULL; - } - // Free application icon if we had one - if (hptrCurrentIcon) { - WinDestroyPointer(hptrCurrentIcon); - hptrCurrentIcon = NULL; - } -} - -/* Set the requested video mode, returning a surface which will be - set to the SDL_VideoSurface. The width and height will already - be verified by ListModes(), and the video subsystem is free to - set the mode to a supported bit depth different from the one - specified -- the desired bpp will be emulated with a shadow - surface if necessary. If a new mode is returned, this function - should take care of cleaning up the current mode. - */ -static SDL_Surface * -os2fslib_SetVideoMode(_THIS, SDL_Surface * current, - int width, int height, int bpp, Uint32 flags) -{ - static int bFirstCall = 1; - FSLib_VideoMode_p pModeInfo, pModeInfoFound; - FSLib_VideoMode TempModeInfo; - HAB hab; - HMQ hmq; - ERRORID hmqerror; - RECTL rectl; - SDL_Surface *pResult; - - // If there is no more window, nothing we can do! - if (_this->hidden->iPMThreadStatus != 1) - return NULL; - -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Request for %dx%d @ %dBPP, flags=0x%x\n", - width, height, bpp, flags); - fflush(stdout); -#endif - - // We don't support palette modes! - if (bpp == 8) - bpp = 32; - - // Also, we don't support resizable modes in fullscreen mode. - if (flags & SDL_RESIZABLE) - flags &= ~SDL_FULLSCREEN; - - // No double buffered mode - if (flags & SDL_DOUBLEBUF) - flags &= ~SDL_DOUBLEBUF; - - // And, we don't support HWSURFACE yet. - if (flags & SDL_HWSURFACE) { - flags &= ~SDL_HWSURFACE; - flags |= SDL_SWSURFACE; - } -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Changed request to %dx%d @ %dBPP, flags=0x%x\n", - width, height, bpp, flags); - fflush(stdout); -#endif - - // First check if there is such a video mode they want! - pModeInfoFound = NULL; - - // For fullscreen mode we don't support every resolution! - // So, go through the video modes, and check for such a resolution! - pModeInfoFound = NULL; - pModeInfo = _this->hidden->pAvailableFSLibVideoModes; - - while (pModeInfo) { - // Check all available fullscreen modes for this resolution - if ((pModeInfo->uiXResolution == width) && (pModeInfo->uiYResolution == height) && (pModeInfo->uiBPP != 8)) // palettized modes not yet supported - { - // If good resolution, try to find the exact BPP, or at least - // something similar... - if (!pModeInfoFound) - pModeInfoFound = pModeInfo; - else if ((pModeInfoFound->uiBPP != bpp) && - (pModeInfoFound->uiBPP < pModeInfo->uiBPP)) - pModeInfoFound = pModeInfo; - } - pModeInfo = pModeInfo->pNext; - } - - // If we did not find a good fullscreen mode, then try a similar - if (!pModeInfoFound) { -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Requested video mode not found, looking for a similar one!\n"); - fflush(stdout); -#endif - // Go through the video modes again, and find a similar resolution! - pModeInfo = _this->hidden->pAvailableFSLibVideoModes; - while (pModeInfo) { - // Check all available fullscreen modes for this resolution - if ((pModeInfo->uiXResolution >= width) && - (pModeInfo->uiYResolution >= height) && - (pModeInfo->uiBPP == bpp)) { - if (!pModeInfoFound) - pModeInfoFound = pModeInfo; - else if (((pModeInfoFound->uiXResolution - - width) * (pModeInfoFound->uiYResolution - - height)) > - ((pModeInfo->uiXResolution - - width) * (pModeInfo->uiYResolution - height))) { - // Found a mode which is closer than the current one - pModeInfoFound = pModeInfo; - } - } - pModeInfo = pModeInfo->pNext; - } - } - // If we did not find a good fullscreen mode, then return NULL - if (!pModeInfoFound) { -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Requested video mode not found!\n"); - fflush(stdout); -#endif - return NULL; - } -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Found mode!\n"); - fflush(stdout); -#endif - - // We'll possibly adjust the structure, so copy out the values - // into TempModeInfo! - SDL_memcpy(&TempModeInfo, pModeInfoFound, sizeof(TempModeInfo)); - pModeInfoFound = &TempModeInfo; - - if (flags & SDL_RESIZABLE) { -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Requested mode is resizable, changing width/height\n"); - fflush(stdout); -#endif - // Change width and height to requested one! - TempModeInfo.uiXResolution = width; - TempModeInfo.uiYResolution = height; - TempModeInfo.uiScanLineSize = width * ((TempModeInfo.uiBPP + 7) / 8); - } - // We can try create new surface! - - // Make sure this thread is prepared for using the Presentation Manager! - hab = WinInitialize(0); - hmq = WinCreateMsgQueue(hab, 0); - // Remember if there was an error at WinCreateMsgQueue(), because we don't - // want to destroy somebody else's queue later. :) - hmqerror = WinGetLastError(hab); - - - - if (DosRequestMutexSem - (_this->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT) == NO_ERROR) { -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Creating new SW surface\n"); - fflush(stdout); -#endif - - // Create new software surface! - pResult = SDL_CreateRGBSurface(SDL_SWSURFACE, - pModeInfoFound->uiXResolution, - pModeInfoFound->uiYResolution, - pModeInfoFound->uiBPP, ((unsigned int) - pModeInfoFound-> - PixelFormat. - ucRedMask) - << pModeInfoFound->PixelFormat. - ucRedPosition, ((unsigned int) - pModeInfoFound-> - PixelFormat. - ucGreenMask) - << pModeInfoFound->PixelFormat. - ucGreenPosition, ((unsigned int) - pModeInfoFound-> - PixelFormat. - ucBlueMask) - << pModeInfoFound->PixelFormat. - ucBluePosition, ((unsigned int) - pModeInfoFound-> - PixelFormat. - ucAlphaMask) - << pModeInfoFound->PixelFormat. - ucAlphaPosition); - - if (pResult == NULL) { - DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer); - SDL_OutOfMemory(); - return NULL; - } -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Adjusting pixel format\n"); - fflush(stdout); -#endif - - // Adjust pixel format mask! - pResult->format->Rmask = - ((unsigned int) pModeInfoFound-> - PixelFormat.ucRedMask) << pModeInfoFound->PixelFormat. - ucRedPosition; - pResult->format->Rshift = pModeInfoFound->PixelFormat.ucRedPosition; - pResult->format->Rloss = pModeInfoFound->PixelFormat.ucRedAdjust; - pResult->format->Gmask = - ((unsigned int) pModeInfoFound-> - PixelFormat.ucGreenMask) << pModeInfoFound->PixelFormat. - ucGreenPosition; - pResult->format->Gshift = pModeInfoFound->PixelFormat.ucGreenPosition; - pResult->format->Gloss = pModeInfoFound->PixelFormat.ucGreenAdjust; - pResult->format->Bmask = - ((unsigned int) pModeInfoFound-> - PixelFormat.ucBlueMask) << pModeInfoFound->PixelFormat. - ucBluePosition; - pResult->format->Bshift = pModeInfoFound->PixelFormat.ucBluePosition; - pResult->format->Bloss = pModeInfoFound->PixelFormat.ucBlueAdjust; - pResult->format->Amask = - ((unsigned int) pModeInfoFound-> - PixelFormat.ucAlphaMask) << pModeInfoFound->PixelFormat. - ucAlphaPosition; - pResult->format->Ashift = pModeInfoFound->PixelFormat.ucAlphaPosition; - pResult->format->Aloss = pModeInfoFound->PixelFormat.ucAlphaAdjust; - -#ifdef REPORT_EMPTY_ALPHA_MASK - pResult->format->Amask = - pResult->format->Ashift = pResult->format->Aloss = 0; -#endif - - // Adjust surface flags - pResult->flags |= (flags & SDL_FULLSCREEN); - pResult->flags |= (flags & SDL_RESIZABLE); - - // It might be that the software surface pitch is not the same as - // the pitch we have, so adjust that! - pModeInfoFound->uiScanLineSize = pResult->pitch; - - // Store new source buffer parameters! - SDL_memcpy(&(_this->hidden->SrcBufferDesc), pModeInfoFound, - sizeof(*pModeInfoFound)); - _this->hidden->pchSrcBuffer = pResult->pixels; - -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Telling FSLib the stuffs\n"); - fflush(stdout); -#endif - - // Tell the FSLib window the new source image format - FSLib_SetSrcBufferDesc(_this->hidden->hwndClient, - &(_this->hidden->SrcBufferDesc)); - - if (((flags & SDL_RESIZABLE) == 0) || (bFirstCall)) { - bFirstCall = 0; -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Modifying window size\n"); - fflush(stdout); -#endif - - // Calculate frame window size from client window size - rectl.xLeft = 0; - rectl.yBottom = 0; - rectl.xRight = pModeInfoFound->uiXResolution; // Noninclusive - rectl.yTop = pModeInfoFound->uiYResolution; // Noninclusive - WinCalcFrameRect(_this->hidden->hwndFrame, &rectl, FALSE); - - // Set the new size of the main window - SetAccessableWindowPos(_this->hidden->hwndFrame, - HWND_TOP, - 0, 0, - (rectl.xRight - rectl.xLeft), - (rectl.yTop - rectl.yBottom), - SWP_SIZE | SWP_ACTIVATE | SWP_SHOW); - } - // Set fullscreen mode flag, and switch to fullscreen if needed! - if (flags & SDL_FULLSCREEN) { -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Also trying to switch to fullscreen\n"); - fflush(stdout); -#endif - FSLib_ToggleFSMode(_this->hidden->hwndClient, 1); - /* Cursor manager functions to FS mode */ - os2fslib_SetCursorManagementFunctions(_this, 0); - } else { -#ifdef DEBUG_BUILD - printf - ("[os2fslib_SetVideoMode] : Also trying to switch to desktop mode\n"); - fflush(stdout); -#endif - FSLib_ToggleFSMode(_this->hidden->hwndClient, 0); - /* Cursor manager functions to Windowed mode */ - os2fslib_SetCursorManagementFunctions(_this, 1); - } - - _this->hidden->pSDLSurface = pResult; - - DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer); - } else { -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Could not get hmtxUseSrcBuffer!\n"); - fflush(stdout); -#endif - - pResult = NULL; - } - - // As we have the new surface, we don't need the current one anymore! - if ((pResult) && (current)) { -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Freeing old surface\n"); - fflush(stdout); -#endif - SDL_FreeSurface(current); - } - // Redraw window - WinInvalidateRegion(_this->hidden->hwndClient, NULL, TRUE); - - // Now destroy the message queue, if we've created it! - if (ERRORIDERROR(hmqerror) == 0) { -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Destroying message queue\n"); - fflush(stdout); -#endif - WinDestroyMsgQueue(hmq); - } -#ifdef DEBUG_BUILD - printf("[os2fslib_SetVideoMode] : Done\n"); - fflush(stdout); -#endif - - /* We're done */ - - // Return with the new surface! - return pResult; -} - -/* List the available video modes for the given pixel format, sorted - from largest to smallest. - */ -static SDL_Rect ** -os2fslib_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags) -{ -#ifdef DEBUG_BUILD - printf("[os2fslib_ListModes] : ListModes of %d Bpp\n", - format->BitsPerPixel); -#endif - // Destroy result of previous call, if there is any - if (_this->hidden->pListModesResult) { - SDL_free(_this->hidden->pListModesResult); - _this->hidden->pListModesResult = NULL; - } - // For resizable and windowed mode we support every resolution! - if ((flags & SDL_RESIZABLE) && ((flags & SDL_FULLSCREEN) == 0)) - return (SDL_Rect **) - 1; - - // Check if they need fullscreen or non-fullscreen video modes! - if ((flags & SDL_FULLSCREEN) == 0) { - // For windowed mode we support every resolution! - return (SDL_Rect **) - 1; - } else { - FSLib_VideoMode_p pFSMode; - // For fullscreen mode we don't support every resolution! - // Now create a new list - pFSMode = _this->hidden->pAvailableFSLibVideoModes; - while (pFSMode) { - if (pFSMode->uiBPP == format->BitsPerPixel) { - SDL_Rect *pRect = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect)); - if (pRect) { - // Fill description - pRect->x = 0; - pRect->y = 0; - pRect->w = pFSMode->uiXResolution; - pRect->h = pFSMode->uiYResolution; -#ifdef DEBUG_BUILD -// printf("!!! Seems to be good!\n"); -// printf("F: %dx%d\n", pRect->w, pRect->h); -#endif - // And insert into list of pRects - if (!(_this->hidden->pListModesResult)) { -#ifdef DEBUG_BUILD -// printf("!!! Inserting to beginning\n"); -#endif - - // We're the first one to be inserted! - _this->hidden->pListModesResult = - (SDL_Rect **) SDL_malloc(2 * sizeof(SDL_Rect *)); - if (_this->hidden->pListModesResult) { - _this->hidden->pListModesResult[0] = pRect; - _this->hidden->pListModesResult[1] = NULL; - } else { - SDL_free(pRect); - } - } else { - // We're not the first ones, so find the place where we - // have to insert ourselves - SDL_Rect **pNewList; - int iPlace, iNumOfSlots, i; - -#ifdef DEBUG_BUILD -// printf("!!! Searching where to insert\n"); -#endif - - iPlace = -1; - iNumOfSlots = 1; // Count the last NULL too! - for (i = 0; _this->hidden->pListModesResult[i]; i++) { - iNumOfSlots++; - if (iPlace == -1) { - if ((_this->hidden->pListModesResult[i]->w * - _this->hidden->pListModesResult[i]->h) < - (pRect->w * pRect->h)) { - iPlace = i; - } - } - } - if (iPlace == -1) - iPlace = iNumOfSlots - 1; - -#ifdef DEBUG_BUILD -// printf("!!! From %d slots, it will be at %d\n", iNumOfSlots, iPlace); -#endif - - pNewList = (SDL_Rect **) - SDL_realloc(_this->hidden->pListModesResult, - (iNumOfSlots + - 1) * sizeof(SDL_Rect *)); - if (pNewList) { - for (i = iNumOfSlots; i > iPlace; i--) - pNewList[i] = pNewList[i - 1]; - pNewList[iPlace] = pRect; - _this->hidden->pListModesResult = pNewList; - } else { - SDL_free(pRect); - } - } - } - } - pFSMode = pFSMode->pNext; - } - } -#ifdef DEBUG_BUILD -// printf("Returning list\n"); -#endif - return _this->hidden->pListModesResult; -} - -/* Initialize the native video subsystem, filling 'vformat' with the - "best" display pixel format, returning 0 or -1 if there's an error. - */ -static int -os2fslib_VideoInit(_THIS, SDL_PixelFormat * vformat) -{ - FSLib_VideoMode_p pDesktopMode; - -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoInit] : Enter\n"); - fflush(stdout); -#endif - - // Report the best pixel format. For this, - // we'll use the current desktop format. - pDesktopMode = FSLib_GetDesktopVideoMode(); - if (!pDesktopMode) { - SDL_SetError("Could not query desktop video mode!"); -#ifdef DEBUG_BUILD - printf - ("[os2fslib_VideoInit] : Could not query desktop video mode!\n"); -#endif - return -1; - } - - /* Determine the current screen size */ - _this->info.current_w = pDesktopMode->uiXResolution; - _this->info.current_h = pDesktopMode->uiYResolution; - - /* Determine the screen depth */ - vformat->BitsPerPixel = pDesktopMode->uiBPP; - vformat->BytesPerPixel = (vformat->BitsPerPixel + 7) / 8; - - vformat->Rmask = - ((unsigned int) pDesktopMode->PixelFormat. - ucRedMask) << pDesktopMode->PixelFormat.ucRedPosition; - vformat->Rshift = pDesktopMode->PixelFormat.ucRedPosition; - vformat->Rloss = pDesktopMode->PixelFormat.ucRedAdjust; - vformat->Gmask = - ((unsigned int) pDesktopMode-> - PixelFormat.ucGreenMask) << pDesktopMode->PixelFormat. - ucGreenPosition; - vformat->Gshift = pDesktopMode->PixelFormat.ucGreenPosition; - vformat->Gloss = pDesktopMode->PixelFormat.ucGreenAdjust; - vformat->Bmask = - ((unsigned int) pDesktopMode-> - PixelFormat.ucBlueMask) << pDesktopMode->PixelFormat.ucBluePosition; - vformat->Bshift = pDesktopMode->PixelFormat.ucBluePosition; - vformat->Bloss = pDesktopMode->PixelFormat.ucBlueAdjust; - vformat->Amask = - ((unsigned int) pDesktopMode-> - PixelFormat.ucAlphaMask) << pDesktopMode->PixelFormat. - ucAlphaPosition; - vformat->Ashift = pDesktopMode->PixelFormat.ucAlphaPosition; - vformat->Aloss = pDesktopMode->PixelFormat.ucAlphaAdjust; - -#ifdef REPORT_EMPTY_ALPHA_MASK - vformat->Amask = vformat->Ashift = vformat->Aloss = 0; -#endif - - // Fill in some window manager capabilities - _this->info.wm_available = 1; - - // Initialize some internal variables - _this->hidden->pListModesResult = NULL; - _this->hidden->fInFocus = 0; - _this->hidden->iSkipWMMOUSEMOVE = 0; - _this->hidden->iMouseVisible = 1; - - if (getenv("SDL_USE_PROPORTIONAL_WINDOW")) - _this->hidden->bProportionalResize = 1; - else { - PPIB pib; - PTIB tib; - char *pchFileName, *pchTemp; - char achConfigFile[CCHMAXPATH]; - FILE *hFile; - - /* No environment variable to have proportional window. - * Ok, let's check if this executable is in config file! - */ - _this->hidden->bProportionalResize = 0; - - DosGetInfoBlocks(&tib, &pib); - pchTemp = pchFileName = pib->pib_pchcmd; - while (*pchTemp) { - if (*pchTemp == '\\') - pchFileName = pchTemp + 1; - pchTemp++; - } - if (getenv("HOME")) { - sprintf(achConfigFile, "%s\\.sdl.proportionals", getenv("HOME")); - hFile = fopen(achConfigFile, "rt"); - if (!hFile) { - /* Seems like the file cannot be opened or does not exist. - * Let's try to create it with defaults! - */ - hFile = fopen(achConfigFile, "wt"); - if (hFile) { - fprintf(hFile, - "; This file is a config file of SDL/2, containing\n"); - fprintf(hFile, - "; the list of executables that must have proportional\n"); - fprintf(hFile, "; windows.\n"); - fprintf(hFile, ";\n"); - fprintf(hFile, - "; You can add executable filenames into this file,\n"); - fprintf(hFile, - "; one under the other. If SDL finds that a given\n"); - fprintf(hFile, - "; program is in this list, then that application\n"); - fprintf(hFile, - "; will have proportional windows, just like if\n"); - fprintf(hFile, - "; the SET SDL_USE_PROPORTIONAL_WINDOW env. variable\n"); - fprintf(hFile, - "; would have been set for that process.\n"); - fprintf(hFile, ";\n"); - fprintf(hFile, "\n"); - fprintf(hFile, "dosbox.exe\n"); - fclose(hFile); - } - - hFile = fopen(achConfigFile, "rt"); - } - - if (hFile) { - while (fgets(achConfigFile, sizeof(achConfigFile), hFile)) { - /* Cut \n from end of string */ - - while (achConfigFile[strlen(achConfigFile) - 1] - == '\n') - achConfigFile[strlen(achConfigFile) - 1] = 0; - - /* Compare... */ - if (stricmp(achConfigFile, pchFileName) == 0) { - /* Found it in config file! */ - _this->hidden->bProportionalResize = 1; - break; - } - } - fclose(hFile); - } - } - } - - DosCreateMutexSem(NULL, &(_this->hidden->hmtxUseSrcBuffer), 0, FALSE); - - // Now create our window with a default size - - // For this, we select the first available fullscreen mode as - // current window size! - SDL_memcpy(&(_this->hidden->SrcBufferDesc), - _this->hidden->pAvailableFSLibVideoModes, - sizeof(_this->hidden->SrcBufferDesc)); - // Allocate new video buffer! - _this->hidden->pchSrcBuffer = - (char *) SDL_malloc(_this->hidden-> - pAvailableFSLibVideoModes->uiScanLineSize * - _this->hidden-> - pAvailableFSLibVideoModes->uiYResolution); - if (!_this->hidden->pchSrcBuffer) { -#ifdef DEBUG_BUILD - printf - ("[os2fslib_VideoInit] : Yikes, not enough memory for new video buffer!\n"); - fflush(stdout); -#endif - SDL_SetError("Not enough memory for new video buffer!\n"); - return -1; - } - // For this, we need a message processing thread. - // We'll create a new thread for this, which will do everything - // what is related to PM - _this->hidden->iPMThreadStatus = 0; - _this->hidden->tidPMThread = - _beginthread(PMThreadFunc, NULL, 65536, (void *) _this); - if (_this->hidden->tidPMThread <= 0) { -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoInit] : Could not create PM thread!\n"); -#endif - SDL_SetError("Could not create PM thread"); - return -1; - } -#ifdef USE_DOSSETPRIORITY - // Burst the priority of PM Thread! - DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, - _this->hidden->tidPMThread); -#endif - // Wait for the PM thread to initialize! - while (_this->hidden->iPMThreadStatus == 0) - DosSleep(32); - // If the PM thread could not set up everything, then - // report an error! - if (_this->hidden->iPMThreadStatus != 1) { -#ifdef DEBUG_BUILD - printf("[os2fslib_VideoInit] : PMThread reported an error : %d\n", - _this->hidden->iPMThreadStatus); -#endif - SDL_SetError("Error initializing PM thread"); - return -1; - } - - return 0; -} - - -static void -os2fslib_DeleteDevice(_THIS) -{ -#ifdef DEBUG_BUILD - printf("[os2fslib_DeleteDevice]\n"); - fflush(stdout); -#endif - // Free used memory - FSLib_FreeVideoModeList(_this->hidden->pAvailableFSLibVideoModes); - if (_this->hidden->pListModesResult) - SDL_free(_this->hidden->pListModesResult); - if (_this->hidden->pchSrcBuffer) - SDL_free(_this->hidden->pchSrcBuffer); - DosCloseMutexSem(_this->hidden->hmtxUseSrcBuffer); - SDL_free(_this->hidden); - SDL_free(_this); - FSLib_Uninitialize(); -} - -static int -os2fslib_Available(void) -{ - - // If we can run, it means that we could load FSLib, - // so we assume that it's available then! - return 1; -} - -static void -os2fslib_MorphToPM() -{ - PPIB pib; - PTIB tib; - - DosGetInfoBlocks(&tib, &pib); - - // Change flag from VIO to PM: - if (pib->pib_ultype == 2) - pib->pib_ultype = 3; -} - -static SDL_VideoDevice * -os2fslib_CreateDevice(int devindex) -{ - SDL_VideoDevice *device; - -#ifdef DEBUG_BUILD - printf("[os2fslib_CreateDevice] : Enter\n"); - fflush(stdout); -#endif - - /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice)); - if (device) { - SDL_memset(device, 0, (sizeof *device)); - // Also allocate memory for private data - device->hidden = (struct SDL_PrivateVideoData *) - SDL_malloc((sizeof(struct SDL_PrivateVideoData))); - } - if ((device == NULL) || (device->hidden == NULL)) { - SDL_OutOfMemory(); - if (device) - SDL_free(device); - return NULL; - } - SDL_memset(device->hidden, 0, (sizeof *device->hidden)); - - /* Set the function pointers */ -#ifdef DEBUG_BUILD - printf("[os2fslib_CreateDevice] : VideoInit is %p\n", os2fslib_VideoInit); - fflush(stdout); -#endif - - /* Initialization/Query functions */ - device->VideoInit = os2fslib_VideoInit; - device->ListModes = os2fslib_ListModes; - device->SetVideoMode = os2fslib_SetVideoMode; - device->ToggleFullScreen = os2fslib_ToggleFullScreen; - device->UpdateMouse = os2fslib_UpdateMouse; - device->CreateYUVOverlay = NULL; - device->SetColors = os2fslib_SetColors; - device->UpdateRects = os2fslib_UpdateRects; - device->VideoQuit = os2fslib_VideoQuit; - /* Hardware acceleration functions */ - device->AllocHWSurface = os2fslib_AllocHWSurface; - device->CheckHWBlit = NULL; - device->FillHWRect = NULL; - device->SetHWColorKey = NULL; - device->SetHWAlpha = NULL; - device->LockHWSurface = os2fslib_LockHWSurface; - device->UnlockHWSurface = os2fslib_UnlockHWSurface; - device->FlipHWSurface = NULL; - device->FreeHWSurface = os2fslib_FreeHWSurface; - /* Window manager functions */ - device->SetCaption = os2fslib_SetCaption; - device->SetIcon = os2fslib_SetIcon; - device->IconifyWindow = os2fslib_IconifyWindow; - device->GrabInput = os2fslib_GrabInput; - device->GetWMInfo = NULL; - /* Cursor manager functions to Windowed mode */ - os2fslib_SetCursorManagementFunctions(device, 1); - /* Event manager functions */ - device->InitOSKeymap = os2fslib_InitOSKeymap; - device->PumpEvents = os2fslib_PumpEvents; - /* The function used to dispose of this structure */ - device->free = os2fslib_DeleteDevice; - - // Make sure we'll be able to use Win* API even if the application - // was linked to be a VIO application! - os2fslib_MorphToPM(); - - // Now initialize FSLib, and query available video modes! - if (!FSLib_Initialize()) { - // Could not initialize FSLib! -#ifdef DEBUG_BUILD - printf("[os2fslib_CreateDevice] : Could not initialize FSLib!\n"); -#endif - SDL_SetError("Could not initialize FSLib!"); - SDL_free(device->hidden); - SDL_free(device); - return NULL; - } - device->hidden->pAvailableFSLibVideoModes = FSLib_GetVideoModeList(); - - return device; -} - -VideoBootStrap OS2FSLib_bootstrap = { - "os2fslib", "OS/2 Video Output using FSLib", - os2fslib_Available, os2fslib_CreateDevice -}; - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/os2fslib/SDL_os2fslib.h Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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@libsdl.org -*/ -#include "SDL_config.h" - -#ifndef _SDL_os2fslib_h -#define _SDL_os2fslib_h - - -// OS2 specific includes -#define INCL_TYPES -#define INCL_DOS -#define INCL_DOSERRORS -#define INCL_DOSPROCESS -#define INCL_WIN -#define INCL_GPI -#include <os2.h> - -#include <FSLib.h> - -/* Hidden "this" pointer for the video functions */ -#define _THIS SDL_VideoDevice *_this - -/* Private display data */ -struct SDL_PrivateVideoData -{ - FSLib_VideoMode_p pAvailableFSLibVideoModes; - SDL_Rect **pListModesResult; // Allocated memory to return list of modes for os2fslib_ListModes() API - - FSLib_VideoMode SrcBufferDesc; // Description of current source image buffer - char *pchSrcBuffer; // The source image buffer itself - SDL_Surface *pSDLSurface; // The SDL surface describing the buffer - HMTX hmtxUseSrcBuffer; // Mutex semaphore to manipulate src buffer - HWND hwndFrame, hwndClient; // Window handle of frame and client - int iPMThreadStatus; // 0: Not running - // 1: Running - // Other: Not running, had an error - int tidPMThread; // Thread ID of PM Thread - int fInFocus; // True if we're in focus! - int iSkipWMMOUSEMOVE; // Number of WM_MOUSEMOVE messages to skip! - int iMouseVisible; // - - PFNWP pfnOldFrameProc; // Old window frame procedure - int bProportionalResize; // 0: No proportional resizing - // 1: Do proportional resizing - ULONG ulResizingFlag; // First resizing flag value -}; - -/* OS/2 specific backdoor function to be able to set FrameControlFlags of */ -/* the SDL window before creating it. */ -extern DECLSPEC void SDLCALL SDL_OS2FSLIB_SetFCFToUse(ULONG ulFCF); - -#endif /* _SDL_os2fslib_h */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/os2fslib/SDL_vkeys.h Sat Sep 19 06:24:07 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 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 -*/ - -#ifndef VK_0 -#define VK_0 '0' -#define VK_1 '1' -#define VK_2 '2' -#define VK_3 '3' -#define VK_4 '4' -#define VK_5 '5' -#define VK_6 '6' -#define VK_7 '7' -#define VK_8 '8' -#define VK_9 '9' -#define VK_A 'A' -#define VK_B 'B' -#define VK_C 'C' -#define VK_D 'D' -#define VK_E 'E' -#define VK_F 'F' -#define VK_G 'G' -#define VK_H 'H' -#define VK_I 'I' -#define VK_J 'J' -#define VK_K 'K' -#define VK_L 'L' -#define VK_M 'M' -#define VK_N 'N' -#define VK_O 'O' -#define VK_P 'P' -#define VK_Q 'Q' -#define VK_R 'R' -#define VK_S 'S' -#define VK_T 'T' -#define VK_U 'U' -#define VK_V 'V' -#define VK_W 'W' -#define VK_X 'X' -#define VK_Y 'Y' -#define VK_Z 'Z' -#endif /* VK_0 */ - -/* These keys haven't been defined, but were experimentally determined */ -#define VK_SEMICOLON 0xBA -#define VK_EQUALS 0xBB -#define VK_COMMA 0xBC -#define VK_MINUS 0xBD -#define VK_PERIOD 0xBE -#define VK_SLASH 0xBF -#define VK_GRAVE 0xC0 -#define VK_LBRACKET 0xDB -#define VK_BACKSLASH 0xDC -#define VK_RBRACKET 0xDD -#define VK_APOSTROPHE 0xDE -#define VK_BACKTICK 0xDF -/* vi: set ts=4 sw=4 expandtab: */