From 1679c3e5ff70a0772b61170881ea41fb2817b99c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 19 Sep 2009 06:43:45 +0000 Subject: [PATCH] Removed outdated OS/2 support --- README | 2 +- README.OS2 | 278 --- Watcom-OS2.zip | Bin 63017 -> 0 bytes docs.html | 7 - include/SDL.h | 2 +- include/SDL_config.h.default | 2 - include/SDL_config.h.in | 6 - include/SDL_config_os2.h | 145 -- include/SDL_thread.h | 14 +- include/begin_code.h | 16 - src/SDL.c | 73 +- src/audio/dart/SDL_dart.c | 448 ---- src/audio/dart/SDL_dart.h | 66 - src/events/SDL_events.c | 18 - src/events/SDL_sysevents.h | 4 - src/joystick/os2/SDL_sysjoystick.c | 698 ------- src/joystick/os2/joyos2.h | 179 -- src/loadso/os2/SDL_sysloadso.c | 77 - src/power/SDL_power.c | 4 - src/power/os2/SDL_syspower.c | 135 -- src/thread/SDL_thread_c.h | 2 - src/thread/os2/SDL_syscond.c | 223 -- src/thread/os2/SDL_syscond_c.h | 23 - src/thread/os2/SDL_sysmutex.c | 107 - src/thread/os2/SDL_syssem.c | 194 -- src/thread/os2/SDL_systhread.c | 105 - src/thread/os2/SDL_systhread_c.h | 28 - src/timer/os2/SDL_systimer.c | 235 --- src/video/SDL_sysvideo.h | 3 - src/video/SDL_video.c | 3 - src/video/os2fslib/SDL_os2fslib.c | 3122 ---------------------------- src/video/os2fslib/SDL_os2fslib.h | 72 - src/video/os2fslib/SDL_vkeys.h | 75 - 33 files changed, 8 insertions(+), 6358 deletions(-) delete mode 100644 README.OS2 delete mode 100644 Watcom-OS2.zip delete mode 100644 include/SDL_config_os2.h delete mode 100644 src/audio/dart/SDL_dart.c delete mode 100644 src/audio/dart/SDL_dart.h delete mode 100644 src/joystick/os2/SDL_sysjoystick.c delete mode 100644 src/joystick/os2/joyos2.h delete mode 100644 src/loadso/os2/SDL_sysloadso.c delete mode 100644 src/power/os2/SDL_syspower.c delete mode 100644 src/thread/os2/SDL_syscond.c delete mode 100644 src/thread/os2/SDL_syscond_c.h delete mode 100644 src/thread/os2/SDL_sysmutex.c delete mode 100644 src/thread/os2/SDL_syssem.c delete mode 100644 src/thread/os2/SDL_systhread.c delete mode 100644 src/thread/os2/SDL_systhread_c.h delete mode 100644 src/timer/os2/SDL_systimer.c delete mode 100644 src/video/os2fslib/SDL_os2fslib.c delete mode 100644 src/video/os2fslib/SDL_os2fslib.h delete mode 100644 src/video/os2fslib/SDL_vkeys.h diff --git a/README b/README index ef9a76825..bc5570f93 100644 --- a/README +++ b/README @@ -15,7 +15,7 @@ and 2D framebuffer across multiple platforms. 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, diff --git a/README.OS2 b/README.OS2 deleted file mode 100644 index 5718c5fef..000000000 --- a/README.OS2 +++ /dev/null @@ -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. - - diff --git a/Watcom-OS2.zip b/Watcom-OS2.zip deleted file mode 100644 index 603210f4b5be271749d4188c5279495be0917c4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63017 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 Mac OS X Notes Icons set with SDL_WM_SetIcon() now have the proper colors on Intel Macs. -

OS/2 Notes

- -
-

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

- [separator] diff --git a/include/SDL.h b/include/SDL.h index afd9b77ca..8db1a1405 100644 --- a/include/SDL.h +++ b/include/SDL.h @@ -39,7 +39,7 @@ and 2D framebuffer across multiple platforms. 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, diff --git a/include/SDL_config.h.default b/include/SDL_config.h.default index d72d7e585..1966cb447 100644 --- a/include/SDL_config.h.default +++ b/include/SDL_config.h.default @@ -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 */ diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 8307c92da..4b3fb55e4 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -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 diff --git a/include/SDL_config_os2.h b/include/SDL_config_os2.h deleted file mode 100644 index c6f05f33e..000000000 --- a/include/SDL_config_os2.h +++ /dev/null @@ -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 */ diff --git a/include/SDL_thread.h b/include/SDL_thread.h index 1a8b13f2e..f0cd5bfee 100644 --- a/include/SDL_thread.h +++ b/include/SDL_thread.h @@ -48,9 +48,9 @@ struct SDL_Thread; typedef struct SDL_Thread SDL_Thread; /* Create a thread */ -#if (defined(__WIN32__) && !defined(HAVE_LIBC)) || defined(__OS2__) +#if defined(__WIN32__) && !defined(HAVE_LIBC) /* - 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 @@ typedef struct SDL_Thread SDL_Thread; #include /* 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 @@ SDL_CreateThread(int (SDLCALL * f) (void *), void *data, 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) diff --git a/include/begin_code.h b/include/begin_code.h index 33e8e5348..e3183ba64 100644 --- a/include/begin_code.h +++ b/include/begin_code.h @@ -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 */ diff --git a/src/SDL.c b/src/SDL.c index ae87fc96d..b06dbfb83 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -277,76 +277,7 @@ SDL_GetRevision(void) return SDL_REVISION; } -#if defined(__OS2__) -/* Building for OS/2 */ -#ifdef __WATCOMC__ - -#define INCL_DOSERRORS -#define INCL_DOSEXCEPTIONS -#include - -/* 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 @@ _DllMainCRTStartup(HANDLE hModule, } #endif /* building DLL with Watcom C */ -#endif /* OS/2 elif __WIN32__ */ +#endif /* __WIN32__ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/dart/SDL_dart.c b/src/audio/dart/SDL_dart.c deleted file mode 100644 index 9593aa00d..000000000 --- a/src/audio/dart/SDL_dart.c +++ /dev/null @@ -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: */ diff --git a/src/audio/dart/SDL_dart.h b/src/audio/dart/SDL_dart.h deleted file mode 100644 index 5ad79c750..000000000 --- a/src/audio/dart/SDL_dart.h +++ /dev/null @@ -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 -#include // 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: */ diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 4bc7e216a..088a3d33e 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -84,29 +84,11 @@ SDL_Unlock_EventThread(void) } } -#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 -#include -#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(); diff --git a/src/events/SDL_sysevents.h b/src/events/SDL_sysevents.h index 9941b1c44..97e26cd78 100644 --- a/src/events/SDL_sysevents.h +++ b/src/events/SDL_sysevents.h @@ -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: */ diff --git a/src/joystick/os2/SDL_sysjoystick.c b/src/joystick/os2/SDL_sysjoystick.c deleted file mode 100644 index bce4ab84d..000000000 --- a/src/joystick/os2/SDL_sysjoystick.c +++ /dev/null @@ -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 - -#define INCL_DOSDEVICES -#define INCL_DOSDEVIOCTL -#define INCL_DOSMEMMGR -#include -#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< 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: */ diff --git a/src/joystick/os2/joyos2.h b/src/joystick/os2/joyos2.h deleted file mode 100644 index 0ceace1bc..000000000 --- a/src/joystick/os2/joyos2.h +++ /dev/null @@ -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: */ diff --git a/src/loadso/os2/SDL_sysloadso.c b/src/loadso/os2/SDL_sysloadso.c deleted file mode 100644 index 2fe9b55cc..000000000 --- a/src/loadso/os2/SDL_sysloadso.c +++ /dev/null @@ -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 -#define INCL_DOSERRORS -#define INCL_DOSMODULEMGR -#include - -#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: */ diff --git a/src/power/SDL_power.c b/src/power/SDL_power.c index ed8ca73f5..9e7ea6f38 100644 --- a/src/power/SDL_power.c +++ b/src/power/SDL_power.c @@ -34,7 +34,6 @@ SDL_bool SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState *, int *, int *); 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 @@ static SDL_GetPowerInfo_Impl implementations[] = { #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 diff --git a/src/power/os2/SDL_syspower.c b/src/power/os2/SDL_syspower.c deleted file mode 100644 index 401f4c2c8..000000000 --- a/src/power/os2/SDL_syspower.c +++ /dev/null @@ -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 - -#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: */ diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index e895a3487..80bce186a 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -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 diff --git a/src/thread/os2/SDL_syscond.c b/src/thread/os2/SDL_syscond.c deleted file mode 100644 index a6e8c434a..000000000 --- a/src/thread/os2/SDL_syscond.c +++ /dev/null @@ -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: */ diff --git a/src/thread/os2/SDL_syscond_c.h b/src/thread/os2/SDL_syscond_c.h deleted file mode 100644 index 5ba245f12..000000000 --- a/src/thread/os2/SDL_syscond_c.h +++ /dev/null @@ -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: */ diff --git a/src/thread/os2/SDL_sysmutex.c b/src/thread/os2/SDL_sysmutex.c deleted file mode 100644 index 475537e83..000000000 --- a/src/thread/os2/SDL_sysmutex.c +++ /dev/null @@ -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 - -#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: */ diff --git a/src/thread/os2/SDL_syssem.c b/src/thread/os2/SDL_syssem.c deleted file mode 100644 index b6eb3e8b1..000000000 --- a/src/thread/os2/SDL_syssem.c +++ /dev/null @@ -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 - -#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: */ diff --git a/src/thread/os2/SDL_systhread.c b/src/thread/os2/SDL_systhread.c deleted file mode 100644 index 02e800dae..000000000 --- a/src/thread/os2/SDL_systhread.c +++ /dev/null @@ -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 -#define INCL_DOSERRORS -#define INCL_DOSPROCESS -#include - -#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: */ diff --git a/src/thread/os2/SDL_systhread_c.h b/src/thread/os2/SDL_systhread_c.h deleted file mode 100644 index c84acd244..000000000 --- a/src/thread/os2/SDL_systhread_c.h +++ /dev/null @@ -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 - -typedef TID SYS_ThreadHandle; -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/timer/os2/SDL_systimer.c b/src/timer/os2/SDL_systimer.c deleted file mode 100644 index 4a72104a8..000000000 --- a/src/timer/os2/SDL_systimer.c +++ /dev/null @@ -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 - -#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: */ diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 3d0ac7937..f828de709 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -395,9 +395,6 @@ extern VideoBootStrap DC_bootstrap; #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 diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 14e603d74..2f8ce810b 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -109,9 +109,6 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_RISCOS &RISCOS_bootstrap, #endif -#if SDL_VIDEO_DRIVER_OS2FS - &OS2FSLib_bootstrap, -#endif #if SDL_VIDEO_DRIVER_NDS &NDS_bootstrap, #endif diff --git a/src/video/os2fslib/SDL_os2fslib.c b/src/video/os2fslib/SDL_os2fslib.c deleted file mode 100644 index 9c2ba79ab..000000000 --- a/src/video/os2fslib/SDL_os2fslib.c +++ /dev/null @@ -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 // Unicode API -#include // Unicode API (codepage conversion) - -#include -#include - -#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: */ diff --git a/src/video/os2fslib/SDL_os2fslib.h b/src/video/os2fslib/SDL_os2fslib.h deleted file mode 100644 index 47a7fe2d4..000000000 --- a/src/video/os2fslib/SDL_os2fslib.h +++ /dev/null @@ -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 - -#include - -/* 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: */ diff --git a/src/video/os2fslib/SDL_vkeys.h b/src/video/os2fslib/SDL_vkeys.h deleted file mode 100644 index 9ec9efafd..000000000 --- a/src/video/os2fslib/SDL_vkeys.h +++ /dev/null @@ -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: */