# HG changeset patch # User Sam Lantinga # Date 1295575445 28800 # Node ID e8916fe9cfc8d754378a9763a4e529b3aa95b9dd # Parent 9e9940eae455c6cd42385261482ae99dbcc12992 Fixed bug #925 Changed "win32" to "windows" diff -r 9e9940eae455 -r e8916fe9cfc8 VisualC/SDL/SDL_VS2005.vcproj --- a/VisualC/SDL/SDL_VS2005.vcproj Thu Jan 20 17:33:06 2011 -0800 +++ b/VisualC/SDL/SDL_VS2005.vcproj Thu Jan 20 18:04:05 2011 -0800 @@ -29,7 +29,7 @@ diff -r 9e9940eae455 -r e8916fe9cfc8 VisualC/SDL/SDL_VS2008.vcproj --- a/VisualC/SDL/SDL_VS2008.vcproj Thu Jan 20 17:33:06 2011 -0800 +++ b/VisualC/SDL/SDL_VS2008.vcproj Thu Jan 20 18:04:05 2011 -0800 @@ -30,7 +30,7 @@ diff -r 9e9940eae455 -r e8916fe9cfc8 VisualC/SDL/SDL_VS2010.vcxproj --- a/VisualC/SDL/SDL_VS2010.vcxproj Thu Jan 20 17:33:06 2011 -0800 +++ b/VisualC/SDL/SDL_VS2010.vcxproj Thu Jan 20 18:04:05 2011 -0800 @@ -75,8 +75,8 @@ Making sure basic SDL headers are in place... if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY -echo Copying SDL_config_win32.h to SDL_config.h... -copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h" +echo Copying SDL_config_windows.h to SDL_config.h... +copy "$(ProjectDir)\..\..\include\SDL_config_windows.h" "$(ProjectDir)\..\..\include\SDL_config.h" :SDLCONFIGOKAY if exist "$(ProjectDir)\..\..\include\SDL_revision.h" goto SDLREVISIONOKAY @@ -155,8 +155,8 @@ Making sure basic SDL headers are in place... if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY -echo Copying SDL_config_win32.h to SDL_config.h... -copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h" +echo Copying SDL_config_windows.h to SDL_config.h... +copy "$(ProjectDir)\..\..\include\SDL_config_windows.h" "$(ProjectDir)\..\..\include\SDL_config.h" :SDLCONFIGOKAY if exist "$(ProjectDir)\..\..\include\SDL_revision.h" goto SDLREVISIONOKAY @@ -238,7 +238,7 @@ - + @@ -290,7 +290,7 @@ - + @@ -299,7 +299,7 @@ - + @@ -323,26 +323,26 @@ - + - + - - - - - - - - - - + + + + + + + + + + - + @@ -389,7 +389,7 @@ - + @@ -397,13 +397,13 @@ - + - + @@ -414,7 +414,7 @@ - + @@ -432,27 +432,27 @@ - - - + + + - - - + + + - - - - - - - - - - + + + + + + + + + + @@ -460,4 +460,4 @@ - \ No newline at end of file + diff -r 9e9940eae455 -r e8916fe9cfc8 VisualC/SDLmain/SDLmain_VS2005.vcproj --- a/VisualC/SDLmain/SDLmain_VS2005.vcproj Thu Jan 20 17:33:06 2011 -0800 +++ b/VisualC/SDLmain/SDLmain_VS2005.vcproj Thu Jan 20 18:04:05 2011 -0800 @@ -29,7 +29,7 @@ diff -r 9e9940eae455 -r e8916fe9cfc8 VisualC/SDLmain/SDLmain_VS2008.vcproj --- a/VisualC/SDLmain/SDLmain_VS2008.vcproj Thu Jan 20 17:33:06 2011 -0800 +++ b/VisualC/SDLmain/SDLmain_VS2008.vcproj Thu Jan 20 18:04:05 2011 -0800 @@ -30,7 +30,7 @@ diff -r 9e9940eae455 -r e8916fe9cfc8 VisualC/SDLmain/SDLmain_VS2010.vcxproj --- a/VisualC/SDLmain/SDLmain_VS2010.vcxproj Thu Jan 20 17:33:06 2011 -0800 +++ b/VisualC/SDLmain/SDLmain_VS2010.vcxproj Thu Jan 20 18:04:05 2011 -0800 @@ -102,8 +102,8 @@ Making sure basic SDL headers are in place... if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY -echo Copying SDL_config_win32.h to SDL_config.h... -copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h" +echo Copying SDL_config_windows.h to SDL_config.h... +copy "$(ProjectDir)\..\..\include\SDL_config_windows.h" "$(ProjectDir)\..\..\include\SDL_config.h" :SDLCONFIGOKAY if exist "$(ProjectDir)\..\..\include\SDL_revision.h" goto SDLREVISIONOKAY @@ -155,8 +155,8 @@ Making sure basic SDL headers are in place... if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY -echo Copying SDL_config_win32.h to SDL_config.h... -copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h" +echo Copying SDL_config_windows.h to SDL_config.h... +copy "$(ProjectDir)\..\..\include\SDL_config_windows.h" "$(ProjectDir)\..\..\include\SDL_config.h" :SDLCONFIGOKAY if exist "$(ProjectDir)\..\..\include\SDL_revision.h" goto SDLREVISIONOKAY @@ -208,8 +208,8 @@ Making sure basic SDL headers are in place... if exist "$(ProjectDir)\..\..\include\SDL_config.h" goto SDLCONFIGOKAY -echo Copying SDL_config_win32.h to SDL_config.h... -copy "$(ProjectDir)\..\..\include\SDL_config_win32.h" "$(ProjectDir)\..\..\include\SDL_config.h" +echo Copying SDL_config_windows.h to SDL_config.h... +copy "$(ProjectDir)\..\..\include\SDL_config_windows.h" "$(ProjectDir)\..\..\include\SDL_config.h" :SDLCONFIGOKAY if exist "$(ProjectDir)\..\..\include\SDL_revision.h" goto SDLREVISIONOKAY @@ -256,9 +256,9 @@ - + - \ No newline at end of file + diff -r 9e9940eae455 -r e8916fe9cfc8 configure.in --- a/configure.in Thu Jan 20 17:33:06 2011 -0800 +++ b/configure.in Thu Jan 20 18:04:05 2011 -0800 @@ -1645,8 +1645,8 @@ } -dnl Check for Win32 OpenGL -CheckWIN32GL() +dnl Check for Windows OpenGL +CheckWINDOWSGL() { if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then AC_DEFINE(SDL_VIDEO_OPENGL) @@ -1906,10 +1906,10 @@ fi } -dnl Determine whether the compiler can produce Win32 executables -CheckWIN32() +dnl Determine whether the compiler can produce Windows executables +CheckWINDOWS() { - AC_MSG_CHECKING(Win32 compiler) + AC_MSG_CHECKING(Windows compiler) have_win32_gcc=no AC_TRY_COMPILE([ #include @@ -1920,7 +1920,7 @@ AC_MSG_RESULT($have_win32_gcc) if test x$have_win32_gcc != xyes; then AC_MSG_ERROR([ -*** Your compiler ($CC) does not produce Win32 executables! +*** Your compiler ($CC) does not produce Windows executables! ]) fi @@ -1938,7 +1938,7 @@ dnl See if the user wants to redirect standard output to files AC_ARG_ENABLE(stdio-redirect, -AC_HELP_STRING([--enable-stdio-redirect], [Redirect STDIO to files on Win32 [[default=yes]]]), +AC_HELP_STRING([--enable-stdio-redirect], [Redirect STDIO to files on Windows [[default=yes]]]), , enable_stdio_redirect=yes) if test x$enable_stdio_redirect != xyes; then EXTRA_CFLAGS="$EXTRA_CFLAGS -DNO_STDIO_REDIRECT" @@ -1949,7 +1949,7 @@ CheckDIRECTX() { AC_ARG_ENABLE(directx, -AC_HELP_STRING([--enable-directx], [use DirectX for Win32 audio/video [[default=yes]]]), +AC_HELP_STRING([--enable-directx], [use DirectX for Windows audio/video [[default=yes]]]), , enable_directx=yes) if test x$enable_directx = xyes; then AC_CHECK_HEADER(d3d9.h, have_d3d=yes) @@ -2332,10 +2332,10 @@ CheckDummyVideo CheckDiskAudio CheckDummyAudio - CheckWIN32 + CheckWINDOWS if test x$enable_video = xyes; then - AC_DEFINE(SDL_VIDEO_DRIVER_WIN32) - SOURCES="$SOURCES $srcdir/src/video/win32/*.c" + AC_DEFINE(SDL_VIDEO_DRIVER_WINDOWS) + SOURCES="$SOURCES $srcdir/src/video/windows/*.c" have_video=yes AC_ARG_ENABLE(render-gdi, AC_HELP_STRING([--enable-render-gdi], [enable the GDI render driver [[default=yes]]]), @@ -2381,10 +2381,10 @@ fi # Set up files for the thread library if test x$enable_threads = xyes; then - AC_DEFINE(SDL_THREAD_WIN32) - SOURCES="$SOURCES $srcdir/src/thread/win32/SDL_sysmutex.c" - SOURCES="$SOURCES $srcdir/src/thread/win32/SDL_syssem.c" - SOURCES="$SOURCES $srcdir/src/thread/win32/SDL_systhread.c" + AC_DEFINE(SDL_THREAD_WINDOWS) + SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_sysmutex.c" + SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_syssem.c" + SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_systhread.c" SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c" have_threads=yes fi @@ -2396,8 +2396,8 @@ fi # Set up files for the shared object loading library if test x$enable_loadso = xyes; then - AC_DEFINE(SDL_LOADSO_WIN32) - SOURCES="$SOURCES $srcdir/src/loadso/win32/*.c" + AC_DEFINE(SDL_LOADSO_WINDOWS) + SOURCES="$SOURCES $srcdir/src/loadso/windows/*.c" have_loadso=yes fi # Set up the system libraries we need @@ -2412,8 +2412,8 @@ ;; esac - # The Win32 platform requires special setup - SDLMAIN_SOURCES="$srcdir/src/main/win32/*.c" + # The Windows platform requires special setup + SDLMAIN_SOURCES="$srcdir/src/main/windows/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS -Dmain=SDL_main -D_WIN32_WCE=0x420" EXTRA_LDFLAGS="-lSDLmain $EXTRA_LDFLAGS" ;; @@ -2431,13 +2431,13 @@ CheckDummyVideo CheckDiskAudio CheckDummyAudio - CheckWIN32 - CheckWIN32GL + CheckWINDOWS + CheckWINDOWSGL CheckDIRECTX # Set up files for the video library if test x$enable_video = xyes; then - AC_DEFINE(SDL_VIDEO_DRIVER_WIN32) - SOURCES="$SOURCES $srcdir/src/video/win32/*.c" + AC_DEFINE(SDL_VIDEO_DRIVER_WINDOWS) + SOURCES="$SOURCES $srcdir/src/video/windows/*.c" have_video=yes AC_ARG_ENABLE(render-gdi, AC_HELP_STRING([--enable-render-gdi], [enable the GDI render driver [[default=yes]]]), @@ -2466,18 +2466,18 @@ if test x$enable_joystick = xyes; then if test x$have_dinput = xyes; then AC_DEFINE(SDL_JOYSTICK_DINPUT) - SOURCES="$SOURCES $srcdir/src/joystick/win32/SDL_dxjoystick.c" + SOURCES="$SOURCES $srcdir/src/joystick/windows/SDL_dxjoystick.c" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid -ldxerr8" else AC_DEFINE(SDL_JOYSTICK_WINMM) - SOURCES="$SOURCES $srcdir/src/joystick/win32/SDL_mmjoystick.c" + SOURCES="$SOURCES $srcdir/src/joystick/windows/SDL_mmjoystick.c" fi have_joystick=yes fi if test x$enable_haptic = xyes; then if test x$have_dinput = xyes; then AC_DEFINE(SDL_HAPTIC_DINPUT) - SOURCES="$SOURCES $srcdir/src/haptic/win32/SDL_syshaptic.c" + SOURCES="$SOURCES $srcdir/src/haptic/windows/SDL_syshaptic.c" have_haptic=yes fi fi @@ -2488,23 +2488,23 @@ fi # Set up files for the thread library if test x$enable_threads = xyes; then - AC_DEFINE(SDL_THREAD_WIN32) - SOURCES="$SOURCES $srcdir/src/thread/win32/SDL_sysmutex.c" - SOURCES="$SOURCES $srcdir/src/thread/win32/SDL_syssem.c" - SOURCES="$SOURCES $srcdir/src/thread/win32/SDL_systhread.c" + AC_DEFINE(SDL_THREAD_WINDOWS) + SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_sysmutex.c" + SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_syssem.c" + SOURCES="$SOURCES $srcdir/src/thread/windows/SDL_systhread.c" SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c" have_threads=yes fi # Set up files for the timer library if test x$enable_timers = xyes; then - AC_DEFINE(SDL_TIMER_WIN32) - SOURCES="$SOURCES $srcdir/src/timer/win32/*.c" + AC_DEFINE(SDL_TIMER_WINDOWS) + SOURCES="$SOURCES $srcdir/src/timer/windows/*.c" have_timers=yes fi # Set up files for the shared object loading library if test x$enable_loadso = xyes; then - AC_DEFINE(SDL_LOADSO_WIN32) - SOURCES="$SOURCES $srcdir/src/loadso/win32/*.c" + AC_DEFINE(SDL_LOADSO_WINDOWS) + SOURCES="$SOURCES $srcdir/src/loadso/windows/*.c" have_loadso=yes fi # Set up the system libraries we need @@ -2512,9 +2512,9 @@ # You can get this here: http://libunicows.sourceforge.net/ #EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lunicows" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lmsimg32 -lwinmm -limm32 -lole32 -loleaut32 -lversion -luuid" - # The Win32 platform requires special setup - VERSION_SOURCES="$srcdir/src/main/win32/*.rc" - SDLMAIN_SOURCES="$srcdir/src/main/win32/*.c" + # The Windows platform requires special setup + VERSION_SOURCES="$srcdir/src/main/windows/*.rc" + SDLMAIN_SOURCES="$srcdir/src/main/windows/*.c" SDL_CFLAGS="$SDL_CFLAGS -Dmain=SDL_main" SDL_LIBS="-lmingw32 -lSDLmain $SDL_LIBS -mwindows" ;; diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_compat.h --- a/include/SDL_compat.h Thu Jan 20 17:33:06 2011 -0800 +++ b/include/SDL_compat.h Thu Jan 20 18:04:05 2011 -0800 @@ -64,6 +64,12 @@ */ /*@{*/ +/* Platform */ +#ifdef __WINDOWS__ +#undef __WIN32__ +#define __WIN32__ 1 +#endif + /** * \name Surface flags */ diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_config.h.default --- a/include/SDL_config.h.default Thu Jan 20 17:33:06 2011 -0800 +++ b/include/SDL_config.h.default Thu Jan 20 18:04:05 2011 -0800 @@ -40,8 +40,8 @@ #include "SDL_config_iphoneos.h" #elif defined(__MACOSX__) #include "SDL_config_macosx.h" -#elif defined(__WIN32__) -#include "SDL_config_win32.h" +#elif defined(__WINDOWS__) +#include "SDL_config_windows.h" #else #include "SDL_config_minimal.h" #endif /* platform config */ diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_config.h.in --- a/include/SDL_config.h.in Thu Jan 20 17:33:06 2011 -0800 +++ b/include/SDL_config.h.in Thu Jan 20 18:04:05 2011 -0800 @@ -89,7 +89,7 @@ #undef HAVE_REALLOC #undef HAVE_FREE #undef HAVE_ALLOCA -#ifndef _WIN32 /* Don't use C runtime versions of these on Windows */ +#ifndef __WINDOWS__ /* Don't use C runtime versions of these on Windows */ #undef HAVE_GETENV #undef HAVE_SETENV #undef HAVE_PUTENV @@ -235,7 +235,7 @@ #undef SDL_LOADSO_DLOPEN #undef SDL_LOADSO_DUMMY #undef SDL_LOADSO_LDG -#undef SDL_LOADSO_WIN32 +#undef SDL_LOADSO_WINDOWS /* Enable various threading systems */ #undef SDL_THREAD_BEOS @@ -244,7 +244,7 @@ #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP #undef SDL_THREAD_SPROC -#undef SDL_THREAD_WIN32 +#undef SDL_THREAD_WINDOWS /* Enable various timer systems */ #undef SDL_TIMER_BEOS @@ -252,7 +252,7 @@ #undef SDL_TIMER_NDS #undef SDL_TIMER_RISCOS #undef SDL_TIMER_UNIX -#undef SDL_TIMER_WIN32 +#undef SDL_TIMER_WINDOWS #undef SDL_TIMER_WINCE /* Enable various video drivers */ @@ -265,7 +265,7 @@ #undef SDL_VIDEO_DRIVER_PHOTON #undef SDL_VIDEO_DRIVER_QNXGF #undef SDL_VIDEO_DRIVER_RISCOS -#undef SDL_VIDEO_DRIVER_WIN32 +#undef SDL_VIDEO_DRIVER_WINDOWS #undef SDL_VIDEO_DRIVER_X11 #undef SDL_VIDEO_DRIVER_X11_DYNAMIC #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_config_win32.h --- a/include/SDL_config_win32.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,199 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_win32_h -#define _SDL_config_win32_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) -#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) -#define HAVE_STDINT_H 1 -#elif defined(_MSC_VER) -typedef signed __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef signed __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef signed __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; -#ifndef _UINTPTR_T_DEFINED -#ifdef _WIN64 -typedef unsigned __int64 uintptr_t; -#else -typedef unsigned int uintptr_t; -#endif -#define _UINTPTR_T_DEFINED -#endif -/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ -#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) -#define DWORD_PTR DWORD -#endif -#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) -#define LONG_PTR LONG -#endif -#else /* !__GNUC__ && !_MSC_VER */ -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 signed long long int64_t; -typedef unsigned long long uint64_t; -#ifndef _SIZE_T_DEFINED_ -#define _SIZE_T_DEFINED_ -typedef unsigned int size_t; -#endif -typedef unsigned int uintptr_t; -#endif /* __GNUC__ || _MSC_VER */ -#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ - -#ifdef _WIN64 -# define SIZEOF_VOIDP 8 -#else -# define SIZEOF_VOIDP 4 -#endif -#define SDL_HAS_64BIT_TYPE 1 - -/* Enabled for SDL 1.2 (binary compatibility) */ -//#define HAVE_LIBC 1 -#ifdef HAVE_LIBC -/* Useful headers */ -#define HAVE_STDIO_H 1 -#define STDC_HEADERS 1 -#define HAVE_STRING_H 1 -#define HAVE_CTYPE_H 1 -#define HAVE_MATH_H 1 -#ifndef _WIN32_WCE -#define HAVE_SIGNAL_H 1 -#endif - -/* 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_QSORT 1 -#define HAVE_ABS 1 -#define HAVE_MEMSET 1 -#define HAVE_MEMCPY 1 -#define HAVE_MEMMOVE 1 -#define HAVE_MEMCMP 1 -#define HAVE_STRLEN 1 -#define HAVE__STRREV 1 -#define HAVE__STRUPR 1 -#define HAVE__STRLWR 1 -#define HAVE_STRCHR 1 -#define HAVE_STRRCHR 1 -#define HAVE_STRSTR 1 -#define HAVE_ITOA 1 -#define HAVE__LTOA 1 -#define HAVE__ULTOA 1 -#define HAVE_STRTOL 1 -#define HAVE_STRTOUL 1 -#define HAVE_STRTOLL 1 -#define HAVE_STRTOD 1 -#define HAVE_ATOI 1 -#define HAVE_ATOF 1 -#define HAVE_STRCMP 1 -#define HAVE_STRNCMP 1 -#define HAVE__STRICMP 1 -#define HAVE__STRNICMP 1 -#define HAVE_SSCANF 1 -#define HAVE_M_PI 1 -#define HAVE_ATAN 1 -#define HAVE_ATAN2 1 -#define HAVE_CEIL 1 -#define HAVE_COPYSIGN 1 -#define HAVE_COS 1 -#define HAVE_COSF 1 -#define HAVE_FABS 1 -#define HAVE_FLOOR 1 -#define HAVE_LOG 1 -#define HAVE_POW 1 -#define HAVE_SCALBN 1 -#define HAVE_SIN 1 -#define HAVE_SINF 1 -#define HAVE_SQRT 1 -#else -#define HAVE_STDARG_H 1 -#define HAVE_STDDEF_H 1 -#endif - -/* Enable various audio drivers */ -#ifndef _WIN32_WCE -#define SDL_AUDIO_DRIVER_DSOUND 1 -#endif -#define SDL_AUDIO_DRIVER_WINWAVEOUT 1 -#define SDL_AUDIO_DRIVER_DISK 1 -#define SDL_AUDIO_DRIVER_DUMMY 1 - -/* Enable various input drivers */ -#ifdef _WIN32_WCE -#define SDL_JOYSTICK_DISABLED 1 -#define SDL_HAPTIC_DUMMY 1 -#else -#define SDL_JOYSTICK_DINPUT 1 -#define SDL_HAPTIC_DINPUT 1 -#endif - -/* Enable various shared object loading systems */ -#define SDL_LOADSO_WIN32 1 - -/* Enable various threading systems */ -#define SDL_THREAD_WIN32 1 - -/* Enable various timer systems */ -#ifdef _WIN32_WCE -#define SDL_TIMER_WINCE 1 -#else -#define SDL_TIMER_WIN32 1 -#endif - -/* Enable various video drivers */ -#define SDL_VIDEO_DRIVER_DUMMY 1 -#define SDL_VIDEO_DRIVER_WIN32 1 - -#define SDL_VIDEO_RENDER_D3D 1 -#define SDL_VIDEO_RENDER_GDI 1 - -/* Enable OpenGL support */ -#ifndef _WIN32_WCE -#define SDL_VIDEO_OPENGL 1 -#define SDL_VIDEO_OPENGL_WGL 1 -#define SDL_VIDEO_RENDER_OGL 1 -#endif - -/* Enable system power support */ -#define SDL_POWER_WINDOWS 1 - -/* Enable assembly routines (Win64 doesn't have inline asm) */ -#ifndef _WIN64 -#define SDL_ASSEMBLY_ROUTINES 1 -#endif - -#endif /* _SDL_config_win32_h */ diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_config_windows.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/SDL_config_windows.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,199 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_windows2_h +#define _SDL_config_windows2_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) +#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) +#define HAVE_STDINT_H 1 +#elif defined(_MSC_VER) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ +#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) +#define DWORD_PTR DWORD +#endif +#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) +#define LONG_PTR LONG +#endif +#else /* !__GNUC__ && !_MSC_VER */ +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 signed long long int64_t; +typedef unsigned long long uint64_t; +#ifndef _SIZE_T_DEFINED_ +#define _SIZE_T_DEFINED_ +typedef unsigned int size_t; +#endif +typedef unsigned int uintptr_t; +#endif /* __GNUC__ || _MSC_VER */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +#ifdef _WIN64 +# define SIZEOF_VOIDP 8 +#else +# define SIZEOF_VOIDP 4 +#endif +#define SDL_HAS_64BIT_TYPE 1 + +/* Enabled for SDL 1.2 (binary compatibility) */ +//#define HAVE_LIBC 1 +#ifdef HAVE_LIBC +/* Useful headers */ +#define HAVE_STDIO_H 1 +#define STDC_HEADERS 1 +#define HAVE_STRING_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_MATH_H 1 +#ifndef _WIN32_WCE +#define HAVE_SIGNAL_H 1 +#endif + +/* 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_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +#define HAVE__STRUPR 1 +#define HAVE__STRLWR 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_ITOA 1 +#define HAVE__LTOA 1 +#define HAVE__ULTOA 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE_SSCANF 1 +#define HAVE_M_PI 1 +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +#define HAVE_CEIL 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_LOG 1 +#define HAVE_POW 1 +#define HAVE_SCALBN 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#endif + +/* Enable various audio drivers */ +#ifndef _WIN32_WCE +#define SDL_AUDIO_DRIVER_DSOUND 1 +#endif +#define SDL_AUDIO_DRIVER_WINWAVEOUT 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#ifdef _WIN32_WCE +#define SDL_JOYSTICK_DISABLED 1 +#define SDL_HAPTIC_DUMMY 1 +#else +#define SDL_JOYSTICK_DINPUT 1 +#define SDL_HAPTIC_DINPUT 1 +#endif + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#define SDL_THREAD_WINDOWS 1 + +/* Enable various timer systems */ +#ifdef _WIN32_WCE +#define SDL_TIMER_WINCE 1 +#else +#define SDL_TIMER_WINDOWS 1 +#endif + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDOWS 1 + +#define SDL_VIDEO_RENDER_D3D 1 +#define SDL_VIDEO_RENDER_GDI 1 + +/* Enable OpenGL support */ +#ifndef _WIN32_WCE +#define SDL_VIDEO_OPENGL 1 +#define SDL_VIDEO_OPENGL_WGL 1 +#define SDL_VIDEO_RENDER_OGL 1 +#endif + +/* Enable system power support */ +#define SDL_POWER_WINDOWS 1 + +/* Enable assembly routines (Win64 doesn't have inline asm) */ +#ifndef _WIN64 +#define SDL_ASSEMBLY_ROUTINES 1 +#endif + +#endif /* _SDL_config_windows2_h */ diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_main.h --- a/include/SDL_main.h Thu Jan 20 17:33:06 2011 -0800 +++ b/include/SDL_main.h Thu Jan 20 18:04:05 2011 -0800 @@ -31,7 +31,7 @@ * Redefine main() on some platforms so that it is called by SDL. */ -#if defined(__WIN32__) || \ +#if defined(__WINDOWS__) || \ (defined(__MWERKS__) && !defined(__BEOS__)) || \ defined(__SYMBIAN32__) || defined(__IPHONEOS__) || \ defined(__ANDROID__) @@ -66,7 +66,7 @@ /* From the SDL library code -- needed for registering the app on Win32 */ -#ifdef __WIN32__ +#ifdef __WINDOWS__ #include "begin_code.h" #ifdef __cplusplus diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_opengl.h --- a/include/SDL_opengl.h Thu Jan 20 17:33:06 2011 -0800 +++ b/include/SDL_opengl.h Thu Jan 20 18:04:05 2011 -0800 @@ -31,7 +31,7 @@ #include "SDL_config.h" -#ifdef __WIN32__ +#ifdef __WINDOWS__ #define WIN32_LEAN_AND_MEAN #ifndef NOMINMAX #define NOMINMAX /* Don't defined min() and max() */ diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_platform.h --- a/include/SDL_platform.h Thu Jan 20 17:33:06 2011 -0800 +++ b/include/SDL_platform.h Thu Jan 20 18:04:05 2011 -0800 @@ -125,8 +125,8 @@ #define __SOLARIS__ 1 #endif #if defined(WIN32) || defined(_WIN32) -#undef __WIN32__ -#define __WIN32__ 1 +#undef __WINDOWS__ +#define __WINDOWS__ 1 #endif #if defined(__NDS__) diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_rwops.h --- a/include/SDL_rwops.h Thu Jan 20 17:33:06 2011 -0800 +++ b/include/SDL_rwops.h Thu Jan 20 18:04:05 2011 -0800 @@ -83,7 +83,7 @@ Uint32 type; union { -#ifdef __WIN32__ +#ifdef __WINDOWS__ struct { SDL_bool append; @@ -94,7 +94,7 @@ size_t size; size_t left; } buffer; - } win32io; + } windowsio; #endif #ifdef HAVE_STDIO_H struct diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_syswm.h --- a/include/SDL_syswm.h Thu Jan 20 17:33:06 2011 -0800 +++ b/include/SDL_syswm.h Thu Jan 20 18:04:05 2011 -0800 @@ -54,7 +54,7 @@ struct SDL_SysWMinfo; #else -#if defined(SDL_VIDEO_DRIVER_WIN32) +#if defined(SDL_VIDEO_DRIVER_WINDOWS) #define WIN32_LEAN_AND_MEAN #include #endif @@ -118,7 +118,7 @@ SDL_SYSWM_TYPE subsystem; union { -#if defined(SDL_VIDEO_DRIVER_WIN32) +#if defined(SDL_VIDEO_DRIVER_WINDOWS) struct { HWND hwnd; /**< The window for the message */ UINT msg; /**< The type of message */ @@ -163,7 +163,7 @@ SDL_SYSWM_TYPE subsystem; union { -#if defined(SDL_VIDEO_DRIVER_WIN32) +#if defined(SDL_VIDEO_DRIVER_WINDOWS) struct { HWND window; /**< The window handle */ diff -r 9e9940eae455 -r e8916fe9cfc8 include/SDL_thread.h --- a/include/SDL_thread.h Thu Jan 20 17:33:06 2011 -0800 +++ b/include/SDL_thread.h Thu Jan 20 18:04:05 2011 -0800 @@ -55,7 +55,7 @@ */ typedef int (SDLCALL * SDL_ThreadFunction) (void *data); -#if defined(__WIN32__) && !defined(HAVE_LIBC) +#if defined(__WINDOWS__) && !defined(HAVE_LIBC) /** * \file SDL_thread.h * diff -r 9e9940eae455 -r e8916fe9cfc8 include/begin_code.h --- a/include/begin_code.h Thu Jan 20 17:33:06 2011 -0800 +++ b/include/begin_code.h Thu Jan 20 18:04:05 2011 -0800 @@ -42,7 +42,7 @@ # else # define DECLSPEC __declspec(export) # endif -# elif defined(__WIN32__) +# elif defined(__WINDOWS__) # ifdef __BORLANDC__ # ifdef BUILD_SDL # define DECLSPEC @@ -63,7 +63,7 @@ /* By default SDL uses the C calling convention */ #ifndef SDLCALL -#if defined(__WIN32__) && !defined(__GNUC__) +#if defined(__WINDOWS__) && !defined(__GNUC__) #define SDLCALL __cdecl #else #define SDLCALL diff -r 9e9940eae455 -r e8916fe9cfc8 src/SDL.c --- a/src/SDL.c Thu Jan 20 17:33:06 2011 -0800 +++ b/src/SDL.c Thu Jan 20 18:04:05 2011 -0800 @@ -39,7 +39,7 @@ extern int SDL_TimerInit(void); extern void SDL_TimerQuit(void); #endif -#if defined(__WIN32__) +#if defined(__WINDOWS__) extern int SDL_HelperWindowCreate(void); extern int SDL_HelperWindowDestroy(void); #endif @@ -147,7 +147,7 @@ /* Clear the error message */ SDL_ClearError(); -#if defined(__WIN32__) +#if defined(__WINDOWS__) if (SDL_HelperWindowCreate() < 0) { return -1; } @@ -220,7 +220,7 @@ fflush(stdout); #endif -#if defined(__WIN32__) +#if defined(__WINDOWS__) SDL_HelperWindowDestroy(); #endif SDL_QuitSubSystem(SDL_INIT_EVERYTHING); @@ -312,7 +312,7 @@ return "RISC OS"; #elif __SOLARIS__ return "Solaris"; -#elif __WIN32__ +#elif __WINDOWS__ #ifdef _WIN32_WCE return "Windows CE"; #else @@ -325,7 +325,7 @@ #endif } -#if defined(__WIN32__) +#if defined(__WINDOWS__) #if !defined(HAVE_LIBC) || (defined(__WATCOMC__) && defined(BUILD_DLL)) /* Need to include DllMain() on Watcom C for some reason.. */ @@ -347,6 +347,6 @@ } #endif /* building DLL with Watcom C */ -#endif /* __WIN32__ */ +#endif /* __WINDOWS__ */ /* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/audio/SDL_audio.c --- a/src/audio/SDL_audio.c Thu Jan 20 17:33:06 2011 -0800 +++ b/src/audio/SDL_audio.c Thu Jan 20 18:04:05 2011 -0800 @@ -971,7 +971,7 @@ if (!current_audio.impl.ProvidesOwnCallbackThread) { /* Start the audio thread */ /* !!! FIXME: this is nasty. */ -#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) +#if (defined(__WINDOWS__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) #undef SDL_CreateThread device->thread = SDL_CreateThread(SDL_RunAudio, device, NULL, NULL); #else diff -r 9e9940eae455 -r e8916fe9cfc8 src/cpuinfo/SDL_cpuinfo.c --- a/src/cpuinfo/SDL_cpuinfo.c Thu Jan 20 17:33:06 2011 -0800 +++ b/src/cpuinfo/SDL_cpuinfo.c Thu Jan 20 18:04:05 2011 -0800 @@ -38,7 +38,7 @@ #include #include #endif -#ifdef __WIN32__ +#ifdef __WINDOWS__ #define WIN32_LEAN_AND_MEAN #include #endif @@ -319,7 +319,7 @@ sysctlbyname("hw.ncpu", &SDL_CPUCount, &size, NULL, 0); } #endif -#ifdef __WIN32__ +#ifdef __WINDOWS__ if (SDL_CPUCount <= 0) { SYSTEM_INFO info; GetSystemInfo(&info); diff -r 9e9940eae455 -r e8916fe9cfc8 src/events/SDL_events.c --- a/src/events/SDL_events.c Thu Jan 20 17:33:06 2011 -0800 +++ b/src/events/SDL_events.c Thu Jan 20 18:04:05 2011 -0800 @@ -170,7 +170,7 @@ /* The event thread will handle timers too */ SDL_SetTimerThreaded(2); -#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) +#if (defined(__WINDOWS__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) #undef SDL_CreateThread SDL_EventThread = SDL_CreateThread(SDL_GobbleEvents, NULL, NULL, NULL); diff -r 9e9940eae455 -r e8916fe9cfc8 src/events/SDL_sysevents.h --- a/src/events/SDL_sysevents.h Thu Jan 20 17:33:06 2011 -0800 +++ b/src/events/SDL_sysevents.h Thu Jan 20 18:04:05 2011 -0800 @@ -29,7 +29,7 @@ #define MUST_THREAD_EVENTS #endif -#ifdef __WIN32__ /* Win32 doesn't allow a separate event thread */ +#ifdef __WINDOWS__ /* Windows doesn't allow a separate event thread */ #define CANT_THREAD_EVENTS #endif diff -r 9e9940eae455 -r e8916fe9cfc8 src/events/scancodes_win32.h --- a/src/events/scancodes_win32.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,287 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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 "../../include/SDL_scancode.h" - -/* Win32 virtual key code to SDL scancode mapping table - Sources: - - msdn.microsoft.com -*/ -/* *INDENT-OFF* */ -static const SDL_scancode win32_scancode_table[] = { - /* 0, 0x00 */ SDL_SCANCODE_UNKNOWN, - /* 1, 0x01 */ SDL_SCANCODE_UNKNOWN, - /* 2, 0x02 */ SDL_SCANCODE_UNKNOWN, - /* 3, 0x03 */ SDL_SCANCODE_UNKNOWN, - /* 4, 0x04 */ SDL_SCANCODE_UNKNOWN, - /* 5, 0x05 */ SDL_SCANCODE_UNKNOWN, - /* 6, 0x06 */ SDL_SCANCODE_UNKNOWN, - /* 7, 0x07 */ SDL_SCANCODE_UNKNOWN, - /* 8, 0x08 */ SDL_SCANCODE_BACKSPACE, - /* 9, 0x09 */ SDL_SCANCODE_TAB, - /* 10, 0x0a */ SDL_SCANCODE_KP_ENTER, /* Not a VKEY, SDL specific */ - /* 11, 0x0b */ SDL_SCANCODE_UNKNOWN, - /* 12, 0x0c */ SDL_SCANCODE_CLEAR, - /* 13, 0x0d */ SDL_SCANCODE_RETURN, - /* 14, 0x0e */ SDL_SCANCODE_UNKNOWN, - /* 15, 0x0f */ SDL_SCANCODE_UNKNOWN, - /* 16, 0x10 */ SDL_SCANCODE_UNKNOWN, - /* 17, 0x11 */ SDL_SCANCODE_UNKNOWN, - /* 18, 0x12 */ SDL_SCANCODE_APPLICATION, - /* 19, 0x13 */ SDL_SCANCODE_PAUSE, - /* 20, 0x14 */ SDL_SCANCODE_CAPSLOCK, - /* 21, 0x15 */ SDL_SCANCODE_UNKNOWN, - /* 22, 0x16 */ SDL_SCANCODE_UNKNOWN, - /* 23, 0x17 */ SDL_SCANCODE_UNKNOWN, - /* 24, 0x18 */ SDL_SCANCODE_UNKNOWN, - /* 25, 0x19 */ SDL_SCANCODE_UNKNOWN, - /* 26, 0x1a */ SDL_SCANCODE_UNKNOWN, - /* 27, 0x1b */ SDL_SCANCODE_ESCAPE, - /* 28, 0x1c */ SDL_SCANCODE_UNKNOWN, - /* 29, 0x1d */ SDL_SCANCODE_UNKNOWN, - /* 30, 0x1e */ SDL_SCANCODE_UNKNOWN, - /* 31, 0x1f */ SDL_SCANCODE_MODE, - /* 32, 0x20 */ SDL_SCANCODE_SPACE, - /* 33, 0x21 */ SDL_SCANCODE_PAGEUP, - /* 34, 0x22 */ SDL_SCANCODE_PAGEDOWN, - /* 35, 0x23 */ SDL_SCANCODE_END, - /* 36, 0x24 */ SDL_SCANCODE_HOME, - /* 37, 0x25 */ SDL_SCANCODE_LEFT, - /* 38, 0x26 */ SDL_SCANCODE_UP, - /* 39, 0x27 */ SDL_SCANCODE_RIGHT, - /* 40, 0x28 */ SDL_SCANCODE_DOWN, - /* 41, 0x29 */ SDL_SCANCODE_SELECT, - /* 42, 0x2a */ SDL_SCANCODE_UNKNOWN, /* VK_PRINT */ - /* 43, 0x2b */ SDL_SCANCODE_EXECUTE, - /* 44, 0x2c */ SDL_SCANCODE_PRINTSCREEN, - /* 45, 0x2d */ SDL_SCANCODE_INSERT, - /* 46, 0x2e */ SDL_SCANCODE_DELETE, - /* 47, 0x2f */ SDL_SCANCODE_HELP, - /* 48, 0x30 */ SDL_SCANCODE_0, - /* 49, 0x31 */ SDL_SCANCODE_1, - /* 50, 0x32 */ SDL_SCANCODE_2, - /* 51, 0x33 */ SDL_SCANCODE_3, - /* 52, 0x34 */ SDL_SCANCODE_4, - /* 53, 0x35 */ SDL_SCANCODE_5, - /* 54, 0x36 */ SDL_SCANCODE_6, - /* 55, 0x37 */ SDL_SCANCODE_7, - /* 56, 0x38 */ SDL_SCANCODE_8, - /* 57, 0x39 */ SDL_SCANCODE_9, - /* 58, 0x3a */ SDL_SCANCODE_UNKNOWN, - /* 59, 0x3b */ SDL_SCANCODE_UNKNOWN, - /* 60, 0x3c */ SDL_SCANCODE_UNKNOWN, - /* 61, 0x3d */ SDL_SCANCODE_UNKNOWN, - /* 62, 0x3e */ SDL_SCANCODE_UNKNOWN, - /* 63, 0x3f */ SDL_SCANCODE_UNKNOWN, - /* 64, 0x40 */ SDL_SCANCODE_UNKNOWN, - /* 65, 0x41 */ SDL_SCANCODE_A, - /* 66, 0x42 */ SDL_SCANCODE_B, - /* 67, 0x43 */ SDL_SCANCODE_C, - /* 68, 0x44 */ SDL_SCANCODE_D, - /* 69, 0x45 */ SDL_SCANCODE_E, - /* 70, 0x46 */ SDL_SCANCODE_F, - /* 71, 0x47 */ SDL_SCANCODE_G, - /* 72, 0x48 */ SDL_SCANCODE_H, - /* 73, 0x49 */ SDL_SCANCODE_I, - /* 74, 0x4a */ SDL_SCANCODE_J, - /* 75, 0x4b */ SDL_SCANCODE_K, - /* 76, 0x4c */ SDL_SCANCODE_L, - /* 77, 0x4d */ SDL_SCANCODE_M, - /* 78, 0x4e */ SDL_SCANCODE_N, - /* 79, 0x4f */ SDL_SCANCODE_O, - /* 80, 0x50 */ SDL_SCANCODE_P, - /* 81, 0x51 */ SDL_SCANCODE_Q, - /* 82, 0x52 */ SDL_SCANCODE_R, - /* 83, 0x53 */ SDL_SCANCODE_S, - /* 84, 0x54 */ SDL_SCANCODE_T, - /* 85, 0x55 */ SDL_SCANCODE_U, - /* 86, 0x56 */ SDL_SCANCODE_V, - /* 87, 0x57 */ SDL_SCANCODE_W, - /* 88, 0x58 */ SDL_SCANCODE_X, - /* 89, 0x59 */ SDL_SCANCODE_Y, - /* 90, 0x5a */ SDL_SCANCODE_Z, - /* 91, 0x5b */ SDL_SCANCODE_LGUI, - /* 92, 0x5c */ SDL_SCANCODE_RGUI, - /* 93, 0x5d */ SDL_SCANCODE_APPLICATION, - /* 94, 0x5e */ SDL_SCANCODE_UNKNOWN, - /* 95, 0x5f */ SDL_SCANCODE_UNKNOWN, - /* 96, 0x60 */ SDL_SCANCODE_KP_0, - /* 97, 0x61 */ SDL_SCANCODE_KP_1, - /* 98, 0x62 */ SDL_SCANCODE_KP_2, - /* 99, 0x63 */ SDL_SCANCODE_KP_3, - /* 100, 0x64 */ SDL_SCANCODE_KP_4, - /* 101, 0x65 */ SDL_SCANCODE_KP_5, - /* 102, 0x66 */ SDL_SCANCODE_KP_6, - /* 103, 0x67 */ SDL_SCANCODE_KP_7, - /* 104, 0x68 */ SDL_SCANCODE_KP_8, - /* 105, 0x69 */ SDL_SCANCODE_KP_9, - /* 106, 0x6a */ SDL_SCANCODE_KP_MULTIPLY, - /* 107, 0x6b */ SDL_SCANCODE_KP_PLUS, - /* 108, 0x6c */ SDL_SCANCODE_SEPARATOR, - /* 109, 0x6d */ SDL_SCANCODE_KP_MINUS, - /* 110, 0x6e */ SDL_SCANCODE_KP_DECIMAL, - /* 111, 0x6f */ SDL_SCANCODE_KP_DIVIDE, - /* 112, 0x70 */ SDL_SCANCODE_F1, - /* 113, 0x71 */ SDL_SCANCODE_F2, - /* 114, 0x72 */ SDL_SCANCODE_F3, - /* 115, 0x73 */ SDL_SCANCODE_F4, - /* 116, 0x74 */ SDL_SCANCODE_F5, - /* 117, 0x75 */ SDL_SCANCODE_F6, - /* 118, 0x76 */ SDL_SCANCODE_F7, - /* 119, 0x77 */ SDL_SCANCODE_F8, - /* 120, 0x78 */ SDL_SCANCODE_F9, - /* 121, 0x79 */ SDL_SCANCODE_F10, - /* 122, 0x7a */ SDL_SCANCODE_F11, - /* 123, 0x7b */ SDL_SCANCODE_F12, - /* 124, 0x7c */ SDL_SCANCODE_F13, - /* 125, 0x7d */ SDL_SCANCODE_F14, - /* 126, 0x7e */ SDL_SCANCODE_F15, - /* 127, 0x7f */ SDL_SCANCODE_F16, - /* 128, 0x80 */ SDL_SCANCODE_F17, /* or SDL_SCANCODE_AUDIONEXT */ - /* 129, 0x81 */ SDL_SCANCODE_F18, /* or SDL_SCANCODE_AUDIOPREV */ - /* 130, 0x82 */ SDL_SCANCODE_F19, /* or SDL_SCANCODE_AUDIOSTOP */ - /* 131, 0x83 */ SDL_SCANCODE_F20, /* or SDL_SCANCODE_AUDIOPLAY */ - /* 132, 0x84 */ SDL_SCANCODE_F21, /* or SDL_SCANCODE_MAIL */ - /* 133, 0x85 */ SDL_SCANCODE_F22, /* or SDL_SCANCODE_MEDIASELECT */ - /* 134, 0x86 */ SDL_SCANCODE_F23, /* or SDL_SCANCODE_WWW */ - /* 135, 0x87 */ SDL_SCANCODE_F24, /* or SDL_SCANCODE_CALCULATOR */ - /* 136, 0x88 */ SDL_SCANCODE_UNKNOWN, - /* 137, 0x89 */ SDL_SCANCODE_UNKNOWN, - /* 138, 0x8a */ SDL_SCANCODE_UNKNOWN, - /* 139, 0x8b */ SDL_SCANCODE_UNKNOWN, - /* 140, 0x8c */ SDL_SCANCODE_UNKNOWN, - /* 141, 0x8d */ SDL_SCANCODE_UNKNOWN, - /* 142, 0x8e */ SDL_SCANCODE_UNKNOWN, - /* 143, 0x8f */ SDL_SCANCODE_UNKNOWN, - /* 144, 0x90 */ SDL_SCANCODE_NUMLOCKCLEAR, - /* 145, 0x91 */ SDL_SCANCODE_SCROLLLOCK, - /* 146, 0x92 */ SDL_SCANCODE_KP_EQUALS, - /* 147, 0x93 */ SDL_SCANCODE_UNKNOWN, - /* 148, 0x94 */ SDL_SCANCODE_UNKNOWN, - /* 149, 0x95 */ SDL_SCANCODE_UNKNOWN, - /* 150, 0x96 */ SDL_SCANCODE_UNKNOWN, - /* 151, 0x97 */ SDL_SCANCODE_UNKNOWN, - /* 152, 0x98 */ SDL_SCANCODE_UNKNOWN, - /* 153, 0x99 */ SDL_SCANCODE_UNKNOWN, - /* 154, 0x9a */ SDL_SCANCODE_UNKNOWN, - /* 155, 0x9b */ SDL_SCANCODE_UNKNOWN, - /* 156, 0x9c */ SDL_SCANCODE_UNKNOWN, - /* 157, 0x9d */ SDL_SCANCODE_UNKNOWN, - /* 158, 0x9e */ SDL_SCANCODE_UNKNOWN, - /* 159, 0x9f */ SDL_SCANCODE_UNKNOWN, - /* 160, 0xa0 */ SDL_SCANCODE_LSHIFT, - /* 161, 0xa1 */ SDL_SCANCODE_RSHIFT, - /* 162, 0xa2 */ SDL_SCANCODE_LCTRL, - /* 163, 0xa3 */ SDL_SCANCODE_RCTRL, - /* 164, 0xa4 */ SDL_SCANCODE_LALT, - /* 165, 0xa5 */ SDL_SCANCODE_RALT, - /* 166, 0xa6 */ SDL_SCANCODE_AC_BACK, - /* 167, 0xa7 */ SDL_SCANCODE_AC_FORWARD, - /* 168, 0xa8 */ SDL_SCANCODE_AC_REFRESH, - /* 169, 0xa9 */ SDL_SCANCODE_AC_STOP, - /* 170, 0xaa */ SDL_SCANCODE_AC_SEARCH, - /* 171, 0xab */ SDL_SCANCODE_AC_BOOKMARKS, - /* 172, 0xac */ SDL_SCANCODE_AC_HOME, - /* 173, 0xad */ SDL_SCANCODE_AUDIOMUTE, - /* 174, 0xae */ SDL_SCANCODE_VOLUMEDOWN, - /* 175, 0xaf */ SDL_SCANCODE_VOLUMEUP, - /* 176, 0xb0 */ SDL_SCANCODE_AUDIONEXT, - /* 177, 0xb1 */ SDL_SCANCODE_AUDIOPREV, - /* 178, 0xb2 */ SDL_SCANCODE_AUDIOSTOP, - /* 179, 0xb3 */ SDL_SCANCODE_AUDIOPLAY, - /* 180, 0xb4 */ SDL_SCANCODE_MAIL, - /* 181, 0xb5 */ SDL_SCANCODE_MEDIASELECT, - /* 182, 0xb6 */ SDL_SCANCODE_UNKNOWN, /* VK_LAUNCH_APP1 */ - /* 183, 0xb7 */ SDL_SCANCODE_UNKNOWN, /* VK_LAUNCH_APP2 */ - /* 184, 0xb8 */ SDL_SCANCODE_UNKNOWN, - /* 185, 0xb9 */ SDL_SCANCODE_UNKNOWN, - /* 186, 0xba */ SDL_SCANCODE_SEMICOLON, - /* 187, 0xbb */ SDL_SCANCODE_EQUALS, - /* 188, 0xbc */ SDL_SCANCODE_COMMA, - /* 189, 0xbd */ SDL_SCANCODE_MINUS, - /* 190, 0xbe */ SDL_SCANCODE_PERIOD, - /* 191, 0xbf */ SDL_SCANCODE_SLASH, - /* 192, 0xc0 */ SDL_SCANCODE_GRAVE, - /* 193, 0xc1 */ SDL_SCANCODE_UNKNOWN, - /* 194, 0xc2 */ SDL_SCANCODE_UNKNOWN, - /* 195, 0xc3 */ SDL_SCANCODE_UNKNOWN, - /* 196, 0xc4 */ SDL_SCANCODE_UNKNOWN, - /* 197, 0xc5 */ SDL_SCANCODE_UNKNOWN, - /* 198, 0xc6 */ SDL_SCANCODE_UNKNOWN, - /* 199, 0xc7 */ SDL_SCANCODE_UNKNOWN, - /* 200, 0xc8 */ SDL_SCANCODE_UNKNOWN, - /* 201, 0xc9 */ SDL_SCANCODE_UNKNOWN, - /* 202, 0xca */ SDL_SCANCODE_UNKNOWN, - /* 203, 0xcb */ SDL_SCANCODE_UNKNOWN, - /* 204, 0xcc */ SDL_SCANCODE_UNKNOWN, - /* 205, 0xcd */ SDL_SCANCODE_UNKNOWN, - /* 206, 0xce */ SDL_SCANCODE_UNKNOWN, - /* 207, 0xcf */ SDL_SCANCODE_UNKNOWN, - /* 208, 0xd0 */ SDL_SCANCODE_UNKNOWN, - /* 209, 0xd1 */ SDL_SCANCODE_UNKNOWN, - /* 210, 0xd2 */ SDL_SCANCODE_UNKNOWN, - /* 211, 0xd3 */ SDL_SCANCODE_UNKNOWN, - /* 212, 0xd4 */ SDL_SCANCODE_UNKNOWN, - /* 213, 0xd5 */ SDL_SCANCODE_UNKNOWN, - /* 214, 0xd6 */ SDL_SCANCODE_UNKNOWN, - /* 215, 0xd7 */ SDL_SCANCODE_UNKNOWN, - /* 216, 0xd8 */ SDL_SCANCODE_UNKNOWN, - /* 217, 0xd9 */ SDL_SCANCODE_UNKNOWN, - /* 218, 0xda */ SDL_SCANCODE_UNKNOWN, - /* 219, 0xdb */ SDL_SCANCODE_LEFTBRACKET, - /* 220, 0xdc */ SDL_SCANCODE_BACKSLASH, - /* 221, 0xdd */ SDL_SCANCODE_RIGHTBRACKET, - /* 222, 0xde */ SDL_SCANCODE_APOSTROPHE, - /* 223, 0xdf */ SDL_SCANCODE_UNKNOWN, - /* 224, 0xe0 */ SDL_SCANCODE_UNKNOWN, - /* 225, 0xe1 */ SDL_SCANCODE_UNKNOWN, - /* 226, 0xe2 */ SDL_SCANCODE_NONUSBACKSLASH, - /* 227, 0xe3 */ SDL_SCANCODE_UNKNOWN, - /* 228, 0xe4 */ SDL_SCANCODE_UNKNOWN, - /* 229, 0xe5 */ SDL_SCANCODE_UNKNOWN, - /* 230, 0xe6 */ SDL_SCANCODE_UNKNOWN, - /* 231, 0xe7 */ SDL_SCANCODE_UNKNOWN, - /* 232, 0xe8 */ SDL_SCANCODE_UNKNOWN, - /* 233, 0xe9 */ SDL_SCANCODE_UNKNOWN, - /* 234, 0xea */ SDL_SCANCODE_UNKNOWN, - /* 235, 0xeb */ SDL_SCANCODE_UNKNOWN, - /* 236, 0xec */ SDL_SCANCODE_UNKNOWN, - /* 237, 0xed */ SDL_SCANCODE_UNKNOWN, - /* 238, 0xee */ SDL_SCANCODE_UNKNOWN, - /* 239, 0xef */ SDL_SCANCODE_UNKNOWN, - /* 240, 0xf0 */ SDL_SCANCODE_UNKNOWN, - /* 241, 0xf1 */ SDL_SCANCODE_UNKNOWN, - /* 242, 0xf2 */ SDL_SCANCODE_UNKNOWN, - /* 243, 0xf3 */ SDL_SCANCODE_UNKNOWN, - /* 244, 0xf4 */ SDL_SCANCODE_UNKNOWN, - /* 245, 0xf5 */ SDL_SCANCODE_UNKNOWN, - /* 246, 0xf6 */ SDL_SCANCODE_SYSREQ, - /* 247, 0xf7 */ SDL_SCANCODE_CRSEL, - /* 248, 0xf8 */ SDL_SCANCODE_EXSEL, - /* 249, 0xf9 */ SDL_SCANCODE_UNKNOWN, /* VK_EREOF */ - /* 250, 0xfa */ SDL_SCANCODE_UNKNOWN, /* VK_PLAY */ - /* 251, 0xfb */ SDL_SCANCODE_UNKNOWN, /* VK_ZOOM */ - /* 252, 0xfc */ SDL_SCANCODE_UNKNOWN, - /* 253, 0xfd */ SDL_SCANCODE_UNKNOWN, /* VK_PA1 */ - /* 254, 0xfe */ SDL_SCANCODE_CLEAR, - /* 255, 0xff */ SDL_SCANCODE_UNKNOWN, -}; -/* *INDENT-ON* */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/events/scancodes_windows.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/events/scancodes_windows.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,287 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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 "../../include/SDL_scancode.h" + +/* Win32 virtual key code to SDL scancode mapping table + Sources: + - msdn.microsoft.com +*/ +/* *INDENT-OFF* */ +static const SDL_scancode windows_scancode_table[] = { + /* 0, 0x00 */ SDL_SCANCODE_UNKNOWN, + /* 1, 0x01 */ SDL_SCANCODE_UNKNOWN, + /* 2, 0x02 */ SDL_SCANCODE_UNKNOWN, + /* 3, 0x03 */ SDL_SCANCODE_UNKNOWN, + /* 4, 0x04 */ SDL_SCANCODE_UNKNOWN, + /* 5, 0x05 */ SDL_SCANCODE_UNKNOWN, + /* 6, 0x06 */ SDL_SCANCODE_UNKNOWN, + /* 7, 0x07 */ SDL_SCANCODE_UNKNOWN, + /* 8, 0x08 */ SDL_SCANCODE_BACKSPACE, + /* 9, 0x09 */ SDL_SCANCODE_TAB, + /* 10, 0x0a */ SDL_SCANCODE_KP_ENTER, /* Not a VKEY, SDL specific */ + /* 11, 0x0b */ SDL_SCANCODE_UNKNOWN, + /* 12, 0x0c */ SDL_SCANCODE_CLEAR, + /* 13, 0x0d */ SDL_SCANCODE_RETURN, + /* 14, 0x0e */ SDL_SCANCODE_UNKNOWN, + /* 15, 0x0f */ SDL_SCANCODE_UNKNOWN, + /* 16, 0x10 */ SDL_SCANCODE_UNKNOWN, + /* 17, 0x11 */ SDL_SCANCODE_UNKNOWN, + /* 18, 0x12 */ SDL_SCANCODE_APPLICATION, + /* 19, 0x13 */ SDL_SCANCODE_PAUSE, + /* 20, 0x14 */ SDL_SCANCODE_CAPSLOCK, + /* 21, 0x15 */ SDL_SCANCODE_UNKNOWN, + /* 22, 0x16 */ SDL_SCANCODE_UNKNOWN, + /* 23, 0x17 */ SDL_SCANCODE_UNKNOWN, + /* 24, 0x18 */ SDL_SCANCODE_UNKNOWN, + /* 25, 0x19 */ SDL_SCANCODE_UNKNOWN, + /* 26, 0x1a */ SDL_SCANCODE_UNKNOWN, + /* 27, 0x1b */ SDL_SCANCODE_ESCAPE, + /* 28, 0x1c */ SDL_SCANCODE_UNKNOWN, + /* 29, 0x1d */ SDL_SCANCODE_UNKNOWN, + /* 30, 0x1e */ SDL_SCANCODE_UNKNOWN, + /* 31, 0x1f */ SDL_SCANCODE_MODE, + /* 32, 0x20 */ SDL_SCANCODE_SPACE, + /* 33, 0x21 */ SDL_SCANCODE_PAGEUP, + /* 34, 0x22 */ SDL_SCANCODE_PAGEDOWN, + /* 35, 0x23 */ SDL_SCANCODE_END, + /* 36, 0x24 */ SDL_SCANCODE_HOME, + /* 37, 0x25 */ SDL_SCANCODE_LEFT, + /* 38, 0x26 */ SDL_SCANCODE_UP, + /* 39, 0x27 */ SDL_SCANCODE_RIGHT, + /* 40, 0x28 */ SDL_SCANCODE_DOWN, + /* 41, 0x29 */ SDL_SCANCODE_SELECT, + /* 42, 0x2a */ SDL_SCANCODE_UNKNOWN, /* VK_PRINT */ + /* 43, 0x2b */ SDL_SCANCODE_EXECUTE, + /* 44, 0x2c */ SDL_SCANCODE_PRINTSCREEN, + /* 45, 0x2d */ SDL_SCANCODE_INSERT, + /* 46, 0x2e */ SDL_SCANCODE_DELETE, + /* 47, 0x2f */ SDL_SCANCODE_HELP, + /* 48, 0x30 */ SDL_SCANCODE_0, + /* 49, 0x31 */ SDL_SCANCODE_1, + /* 50, 0x32 */ SDL_SCANCODE_2, + /* 51, 0x33 */ SDL_SCANCODE_3, + /* 52, 0x34 */ SDL_SCANCODE_4, + /* 53, 0x35 */ SDL_SCANCODE_5, + /* 54, 0x36 */ SDL_SCANCODE_6, + /* 55, 0x37 */ SDL_SCANCODE_7, + /* 56, 0x38 */ SDL_SCANCODE_8, + /* 57, 0x39 */ SDL_SCANCODE_9, + /* 58, 0x3a */ SDL_SCANCODE_UNKNOWN, + /* 59, 0x3b */ SDL_SCANCODE_UNKNOWN, + /* 60, 0x3c */ SDL_SCANCODE_UNKNOWN, + /* 61, 0x3d */ SDL_SCANCODE_UNKNOWN, + /* 62, 0x3e */ SDL_SCANCODE_UNKNOWN, + /* 63, 0x3f */ SDL_SCANCODE_UNKNOWN, + /* 64, 0x40 */ SDL_SCANCODE_UNKNOWN, + /* 65, 0x41 */ SDL_SCANCODE_A, + /* 66, 0x42 */ SDL_SCANCODE_B, + /* 67, 0x43 */ SDL_SCANCODE_C, + /* 68, 0x44 */ SDL_SCANCODE_D, + /* 69, 0x45 */ SDL_SCANCODE_E, + /* 70, 0x46 */ SDL_SCANCODE_F, + /* 71, 0x47 */ SDL_SCANCODE_G, + /* 72, 0x48 */ SDL_SCANCODE_H, + /* 73, 0x49 */ SDL_SCANCODE_I, + /* 74, 0x4a */ SDL_SCANCODE_J, + /* 75, 0x4b */ SDL_SCANCODE_K, + /* 76, 0x4c */ SDL_SCANCODE_L, + /* 77, 0x4d */ SDL_SCANCODE_M, + /* 78, 0x4e */ SDL_SCANCODE_N, + /* 79, 0x4f */ SDL_SCANCODE_O, + /* 80, 0x50 */ SDL_SCANCODE_P, + /* 81, 0x51 */ SDL_SCANCODE_Q, + /* 82, 0x52 */ SDL_SCANCODE_R, + /* 83, 0x53 */ SDL_SCANCODE_S, + /* 84, 0x54 */ SDL_SCANCODE_T, + /* 85, 0x55 */ SDL_SCANCODE_U, + /* 86, 0x56 */ SDL_SCANCODE_V, + /* 87, 0x57 */ SDL_SCANCODE_W, + /* 88, 0x58 */ SDL_SCANCODE_X, + /* 89, 0x59 */ SDL_SCANCODE_Y, + /* 90, 0x5a */ SDL_SCANCODE_Z, + /* 91, 0x5b */ SDL_SCANCODE_LGUI, + /* 92, 0x5c */ SDL_SCANCODE_RGUI, + /* 93, 0x5d */ SDL_SCANCODE_APPLICATION, + /* 94, 0x5e */ SDL_SCANCODE_UNKNOWN, + /* 95, 0x5f */ SDL_SCANCODE_UNKNOWN, + /* 96, 0x60 */ SDL_SCANCODE_KP_0, + /* 97, 0x61 */ SDL_SCANCODE_KP_1, + /* 98, 0x62 */ SDL_SCANCODE_KP_2, + /* 99, 0x63 */ SDL_SCANCODE_KP_3, + /* 100, 0x64 */ SDL_SCANCODE_KP_4, + /* 101, 0x65 */ SDL_SCANCODE_KP_5, + /* 102, 0x66 */ SDL_SCANCODE_KP_6, + /* 103, 0x67 */ SDL_SCANCODE_KP_7, + /* 104, 0x68 */ SDL_SCANCODE_KP_8, + /* 105, 0x69 */ SDL_SCANCODE_KP_9, + /* 106, 0x6a */ SDL_SCANCODE_KP_MULTIPLY, + /* 107, 0x6b */ SDL_SCANCODE_KP_PLUS, + /* 108, 0x6c */ SDL_SCANCODE_SEPARATOR, + /* 109, 0x6d */ SDL_SCANCODE_KP_MINUS, + /* 110, 0x6e */ SDL_SCANCODE_KP_DECIMAL, + /* 111, 0x6f */ SDL_SCANCODE_KP_DIVIDE, + /* 112, 0x70 */ SDL_SCANCODE_F1, + /* 113, 0x71 */ SDL_SCANCODE_F2, + /* 114, 0x72 */ SDL_SCANCODE_F3, + /* 115, 0x73 */ SDL_SCANCODE_F4, + /* 116, 0x74 */ SDL_SCANCODE_F5, + /* 117, 0x75 */ SDL_SCANCODE_F6, + /* 118, 0x76 */ SDL_SCANCODE_F7, + /* 119, 0x77 */ SDL_SCANCODE_F8, + /* 120, 0x78 */ SDL_SCANCODE_F9, + /* 121, 0x79 */ SDL_SCANCODE_F10, + /* 122, 0x7a */ SDL_SCANCODE_F11, + /* 123, 0x7b */ SDL_SCANCODE_F12, + /* 124, 0x7c */ SDL_SCANCODE_F13, + /* 125, 0x7d */ SDL_SCANCODE_F14, + /* 126, 0x7e */ SDL_SCANCODE_F15, + /* 127, 0x7f */ SDL_SCANCODE_F16, + /* 128, 0x80 */ SDL_SCANCODE_F17, /* or SDL_SCANCODE_AUDIONEXT */ + /* 129, 0x81 */ SDL_SCANCODE_F18, /* or SDL_SCANCODE_AUDIOPREV */ + /* 130, 0x82 */ SDL_SCANCODE_F19, /* or SDL_SCANCODE_AUDIOSTOP */ + /* 131, 0x83 */ SDL_SCANCODE_F20, /* or SDL_SCANCODE_AUDIOPLAY */ + /* 132, 0x84 */ SDL_SCANCODE_F21, /* or SDL_SCANCODE_MAIL */ + /* 133, 0x85 */ SDL_SCANCODE_F22, /* or SDL_SCANCODE_MEDIASELECT */ + /* 134, 0x86 */ SDL_SCANCODE_F23, /* or SDL_SCANCODE_WWW */ + /* 135, 0x87 */ SDL_SCANCODE_F24, /* or SDL_SCANCODE_CALCULATOR */ + /* 136, 0x88 */ SDL_SCANCODE_UNKNOWN, + /* 137, 0x89 */ SDL_SCANCODE_UNKNOWN, + /* 138, 0x8a */ SDL_SCANCODE_UNKNOWN, + /* 139, 0x8b */ SDL_SCANCODE_UNKNOWN, + /* 140, 0x8c */ SDL_SCANCODE_UNKNOWN, + /* 141, 0x8d */ SDL_SCANCODE_UNKNOWN, + /* 142, 0x8e */ SDL_SCANCODE_UNKNOWN, + /* 143, 0x8f */ SDL_SCANCODE_UNKNOWN, + /* 144, 0x90 */ SDL_SCANCODE_NUMLOCKCLEAR, + /* 145, 0x91 */ SDL_SCANCODE_SCROLLLOCK, + /* 146, 0x92 */ SDL_SCANCODE_KP_EQUALS, + /* 147, 0x93 */ SDL_SCANCODE_UNKNOWN, + /* 148, 0x94 */ SDL_SCANCODE_UNKNOWN, + /* 149, 0x95 */ SDL_SCANCODE_UNKNOWN, + /* 150, 0x96 */ SDL_SCANCODE_UNKNOWN, + /* 151, 0x97 */ SDL_SCANCODE_UNKNOWN, + /* 152, 0x98 */ SDL_SCANCODE_UNKNOWN, + /* 153, 0x99 */ SDL_SCANCODE_UNKNOWN, + /* 154, 0x9a */ SDL_SCANCODE_UNKNOWN, + /* 155, 0x9b */ SDL_SCANCODE_UNKNOWN, + /* 156, 0x9c */ SDL_SCANCODE_UNKNOWN, + /* 157, 0x9d */ SDL_SCANCODE_UNKNOWN, + /* 158, 0x9e */ SDL_SCANCODE_UNKNOWN, + /* 159, 0x9f */ SDL_SCANCODE_UNKNOWN, + /* 160, 0xa0 */ SDL_SCANCODE_LSHIFT, + /* 161, 0xa1 */ SDL_SCANCODE_RSHIFT, + /* 162, 0xa2 */ SDL_SCANCODE_LCTRL, + /* 163, 0xa3 */ SDL_SCANCODE_RCTRL, + /* 164, 0xa4 */ SDL_SCANCODE_LALT, + /* 165, 0xa5 */ SDL_SCANCODE_RALT, + /* 166, 0xa6 */ SDL_SCANCODE_AC_BACK, + /* 167, 0xa7 */ SDL_SCANCODE_AC_FORWARD, + /* 168, 0xa8 */ SDL_SCANCODE_AC_REFRESH, + /* 169, 0xa9 */ SDL_SCANCODE_AC_STOP, + /* 170, 0xaa */ SDL_SCANCODE_AC_SEARCH, + /* 171, 0xab */ SDL_SCANCODE_AC_BOOKMARKS, + /* 172, 0xac */ SDL_SCANCODE_AC_HOME, + /* 173, 0xad */ SDL_SCANCODE_AUDIOMUTE, + /* 174, 0xae */ SDL_SCANCODE_VOLUMEDOWN, + /* 175, 0xaf */ SDL_SCANCODE_VOLUMEUP, + /* 176, 0xb0 */ SDL_SCANCODE_AUDIONEXT, + /* 177, 0xb1 */ SDL_SCANCODE_AUDIOPREV, + /* 178, 0xb2 */ SDL_SCANCODE_AUDIOSTOP, + /* 179, 0xb3 */ SDL_SCANCODE_AUDIOPLAY, + /* 180, 0xb4 */ SDL_SCANCODE_MAIL, + /* 181, 0xb5 */ SDL_SCANCODE_MEDIASELECT, + /* 182, 0xb6 */ SDL_SCANCODE_UNKNOWN, /* VK_LAUNCH_APP1 */ + /* 183, 0xb7 */ SDL_SCANCODE_UNKNOWN, /* VK_LAUNCH_APP2 */ + /* 184, 0xb8 */ SDL_SCANCODE_UNKNOWN, + /* 185, 0xb9 */ SDL_SCANCODE_UNKNOWN, + /* 186, 0xba */ SDL_SCANCODE_SEMICOLON, + /* 187, 0xbb */ SDL_SCANCODE_EQUALS, + /* 188, 0xbc */ SDL_SCANCODE_COMMA, + /* 189, 0xbd */ SDL_SCANCODE_MINUS, + /* 190, 0xbe */ SDL_SCANCODE_PERIOD, + /* 191, 0xbf */ SDL_SCANCODE_SLASH, + /* 192, 0xc0 */ SDL_SCANCODE_GRAVE, + /* 193, 0xc1 */ SDL_SCANCODE_UNKNOWN, + /* 194, 0xc2 */ SDL_SCANCODE_UNKNOWN, + /* 195, 0xc3 */ SDL_SCANCODE_UNKNOWN, + /* 196, 0xc4 */ SDL_SCANCODE_UNKNOWN, + /* 197, 0xc5 */ SDL_SCANCODE_UNKNOWN, + /* 198, 0xc6 */ SDL_SCANCODE_UNKNOWN, + /* 199, 0xc7 */ SDL_SCANCODE_UNKNOWN, + /* 200, 0xc8 */ SDL_SCANCODE_UNKNOWN, + /* 201, 0xc9 */ SDL_SCANCODE_UNKNOWN, + /* 202, 0xca */ SDL_SCANCODE_UNKNOWN, + /* 203, 0xcb */ SDL_SCANCODE_UNKNOWN, + /* 204, 0xcc */ SDL_SCANCODE_UNKNOWN, + /* 205, 0xcd */ SDL_SCANCODE_UNKNOWN, + /* 206, 0xce */ SDL_SCANCODE_UNKNOWN, + /* 207, 0xcf */ SDL_SCANCODE_UNKNOWN, + /* 208, 0xd0 */ SDL_SCANCODE_UNKNOWN, + /* 209, 0xd1 */ SDL_SCANCODE_UNKNOWN, + /* 210, 0xd2 */ SDL_SCANCODE_UNKNOWN, + /* 211, 0xd3 */ SDL_SCANCODE_UNKNOWN, + /* 212, 0xd4 */ SDL_SCANCODE_UNKNOWN, + /* 213, 0xd5 */ SDL_SCANCODE_UNKNOWN, + /* 214, 0xd6 */ SDL_SCANCODE_UNKNOWN, + /* 215, 0xd7 */ SDL_SCANCODE_UNKNOWN, + /* 216, 0xd8 */ SDL_SCANCODE_UNKNOWN, + /* 217, 0xd9 */ SDL_SCANCODE_UNKNOWN, + /* 218, 0xda */ SDL_SCANCODE_UNKNOWN, + /* 219, 0xdb */ SDL_SCANCODE_LEFTBRACKET, + /* 220, 0xdc */ SDL_SCANCODE_BACKSLASH, + /* 221, 0xdd */ SDL_SCANCODE_RIGHTBRACKET, + /* 222, 0xde */ SDL_SCANCODE_APOSTROPHE, + /* 223, 0xdf */ SDL_SCANCODE_UNKNOWN, + /* 224, 0xe0 */ SDL_SCANCODE_UNKNOWN, + /* 225, 0xe1 */ SDL_SCANCODE_UNKNOWN, + /* 226, 0xe2 */ SDL_SCANCODE_NONUSBACKSLASH, + /* 227, 0xe3 */ SDL_SCANCODE_UNKNOWN, + /* 228, 0xe4 */ SDL_SCANCODE_UNKNOWN, + /* 229, 0xe5 */ SDL_SCANCODE_UNKNOWN, + /* 230, 0xe6 */ SDL_SCANCODE_UNKNOWN, + /* 231, 0xe7 */ SDL_SCANCODE_UNKNOWN, + /* 232, 0xe8 */ SDL_SCANCODE_UNKNOWN, + /* 233, 0xe9 */ SDL_SCANCODE_UNKNOWN, + /* 234, 0xea */ SDL_SCANCODE_UNKNOWN, + /* 235, 0xeb */ SDL_SCANCODE_UNKNOWN, + /* 236, 0xec */ SDL_SCANCODE_UNKNOWN, + /* 237, 0xed */ SDL_SCANCODE_UNKNOWN, + /* 238, 0xee */ SDL_SCANCODE_UNKNOWN, + /* 239, 0xef */ SDL_SCANCODE_UNKNOWN, + /* 240, 0xf0 */ SDL_SCANCODE_UNKNOWN, + /* 241, 0xf1 */ SDL_SCANCODE_UNKNOWN, + /* 242, 0xf2 */ SDL_SCANCODE_UNKNOWN, + /* 243, 0xf3 */ SDL_SCANCODE_UNKNOWN, + /* 244, 0xf4 */ SDL_SCANCODE_UNKNOWN, + /* 245, 0xf5 */ SDL_SCANCODE_UNKNOWN, + /* 246, 0xf6 */ SDL_SCANCODE_SYSREQ, + /* 247, 0xf7 */ SDL_SCANCODE_CRSEL, + /* 248, 0xf8 */ SDL_SCANCODE_EXSEL, + /* 249, 0xf9 */ SDL_SCANCODE_UNKNOWN, /* VK_EREOF */ + /* 250, 0xfa */ SDL_SCANCODE_UNKNOWN, /* VK_PLAY */ + /* 251, 0xfb */ SDL_SCANCODE_UNKNOWN, /* VK_ZOOM */ + /* 252, 0xfc */ SDL_SCANCODE_UNKNOWN, + /* 253, 0xfd */ SDL_SCANCODE_UNKNOWN, /* VK_PA1 */ + /* 254, 0xfe */ SDL_SCANCODE_CLEAR, + /* 255, 0xff */ SDL_SCANCODE_UNKNOWN, +}; +/* *INDENT-ON* */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/file/SDL_rwops.c --- a/src/file/SDL_rwops.c Thu Jan 20 17:33:06 2011 -0800 +++ b/src/file/SDL_rwops.c Thu Jan 20 18:04:05 2011 -0800 @@ -37,7 +37,7 @@ #include #endif /* __NDS__ */ -#ifdef __WIN32__ +#ifdef __WINDOWS__ /* Functions to read/write Win32 API file pointers */ /* Will not use it on WinCE because stdio is buffered, it means @@ -54,7 +54,7 @@ #define READAHEAD_BUFFER_SIZE 1024 static int SDLCALL -win32_file_open(SDL_RWops * context, const char *filename, const char *mode) +windows_file_open(SDL_RWops * context, const char *filename, const char *mode) { #ifndef _WIN32_WCE UINT old_error_mode; @@ -67,10 +67,10 @@ if (!context) return -1; /* failed (invalid call) */ - context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* mark this as unusable */ - context->hidden.win32io.buffer.data = NULL; - context->hidden.win32io.buffer.size = 0; - context->hidden.win32io.buffer.left = 0; + context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* mark this as unusable */ + context->hidden.windowsio.buffer.data = NULL; + context->hidden.windowsio.buffer.size = 0; + context->hidden.windowsio.buffer.left = 0; /* "r" = reading, file must exist */ /* "w" = writing, truncate existing, file may not exist */ @@ -90,9 +90,9 @@ if (!r_right && !w_right) /* inconsistent mode */ return -1; /* failed (invalid call) */ - context->hidden.win32io.buffer.data = + context->hidden.windowsio.buffer.data = (char *) SDL_malloc(READAHEAD_BUFFER_SIZE); - if (!context->hidden.win32io.buffer.data) { + if (!context->hidden.windowsio.buffer.data) { SDL_OutOfMemory(); return -1; } @@ -104,8 +104,8 @@ if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, size) == 0) { SDL_stack_free(filenameW); - SDL_free(context->hidden.win32io.buffer.data); - context->hidden.win32io.buffer.data = NULL; + SDL_free(context->hidden.windowsio.buffer.data); + context->hidden.windowsio.buffer.data = NULL; SDL_SetError("Unable to convert filename to Unicode"); return -1; } @@ -130,51 +130,51 @@ #endif /* _WIN32_WCE */ if (h == INVALID_HANDLE_VALUE) { - SDL_free(context->hidden.win32io.buffer.data); - context->hidden.win32io.buffer.data = NULL; + SDL_free(context->hidden.windowsio.buffer.data); + context->hidden.windowsio.buffer.data = NULL; SDL_SetError("Couldn't open %s", filename); return -2; /* failed (CreateFile) */ } - context->hidden.win32io.h = h; - context->hidden.win32io.append = a_mode ? SDL_TRUE : SDL_FALSE; + context->hidden.windowsio.h = h; + context->hidden.windowsio.append = a_mode ? SDL_TRUE : SDL_FALSE; return 0; /* ok */ } static long SDLCALL -win32_file_seek(SDL_RWops * context, long offset, int whence) +windows_file_seek(SDL_RWops * context, long offset, int whence) { - DWORD win32whence; + DWORD windowswhence; long file_pos; - if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE) { - SDL_SetError("win32_file_seek: invalid context/file not opened"); + if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE) { + SDL_SetError("windows_file_seek: invalid context/file not opened"); return -1; } /* FIXME: We may be able to satisfy the seek within buffered data */ - if (whence == RW_SEEK_CUR && context->hidden.win32io.buffer.left) { - offset -= (long)context->hidden.win32io.buffer.left; + if (whence == RW_SEEK_CUR && context->hidden.windowsio.buffer.left) { + offset -= (long)context->hidden.windowsio.buffer.left; } - context->hidden.win32io.buffer.left = 0; + context->hidden.windowsio.buffer.left = 0; switch (whence) { case RW_SEEK_SET: - win32whence = FILE_BEGIN; + windowswhence = FILE_BEGIN; break; case RW_SEEK_CUR: - win32whence = FILE_CURRENT; + windowswhence = FILE_CURRENT; break; case RW_SEEK_END: - win32whence = FILE_END; + windowswhence = FILE_END; break; default: - SDL_SetError("win32_file_seek: Unknown value for 'whence'"); + SDL_SetError("windows_file_seek: Unknown value for 'whence'"); return -1; } file_pos = - SetFilePointer(context->hidden.win32io.h, offset, NULL, win32whence); + SetFilePointer(context->hidden.windowsio.h, offset, NULL, windowswhence); if (file_pos != INVALID_SET_FILE_POINTER) return file_pos; /* success */ @@ -184,7 +184,7 @@ } static size_t SDLCALL -win32_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum) +windows_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum) { size_t total_need; size_t total_read = 0; @@ -193,18 +193,18 @@ total_need = size * maxnum; - if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE + if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE || !total_need) return 0; - if (context->hidden.win32io.buffer.left > 0) { - void *data = (char *) context->hidden.win32io.buffer.data + - context->hidden.win32io.buffer.size - - context->hidden.win32io.buffer.left; + if (context->hidden.windowsio.buffer.left > 0) { + void *data = (char *) context->hidden.windowsio.buffer.data + + context->hidden.windowsio.buffer.size - + context->hidden.windowsio.buffer.left; read_ahead = - SDL_min(total_need, context->hidden.win32io.buffer.left); + SDL_min(total_need, context->hidden.windowsio.buffer.left); SDL_memcpy(ptr, data, read_ahead); - context->hidden.win32io.buffer.left -= read_ahead; + context->hidden.windowsio.buffer.left -= read_ahead; if (read_ahead == total_need) { return maxnum; @@ -216,19 +216,19 @@ if (total_need < READAHEAD_BUFFER_SIZE) { if (!ReadFile - (context->hidden.win32io.h, context->hidden.win32io.buffer.data, + (context->hidden.windowsio.h, context->hidden.windowsio.buffer.data, READAHEAD_BUFFER_SIZE, &byte_read, NULL)) { SDL_Error(SDL_EFREAD); return 0; } read_ahead = SDL_min(total_need, (int) byte_read); - SDL_memcpy(ptr, context->hidden.win32io.buffer.data, read_ahead); - context->hidden.win32io.buffer.size = byte_read; - context->hidden.win32io.buffer.left = byte_read - read_ahead; + SDL_memcpy(ptr, context->hidden.windowsio.buffer.data, read_ahead); + context->hidden.windowsio.buffer.size = byte_read; + context->hidden.windowsio.buffer.left = byte_read - read_ahead; total_read += read_ahead; } else { if (!ReadFile - (context->hidden.win32io.h, ptr, (DWORD)total_need, &byte_read, NULL)) { + (context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) { SDL_Error(SDL_EFREAD); return 0; } @@ -238,7 +238,7 @@ } static size_t SDLCALL -win32_file_write(SDL_RWops * context, const void *ptr, size_t size, +windows_file_write(SDL_RWops * context, const void *ptr, size_t size, size_t num) { @@ -248,20 +248,20 @@ total_bytes = size * num; - if (!context || context->hidden.win32io.h == INVALID_HANDLE_VALUE + if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE || total_bytes <= 0 || !size) return 0; - if (context->hidden.win32io.buffer.left) { - SetFilePointer(context->hidden.win32io.h, - -(LONG)context->hidden.win32io.buffer.left, NULL, + if (context->hidden.windowsio.buffer.left) { + SetFilePointer(context->hidden.windowsio.h, + -(LONG)context->hidden.windowsio.buffer.left, NULL, FILE_CURRENT); - context->hidden.win32io.buffer.left = 0; + context->hidden.windowsio.buffer.left = 0; } /* if in append mode, we must go to the EOF before write */ - if (context->hidden.win32io.append) { - if (SetFilePointer(context->hidden.win32io.h, 0L, NULL, FILE_END) == + if (context->hidden.windowsio.append) { + if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) == INVALID_SET_FILE_POINTER) { SDL_Error(SDL_EFWRITE); return 0; @@ -269,7 +269,7 @@ } if (!WriteFile - (context->hidden.win32io.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) { + (context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) { SDL_Error(SDL_EFWRITE); return 0; } @@ -279,23 +279,23 @@ } static int SDLCALL -win32_file_close(SDL_RWops * context) +windows_file_close(SDL_RWops * context) { if (context) { - if (context->hidden.win32io.h != INVALID_HANDLE_VALUE) { - CloseHandle(context->hidden.win32io.h); - context->hidden.win32io.h = INVALID_HANDLE_VALUE; /* to be sure */ + if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) { + CloseHandle(context->hidden.windowsio.h); + context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* to be sure */ } - if (context->hidden.win32io.buffer.data) { - SDL_free(context->hidden.win32io.buffer.data); - context->hidden.win32io.buffer.data = NULL; + if (context->hidden.windowsio.buffer.data) { + SDL_free(context->hidden.windowsio.buffer.data); + context->hidden.windowsio.buffer.data = NULL; } SDL_FreeRW(context); } return (0); } -#endif /* __WIN32__ */ +#endif /* __WINDOWS__ */ #ifdef HAVE_STDIO_H @@ -449,18 +449,18 @@ SDL_SetError("SDL_RWFromFile(): No file or no mode specified"); return NULL; } -#if defined(__WIN32__) +#if defined(__WINDOWS__) rwops = SDL_AllocRW(); if (!rwops) return NULL; /* SDL_SetError already setup by SDL_AllocRW() */ - if (win32_file_open(rwops, file, mode) < 0) { + if (windows_file_open(rwops, file, mode) < 0) { SDL_FreeRW(rwops); return NULL; } - rwops->seek = win32_file_seek; - rwops->read = win32_file_read; - rwops->write = win32_file_write; - rwops->close = win32_file_close; + rwops->seek = windows_file_seek; + rwops->read = windows_file_read; + rwops->write = windows_file_write; + rwops->close = windows_file_close; #elif HAVE_STDIO_H #ifdef __APPLE__ diff -r 9e9940eae455 -r e8916fe9cfc8 src/haptic/win32/SDL_syshaptic.c --- a/src/haptic/win32/SDL_syshaptic.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1379 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 2008 Edgar Simo - - 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_HAPTIC_DINPUT - -#include "SDL_haptic.h" -#include "../SDL_syshaptic.h" -#include "SDL_joystick.h" -#include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */ -#include "../../joystick/win32/SDL_dxjoystick_c.h" /* For joystick hwdata */ - - -#define MAX_HAPTICS 32 - - -/* - * List of available haptic devices. - */ -static struct -{ - DIDEVICEINSTANCE instance; - SDL_Haptic *haptic; - DIDEVCAPS capabilities; -} SDL_hapticlist[MAX_HAPTICS]; - - -/* - * Haptic system hardware data. - */ -struct haptic_hwdata -{ - LPDIRECTINPUTDEVICE2 device; - DWORD axes[3]; /* Axes to use. */ - int is_joystick; /* Device is loaded as joystick. */ -}; - - -/* - * Haptic system effect data. - */ -struct haptic_hweffect -{ - DIEFFECT effect; - LPDIRECTINPUTEFFECT ref; -}; - - -/* - * Internal stuff. - */ -static LPDIRECTINPUT dinput = NULL; - - -/* - * External stuff. - */ -extern HWND SDL_HelperWindow; - - -/* - * Prototypes. - */ -static void DI_SetError(const char *str, HRESULT err); -static int DI_GUIDIsSame(const GUID * a, const GUID * b); -static int SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, - DIDEVICEINSTANCE instance); -static int SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, - LPDIRECTINPUTDEVICE2 device2); -static DWORD DIGetTriggerButton(Uint16 button); -static int SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, - int naxes); -static int SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, - SDL_HapticEffect * src); -static void SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type); -static REFGUID SDL_SYS_HapticEffectType(SDL_HapticEffect * effect); -/* Callbacks. */ -static BOOL CALLBACK EnumHapticsCallback(const DIDEVICEINSTANCE * - pdidInstance, VOID * pContext); -static BOOL CALLBACK DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv); - - -/* - * Like SDL_SetError but for DX error codes. - */ -static void -DI_SetError(const char *str, HRESULT err) -{ - /* - SDL_SetError("Haptic: %s - %s: %s", str, - DXGetErrorString8A(err), DXGetErrorDescription8A(err)); - */ - SDL_SetError("Haptic error %s", str); -} - - -/* - * Checks to see if two GUID are the same. - */ -static int -DI_GUIDIsSame(const GUID * a, const GUID * b) -{ - if (((a)->Data1 == (b)->Data1) && - ((a)->Data2 == (b)->Data2) && - ((a)->Data3 == (b)->Data3) && - (SDL_strcmp((a)->Data4, (b)->Data4) == 0)) - return 1; - return 0; -} - - -/* - * Initializes the haptic subsystem. - */ -int -SDL_SYS_HapticInit(void) -{ - HRESULT ret; - HINSTANCE instance; - - if (dinput != NULL) { /* Already open. */ - SDL_SetError("Haptic: SubSystem already open."); - return -1; - } - - /* Clear all the memory. */ - SDL_memset(SDL_hapticlist, 0, sizeof(SDL_hapticlist)); - - SDL_numhaptics = 0; - - ret = CoInitialize(NULL); - if (FAILED(ret)) { - DI_SetError("Coinitialize", ret); - return -1; - } - - ret = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, - &IID_IDirectInput, (LPVOID) & dinput); - if (FAILED(ret)) { - DI_SetError("CoCreateInstance", ret); - return -1; - } - - /* Because we used CoCreateInstance, we need to Initialize it, first. */ - instance = GetModuleHandle(NULL); - if (instance == NULL) { - SDL_SetError("GetModuleHandle() failed with error code %d.", - GetLastError()); - return -1; - } - ret = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION); - if (FAILED(ret)) { - DI_SetError("Initializing DirectInput device", ret); - return -1; - } - - /* Look for haptic devices. */ - ret = IDirectInput_EnumDevices(dinput, - 0, - EnumHapticsCallback, - NULL, - DIEDFL_FORCEFEEDBACK | - DIEDFL_ATTACHEDONLY); - if (FAILED(ret)) { - DI_SetError("Enumerating DirectInput devices", ret); - return -1; - } - - return SDL_numhaptics; -} - -/* - * Callback to find the haptic devices. - */ -static BOOL CALLBACK -EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) -{ - HRESULT ret; - LPDIRECTINPUTDEVICE device; - - /* Copy the instance over, useful for creating devices. */ - SDL_memcpy(&SDL_hapticlist[SDL_numhaptics].instance, pdidInstance, - sizeof(DIDEVICEINSTANCE)); - - /* Open the device */ - ret = IDirectInput_CreateDevice(dinput, &pdidInstance->guidInstance, - &device, NULL); - if (FAILED(ret)) { - /* DI_SetError("Creating DirectInput device",ret); */ - return DIENUM_CONTINUE; - } - - /* Get capabilities. */ - SDL_hapticlist[SDL_numhaptics].capabilities.dwSize = sizeof(DIDEVCAPS); - ret = IDirectInputDevice_GetCapabilities(device, - &SDL_hapticlist[SDL_numhaptics]. - capabilities); - if (FAILED(ret)) { - /* DI_SetError("Getting device capabilities",ret); */ - IDirectInputDevice_Release(device); - return DIENUM_CONTINUE; - } - - /* Close up device and count it. */ - IDirectInputDevice_Release(device); - SDL_numhaptics++; - - /* Watch out for hard limit. */ - if (SDL_numhaptics >= MAX_HAPTICS) - return DIENUM_STOP; - - return DIENUM_CONTINUE; -} - - -/* - * Return the name of a haptic device, does not need to be opened. - */ -const char * -SDL_SYS_HapticName(int index) -{ - return SDL_hapticlist[index].instance.tszProductName; -} - - -/* - * Callback to get all supported effects. - */ -#define EFFECT_TEST(e,s) \ -if (DI_GUIDIsSame(&pei->guid, &(e))) \ - haptic->supported |= (s) -static BOOL CALLBACK -DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv) -{ - /* Prepare the haptic device. */ - SDL_Haptic *haptic = (SDL_Haptic *) pv; - - /* Get supported. */ - EFFECT_TEST(GUID_Spring, SDL_HAPTIC_SPRING); - EFFECT_TEST(GUID_Damper, SDL_HAPTIC_DAMPER); - EFFECT_TEST(GUID_Inertia, SDL_HAPTIC_INERTIA); - EFFECT_TEST(GUID_Friction, SDL_HAPTIC_FRICTION); - EFFECT_TEST(GUID_ConstantForce, SDL_HAPTIC_CONSTANT); - EFFECT_TEST(GUID_CustomForce, SDL_HAPTIC_CUSTOM); - EFFECT_TEST(GUID_Sine, SDL_HAPTIC_SINE); - EFFECT_TEST(GUID_Square, SDL_HAPTIC_SQUARE); - EFFECT_TEST(GUID_Triangle, SDL_HAPTIC_TRIANGLE); - EFFECT_TEST(GUID_SawtoothUp, SDL_HAPTIC_SAWTOOTHUP); - EFFECT_TEST(GUID_SawtoothDown, SDL_HAPTIC_SAWTOOTHDOWN); - EFFECT_TEST(GUID_RampForce, SDL_HAPTIC_RAMP); - - /* Check for more. */ - return DIENUM_CONTINUE; -} - - -/* - * Callback to get supported axes. - */ -static BOOL CALLBACK -DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) -{ - SDL_Haptic *haptic = (SDL_Haptic *) pvRef; - - if ((dev->dwType & DIDFT_AXIS) && (dev->dwFlags & DIDOI_FFACTUATOR)) { - - haptic->hwdata->axes[haptic->naxes] = dev->dwOfs; - haptic->naxes++; - - /* Currently using the artificial limit of 3 axes. */ - if (haptic->naxes >= 3) { - return DIENUM_STOP; - } - } - - return DIENUM_CONTINUE; -} - - -/* - * Opens the haptic device from the file descriptor. - * - * Steps: - * - Open temporary DirectInputDevice interface. - * - Create DirectInputDevice2 interface. - * - Release DirectInputDevice interface. - * - Call SDL_SYS_HapticOpenFromDevice2 - */ -static int -SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance) -{ - HRESULT ret; - int ret2; - LPDIRECTINPUTDEVICE device; - - /* Allocate the hwdata */ - haptic->hwdata = (struct haptic_hwdata *) - SDL_malloc(sizeof(*haptic->hwdata)); - if (haptic->hwdata == NULL) { - SDL_OutOfMemory(); - goto creat_err; - } - SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); - - /* Open the device */ - ret = IDirectInput_CreateDevice(dinput, &instance.guidInstance, - &device, NULL); - if (FAILED(ret)) { - DI_SetError("Creating DirectInput device", ret); - goto creat_err; - } - - /* Now get the IDirectInputDevice2 interface, instead. */ - ret = IDirectInputDevice_QueryInterface(device, - &IID_IDirectInputDevice2, - (LPVOID *) & haptic->hwdata-> - device); - /* Done with the temporary one now. */ - IDirectInputDevice_Release(device); - if (FAILED(ret)) { - DI_SetError("Querying DirectInput interface", ret); - goto creat_err; - } - - ret2 = SDL_SYS_HapticOpenFromDevice2(haptic, haptic->hwdata->device); - if (ret2 < 0) { - goto query_err; - } - - return 0; - - query_err: - IDirectInputDevice2_Release(haptic->hwdata->device); - creat_err: - if (haptic->hwdata != NULL) { - SDL_free(haptic->hwdata); - haptic->hwdata = NULL; - } - return -1; -} - - -/* - * Opens the haptic device from the file descriptor. - * - * Steps: - * - Set cooperative level. - * - Set data format. - * - Acquire exclusiveness. - * - Reset actuators. - * - Get supported featuers. - */ -static int -SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, - LPDIRECTINPUTDEVICE2 device2) -{ - HRESULT ret; - DIPROPDWORD dipdw; - - /* We'll use the device2 from now on. */ - haptic->hwdata->device = device2; - - /* Grab it exclusively to use force feedback stuff. */ - ret = IDirectInputDevice2_SetCooperativeLevel(haptic->hwdata->device, - SDL_HelperWindow, - DISCL_EXCLUSIVE | - DISCL_BACKGROUND); - if (FAILED(ret)) { - DI_SetError("Setting cooperative level to exclusive", ret); - goto acquire_err; - } - - /* Set data format. */ - ret = IDirectInputDevice2_SetDataFormat(haptic->hwdata->device, - &c_dfDIJoystick2); - if (FAILED(ret)) { - DI_SetError("Setting data format", ret); - goto acquire_err; - } - - /* Get number of axes. */ - ret = IDirectInputDevice2_EnumObjects(haptic->hwdata->device, - DI_DeviceObjectCallback, - haptic, DIDFT_AXIS); - if (FAILED(ret)) { - DI_SetError("Getting device axes", ret); - goto acquire_err; - } - - /* Acquire the device. */ - ret = IDirectInputDevice2_Acquire(haptic->hwdata->device); - if (FAILED(ret)) { - DI_SetError("Acquiring DirectInput device", ret); - goto acquire_err; - } - - /* Reset all actuators - just in case. */ - ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, - DISFFC_RESET); - if (FAILED(ret)) { - DI_SetError("Resetting device", ret); - goto acquire_err; - } - - /* Enabling actuators. */ - ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, - DISFFC_SETACTUATORSON); - if (FAILED(ret)) { - DI_SetError("Enabling actuators", ret); - goto acquire_err; - } - - /* Get supported effects. */ - ret = IDirectInputDevice2_EnumEffects(haptic->hwdata->device, - DI_EffectCallback, haptic, - DIEFT_ALL); - if (FAILED(ret)) { - DI_SetError("Enumerating supported effects", ret); - goto acquire_err; - } - if (haptic->supported == 0) { /* Error since device supports nothing. */ - SDL_SetError("Haptic: Internal error on finding supported effects."); - goto acquire_err; - } - - /* Check autogain and autocenter. */ - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = 10000; - ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, - DIPROP_FFGAIN, &dipdw.diph); - if (!FAILED(ret)) { /* Gain is supported. */ - haptic->supported |= SDL_HAPTIC_GAIN; - } - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = DIPROPAUTOCENTER_OFF; - ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, - DIPROP_AUTOCENTER, &dipdw.diph); - if (!FAILED(ret)) { /* Autocenter is supported. */ - haptic->supported |= SDL_HAPTIC_AUTOCENTER; - } - - /* Status is always supported. */ - haptic->supported |= SDL_HAPTIC_STATUS | SDL_HAPTIC_PAUSE; - - /* Check maximum effects. */ - haptic->neffects = 128; /* This is not actually supported as thus under windows, - there is no way to tell the number of EFFECTS that a - device can hold, so we'll just use a "random" number - instead and put warnings in SDL_haptic.h */ - haptic->nplaying = 128; /* Even more impossible to get this then neffects. */ - - /* Prepare effects memory. */ - haptic->effects = (struct haptic_effect *) - SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); - if (haptic->effects == NULL) { - SDL_OutOfMemory(); - goto acquire_err; - } - /* Clear the memory */ - SDL_memset(haptic->effects, 0, - sizeof(struct haptic_effect) * haptic->neffects); - - return 0; - - /* Error handling */ - acquire_err: - IDirectInputDevice2_Unacquire(haptic->hwdata->device); - return -1; - -} - - -/* - * Opens a haptic device for usage. - */ -int -SDL_SYS_HapticOpen(SDL_Haptic * haptic) -{ - return SDL_SYS_HapticOpenFromInstance(haptic, - SDL_hapticlist[haptic->index]. - instance); -} - - -/* - * Opens a haptic device from first mouse it finds for usage. - */ -int -SDL_SYS_HapticMouse(void) -{ - int i; - - /* Grab the first mouse haptic device we find. */ - for (i = 0; i < SDL_numhaptics; i++) { - if (SDL_hapticlist[i].capabilities.dwDevType == DIDEVTYPE_MOUSE) { - return i; - } - } - - return -1; -} - - -/* - * Checks to see if a joystick has haptic features. - */ -int -SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) -{ - if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { - return SDL_TRUE; - } - - return SDL_FALSE; -} - - -/* - * Checks to see if the haptic device and joystick and in reality the same. - */ -int -SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) -{ - HRESULT ret; - DIDEVICEINSTANCE hap_instance, joy_instance; - - /* Get the device instances. */ - ret = IDirectInputDevice2_GetDeviceInfo(haptic->hwdata->device, - &hap_instance); - if (FAILED(ret)) { - return 0; - } - ret = IDirectInputDevice2_GetDeviceInfo(joystick->hwdata->InputDevice, - &joy_instance); - if (FAILED(ret)) { - return 0; - } - - if (DI_GUIDIsSame(&hap_instance.guidInstance, &joy_instance.guidInstance)) - return 1; - - return 0; -} - - -/* - * Opens a SDL_Haptic from a SDL_Joystick. - */ -int -SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) -{ - int ret; - - /* Allocate the hwdata */ - haptic->hwdata = (struct haptic_hwdata *) - SDL_malloc(sizeof(*haptic->hwdata)); - if (haptic->hwdata == NULL) { - SDL_OutOfMemory(); - return -1; - } - SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); - - /* Now open the device. */ - ret = - SDL_SYS_HapticOpenFromDevice2(haptic, joystick->hwdata->InputDevice); - if (ret < 0) { - return -1; - } - - /* It's using the joystick device. */ - haptic->hwdata->is_joystick = 1; - - return 0; -} - - -/* - * Closes the haptic device. - */ -void -SDL_SYS_HapticClose(SDL_Haptic * haptic) -{ - if (haptic->hwdata) { - - /* Free effects. */ - SDL_free(haptic->effects); - haptic->effects = NULL; - haptic->neffects = 0; - - /* Clean up */ - IDirectInputDevice2_Unacquire(haptic->hwdata->device); - /* Only release if isn't grabbed by a joystick. */ - if (haptic->hwdata->is_joystick == 0) { - IDirectInputDevice2_Release(haptic->hwdata->device); - } - - /* Free */ - SDL_free(haptic->hwdata); - haptic->hwdata = NULL; - } -} - - -/* - * Clean up after system specific haptic stuff - */ -void -SDL_SYS_HapticQuit(void) -{ - IDirectInput_Release(dinput); - dinput = NULL; -} - - -/* - * Converts an SDL trigger button to an DIEFFECT trigger button. - */ -static DWORD -DIGetTriggerButton(Uint16 button) -{ - DWORD dwTriggerButton; - - dwTriggerButton = DIEB_NOTRIGGER; - - if (button != 0) { - dwTriggerButton = DIJOFS_BUTTON(button - 1); - } - - return dwTriggerButton; -} - - -/* - * Sets the direction. - */ -static int -SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, int naxes) -{ - LONG *rglDir; - - /* Handle no axes a part. */ - if (naxes == 0) { - effect->dwFlags |= DIEFF_SPHERICAL; /* Set as default. */ - effect->rglDirection = NULL; - return 0; - } - - /* Has axes. */ - rglDir = SDL_malloc(sizeof(LONG) * naxes); - if (rglDir == NULL) { - SDL_OutOfMemory(); - return -1; - } - SDL_memset(rglDir, 0, sizeof(LONG) * naxes); - effect->rglDirection = rglDir; - - switch (dir->type) { - case SDL_HAPTIC_POLAR: - effect->dwFlags |= DIEFF_POLAR; - rglDir[0] = dir->dir[0]; - return 0; - case SDL_HAPTIC_CARTESIAN: - effect->dwFlags |= DIEFF_CARTESIAN; - rglDir[0] = dir->dir[0]; - if (naxes > 1) - rglDir[1] = dir->dir[1]; - if (naxes > 2) - rglDir[2] = dir->dir[2]; - return 0; - case SDL_HAPTIC_SPHERICAL: - effect->dwFlags |= DIEFF_SPHERICAL; - rglDir[0] = dir->dir[0]; - if (naxes > 1) - rglDir[1] = dir->dir[1]; - if (naxes > 2) - rglDir[2] = dir->dir[2]; - return 0; - - default: - SDL_SetError("Haptic: Unknown direction type."); - return -1; - } -} - -#define CONVERT(x) (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF) -/* - * Creates the DIEFFECT from a SDL_HapticEffect. - */ -static int -SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, - SDL_HapticEffect * src) -{ - int i; - DICONSTANTFORCE *constant; - DIPERIODIC *periodic; - DICONDITION *condition; /* Actually an array of conditions - one per axis. */ - DIRAMPFORCE *ramp; - DICUSTOMFORCE *custom; - DIENVELOPE *envelope; - SDL_HapticConstant *hap_constant; - SDL_HapticPeriodic *hap_periodic; - SDL_HapticCondition *hap_condition; - SDL_HapticRamp *hap_ramp; - SDL_HapticCustom *hap_custom; - DWORD *axes; - - /* Set global stuff. */ - SDL_memset(dest, 0, sizeof(DIEFFECT)); - dest->dwSize = sizeof(DIEFFECT); /* Set the structure size. */ - dest->dwSamplePeriod = 0; /* Not used by us. */ - dest->dwGain = 10000; /* Gain is set globally, not locally. */ - dest->dwFlags = DIEFF_OBJECTOFFSETS; /* Seems obligatory. */ - - /* Envelope. */ - envelope = SDL_malloc(sizeof(DIENVELOPE)); - if (envelope == NULL) { - SDL_OutOfMemory(); - return -1; - } - SDL_memset(envelope, 0, sizeof(DIENVELOPE)); - dest->lpEnvelope = envelope; - envelope->dwSize = sizeof(DIENVELOPE); /* Always should be this. */ - - /* Axes. */ - dest->cAxes = haptic->naxes; - if (dest->cAxes > 0) { - axes = SDL_malloc(sizeof(DWORD) * dest->cAxes); - if (axes == NULL) { - SDL_OutOfMemory(); - return -1; - } - axes[0] = haptic->hwdata->axes[0]; /* Always at least one axis. */ - if (dest->cAxes > 1) { - axes[1] = haptic->hwdata->axes[1]; - } - if (dest->cAxes > 2) { - axes[2] = haptic->hwdata->axes[2]; - } - dest->rgdwAxes = axes; - } - - - /* The big type handling switch, even bigger then linux's version. */ - switch (src->type) { - case SDL_HAPTIC_CONSTANT: - hap_constant = &src->constant; - constant = SDL_malloc(sizeof(DICONSTANTFORCE)); - if (constant == NULL) { - SDL_OutOfMemory(); - return -1; - } - SDL_memset(constant, 0, sizeof(DICONSTANTFORCE)); - - /* Specifics */ - constant->lMagnitude = CONVERT(hap_constant->level); - dest->cbTypeSpecificParams = sizeof(DICONSTANTFORCE); - dest->lpvTypeSpecificParams = constant; - - /* Generics */ - dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */ - dest->dwTriggerButton = DIGetTriggerButton(hap_constant->button); - dest->dwTriggerRepeatInterval = hap_constant->interval; - dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */ - - /* Direction. */ - if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) - < 0) { - return -1; - } - - /* Envelope */ - if ((hap_constant->attack_length == 0) - && (hap_constant->fade_length == 0)) { - SDL_free(dest->lpEnvelope); - dest->lpEnvelope = NULL; - } else { - envelope->dwAttackLevel = CONVERT(hap_constant->attack_level); - envelope->dwAttackTime = hap_constant->attack_length * 1000; - envelope->dwFadeLevel = CONVERT(hap_constant->fade_level); - envelope->dwFadeTime = hap_constant->fade_length * 1000; - } - - break; - - case SDL_HAPTIC_SINE: - case SDL_HAPTIC_SQUARE: - case SDL_HAPTIC_TRIANGLE: - case SDL_HAPTIC_SAWTOOTHUP: - case SDL_HAPTIC_SAWTOOTHDOWN: - hap_periodic = &src->periodic; - periodic = SDL_malloc(sizeof(DIPERIODIC)); - if (periodic == NULL) { - SDL_OutOfMemory(); - return -1; - } - SDL_memset(periodic, 0, sizeof(DIPERIODIC)); - - /* Specifics */ - periodic->dwMagnitude = CONVERT(hap_periodic->magnitude); - periodic->lOffset = CONVERT(hap_periodic->offset); - periodic->dwPhase = hap_periodic->phase; - periodic->dwPeriod = hap_periodic->period * 1000; - dest->cbTypeSpecificParams = sizeof(DIPERIODIC); - dest->lpvTypeSpecificParams = periodic; - - /* Generics */ - dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */ - dest->dwTriggerButton = DIGetTriggerButton(hap_periodic->button); - dest->dwTriggerRepeatInterval = hap_periodic->interval; - dest->dwStartDelay = hap_periodic->delay * 1000; /* In microseconds. */ - - /* Direction. */ - if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes) - < 0) { - return -1; - } - - /* Envelope */ - if ((hap_periodic->attack_length == 0) - && (hap_periodic->fade_length == 0)) { - SDL_free(dest->lpEnvelope); - dest->lpEnvelope = NULL; - } else { - envelope->dwAttackLevel = CONVERT(hap_periodic->attack_level); - envelope->dwAttackTime = hap_periodic->attack_length * 1000; - envelope->dwFadeLevel = CONVERT(hap_periodic->fade_level); - envelope->dwFadeTime = hap_periodic->fade_length * 1000; - } - - break; - - case SDL_HAPTIC_SPRING: - case SDL_HAPTIC_DAMPER: - case SDL_HAPTIC_INERTIA: - case SDL_HAPTIC_FRICTION: - hap_condition = &src->condition; - condition = SDL_malloc(sizeof(DICONDITION) * dest->cAxes); - if (condition == NULL) { - SDL_OutOfMemory(); - return -1; - } - SDL_memset(condition, 0, sizeof(DICONDITION)); - - /* Specifics */ - for (i = 0; i < (int) dest->cAxes; i++) { - condition[i].lOffset = CONVERT(hap_condition->center[i]); - condition[i].lPositiveCoefficient = - CONVERT(hap_condition->right_coeff[i]); - condition[i].lNegativeCoefficient = - CONVERT(hap_condition->left_coeff[i]); - condition[i].dwPositiveSaturation = - CONVERT(hap_condition->right_sat[i]); - condition[i].dwNegativeSaturation = - CONVERT(hap_condition->left_sat[i]); - condition[i].lDeadBand = CONVERT(hap_condition->deadband[i]); - } - dest->cbTypeSpecificParams = sizeof(DICONDITION) * dest->cAxes; - dest->lpvTypeSpecificParams = condition; - - /* Generics */ - dest->dwDuration = hap_condition->length * 1000; /* In microseconds. */ - dest->dwTriggerButton = DIGetTriggerButton(hap_condition->button); - dest->dwTriggerRepeatInterval = hap_condition->interval; - dest->dwStartDelay = hap_condition->delay * 1000; /* In microseconds. */ - - /* Direction. */ - if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes) - < 0) { - return -1; - } - - /* Envelope - Not actually supported by most CONDITION implementations. */ - SDL_free(dest->lpEnvelope); - dest->lpEnvelope = NULL; - - break; - - case SDL_HAPTIC_RAMP: - hap_ramp = &src->ramp; - ramp = SDL_malloc(sizeof(DIRAMPFORCE)); - if (ramp == NULL) { - SDL_OutOfMemory(); - return -1; - } - SDL_memset(ramp, 0, sizeof(DIRAMPFORCE)); - - /* Specifics */ - ramp->lStart = CONVERT(hap_ramp->start); - ramp->lEnd = CONVERT(hap_ramp->end); - dest->cbTypeSpecificParams = sizeof(DIRAMPFORCE); - dest->lpvTypeSpecificParams = ramp; - - /* Generics */ - dest->dwDuration = hap_ramp->length * 1000; /* In microseconds. */ - dest->dwTriggerButton = DIGetTriggerButton(hap_ramp->button); - dest->dwTriggerRepeatInterval = hap_ramp->interval; - dest->dwStartDelay = hap_ramp->delay * 1000; /* In microseconds. */ - - /* Direction. */ - if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) { - return -1; - } - - /* Envelope */ - if ((hap_ramp->attack_length == 0) && (hap_ramp->fade_length == 0)) { - SDL_free(dest->lpEnvelope); - dest->lpEnvelope = NULL; - } else { - envelope->dwAttackLevel = CONVERT(hap_ramp->attack_level); - envelope->dwAttackTime = hap_ramp->attack_length * 1000; - envelope->dwFadeLevel = CONVERT(hap_ramp->fade_level); - envelope->dwFadeTime = hap_ramp->fade_length * 1000; - } - - break; - - case SDL_HAPTIC_CUSTOM: - hap_custom = &src->custom; - custom = SDL_malloc(sizeof(DICUSTOMFORCE)); - if (custom == NULL) { - SDL_OutOfMemory(); - return -1; - } - SDL_memset(custom, 0, sizeof(DICUSTOMFORCE)); - - /* Specifics */ - custom->cChannels = hap_custom->channels; - custom->dwSamplePeriod = hap_custom->period * 1000; - custom->cSamples = hap_custom->samples; - custom->rglForceData = - SDL_malloc(sizeof(LONG) * custom->cSamples * custom->cChannels); - for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) { /* Copy data. */ - custom->rglForceData[i] = CONVERT(hap_custom->data[i]); - } - dest->cbTypeSpecificParams = sizeof(DICUSTOMFORCE); - dest->lpvTypeSpecificParams = custom; - - /* Generics */ - dest->dwDuration = hap_custom->length * 1000; /* In microseconds. */ - dest->dwTriggerButton = DIGetTriggerButton(hap_custom->button); - dest->dwTriggerRepeatInterval = hap_custom->interval; - dest->dwStartDelay = hap_custom->delay * 1000; /* In microseconds. */ - - /* Direction. */ - if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) < - 0) { - return -1; - } - - /* Envelope */ - if ((hap_custom->attack_length == 0) - && (hap_custom->fade_length == 0)) { - SDL_free(dest->lpEnvelope); - dest->lpEnvelope = NULL; - } else { - envelope->dwAttackLevel = CONVERT(hap_custom->attack_level); - envelope->dwAttackTime = hap_custom->attack_length * 1000; - envelope->dwFadeLevel = CONVERT(hap_custom->fade_level); - envelope->dwFadeTime = hap_custom->fade_length * 1000; - } - - break; - - - default: - SDL_SetError("Haptic: Unknown effect type."); - return -1; - } - - return 0; -} - - -/* - * Frees an DIEFFECT allocated by SDL_SYS_ToDIEFFECT. - */ -static void -SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type) -{ - DICUSTOMFORCE *custom; - - if (effect->lpEnvelope != NULL) { - SDL_free(effect->lpEnvelope); - effect->lpEnvelope = NULL; - } - if (effect->rgdwAxes != NULL) { - SDL_free(effect->rgdwAxes); - effect->rgdwAxes = NULL; - } - if (effect->lpvTypeSpecificParams != NULL) { - if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */ - custom = (DICUSTOMFORCE *) effect->lpvTypeSpecificParams; - SDL_free(custom->rglForceData); - custom->rglForceData = NULL; - } - SDL_free(effect->lpvTypeSpecificParams); - effect->lpvTypeSpecificParams = NULL; - } - if (effect->rglDirection != NULL) { - SDL_free(effect->rglDirection); - effect->rglDirection = NULL; - } -} - - -/* - * Gets the effect type from the generic SDL haptic effect wrapper. - */ -static REFGUID -SDL_SYS_HapticEffectType(SDL_HapticEffect * effect) -{ - switch (effect->type) { - case SDL_HAPTIC_CONSTANT: - return &GUID_ConstantForce; - - case SDL_HAPTIC_RAMP: - return &GUID_RampForce; - - case SDL_HAPTIC_SQUARE: - return &GUID_Square; - - case SDL_HAPTIC_SINE: - return &GUID_Sine; - - case SDL_HAPTIC_TRIANGLE: - return &GUID_Triangle; - - case SDL_HAPTIC_SAWTOOTHUP: - return &GUID_SawtoothUp; - - case SDL_HAPTIC_SAWTOOTHDOWN: - return &GUID_SawtoothDown; - - case SDL_HAPTIC_SPRING: - return &GUID_Spring; - - case SDL_HAPTIC_DAMPER: - return &GUID_Damper; - - case SDL_HAPTIC_INERTIA: - return &GUID_Inertia; - - case SDL_HAPTIC_FRICTION: - return &GUID_Friction; - - case SDL_HAPTIC_CUSTOM: - return &GUID_CustomForce; - - default: - SDL_SetError("Haptic: Unknown effect type."); - return NULL; - } -} - - -/* - * Creates a new haptic effect. - */ -int -SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, - SDL_HapticEffect * base) -{ - HRESULT ret; - - /* Get the type. */ - REFGUID type = SDL_SYS_HapticEffectType(base); - if (type == NULL) { - goto err_hweffect; - } - - /* Alloc the effect. */ - effect->hweffect = (struct haptic_hweffect *) - SDL_malloc(sizeof(struct haptic_hweffect)); - if (effect->hweffect == NULL) { - SDL_OutOfMemory(); - goto err_hweffect; - } - - /* Get the effect. */ - if (SDL_SYS_ToDIEFFECT(haptic, &effect->hweffect->effect, base) < 0) { - goto err_effectdone; - } - - /* Create the actual effect. */ - ret = IDirectInputDevice2_CreateEffect(haptic->hwdata->device, type, - &effect->hweffect->effect, - &effect->hweffect->ref, NULL); - if (FAILED(ret)) { - DI_SetError("Unable to create effect", ret); - goto err_effectdone; - } - - return 0; - - err_effectdone: - SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, base->type); - err_hweffect: - if (effect->hweffect != NULL) { - SDL_free(effect->hweffect); - effect->hweffect = NULL; - } - return -1; -} - - -/* - * Updates an effect. - */ -int -SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, - struct haptic_effect *effect, - SDL_HapticEffect * data) -{ - HRESULT ret; - DWORD flags; - DIEFFECT temp; - - /* Get the effect. */ - SDL_memset(&temp, 0, sizeof(DIEFFECT)); - if (SDL_SYS_ToDIEFFECT(haptic, &temp, data) < 0) { - goto err_update; - } - - /* Set the flags. Might be worthwhile to diff temp with loaded effect and - * only change those parameters. */ - flags = DIEP_DIRECTION | - DIEP_DURATION | - DIEP_ENVELOPE | - DIEP_STARTDELAY | - DIEP_TRIGGERBUTTON | - DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS; - - /* Create the actual effect. */ - ret = - IDirectInputEffect_SetParameters(effect->hweffect->ref, &temp, flags); - if (FAILED(ret)) { - DI_SetError("Unable to update effect", ret); - goto err_update; - } - - /* Copy it over. */ - SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, data->type); - SDL_memcpy(&effect->hweffect->effect, &temp, sizeof(DIEFFECT)); - - return 0; - - err_update: - SDL_SYS_HapticFreeDIEFFECT(&temp, data->type); - return -1; -} - - -/* - * Runs an effect. - */ -int -SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, - Uint32 iterations) -{ - HRESULT ret; - DWORD iter; - - /* Check if it's infinite. */ - if (iterations == SDL_HAPTIC_INFINITY) { - iter = INFINITE; - } else - iter = iterations; - - /* Run the effect. */ - ret = IDirectInputEffect_Start(effect->hweffect->ref, iter, 0); - if (FAILED(ret)) { - DI_SetError("Running the effect", ret); - return -1; - } - - return 0; -} - - -/* - * Stops an effect. - */ -int -SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) -{ - HRESULT ret; - - ret = IDirectInputEffect_Stop(effect->hweffect->ref); - if (FAILED(ret)) { - DI_SetError("Unable to stop effect", ret); - return -1; - } - - return 0; -} - - -/* - * Frees the effect. - */ -void -SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) -{ - HRESULT ret; - - ret = IDirectInputEffect_Unload(effect->hweffect->ref); - if (FAILED(ret)) { - DI_SetError("Removing effect from the device", ret); - } - SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, - effect->effect.type); - SDL_free(effect->hweffect); - effect->hweffect = NULL; -} - - -/* - * Gets the status of a haptic effect. - */ -int -SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, - struct haptic_effect *effect) -{ - HRESULT ret; - DWORD status; - - ret = IDirectInputEffect_GetEffectStatus(effect->hweffect->ref, &status); - if (FAILED(ret)) { - DI_SetError("Getting effect status", ret); - return -1; - } - - if (status == 0) - return SDL_FALSE; - return SDL_TRUE; -} - - -/* - * Sets the gain. - */ -int -SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) -{ - HRESULT ret; - DIPROPDWORD dipdw; - - /* Create the weird structure thingy. */ - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = gain * 100; /* 0 to 10,000 */ - - /* Try to set the autocenter. */ - ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, - DIPROP_FFGAIN, &dipdw.diph); - if (FAILED(ret)) { - DI_SetError("Setting gain", ret); - return -1; - } - - return 0; -} - - -/* - * Sets the autocentering. - */ -int -SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) -{ - HRESULT ret; - DIPROPDWORD dipdw; - - /* Create the weird structure thingy. */ - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = (autocenter == 0) ? DIPROPAUTOCENTER_OFF : - DIPROPAUTOCENTER_ON; - - /* Try to set the autocenter. */ - ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, - DIPROP_AUTOCENTER, &dipdw.diph); - if (FAILED(ret)) { - DI_SetError("Setting autocenter", ret); - return -1; - } - - return 0; -} - - -/* - * Pauses the device. - */ -int -SDL_SYS_HapticPause(SDL_Haptic * haptic) -{ - HRESULT ret; - - /* Pause the device. */ - ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, - DISFFC_PAUSE); - if (FAILED(ret)) { - DI_SetError("Pausing the device", ret); - return -1; - } - - return 0; -} - - -/* - * Pauses the device. - */ -int -SDL_SYS_HapticUnpause(SDL_Haptic * haptic) -{ - HRESULT ret; - - /* Unpause the device. */ - ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, - DISFFC_CONTINUE); - if (FAILED(ret)) { - DI_SetError("Pausing the device", ret); - return -1; - } - - return 0; -} - - -/* - * Stops all the playing effects on the device. - */ -int -SDL_SYS_HapticStopAll(SDL_Haptic * haptic) -{ - HRESULT ret; - - /* Try to stop the effects. */ - ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, - DISFFC_STOPALL); - if (FAILED(ret)) { - DI_SetError("Stopping the device", ret); - return -1; - } - - return 0; -} - - -#endif /* SDL_HAPTIC_DINPUT */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/haptic/windows/SDL_syshaptic.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/haptic/windows/SDL_syshaptic.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,1379 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 2008 Edgar Simo + + 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_HAPTIC_DINPUT + +#include "SDL_haptic.h" +#include "../SDL_syshaptic.h" +#include "SDL_joystick.h" +#include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */ +#include "../../joystick/windows/SDL_dxjoystick_c.h" /* For joystick hwdata */ + + +#define MAX_HAPTICS 32 + + +/* + * List of available haptic devices. + */ +static struct +{ + DIDEVICEINSTANCE instance; + SDL_Haptic *haptic; + DIDEVCAPS capabilities; +} SDL_hapticlist[MAX_HAPTICS]; + + +/* + * Haptic system hardware data. + */ +struct haptic_hwdata +{ + LPDIRECTINPUTDEVICE2 device; + DWORD axes[3]; /* Axes to use. */ + int is_joystick; /* Device is loaded as joystick. */ +}; + + +/* + * Haptic system effect data. + */ +struct haptic_hweffect +{ + DIEFFECT effect; + LPDIRECTINPUTEFFECT ref; +}; + + +/* + * Internal stuff. + */ +static LPDIRECTINPUT dinput = NULL; + + +/* + * External stuff. + */ +extern HWND SDL_HelperWindow; + + +/* + * Prototypes. + */ +static void DI_SetError(const char *str, HRESULT err); +static int DI_GUIDIsSame(const GUID * a, const GUID * b); +static int SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, + DIDEVICEINSTANCE instance); +static int SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, + LPDIRECTINPUTDEVICE2 device2); +static DWORD DIGetTriggerButton(Uint16 button); +static int SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, + int naxes); +static int SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, + SDL_HapticEffect * src); +static void SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type); +static REFGUID SDL_SYS_HapticEffectType(SDL_HapticEffect * effect); +/* Callbacks. */ +static BOOL CALLBACK EnumHapticsCallback(const DIDEVICEINSTANCE * + pdidInstance, VOID * pContext); +static BOOL CALLBACK DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv); + + +/* + * Like SDL_SetError but for DX error codes. + */ +static void +DI_SetError(const char *str, HRESULT err) +{ + /* + SDL_SetError("Haptic: %s - %s: %s", str, + DXGetErrorString8A(err), DXGetErrorDescription8A(err)); + */ + SDL_SetError("Haptic error %s", str); +} + + +/* + * Checks to see if two GUID are the same. + */ +static int +DI_GUIDIsSame(const GUID * a, const GUID * b) +{ + if (((a)->Data1 == (b)->Data1) && + ((a)->Data2 == (b)->Data2) && + ((a)->Data3 == (b)->Data3) && + (SDL_strcmp((a)->Data4, (b)->Data4) == 0)) + return 1; + return 0; +} + + +/* + * Initializes the haptic subsystem. + */ +int +SDL_SYS_HapticInit(void) +{ + HRESULT ret; + HINSTANCE instance; + + if (dinput != NULL) { /* Already open. */ + SDL_SetError("Haptic: SubSystem already open."); + return -1; + } + + /* Clear all the memory. */ + SDL_memset(SDL_hapticlist, 0, sizeof(SDL_hapticlist)); + + SDL_numhaptics = 0; + + ret = CoInitialize(NULL); + if (FAILED(ret)) { + DI_SetError("Coinitialize", ret); + return -1; + } + + ret = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, + &IID_IDirectInput, (LPVOID) & dinput); + if (FAILED(ret)) { + DI_SetError("CoCreateInstance", ret); + return -1; + } + + /* Because we used CoCreateInstance, we need to Initialize it, first. */ + instance = GetModuleHandle(NULL); + if (instance == NULL) { + SDL_SetError("GetModuleHandle() failed with error code %d.", + GetLastError()); + return -1; + } + ret = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION); + if (FAILED(ret)) { + DI_SetError("Initializing DirectInput device", ret); + return -1; + } + + /* Look for haptic devices. */ + ret = IDirectInput_EnumDevices(dinput, + 0, + EnumHapticsCallback, + NULL, + DIEDFL_FORCEFEEDBACK | + DIEDFL_ATTACHEDONLY); + if (FAILED(ret)) { + DI_SetError("Enumerating DirectInput devices", ret); + return -1; + } + + return SDL_numhaptics; +} + +/* + * Callback to find the haptic devices. + */ +static BOOL CALLBACK +EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +{ + HRESULT ret; + LPDIRECTINPUTDEVICE device; + + /* Copy the instance over, useful for creating devices. */ + SDL_memcpy(&SDL_hapticlist[SDL_numhaptics].instance, pdidInstance, + sizeof(DIDEVICEINSTANCE)); + + /* Open the device */ + ret = IDirectInput_CreateDevice(dinput, &pdidInstance->guidInstance, + &device, NULL); + if (FAILED(ret)) { + /* DI_SetError("Creating DirectInput device",ret); */ + return DIENUM_CONTINUE; + } + + /* Get capabilities. */ + SDL_hapticlist[SDL_numhaptics].capabilities.dwSize = sizeof(DIDEVCAPS); + ret = IDirectInputDevice_GetCapabilities(device, + &SDL_hapticlist[SDL_numhaptics]. + capabilities); + if (FAILED(ret)) { + /* DI_SetError("Getting device capabilities",ret); */ + IDirectInputDevice_Release(device); + return DIENUM_CONTINUE; + } + + /* Close up device and count it. */ + IDirectInputDevice_Release(device); + SDL_numhaptics++; + + /* Watch out for hard limit. */ + if (SDL_numhaptics >= MAX_HAPTICS) + return DIENUM_STOP; + + return DIENUM_CONTINUE; +} + + +/* + * Return the name of a haptic device, does not need to be opened. + */ +const char * +SDL_SYS_HapticName(int index) +{ + return SDL_hapticlist[index].instance.tszProductName; +} + + +/* + * Callback to get all supported effects. + */ +#define EFFECT_TEST(e,s) \ +if (DI_GUIDIsSame(&pei->guid, &(e))) \ + haptic->supported |= (s) +static BOOL CALLBACK +DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv) +{ + /* Prepare the haptic device. */ + SDL_Haptic *haptic = (SDL_Haptic *) pv; + + /* Get supported. */ + EFFECT_TEST(GUID_Spring, SDL_HAPTIC_SPRING); + EFFECT_TEST(GUID_Damper, SDL_HAPTIC_DAMPER); + EFFECT_TEST(GUID_Inertia, SDL_HAPTIC_INERTIA); + EFFECT_TEST(GUID_Friction, SDL_HAPTIC_FRICTION); + EFFECT_TEST(GUID_ConstantForce, SDL_HAPTIC_CONSTANT); + EFFECT_TEST(GUID_CustomForce, SDL_HAPTIC_CUSTOM); + EFFECT_TEST(GUID_Sine, SDL_HAPTIC_SINE); + EFFECT_TEST(GUID_Square, SDL_HAPTIC_SQUARE); + EFFECT_TEST(GUID_Triangle, SDL_HAPTIC_TRIANGLE); + EFFECT_TEST(GUID_SawtoothUp, SDL_HAPTIC_SAWTOOTHUP); + EFFECT_TEST(GUID_SawtoothDown, SDL_HAPTIC_SAWTOOTHDOWN); + EFFECT_TEST(GUID_RampForce, SDL_HAPTIC_RAMP); + + /* Check for more. */ + return DIENUM_CONTINUE; +} + + +/* + * Callback to get supported axes. + */ +static BOOL CALLBACK +DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) +{ + SDL_Haptic *haptic = (SDL_Haptic *) pvRef; + + if ((dev->dwType & DIDFT_AXIS) && (dev->dwFlags & DIDOI_FFACTUATOR)) { + + haptic->hwdata->axes[haptic->naxes] = dev->dwOfs; + haptic->naxes++; + + /* Currently using the artificial limit of 3 axes. */ + if (haptic->naxes >= 3) { + return DIENUM_STOP; + } + } + + return DIENUM_CONTINUE; +} + + +/* + * Opens the haptic device from the file descriptor. + * + * Steps: + * - Open temporary DirectInputDevice interface. + * - Create DirectInputDevice2 interface. + * - Release DirectInputDevice interface. + * - Call SDL_SYS_HapticOpenFromDevice2 + */ +static int +SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance) +{ + HRESULT ret; + int ret2; + LPDIRECTINPUTDEVICE device; + + /* Allocate the hwdata */ + haptic->hwdata = (struct haptic_hwdata *) + SDL_malloc(sizeof(*haptic->hwdata)); + if (haptic->hwdata == NULL) { + SDL_OutOfMemory(); + goto creat_err; + } + SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); + + /* Open the device */ + ret = IDirectInput_CreateDevice(dinput, &instance.guidInstance, + &device, NULL); + if (FAILED(ret)) { + DI_SetError("Creating DirectInput device", ret); + goto creat_err; + } + + /* Now get the IDirectInputDevice2 interface, instead. */ + ret = IDirectInputDevice_QueryInterface(device, + &IID_IDirectInputDevice2, + (LPVOID *) & haptic->hwdata-> + device); + /* Done with the temporary one now. */ + IDirectInputDevice_Release(device); + if (FAILED(ret)) { + DI_SetError("Querying DirectInput interface", ret); + goto creat_err; + } + + ret2 = SDL_SYS_HapticOpenFromDevice2(haptic, haptic->hwdata->device); + if (ret2 < 0) { + goto query_err; + } + + return 0; + + query_err: + IDirectInputDevice2_Release(haptic->hwdata->device); + creat_err: + if (haptic->hwdata != NULL) { + SDL_free(haptic->hwdata); + haptic->hwdata = NULL; + } + return -1; +} + + +/* + * Opens the haptic device from the file descriptor. + * + * Steps: + * - Set cooperative level. + * - Set data format. + * - Acquire exclusiveness. + * - Reset actuators. + * - Get supported featuers. + */ +static int +SDL_SYS_HapticOpenFromDevice2(SDL_Haptic * haptic, + LPDIRECTINPUTDEVICE2 device2) +{ + HRESULT ret; + DIPROPDWORD dipdw; + + /* We'll use the device2 from now on. */ + haptic->hwdata->device = device2; + + /* Grab it exclusively to use force feedback stuff. */ + ret = IDirectInputDevice2_SetCooperativeLevel(haptic->hwdata->device, + SDL_HelperWindow, + DISCL_EXCLUSIVE | + DISCL_BACKGROUND); + if (FAILED(ret)) { + DI_SetError("Setting cooperative level to exclusive", ret); + goto acquire_err; + } + + /* Set data format. */ + ret = IDirectInputDevice2_SetDataFormat(haptic->hwdata->device, + &c_dfDIJoystick2); + if (FAILED(ret)) { + DI_SetError("Setting data format", ret); + goto acquire_err; + } + + /* Get number of axes. */ + ret = IDirectInputDevice2_EnumObjects(haptic->hwdata->device, + DI_DeviceObjectCallback, + haptic, DIDFT_AXIS); + if (FAILED(ret)) { + DI_SetError("Getting device axes", ret); + goto acquire_err; + } + + /* Acquire the device. */ + ret = IDirectInputDevice2_Acquire(haptic->hwdata->device); + if (FAILED(ret)) { + DI_SetError("Acquiring DirectInput device", ret); + goto acquire_err; + } + + /* Reset all actuators - just in case. */ + ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, + DISFFC_RESET); + if (FAILED(ret)) { + DI_SetError("Resetting device", ret); + goto acquire_err; + } + + /* Enabling actuators. */ + ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, + DISFFC_SETACTUATORSON); + if (FAILED(ret)) { + DI_SetError("Enabling actuators", ret); + goto acquire_err; + } + + /* Get supported effects. */ + ret = IDirectInputDevice2_EnumEffects(haptic->hwdata->device, + DI_EffectCallback, haptic, + DIEFT_ALL); + if (FAILED(ret)) { + DI_SetError("Enumerating supported effects", ret); + goto acquire_err; + } + if (haptic->supported == 0) { /* Error since device supports nothing. */ + SDL_SetError("Haptic: Internal error on finding supported effects."); + goto acquire_err; + } + + /* Check autogain and autocenter. */ + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = 10000; + ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, + DIPROP_FFGAIN, &dipdw.diph); + if (!FAILED(ret)) { /* Gain is supported. */ + haptic->supported |= SDL_HAPTIC_GAIN; + } + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = DIPROPAUTOCENTER_OFF; + ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, + DIPROP_AUTOCENTER, &dipdw.diph); + if (!FAILED(ret)) { /* Autocenter is supported. */ + haptic->supported |= SDL_HAPTIC_AUTOCENTER; + } + + /* Status is always supported. */ + haptic->supported |= SDL_HAPTIC_STATUS | SDL_HAPTIC_PAUSE; + + /* Check maximum effects. */ + haptic->neffects = 128; /* This is not actually supported as thus under windows, + there is no way to tell the number of EFFECTS that a + device can hold, so we'll just use a "random" number + instead and put warnings in SDL_haptic.h */ + haptic->nplaying = 128; /* Even more impossible to get this then neffects. */ + + /* Prepare effects memory. */ + haptic->effects = (struct haptic_effect *) + SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); + if (haptic->effects == NULL) { + SDL_OutOfMemory(); + goto acquire_err; + } + /* Clear the memory */ + SDL_memset(haptic->effects, 0, + sizeof(struct haptic_effect) * haptic->neffects); + + return 0; + + /* Error handling */ + acquire_err: + IDirectInputDevice2_Unacquire(haptic->hwdata->device); + return -1; + +} + + +/* + * Opens a haptic device for usage. + */ +int +SDL_SYS_HapticOpen(SDL_Haptic * haptic) +{ + return SDL_SYS_HapticOpenFromInstance(haptic, + SDL_hapticlist[haptic->index]. + instance); +} + + +/* + * Opens a haptic device from first mouse it finds for usage. + */ +int +SDL_SYS_HapticMouse(void) +{ + int i; + + /* Grab the first mouse haptic device we find. */ + for (i = 0; i < SDL_numhaptics; i++) { + if (SDL_hapticlist[i].capabilities.dwDevType == DIDEVTYPE_MOUSE) { + return i; + } + } + + return -1; +} + + +/* + * Checks to see if a joystick has haptic features. + */ +int +SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) +{ + if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { + return SDL_TRUE; + } + + return SDL_FALSE; +} + + +/* + * Checks to see if the haptic device and joystick and in reality the same. + */ +int +SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +{ + HRESULT ret; + DIDEVICEINSTANCE hap_instance, joy_instance; + + /* Get the device instances. */ + ret = IDirectInputDevice2_GetDeviceInfo(haptic->hwdata->device, + &hap_instance); + if (FAILED(ret)) { + return 0; + } + ret = IDirectInputDevice2_GetDeviceInfo(joystick->hwdata->InputDevice, + &joy_instance); + if (FAILED(ret)) { + return 0; + } + + if (DI_GUIDIsSame(&hap_instance.guidInstance, &joy_instance.guidInstance)) + return 1; + + return 0; +} + + +/* + * Opens a SDL_Haptic from a SDL_Joystick. + */ +int +SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) +{ + int ret; + + /* Allocate the hwdata */ + haptic->hwdata = (struct haptic_hwdata *) + SDL_malloc(sizeof(*haptic->hwdata)); + if (haptic->hwdata == NULL) { + SDL_OutOfMemory(); + return -1; + } + SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); + + /* Now open the device. */ + ret = + SDL_SYS_HapticOpenFromDevice2(haptic, joystick->hwdata->InputDevice); + if (ret < 0) { + return -1; + } + + /* It's using the joystick device. */ + haptic->hwdata->is_joystick = 1; + + return 0; +} + + +/* + * Closes the haptic device. + */ +void +SDL_SYS_HapticClose(SDL_Haptic * haptic) +{ + if (haptic->hwdata) { + + /* Free effects. */ + SDL_free(haptic->effects); + haptic->effects = NULL; + haptic->neffects = 0; + + /* Clean up */ + IDirectInputDevice2_Unacquire(haptic->hwdata->device); + /* Only release if isn't grabbed by a joystick. */ + if (haptic->hwdata->is_joystick == 0) { + IDirectInputDevice2_Release(haptic->hwdata->device); + } + + /* Free */ + SDL_free(haptic->hwdata); + haptic->hwdata = NULL; + } +} + + +/* + * Clean up after system specific haptic stuff + */ +void +SDL_SYS_HapticQuit(void) +{ + IDirectInput_Release(dinput); + dinput = NULL; +} + + +/* + * Converts an SDL trigger button to an DIEFFECT trigger button. + */ +static DWORD +DIGetTriggerButton(Uint16 button) +{ + DWORD dwTriggerButton; + + dwTriggerButton = DIEB_NOTRIGGER; + + if (button != 0) { + dwTriggerButton = DIJOFS_BUTTON(button - 1); + } + + return dwTriggerButton; +} + + +/* + * Sets the direction. + */ +static int +SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, int naxes) +{ + LONG *rglDir; + + /* Handle no axes a part. */ + if (naxes == 0) { + effect->dwFlags |= DIEFF_SPHERICAL; /* Set as default. */ + effect->rglDirection = NULL; + return 0; + } + + /* Has axes. */ + rglDir = SDL_malloc(sizeof(LONG) * naxes); + if (rglDir == NULL) { + SDL_OutOfMemory(); + return -1; + } + SDL_memset(rglDir, 0, sizeof(LONG) * naxes); + effect->rglDirection = rglDir; + + switch (dir->type) { + case SDL_HAPTIC_POLAR: + effect->dwFlags |= DIEFF_POLAR; + rglDir[0] = dir->dir[0]; + return 0; + case SDL_HAPTIC_CARTESIAN: + effect->dwFlags |= DIEFF_CARTESIAN; + rglDir[0] = dir->dir[0]; + if (naxes > 1) + rglDir[1] = dir->dir[1]; + if (naxes > 2) + rglDir[2] = dir->dir[2]; + return 0; + case SDL_HAPTIC_SPHERICAL: + effect->dwFlags |= DIEFF_SPHERICAL; + rglDir[0] = dir->dir[0]; + if (naxes > 1) + rglDir[1] = dir->dir[1]; + if (naxes > 2) + rglDir[2] = dir->dir[2]; + return 0; + + default: + SDL_SetError("Haptic: Unknown direction type."); + return -1; + } +} + +#define CONVERT(x) (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF) +/* + * Creates the DIEFFECT from a SDL_HapticEffect. + */ +static int +SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, + SDL_HapticEffect * src) +{ + int i; + DICONSTANTFORCE *constant; + DIPERIODIC *periodic; + DICONDITION *condition; /* Actually an array of conditions - one per axis. */ + DIRAMPFORCE *ramp; + DICUSTOMFORCE *custom; + DIENVELOPE *envelope; + SDL_HapticConstant *hap_constant; + SDL_HapticPeriodic *hap_periodic; + SDL_HapticCondition *hap_condition; + SDL_HapticRamp *hap_ramp; + SDL_HapticCustom *hap_custom; + DWORD *axes; + + /* Set global stuff. */ + SDL_memset(dest, 0, sizeof(DIEFFECT)); + dest->dwSize = sizeof(DIEFFECT); /* Set the structure size. */ + dest->dwSamplePeriod = 0; /* Not used by us. */ + dest->dwGain = 10000; /* Gain is set globally, not locally. */ + dest->dwFlags = DIEFF_OBJECTOFFSETS; /* Seems obligatory. */ + + /* Envelope. */ + envelope = SDL_malloc(sizeof(DIENVELOPE)); + if (envelope == NULL) { + SDL_OutOfMemory(); + return -1; + } + SDL_memset(envelope, 0, sizeof(DIENVELOPE)); + dest->lpEnvelope = envelope; + envelope->dwSize = sizeof(DIENVELOPE); /* Always should be this. */ + + /* Axes. */ + dest->cAxes = haptic->naxes; + if (dest->cAxes > 0) { + axes = SDL_malloc(sizeof(DWORD) * dest->cAxes); + if (axes == NULL) { + SDL_OutOfMemory(); + return -1; + } + axes[0] = haptic->hwdata->axes[0]; /* Always at least one axis. */ + if (dest->cAxes > 1) { + axes[1] = haptic->hwdata->axes[1]; + } + if (dest->cAxes > 2) { + axes[2] = haptic->hwdata->axes[2]; + } + dest->rgdwAxes = axes; + } + + + /* The big type handling switch, even bigger then linux's version. */ + switch (src->type) { + case SDL_HAPTIC_CONSTANT: + hap_constant = &src->constant; + constant = SDL_malloc(sizeof(DICONSTANTFORCE)); + if (constant == NULL) { + SDL_OutOfMemory(); + return -1; + } + SDL_memset(constant, 0, sizeof(DICONSTANTFORCE)); + + /* Specifics */ + constant->lMagnitude = CONVERT(hap_constant->level); + dest->cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + dest->lpvTypeSpecificParams = constant; + + /* Generics */ + dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */ + dest->dwTriggerButton = DIGetTriggerButton(hap_constant->button); + dest->dwTriggerRepeatInterval = hap_constant->interval; + dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */ + + /* Direction. */ + if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) + < 0) { + return -1; + } + + /* Envelope */ + if ((hap_constant->attack_length == 0) + && (hap_constant->fade_length == 0)) { + SDL_free(dest->lpEnvelope); + dest->lpEnvelope = NULL; + } else { + envelope->dwAttackLevel = CONVERT(hap_constant->attack_level); + envelope->dwAttackTime = hap_constant->attack_length * 1000; + envelope->dwFadeLevel = CONVERT(hap_constant->fade_level); + envelope->dwFadeTime = hap_constant->fade_length * 1000; + } + + break; + + case SDL_HAPTIC_SINE: + case SDL_HAPTIC_SQUARE: + case SDL_HAPTIC_TRIANGLE: + case SDL_HAPTIC_SAWTOOTHUP: + case SDL_HAPTIC_SAWTOOTHDOWN: + hap_periodic = &src->periodic; + periodic = SDL_malloc(sizeof(DIPERIODIC)); + if (periodic == NULL) { + SDL_OutOfMemory(); + return -1; + } + SDL_memset(periodic, 0, sizeof(DIPERIODIC)); + + /* Specifics */ + periodic->dwMagnitude = CONVERT(hap_periodic->magnitude); + periodic->lOffset = CONVERT(hap_periodic->offset); + periodic->dwPhase = hap_periodic->phase; + periodic->dwPeriod = hap_periodic->period * 1000; + dest->cbTypeSpecificParams = sizeof(DIPERIODIC); + dest->lpvTypeSpecificParams = periodic; + + /* Generics */ + dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */ + dest->dwTriggerButton = DIGetTriggerButton(hap_periodic->button); + dest->dwTriggerRepeatInterval = hap_periodic->interval; + dest->dwStartDelay = hap_periodic->delay * 1000; /* In microseconds. */ + + /* Direction. */ + if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes) + < 0) { + return -1; + } + + /* Envelope */ + if ((hap_periodic->attack_length == 0) + && (hap_periodic->fade_length == 0)) { + SDL_free(dest->lpEnvelope); + dest->lpEnvelope = NULL; + } else { + envelope->dwAttackLevel = CONVERT(hap_periodic->attack_level); + envelope->dwAttackTime = hap_periodic->attack_length * 1000; + envelope->dwFadeLevel = CONVERT(hap_periodic->fade_level); + envelope->dwFadeTime = hap_periodic->fade_length * 1000; + } + + break; + + case SDL_HAPTIC_SPRING: + case SDL_HAPTIC_DAMPER: + case SDL_HAPTIC_INERTIA: + case SDL_HAPTIC_FRICTION: + hap_condition = &src->condition; + condition = SDL_malloc(sizeof(DICONDITION) * dest->cAxes); + if (condition == NULL) { + SDL_OutOfMemory(); + return -1; + } + SDL_memset(condition, 0, sizeof(DICONDITION)); + + /* Specifics */ + for (i = 0; i < (int) dest->cAxes; i++) { + condition[i].lOffset = CONVERT(hap_condition->center[i]); + condition[i].lPositiveCoefficient = + CONVERT(hap_condition->right_coeff[i]); + condition[i].lNegativeCoefficient = + CONVERT(hap_condition->left_coeff[i]); + condition[i].dwPositiveSaturation = + CONVERT(hap_condition->right_sat[i]); + condition[i].dwNegativeSaturation = + CONVERT(hap_condition->left_sat[i]); + condition[i].lDeadBand = CONVERT(hap_condition->deadband[i]); + } + dest->cbTypeSpecificParams = sizeof(DICONDITION) * dest->cAxes; + dest->lpvTypeSpecificParams = condition; + + /* Generics */ + dest->dwDuration = hap_condition->length * 1000; /* In microseconds. */ + dest->dwTriggerButton = DIGetTriggerButton(hap_condition->button); + dest->dwTriggerRepeatInterval = hap_condition->interval; + dest->dwStartDelay = hap_condition->delay * 1000; /* In microseconds. */ + + /* Direction. */ + if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes) + < 0) { + return -1; + } + + /* Envelope - Not actually supported by most CONDITION implementations. */ + SDL_free(dest->lpEnvelope); + dest->lpEnvelope = NULL; + + break; + + case SDL_HAPTIC_RAMP: + hap_ramp = &src->ramp; + ramp = SDL_malloc(sizeof(DIRAMPFORCE)); + if (ramp == NULL) { + SDL_OutOfMemory(); + return -1; + } + SDL_memset(ramp, 0, sizeof(DIRAMPFORCE)); + + /* Specifics */ + ramp->lStart = CONVERT(hap_ramp->start); + ramp->lEnd = CONVERT(hap_ramp->end); + dest->cbTypeSpecificParams = sizeof(DIRAMPFORCE); + dest->lpvTypeSpecificParams = ramp; + + /* Generics */ + dest->dwDuration = hap_ramp->length * 1000; /* In microseconds. */ + dest->dwTriggerButton = DIGetTriggerButton(hap_ramp->button); + dest->dwTriggerRepeatInterval = hap_ramp->interval; + dest->dwStartDelay = hap_ramp->delay * 1000; /* In microseconds. */ + + /* Direction. */ + if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) { + return -1; + } + + /* Envelope */ + if ((hap_ramp->attack_length == 0) && (hap_ramp->fade_length == 0)) { + SDL_free(dest->lpEnvelope); + dest->lpEnvelope = NULL; + } else { + envelope->dwAttackLevel = CONVERT(hap_ramp->attack_level); + envelope->dwAttackTime = hap_ramp->attack_length * 1000; + envelope->dwFadeLevel = CONVERT(hap_ramp->fade_level); + envelope->dwFadeTime = hap_ramp->fade_length * 1000; + } + + break; + + case SDL_HAPTIC_CUSTOM: + hap_custom = &src->custom; + custom = SDL_malloc(sizeof(DICUSTOMFORCE)); + if (custom == NULL) { + SDL_OutOfMemory(); + return -1; + } + SDL_memset(custom, 0, sizeof(DICUSTOMFORCE)); + + /* Specifics */ + custom->cChannels = hap_custom->channels; + custom->dwSamplePeriod = hap_custom->period * 1000; + custom->cSamples = hap_custom->samples; + custom->rglForceData = + SDL_malloc(sizeof(LONG) * custom->cSamples * custom->cChannels); + for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) { /* Copy data. */ + custom->rglForceData[i] = CONVERT(hap_custom->data[i]); + } + dest->cbTypeSpecificParams = sizeof(DICUSTOMFORCE); + dest->lpvTypeSpecificParams = custom; + + /* Generics */ + dest->dwDuration = hap_custom->length * 1000; /* In microseconds. */ + dest->dwTriggerButton = DIGetTriggerButton(hap_custom->button); + dest->dwTriggerRepeatInterval = hap_custom->interval; + dest->dwStartDelay = hap_custom->delay * 1000; /* In microseconds. */ + + /* Direction. */ + if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) < + 0) { + return -1; + } + + /* Envelope */ + if ((hap_custom->attack_length == 0) + && (hap_custom->fade_length == 0)) { + SDL_free(dest->lpEnvelope); + dest->lpEnvelope = NULL; + } else { + envelope->dwAttackLevel = CONVERT(hap_custom->attack_level); + envelope->dwAttackTime = hap_custom->attack_length * 1000; + envelope->dwFadeLevel = CONVERT(hap_custom->fade_level); + envelope->dwFadeTime = hap_custom->fade_length * 1000; + } + + break; + + + default: + SDL_SetError("Haptic: Unknown effect type."); + return -1; + } + + return 0; +} + + +/* + * Frees an DIEFFECT allocated by SDL_SYS_ToDIEFFECT. + */ +static void +SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type) +{ + DICUSTOMFORCE *custom; + + if (effect->lpEnvelope != NULL) { + SDL_free(effect->lpEnvelope); + effect->lpEnvelope = NULL; + } + if (effect->rgdwAxes != NULL) { + SDL_free(effect->rgdwAxes); + effect->rgdwAxes = NULL; + } + if (effect->lpvTypeSpecificParams != NULL) { + if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */ + custom = (DICUSTOMFORCE *) effect->lpvTypeSpecificParams; + SDL_free(custom->rglForceData); + custom->rglForceData = NULL; + } + SDL_free(effect->lpvTypeSpecificParams); + effect->lpvTypeSpecificParams = NULL; + } + if (effect->rglDirection != NULL) { + SDL_free(effect->rglDirection); + effect->rglDirection = NULL; + } +} + + +/* + * Gets the effect type from the generic SDL haptic effect wrapper. + */ +static REFGUID +SDL_SYS_HapticEffectType(SDL_HapticEffect * effect) +{ + switch (effect->type) { + case SDL_HAPTIC_CONSTANT: + return &GUID_ConstantForce; + + case SDL_HAPTIC_RAMP: + return &GUID_RampForce; + + case SDL_HAPTIC_SQUARE: + return &GUID_Square; + + case SDL_HAPTIC_SINE: + return &GUID_Sine; + + case SDL_HAPTIC_TRIANGLE: + return &GUID_Triangle; + + case SDL_HAPTIC_SAWTOOTHUP: + return &GUID_SawtoothUp; + + case SDL_HAPTIC_SAWTOOTHDOWN: + return &GUID_SawtoothDown; + + case SDL_HAPTIC_SPRING: + return &GUID_Spring; + + case SDL_HAPTIC_DAMPER: + return &GUID_Damper; + + case SDL_HAPTIC_INERTIA: + return &GUID_Inertia; + + case SDL_HAPTIC_FRICTION: + return &GUID_Friction; + + case SDL_HAPTIC_CUSTOM: + return &GUID_CustomForce; + + default: + SDL_SetError("Haptic: Unknown effect type."); + return NULL; + } +} + + +/* + * Creates a new haptic effect. + */ +int +SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, + SDL_HapticEffect * base) +{ + HRESULT ret; + + /* Get the type. */ + REFGUID type = SDL_SYS_HapticEffectType(base); + if (type == NULL) { + goto err_hweffect; + } + + /* Alloc the effect. */ + effect->hweffect = (struct haptic_hweffect *) + SDL_malloc(sizeof(struct haptic_hweffect)); + if (effect->hweffect == NULL) { + SDL_OutOfMemory(); + goto err_hweffect; + } + + /* Get the effect. */ + if (SDL_SYS_ToDIEFFECT(haptic, &effect->hweffect->effect, base) < 0) { + goto err_effectdone; + } + + /* Create the actual effect. */ + ret = IDirectInputDevice2_CreateEffect(haptic->hwdata->device, type, + &effect->hweffect->effect, + &effect->hweffect->ref, NULL); + if (FAILED(ret)) { + DI_SetError("Unable to create effect", ret); + goto err_effectdone; + } + + return 0; + + err_effectdone: + SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, base->type); + err_hweffect: + if (effect->hweffect != NULL) { + SDL_free(effect->hweffect); + effect->hweffect = NULL; + } + return -1; +} + + +/* + * Updates an effect. + */ +int +SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, + struct haptic_effect *effect, + SDL_HapticEffect * data) +{ + HRESULT ret; + DWORD flags; + DIEFFECT temp; + + /* Get the effect. */ + SDL_memset(&temp, 0, sizeof(DIEFFECT)); + if (SDL_SYS_ToDIEFFECT(haptic, &temp, data) < 0) { + goto err_update; + } + + /* Set the flags. Might be worthwhile to diff temp with loaded effect and + * only change those parameters. */ + flags = DIEP_DIRECTION | + DIEP_DURATION | + DIEP_ENVELOPE | + DIEP_STARTDELAY | + DIEP_TRIGGERBUTTON | + DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS; + + /* Create the actual effect. */ + ret = + IDirectInputEffect_SetParameters(effect->hweffect->ref, &temp, flags); + if (FAILED(ret)) { + DI_SetError("Unable to update effect", ret); + goto err_update; + } + + /* Copy it over. */ + SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, data->type); + SDL_memcpy(&effect->hweffect->effect, &temp, sizeof(DIEFFECT)); + + return 0; + + err_update: + SDL_SYS_HapticFreeDIEFFECT(&temp, data->type); + return -1; +} + + +/* + * Runs an effect. + */ +int +SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, + Uint32 iterations) +{ + HRESULT ret; + DWORD iter; + + /* Check if it's infinite. */ + if (iterations == SDL_HAPTIC_INFINITY) { + iter = INFINITE; + } else + iter = iterations; + + /* Run the effect. */ + ret = IDirectInputEffect_Start(effect->hweffect->ref, iter, 0); + if (FAILED(ret)) { + DI_SetError("Running the effect", ret); + return -1; + } + + return 0; +} + + +/* + * Stops an effect. + */ +int +SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +{ + HRESULT ret; + + ret = IDirectInputEffect_Stop(effect->hweffect->ref); + if (FAILED(ret)) { + DI_SetError("Unable to stop effect", ret); + return -1; + } + + return 0; +} + + +/* + * Frees the effect. + */ +void +SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +{ + HRESULT ret; + + ret = IDirectInputEffect_Unload(effect->hweffect->ref); + if (FAILED(ret)) { + DI_SetError("Removing effect from the device", ret); + } + SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, + effect->effect.type); + SDL_free(effect->hweffect); + effect->hweffect = NULL; +} + + +/* + * Gets the status of a haptic effect. + */ +int +SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, + struct haptic_effect *effect) +{ + HRESULT ret; + DWORD status; + + ret = IDirectInputEffect_GetEffectStatus(effect->hweffect->ref, &status); + if (FAILED(ret)) { + DI_SetError("Getting effect status", ret); + return -1; + } + + if (status == 0) + return SDL_FALSE; + return SDL_TRUE; +} + + +/* + * Sets the gain. + */ +int +SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) +{ + HRESULT ret; + DIPROPDWORD dipdw; + + /* Create the weird structure thingy. */ + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = gain * 100; /* 0 to 10,000 */ + + /* Try to set the autocenter. */ + ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, + DIPROP_FFGAIN, &dipdw.diph); + if (FAILED(ret)) { + DI_SetError("Setting gain", ret); + return -1; + } + + return 0; +} + + +/* + * Sets the autocentering. + */ +int +SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +{ + HRESULT ret; + DIPROPDWORD dipdw; + + /* Create the weird structure thingy. */ + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = (autocenter == 0) ? DIPROPAUTOCENTER_OFF : + DIPROPAUTOCENTER_ON; + + /* Try to set the autocenter. */ + ret = IDirectInputDevice2_SetProperty(haptic->hwdata->device, + DIPROP_AUTOCENTER, &dipdw.diph); + if (FAILED(ret)) { + DI_SetError("Setting autocenter", ret); + return -1; + } + + return 0; +} + + +/* + * Pauses the device. + */ +int +SDL_SYS_HapticPause(SDL_Haptic * haptic) +{ + HRESULT ret; + + /* Pause the device. */ + ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, + DISFFC_PAUSE); + if (FAILED(ret)) { + DI_SetError("Pausing the device", ret); + return -1; + } + + return 0; +} + + +/* + * Pauses the device. + */ +int +SDL_SYS_HapticUnpause(SDL_Haptic * haptic) +{ + HRESULT ret; + + /* Unpause the device. */ + ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, + DISFFC_CONTINUE); + if (FAILED(ret)) { + DI_SetError("Pausing the device", ret); + return -1; + } + + return 0; +} + + +/* + * Stops all the playing effects on the device. + */ +int +SDL_SYS_HapticStopAll(SDL_Haptic * haptic) +{ + HRESULT ret; + + /* Try to stop the effects. */ + ret = IDirectInputDevice2_SendForceFeedbackCommand(haptic->hwdata->device, + DISFFC_STOPALL); + if (FAILED(ret)) { + DI_SetError("Stopping the device", ret); + return -1; + } + + return 0; +} + + +#endif /* SDL_HAPTIC_DINPUT */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/joystick/win32/SDL_dxjoystick.c --- a/src/joystick/win32/SDL_dxjoystick.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,802 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_DINPUT - -/* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de - * A. Formiga's WINMM driver. - * - * Hats and sliders are completely untested; the app I'm writing this for mostly - * doesn't use them and I don't own any joysticks with them. - * - * We don't bother to use event notification here. It doesn't seem to work - * with polled devices, and it's fine to call IDirectInputDevice2_GetDeviceData and - * let it return 0 events. */ - -#include "SDL_error.h" -#include "SDL_events.h" -#include "SDL_joystick.h" -#include "../SDL_sysjoystick.h" -#include "../SDL_joystick_c.h" -#define INITGUID /* Only set here, if set twice will cause mingw32 to break. */ -#include "SDL_dxjoystick_c.h" - - -#ifndef DIDFT_OPTIONAL -#define DIDFT_OPTIONAL 0x80000000 -#endif - - -#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */ -#define MAX_JOYSTICKS 8 -#define AXIS_MIN -32768 /* minimum value for axis coordinate */ -#define AXIS_MAX 32767 /* maximum value for axis coordinate */ -#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/100) /* 1% motion */ - -/* external variables referenced. */ -extern HWND SDL_HelperWindow; - - -/* local variables */ -static LPDIRECTINPUT dinput = NULL; -extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion, - LPDIRECTINPUT * ppDI, - LPUNKNOWN punkOuter); -static DIDEVICEINSTANCE SYS_Joystick[MAX_JOYSTICKS]; /* array to hold joystick ID values */ -static int SYS_NumJoysticks; -static HINSTANCE DInputDLL = NULL; - - -/* local prototypes */ -static void SetDIerror(const char *function, HRESULT code); -static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE * - pdidInstance, VOID * pContext); -static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, - LPVOID pvRef); -static Uint8 TranslatePOV(DWORD value); -static int SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, - Sint16 value); -static int SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, - Uint8 value); -static int SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, - Uint8 button, Uint8 state); - -/* Taken from Wine - Thanks! */ -DIOBJECTDATAFORMAT dfDIJoystick2[] = { - { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, - { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, - { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, - { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(16),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(17),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(18),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(19),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(20),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(21),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(22),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(23),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(24),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(25),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(26),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(27),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(28),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(29),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(30),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(31),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(32),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(33),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(34),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(35),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(36),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(37),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(38),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(39),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(40),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(41),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(42),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(43),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(44),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(45),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(46),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(47),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(48),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(49),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(50),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(51),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(52),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(53),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(54),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(55),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(56),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(57),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(58),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(59),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(60),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(61),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(62),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(63),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(64),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(65),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(66),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(67),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(68),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(69),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(70),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(71),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(72),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(73),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(74),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(75),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(76),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(77),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(78),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(79),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(80),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(81),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(82),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(83),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(84),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(85),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(86),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(87),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(88),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(89),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(90),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(91),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(92),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(93),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(94),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(95),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(96),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(97),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(98),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(99),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(100),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(101),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(102),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(103),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(104),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(105),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(106),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(107),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(108),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(109),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(110),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(111),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(112),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(113),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(114),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(115),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(116),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(117),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(118),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(119),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(120),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(121),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(122),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(123),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(124),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(125),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(126),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { NULL,DIJOFS_BUTTON(127),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, - { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lVX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lVY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lVZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lVRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lVRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lVRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lAX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lAY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lAZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lARx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lARy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lARz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lFX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lFY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lFZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lFRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lFRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lFRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, - { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, -}; - -const DIDATAFORMAT c_dfDIJoystick2 = { - sizeof(DIDATAFORMAT), - sizeof(DIOBJECTDATAFORMAT), - DIDF_ABSAXIS, - sizeof(DIJOYSTATE2), - SDL_arraysize(dfDIJoystick2), - dfDIJoystick2 -}; - - -/* Convert a DirectInput return code to a text message */ -static void -SetDIerror(const char *function, HRESULT code) -{ - /* - SDL_SetError("%s() [%s]: %s", function, - DXGetErrorString9A(code), DXGetErrorDescription9A(code)); - */ - SDL_SetError("%s() DirectX error %d", function, code); -} - - -/* Function to scan the system for joysticks. - * This function should set SDL_numjoysticks to the number of available - * joysticks. Joystick 0 should be the system default joystick. - * It should return 0, or -1 on an unrecoverable fatal error. - */ -int -SDL_SYS_JoystickInit(void) -{ - HRESULT result; - HINSTANCE instance; - - SYS_NumJoysticks = 0; - - result = CoInitialize(NULL); - if (FAILED(result)) { - SetDIerror("CoInitialize", result); - return (-1); - } - - result = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, - &IID_IDirectInput, (LPVOID)&dinput); - - if (FAILED(result)) { - SetDIerror("CoCreateInstance", result); - return (-1); - } - - /* Because we used CoCreateInstance, we need to Initialize it, first. */ - instance = GetModuleHandle(NULL); - if (instance == NULL) { - SDL_SetError("GetModuleHandle() failed with error code %d.", - GetLastError()); - return (-1); - } - result = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION); - - if (FAILED(result)) { - SetDIerror("IDirectInput::Initialize", result); - return (-1); - } - - /* Look for joysticks, wheels, head trackers, gamepads, etc.. */ - result = IDirectInput_EnumDevices(dinput, - DIDEVTYPE_JOYSTICK, - EnumJoysticksCallback, - NULL, DIEDFL_ATTACHEDONLY); - - return SYS_NumJoysticks; -} - -static BOOL CALLBACK -EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) -{ - SDL_memcpy(&SYS_Joystick[SYS_NumJoysticks], pdidInstance, - sizeof(DIDEVICEINSTANCE)); - SYS_NumJoysticks++; - - if (SYS_NumJoysticks >= MAX_JOYSTICKS) - return DIENUM_STOP; - - return DIENUM_CONTINUE; -} - -/* Function to get the device-dependent name of a joystick */ -const char * -SDL_SYS_JoystickName(int index) -{ - /***-> test for invalid index ? */ - return (SYS_Joystick[index].tszProductName); -} - -/* 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) -{ - HRESULT result; - LPDIRECTINPUTDEVICE device; - DIPROPDWORD dipdw; - - SDL_memset(&dipdw, 0, sizeof(DIPROPDWORD)); - dipdw.diph.dwSize = sizeof(DIPROPDWORD); - dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); - - - /* allocate memory for system specific hardware data */ - joystick->hwdata = - (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata)); - if (joystick->hwdata == NULL) { - SDL_OutOfMemory(); - return (-1); - } - SDL_memset(joystick->hwdata, 0, sizeof(struct joystick_hwdata)); - joystick->hwdata->buffered = 1; - joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS); - - result = - IDirectInput_CreateDevice(dinput, - &SYS_Joystick[joystick->index]. - guidInstance, &device, NULL); - if (FAILED(result)) { - SetDIerror("IDirectInput::CreateDevice", result); - return (-1); - } - - /* Now get the IDirectInputDevice2 interface, instead. */ - result = IDirectInputDevice_QueryInterface(device, - &IID_IDirectInputDevice2, - (LPVOID *) & joystick-> - hwdata->InputDevice); - /* We are done with this object. Use the stored one from now on. */ - IDirectInputDevice_Release(device); - - if (FAILED(result)) { - SetDIerror("IDirectInputDevice::QueryInterface", result); - return (-1); - } - - /* Aquire shared access. Exclusive access is required for forces, - * though. */ - result = - IDirectInputDevice2_SetCooperativeLevel(joystick->hwdata-> - InputDevice, SDL_HelperWindow, - DISCL_EXCLUSIVE | - DISCL_BACKGROUND); - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::SetCooperativeLevel", result); - return (-1); - } - - /* Use the extended data structure: DIJOYSTATE2. */ - result = - IDirectInputDevice2_SetDataFormat(joystick->hwdata->InputDevice, - &c_dfDIJoystick2); - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::SetDataFormat", result); - return (-1); - } - - /* Get device capabilities */ - result = - IDirectInputDevice2_GetCapabilities(joystick->hwdata->InputDevice, - &joystick->hwdata->Capabilities); - - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::GetCapabilities", result); - return (-1); - } - - /* Force capable? */ - if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { - - result = IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); - - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::Acquire", result); - return (-1); - } - - /* reset all accuators. */ - result = - IDirectInputDevice2_SendForceFeedbackCommand(joystick->hwdata-> - InputDevice, - DISFFC_RESET); - - /* Not necessarily supported, ignore if not supported. - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::SendForceFeedbackCommand", - result); - return (-1); - } - */ - - result = IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice); - - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::Unacquire", result); - return (-1); - } - - /* Turn on auto-centering for a ForceFeedback device (until told - * otherwise). */ - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = DIPROPAUTOCENTER_ON; - - result = - IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, - DIPROP_AUTOCENTER, &dipdw.diph); - - /* Not necessarily supported, ignore if not supported. - if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::SetProperty", result); - return (-1); - } - */ - } - - /* What buttons and axes does it have? */ - IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice, - EnumDevObjectsCallback, joystick, - DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); - - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = INPUT_QSIZE; - - /* Set the buffer size */ - result = - IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, - DIPROP_BUFFERSIZE, &dipdw.diph); - - if (result == DI_POLLEDDEVICE) { - /* This device doesn't support buffering, so we're forced - * to use less reliable polling. */ - joystick->hwdata->buffered = 0; - } else if (FAILED(result)) { - SetDIerror("IDirectInputDevice2::SetProperty", result); - return (-1); - } - - return (0); -} - -static BOOL CALLBACK -EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) -{ - SDL_Joystick *joystick = (SDL_Joystick *) pvRef; - HRESULT result; - input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs]; - - in->ofs = dev->dwOfs; - - if (dev->dwType & DIDFT_BUTTON) { - in->type = BUTTON; - in->num = joystick->nbuttons; - joystick->nbuttons++; - } else if (dev->dwType & DIDFT_POV) { - in->type = HAT; - in->num = joystick->nhats; - joystick->nhats++; - } else if (dev->dwType & DIDFT_AXIS) { - DIPROPRANGE diprg; - DIPROPDWORD dilong; - - in->type = AXIS; - in->num = joystick->naxes; - - diprg.diph.dwSize = sizeof(diprg); - diprg.diph.dwHeaderSize = sizeof(diprg.diph); - diprg.diph.dwObj = dev->dwOfs; - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.lMin = AXIS_MIN; - diprg.lMax = AXIS_MAX; - - result = - IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, - DIPROP_RANGE, &diprg.diph); - if (FAILED(result)) { - return DIENUM_CONTINUE; /* don't use this axis */ - } - - /* Set dead zone to 0. */ - dilong.diph.dwSize = sizeof(dilong); - dilong.diph.dwHeaderSize = sizeof(dilong.diph); - dilong.diph.dwObj = dev->dwOfs; - dilong.diph.dwHow = DIPH_BYOFFSET; - dilong.dwData = 0; - result = - IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, - DIPROP_DEADZONE, &dilong.diph); - if (FAILED(result)) { - return DIENUM_CONTINUE; /* don't use this axis */ - } - - joystick->naxes++; - } else { - /* not supported at this time */ - return DIENUM_CONTINUE; - } - - joystick->hwdata->NumInputs++; - - if (joystick->hwdata->NumInputs == MAX_INPUTS) { - return DIENUM_STOP; /* too many */ - } - - return DIENUM_CONTINUE; -} - -/* 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_Polled(SDL_Joystick * joystick) -{ - DIJOYSTATE2 state; - HRESULT result; - int i; - - result = - IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice, - sizeof(DIJOYSTATE2), &state); - if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { - IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); - result = - IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice, - sizeof(DIJOYSTATE2), &state); - } - - /* Set each known axis, button and POV. */ - for (i = 0; i < joystick->hwdata->NumInputs; ++i) { - const input_t *in = &joystick->hwdata->Inputs[i]; - - switch (in->type) { - case AXIS: - switch (in->ofs) { - case DIJOFS_X: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lX); - break; - case DIJOFS_Y: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lY); - break; - case DIJOFS_Z: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lZ); - break; - case DIJOFS_RX: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lRx); - break; - case DIJOFS_RY: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lRy); - break; - case DIJOFS_RZ: - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.lRz); - break; - case DIJOFS_SLIDER(0): - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.rglSlider[0]); - break; - case DIJOFS_SLIDER(1): - SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.rglSlider[1]); - break; - } - - break; - - case BUTTON: - SDL_PrivateJoystickButton_Int(joystick, in->num, - (Uint8) (state. - rgbButtons[in->ofs - - DIJOFS_BUTTON0] - ? SDL_PRESSED : - SDL_RELEASED)); - break; - case HAT: - { - Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - - DIJOFS_POV(0)]); - SDL_PrivateJoystickHat_Int(joystick, in->num, pos); - break; - } - } - } -} - -void -SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) -{ - int i; - HRESULT result; - DWORD numevents; - DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE]; - - numevents = INPUT_QSIZE; - result = - IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice, - sizeof(DIDEVICEOBJECTDATA), evtbuf, - &numevents, 0); - if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { - IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); - result = - IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice, - sizeof(DIDEVICEOBJECTDATA), - evtbuf, &numevents, 0); - } - - /* Handle the events or punt */ - if (FAILED(result)) - return; - - for (i = 0; i < (int) numevents; ++i) { - int j; - - for (j = 0; j < joystick->hwdata->NumInputs; ++j) { - const input_t *in = &joystick->hwdata->Inputs[j]; - - if (evtbuf[i].dwOfs != in->ofs) - continue; - - switch (in->type) { - case AXIS: - SDL_PrivateJoystickAxis(joystick, in->num, - (Sint16) evtbuf[i].dwData); - break; - case BUTTON: - SDL_PrivateJoystickButton(joystick, in->num, - (Uint8) (evtbuf[i]. - dwData ? SDL_PRESSED : - SDL_RELEASED)); - break; - case HAT: - { - Uint8 pos = TranslatePOV(evtbuf[i].dwData); - SDL_PrivateJoystickHat(joystick, in->num, pos); - } - } - } - } -} - - -static Uint8 -TranslatePOV(DWORD value) -{ - const int HAT_VALS[] = { - SDL_HAT_UP, - SDL_HAT_UP | SDL_HAT_RIGHT, - SDL_HAT_RIGHT, - SDL_HAT_DOWN | SDL_HAT_RIGHT, - SDL_HAT_DOWN, - SDL_HAT_DOWN | SDL_HAT_LEFT, - SDL_HAT_LEFT, - SDL_HAT_UP | SDL_HAT_LEFT - }; - - if (LOWORD(value) == 0xFFFF) - return SDL_HAT_CENTERED; - - /* Round the value up: */ - value += 4500 / 2; - value %= 36000; - value /= 4500; - - if (value >= 8) - return SDL_HAT_CENTERED; /* shouldn't happen */ - - return HAT_VALS[value]; -} - -/* SDL_PrivateJoystick* doesn't discard duplicate events, so we need to - * do it. */ -static int -SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, Sint16 value) -{ - if (joystick->axes[axis] != value) - return SDL_PrivateJoystickAxis(joystick, axis, value); - return 0; -} - -static int -SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, Uint8 value) -{ - if (joystick->hats[hat] != value) - return SDL_PrivateJoystickHat(joystick, hat, value); - return 0; -} - -static int -SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, Uint8 button, - Uint8 state) -{ - if (joystick->buttons[button] != state) - return SDL_PrivateJoystickButton(joystick, button, state); - return 0; -} - -void -SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) -{ - HRESULT result; - - result = IDirectInputDevice2_Poll(joystick->hwdata->InputDevice); - if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { - IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); - IDirectInputDevice2_Poll(joystick->hwdata->InputDevice); - } - - if (joystick->hwdata->buffered) - SDL_SYS_JoystickUpdate_Buffered(joystick); - else - SDL_SYS_JoystickUpdate_Polled(joystick); -} - -/* Function to close a joystick after use */ -void -SDL_SYS_JoystickClose(SDL_Joystick * joystick) -{ - IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice); - IDirectInputDevice2_Release(joystick->hwdata->InputDevice); - - 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) -{ - IDirectInput_Release(dinput); - dinput = NULL; -} - -#endif /* SDL_JOYSTICK_DINPUT */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/joystick/win32/SDL_dxjoystick_c.h --- a/src/joystick/win32/SDL_dxjoystick_c.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_JOYSTICK_DINPUT_H - -/* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de - * A. Formiga's WINMM driver. - * - * Hats and sliders are completely untested; the app I'm writing this for mostly - * doesn't use them and I don't own any joysticks with them. - * - * We don't bother to use event notification here. It doesn't seem to work - * with polled devices, and it's fine to call IDirectInputDevice2_GetDeviceData and - * let it return 0 events. */ - -#define WIN32_LEAN_AND_MEAN -#include - -#define DIRECTINPUT_VERSION 0x0700 /* Need version 7 for force feedback. */ -#include - - -#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */ - - -/* local types */ -typedef enum Type -{ BUTTON, AXIS, HAT } Type; - -typedef struct input_t -{ - /* DirectInput offset for this input type: */ - DWORD ofs; - - /* Button, axis or hat: */ - Type type; - - /* SDL input offset: */ - Uint8 num; -} input_t; - -/* The private structure used to keep track of a joystick */ -struct joystick_hwdata -{ - LPDIRECTINPUTDEVICE2 InputDevice; - DIDEVCAPS Capabilities; - int buffered; - - input_t Inputs[MAX_INPUTS]; - int NumInputs; -}; - -#endif /* SDL_JOYSTICK_DINPUT_H */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/joystick/win32/SDL_mmjoystick.c --- a/src/joystick/win32/SDL_mmjoystick.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,428 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_WINMM - -/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */ - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include - -#include "SDL_events.h" -#include "SDL_joystick.h" -#include "../SDL_sysjoystick.h" -#include "../SDL_joystick_c.h" - -#define MAX_JOYSTICKS 16 -#define MAX_AXES 6 /* each joystick can have up to 6 axes */ -#define MAX_BUTTONS 32 /* and 32 buttons */ -#define AXIS_MIN -32768 /* minimum value for axis coordinate */ -#define AXIS_MAX 32767 /* maximum value for axis coordinate */ -/* limit axis to 256 possible positions to filter out noise */ -#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/256) -#define JOY_BUTTON_FLAG(n) (1<index; - axis_min[0] = SYS_Joystick[index].wXmin; - axis_max[0] = SYS_Joystick[index].wXmax; - axis_min[1] = SYS_Joystick[index].wYmin; - axis_max[1] = SYS_Joystick[index].wYmax; - axis_min[2] = SYS_Joystick[index].wZmin; - axis_max[2] = SYS_Joystick[index].wZmax; - axis_min[3] = SYS_Joystick[index].wRmin; - axis_max[3] = SYS_Joystick[index].wRmax; - axis_min[4] = SYS_Joystick[index].wUmin; - axis_max[4] = SYS_Joystick[index].wUmax; - axis_min[5] = SYS_Joystick[index].wVmin; - axis_max[5] = SYS_Joystick[index].wVmax; - - /* 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); - } - SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); - - /* set hardware data */ - joystick->hwdata->id = SYS_JoystickID[index]; - for (i = 0; i < MAX_AXES; ++i) { - if ((i < 2) || (SYS_Joystick[index].wCaps & caps_flags[i - 2])) { - joystick->hwdata->transaxis[i].offset = AXIS_MIN - axis_min[i]; - joystick->hwdata->transaxis[i].scale = - (float) (AXIS_MAX - AXIS_MIN) / (axis_max[i] - axis_min[i]); - } else { - joystick->hwdata->transaxis[i].offset = 0; - joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */ - } - } - - /* fill nbuttons, naxes, and nhats fields */ - joystick->nbuttons = SYS_Joystick[index].wNumButtons; - joystick->naxes = SYS_Joystick[index].wNumAxes; - if (SYS_Joystick[index].wCaps & JOYCAPS_HASPOV) { - joystick->nhats = 1; - } else { - joystick->nhats = 0; - } - return (0); -} - -static Uint8 -TranslatePOV(DWORD value) -{ - Uint8 pos; - - pos = SDL_HAT_CENTERED; - if (value != JOY_POVCENTERED) { - if ((value > JOY_POVLEFT) || (value < JOY_POVRIGHT)) { - pos |= SDL_HAT_UP; - } - if ((value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD)) { - pos |= SDL_HAT_RIGHT; - } - if ((value > JOY_POVRIGHT) && (value < JOY_POVLEFT)) { - pos |= SDL_HAT_DOWN; - } - if (value > JOY_POVBACKWARD) { - pos |= SDL_HAT_LEFT; - } - } - return (pos); -} - -/* 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) -{ - MMRESULT result; - int i; - DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, - JOY_RETURNR, JOY_RETURNU, JOY_RETURNV - }; - DWORD pos[MAX_AXES]; - struct _transaxis *transaxis; - int value, change; - JOYINFOEX joyinfo; - - joyinfo.dwSize = sizeof(joyinfo); - joyinfo.dwFlags = JOY_RETURNALL | JOY_RETURNPOVCTS; - if (!joystick->hats) { - joyinfo.dwFlags &= ~(JOY_RETURNPOV | JOY_RETURNPOVCTS); - } - result = joyGetPosEx(joystick->hwdata->id, &joyinfo); - if (result != JOYERR_NOERROR) { - SetMMerror("joyGetPosEx", result); - return; - } - - /* joystick motion events */ - pos[0] = joyinfo.dwXpos; - pos[1] = joyinfo.dwYpos; - pos[2] = joyinfo.dwZpos; - pos[3] = joyinfo.dwRpos; - pos[4] = joyinfo.dwUpos; - pos[5] = joyinfo.dwVpos; - - transaxis = joystick->hwdata->transaxis; - for (i = 0; i < joystick->naxes; i++) { - if (joyinfo.dwFlags & flags[i]) { - value = - (int) (((float) pos[i] + - transaxis[i].offset) * transaxis[i].scale); - change = (value - joystick->axes[i]); - if ((change < -JOY_AXIS_THRESHOLD) - || (change > JOY_AXIS_THRESHOLD)) { - SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value); - } - } - } - - /* joystick button events */ - if (joyinfo.dwFlags & JOY_RETURNBUTTONS) { - for (i = 0; i < joystick->nbuttons; ++i) { - if (joyinfo.dwButtons & JOY_BUTTON_FLAG(i)) { - if (!joystick->buttons[i]) { - SDL_PrivateJoystickButton(joystick, (Uint8) i, - SDL_PRESSED); - } - } else { - if (joystick->buttons[i]) { - SDL_PrivateJoystickButton(joystick, (Uint8) i, - SDL_RELEASED); - } - } - } - } - - /* joystick hat events */ - if (joyinfo.dwFlags & JOY_RETURNPOV) { - Uint8 pos; - - pos = TranslatePOV(joyinfo.dwPOV); - if (pos != joystick->hats[0]) { - SDL_PrivateJoystickHat(joystick, 0, pos); - } - } -} - -/* 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); - joystick->hwdata = NULL; - } -} - -/* Function to perform any system-specific joystick related cleanup */ -void -SDL_SYS_JoystickQuit(void) -{ - int i; - for (i = 0; i < MAX_JOYSTICKS; i++) { - if (SYS_JoystickName[i] != NULL) { - SDL_free(SYS_JoystickName[i]); - SYS_JoystickName[i] = NULL; - } - } -} - - -/* implementation functions */ -void -SetMMerror(char *function, int code) -{ - static char *error; - static char errbuf[1024]; - - errbuf[0] = 0; - switch (code) { - case MMSYSERR_NODRIVER: - error = "Joystick driver not present"; - break; - - case MMSYSERR_INVALPARAM: - case JOYERR_PARMS: - error = "Invalid parameter(s)"; - break; - - case MMSYSERR_BADDEVICEID: - error = "Bad device ID"; - break; - - case JOYERR_UNPLUGGED: - error = "Joystick not attached"; - break; - - case JOYERR_NOCANDO: - error = "Can't capture joystick input"; - break; - - default: - SDL_snprintf(errbuf, SDL_arraysize(errbuf), - "%s: Unknown Multimedia system error: 0x%x", - function, code); - break; - } - - if (!errbuf[0]) { - SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, - error); - } - SDL_SetError("%s", errbuf); -} - -#endif /* SDL_JOYSTICK_WINMM */ -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/joystick/windows/SDL_dxjoystick.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/joystick/windows/SDL_dxjoystick.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,802 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_DINPUT + +/* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de + * A. Formiga's WINMM driver. + * + * Hats and sliders are completely untested; the app I'm writing this for mostly + * doesn't use them and I don't own any joysticks with them. + * + * We don't bother to use event notification here. It doesn't seem to work + * with polled devices, and it's fine to call IDirectInputDevice2_GetDeviceData and + * let it return 0 events. */ + +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" +#define INITGUID /* Only set here, if set twice will cause mingw32 to break. */ +#include "SDL_dxjoystick_c.h" + + +#ifndef DIDFT_OPTIONAL +#define DIDFT_OPTIONAL 0x80000000 +#endif + + +#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */ +#define MAX_JOYSTICKS 8 +#define AXIS_MIN -32768 /* minimum value for axis coordinate */ +#define AXIS_MAX 32767 /* maximum value for axis coordinate */ +#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/100) /* 1% motion */ + +/* external variables referenced. */ +extern HWND SDL_HelperWindow; + + +/* local variables */ +static LPDIRECTINPUT dinput = NULL; +extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion, + LPDIRECTINPUT * ppDI, + LPUNKNOWN punkOuter); +static DIDEVICEINSTANCE SYS_Joystick[MAX_JOYSTICKS]; /* array to hold joystick ID values */ +static int SYS_NumJoysticks; +static HINSTANCE DInputDLL = NULL; + + +/* local prototypes */ +static void SetDIerror(const char *function, HRESULT code); +static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE * + pdidInstance, VOID * pContext); +static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, + LPVOID pvRef); +static Uint8 TranslatePOV(DWORD value); +static int SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, + Sint16 value); +static int SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, + Uint8 value); +static int SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, + Uint8 button, Uint8 state); + +/* Taken from Wine - Thanks! */ +DIOBJECTDATAFORMAT dfDIJoystick2[] = { + { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, + { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, + { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, + { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(16),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(17),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(18),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(19),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(20),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(21),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(22),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(23),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(24),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(25),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(26),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(27),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(28),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(29),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(30),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(31),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(32),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(33),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(34),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(35),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(36),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(37),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(38),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(39),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(40),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(41),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(42),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(43),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(44),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(45),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(46),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(47),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(48),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(49),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(50),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(51),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(52),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(53),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(54),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(55),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(56),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(57),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(58),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(59),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(60),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(61),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(62),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(63),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(64),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(65),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(66),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(67),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(68),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(69),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(70),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(71),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(72),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(73),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(74),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(75),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(76),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(77),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(78),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(79),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(80),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(81),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(82),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(83),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(84),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(85),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(86),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(87),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(88),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(89),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(90),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(91),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(92),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(93),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(94),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(95),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(96),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(97),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(98),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(99),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(100),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(101),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(102),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(103),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(104),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(105),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(106),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(107),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(108),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(109),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(110),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(111),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(112),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(113),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(114),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(115),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(116),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(117),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(118),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(119),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(120),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(121),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(122),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(123),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(124),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(125),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(126),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { NULL,DIJOFS_BUTTON(127),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0}, + { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lVX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lVY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lVZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lVRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lVRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lVRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lAX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lAY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lAZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lARx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lARy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lARz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lFX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lFY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lFZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lFRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lFRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lFRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, + { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, +}; + +const DIDATAFORMAT c_dfDIJoystick2 = { + sizeof(DIDATAFORMAT), + sizeof(DIOBJECTDATAFORMAT), + DIDF_ABSAXIS, + sizeof(DIJOYSTATE2), + SDL_arraysize(dfDIJoystick2), + dfDIJoystick2 +}; + + +/* Convert a DirectInput return code to a text message */ +static void +SetDIerror(const char *function, HRESULT code) +{ + /* + SDL_SetError("%s() [%s]: %s", function, + DXGetErrorString9A(code), DXGetErrorDescription9A(code)); + */ + SDL_SetError("%s() DirectX error %d", function, code); +} + + +/* Function to scan the system for joysticks. + * This function should set SDL_numjoysticks to the number of available + * joysticks. Joystick 0 should be the system default joystick. + * It should return 0, or -1 on an unrecoverable fatal error. + */ +int +SDL_SYS_JoystickInit(void) +{ + HRESULT result; + HINSTANCE instance; + + SYS_NumJoysticks = 0; + + result = CoInitialize(NULL); + if (FAILED(result)) { + SetDIerror("CoInitialize", result); + return (-1); + } + + result = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, + &IID_IDirectInput, (LPVOID)&dinput); + + if (FAILED(result)) { + SetDIerror("CoCreateInstance", result); + return (-1); + } + + /* Because we used CoCreateInstance, we need to Initialize it, first. */ + instance = GetModuleHandle(NULL); + if (instance == NULL) { + SDL_SetError("GetModuleHandle() failed with error code %d.", + GetLastError()); + return (-1); + } + result = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION); + + if (FAILED(result)) { + SetDIerror("IDirectInput::Initialize", result); + return (-1); + } + + /* Look for joysticks, wheels, head trackers, gamepads, etc.. */ + result = IDirectInput_EnumDevices(dinput, + DIDEVTYPE_JOYSTICK, + EnumJoysticksCallback, + NULL, DIEDFL_ATTACHEDONLY); + + return SYS_NumJoysticks; +} + +static BOOL CALLBACK +EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +{ + SDL_memcpy(&SYS_Joystick[SYS_NumJoysticks], pdidInstance, + sizeof(DIDEVICEINSTANCE)); + SYS_NumJoysticks++; + + if (SYS_NumJoysticks >= MAX_JOYSTICKS) + return DIENUM_STOP; + + return DIENUM_CONTINUE; +} + +/* Function to get the device-dependent name of a joystick */ +const char * +SDL_SYS_JoystickName(int index) +{ + /***-> test for invalid index ? */ + return (SYS_Joystick[index].tszProductName); +} + +/* 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) +{ + HRESULT result; + LPDIRECTINPUTDEVICE device; + DIPROPDWORD dipdw; + + SDL_memset(&dipdw, 0, sizeof(DIPROPDWORD)); + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + + + /* allocate memory for system specific hardware data */ + joystick->hwdata = + (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata)); + if (joystick->hwdata == NULL) { + SDL_OutOfMemory(); + return (-1); + } + SDL_memset(joystick->hwdata, 0, sizeof(struct joystick_hwdata)); + joystick->hwdata->buffered = 1; + joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS); + + result = + IDirectInput_CreateDevice(dinput, + &SYS_Joystick[joystick->index]. + guidInstance, &device, NULL); + if (FAILED(result)) { + SetDIerror("IDirectInput::CreateDevice", result); + return (-1); + } + + /* Now get the IDirectInputDevice2 interface, instead. */ + result = IDirectInputDevice_QueryInterface(device, + &IID_IDirectInputDevice2, + (LPVOID *) & joystick-> + hwdata->InputDevice); + /* We are done with this object. Use the stored one from now on. */ + IDirectInputDevice_Release(device); + + if (FAILED(result)) { + SetDIerror("IDirectInputDevice::QueryInterface", result); + return (-1); + } + + /* Aquire shared access. Exclusive access is required for forces, + * though. */ + result = + IDirectInputDevice2_SetCooperativeLevel(joystick->hwdata-> + InputDevice, SDL_HelperWindow, + DISCL_EXCLUSIVE | + DISCL_BACKGROUND); + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::SetCooperativeLevel", result); + return (-1); + } + + /* Use the extended data structure: DIJOYSTATE2. */ + result = + IDirectInputDevice2_SetDataFormat(joystick->hwdata->InputDevice, + &c_dfDIJoystick2); + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::SetDataFormat", result); + return (-1); + } + + /* Get device capabilities */ + result = + IDirectInputDevice2_GetCapabilities(joystick->hwdata->InputDevice, + &joystick->hwdata->Capabilities); + + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::GetCapabilities", result); + return (-1); + } + + /* Force capable? */ + if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { + + result = IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); + + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::Acquire", result); + return (-1); + } + + /* reset all accuators. */ + result = + IDirectInputDevice2_SendForceFeedbackCommand(joystick->hwdata-> + InputDevice, + DISFFC_RESET); + + /* Not necessarily supported, ignore if not supported. + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::SendForceFeedbackCommand", + result); + return (-1); + } + */ + + result = IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice); + + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::Unacquire", result); + return (-1); + } + + /* Turn on auto-centering for a ForceFeedback device (until told + * otherwise). */ + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = DIPROPAUTOCENTER_ON; + + result = + IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, + DIPROP_AUTOCENTER, &dipdw.diph); + + /* Not necessarily supported, ignore if not supported. + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::SetProperty", result); + return (-1); + } + */ + } + + /* What buttons and axes does it have? */ + IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice, + EnumDevObjectsCallback, joystick, + DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); + + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = INPUT_QSIZE; + + /* Set the buffer size */ + result = + IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, + DIPROP_BUFFERSIZE, &dipdw.diph); + + if (result == DI_POLLEDDEVICE) { + /* This device doesn't support buffering, so we're forced + * to use less reliable polling. */ + joystick->hwdata->buffered = 0; + } else if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::SetProperty", result); + return (-1); + } + + return (0); +} + +static BOOL CALLBACK +EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) +{ + SDL_Joystick *joystick = (SDL_Joystick *) pvRef; + HRESULT result; + input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs]; + + in->ofs = dev->dwOfs; + + if (dev->dwType & DIDFT_BUTTON) { + in->type = BUTTON; + in->num = joystick->nbuttons; + joystick->nbuttons++; + } else if (dev->dwType & DIDFT_POV) { + in->type = HAT; + in->num = joystick->nhats; + joystick->nhats++; + } else if (dev->dwType & DIDFT_AXIS) { + DIPROPRANGE diprg; + DIPROPDWORD dilong; + + in->type = AXIS; + in->num = joystick->naxes; + + diprg.diph.dwSize = sizeof(diprg); + diprg.diph.dwHeaderSize = sizeof(diprg.diph); + diprg.diph.dwObj = dev->dwOfs; + diprg.diph.dwHow = DIPH_BYOFFSET; + diprg.lMin = AXIS_MIN; + diprg.lMax = AXIS_MAX; + + result = + IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, + DIPROP_RANGE, &diprg.diph); + if (FAILED(result)) { + return DIENUM_CONTINUE; /* don't use this axis */ + } + + /* Set dead zone to 0. */ + dilong.diph.dwSize = sizeof(dilong); + dilong.diph.dwHeaderSize = sizeof(dilong.diph); + dilong.diph.dwObj = dev->dwOfs; + dilong.diph.dwHow = DIPH_BYOFFSET; + dilong.dwData = 0; + result = + IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, + DIPROP_DEADZONE, &dilong.diph); + if (FAILED(result)) { + return DIENUM_CONTINUE; /* don't use this axis */ + } + + joystick->naxes++; + } else { + /* not supported at this time */ + return DIENUM_CONTINUE; + } + + joystick->hwdata->NumInputs++; + + if (joystick->hwdata->NumInputs == MAX_INPUTS) { + return DIENUM_STOP; /* too many */ + } + + return DIENUM_CONTINUE; +} + +/* 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_Polled(SDL_Joystick * joystick) +{ + DIJOYSTATE2 state; + HRESULT result; + int i; + + result = + IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice, + sizeof(DIJOYSTATE2), &state); + if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { + IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); + result = + IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice, + sizeof(DIJOYSTATE2), &state); + } + + /* Set each known axis, button and POV. */ + for (i = 0; i < joystick->hwdata->NumInputs; ++i) { + const input_t *in = &joystick->hwdata->Inputs[i]; + + switch (in->type) { + case AXIS: + switch (in->ofs) { + case DIJOFS_X: + SDL_PrivateJoystickAxis_Int(joystick, in->num, + (Sint16) state.lX); + break; + case DIJOFS_Y: + SDL_PrivateJoystickAxis_Int(joystick, in->num, + (Sint16) state.lY); + break; + case DIJOFS_Z: + SDL_PrivateJoystickAxis_Int(joystick, in->num, + (Sint16) state.lZ); + break; + case DIJOFS_RX: + SDL_PrivateJoystickAxis_Int(joystick, in->num, + (Sint16) state.lRx); + break; + case DIJOFS_RY: + SDL_PrivateJoystickAxis_Int(joystick, in->num, + (Sint16) state.lRy); + break; + case DIJOFS_RZ: + SDL_PrivateJoystickAxis_Int(joystick, in->num, + (Sint16) state.lRz); + break; + case DIJOFS_SLIDER(0): + SDL_PrivateJoystickAxis_Int(joystick, in->num, + (Sint16) state.rglSlider[0]); + break; + case DIJOFS_SLIDER(1): + SDL_PrivateJoystickAxis_Int(joystick, in->num, + (Sint16) state.rglSlider[1]); + break; + } + + break; + + case BUTTON: + SDL_PrivateJoystickButton_Int(joystick, in->num, + (Uint8) (state. + rgbButtons[in->ofs - + DIJOFS_BUTTON0] + ? SDL_PRESSED : + SDL_RELEASED)); + break; + case HAT: + { + Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - + DIJOFS_POV(0)]); + SDL_PrivateJoystickHat_Int(joystick, in->num, pos); + break; + } + } + } +} + +void +SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) +{ + int i; + HRESULT result; + DWORD numevents; + DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE]; + + numevents = INPUT_QSIZE; + result = + IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice, + sizeof(DIDEVICEOBJECTDATA), evtbuf, + &numevents, 0); + if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { + IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); + result = + IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice, + sizeof(DIDEVICEOBJECTDATA), + evtbuf, &numevents, 0); + } + + /* Handle the events or punt */ + if (FAILED(result)) + return; + + for (i = 0; i < (int) numevents; ++i) { + int j; + + for (j = 0; j < joystick->hwdata->NumInputs; ++j) { + const input_t *in = &joystick->hwdata->Inputs[j]; + + if (evtbuf[i].dwOfs != in->ofs) + continue; + + switch (in->type) { + case AXIS: + SDL_PrivateJoystickAxis(joystick, in->num, + (Sint16) evtbuf[i].dwData); + break; + case BUTTON: + SDL_PrivateJoystickButton(joystick, in->num, + (Uint8) (evtbuf[i]. + dwData ? SDL_PRESSED : + SDL_RELEASED)); + break; + case HAT: + { + Uint8 pos = TranslatePOV(evtbuf[i].dwData); + SDL_PrivateJoystickHat(joystick, in->num, pos); + } + } + } + } +} + + +static Uint8 +TranslatePOV(DWORD value) +{ + const int HAT_VALS[] = { + SDL_HAT_UP, + SDL_HAT_UP | SDL_HAT_RIGHT, + SDL_HAT_RIGHT, + SDL_HAT_DOWN | SDL_HAT_RIGHT, + SDL_HAT_DOWN, + SDL_HAT_DOWN | SDL_HAT_LEFT, + SDL_HAT_LEFT, + SDL_HAT_UP | SDL_HAT_LEFT + }; + + if (LOWORD(value) == 0xFFFF) + return SDL_HAT_CENTERED; + + /* Round the value up: */ + value += 4500 / 2; + value %= 36000; + value /= 4500; + + if (value >= 8) + return SDL_HAT_CENTERED; /* shouldn't happen */ + + return HAT_VALS[value]; +} + +/* SDL_PrivateJoystick* doesn't discard duplicate events, so we need to + * do it. */ +static int +SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, Sint16 value) +{ + if (joystick->axes[axis] != value) + return SDL_PrivateJoystickAxis(joystick, axis, value); + return 0; +} + +static int +SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, Uint8 value) +{ + if (joystick->hats[hat] != value) + return SDL_PrivateJoystickHat(joystick, hat, value); + return 0; +} + +static int +SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, Uint8 button, + Uint8 state) +{ + if (joystick->buttons[button] != state) + return SDL_PrivateJoystickButton(joystick, button, state); + return 0; +} + +void +SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) +{ + HRESULT result; + + result = IDirectInputDevice2_Poll(joystick->hwdata->InputDevice); + if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { + IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); + IDirectInputDevice2_Poll(joystick->hwdata->InputDevice); + } + + if (joystick->hwdata->buffered) + SDL_SYS_JoystickUpdate_Buffered(joystick); + else + SDL_SYS_JoystickUpdate_Polled(joystick); +} + +/* Function to close a joystick after use */ +void +SDL_SYS_JoystickClose(SDL_Joystick * joystick) +{ + IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice); + IDirectInputDevice2_Release(joystick->hwdata->InputDevice); + + 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) +{ + IDirectInput_Release(dinput); + dinput = NULL; +} + +#endif /* SDL_JOYSTICK_DINPUT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/joystick/windows/SDL_dxjoystick_c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/joystick/windows/SDL_dxjoystick_c.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,73 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_JOYSTICK_DINPUT_H + +/* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de + * A. Formiga's WINMM driver. + * + * Hats and sliders are completely untested; the app I'm writing this for mostly + * doesn't use them and I don't own any joysticks with them. + * + * We don't bother to use event notification here. It doesn't seem to work + * with polled devices, and it's fine to call IDirectInputDevice2_GetDeviceData and + * let it return 0 events. */ + +#define WIN32_LEAN_AND_MEAN +#include + +#define DIRECTINPUT_VERSION 0x0700 /* Need version 7 for force feedback. */ +#include + + +#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */ + + +/* local types */ +typedef enum Type +{ BUTTON, AXIS, HAT } Type; + +typedef struct input_t +{ + /* DirectInput offset for this input type: */ + DWORD ofs; + + /* Button, axis or hat: */ + Type type; + + /* SDL input offset: */ + Uint8 num; +} input_t; + +/* The private structure used to keep track of a joystick */ +struct joystick_hwdata +{ + LPDIRECTINPUTDEVICE2 InputDevice; + DIDEVCAPS Capabilities; + int buffered; + + input_t Inputs[MAX_INPUTS]; + int NumInputs; +}; + +#endif /* SDL_JOYSTICK_DINPUT_H */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/joystick/windows/SDL_mmjoystick.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/joystick/windows/SDL_mmjoystick.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,428 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_WINMM + +/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#define MAX_JOYSTICKS 16 +#define MAX_AXES 6 /* each joystick can have up to 6 axes */ +#define MAX_BUTTONS 32 /* and 32 buttons */ +#define AXIS_MIN -32768 /* minimum value for axis coordinate */ +#define AXIS_MAX 32767 /* maximum value for axis coordinate */ +/* limit axis to 256 possible positions to filter out noise */ +#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/256) +#define JOY_BUTTON_FLAG(n) (1<index; + axis_min[0] = SYS_Joystick[index].wXmin; + axis_max[0] = SYS_Joystick[index].wXmax; + axis_min[1] = SYS_Joystick[index].wYmin; + axis_max[1] = SYS_Joystick[index].wYmax; + axis_min[2] = SYS_Joystick[index].wZmin; + axis_max[2] = SYS_Joystick[index].wZmax; + axis_min[3] = SYS_Joystick[index].wRmin; + axis_max[3] = SYS_Joystick[index].wRmax; + axis_min[4] = SYS_Joystick[index].wUmin; + axis_max[4] = SYS_Joystick[index].wUmax; + axis_min[5] = SYS_Joystick[index].wVmin; + axis_max[5] = SYS_Joystick[index].wVmax; + + /* 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); + } + SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); + + /* set hardware data */ + joystick->hwdata->id = SYS_JoystickID[index]; + for (i = 0; i < MAX_AXES; ++i) { + if ((i < 2) || (SYS_Joystick[index].wCaps & caps_flags[i - 2])) { + joystick->hwdata->transaxis[i].offset = AXIS_MIN - axis_min[i]; + joystick->hwdata->transaxis[i].scale = + (float) (AXIS_MAX - AXIS_MIN) / (axis_max[i] - axis_min[i]); + } else { + joystick->hwdata->transaxis[i].offset = 0; + joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */ + } + } + + /* fill nbuttons, naxes, and nhats fields */ + joystick->nbuttons = SYS_Joystick[index].wNumButtons; + joystick->naxes = SYS_Joystick[index].wNumAxes; + if (SYS_Joystick[index].wCaps & JOYCAPS_HASPOV) { + joystick->nhats = 1; + } else { + joystick->nhats = 0; + } + return (0); +} + +static Uint8 +TranslatePOV(DWORD value) +{ + Uint8 pos; + + pos = SDL_HAT_CENTERED; + if (value != JOY_POVCENTERED) { + if ((value > JOY_POVLEFT) || (value < JOY_POVRIGHT)) { + pos |= SDL_HAT_UP; + } + if ((value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD)) { + pos |= SDL_HAT_RIGHT; + } + if ((value > JOY_POVRIGHT) && (value < JOY_POVLEFT)) { + pos |= SDL_HAT_DOWN; + } + if (value > JOY_POVBACKWARD) { + pos |= SDL_HAT_LEFT; + } + } + return (pos); +} + +/* 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) +{ + MMRESULT result; + int i; + DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, + JOY_RETURNR, JOY_RETURNU, JOY_RETURNV + }; + DWORD pos[MAX_AXES]; + struct _transaxis *transaxis; + int value, change; + JOYINFOEX joyinfo; + + joyinfo.dwSize = sizeof(joyinfo); + joyinfo.dwFlags = JOY_RETURNALL | JOY_RETURNPOVCTS; + if (!joystick->hats) { + joyinfo.dwFlags &= ~(JOY_RETURNPOV | JOY_RETURNPOVCTS); + } + result = joyGetPosEx(joystick->hwdata->id, &joyinfo); + if (result != JOYERR_NOERROR) { + SetMMerror("joyGetPosEx", result); + return; + } + + /* joystick motion events */ + pos[0] = joyinfo.dwXpos; + pos[1] = joyinfo.dwYpos; + pos[2] = joyinfo.dwZpos; + pos[3] = joyinfo.dwRpos; + pos[4] = joyinfo.dwUpos; + pos[5] = joyinfo.dwVpos; + + transaxis = joystick->hwdata->transaxis; + for (i = 0; i < joystick->naxes; i++) { + if (joyinfo.dwFlags & flags[i]) { + value = + (int) (((float) pos[i] + + transaxis[i].offset) * transaxis[i].scale); + change = (value - joystick->axes[i]); + if ((change < -JOY_AXIS_THRESHOLD) + || (change > JOY_AXIS_THRESHOLD)) { + SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value); + } + } + } + + /* joystick button events */ + if (joyinfo.dwFlags & JOY_RETURNBUTTONS) { + for (i = 0; i < joystick->nbuttons; ++i) { + if (joyinfo.dwButtons & JOY_BUTTON_FLAG(i)) { + if (!joystick->buttons[i]) { + SDL_PrivateJoystickButton(joystick, (Uint8) i, + SDL_PRESSED); + } + } else { + if (joystick->buttons[i]) { + SDL_PrivateJoystickButton(joystick, (Uint8) i, + SDL_RELEASED); + } + } + } + } + + /* joystick hat events */ + if (joyinfo.dwFlags & JOY_RETURNPOV) { + Uint8 pos; + + pos = TranslatePOV(joyinfo.dwPOV); + if (pos != joystick->hats[0]) { + SDL_PrivateJoystickHat(joystick, 0, pos); + } + } +} + +/* 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); + joystick->hwdata = NULL; + } +} + +/* Function to perform any system-specific joystick related cleanup */ +void +SDL_SYS_JoystickQuit(void) +{ + int i; + for (i = 0; i < MAX_JOYSTICKS; i++) { + if (SYS_JoystickName[i] != NULL) { + SDL_free(SYS_JoystickName[i]); + SYS_JoystickName[i] = NULL; + } + } +} + + +/* implementation functions */ +void +SetMMerror(char *function, int code) +{ + static char *error; + static char errbuf[1024]; + + errbuf[0] = 0; + switch (code) { + case MMSYSERR_NODRIVER: + error = "Joystick driver not present"; + break; + + case MMSYSERR_INVALPARAM: + case JOYERR_PARMS: + error = "Invalid parameter(s)"; + break; + + case MMSYSERR_BADDEVICEID: + error = "Bad device ID"; + break; + + case JOYERR_UNPLUGGED: + error = "Joystick not attached"; + break; + + case JOYERR_NOCANDO: + error = "Can't capture joystick input"; + break; + + default: + SDL_snprintf(errbuf, SDL_arraysize(errbuf), + "%s: Unknown Multimedia system error: 0x%x", + function, code); + break; + } + + if (!errbuf[0]) { + SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, + error); + } + SDL_SetError("%s", errbuf); +} + +#endif /* SDL_JOYSTICK_WINMM */ +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/loadso/win32/SDL_sysloadso.c --- a/src/loadso/win32/SDL_sysloadso.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_WIN32 - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* System dependent library loading routines */ - -#define WIN32_LEAN_AND_MEAN -#include - -#include "SDL_loadso.h" - -void * -SDL_LoadObject(const char *sofile) -{ - void *handle = NULL; - const char *loaderror = "Unknown error"; - -#if defined(_WIN32_WCE) - char errbuf[512]; - - wchar_t *errbuf_t = SDL_malloc(512 * sizeof(wchar_t)); - wchar_t *sofile_t = SDL_malloc((MAX_PATH + 1) * sizeof(wchar_t)); - - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sofile, -1, sofile_t, - MAX_PATH); - handle = (void *) LoadLibrary(sofile_t); - - /* Generate an error message if all loads failed */ - if (handle == NULL) { - FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM), - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - errbuf_t, SDL_arraysize(errbuf), NULL); - WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL); - loaderror = errbuf; - } - - SDL_free(sofile_t); - SDL_free(errbuf_t); - -#else /*if defined(__WIN32__) */ - char errbuf[512]; - - handle = (void *) LoadLibrary(sofile); - - /* Generate an error message if all loads failed */ - if (handle == NULL) { - FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM), - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - errbuf, SDL_arraysize(errbuf), NULL); - loaderror = errbuf; - } -#endif - - if (handle == NULL) { - SDL_SetError("Failed loading %s: %s", sofile, loaderror); - } - return (handle); -} - -void * -SDL_LoadFunction(void *handle, const char *name) -{ - void *symbol = NULL; - const char *loaderror = "Unknown error"; - -#if defined(_WIN32_WCE) - char errbuf[512]; - int length = SDL_strlen(name); - - wchar_t *name_t = SDL_malloc((length + 1) * sizeof(wchar_t)); - wchar_t *errbuf_t = SDL_malloc(512 * sizeof(wchar_t)); - - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, name_t, length + 1); - - symbol = (void *) GetProcAddress((HMODULE) handle, name_t); - if (symbol == NULL) { - FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM), - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - errbuf_t, SDL_arraysize(errbuf), NULL); - WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL); - loaderror = errbuf; - } - - SDL_free(name_t); - SDL_free(errbuf_t); - -#else /*if defined(WIN32) */ - char errbuf[512]; - - symbol = (void *) GetProcAddress((HMODULE) handle, name); - if (symbol == NULL) { - FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM), - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - errbuf, SDL_arraysize(errbuf), NULL); - loaderror = errbuf; - } -#endif - - if (symbol == NULL) { - SDL_SetError("Failed loading %s: %s", name, loaderror); - } - return (symbol); -} - -void -SDL_UnloadObject(void *handle) -{ - if (handle != NULL) { - FreeLibrary((HMODULE) handle); - } -} - -#endif /* SDL_LOADSO_WIN32 */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/loadso/windows/SDL_sysloadso.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/loadso/windows/SDL_sysloadso.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,145 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_WINDOWS + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent library loading routines */ + +#define WIN32_LEAN_AND_MEAN +#include + +#include "SDL_loadso.h" + +void * +SDL_LoadObject(const char *sofile) +{ + void *handle = NULL; + const char *loaderror = "Unknown error"; + +#if defined(_WIN32_WCE) + char errbuf[512]; + + wchar_t *errbuf_t = SDL_malloc(512 * sizeof(wchar_t)); + wchar_t *sofile_t = SDL_malloc((MAX_PATH + 1) * sizeof(wchar_t)); + + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sofile, -1, sofile_t, + MAX_PATH); + handle = (void *) LoadLibrary(sofile_t); + + /* Generate an error message if all loads failed */ + if (handle == NULL) { + FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM), + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + errbuf_t, SDL_arraysize(errbuf), NULL); + WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL); + loaderror = errbuf; + } + + SDL_free(sofile_t); + SDL_free(errbuf_t); + +#else /*if defined(__WINDOWS__) */ + char errbuf[512]; + + handle = (void *) LoadLibrary(sofile); + + /* Generate an error message if all loads failed */ + if (handle == NULL) { + FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM), + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + errbuf, SDL_arraysize(errbuf), NULL); + loaderror = errbuf; + } +#endif + + if (handle == NULL) { + SDL_SetError("Failed loading %s: %s", sofile, loaderror); + } + return (handle); +} + +void * +SDL_LoadFunction(void *handle, const char *name) +{ + void *symbol = NULL; + const char *loaderror = "Unknown error"; + +#if defined(_WIN32_WCE) + char errbuf[512]; + int length = SDL_strlen(name); + + wchar_t *name_t = SDL_malloc((length + 1) * sizeof(wchar_t)); + wchar_t *errbuf_t = SDL_malloc(512 * sizeof(wchar_t)); + + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, name_t, length + 1); + + symbol = (void *) GetProcAddress((HMODULE) handle, name_t); + if (symbol == NULL) { + FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM), + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + errbuf_t, SDL_arraysize(errbuf), NULL); + WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL); + loaderror = errbuf; + } + + SDL_free(name_t); + SDL_free(errbuf_t); + +#else /*if defined(WIN32) */ + char errbuf[512]; + + symbol = (void *) GetProcAddress((HMODULE) handle, name); + if (symbol == NULL) { + FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM), + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + errbuf, SDL_arraysize(errbuf), NULL); + loaderror = errbuf; + } +#endif + + if (symbol == NULL) { + SDL_SetError("Failed loading %s: %s", name, loaderror); + } + return (symbol); +} + +void +SDL_UnloadObject(void *handle) +{ + if (handle != NULL) { + FreeLibrary((HMODULE) handle); + } +} + +#endif /* SDL_LOADSO_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/main/win32/SDL_win32_main.c --- a/src/main/win32/SDL_win32_main.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,205 +0,0 @@ -/* - SDL_main.c, placed in the public domain by Sam Lantinga 4/13/98 - - The WinMain function -- calls your program's main() function -*/ - -#include -#include - -#define WIN32_LEAN_AND_MEAN -#include - -/* Include the SDL main definition header */ -#include "SDL.h" -#include "SDL_main.h" - -#ifdef main -# ifndef _WIN32_WCE_EMULATION -# undef main -# endif /* _WIN32_WCE_EMULATION */ -#endif /* main */ - -#if defined(_WIN32_WCE) && _WIN32_WCE < 300 -/* seems to be undefined in Win CE although in online help */ -#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) -#endif /* _WIN32_WCE < 300 */ - -static void -UnEscapeQuotes(char *arg) -{ - char *last = NULL; - - while (*arg) { - if (*arg == '"' && *last == '\\') { - char *c_curr = arg; - char *c_last = last; - - while (*c_curr) { - *c_last = *c_curr; - c_last = c_curr; - c_curr++; - } - *c_last = '\0'; - } - last = arg; - arg++; - } -} - -/* Parse a command line buffer into arguments */ -static int -ParseCommandLine(char *cmdline, char **argv) -{ - char *bufp; - char *lastp = NULL; - int argc, last_argc; - - argc = last_argc = 0; - for (bufp = cmdline; *bufp;) { - /* Skip leading whitespace */ - while (isspace(*bufp)) { - ++bufp; - } - /* Skip over argument */ - if (*bufp == '"') { - ++bufp; - if (*bufp) { - if (argv) { - argv[argc] = bufp; - } - ++argc; - } - /* Skip over word */ - lastp = bufp; - while (*bufp && (*bufp != '"' || *lastp == '\\')) { - lastp = bufp; - ++bufp; - } - } else { - if (*bufp) { - if (argv) { - argv[argc] = bufp; - } - ++argc; - } - /* Skip over word */ - while (*bufp && !isspace(*bufp)) { - ++bufp; - } - } - if (*bufp) { - if (argv) { - *bufp = '\0'; - } - ++bufp; - } - - /* Strip out \ from \" sequences */ - if (argv && last_argc != argc) { - UnEscapeQuotes(argv[last_argc]); - } - last_argc = argc; - } - if (argv) { - argv[argc] = NULL; - } - return (argc); -} - -/* Show an error message */ -static void -ShowError(const char *title, const char *message) -{ -/* If USE_MESSAGEBOX is defined, you need to link with user32.lib */ -#ifdef USE_MESSAGEBOX - MessageBox(NULL, message, title, MB_ICONEXCLAMATION | MB_OK); -#else - fprintf(stderr, "%s: %s\n", title, message); -#endif -} - -/* Pop up an out of memory message, returns to Windows */ -static BOOL -OutOfMemory(void) -{ - ShowError("Fatal Error", "Out of memory - aborting"); - return FALSE; -} - -#if defined(_MSC_VER) && !defined(_WIN32_WCE) -/* The VC++ compiler needs main defined */ -#define console_main main -#endif - -/* This is where execution begins [console apps] */ -int -console_main(int argc, char *argv[]) -{ - int status; - - /* Run the application main() code */ - status = SDL_main(argc, argv); - - /* Exit cleanly, calling atexit() functions */ - exit(status); - - /* Hush little compiler, don't you cry... */ - return 0; -} - -/* This is where execution begins [windowed apps] */ -int WINAPI -WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int sw) -{ - char **argv; - int argc; - char *cmdline; -#ifdef _WIN32_WCE - wchar_t *bufp; - int nLen; -#else - char *bufp; - size_t nLen; -#endif - -#ifdef _WIN32_WCE - nLen = wcslen(szCmdLine) + 128 + 1; - bufp = SDL_stack_alloc(wchar_t, nLen * 2); - wcscpy(bufp, TEXT("\"")); - GetModuleFileName(NULL, bufp + 1, 128 - 3); - wcscpy(bufp + wcslen(bufp), TEXT("\" ")); - wcsncpy(bufp + wcslen(bufp), szCmdLine, nLen - wcslen(bufp)); - nLen = wcslen(bufp) + 1; - cmdline = SDL_stack_alloc(char, nLen); - if (cmdline == NULL) { - return OutOfMemory(); - } - WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL); -#else - /* Grab the command line */ - bufp = GetCommandLine(); - nLen = SDL_strlen(bufp) + 1; - cmdline = SDL_stack_alloc(char, nLen); - if (cmdline == NULL) { - return OutOfMemory(); - } - SDL_strlcpy(cmdline, bufp, nLen); -#endif - - /* Parse it into argv and argc */ - argc = ParseCommandLine(cmdline, NULL); - argv = SDL_stack_alloc(char *, argc + 1); - if (argv == NULL) { - return OutOfMemory(); - } - ParseCommandLine(cmdline, argv); - - /* Run the main program */ - console_main(argc, argv); - - /* Hush little compiler, don't you cry... */ - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/main/win32/version.rc --- a/src/main/win32/version.rc Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ - -#include "winresrc.h" - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,0,0 - PRODUCTVERSION 1,3,0,0 - FILEFLAGSMASK 0x3fL - FILEFLAGS 0x0L - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "\0" - VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 3, 0, 0\0" - VALUE "InternalName", "SDL\0" - VALUE "LegalCopyright", "Copyright © 2009 Sam Lantinga\0" - VALUE "OriginalFilename", "SDL.dll\0" - VALUE "ProductName", "Simple DirectMedia Layer\0" - VALUE "ProductVersion", "1, 3, 0, 0\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff -r 9e9940eae455 -r e8916fe9cfc8 src/main/windows/SDL_windows_main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/windows/SDL_windows_main.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,205 @@ +/* + SDL_main.c, placed in the public domain by Sam Lantinga 4/13/98 + + The WinMain function -- calls your program's main() function +*/ + +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +/* Include the SDL main definition header */ +#include "SDL.h" +#include "SDL_main.h" + +#ifdef main +# ifndef _WIN32_WCE_EMULATION +# undef main +# endif /* _WIN32_WCE_EMULATION */ +#endif /* main */ + +#if defined(_WIN32_WCE) && _WIN32_WCE < 300 +/* seems to be undefined in Win CE although in online help */ +#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) +#endif /* _WIN32_WCE < 300 */ + +static void +UnEscapeQuotes(char *arg) +{ + char *last = NULL; + + while (*arg) { + if (*arg == '"' && *last == '\\') { + char *c_curr = arg; + char *c_last = last; + + while (*c_curr) { + *c_last = *c_curr; + c_last = c_curr; + c_curr++; + } + *c_last = '\0'; + } + last = arg; + arg++; + } +} + +/* Parse a command line buffer into arguments */ +static int +ParseCommandLine(char *cmdline, char **argv) +{ + char *bufp; + char *lastp = NULL; + int argc, last_argc; + + argc = last_argc = 0; + for (bufp = cmdline; *bufp;) { + /* Skip leading whitespace */ + while (isspace(*bufp)) { + ++bufp; + } + /* Skip over argument */ + if (*bufp == '"') { + ++bufp; + if (*bufp) { + if (argv) { + argv[argc] = bufp; + } + ++argc; + } + /* Skip over word */ + lastp = bufp; + while (*bufp && (*bufp != '"' || *lastp == '\\')) { + lastp = bufp; + ++bufp; + } + } else { + if (*bufp) { + if (argv) { + argv[argc] = bufp; + } + ++argc; + } + /* Skip over word */ + while (*bufp && !isspace(*bufp)) { + ++bufp; + } + } + if (*bufp) { + if (argv) { + *bufp = '\0'; + } + ++bufp; + } + + /* Strip out \ from \" sequences */ + if (argv && last_argc != argc) { + UnEscapeQuotes(argv[last_argc]); + } + last_argc = argc; + } + if (argv) { + argv[argc] = NULL; + } + return (argc); +} + +/* Show an error message */ +static void +ShowError(const char *title, const char *message) +{ +/* If USE_MESSAGEBOX is defined, you need to link with user32.lib */ +#ifdef USE_MESSAGEBOX + MessageBox(NULL, message, title, MB_ICONEXCLAMATION | MB_OK); +#else + fprintf(stderr, "%s: %s\n", title, message); +#endif +} + +/* Pop up an out of memory message, returns to Windows */ +static BOOL +OutOfMemory(void) +{ + ShowError("Fatal Error", "Out of memory - aborting"); + return FALSE; +} + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) +/* The VC++ compiler needs main defined */ +#define console_main main +#endif + +/* This is where execution begins [console apps] */ +int +console_main(int argc, char *argv[]) +{ + int status; + + /* Run the application main() code */ + status = SDL_main(argc, argv); + + /* Exit cleanly, calling atexit() functions */ + exit(status); + + /* Hush little compiler, don't you cry... */ + return 0; +} + +/* This is where execution begins [windowed apps] */ +int WINAPI +WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int sw) +{ + char **argv; + int argc; + char *cmdline; +#ifdef _WIN32_WCE + wchar_t *bufp; + int nLen; +#else + char *bufp; + size_t nLen; +#endif + +#ifdef _WIN32_WCE + nLen = wcslen(szCmdLine) + 128 + 1; + bufp = SDL_stack_alloc(wchar_t, nLen * 2); + wcscpy(bufp, TEXT("\"")); + GetModuleFileName(NULL, bufp + 1, 128 - 3); + wcscpy(bufp + wcslen(bufp), TEXT("\" ")); + wcsncpy(bufp + wcslen(bufp), szCmdLine, nLen - wcslen(bufp)); + nLen = wcslen(bufp) + 1; + cmdline = SDL_stack_alloc(char, nLen); + if (cmdline == NULL) { + return OutOfMemory(); + } + WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL); +#else + /* Grab the command line */ + bufp = GetCommandLine(); + nLen = SDL_strlen(bufp) + 1; + cmdline = SDL_stack_alloc(char, nLen); + if (cmdline == NULL) { + return OutOfMemory(); + } + SDL_strlcpy(cmdline, bufp, nLen); +#endif + + /* Parse it into argv and argc */ + argc = ParseCommandLine(cmdline, NULL); + argv = SDL_stack_alloc(char *, argc + 1); + if (argv == NULL) { + return OutOfMemory(); + } + ParseCommandLine(cmdline, argv); + + /* Run the main program */ + console_main(argc, argv); + + /* Hush little compiler, don't you cry... */ + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/main/windows/version.rc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/windows/version.rc Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,38 @@ + +#include "winresrc.h" + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,3,0,0 + PRODUCTVERSION 1,3,0,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "SDL\0" + VALUE "FileVersion", "1, 3, 0, 0\0" + VALUE "InternalName", "SDL\0" + VALUE "LegalCopyright", "Copyright © 2009 Sam Lantinga\0" + VALUE "OriginalFilename", "SDL.dll\0" + VALUE "ProductName", "Simple DirectMedia Layer\0" + VALUE "ProductVersion", "1, 3, 0, 0\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff -r 9e9940eae455 -r e8916fe9cfc8 src/stdlib/SDL_getenv.c --- a/src/stdlib/SDL_getenv.c Thu Jan 20 17:33:06 2011 -0800 +++ b/src/stdlib/SDL_getenv.c Thu Jan 20 18:04:05 2011 -0800 @@ -25,7 +25,7 @@ #ifndef HAVE_GETENV -#if defined(__WIN32__) && !defined(_WIN32_WCE) +#if defined(__WINDOWS__) && !defined(_WIN32_WCE) #define WIN32_LEAN_AND_MEAN #include @@ -163,7 +163,7 @@ return value; } -#endif /* __WIN32__ */ +#endif /* __WINDOWS__ */ #endif /* !HAVE_GETENV */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/SDL_thread_c.h --- a/src/thread/SDL_thread_c.h Thu Jan 20 17:33:06 2011 -0800 +++ b/src/thread/SDL_thread_c.h Thu Jan 20 18:04:05 2011 -0800 @@ -35,8 +35,8 @@ #include "pthread/SDL_systhread_c.h" #elif SDL_THREAD_SPROC #include "irix/SDL_systhread_c.h" -#elif SDL_THREAD_WIN32 -#include "win32/SDL_systhread_c.h" +#elif SDL_THREAD_WINDOWS +#include "windows/SDL_systhread_c.h" #elif SDL_THREAD_NDS #include "nds/SDL_systhread_c.h" #else diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/win32/SDL_sysmutex.c --- a/src/thread/win32/SDL_sysmutex.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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 Win32 API */ - -#define WIN32_LEAN_AND_MEAN -#include - -#include "SDL_mutex.h" - - -struct SDL_mutex -{ - HANDLE id; -}; - -/* Create a mutex */ -SDL_mutex * -SDL_CreateMutex(void) -{ - SDL_mutex *mutex; - - /* Allocate mutex memory */ - mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); - if (mutex) { - /* Create the mutex, with initial value signaled */ - mutex->id = CreateMutex(NULL, FALSE, NULL); - if (!mutex->id) { - SDL_SetError("Couldn't create mutex"); - SDL_free(mutex); - mutex = NULL; - } - } else { - SDL_OutOfMemory(); - } - return (mutex); -} - -/* Free the mutex */ -void -SDL_DestroyMutex(SDL_mutex * mutex) -{ - if (mutex) { - if (mutex->id) { - CloseHandle(mutex->id); - mutex->id = 0; - } - SDL_free(mutex); - } -} - -/* Lock the mutex */ -int -SDL_mutexP(SDL_mutex * mutex) -{ - if (mutex == NULL) { - SDL_SetError("Passed a NULL mutex"); - return -1; - } - if (WaitForSingleObject(mutex->id, INFINITE) == WAIT_FAILED) { - SDL_SetError("Couldn't wait on mutex"); - return -1; - } - return (0); -} - -/* Unlock the mutex */ -int -SDL_mutexV(SDL_mutex * mutex) -{ - if (mutex == NULL) { - SDL_SetError("Passed a NULL mutex"); - return -1; - } - if (ReleaseMutex(mutex->id) == FALSE) { - SDL_SetError("Couldn't release mutex"); - return -1; - } - return (0); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/win32/SDL_syssem.c --- a/src/thread/win32/SDL_syssem.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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 Win32 API */ - -#define WIN32_LEAN_AND_MEAN -#include - -#include "SDL_thread.h" -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) -#include "win_ce_semaphore.h" -#endif - - -struct SDL_semaphore -{ -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - SYNCHHANDLE id; -#else - HANDLE id; -#endif - LONG volatile count; -}; - - -/* Create a semaphore */ -SDL_sem * -SDL_CreateSemaphore(Uint32 initial_value) -{ - SDL_sem *sem; - - /* Allocate sem memory */ - sem = (SDL_sem *) SDL_malloc(sizeof(*sem)); - if (sem) { - /* Create the semaphore, with max value 32K */ -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - sem->id = CreateSemaphoreCE(NULL, initial_value, 32 * 1024, NULL); -#else - sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL); -#endif - sem->count = initial_value; - if (!sem->id) { - SDL_SetError("Couldn't create semaphore"); - SDL_free(sem); - sem = NULL; - } - } else { - SDL_OutOfMemory(); - } - return (sem); -} - -/* Free the semaphore */ -void -SDL_DestroySemaphore(SDL_sem * sem) -{ - if (sem) { - if (sem->id) { -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - CloseSynchHandle(sem->id); -#else - CloseHandle(sem->id); -#endif - sem->id = 0; - } - SDL_free(sem); - } -} - -int -SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) -{ - int retval; - DWORD dwMilliseconds; - - if (!sem) { - SDL_SetError("Passed a NULL sem"); - return -1; - } - - if (timeout == SDL_MUTEX_MAXWAIT) { - dwMilliseconds = INFINITE; - } else { - dwMilliseconds = (DWORD) timeout; - } -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - switch (WaitForSemaphoreCE(sem->id, dwMilliseconds)) { -#else - switch (WaitForSingleObject(sem->id, dwMilliseconds)) { -#endif - case WAIT_OBJECT_0: - InterlockedDecrement(&sem->count); - retval = 0; - break; - case WAIT_TIMEOUT: - retval = SDL_MUTEX_TIMEDOUT; - break; - default: - SDL_SetError("WaitForSingleObject() failed"); - retval = -1; - break; - } - return retval; -} - -int -SDL_SemTryWait(SDL_sem * sem) -{ - return SDL_SemWaitTimeout(sem, 0); -} - -int -SDL_SemWait(SDL_sem * sem) -{ - return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); -} - -/* Returns the current count of the semaphore */ -Uint32 -SDL_SemValue(SDL_sem * sem) -{ - if (!sem) { - SDL_SetError("Passed a NULL sem"); - return 0; - } - return (Uint32)sem->count; -} - -int -SDL_SemPost(SDL_sem * sem) -{ - if (!sem) { - SDL_SetError("Passed a NULL sem"); - return -1; - } - /* Increase the counter in the first place, because - * after a successful release the semaphore may - * immediately get destroyed by another thread which - * is waiting for this semaphore. - */ - InterlockedIncrement(&sem->count); -#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) - if (ReleaseSemaphoreCE(sem->id, 1, NULL) == FALSE) { -#else - if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) { -#endif - InterlockedDecrement(&sem->count); /* restore */ - SDL_SetError("ReleaseSemaphore() failed"); - return -1; - } - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/win32/SDL_systhread.c --- a/src/thread/win32/SDL_systhread.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -/* Win32 thread management routines for SDL */ - -#define WIN32_LEAN_AND_MEAN -#include - -#include "SDL_thread.h" -#include "../SDL_thread_c.h" -#include "../SDL_systhread.h" - -#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD -#ifndef _WIN32_WCE -/* We'll use the C library from this DLL */ -#include -#endif - -#if __GNUC__ -typedef uintptr_t (__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, - unsigned - (__stdcall * - func) (void *), - void *arg, - unsigned, - unsigned - *threadID); -typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); -#elif defined(__WATCOMC__) -/* This is for Watcom targets except OS2 */ -#if __WATCOMC__ < 1240 -#define __watcall -#endif -typedef unsigned long (__watcall * pfnSDL_CurrentBeginThread) (void *, - unsigned, - unsigned - (__stdcall * - func) (void - *), - void *arg, - unsigned, - unsigned - *threadID); -typedef void (__watcall * pfnSDL_CurrentEndThread) (unsigned code); -#else -typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, - unsigned (__stdcall * - func) (void - *), - void *arg, unsigned, - unsigned *threadID); -typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); -#endif -#endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */ - - -typedef struct ThreadStartParms -{ - void *args; - pfnSDL_CurrentEndThread pfnCurrentEndThread; -} tThreadStartParms, *pThreadStartParms; - -static DWORD __stdcall -RunThread(void *data) -{ - pThreadStartParms pThreadParms = (pThreadStartParms) data; - 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) (0); - return (0); -} - -#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD -int -SDL_SYS_CreateThread(SDL_Thread * thread, void *args, - pfnSDL_CurrentBeginThread pfnBeginThread, - pfnSDL_CurrentEndThread pfnEndThread) -{ -#else -int -SDL_SYS_CreateThread(SDL_Thread * thread, void *args) -{ -#ifdef _WIN32_WCE - pfnSDL_CurrentBeginThread pfnBeginThread = NULL; - pfnSDL_CurrentEndThread pfnEndThread = NULL; -#else - pfnSDL_CurrentBeginThread pfnBeginThread = _beginthreadex; - pfnSDL_CurrentEndThread pfnEndThread = _endthreadex; -#endif -#endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */ - unsigned threadid; - pThreadStartParms pThreadParms = - (pThreadStartParms) SDL_malloc(sizeof(tThreadStartParms)); - if (!pThreadParms) { - SDL_OutOfMemory(); - 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; - - if (pfnBeginThread) { - thread->handle = - (SYS_ThreadHandle) pfnBeginThread(NULL, 0, RunThread, - pThreadParms, 0, &threadid); - } else { - thread->handle = - CreateThread(NULL, 0, RunThread, pThreadParms, 0, &threadid); - } - if (thread->handle == NULL) { - SDL_SetError("Not enough resources to create thread"); - return (-1); - } - return (0); -} - -void -SDL_SYS_SetupThread(void) -{ - return; -} - -SDL_threadID -SDL_ThreadID(void) -{ - return ((SDL_threadID) GetCurrentThreadId()); -} - -void -SDL_SYS_WaitThread(SDL_Thread * thread) -{ - WaitForSingleObject(thread->handle, INFINITE); - CloseHandle(thread->handle); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/win32/SDL_systhread_c.h --- a/src/thread/win32/SDL_systhread_c.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#define WIN32_LEAN_AND_MEAN -#include - -typedef HANDLE SYS_ThreadHandle; - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/win32/win_ce_semaphore.c --- a/src/thread/win32/win_ce_semaphore.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,228 +0,0 @@ -/* win_ce_semaphore.c - - Copyright (c) 1998, Johnson M. Hart - (with corrections 2001 by Rainer Loritz) - Permission is granted for any and all use providing that this - copyright is properly acknowledged. - There are no assurances of suitability for any use whatsoever. - - WINDOWS CE: There is a collection of Windows CE functions to simulate - semaphores using only a mutex and an event. As Windows CE events cannot - be named, these simulated semaphores cannot be named either. - - Implementation notes: - 1. All required internal data structures are allocated on the process's heap. - 2. Where appropriate, a new error code is returned (see the header - file), or, if the error is a Win32 error, that code is unchanged. - 3. Notice the new handle type "SYNCHHANDLE" that has handles, counters, - and other information. This structure will grow as new objects are added - to this set; some members are specific to only one or two of the objects. - 4. Mutexes are used for critical sections. These could be replaced with - CRITICAL_SECTION objects but then this would give up the time out - capability. - 5. The implementation shows several interesting aspects of synchronization, some - of which are specific to Win32 and some of which are general. These are pointed - out in the comments as appropriate. - 6. The wait function emulates WaitForSingleObject only. An emulation of - WaitForMultipleObjects is much harder to implement outside the kernel, - and it is not clear how to handle a mixture of WCE semaphores and normal - events and mutexes. */ - -#define WIN32_LEAN_AND_MEAN -#include - -#include "win_ce_semaphore.h" - -static SYNCHHANDLE CleanUp(SYNCHHANDLE hSynch, DWORD Flags); - -SYNCHHANDLE -CreateSemaphoreCE(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, /* pointer to security attributes */ - LONG lInitialCount, /* initial count */ - LONG lMaximumCount, /* maximum count */ - LPCTSTR lpName) -/* Semaphore for use with Windows CE that does not support them directly. - Requires a counter, a mutex to protect the counter, and an - autoreset event. - - Here are the rules that must always hold between the autoreset event - and the mutex (any violation of these rules by the CE semaphore functions - will, in all likelihood, result in a defect): - 1. No thread can set, pulse, or reset the event, - nor can it access any part of the SYNCHHANDLE structure, - without first gaining ownership of the mutex. - BUT, a thread can wait on the event without owning the mutex - (this is clearly necessary or else the event could never be set). - 2. The event is in a signaled state if and only if the current semaphore - count ("CurCount") is greater than zero. - 3. The semaphore count is always >= 0 and <= the maximum count */ -{ - SYNCHHANDLE hSynch = NULL, result = NULL; - - __try { - if (lInitialCount > lMaximumCount || lMaximumCount < 0 - || lInitialCount < 0) { - /* Bad parameters */ - SetLastError(SYNCH_ERROR); - __leave; - } - - hSynch = - HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SYNCH_HANDLE_SIZE); - if (hSynch == NULL) - __leave; - - hSynch->MaxCount = lMaximumCount; - hSynch->CurCount = lInitialCount; - hSynch->lpName = lpName; - - hSynch->hMutex = CreateMutex(lpSemaphoreAttributes, FALSE, NULL); - - WaitForSingleObject(hSynch->hMutex, INFINITE); - /* Create the event. It is initially signaled if and only if the - initial count is > 0 */ - hSynch->hEvent = CreateEvent(lpSemaphoreAttributes, FALSE, - lInitialCount > 0, NULL); - ReleaseMutex(hSynch->hMutex); - hSynch->hSemph = NULL; - } - __finally { - /* Return with the handle, or, if there was any error, return - a null after closing any open handles and freeing any allocated memory. */ - result = - CleanUp(hSynch, 6 /* An event and a mutex, but no semaphore. */ ); - } - - return result; -} - -BOOL -ReleaseSemaphoreCE(SYNCHHANDLE hSemCE, LONG cReleaseCount, - LPLONG lpPreviousCount) -/* Windows CE equivalent to ReleaseSemaphore. */ -{ - BOOL Result = TRUE; - - /* Gain access to the object to assure that the release count - would not cause the total count to exceed the maximum. */ - - __try { - WaitForSingleObject(hSemCE->hMutex, INFINITE); - /* reply only if asked to */ - if (lpPreviousCount != NULL) - *lpPreviousCount = hSemCE->CurCount; - if (hSemCE->CurCount + cReleaseCount > hSemCE->MaxCount - || cReleaseCount <= 0) { - SetLastError(SYNCH_ERROR); - Result = FALSE; - __leave; - } - hSemCE->CurCount += cReleaseCount; - - /* Set the autoreset event, releasing exactly one waiting thread, now or - in the future. */ - - SetEvent(hSemCE->hEvent); - } - __finally { - ReleaseMutex(hSemCE->hMutex); - } - - return Result; -} - -DWORD -WaitForSemaphoreCE(SYNCHHANDLE hSemCE, DWORD dwMilliseconds) - /* Windows CE semaphore equivalent of WaitForSingleObject. */ -{ - DWORD WaitResult; - - WaitResult = WaitForSingleObject(hSemCE->hMutex, dwMilliseconds); - if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) - return WaitResult; - while (hSemCE->CurCount <= 0) { - - /* The count is 0, and the thread must wait on the event (which, by - the rules, is currently reset) for semaphore resources to become - available. First, of course, the mutex must be released so that another - thread will be capable of setting the event. */ - - ReleaseMutex(hSemCE->hMutex); - - /* Wait for the event to be signaled, indicating a semaphore state change. - The event is autoreset and signaled with a SetEvent (not PulseEvent) - so exactly one waiting thread (whether or not there is currently - a waiting thread) is released as a result of the SetEvent. */ - - WaitResult = WaitForSingleObject(hSemCE->hEvent, dwMilliseconds); - if (WaitResult != WAIT_OBJECT_0) - return WaitResult; - - /* This is where the properties of setting of an autoreset event is critical - to assure that, even if the semaphore state changes between the - preceding Wait and the next, and even if NO threads are waiting - on the event at the time of the SetEvent, at least one thread - will be released. - Pulsing a manual reset event would appear to work, but it would have - a defect which could appear if the semaphore state changed between - the two waits. */ - - WaitResult = WaitForSingleObject(hSemCE->hMutex, dwMilliseconds); - if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) - return WaitResult; - - } - /* The count is not zero and this thread owns the mutex. */ - - hSemCE->CurCount--; - /* The event is now unsignaled, BUT, the semaphore count may not be - zero, in which case the event should be signaled again - before releasing the mutex. */ - - if (hSemCE->CurCount > 0) - SetEvent(hSemCE->hEvent); - ReleaseMutex(hSemCE->hMutex); - return WaitResult; -} - -BOOL -CloseSynchHandle(SYNCHHANDLE hSynch) -/* Close a synchronization handle. - Improvement: Test for a valid handle before dereferencing the handle. */ -{ - BOOL Result = TRUE; - if (hSynch->hEvent != NULL) - Result = Result && CloseHandle(hSynch->hEvent); - if (hSynch->hMutex != NULL) - Result = Result && CloseHandle(hSynch->hMutex); - if (hSynch->hSemph != NULL) - Result = Result && CloseHandle(hSynch->hSemph); - HeapFree(GetProcessHeap(), 0, hSynch); - return (Result); -} - -static SYNCHHANDLE -CleanUp(SYNCHHANDLE hSynch, DWORD Flags) -{ /* Prepare to return from a create of a synchronization handle. - If there was any failure, free any allocated resources. - "Flags" indicates which Win32 objects are required in the - synchronization handle. */ - - BOOL ok = TRUE; - - if (hSynch == NULL) - return NULL; - if ((Flags & 4) == 1 && (hSynch->hEvent == NULL)) - ok = FALSE; - if ((Flags & 2) == 1 && (hSynch->hMutex == NULL)) - ok = FALSE; - if ((Flags & 1) == 1 && (hSynch->hEvent == NULL)) - ok = FALSE; - if (!ok) { - CloseSynchHandle(hSynch); - return NULL; - } - /* Everything worked */ - return hSynch; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/win32/win_ce_semaphore.h --- a/src/thread/win32/win_ce_semaphore.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/* win_ce_semaphore.h - header file to go with win_ce_semaphore.c */ - -typedef struct _SYNCH_HANDLE_STRUCTURE -{ - HANDLE hEvent; - HANDLE hMutex; - HANDLE hSemph; - LONG MaxCount; - volatile LONG CurCount; - LPCTSTR lpName; -} SYNCH_HANDLE_STRUCTURE, *SYNCHHANDLE; - -#define SYNCH_HANDLE_SIZE sizeof (SYNCH_HANDLE_STRUCTURE) - - /* Error codes - all must have bit 29 set */ -#define SYNCH_ERROR 0X20000000 /* EXERCISE - REFINE THE ERROR NUMBERS */ - -extern SYNCHHANDLE CreateSemaphoreCE(LPSECURITY_ATTRIBUTES, LONG, LONG, - LPCTSTR); - -extern BOOL ReleaseSemaphoreCE(SYNCHHANDLE, LONG, LPLONG); -extern DWORD WaitForSemaphoreCE(SYNCHHANDLE, DWORD); - -extern BOOL CloseSynchHandle(SYNCHHANDLE); -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/windows/SDL_sysmutex.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/thread/windows/SDL_sysmutex.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,102 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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 Win32 API */ + +#define WIN32_LEAN_AND_MEAN +#include + +#include "SDL_mutex.h" + + +struct SDL_mutex +{ + HANDLE id; +}; + +/* Create a mutex */ +SDL_mutex * +SDL_CreateMutex(void) +{ + SDL_mutex *mutex; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); + if (mutex) { + /* Create the mutex, with initial value signaled */ + mutex->id = CreateMutex(NULL, FALSE, NULL); + if (!mutex->id) { + SDL_SetError("Couldn't create mutex"); + SDL_free(mutex); + mutex = NULL; + } + } else { + SDL_OutOfMemory(); + } + return (mutex); +} + +/* Free the mutex */ +void +SDL_DestroyMutex(SDL_mutex * mutex) +{ + if (mutex) { + if (mutex->id) { + CloseHandle(mutex->id); + mutex->id = 0; + } + SDL_free(mutex); + } +} + +/* Lock the mutex */ +int +SDL_mutexP(SDL_mutex * mutex) +{ + if (mutex == NULL) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + if (WaitForSingleObject(mutex->id, INFINITE) == WAIT_FAILED) { + SDL_SetError("Couldn't wait on mutex"); + return -1; + } + return (0); +} + +/* Unlock the mutex */ +int +SDL_mutexV(SDL_mutex * mutex) +{ + if (mutex == NULL) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + if (ReleaseMutex(mutex->id) == FALSE) { + SDL_SetError("Couldn't release mutex"); + return -1; + } + return (0); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/windows/SDL_syssem.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/thread/windows/SDL_syssem.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,174 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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 Win32 API */ + +#define WIN32_LEAN_AND_MEAN +#include + +#include "SDL_thread.h" +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) +#include "win_ce_semaphore.h" +#endif + + +struct SDL_semaphore +{ +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) + SYNCHHANDLE id; +#else + HANDLE id; +#endif + LONG volatile count; +}; + + +/* Create a semaphore */ +SDL_sem * +SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_sem *sem; + + /* Allocate sem memory */ + sem = (SDL_sem *) SDL_malloc(sizeof(*sem)); + if (sem) { + /* Create the semaphore, with max value 32K */ +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) + sem->id = CreateSemaphoreCE(NULL, initial_value, 32 * 1024, NULL); +#else + sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL); +#endif + sem->count = initial_value; + if (!sem->id) { + SDL_SetError("Couldn't create semaphore"); + SDL_free(sem); + sem = NULL; + } + } else { + SDL_OutOfMemory(); + } + return (sem); +} + +/* Free the semaphore */ +void +SDL_DestroySemaphore(SDL_sem * sem) +{ + if (sem) { + if (sem->id) { +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) + CloseSynchHandle(sem->id); +#else + CloseHandle(sem->id); +#endif + sem->id = 0; + } + SDL_free(sem); + } +} + +int +SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) +{ + int retval; + DWORD dwMilliseconds; + + if (!sem) { + SDL_SetError("Passed a NULL sem"); + return -1; + } + + if (timeout == SDL_MUTEX_MAXWAIT) { + dwMilliseconds = INFINITE; + } else { + dwMilliseconds = (DWORD) timeout; + } +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) + switch (WaitForSemaphoreCE(sem->id, dwMilliseconds)) { +#else + switch (WaitForSingleObject(sem->id, dwMilliseconds)) { +#endif + case WAIT_OBJECT_0: + InterlockedDecrement(&sem->count); + retval = 0; + break; + case WAIT_TIMEOUT: + retval = SDL_MUTEX_TIMEDOUT; + break; + default: + SDL_SetError("WaitForSingleObject() failed"); + retval = -1; + break; + } + return retval; +} + +int +SDL_SemTryWait(SDL_sem * sem) +{ + return SDL_SemWaitTimeout(sem, 0); +} + +int +SDL_SemWait(SDL_sem * sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +/* Returns the current count of the semaphore */ +Uint32 +SDL_SemValue(SDL_sem * sem) +{ + if (!sem) { + SDL_SetError("Passed a NULL sem"); + return 0; + } + return (Uint32)sem->count; +} + +int +SDL_SemPost(SDL_sem * sem) +{ + if (!sem) { + SDL_SetError("Passed a NULL sem"); + return -1; + } + /* Increase the counter in the first place, because + * after a successful release the semaphore may + * immediately get destroyed by another thread which + * is waiting for this semaphore. + */ + InterlockedIncrement(&sem->count); +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) + if (ReleaseSemaphoreCE(sem->id, 1, NULL) == FALSE) { +#else + if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) { +#endif + InterlockedDecrement(&sem->count); /* restore */ + SDL_SetError("ReleaseSemaphore() failed"); + return -1; + } + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/windows/SDL_systhread.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/thread/windows/SDL_systhread.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,167 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +/* Win32 thread management routines for SDL */ + +#define WIN32_LEAN_AND_MEAN +#include + +#include "SDL_thread.h" +#include "../SDL_thread_c.h" +#include "../SDL_systhread.h" + +#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD +#ifndef _WIN32_WCE +/* We'll use the C library from this DLL */ +#include +#endif + +#if __GNUC__ +typedef uintptr_t (__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, + unsigned + (__stdcall * + func) (void *), + void *arg, + unsigned, + unsigned + *threadID); +typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); +#elif defined(__WATCOMC__) +/* This is for Watcom targets except OS2 */ +#if __WATCOMC__ < 1240 +#define __watcall +#endif +typedef unsigned long (__watcall * pfnSDL_CurrentBeginThread) (void *, + unsigned, + unsigned + (__stdcall * + func) (void + *), + void *arg, + unsigned, + unsigned + *threadID); +typedef void (__watcall * pfnSDL_CurrentEndThread) (unsigned code); +#else +typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, + unsigned (__stdcall * + func) (void + *), + void *arg, unsigned, + unsigned *threadID); +typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); +#endif +#endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */ + + +typedef struct ThreadStartParms +{ + void *args; + pfnSDL_CurrentEndThread pfnCurrentEndThread; +} tThreadStartParms, *pThreadStartParms; + +static DWORD __stdcall +RunThread(void *data) +{ + pThreadStartParms pThreadParms = (pThreadStartParms) data; + 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) (0); + return (0); +} + +#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD +int +SDL_SYS_CreateThread(SDL_Thread * thread, void *args, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) +{ +#else +int +SDL_SYS_CreateThread(SDL_Thread * thread, void *args) +{ +#ifdef _WIN32_WCE + pfnSDL_CurrentBeginThread pfnBeginThread = NULL; + pfnSDL_CurrentEndThread pfnEndThread = NULL; +#else + pfnSDL_CurrentBeginThread pfnBeginThread = _beginthreadex; + pfnSDL_CurrentEndThread pfnEndThread = _endthreadex; +#endif +#endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */ + unsigned threadid; + pThreadStartParms pThreadParms = + (pThreadStartParms) SDL_malloc(sizeof(tThreadStartParms)); + if (!pThreadParms) { + SDL_OutOfMemory(); + 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; + + if (pfnBeginThread) { + thread->handle = + (SYS_ThreadHandle) pfnBeginThread(NULL, 0, RunThread, + pThreadParms, 0, &threadid); + } else { + thread->handle = + CreateThread(NULL, 0, RunThread, pThreadParms, 0, &threadid); + } + if (thread->handle == NULL) { + SDL_SetError("Not enough resources to create thread"); + return (-1); + } + return (0); +} + +void +SDL_SYS_SetupThread(void) +{ + return; +} + +SDL_threadID +SDL_ThreadID(void) +{ + return ((SDL_threadID) GetCurrentThreadId()); +} + +void +SDL_SYS_WaitThread(SDL_Thread * thread) +{ + WaitForSingleObject(thread->handle, INFINITE); + CloseHandle(thread->handle); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/windows/SDL_systhread_c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/thread/windows/SDL_systhread_c.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,29 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#define WIN32_LEAN_AND_MEAN +#include + +typedef HANDLE SYS_ThreadHandle; + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/windows/win_ce_semaphore.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/thread/windows/win_ce_semaphore.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,228 @@ +/* win_ce_semaphore.c + + Copyright (c) 1998, Johnson M. Hart + (with corrections 2001 by Rainer Loritz) + Permission is granted for any and all use providing that this + copyright is properly acknowledged. + There are no assurances of suitability for any use whatsoever. + + WINDOWS CE: There is a collection of Windows CE functions to simulate + semaphores using only a mutex and an event. As Windows CE events cannot + be named, these simulated semaphores cannot be named either. + + Implementation notes: + 1. All required internal data structures are allocated on the process's heap. + 2. Where appropriate, a new error code is returned (see the header + file), or, if the error is a Win32 error, that code is unchanged. + 3. Notice the new handle type "SYNCHHANDLE" that has handles, counters, + and other information. This structure will grow as new objects are added + to this set; some members are specific to only one or two of the objects. + 4. Mutexes are used for critical sections. These could be replaced with + CRITICAL_SECTION objects but then this would give up the time out + capability. + 5. The implementation shows several interesting aspects of synchronization, some + of which are specific to Win32 and some of which are general. These are pointed + out in the comments as appropriate. + 6. The wait function emulates WaitForSingleObject only. An emulation of + WaitForMultipleObjects is much harder to implement outside the kernel, + and it is not clear how to handle a mixture of WCE semaphores and normal + events and mutexes. */ + +#define WIN32_LEAN_AND_MEAN +#include + +#include "win_ce_semaphore.h" + +static SYNCHHANDLE CleanUp(SYNCHHANDLE hSynch, DWORD Flags); + +SYNCHHANDLE +CreateSemaphoreCE(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, /* pointer to security attributes */ + LONG lInitialCount, /* initial count */ + LONG lMaximumCount, /* maximum count */ + LPCTSTR lpName) +/* Semaphore for use with Windows CE that does not support them directly. + Requires a counter, a mutex to protect the counter, and an + autoreset event. + + Here are the rules that must always hold between the autoreset event + and the mutex (any violation of these rules by the CE semaphore functions + will, in all likelihood, result in a defect): + 1. No thread can set, pulse, or reset the event, + nor can it access any part of the SYNCHHANDLE structure, + without first gaining ownership of the mutex. + BUT, a thread can wait on the event without owning the mutex + (this is clearly necessary or else the event could never be set). + 2. The event is in a signaled state if and only if the current semaphore + count ("CurCount") is greater than zero. + 3. The semaphore count is always >= 0 and <= the maximum count */ +{ + SYNCHHANDLE hSynch = NULL, result = NULL; + + __try { + if (lInitialCount > lMaximumCount || lMaximumCount < 0 + || lInitialCount < 0) { + /* Bad parameters */ + SetLastError(SYNCH_ERROR); + __leave; + } + + hSynch = + HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SYNCH_HANDLE_SIZE); + if (hSynch == NULL) + __leave; + + hSynch->MaxCount = lMaximumCount; + hSynch->CurCount = lInitialCount; + hSynch->lpName = lpName; + + hSynch->hMutex = CreateMutex(lpSemaphoreAttributes, FALSE, NULL); + + WaitForSingleObject(hSynch->hMutex, INFINITE); + /* Create the event. It is initially signaled if and only if the + initial count is > 0 */ + hSynch->hEvent = CreateEvent(lpSemaphoreAttributes, FALSE, + lInitialCount > 0, NULL); + ReleaseMutex(hSynch->hMutex); + hSynch->hSemph = NULL; + } + __finally { + /* Return with the handle, or, if there was any error, return + a null after closing any open handles and freeing any allocated memory. */ + result = + CleanUp(hSynch, 6 /* An event and a mutex, but no semaphore. */ ); + } + + return result; +} + +BOOL +ReleaseSemaphoreCE(SYNCHHANDLE hSemCE, LONG cReleaseCount, + LPLONG lpPreviousCount) +/* Windows CE equivalent to ReleaseSemaphore. */ +{ + BOOL Result = TRUE; + + /* Gain access to the object to assure that the release count + would not cause the total count to exceed the maximum. */ + + __try { + WaitForSingleObject(hSemCE->hMutex, INFINITE); + /* reply only if asked to */ + if (lpPreviousCount != NULL) + *lpPreviousCount = hSemCE->CurCount; + if (hSemCE->CurCount + cReleaseCount > hSemCE->MaxCount + || cReleaseCount <= 0) { + SetLastError(SYNCH_ERROR); + Result = FALSE; + __leave; + } + hSemCE->CurCount += cReleaseCount; + + /* Set the autoreset event, releasing exactly one waiting thread, now or + in the future. */ + + SetEvent(hSemCE->hEvent); + } + __finally { + ReleaseMutex(hSemCE->hMutex); + } + + return Result; +} + +DWORD +WaitForSemaphoreCE(SYNCHHANDLE hSemCE, DWORD dwMilliseconds) + /* Windows CE semaphore equivalent of WaitForSingleObject. */ +{ + DWORD WaitResult; + + WaitResult = WaitForSingleObject(hSemCE->hMutex, dwMilliseconds); + if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) + return WaitResult; + while (hSemCE->CurCount <= 0) { + + /* The count is 0, and the thread must wait on the event (which, by + the rules, is currently reset) for semaphore resources to become + available. First, of course, the mutex must be released so that another + thread will be capable of setting the event. */ + + ReleaseMutex(hSemCE->hMutex); + + /* Wait for the event to be signaled, indicating a semaphore state change. + The event is autoreset and signaled with a SetEvent (not PulseEvent) + so exactly one waiting thread (whether or not there is currently + a waiting thread) is released as a result of the SetEvent. */ + + WaitResult = WaitForSingleObject(hSemCE->hEvent, dwMilliseconds); + if (WaitResult != WAIT_OBJECT_0) + return WaitResult; + + /* This is where the properties of setting of an autoreset event is critical + to assure that, even if the semaphore state changes between the + preceding Wait and the next, and even if NO threads are waiting + on the event at the time of the SetEvent, at least one thread + will be released. + Pulsing a manual reset event would appear to work, but it would have + a defect which could appear if the semaphore state changed between + the two waits. */ + + WaitResult = WaitForSingleObject(hSemCE->hMutex, dwMilliseconds); + if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) + return WaitResult; + + } + /* The count is not zero and this thread owns the mutex. */ + + hSemCE->CurCount--; + /* The event is now unsignaled, BUT, the semaphore count may not be + zero, in which case the event should be signaled again + before releasing the mutex. */ + + if (hSemCE->CurCount > 0) + SetEvent(hSemCE->hEvent); + ReleaseMutex(hSemCE->hMutex); + return WaitResult; +} + +BOOL +CloseSynchHandle(SYNCHHANDLE hSynch) +/* Close a synchronization handle. + Improvement: Test for a valid handle before dereferencing the handle. */ +{ + BOOL Result = TRUE; + if (hSynch->hEvent != NULL) + Result = Result && CloseHandle(hSynch->hEvent); + if (hSynch->hMutex != NULL) + Result = Result && CloseHandle(hSynch->hMutex); + if (hSynch->hSemph != NULL) + Result = Result && CloseHandle(hSynch->hSemph); + HeapFree(GetProcessHeap(), 0, hSynch); + return (Result); +} + +static SYNCHHANDLE +CleanUp(SYNCHHANDLE hSynch, DWORD Flags) +{ /* Prepare to return from a create of a synchronization handle. + If there was any failure, free any allocated resources. + "Flags" indicates which Win32 objects are required in the + synchronization handle. */ + + BOOL ok = TRUE; + + if (hSynch == NULL) + return NULL; + if ((Flags & 4) == 1 && (hSynch->hEvent == NULL)) + ok = FALSE; + if ((Flags & 2) == 1 && (hSynch->hMutex == NULL)) + ok = FALSE; + if ((Flags & 1) == 1 && (hSynch->hEvent == NULL)) + ok = FALSE; + if (!ok) { + CloseSynchHandle(hSynch); + return NULL; + } + /* Everything worked */ + return hSynch; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/thread/windows/win_ce_semaphore.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/thread/windows/win_ce_semaphore.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,25 @@ +/* win_ce_semaphore.h - header file to go with win_ce_semaphore.c */ + +typedef struct _SYNCH_HANDLE_STRUCTURE +{ + HANDLE hEvent; + HANDLE hMutex; + HANDLE hSemph; + LONG MaxCount; + volatile LONG CurCount; + LPCTSTR lpName; +} SYNCH_HANDLE_STRUCTURE, *SYNCHHANDLE; + +#define SYNCH_HANDLE_SIZE sizeof (SYNCH_HANDLE_STRUCTURE) + + /* Error codes - all must have bit 29 set */ +#define SYNCH_ERROR 0X20000000 /* EXERCISE - REFINE THE ERROR NUMBERS */ + +extern SYNCHHANDLE CreateSemaphoreCE(LPSECURITY_ATTRIBUTES, LONG, LONG, + LPCTSTR); + +extern BOOL ReleaseSemaphoreCE(SYNCHHANDLE, LONG, LPLONG); +extern DWORD WaitForSemaphoreCE(SYNCHHANDLE, DWORD); + +extern BOOL CloseSynchHandle(SYNCHHANDLE); +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/timer/win32/SDL_systimer.c --- a/src/timer/win32/SDL_systimer.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_WIN32 - -#define WIN32_LEAN_AND_MEAN -#include -#include - -#include "SDL_timer.h" -#include "../SDL_timer_c.h" - -#ifdef _WIN32_WCE -#error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead. -#endif - -#define TIME_WRAP_VALUE (~(DWORD)0) - -/* The first (low-resolution) ticks value of the application */ -static DWORD start; - -#ifndef USE_GETTICKCOUNT -/* Store if a high-resolution performance counter exists on the system */ -static BOOL hires_timer_available; -/* The first high-resolution ticks value of the application */ -static LARGE_INTEGER hires_start_ticks; -/* The number of ticks per second of the high-resolution performance counter */ -static LARGE_INTEGER hires_ticks_per_second; -#endif - -void -SDL_StartTicks(void) -{ - /* Set first ticks value */ -#ifdef USE_GETTICKCOUNT - start = GetTickCount(); -#else -#if 0 /* Apparently there are problems with QPC on Win2K */ - if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) { - hires_timer_available = TRUE; - QueryPerformanceCounter(&hires_start_ticks); - } else -#endif - { - hires_timer_available = FALSE; - timeBeginPeriod(1); /* use 1 ms timer precision */ - start = timeGetTime(); - } -#endif -} - -Uint32 -SDL_GetTicks(void) -{ - DWORD now, ticks; -#ifndef USE_GETTICKCOUNT - LARGE_INTEGER hires_now; -#endif - -#ifdef USE_GETTICKCOUNT - now = GetTickCount(); -#else - if (hires_timer_available) { - QueryPerformanceCounter(&hires_now); - - hires_now.QuadPart -= hires_start_ticks.QuadPart; - hires_now.QuadPart *= 1000; - hires_now.QuadPart /= hires_ticks_per_second.QuadPart; - - return (DWORD) hires_now.QuadPart; - } else { - now = timeGetTime(); - } -#endif - - if (now < start) { - ticks = (TIME_WRAP_VALUE - start) + now; - } else { - ticks = (now - start); - } - return (ticks); -} - -void -SDL_Delay(Uint32 ms) -{ - Sleep(ms); -} - -/* Data to handle a single periodic alarm */ -static UINT timerID = 0; - -static void CALLBACK -HandleAlarm(UINT uID, UINT uMsg, DWORD_PTR dwUser, - DWORD_PTR dw1, DWORD_PTR dw2) -{ - SDL_ThreadedTimerCheck(); -} - - -int -SDL_SYS_TimerInit(void) -{ - MMRESULT result; - - /* Set timer resolution */ - result = timeBeginPeriod(TIMER_RESOLUTION); - if (result != TIMERR_NOERROR) { - SDL_SetError("Warning: Can't set %d ms timer resolution", - TIMER_RESOLUTION); - } - /* Allow 10 ms of drift so we don't chew on CPU */ - timerID = - timeSetEvent(TIMER_RESOLUTION, 1, HandleAlarm, 0, TIME_PERIODIC); - if (!timerID) { - SDL_SetError("timeSetEvent() failed"); - return (-1); - } - return (SDL_SetTimerThreaded(1)); -} - -void -SDL_SYS_TimerQuit(void) -{ - if (timerID) { - timeKillEvent(timerID); - } - timeEndPeriod(TIMER_RESOLUTION); -} - -int -SDL_SYS_StartTimer(void) -{ - SDL_SetError("Internal logic error: Win32 uses threaded timer"); - return (-1); -} - -void -SDL_SYS_StopTimer(void) -{ - return; -} - -#endif /* SDL_TIMER_WIN32 */ -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/timer/windows/SDL_systimer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/timer/windows/SDL_systimer.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,166 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_WINDOWS + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include "SDL_timer.h" +#include "../SDL_timer_c.h" + +#ifdef _WIN32_WCE +#error This is WinCE. Please use src/timer/wince/SDL_systimer.c instead. +#endif + +#define TIME_WRAP_VALUE (~(DWORD)0) + +/* The first (low-resolution) ticks value of the application */ +static DWORD start; + +#ifndef USE_GETTICKCOUNT +/* Store if a high-resolution performance counter exists on the system */ +static BOOL hires_timer_available; +/* The first high-resolution ticks value of the application */ +static LARGE_INTEGER hires_start_ticks; +/* The number of ticks per second of the high-resolution performance counter */ +static LARGE_INTEGER hires_ticks_per_second; +#endif + +void +SDL_StartTicks(void) +{ + /* Set first ticks value */ +#ifdef USE_GETTICKCOUNT + start = GetTickCount(); +#else +#if 0 /* Apparently there are problems with QPC on Win2K */ + if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) { + hires_timer_available = TRUE; + QueryPerformanceCounter(&hires_start_ticks); + } else +#endif + { + hires_timer_available = FALSE; + timeBeginPeriod(1); /* use 1 ms timer precision */ + start = timeGetTime(); + } +#endif +} + +Uint32 +SDL_GetTicks(void) +{ + DWORD now, ticks; +#ifndef USE_GETTICKCOUNT + LARGE_INTEGER hires_now; +#endif + +#ifdef USE_GETTICKCOUNT + now = GetTickCount(); +#else + if (hires_timer_available) { + QueryPerformanceCounter(&hires_now); + + hires_now.QuadPart -= hires_start_ticks.QuadPart; + hires_now.QuadPart *= 1000; + hires_now.QuadPart /= hires_ticks_per_second.QuadPart; + + return (DWORD) hires_now.QuadPart; + } else { + now = timeGetTime(); + } +#endif + + if (now < start) { + ticks = (TIME_WRAP_VALUE - start) + now; + } else { + ticks = (now - start); + } + return (ticks); +} + +void +SDL_Delay(Uint32 ms) +{ + Sleep(ms); +} + +/* Data to handle a single periodic alarm */ +static UINT timerID = 0; + +static void CALLBACK +HandleAlarm(UINT uID, UINT uMsg, DWORD_PTR dwUser, + DWORD_PTR dw1, DWORD_PTR dw2) +{ + SDL_ThreadedTimerCheck(); +} + + +int +SDL_SYS_TimerInit(void) +{ + MMRESULT result; + + /* Set timer resolution */ + result = timeBeginPeriod(TIMER_RESOLUTION); + if (result != TIMERR_NOERROR) { + SDL_SetError("Warning: Can't set %d ms timer resolution", + TIMER_RESOLUTION); + } + /* Allow 10 ms of drift so we don't chew on CPU */ + timerID = + timeSetEvent(TIMER_RESOLUTION, 1, HandleAlarm, 0, TIME_PERIODIC); + if (!timerID) { + SDL_SetError("timeSetEvent() failed"); + return (-1); + } + return (SDL_SetTimerThreaded(1)); +} + +void +SDL_SYS_TimerQuit(void) +{ + if (timerID) { + timeKillEvent(timerID); + } + timeEndPeriod(TIMER_RESOLUTION); +} + +int +SDL_SYS_StartTimer(void) +{ + SDL_SetError("Internal logic error: Win32 uses threaded timer"); + return (-1); +} + +void +SDL_SYS_StopTimer(void) +{ + return; +} + +#endif /* SDL_TIMER_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/SDL_renderer_gl.c --- a/src/video/SDL_renderer_gl.c Thu Jan 20 17:33:06 2011 -0800 +++ b/src/video/SDL_renderer_gl.c Thu Jan 20 18:04:05 2011 -0800 @@ -1181,7 +1181,7 @@ } data->glEnd(); } else { -#if defined(__APPLE__) || defined(__WIN32__) +#if defined(__APPLE__) || defined(__WINDOWS__) #else int x1, y1, x2, y2; #endif @@ -1200,7 +1200,7 @@ * least it would be pixel perfect. */ data->glBegin(GL_POINTS); -#if defined(__APPLE__) || defined(__WIN32__) +#if defined(__APPLE__) || defined(__WINDOWS__) /* Mac OS X and Windows seem to always leave the second point open */ data->glVertex2f(0.5f + points[count-1].x, 0.5f + points[count-1].y); #else diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/SDL_sysvideo.h --- a/src/video/SDL_sysvideo.h Thu Jan 20 17:33:06 2011 -0800 +++ b/src/video/SDL_sysvideo.h Thu Jan 20 18:04:05 2011 -0800 @@ -411,8 +411,8 @@ #if SDL_VIDEO_DRIVER_DIRECTFB extern VideoBootStrap DirectFB_bootstrap; #endif -#if SDL_VIDEO_DRIVER_WIN32 -extern VideoBootStrap WIN32_bootstrap; +#if SDL_VIDEO_DRIVER_WINDOWS +extern VideoBootStrap WINDOWS_bootstrap; #endif #if SDL_VIDEO_DRIVER_BWINDOW extern VideoBootStrap BWINDOW_bootstrap; diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/SDL_video.c --- a/src/video/SDL_video.c Thu Jan 20 17:33:06 2011 -0800 +++ b/src/video/SDL_video.c Thu Jan 20 18:04:05 2011 -0800 @@ -34,8 +34,8 @@ #include "../events/SDL_sysevents.h" #include "../events/SDL_events_c.h" -#if SDL_VIDEO_DRIVER_WIN32 -#include "win32/SDL_win32video.h" +#if SDL_VIDEO_DRIVER_WINDOWS +#include "windows/SDL_windowsvideo.h" extern void IME_Present(SDL_VideoData *videodata); #endif @@ -65,8 +65,8 @@ #if SDL_VIDEO_DRIVER_DIRECTFB &DirectFB_bootstrap, #endif -#if SDL_VIDEO_DRIVER_WIN32 - &WIN32_bootstrap, +#if SDL_VIDEO_DRIVER_WINDOWS + &WINDOWS_bootstrap, #endif #if SDL_VIDEO_DRIVER_BWINDOW &BWINDOW_bootstrap, @@ -2708,7 +2708,7 @@ if (!renderer || !renderer->RenderPresent) { return; } -#if SDL_VIDEO_DRIVER_WIN32 +#if SDL_VIDEO_DRIVER_WINDOWS IME_Present((SDL_VideoData *)_this->driverdata); #endif renderer->RenderPresent(renderer); diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_ceddrawrender.c --- a/src/video/win32/SDL_ceddrawrender.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,835 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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 - - Stefan Klug - klug.stefan@gmx.de -*/ -#include "SDL_config.h" - -#if SDL_VIDEO_RENDER_DDRAW - -#include "SDL_win32video.h" -#include "../SDL_yuv_sw_c.h" - -#if 0 -#define DDRAW_LOG(...) printf(__VA_ARGS__) -#else -#define DDRAW_LOG(...) -#endif - - -/* DirectDraw renderer implementation */ - -static SDL_Renderer *DDRAW_CreateRenderer(SDL_Window * window, Uint32 flags); -static int DDRAW_DisplayModeChanged(SDL_Renderer * renderer); -static int DDRAW_CreateTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static int DDRAW_QueryTexturePixels(SDL_Renderer * renderer, - SDL_Texture * texture, void **pixels, - int *pitch); -static int DDRAW_SetTextureColorMod(SDL_Renderer * renderer, - SDL_Texture * texture); -static int DDRAW_SetTextureAlphaMod(SDL_Renderer * renderer, - SDL_Texture * texture); -static int DDRAW_SetTextureBlendMode(SDL_Renderer * renderer, - SDL_Texture * texture); -static int DDRAW_SetTextureScaleMode(SDL_Renderer * renderer, - SDL_Texture * texture); -static int DDRAW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, - int pitch); -static int DDRAW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, - void **pixels, int *pitch); -static void DDRAW_UnlockTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static void DDRAW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, - int numrects, const SDL_Rect * rects); -static int DDRAW_RenderPoint(SDL_Renderer * renderer, int x, int y); -static int DDRAW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, - int y2); -static int DDRAW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect); -static int DDRAW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, - const SDL_Rect * dstrect); -static void DDRAW_RenderPresent(SDL_Renderer * renderer); -static void DDRAW_DestroyTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static void DDRAW_DestroyRenderer(SDL_Renderer * renderer); - - -SDL_RenderDriver DDRAW_RenderDriver = { - DDRAW_CreateRenderer, - { - "ddraw", - (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY | - SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | - SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED), - (SDL_TEXTUREMODULATE_NONE), - (SDL_BLENDMODE_NONE), - (SDL_SCALEMODE_NONE), - 0, - {0}, - 0, - 0} -}; - -typedef struct -{ - IDirectDraw *ddraw; - IDirectDrawSurface *primary; -} DDRAW_RenderData; - -typedef struct -{ - RECT lock; - IDirectDrawSurface *surface; -} DDRAW_TextureData; - - -static void -DDRAW_SetError(const char *prefix, HRESULT result) -{ - const char *error; - - switch (result) { - case DDERR_CANTCREATEDC: - error = "CANTCREATEDC"; - break; - case DDERR_CANTLOCKSURFACE: - error = "CANTLOCKSURFACE"; - break; - case DDERR_CLIPPERISUSINGHWND: - error = "CLIPPERISUSINGHWND"; - break; - case DDERR_COLORKEYNOTSET: - error = "COLORKEYNOTSET"; - break; - case DDERR_CURRENTLYNOTAVAIL: - error = "CURRENTLYNOTAVAIL"; - break; - case DDERR_DCALREADYCREATED: - error = "DCALREADYCREATED"; - break; - case DDERR_DEVICEDOESNTOWNSURFACE: - error = "DEVICEDOESNTOWNSURFACE"; - break; - case DDERR_DIRECTDRAWALREADYCREATED: - error = "DIRECTDRAWALREADYCREATED"; - break; - case DDERR_EXCLUSIVEMODEALREADYSET: - error = "EXCLUSIVEMODEALREADYSET"; - break; - case DDERR_GENERIC: - error = "GENERIC"; - break; - case DDERR_HEIGHTALIGN: - error = "HEIGHTALIGN"; - break; - case DDERR_IMPLICITLYCREATED: - error = "IMPLICITLYCREATED"; - break; - case DDERR_INCOMPATIBLEPRIMARY: - error = "INCOMPATIBLEPRIMARY"; - break; - case DDERR_INVALIDCAPS: - error = "INVALIDCAPS"; - break; - case DDERR_INVALIDCLIPLIST: - error = "INVALIDCLIPLIST"; - break; - case DDERR_INVALIDMODE: - error = "INVALIDMODE"; - break; - case DDERR_INVALIDOBJECT: - error = "INVALIDOBJECT"; - break; - case DDERR_INVALIDPARAMS: - error = "INVALIDPARAMS"; - break; - case DDERR_INVALIDPIXELFORMAT: - error = "INVALIDPIXELFORMAT"; - break; - case DDERR_INVALIDPOSITION: - error = "INVALIDPOSITION"; - break; - case DDERR_INVALIDRECT: - error = "INVALIDRECT"; - break; - case DDERR_LOCKEDSURFACES: - error = "LOCKEDSURFACES"; - break; - case DDERR_MOREDATA: - error = "MOREDATA"; - break; - case DDERR_NOALPHAHW: - error = "NOALPHAHW"; - break; - case DDERR_NOBLTHW: - error = "NOBLTHW"; - break; - case DDERR_NOCLIPLIST: - error = "NOCLIPLIST"; - break; - case DDERR_NOCLIPPERATTACHED: - error = "NOCLIPPERATTACHED"; - break; - case DDERR_NOCOLORCONVHW: - error = "NOCOLORCONVHW"; - break; - case DDERR_NOCOLORKEYHW: - error = "NOCOLORKEYHW"; - break; - case DDERR_NOCOOPERATIVELEVELSET: - error = "NOCOOPERATIVELEVELSET"; - break; - case DDERR_NODC: - error = "NODC"; - break; - case DDERR_NOFLIPHW: - error = "NOFLIPHW"; - break; - case DDERR_NOOVERLAYDEST: - error = "NOOVERLAYDEST"; - break; - case DDERR_NOOVERLAYHW: - error = "NOOVERLAYHW"; - break; - case DDERR_NOPALETTEATTACHED: - error = "NOPALETTEATTACHED"; - break; - case DDERR_NOPALETTEHW: - error = "NOPALETTEHW"; - break; - case DDERR_NORASTEROPHW: - error = "NORASTEROPHW"; - break; - case DDERR_NOSTRETCHHW: - error = "NOSTRETCHHW"; - break; - case DDERR_NOTAOVERLAYSURFACE: - error = "NOTAOVERLAYSURFACE"; - break; - case DDERR_NOTFLIPPABLE: - error = "NOTFLIPPABLE"; - break; - case DDERR_NOTFOUND: - error = "NOTFOUND"; - break; - case DDERR_NOTLOCKED: - error = "NOTLOCKED"; - break; - case DDERR_NOTPALETTIZED: - error = "NOTPALETTIZED"; - break; - case DDERR_NOVSYNCHW: - error = "NOVSYNCHW"; - break; - case DDERR_NOZOVERLAYHW: - error = "NOZOVERLAYHW"; - break; - case DDERR_OUTOFCAPS: - error = "OUTOFCAPS"; - break; - case DDERR_OUTOFMEMORY: - error = "OUTOFMEMORY"; - break; - case DDERR_OUTOFVIDEOMEMORY: - error = "OUTOFVIDEOMEMORY"; - break; - case DDERR_OVERLAPPINGRECTS: - error = "OVERLAPPINGRECTS"; - break; - case DDERR_OVERLAYNOTVISIBLE: - error = "OVERLAYNOTVISIBLE"; - break; - case DDERR_PALETTEBUSY: - error = "PALETTEBUSY"; - break; - case DDERR_PRIMARYSURFACEALREADYEXISTS: - error = "PRIMARYSURFACEALREADYEXISTS"; - break; - case DDERR_REGIONTOOSMALL: - error = "REGIONTOOSMALL"; - break; - case DDERR_SURFACEBUSY: - error = "SURFACEBUSY"; - break; - case DDERR_SURFACELOST: - error = "SURFACELOST"; - break; - case DDERR_TOOBIGHEIGHT: - error = "TOOBIGHEIGHT"; - break; - case DDERR_TOOBIGSIZE: - error = "TOOBIGSIZE"; - break; - case DDERR_TOOBIGWIDTH: - error = "TOOBIGWIDTH"; - break; - case DDERR_UNSUPPORTED: - error = "UNSUPPORTED"; - break; - case DDERR_UNSUPPORTEDFORMAT: - error = "UNSUPPORTEDFORMAT"; - break; - case DDERR_VERTICALBLANKINPROGRESS: - error = "VERTICALBLANKINPROGRESS"; - break; - case DDERR_VIDEONOTACTIVE: - error = "VIDEONOTACTIVE"; - break; - case DDERR_WASSTILLDRAWING: - error = "WASSTILLDRAWING"; - break; - case DDERR_WRONGMODE: - error = "WRONGMODE"; - break; - default: - error = "UNKNOWN"; - break; - } - SDL_SetError("%s: %s", prefix, error); -} - -static SDL_bool -PixelFormatToDDPIXELFORMAT(Uint32 format, LPDDPIXELFORMAT dst) -{ - SDL_zerop(dst); - dst->dwSize = sizeof(*dst); - - if (SDL_ISPIXELFORMAT_FOURCC(format)) { - dst->dwFlags = DDPF_FOURCC; - dst->dwFourCC = format; - } else if (SDL_ISPIXELFORMAT_INDEXED(format)) { - SDL_SetError("Indexed pixelformats are not supported."); - return SDL_FALSE; - } else { - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - if (!SDL_PixelFormatEnumToMasks - (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { - SDL_SetError("pixelformat not supported"); - return SDL_FALSE; - } - - if (!Rmask && !Gmask && !Bmask) { - dst->dwFlags = DDPF_ALPHA; - dst->dwAlphaBitDepth = bpp; - } else { - dst->dwFlags = DDPF_RGB; - dst->dwRGBBitCount = bpp; - dst->dwRBitMask = Rmask; - dst->dwGBitMask = Gmask; - dst->dwBBitMask = Bmask; - - if (Amask) { - dst->dwFlags |= DDPF_ALPHAPIXELS; - dst->dwRGBAlphaBitMask = Amask; - } - } - } - - return SDL_TRUE; -} - -static SDL_bool -DDRAW_IsTextureFormatAvailable(IDirectDraw * ddraw, Uint32 display_format, - Uint32 texture_format) -{ - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - - if (SDL_ISPIXELFORMAT_FOURCC(texture_format)) { - //TODO I don't expect DDRAW to support all 4CC formats, but I don't know which ones - return SDL_TRUE; - } - //These are only basic checks - if (SDL_ISPIXELFORMAT_INDEXED(texture_format)) { - return SDL_FALSE; - } - - if (!SDL_PixelFormatEnumToMasks - (texture_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { - return SDL_FALSE; - } - - switch (bpp) { - case 4: - case 8: - case 16: - case 24: - case 32: - break; - default: - return SDL_FALSE; - } - - return SDL_TRUE; -} - -void -DDRAW_AddRenderDriver(_THIS) -{ - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - SDL_RendererInfo *info = &DDRAW_RenderDriver.info; - SDL_DisplayMode *mode = &SDL_CurrentDisplay->desktop_mode; - - if (data->ddraw) { - int i; - int formats[] = { - SDL_PIXELFORMAT_INDEX8, - SDL_PIXELFORMAT_RGB332, - SDL_PIXELFORMAT_RGB444, - SDL_PIXELFORMAT_RGB555, - SDL_PIXELFORMAT_ARGB4444, - SDL_PIXELFORMAT_ARGB1555, - SDL_PIXELFORMAT_RGB565, - SDL_PIXELFORMAT_RGB888, - SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_ARGB2101010, - }; - - for (i = 0; i < SDL_arraysize(formats); ++i) { - if (DDRAW_IsTextureFormatAvailable - (data->ddraw, mode->format, formats[i])) { - info->texture_formats[info->num_texture_formats++] = - formats[i]; - } - } - - //TODO the fourcc formats should get fetched from IDirectDraw::GetFourCCCodes - info->texture_formats[info->num_texture_formats++] = - SDL_PIXELFORMAT_YV12; - info->texture_formats[info->num_texture_formats++] = - SDL_PIXELFORMAT_IYUV; - info->texture_formats[info->num_texture_formats++] = - SDL_PIXELFORMAT_YUY2; - info->texture_formats[info->num_texture_formats++] = - SDL_PIXELFORMAT_UYVY; - info->texture_formats[info->num_texture_formats++] = - SDL_PIXELFORMAT_YVYU; - - for (i = 0; i < _this->num_displays; ++i) - SDL_AddRenderDriver(&_this->displays[i], &DDRAW_RenderDriver); - } - } -} - -SDL_Renderer * -DDRAW_CreateRenderer(SDL_Window * window, Uint32 flags) -{ - SDL_VideoDisplay *display = window->display; - SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata; - SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; - SDL_Renderer *renderer; - DDRAW_RenderData *data; - HRESULT result; - DDSURFACEDESC ddsd; - - renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); - if (!renderer) { - SDL_OutOfMemory(); - return NULL; - } - - data = (DDRAW_RenderData *) SDL_calloc(1, sizeof(*data)); - if (!data) { - DDRAW_DestroyRenderer(renderer); - SDL_OutOfMemory(); - return NULL; - } - data->ddraw = videodata->ddraw; - - videodata->render = RENDER_DDRAW; - - renderer->DisplayModeChanged = DDRAW_DisplayModeChanged; - renderer->CreateTexture = DDRAW_CreateTexture; - renderer->QueryTexturePixels = DDRAW_QueryTexturePixels; - - renderer->SetTextureColorMod = DDRAW_SetTextureColorMod; - renderer->SetTextureAlphaMod = DDRAW_SetTextureAlphaMod; - renderer->SetTextureBlendMode = DDRAW_SetTextureBlendMode; - renderer->SetTextureScaleMode = DDRAW_SetTextureScaleMode; - renderer->UpdateTexture = DDRAW_UpdateTexture; - renderer->LockTexture = DDRAW_LockTexture; - renderer->UnlockTexture = DDRAW_UnlockTexture; - renderer->DirtyTexture = DDRAW_DirtyTexture; - renderer->RenderPoint = DDRAW_RenderPoint; - renderer->RenderLine = DDRAW_RenderLine; - renderer->RenderFill = DDRAW_RenderFill; - renderer->RenderCopy = DDRAW_RenderCopy; - renderer->RenderPresent = DDRAW_RenderPresent; - renderer->DestroyTexture = DDRAW_DestroyTexture; - renderer->DestroyRenderer = DDRAW_DestroyRenderer; - renderer->info = DDRAW_RenderDriver.info; - renderer->window = window; - renderer->driverdata = data; - - renderer->info.flags = SDL_RENDERER_ACCELERATED; - - SDL_zero(ddsd); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS; - - if (window->flags & SDL_WINDOW_FULLSCREEN) { - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - } else { - //TODO handle non fullscreen - SDL_SetError("DirectDraw renderer has only fullscreen implemented"); - DDRAW_DestroyRenderer(renderer); - return NULL; - } - - if (flags & SDL_RENDERER_PRESENTFLIP2) { - ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; - ddsd.dwBackBufferCount = 2; - } else if (flags & SDL_RENDERER_PRESENTFLIP3) { - ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; - ddsd.dwBackBufferCount = 3; - } else if (flags & SDL_RENDERER_PRESENTCOPY) { - //TODO what is the best approximation to this mode - } else { - - } - - if (flags & SDL_RENDERER_PRESENTVSYNC) { - SDL_SetError("DirectDraw renderer with v-sync is not implemented"); - DDRAW_DestroyRenderer(renderer); - return NULL; - } - - result = - data->ddraw->lpVtbl->SetCooperativeLevel(data->ddraw, - windowdata->hwnd, - DDSCL_NORMAL); - if (result != DD_OK) { - DDRAW_SetError("CreateDevice()", result); - DDRAW_DestroyRenderer(renderer); - return NULL; - } - - result = - data->ddraw->lpVtbl->CreateSurface(data->ddraw, &ddsd, &data->primary, - NULL); - if (result != DD_OK) { - DDRAW_SetError("CreateDevice()", result); - DDRAW_DestroyRenderer(renderer); - return NULL; - } - - return renderer; -} - -static int -DDRAW_Reset(SDL_Renderer * renderer) -{ - //TODO implement - /*D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - HRESULT result; - - result = IDirect3DDevice9_Reset(data->device, &data->pparams); - if (FAILED(result)) { - if (result == D3DERR_DEVICELOST) { - /* Don't worry about it, we'll reset later... * - return 0; - } else { - D3D_SetError("Reset()", result); - return -1; - } - } - IDirect3DDevice9_SetVertexShader(data->device, NULL); - IDirect3DDevice9_SetFVF(data->device, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, - D3DCULL_NONE); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); */ - return 0; -} - -static int -DDRAW_DisplayModeChanged(SDL_Renderer * renderer) -{ - //TODO implement - /*D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - SDL_VideoDisplay *display = window->display; - - data->pparams.BackBufferWidth = window->w; - data->pparams.BackBufferHeight = window->h; - if (window->flags & SDL_WINDOW_FULLSCREEN) { - data->pparams.BackBufferFormat = - PixelFormatToD3DFMT(display->fullscreen_mode.format); - } else { - data->pparams.BackBufferFormat = D3DFMT_UNKNOWN; - } - return D3D_Reset(renderer); */ - return 0; -} - -static int -DDRAW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - DDRAW_RenderData *renderdata = (DDRAW_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - SDL_VideoDisplay *display = window->display; - Uint32 display_format = display->current_mode.format; - DDRAW_TextureData *data; - DDSURFACEDESC ddsd; - HRESULT result; - - data = (DDRAW_TextureData *) SDL_calloc(1, sizeof(*data)); - if (!data) { - SDL_OutOfMemory(); - return -1; - } - - SDL_zero(ddsd); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_HEIGHT | DDSD_WIDTH; - ddsd.dwWidth = texture->w; - ddsd.dwHeight = texture->h; - - - if (!PixelFormatToDDPIXELFORMAT(texture->format, &ddsd.ddpfPixelFormat)) { - SDL_free(data); - return -1; - } - - texture->driverdata = data; - - result = - renderdata->ddraw->lpVtbl->CreateSurface(renderdata->ddraw, &ddsd, - &data->surface, NULL); - if (result != DD_OK) { - SDL_free(data); - DDRAW_SetError("CreateTexture", result); - return -1; - } - - return 0; -} - -static int -DDRAW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, - void **pixels, int *pitch) -{ - //TODO implement - SDL_SetError("QueryTexturePixels is not implemented"); - return -1; -} - -static int -DDRAW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) -{ - return 0; -} - -static int -DDRAW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) -{ - return 0; -} - -static int -DDRAW_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) -{ - switch (texture->blendMode) { - case SDL_BLENDMODE_NONE: - return 0; - default: - SDL_Unsupported(); - texture->blendMode = SDL_BLENDMODE_NONE; - return -1; - } -} - -static int -DDRAW_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) -{ - switch (texture->scaleMode) { - case SDL_SCALEMODE_NONE: - default: - SDL_Unsupported(); - texture->scaleMode = SDL_SCALEMODE_NONE; - return -1; - } - return 0; -} - -static int -DDRAW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, int pitch) -{ - DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata; - - //TODO implement - SDL_SetError("UpdateTexture is not implemented"); - return 0; -} - -static int -DDRAW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, void **pixels, - int *pitch) -{ - DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata; - HRESULT result; - DDSURFACEDESC ddsd; - - SDL_zero(ddsd); - ddsd.dwSize = sizeof(ddsd); - - /** - * On a Axim x51v locking a subrect returns the startaddress of the whole surface, - * wheras on my ASUS MyPal 696 the startaddress of the locked area is returned, - * thats why I always lock the whole surface and calculate the pixels pointer by hand. - * This shouldn't be a speed problem, as multiple locks aren't available on DDraw Mobile - * see http://msdn.microsoft.com/en-us/library/ms858221.aspx - */ - - result = data->surface->lpVtbl->Lock(data->surface, NULL, &ddsd, 0, NULL); - if (result != DD_OK) { - DDRAW_SetError("LockRect()", result); - return -1; - } - - *pixels = ddsd.lpSurface + rect->y * ddsd.lPitch + rect->x * ddsd.lXPitch; - *pitch = ddsd.lPitch; - return 0; -} - -static void -DDRAW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata; - - data->surface->lpVtbl->Unlock(data->surface, NULL); -} - -static void -DDRAW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, - int numrects, const SDL_Rect * rects) -{ -} - -static void -DDRAW_SetBlendMode(DDRAW_RenderData * data, int blendMode) -{ - switch (blendMode) { - - } -} - -static int -DDRAW_RenderPoint(SDL_Renderer * renderer, int x, int y) -{ - return -1; -} - -static int -DDRAW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) -{ - return -1; -} - -static int -DDRAW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect) -{ - return -1; -} - -static int -DDRAW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) -{ - DDRAW_RenderData *data = (DDRAW_RenderData *) renderer->driverdata; - DDRAW_TextureData *texturedata = - (DDRAW_TextureData *) texture->driverdata; - HRESULT result; - RECT srcr; - RECT dstr; - DDBLTFX bltfx; - - srcr.left = srcrect->x; - srcr.top = srcrect->y; - srcr.right = srcrect->x + srcrect->w; - srcr.bottom = srcrect->y + srcrect->h; - - dstr.left = dstrect->x; - dstr.top = dstrect->y; - dstr.right = dstrect->x + dstrect->w; - dstr.bottom = dstrect->y + dstrect->h; - - SDL_zero(bltfx); - bltfx.dwSize = sizeof(bltfx); - bltfx.dwROP = SRCCOPY; - - data->primary->lpVtbl->Blt(data->primary, &dstr, texturedata->surface, - &srcr, DDBLT_ROP, &bltfx); - - return 0; -} - -static void -DDRAW_RenderPresent(SDL_Renderer * renderer) -{ - DDRAW_RenderData *data = (DDRAW_RenderData *) renderer->driverdata; - HRESULT result; - - return; - - result = - data->primary->lpVtbl->Flip(data->primary, NULL, DDFLIP_INTERVAL1); - if (result != DD_OK) { - DDRAW_SetError("Present()", result); - } -} - -static void -DDRAW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata; - - if (!data) { - return; - } - - data->surface->lpVtbl->Release(data->surface); - SDL_free(data); - texture->driverdata = NULL; -} - -static void -DDRAW_DestroyRenderer(SDL_Renderer * renderer) -{ - DDRAW_RenderData *data = (DDRAW_RenderData *) renderer->driverdata; - - if (data) { - data->primary->lpVtbl->Release(data->primary); - SDL_free(data); - } - SDL_free(renderer); -} - -#endif /* SDL_VIDEO_RENDER_DDRAW */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_ceddrawrender.h --- a/src/video/win32/SDL_ceddrawrender.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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 - - Stefan Klug - klug.stefan@gmx.de -*/ -#include "SDL_config.h" - -#if SDL_VIDEO_RENDER_DDRAW -extern void DDRAW_AddRenderDriver(_THIS); -#endif - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_d3drender.c --- a/src/video/win32/SDL_d3drender.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1533 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#if SDL_VIDEO_RENDER_D3D - -#include "SDL_win32video.h" -#include "../SDL_yuv_sw_c.h" - -#ifdef ASSEMBLE_SHADER -/////////////////////////////////////////////////////////////////////////// -// ID3DXBuffer: -// ------------ -// The buffer object is used by D3DX to return arbitrary size data. -// -// GetBufferPointer - -// Returns a pointer to the beginning of the buffer. -// -// GetBufferSize - -// Returns the size of the buffer, in bytes. -/////////////////////////////////////////////////////////////////////////// - -typedef interface ID3DXBuffer ID3DXBuffer; -typedef interface ID3DXBuffer *LPD3DXBUFFER; - -// {8BA5FB08-5195-40e2-AC58-0D989C3A0102} -DEFINE_GUID(IID_ID3DXBuffer, -0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2); - -#undef INTERFACE -#define INTERFACE ID3DXBuffer - -typedef interface ID3DXBuffer { - const struct ID3DXBufferVtbl FAR* lpVtbl; -} ID3DXBuffer; -typedef const struct ID3DXBufferVtbl ID3DXBufferVtbl; -const struct ID3DXBufferVtbl -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXBuffer - STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE; - STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE; -}; - -HRESULT WINAPI - D3DXAssembleShader( - LPCSTR pSrcData, - UINT SrcDataLen, - CONST LPVOID* pDefines, - LPVOID pInclude, - DWORD Flags, - LPD3DXBUFFER* ppShader, - LPD3DXBUFFER* ppErrorMsgs); - -#endif /* ASSEMBLE_SHADER */ - - -/* Direct3D renderer implementation */ - -#if 1 /* This takes more memory but you won't lose your texture data */ -#define D3DPOOL_SDL D3DPOOL_MANAGED -#define SDL_MEMORY_POOL_MANAGED -#else -#define D3DPOOL_SDL D3DPOOL_DEFAULT -#define SDL_MEMORY_POOL_DEFAULT -#endif - -static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags); -static int D3D_DisplayModeChanged(SDL_Renderer * renderer); -static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); -static int D3D_QueryTexturePixels(SDL_Renderer * renderer, - SDL_Texture * texture, void **pixels, - int *pitch); -static int D3D_SetTexturePalette(SDL_Renderer * renderer, - SDL_Texture * texture, - const SDL_Color * colors, int firstcolor, - int ncolors); -static int D3D_GetTexturePalette(SDL_Renderer * renderer, - SDL_Texture * texture, SDL_Color * colors, - int firstcolor, int ncolors); -static int D3D_SetTextureColorMod(SDL_Renderer * renderer, - SDL_Texture * texture); -static int D3D_SetTextureAlphaMod(SDL_Renderer * renderer, - SDL_Texture * texture); -static int D3D_SetTextureBlendMode(SDL_Renderer * renderer, - SDL_Texture * texture); -static int D3D_SetTextureScaleMode(SDL_Renderer * renderer, - SDL_Texture * texture); -static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, - int pitch); -static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, - void **pixels, int *pitch); -static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); -static void D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, - int numrects, const SDL_Rect * rects); -static int D3D_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, int count); -static int D3D_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, int count); -static int D3D_RenderDrawRects(SDL_Renderer * renderer, - const SDL_Rect ** rects, int count); -static int D3D_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect ** rects, int count); -static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect); -static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, void * pixels, int pitch); -static int D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, const void * pixels, int pitch); -static void D3D_RenderPresent(SDL_Renderer * renderer); -static void D3D_DestroyTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static void D3D_DestroyRenderer(SDL_Renderer * renderer); - - -SDL_RenderDriver D3D_RenderDriver = { - D3D_CreateRenderer, - { - "d3d", - (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY | - SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | - SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_PRESENTVSYNC | - SDL_RENDERER_ACCELERATED), - (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR | - SDL_TEXTUREMODULATE_ALPHA), - (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | - SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD), - (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST | - SDL_SCALEMODE_SLOW | SDL_SCALEMODE_BEST), - 0, - {0}, - 0, - 0} -}; - -typedef struct -{ - IDirect3D9 *d3d; - IDirect3DDevice9 *device; - UINT adapter; - D3DPRESENT_PARAMETERS pparams; - LPDIRECT3DPIXELSHADER9 ps_mask; - SDL_bool beginScene; -} D3D_RenderData; - -typedef struct -{ - SDL_SW_YUVTexture *yuv; - Uint32 format; - IDirect3DTexture9 *texture; -} D3D_TextureData; - -typedef struct -{ - float x, y, z; - float rhw; - DWORD color; - float u, v; -} Vertex; - -static void -D3D_SetError(const char *prefix, HRESULT result) -{ - const char *error; - - switch (result) { - case D3DERR_WRONGTEXTUREFORMAT: - error = "WRONGTEXTUREFORMAT"; - break; - case D3DERR_UNSUPPORTEDCOLOROPERATION: - error = "UNSUPPORTEDCOLOROPERATION"; - break; - case D3DERR_UNSUPPORTEDCOLORARG: - error = "UNSUPPORTEDCOLORARG"; - break; - case D3DERR_UNSUPPORTEDALPHAOPERATION: - error = "UNSUPPORTEDALPHAOPERATION"; - break; - case D3DERR_UNSUPPORTEDALPHAARG: - error = "UNSUPPORTEDALPHAARG"; - break; - case D3DERR_TOOMANYOPERATIONS: - error = "TOOMANYOPERATIONS"; - break; - case D3DERR_CONFLICTINGTEXTUREFILTER: - error = "CONFLICTINGTEXTUREFILTER"; - break; - case D3DERR_UNSUPPORTEDFACTORVALUE: - error = "UNSUPPORTEDFACTORVALUE"; - break; - case D3DERR_CONFLICTINGRENDERSTATE: - error = "CONFLICTINGRENDERSTATE"; - break; - case D3DERR_UNSUPPORTEDTEXTUREFILTER: - error = "UNSUPPORTEDTEXTUREFILTER"; - break; - case D3DERR_CONFLICTINGTEXTUREPALETTE: - error = "CONFLICTINGTEXTUREPALETTE"; - break; - case D3DERR_DRIVERINTERNALERROR: - error = "DRIVERINTERNALERROR"; - break; - case D3DERR_NOTFOUND: - error = "NOTFOUND"; - break; - case D3DERR_MOREDATA: - error = "MOREDATA"; - break; - case D3DERR_DEVICELOST: - error = "DEVICELOST"; - break; - case D3DERR_DEVICENOTRESET: - error = "DEVICENOTRESET"; - break; - case D3DERR_NOTAVAILABLE: - error = "NOTAVAILABLE"; - break; - case D3DERR_OUTOFVIDEOMEMORY: - error = "OUTOFVIDEOMEMORY"; - break; - case D3DERR_INVALIDDEVICE: - error = "INVALIDDEVICE"; - break; - case D3DERR_INVALIDCALL: - error = "INVALIDCALL"; - break; - case D3DERR_DRIVERINVALIDCALL: - error = "DRIVERINVALIDCALL"; - break; - case D3DERR_WASSTILLDRAWING: - error = "WASSTILLDRAWING"; - break; - default: - error = "UNKNOWN"; - break; - } - SDL_SetError("%s: %s", prefix, error); -} - -static D3DFORMAT -PixelFormatToD3DFMT(Uint32 format) -{ - switch (format) { - case SDL_PIXELFORMAT_INDEX8: - return D3DFMT_P8; - case SDL_PIXELFORMAT_RGB332: - return D3DFMT_R3G3B2; - case SDL_PIXELFORMAT_RGB444: - return D3DFMT_X4R4G4B4; - case SDL_PIXELFORMAT_RGB555: - return D3DFMT_X1R5G5B5; - case SDL_PIXELFORMAT_ARGB4444: - return D3DFMT_A4R4G4B4; - case SDL_PIXELFORMAT_ARGB1555: - return D3DFMT_A1R5G5B5; - case SDL_PIXELFORMAT_RGB565: - return D3DFMT_R5G6B5; - case SDL_PIXELFORMAT_RGB888: - return D3DFMT_X8R8G8B8; - case SDL_PIXELFORMAT_ARGB8888: - return D3DFMT_A8R8G8B8; - case SDL_PIXELFORMAT_ARGB2101010: - return D3DFMT_A2R10G10B10; - case SDL_PIXELFORMAT_YV12: - return MAKEFOURCC('Y','V','1','2'); - case SDL_PIXELFORMAT_IYUV: - return MAKEFOURCC('I','4','2','0'); - case SDL_PIXELFORMAT_UYVY: - return D3DFMT_UYVY; - case SDL_PIXELFORMAT_YUY2: - return D3DFMT_YUY2; - default: - return D3DFMT_UNKNOWN; - } -} - -static UINT D3D_FindAdapter(IDirect3D9 * d3d, SDL_VideoDisplay * display) -{ - SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; - UINT adapter, count; - - count = IDirect3D9_GetAdapterCount(d3d); - for (adapter = 0; adapter < count; ++adapter) { - HRESULT result; - D3DADAPTER_IDENTIFIER9 info; - char *name; - - result = IDirect3D9_GetAdapterIdentifier(d3d, adapter, 0, &info); - if (FAILED(result)) { - continue; - } - name = WIN_StringToUTF8(displaydata->DeviceName); - if (SDL_strcmp(name, info.DeviceName) == 0) { - SDL_free(name); - return adapter; - } - SDL_free(name); - } - - /* This should never happen, but just in case... */ - return D3DADAPTER_DEFAULT; -} - -static SDL_bool -D3D_IsTextureFormatAvailable(IDirect3D9 * d3d, UINT adapter, - Uint32 display_format, - Uint32 texture_format) -{ - HRESULT result; - - result = IDirect3D9_CheckDeviceFormat(d3d, adapter, - D3DDEVTYPE_HAL, - PixelFormatToD3DFMT(display_format), - 0, - D3DRTYPE_TEXTURE, - PixelFormatToD3DFMT - (texture_format)); - return FAILED(result) ? SDL_FALSE : SDL_TRUE; -} - -static void -UpdateYUVTextureData(SDL_Texture * texture) -{ - D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; - SDL_Rect rect; - RECT d3drect; - D3DLOCKED_RECT locked; - HRESULT result; - - d3drect.left = 0; - d3drect.right = texture->w; - d3drect.top = 0; - d3drect.bottom = texture->h; - - result = - IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0); - if (FAILED(result)) { - return; - } - - rect.x = 0; - rect.y = 0; - rect.w = texture->w; - rect.h = texture->h; - SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w, - texture->h, locked.pBits, locked.Pitch); - - IDirect3DTexture9_UnlockRect(data->texture, 0); -} - -void -D3D_AddRenderDriver(_THIS) -{ - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - SDL_RendererInfo *info = &D3D_RenderDriver.info; - - if (data->d3d) { - int i, j; - int formats[] = { - SDL_PIXELFORMAT_INDEX8, - SDL_PIXELFORMAT_RGB332, - SDL_PIXELFORMAT_RGB444, - SDL_PIXELFORMAT_RGB555, - SDL_PIXELFORMAT_ARGB4444, - SDL_PIXELFORMAT_ARGB1555, - SDL_PIXELFORMAT_RGB565, - SDL_PIXELFORMAT_RGB888, - SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_ARGB2101010, - }; - - for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; - SDL_DisplayMode *mode = &display->desktop_mode; - UINT adapter = D3D_FindAdapter(data->d3d, display); - - /* Get the matching D3D adapter for this display */ - info->num_texture_formats = 0; - for (j = 0; j < SDL_arraysize(formats); ++j) { - if (D3D_IsTextureFormatAvailable - (data->d3d, adapter, mode->format, formats[j])) { - info->texture_formats[info->num_texture_formats++] = - formats[j]; - } - } - info->texture_formats[info->num_texture_formats++] = - SDL_PIXELFORMAT_YV12; - info->texture_formats[info->num_texture_formats++] = - SDL_PIXELFORMAT_IYUV; - info->texture_formats[info->num_texture_formats++] = - SDL_PIXELFORMAT_YUY2; - info->texture_formats[info->num_texture_formats++] = - SDL_PIXELFORMAT_UYVY; - info->texture_formats[info->num_texture_formats++] = - SDL_PIXELFORMAT_YVYU; - - SDL_AddRenderDriver(display, &D3D_RenderDriver); - } - } -} - -SDL_Renderer * -D3D_CreateRenderer(SDL_Window * window, Uint32 flags) -{ - SDL_VideoDisplay *display = window->display; - SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata; - SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; - SDL_Renderer *renderer; - D3D_RenderData *data; - HRESULT result; - D3DPRESENT_PARAMETERS pparams; - IDirect3DSwapChain9 *chain; - D3DCAPS9 caps; - - renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); - if (!renderer) { - SDL_OutOfMemory(); - return NULL; - } - - data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data)); - if (!data) { - D3D_DestroyRenderer(renderer); - SDL_OutOfMemory(); - return NULL; - } - data->d3d = videodata->d3d; - - videodata->render = RENDER_D3D; - - renderer->DisplayModeChanged = D3D_DisplayModeChanged; - renderer->CreateTexture = D3D_CreateTexture; - renderer->QueryTexturePixels = D3D_QueryTexturePixels; - renderer->SetTexturePalette = D3D_SetTexturePalette; - renderer->GetTexturePalette = D3D_GetTexturePalette; - renderer->SetTextureColorMod = D3D_SetTextureColorMod; - renderer->SetTextureAlphaMod = D3D_SetTextureAlphaMod; - renderer->SetTextureBlendMode = D3D_SetTextureBlendMode; - renderer->SetTextureScaleMode = D3D_SetTextureScaleMode; - renderer->UpdateTexture = D3D_UpdateTexture; - renderer->LockTexture = D3D_LockTexture; - renderer->UnlockTexture = D3D_UnlockTexture; - renderer->DirtyTexture = D3D_DirtyTexture; - renderer->RenderDrawPoints = D3D_RenderDrawPoints; - renderer->RenderDrawLines = D3D_RenderDrawLines; - renderer->RenderDrawRects = D3D_RenderDrawRects; - renderer->RenderFillRects = D3D_RenderFillRects; - renderer->RenderCopy = D3D_RenderCopy; - renderer->RenderReadPixels = D3D_RenderReadPixels; - renderer->RenderWritePixels = D3D_RenderWritePixels; - renderer->RenderPresent = D3D_RenderPresent; - renderer->DestroyTexture = D3D_DestroyTexture; - renderer->DestroyRenderer = D3D_DestroyRenderer; - renderer->info = D3D_RenderDriver.info; - renderer->window = window; - renderer->driverdata = data; - - renderer->info.flags = SDL_RENDERER_ACCELERATED; - - SDL_zero(pparams); - pparams.BackBufferWidth = window->w; - pparams.BackBufferHeight = window->h; - if (window->flags & SDL_WINDOW_FULLSCREEN) { - pparams.BackBufferFormat = - PixelFormatToD3DFMT(window->fullscreen_mode.format); - } else { - pparams.BackBufferFormat = D3DFMT_UNKNOWN; - } - if (flags & SDL_RENDERER_PRESENTFLIP2) { - pparams.BackBufferCount = 2; - pparams.SwapEffect = D3DSWAPEFFECT_FLIP; - } else if (flags & SDL_RENDERER_PRESENTFLIP3) { - pparams.BackBufferCount = 3; - pparams.SwapEffect = D3DSWAPEFFECT_FLIP; - } else if (flags & SDL_RENDERER_PRESENTCOPY) { - pparams.BackBufferCount = 1; - pparams.SwapEffect = D3DSWAPEFFECT_COPY; - } else { - pparams.BackBufferCount = 1; - pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; - } - if (window->flags & SDL_WINDOW_FULLSCREEN) { - pparams.Windowed = FALSE; - pparams.FullScreen_RefreshRateInHz = - window->fullscreen_mode.refresh_rate; - } else { - pparams.Windowed = TRUE; - pparams.FullScreen_RefreshRateInHz = 0; - } - if (flags & SDL_RENDERER_PRESENTVSYNC) { - pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; - } else { - pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - } - - data->adapter = D3D_FindAdapter(videodata->d3d, display); - IDirect3D9_GetDeviceCaps(videodata->d3d, data->adapter, - D3DDEVTYPE_HAL, &caps); - - result = IDirect3D9_CreateDevice(videodata->d3d, data->adapter, - D3DDEVTYPE_HAL, - windowdata->hwnd, - (caps. - DevCaps & - D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? - D3DCREATE_HARDWARE_VERTEXPROCESSING : - D3DCREATE_SOFTWARE_VERTEXPROCESSING, - &pparams, &data->device); - if (FAILED(result)) { - D3D_DestroyRenderer(renderer); - D3D_SetError("CreateDevice()", result); - return NULL; - } - data->beginScene = SDL_TRUE; - - /* Get presentation parameters to fill info */ - result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); - if (FAILED(result)) { - D3D_DestroyRenderer(renderer); - D3D_SetError("GetSwapChain()", result); - return NULL; - } - result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); - if (FAILED(result)) { - IDirect3DSwapChain9_Release(chain); - D3D_DestroyRenderer(renderer); - D3D_SetError("GetPresentParameters()", result); - return NULL; - } - IDirect3DSwapChain9_Release(chain); - switch (pparams.SwapEffect) { - case D3DSWAPEFFECT_COPY: - renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; - break; - case D3DSWAPEFFECT_FLIP: - switch (pparams.BackBufferCount) { - case 2: - renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; - break; - case 3: - renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; - break; - } - break; - case D3DSWAPEFFECT_DISCARD: - renderer->info.flags |= SDL_RENDERER_PRESENTDISCARD; - break; - } - if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { - renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; - } - data->pparams = pparams; - - IDirect3DDevice9_GetDeviceCaps(data->device, &caps); - renderer->info.max_texture_width = caps.MaxTextureWidth; - renderer->info.max_texture_height = caps.MaxTextureHeight; - - /* Set up parameters for rendering */ - IDirect3DDevice9_SetVertexShader(data->device, NULL); - IDirect3DDevice9_SetFVF(data->device, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, - D3DCULL_NONE); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); - /* Enable color modulation by diffuse color */ - IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP, - D3DTOP_MODULATE); - IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1, - D3DTA_TEXTURE); - IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2, - D3DTA_DIFFUSE); - /* Enable alpha modulation by diffuse alpha */ - IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP, - D3DTOP_MODULATE); - IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1, - D3DTA_TEXTURE); - IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2, - D3DTA_DIFFUSE); - /* Disable second texture stage, since we're done */ - IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP, - D3DTOP_DISABLE); - IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP, - D3DTOP_DISABLE); - - { -#ifdef ASSEMBLE_SHADER - const char *shader_text = -"ps_1_1\n" -"def c0, 0, 0, 0, 0.496\n" -"def c1, 0, 0, 0, 1\n" -"def c2, 0, 0, 0, -1\n" -"tex t0\n" -"mul r1, t0, v0\n" -"add r0, r1, c0\n" -"cnd r0, r0.a, c1, c2\n" -"add r0, r0, r1\n"; - LPD3DXBUFFER pCode; // buffer with the assembled shader code - LPD3DXBUFFER pErrorMsgs; // buffer with error messages - LPDWORD shader_data; - DWORD shader_size; - result = D3DXAssembleShader( shader_text, SDL_strlen(shader_text), NULL, NULL, 0, &pCode, &pErrorMsgs ); - if (FAILED(result)) { - D3D_SetError("D3DXAssembleShader()", result); - } - shader_data = (DWORD*)pCode->lpVtbl->GetBufferPointer(pCode); - shader_size = pCode->lpVtbl->GetBufferSize(pCode); -#else - const DWORD shader_data[] = { - 0xffff0101,0x00000051,0xa00f0000,0x00000000,0x00000000,0x00000000, - 0x3efdf3b6,0x00000051,0xa00f0001,0x00000000,0x00000000,0x00000000, - 0x3f800000,0x00000051,0xa00f0002,0x00000000,0x00000000,0x00000000, - 0xbf800000,0x00000042,0xb00f0000,0x00000005,0x800f0001,0xb0e40000, - 0x90e40000,0x00000002,0x800f0000,0x80e40001,0xa0e40000,0x00000050, - 0x800f0000,0x80ff0000,0xa0e40001,0xa0e40002,0x00000002,0x800f0000, - 0x80e40000,0x80e40001,0x0000ffff - }; -#endif - result = IDirect3DDevice9_CreatePixelShader(data->device, shader_data, &data->ps_mask); - if (FAILED(result)) { - D3D_SetError("CreatePixelShader()", result); - } - } - - return renderer; -} - -static int -D3D_Reset(SDL_Renderer * renderer) -{ - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - HRESULT result; - - result = IDirect3DDevice9_Reset(data->device, &data->pparams); - if (FAILED(result)) { - if (result == D3DERR_DEVICELOST) { - /* Don't worry about it, we'll reset later... */ - return 0; - } else { - D3D_SetError("Reset()", result); - return -1; - } - } - IDirect3DDevice9_SetVertexShader(data->device, NULL); - IDirect3DDevice9_SetFVF(data->device, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, - D3DCULL_NONE); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); - return 0; -} - -static int -D3D_DisplayModeChanged(SDL_Renderer * renderer) -{ - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - SDL_VideoDisplay *display = window->display; - - data->pparams.BackBufferWidth = window->w; - data->pparams.BackBufferHeight = window->h; - if (window->flags & SDL_WINDOW_FULLSCREEN) { - data->pparams.BackBufferFormat = - PixelFormatToD3DFMT(window->fullscreen_mode.format); - } else { - data->pparams.BackBufferFormat = D3DFMT_UNKNOWN; - } - return D3D_Reset(renderer); -} - -static int -D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - SDL_VideoDisplay *display = window->display; - Uint32 display_format = display->current_mode.format; - D3D_TextureData *data; - HRESULT result; - - data = (D3D_TextureData *) SDL_calloc(1, sizeof(*data)); - if (!data) { - SDL_OutOfMemory(); - return -1; - } - - texture->driverdata = data; - - if (SDL_ISPIXELFORMAT_FOURCC(texture->format) && - (texture->format != SDL_PIXELFORMAT_YUY2 || - !D3D_IsTextureFormatAvailable(renderdata->d3d, renderdata->adapter, - display_format, texture->format)) - && (texture->format != SDL_PIXELFORMAT_YVYU - || !D3D_IsTextureFormatAvailable(renderdata->d3d, renderdata->adapter, - display_format, texture->format))) { - data->yuv = - SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); - if (!data->yuv) { - return -1; - } - data->format = display->current_mode.format; - } else { - data->format = texture->format; - } - - result = - IDirect3DDevice9_CreateTexture(renderdata->device, texture->w, - texture->h, 1, 0, - PixelFormatToD3DFMT(data->format), - D3DPOOL_SDL, &data->texture, NULL); - if (FAILED(result)) { - D3D_SetError("CreateTexture()", result); - return -1; - } - - return 0; -} - -static int -D3D_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, - void **pixels, int *pitch) -{ - D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; - - if (data->yuv) { - return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch); - } else { - /* D3D textures don't have their pixels hanging out */ - return -1; - } -} - -static int -D3D_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Color * colors, int firstcolor, int ncolors) -{ - D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; - D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; - - return 0; -} - -static int -D3D_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, - SDL_Color * colors, int firstcolor, int ncolors) -{ - D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; - - return 0; -} - -static int -D3D_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) -{ - return 0; -} - -static int -D3D_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) -{ - return 0; -} - -static int -D3D_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) -{ - switch (texture->blendMode) { - case SDL_BLENDMODE_NONE: - case SDL_BLENDMODE_MASK: - case SDL_BLENDMODE_BLEND: - case SDL_BLENDMODE_ADD: - case SDL_BLENDMODE_MOD: - return 0; - default: - SDL_Unsupported(); - texture->blendMode = SDL_BLENDMODE_NONE; - return -1; - } -} - -static int -D3D_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) -{ - switch (texture->scaleMode) { - case SDL_SCALEMODE_NONE: - case SDL_SCALEMODE_FAST: - case SDL_SCALEMODE_SLOW: - case SDL_SCALEMODE_BEST: - return 0; - default: - SDL_Unsupported(); - texture->scaleMode = SDL_SCALEMODE_NONE; - return -1; - } - return 0; -} - -static int -D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, int pitch) -{ - D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; - D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; - - if (data->yuv) { - if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) { - return -1; - } - UpdateYUVTextureData(texture); - return 0; - } else { -#ifdef SDL_MEMORY_POOL_DEFAULT - IDirect3DTexture9 *temp; - RECT d3drect; - D3DLOCKED_RECT locked; - const Uint8 *src; - Uint8 *dst; - int row, length; - HRESULT result; - - result = - IDirect3DDevice9_CreateTexture(renderdata->device, texture->w, - texture->h, 1, 0, - PixelFormatToD3DFMT(texture-> - format), - D3DPOOL_SYSTEMMEM, &temp, NULL); - if (FAILED(result)) { - D3D_SetError("CreateTexture()", result); - return -1; - } - - d3drect.left = rect->x; - d3drect.right = rect->x + rect->w; - d3drect.top = rect->y; - d3drect.bottom = rect->y + rect->h; - - result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0); - if (FAILED(result)) { - IDirect3DTexture9_Release(temp); - D3D_SetError("LockRect()", result); - return -1; - } - - src = pixels; - dst = locked.pBits; - length = rect->w * SDL_BYTESPERPIXEL(texture->format); - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += pitch; - dst += locked.Pitch; - } - IDirect3DTexture9_UnlockRect(temp, 0); - - result = - IDirect3DDevice9_UpdateTexture(renderdata->device, - (IDirect3DBaseTexture9 *) temp, - (IDirect3DBaseTexture9 *) - data->texture); - IDirect3DTexture9_Release(temp); - if (FAILED(result)) { - D3D_SetError("UpdateTexture()", result); - return -1; - } -#else - RECT d3drect; - D3DLOCKED_RECT locked; - const Uint8 *src; - Uint8 *dst; - int row, length; - HRESULT result; - - d3drect.left = rect->x; - d3drect.right = rect->x + rect->w; - d3drect.top = rect->y; - d3drect.bottom = rect->y + rect->h; - - result = - IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, - 0); - if (FAILED(result)) { - D3D_SetError("LockRect()", result); - return -1; - } - - src = pixels; - dst = locked.pBits; - length = rect->w * SDL_BYTESPERPIXEL(texture->format); - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += pitch; - dst += locked.Pitch; - } - IDirect3DTexture9_UnlockRect(data->texture, 0); -#endif // SDL_MEMORY_POOL_DEFAULT - - return 0; - } -} - -static int -D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, void **pixels, - int *pitch) -{ - D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; - - if (data->yuv) { - return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, - pitch); - } else { - RECT d3drect; - D3DLOCKED_RECT locked; - HRESULT result; - - d3drect.left = rect->x; - d3drect.right = rect->x + rect->w; - d3drect.top = rect->y; - d3drect.bottom = rect->y + rect->h; - - result = - IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, - markDirty ? 0 : - D3DLOCK_NO_DIRTY_UPDATE); - if (FAILED(result)) { - D3D_SetError("LockRect()", result); - return -1; - } - *pixels = locked.pBits; - *pitch = locked.Pitch; - return 0; - } -} - -static void -D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; - - if (data->yuv) { - SDL_SW_UnlockYUVTexture(data->yuv); - UpdateYUVTextureData(texture); - } else { - IDirect3DTexture9_UnlockRect(data->texture, 0); - } -} - -static void -D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, - const SDL_Rect * rects) -{ - D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; - RECT d3drect; - int i; - - for (i = 0; i < numrects; ++i) { - const SDL_Rect *rect = &rects[i]; - - d3drect.left = rect->x; - d3drect.right = rect->x + rect->w; - d3drect.top = rect->y; - d3drect.bottom = rect->y + rect->h; - - IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect); - } -} - -static void -D3D_SetBlendMode(D3D_RenderData * data, int blendMode) -{ - switch (blendMode) { - case SDL_BLENDMODE_NONE: - IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE, - FALSE); - break; - case SDL_BLENDMODE_MASK: - case SDL_BLENDMODE_BLEND: - IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE, - TRUE); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND, - D3DBLEND_SRCALPHA); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND, - D3DBLEND_INVSRCALPHA); - break; - case SDL_BLENDMODE_ADD: - IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE, - TRUE); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND, - D3DBLEND_SRCALPHA); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND, - D3DBLEND_ONE); - break; - case SDL_BLENDMODE_MOD: - IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE, - TRUE); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND, - D3DBLEND_ZERO); - IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND, - D3DBLEND_SRCCOLOR); - break; - } -} - -static int -D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, - int count) -{ - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - DWORD color; - Vertex *vertices; - int i; - HRESULT result; - - if (data->beginScene) { - IDirect3DDevice9_BeginScene(data->device); - data->beginScene = SDL_FALSE; - } - - D3D_SetBlendMode(data, renderer->blendMode); - - result = - IDirect3DDevice9_SetTexture(data->device, 0, - (IDirect3DBaseTexture9 *) 0); - if (FAILED(result)) { - D3D_SetError("SetTexture()", result); - return -1; - } - - color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b); - - vertices = SDL_stack_alloc(Vertex, count); - for (i = 0; i < count; ++i) { - vertices[i].x = (float) points[i].x; - vertices[i].y = (float) points[i].y; - vertices[i].z = 0.0f; - vertices[i].rhw = 1.0f; - vertices[i].color = color; - vertices[i].u = 0.0f; - vertices[i].v = 0.0f; - } - result = - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, count, - vertices, sizeof(*vertices)); - SDL_stack_free(vertices); - if (FAILED(result)) { - D3D_SetError("DrawPrimitiveUP()", result); - return -1; - } - return 0; -} - -static int -D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, - int count) -{ - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - DWORD color; - Vertex *vertices; - int i; - HRESULT result; - - if (data->beginScene) { - IDirect3DDevice9_BeginScene(data->device); - data->beginScene = SDL_FALSE; - } - - D3D_SetBlendMode(data, renderer->blendMode); - - result = - IDirect3DDevice9_SetTexture(data->device, 0, - (IDirect3DBaseTexture9 *) 0); - if (FAILED(result)) { - D3D_SetError("SetTexture()", result); - return -1; - } - - color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b); - - vertices = SDL_stack_alloc(Vertex, count); - for (i = 0; i < count; ++i) { - vertices[i].x = (float) points[i].x; - vertices[i].y = (float) points[i].y; - vertices[i].z = 0.0f; - vertices[i].rhw = 1.0f; - vertices[i].color = color; - vertices[i].u = 0.0f; - vertices[i].v = 0.0f; - } - result = - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, count-1, - vertices, sizeof(*vertices)); - - /* DirectX 9 has the same line rasterization semantics as GDI, - so we need to close the endpoint of the line */ - if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { - vertices[0].x = (float) points[count-1].x; - vertices[0].y = (float) points[count-1].y; - result = IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, vertices, sizeof(*vertices)); - } - - SDL_stack_free(vertices); - if (FAILED(result)) { - D3D_SetError("DrawPrimitiveUP()", result); - return -1; - } - return 0; -} - -static int -D3D_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, - int count) -{ - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - DWORD color; - int i; - Vertex vertices[5]; - HRESULT result; - - if (data->beginScene) { - IDirect3DDevice9_BeginScene(data->device); - data->beginScene = SDL_FALSE; - } - - D3D_SetBlendMode(data, renderer->blendMode); - - result = - IDirect3DDevice9_SetTexture(data->device, 0, - (IDirect3DBaseTexture9 *) 0); - if (FAILED(result)) { - D3D_SetError("SetTexture()", result); - return -1; - } - - color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b); - - for (i = 0; i < SDL_arraysize(vertices); ++i) { - vertices[i].z = 0.0f; - vertices[i].rhw = 1.0f; - vertices[i].color = color; - vertices[i].u = 0.0f; - vertices[i].v = 0.0f; - } - - for (i = 0; i < count; ++i) { - const SDL_Rect *rect = rects[i]; - - vertices[0].x = (float) rect->x; - vertices[0].y = (float) rect->y; - - vertices[1].x = (float) rect->x+rect->w-1; - vertices[1].y = (float) rect->y; - - vertices[2].x = (float) rect->x+rect->w-1; - vertices[2].y = (float) rect->y+rect->h-1; - - vertices[3].x = (float) rect->x; - vertices[3].y = (float) rect->y+rect->h-1; - - vertices[4].x = (float) rect->x; - vertices[4].y = (float) rect->y; - - result = - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, 4, - vertices, sizeof(*vertices)); - - if (FAILED(result)) { - D3D_SetError("DrawPrimitiveUP()", result); - return -1; - } - } - return 0; -} - -static int -D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, - int count) -{ - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - DWORD color; - int i; - float minx, miny, maxx, maxy; - Vertex vertices[4]; - HRESULT result; - - if (data->beginScene) { - IDirect3DDevice9_BeginScene(data->device); - data->beginScene = SDL_FALSE; - } - - D3D_SetBlendMode(data, renderer->blendMode); - - result = - IDirect3DDevice9_SetTexture(data->device, 0, - (IDirect3DBaseTexture9 *) 0); - if (FAILED(result)) { - D3D_SetError("SetTexture()", result); - return -1; - } - - color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b); - - for (i = 0; i < count; ++i) { - const SDL_Rect *rect = rects[i]; - - minx = (float) rect->x; - miny = (float) rect->y; - maxx = (float) rect->x + rect->w; - maxy = (float) rect->y + rect->h; - - vertices[0].x = minx; - vertices[0].y = miny; - vertices[0].z = 0.0f; - vertices[0].rhw = 1.0f; - vertices[0].color = color; - vertices[0].u = 0.0f; - vertices[0].v = 0.0f; - - vertices[1].x = maxx; - vertices[1].y = miny; - vertices[1].z = 0.0f; - vertices[1].rhw = 1.0f; - vertices[1].color = color; - vertices[1].u = 0.0f; - vertices[1].v = 0.0f; - - vertices[2].x = maxx; - vertices[2].y = maxy; - vertices[2].z = 0.0f; - vertices[2].rhw = 1.0f; - vertices[2].color = color; - vertices[2].u = 0.0f; - vertices[2].v = 0.0f; - - vertices[3].x = minx; - vertices[3].y = maxy; - vertices[3].z = 0.0f; - vertices[3].rhw = 1.0f; - vertices[3].color = color; - vertices[3].u = 0.0f; - vertices[3].v = 0.0f; - - result = - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, - 2, vertices, sizeof(*vertices)); - if (FAILED(result)) { - D3D_SetError("DrawPrimitiveUP()", result); - return -1; - } - } - return 0; -} - -static int -D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) -{ - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; - LPDIRECT3DPIXELSHADER9 shader = NULL; - float minx, miny, maxx, maxy; - float minu, maxu, minv, maxv; - DWORD color; - Vertex vertices[4]; - HRESULT result; - - if (data->beginScene) { - IDirect3DDevice9_BeginScene(data->device); - data->beginScene = SDL_FALSE; - } - - minx = (float) dstrect->x - 0.5f; - miny = (float) dstrect->y - 0.5f; - maxx = (float) dstrect->x + dstrect->w - 0.5f; - maxy = (float) dstrect->y + dstrect->h - 0.5f; - - minu = (float) srcrect->x / texture->w; - maxu = (float) (srcrect->x + srcrect->w) / texture->w; - minv = (float) srcrect->y / texture->h; - maxv = (float) (srcrect->y + srcrect->h) / texture->h; - - color = D3DCOLOR_ARGB(texture->a, texture->r, texture->g, texture->b); - - vertices[0].x = minx; - vertices[0].y = miny; - vertices[0].z = 0.0f; - vertices[0].rhw = 1.0f; - vertices[0].color = color; - vertices[0].u = minu; - vertices[0].v = minv; - - vertices[1].x = maxx; - vertices[1].y = miny; - vertices[1].z = 0.0f; - vertices[1].rhw = 1.0f; - vertices[1].color = color; - vertices[1].u = maxu; - vertices[1].v = minv; - - vertices[2].x = maxx; - vertices[2].y = maxy; - vertices[2].z = 0.0f; - vertices[2].rhw = 1.0f; - vertices[2].color = color; - vertices[2].u = maxu; - vertices[2].v = maxv; - - vertices[3].x = minx; - vertices[3].y = maxy; - vertices[3].z = 0.0f; - vertices[3].rhw = 1.0f; - vertices[3].color = color; - vertices[3].u = minu; - vertices[3].v = maxv; - - D3D_SetBlendMode(data, texture->blendMode); - - if (texture->blendMode == SDL_BLENDMODE_MASK) { - shader = data->ps_mask; - } - - switch (texture->scaleMode) { - case SDL_SCALEMODE_NONE: - case SDL_SCALEMODE_FAST: - IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER, - D3DTEXF_POINT); - IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER, - D3DTEXF_POINT); - break; - case SDL_SCALEMODE_SLOW: - IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER, - D3DTEXF_LINEAR); - IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER, - D3DTEXF_LINEAR); - break; - case SDL_SCALEMODE_BEST: - IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER, - D3DTEXF_GAUSSIANQUAD); - IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER, - D3DTEXF_GAUSSIANQUAD); - break; - } - - result = - IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *) - texturedata->texture); - if (FAILED(result)) { - D3D_SetError("SetTexture()", result); - return -1; - } - if (shader) { - result = IDirect3DDevice9_SetPixelShader(data->device, shader); - if (FAILED(result)) { - D3D_SetError("SetShader()", result); - return -1; - } - } - result = - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, - vertices, sizeof(*vertices)); - if (FAILED(result)) { - D3D_SetError("DrawPrimitiveUP()", result); - return -1; - } - if (shader) { - result = IDirect3DDevice9_SetPixelShader(data->device, NULL); - if (FAILED(result)) { - D3D_SetError("SetShader()", result); - return -1; - } - } - return 0; -} - -static int -D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, void * pixels, int pitch) -{ - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - SDL_VideoDisplay *display = window->display; - D3DSURFACE_DESC desc; - LPDIRECT3DSURFACE9 backBuffer; - LPDIRECT3DSURFACE9 surface; - RECT d3drect; - D3DLOCKED_RECT locked; - HRESULT result; - - result = IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer); - if (FAILED(result)) { - D3D_SetError("GetBackBuffer()", result); - return -1; - } - - result = IDirect3DSurface9_GetDesc(backBuffer, &desc); - if (FAILED(result)) { - D3D_SetError("GetDesc()", result); - IDirect3DSurface9_Release(backBuffer); - return -1; - } - - result = IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL); - if (FAILED(result)) { - D3D_SetError("CreateOffscreenPlainSurface()", result); - IDirect3DSurface9_Release(backBuffer); - return -1; - } - - result = IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, surface); - if (FAILED(result)) { - D3D_SetError("GetRenderTargetData()", result); - IDirect3DSurface9_Release(surface); - IDirect3DSurface9_Release(backBuffer); - return -1; - } - - d3drect.left = rect->x; - d3drect.right = rect->x + rect->w; - d3drect.top = rect->y; - d3drect.bottom = rect->y + rect->h; - - result = IDirect3DSurface9_LockRect(surface, &locked, &d3drect, D3DLOCK_READONLY); - if (FAILED(result)) { - D3D_SetError("LockRect()", result); - IDirect3DSurface9_Release(surface); - IDirect3DSurface9_Release(backBuffer); - return -1; - } - - SDL_ConvertPixels(rect->w, rect->h, - display->current_mode.format, locked.pBits, locked.Pitch, - format, pixels, pitch); - - IDirect3DSurface9_UnlockRect(surface); - - IDirect3DSurface9_Release(surface); - IDirect3DSurface9_Release(backBuffer); - - return 0; -} - -static int -D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, const void * pixels, int pitch) -{ - /* Work in progress */ - SDL_Unsupported(); - return -1; -} - -static void -D3D_RenderPresent(SDL_Renderer * renderer) -{ - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - HRESULT result; - - if (!data->beginScene) { - IDirect3DDevice9_EndScene(data->device); - data->beginScene = SDL_TRUE; - } - - result = IDirect3DDevice9_TestCooperativeLevel(data->device); - if (result == D3DERR_DEVICELOST) { - /* We'll reset later */ - return; - } - if (result == D3DERR_DEVICENOTRESET) { - D3D_Reset(renderer); - } - result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL); - if (FAILED(result)) { - D3D_SetError("Present()", result); - } -} - -static void -D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; - - if (!data) { - return; - } - if (data->yuv) { - SDL_SW_DestroyYUVTexture(data->yuv); - } - if (data->texture) { - IDirect3DTexture9_Release(data->texture); - } - SDL_free(data); - texture->driverdata = NULL; -} - -static void -D3D_DestroyRenderer(SDL_Renderer * renderer) -{ - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; - - if (data) { - if (data->device) { - IDirect3DDevice9_Release(data->device); - } - SDL_free(data); - } - SDL_free(renderer); -} - -#endif /* SDL_VIDEO_RENDER_D3D */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_d3drender.h --- a/src/video/win32/SDL_d3drender.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#if SDL_VIDEO_RENDER_D3D -extern void D3D_AddRenderDriver(_THIS); -#endif - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_gapirender.c --- a/src/video/win32/SDL_gapirender.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1281 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2010 by Andrey Afletdinov * - * * - * WinCE RAW/GAPI video driver * - * * - * Part of the SDL - (Simple DirectMedia Layer) * - * http://www.libsdl.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include "SDL_config.h" - -#if SDL_VIDEO_RENDER_GAPI - -#include "SDL_win32video.h" -#include "SDL_win32window.h" -#include "../SDL_yuv_sw_c.h" - -// RawFrameBufferInfo -typedef struct -{ - WORD wFormat; - WORD wBPP; - VOID *pFramePointer; - int cxStride; - int cyStride; - int cxPixels; - int cyPixels; -} RawFrameBufferInfo; - -// GXDeviceInfo -typedef struct -{ - long Version; - void* pvFrameBuffer; - unsigned long cbStride; - unsigned long cxWidth; - unsigned long cyHeight; - unsigned long cBPP; - unsigned long ffFormat; - char unknown[0x84 - 7 * 4]; -} GXDeviceInfo; - -// wince: GXDisplayProperties -struct GXDisplayProperties -{ - DWORD cxWidth; - DWORD cyHeight; - long cbxPitch; - long cbyPitch; - long cBPP; - DWORD ffFormat; -}; - -// gx.dll -typedef int (*PFNGXOpenDisplay)(HWND hWnd, DWORD dwFlags); -typedef int (*PFNGXCloseDisplay)(); -typedef void* (*PFNGXBeginDraw)(); -typedef int (*PFNGXEndDraw)(); -typedef struct GXDisplayProperties (*PFNGXGetDisplayProperties)(); -typedef int (*PFNGXSuspend)(); -typedef int (*PFNGXResume)(); - -typedef struct -{ - // gx.dll - HMODULE hGapiLib; - PFNGXOpenDisplay GXOpenDisplay; - PFNGXCloseDisplay GXCloseDisplay; - PFNGXBeginDraw GXBeginDraw; - PFNGXEndDraw GXEndDraw; - PFNGXGetDisplayProperties GXGetDisplayProperties; - PFNGXSuspend GXSuspend; - PFNGXResume GXResume; -} GapiInfo; - -//#ifndef DM_DISPLAYORIENTATION -//#define DM_DISPLAYORIENTATION 0x00800000L -//#endif - -#define FORMAT_565 1 -#define FORMAT_555 2 -#define FORMAT_OTHER 3 - -#define GETRAWFRAMEBUFFER 0x00020001 -#define GETGXINFO 0x00020000 - -#define kfPalette 0x10 -#define kfDirect 0x20 -#define kfDirect555 0x40 -#define kfDirect565 0x80 - -#define GX_FULLSCREEN 0x01 - -enum ScreenOrientation { ORIENTATION_UNKNOWN = -1, ORIENTATION_UP = DMDO_0, ORIENTATION_DOWN = DMDO_180, ORIENTATION_LEFT = DMDO_270, ORIENTATION_RIGHT = DMDO_90 }; -enum ScreenGeometry { GEOMETRY_UNKNOWN, GEOMETRY_PORTRAIT, GEOMETRY_LANDSCAPE, GEOMETRY_SQUARE }; -enum FrameBufferFlags { FB_SKIP_OFFSET = 0x0001, FB_RAW_MODE = 0x0002, FB_SUSPENDED = 0x0004 }; - -// private framebuffer info -typedef struct -{ - int width; - int height; - int xpitch; - int ypitch; - int offset; -} FrameBufferInfo; - -// private display data -typedef struct -{ - unsigned char* pixels; // video memory - int format; // video format - FrameBufferInfo fb; // framebuffer geometry - GapiInfo* gapi; // GAPI module - int userOrientation; - int systemOrientation; - int hardwareGeometry; - int flags; // fb flags - float scale; // scale pointer position - int debug; - -} WINCE_RenderData; - -typedef struct -{ - SDL_SW_YUVTexture *yuv; - Uint32 format; - void *pixels; - int pitch; - -} WINCE_TextureData; - - -// system func -SDL_Renderer* WINCE_CreateRenderer(SDL_Window* window, Uint32 flags); -void WINCE_DestroyRenderer(SDL_Renderer* renderer); - -int WINCE_CreateTexture(SDL_Renderer* renderer, SDL_Texture* texture); -void WINCE_DestroyTexture(SDL_Renderer* renderer, SDL_Texture* texture); -int WINCE_QueryTexturePixels(SDL_Renderer* renderer, SDL_Texture* texture, void** pixels, int* pitch); -int WINCE_UpdateTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, const void* pixels, int pitch); -int WINCE_LockTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, int dirty, void** pixels, int* pitch); -void WINCE_UnlockTexture(SDL_Renderer* renderer, SDL_Texture* texture); - -int WINCE_Available(void); -void WINCE_SetupOrientation(WINCE_RenderData* data, int width, int height); - -int WINCE_RenderCopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srect, const SDL_Rect* drect); -void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible); - -void WINCE_RenderPresent(SDL_Renderer* renderer); -int WINCE_RenderDrawPoints(SDL_Renderer* renderer, const SDL_Point* points, int count); -int WINCE_RenderDrawLines(SDL_Renderer* renderer, const SDL_Point* points, int count); -int WINCE_RenderDrawRects(SDL_Renderer* renderer, const SDL_Rect ** rects, int count); -int WINCE_RenderFillRects(SDL_Renderer* renderer, const SDL_Rect** rects, int count); - -void WINCE_PointerCoordinateTransform(SDL_Window* window, POINT* pt); -void WINCE_DumpVideoInfo(WINCE_RenderData* data); -void WINCE_PortraitTransform(WINCE_RenderData* data, int width, int height); -void WINCE_LandscapeTransform(WINCE_RenderData* data, int width, int height); -void WINCE_SquareTransform(WINCE_RenderData* data, int width, int height); -int WINCE_FixedGeometry(FrameBufferInfo* fb, int bpp, int debug); -int WINCE_GetDMOrientation(void); -int WINCE_SetDMOrientation(int orientation); -void WINCE_UpdateYUVTextureData(SDL_Texture* texture); - -// gapi engine specific -int GAPI_Init(WINCE_RenderData* data, HWND hwnd); -void GAPI_Quit(WINCE_RenderData* data); - -// raw engine specific -int RAW_Init(WINCE_RenderData* data); -void RAW_Quit(WINCE_RenderData* data); - -// tools -void FrameBufferRotate(FrameBufferInfo* src, int orientation); -int GetFrameBufferOrientation(const FrameBufferInfo* src); -void PointerRotate(POINT* pt, const FrameBufferInfo* fb, int orientation); -void FrameBufferInitialize(FrameBufferInfo* fb); -void FrameBufferDumpInfo(const FrameBufferInfo* fb, const char*); -const char* GetOrientationName(int orientation); -void UpdateLine16to16(const FrameBufferInfo* fb, const Uint16* src, Uint16* dst, Uint16 width); - -// stdlib -inline int __abs(int x){ return x < 0 ? -x : x; }; -inline void __swap(int* a, int* b){ int t = *a; *a = *b; *b = t; }; - -#define GAPI_RENDER_NAME "gapi" -#define RAW_RENDER_NAME "raw" -// -SDL_RenderDriver GAPI_RenderDriver = { - WINCE_CreateRenderer, - { - GAPI_RENDER_NAME, - (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD), - (SDL_TEXTUREMODULATE_NONE), - (SDL_BLENDMODE_NONE), - (SDL_SCALEMODE_NONE), - 7, - { - SDL_PIXELFORMAT_RGB555, - SDL_PIXELFORMAT_RGB565, - SDL_PIXELFORMAT_YV12, - SDL_PIXELFORMAT_IYUV, - SDL_PIXELFORMAT_YUY2, - SDL_PIXELFORMAT_UYVY, - SDL_PIXELFORMAT_YVYU - }, - 0, - 0 - } -}; - -SDL_RenderDriver RAW_RenderDriver = { - WINCE_CreateRenderer, - { - RAW_RENDER_NAME, - (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD), - (SDL_TEXTUREMODULATE_NONE), - (SDL_BLENDMODE_NONE), - (SDL_SCALEMODE_NONE), - 7, - { - SDL_PIXELFORMAT_RGB555, - SDL_PIXELFORMAT_RGB565, - SDL_PIXELFORMAT_YV12, - SDL_PIXELFORMAT_IYUV, - SDL_PIXELFORMAT_YUY2, - SDL_PIXELFORMAT_UYVY, - SDL_PIXELFORMAT_YVYU - }, - 0, - 0 - } -}; - -int WINCE_Available(void) -{ - const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER"); - - // raw check - RawFrameBufferInfo rfbi = { 0 }; - HDC hdc = GetDC(NULL); - int render_raw = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi); - ReleaseDC(NULL, hdc); - - if(render_raw != 0 && rfbi.cxPixels != 0 && rfbi.cyPixels != 0 && - rfbi.pFramePointer != 0 && rfbi.cxStride != 0 && rfbi.cyStride != 0) - render_raw = 1; - - if(preferably && 0 == SDL_strcasecmp(preferably, RAW_RENDER_NAME)) return 0 != render_raw; - - // gapi check - HMODULE render_gapi = LoadLibrary(TEXT("\\Windows\\gx.dll")); - if(0 == render_gapi) - render_gapi = LoadLibrary(TEXT("gx.dll")); - FreeLibrary(render_gapi); - - if(preferably && 0 == SDL_strcasecmp(preferably, GAPI_RENDER_NAME)) return 0 != render_gapi; - - return 0 != render_raw || 0 != render_gapi; -} - -void WINCE_AddRenderDriver(_THIS) -{ - HDC hdc; - HMODULE render_gapi; - int render_raw, ii; - const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER"); - - // raw check - RawFrameBufferInfo rfbi = { 0 }; - hdc = GetDC(NULL); - render_raw = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi); - ReleaseDC(NULL, hdc); - - if(render_raw != 0 && rfbi.cxPixels != 0 && rfbi.cyPixels != 0 && - rfbi.pFramePointer != 0 && rfbi.cxStride != 0 && rfbi.cyStride != 0) - render_raw = 1; - - // gapi check - render_gapi = LoadLibrary(TEXT("\\Windows\\gx.dll")); - if(0 == render_gapi) - render_gapi = LoadLibrary(TEXT("gx.dll")); - - if(render_gapi) - FreeLibrary(render_gapi); - - for(ii = 0; ii < _this->num_displays; ++ii) - { - if(preferably) - { - if(0 == SDL_strcasecmp(preferably, RAW_RENDER_NAME) && render_raw) - SDL_AddRenderDriver(&_this->displays[ii], &RAW_RenderDriver); - else - if(0 == SDL_strcasecmp(preferably, GAPI_RENDER_NAME) && render_gapi) - SDL_AddRenderDriver(&_this->displays[ii], &GAPI_RenderDriver); - } - else - { - if(render_raw) - SDL_AddRenderDriver(&_this->displays[ii], &RAW_RenderDriver); - if(render_gapi) - SDL_AddRenderDriver(&_this->displays[ii], &GAPI_RenderDriver); - } - } -} - -SDL_Renderer* WINCE_CreateRenderer(SDL_Window* window, Uint32 flags) -{ - SDL_VideoDisplay* display = window->display; - SDL_DisplayMode* displayMode = &display->current_mode; - SDL_WindowData* windowdata = (SDL_WindowData *) window->driverdata; - SDL_Renderer* renderer; - WINCE_RenderData* data; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - - if(!(window->flags & SDL_WINDOW_FULLSCREEN)) - window->flags |= SDL_WINDOW_FULLSCREEN; - - if(!SDL_PixelFormatEnumToMasks(displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) - { - SDL_SetError("Unknown display format"); - return NULL; - } - - switch(window->fullscreen_mode.format) - { - case SDL_PIXELFORMAT_RGB555: - case SDL_PIXELFORMAT_RGB565: - break; - - default: - SDL_SetError("Support only 16 or 15 bpp"); - return NULL; - } - - renderer = (SDL_Renderer*) SDL_calloc(1, sizeof(SDL_Renderer)); - if(!renderer) - { - SDL_OutOfMemory(); - return NULL; - } - - data = (WINCE_RenderData*) SDL_calloc(1, sizeof(WINCE_RenderData)); - if(!data) - { - WINCE_DestroyRenderer(renderer); - SDL_OutOfMemory(); - return NULL; - } - - // initialize internal engine - if(!RAW_Init(data) && !GAPI_Init(data, windowdata->hwnd)) - { - WINCE_DestroyRenderer(renderer); - return NULL; - } - - - // set debug - data->debug = SDL_getenv("DEBUG_VIDEO_GAPI") || SDL_getenv("GAPI_RENDERER_DEBUG") ? 1 : 0; -#if defined(DEBUG_VIDEO_GAPI) || defined(GAPI_RENDERER_DEBUG) - data->debug = 1; -#endif - - windowdata->videodata->render = data->gapi ? RENDER_GAPI : RENDER_RAW; - windowdata->videodata->CoordTransform = WINCE_PointerCoordinateTransform; - - window->display->device->MaximizeWindow = NULL; - window->display->device->MinimizeWindow = NULL; - - WINCE_SetupOrientation(data, window->w, window->h); - - renderer->CreateTexture = WINCE_CreateTexture; - renderer->DestroyTexture = WINCE_DestroyTexture; - renderer->QueryTexturePixels = WINCE_QueryTexturePixels; - renderer->UpdateTexture = WINCE_UpdateTexture; - renderer->LockTexture = WINCE_LockTexture; - renderer->UnlockTexture = WINCE_UnlockTexture; - - renderer->RenderCopy = WINCE_RenderCopy; - renderer->DestroyRenderer = WINCE_DestroyRenderer; - - renderer->RenderPresent = WINCE_RenderPresent; - renderer->RenderDrawPoints = WINCE_RenderDrawPoints; - renderer->RenderDrawLines = WINCE_RenderDrawLines; - renderer->RenderDrawRects = WINCE_RenderDrawRects; - renderer->RenderFillRects = WINCE_RenderFillRects; - - renderer->info = data->gapi ? GAPI_RenderDriver.info : RAW_RenderDriver.info; - - renderer->window = window; - renderer->driverdata = data; - - return renderer; -} - -void WINCE_DestroyRenderer(SDL_Renderer* renderer) -{ - WINCE_RenderData *renderdata = (WINCE_RenderData*) renderer->driverdata; - - if(renderdata) - { - if(renderdata->gapi) - GAPI_Quit(renderdata); - else - RAW_Quit(renderdata); - - SDL_free(renderdata); - } - - SDL_free(renderer); -} - -int WINCE_CreateTexture(SDL_Renderer* renderer, SDL_Texture* texture) -{ - WINCE_TextureData* texturedata = (WINCE_TextureData*) SDL_calloc(1, sizeof(WINCE_TextureData)); - if(NULL == texturedata) - { - SDL_OutOfMemory(); - return -1; - } - - texturedata->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); - texturedata->pixels = SDL_malloc(texture->h * texturedata->pitch); - if(NULL == texturedata->pixels) - { - SDL_OutOfMemory(); - return -1; - } - - if(SDL_ISPIXELFORMAT_FOURCC(texture->format)) - { - texturedata->yuv = SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); - if(NULL == texturedata->yuv) - { - SDL_OutOfMemory(); - return -1; - } - SDL_Window* window = renderer->window; - SDL_VideoDisplay* display = window->display; - texturedata->format = display->current_mode.format; - } - else - { - texturedata->yuv = NULL; - texturedata->format = texture->format; - } - - texture->driverdata = texturedata; - - return 0; -} - -void WINCE_DestroyTexture(SDL_Renderer* renderer, SDL_Texture* texture) -{ - WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata; - - if(texturedata) - { - if(texturedata->yuv) SDL_SW_DestroyYUVTexture(texturedata->yuv); - if(texturedata->pixels) SDL_free(texturedata->pixels); - SDL_free(texturedata); - texture->driverdata = NULL; - } -} - -int WINCE_QueryTexturePixels(SDL_Renderer* renderer, SDL_Texture* texture, void** pixels, int* pitch) -{ - WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata; - - if(texturedata->yuv) - return SDL_SW_QueryYUVTexturePixels(texturedata->yuv, pixels, pitch); - - *pixels = texturedata->pixels; - *pitch = texturedata->pitch; - - return 0; -} - -int WINCE_UpdateTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, const void* pixels, int pitch) -{ - WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata; - - if(texturedata->yuv) - { - if(SDL_SW_UpdateYUVTexture(texturedata->yuv, rect, pixels, pitch) < 0) - return -1; - WINCE_UpdateYUVTextureData(texture); - return 0; - } - - if(0 < rect->w && 0 < rect->h) - { - const unsigned char *src = ((const unsigned char*) pixels); - unsigned char *dst = ((unsigned char*) texturedata->pixels) + - rect->y * texturedata->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format); - int length = rect->w * SDL_BYTESPERPIXEL(texture->format); - int height = rect->h; - - while(height--) - { - SDL_memcpy(dst, src, length); - dst += texturedata->pitch; - src += pitch; - } - } - - return 0; -} - -int WINCE_LockTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, int dirty, void** pixels, int* pitch) -{ - WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata; - - if(texturedata->yuv) - return SDL_SW_LockYUVTexture(texturedata->yuv, rect, dirty, pixels, pitch); - - *pixels = (void *) ((unsigned char*) texturedata->pixels + - rect->y * texturedata->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format)); - *pitch = texturedata->pitch; -} - -void WINCE_UnlockTexture(SDL_Renderer* renderer, SDL_Texture* texture) -{ - WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata; - - if(texturedata->yuv) - { - SDL_SW_UnlockYUVTexture(texturedata->yuv); - WINCE_UpdateYUVTextureData(texture); - } -} - -int WINCE_RenderCopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srect, const SDL_Rect* drect) -{ - WINCE_RenderData* dstdata = (WINCE_RenderData*) renderer->driverdata; - WINCE_TextureData* srcdata = (WINCE_TextureData*) texture->driverdata; - - if((dstdata->flags & FB_SUSPENDED) || - 0 >= srect->w || 0 >= srect->h) return; - - // lock gapi - if(dstdata->gapi) dstdata->gapi->GXBeginDraw(); - - const unsigned char *src = ((const unsigned char*) srcdata->pixels); - unsigned char *dst = dstdata->pixels + (dstdata->flags & FB_SKIP_OFFSET ? 0 : dstdata->fb.offset) + - drect->y * dstdata->fb.ypitch + - drect->x * dstdata->fb.xpitch; - if(srcdata->yuv) - { - return SDL_SW_CopyYUVToRGB(srcdata->yuv, - srect, srcdata->format, - drect->w, drect->h, dst, - dstdata->fb.ypitch); - } - else - { - int height = drect->h; - int length = drect->w * SDL_BYTESPERPIXEL(texture->format); // in bytes - - while(height--) - { - switch(SDL_BYTESPERPIXEL(texture->format)) - { - case 2: UpdateLine16to16(&dstdata->fb, (Uint16*) src, (Uint16*) dst, length >> 1); break; - - default: break; - } - - dst += dstdata->fb.ypitch; - src += srcdata->pitch; - } - } - - // unlock gapi - if(dstdata->gapi) dstdata->gapi->GXEndDraw(); - - return 0; -} - -void WINCE_RenderPresent(SDL_Renderer* renderer) -{ -} - -int WINCE_RenderDrawPoints(SDL_Renderer* renderer, const SDL_Point* points, int count) -{ - SDL_Unsupported(); - return -1; -} - -int WINCE_RenderDrawLines(SDL_Renderer* renderer, const SDL_Point* points, int count) -{ - SDL_Unsupported(); - return -1; -} - -int WINCE_RenderDrawRects(SDL_Renderer* renderer, const SDL_Rect ** rects, int count) -{ - SDL_Unsupported(); - return -1; -} - -int WINCE_RenderFillRects(SDL_Renderer* renderer, const SDL_Rect** rects, int count) -{ - SDL_Unsupported(); - return -1; -} - - - -void WINCE_SetupOrientation(WINCE_RenderData* data, int width, int height) -{ - const float maxW1 = GetSystemMetrics(SM_CXSCREEN) > GetSystemMetrics(SM_CYSCREEN) ? GetSystemMetrics(SM_CXSCREEN) : GetSystemMetrics(SM_CYSCREEN); - const float maxW2 = data->fb.width > data->fb.height ? data->fb.width : data->fb.height; - - // scale define - data->scale = maxW2 / maxW1; - - // init fb values - FrameBufferInitialize(&data->fb); - - // orientation values - data->userOrientation = ORIENTATION_UP; - data->systemOrientation = WINCE_GetDMOrientation(); - data->hardwareGeometry = data->fb.width == data->fb.height ? GEOMETRY_SQUARE : - (data->fb.width < data->fb.height ? GEOMETRY_PORTRAIT : GEOMETRY_LANDSCAPE); - - if(data->debug) - WINCE_DumpVideoInfo(data); - - if(data->systemOrientation == ORIENTATION_UNKNOWN) - data->systemOrientation == ORIENTATION_UP; - - data->userOrientation = ORIENTATION_UP; - - switch(data->hardwareGeometry) - { - case GEOMETRY_PORTRAIT: WINCE_PortraitTransform(data, width, height); break; - case GEOMETRY_LANDSCAPE: WINCE_LandscapeTransform(data, width, height); break; - case GEOMETRY_SQUARE: WINCE_SquareTransform(data, width, height); break; - default: break; - } - - // debug - if(data->debug) - { - printf("\n"); - printf("user video width: %d\n", width); - printf("user video height: %d\n", height); - FrameBufferDumpInfo(&data->fb, "user"); - } -} - -void WINCE_DumpVideoInfo(WINCE_RenderData* data) -{ - // get oem info - WCHAR oemInfo[48]; - SDL_memset(oemInfo, 0, sizeof(oemInfo)); - SystemParametersInfo(SPI_GETOEMINFO, sizeof(oemInfo) - sizeof(WCHAR), oemInfo, 0); - - printf("hardware oem: "); - wprintf(oemInfo); - printf("\n"); - - printf("video driver mode: %s\n", (data->flags & FB_RAW_MODE ? RAW_RENDER_NAME : GAPI_RENDER_NAME)); - printf("GetSystemMetrics(SM_CXSCREEN): %d\n", GetSystemMetrics(SM_CXSCREEN)); - printf("GetSystemMetrics(SM_CYSCREEN): %d\n", GetSystemMetrics(SM_CYSCREEN)); - printf("scale coord: %f\n", data->scale); - - FrameBufferDumpInfo(&data->fb, "hardware"); - - printf("display format: %p\n", data->format); - printf("display bits per pixel: %d\n", SDL_BITSPERPIXEL(data->format)); - printf("display bytes per pixel: %d\n", SDL_BYTESPERPIXEL(data->format)); - printf("display memory: %p\n", data->pixels); - printf("system orientation: %d, %s\n", data->systemOrientation, GetOrientationName(data->systemOrientation)); - printf("hardware geometry: %d\n", data->hardwareGeometry); -} - -void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible) -{ - SDL_WindowData* windowdata = (SDL_WindowData*) window->driverdata; - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - SDL_Renderer* renderer = (SDL_Renderer*) window->renderer; - - if(visible) - { - if(window->flags & SDL_WINDOW_FULLSCREEN) - { - if(videodata->SHFullScreen) - videodata->SHFullScreen(windowdata->hwnd, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON); - ShowWindow(FindWindow(TEXT("HHTaskBar"), NULL), SW_HIDE); - } - - ShowWindow(windowdata->hwnd, SW_SHOW); - SetForegroundWindow(windowdata->hwnd); - - if(renderer && - (videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW)) - { - WINCE_RenderData* renderdata = (WINCE_RenderData*) renderer->driverdata; - renderdata->flags &= ~FB_SUSPENDED; - if(renderdata->gapi) renderdata->gapi->GXResume(); - } - } - else - { - if(renderer && - (videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW)) - { - WINCE_RenderData* renderdata = (WINCE_RenderData*) renderer->driverdata; - if(renderdata->gapi) renderdata->gapi->GXSuspend(); - renderdata->flags |= FB_SUSPENDED; - } - - ShowWindow(windowdata->hwnd, SW_HIDE); - - if(window->flags & SDL_WINDOW_FULLSCREEN) - { - if(videodata->SHFullScreen) - videodata->SHFullScreen(windowdata->hwnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON); - ShowWindow(FindWindow(TEXT("HHTaskBar"), NULL), SW_SHOW); - } - } -} - - -void WINCE_PointerCoordinateTransform(SDL_Window* window, POINT* pt) -{ - WINCE_RenderData* data = (WINCE_RenderData*) window->renderer->driverdata; - - pt->x *= data->scale; - pt->y *= data->scale; - - PointerRotate(pt, &data->fb, data->userOrientation); -} - -void WINCE_PortraitTransform(WINCE_RenderData* data, int width, int height) -{ - if(data->systemOrientation != ORIENTATION_UP) - FrameBufferRotate(&data->fb, data->systemOrientation); - - if(data->fb.width != width || data->fb.height != height) - switch(data->systemOrientation) - { - case ORIENTATION_UP: - case ORIENTATION_LEFT: data->userOrientation = ORIENTATION_RIGHT; break; - case ORIENTATION_RIGHT: - case ORIENTATION_DOWN: data->userOrientation = ORIENTATION_LEFT; break; - default: break; - } - - if(data->userOrientation != ORIENTATION_UP) - FrameBufferRotate(&data->fb, data->userOrientation); -} - -void WINCE_LandscapeTransform(WINCE_RenderData* data, int width, int height) -{ - switch(data->systemOrientation) - { - case ORIENTATION_UP: FrameBufferRotate(&data->fb, ORIENTATION_LEFT); break; - case ORIENTATION_LEFT:FrameBufferRotate(&data->fb, ORIENTATION_DOWN); break; - case ORIENTATION_DOWN:FrameBufferRotate(&data->fb, ORIENTATION_RIGHT); break; - default: break; - } - - if(data->fb.width != width || data->fb.height != height) - switch(data->systemOrientation) - { - case ORIENTATION_UP: - case ORIENTATION_LEFT: data->userOrientation = ORIENTATION_RIGHT; break; - case ORIENTATION_RIGHT: - case ORIENTATION_DOWN: data->userOrientation = ORIENTATION_LEFT; break; - default: break; - } - - if(data->userOrientation != ORIENTATION_UP) - FrameBufferRotate(&data->fb, data->userOrientation); -} - -void WINCE_SquareTransform(WINCE_RenderData* data, int width, int height) -{ - WINCE_PortraitTransform(data, width, height); -} - -int WINCE_FixedGeometry(FrameBufferInfo* fb, int bpp, int debug) -{ - // check square - if(GetSystemMetrics(SM_CXSCREEN) == GetSystemMetrics(SM_CYSCREEN) && - fb->width != fb->height) - { - if(fb->width < fb->height) - fb->height = fb->width; - else - if(fb->height < fb->width) - fb->width = fb->height; - } - - // check width - if(__abs(fb->xpitch) == bpp && - fb->width != __abs(fb->ypitch) / bpp) - { - if(fb->height == __abs(fb->ypitch) / bpp) - { - __swap(&fb->width, &fb->height); - - if(debug) - printf("WINCE_FixedGeometry: width: %d, height: %d\n", fb->width, fb->height); - } - else - return -1; - } - else - // check height - if(__abs(fb->ypitch) == bpp && - fb->height != __abs(fb->xpitch) / bpp) - { - if(fb->width == __abs(fb->xpitch) / bpp) - { - __swap(&fb->width, &fb->height); - - if(debug) - printf("WINCE_FixedGeometry: width: %d, height: %d\n", fb->width, fb->height); - } - else - return -1; - } - - return 0; -} - -void WINCE_UpdateYUVTextureData(SDL_Texture* texture) -{ - WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata; - SDL_Rect rect; - - rect.x = 0; - rect.y = 0; - rect.w = texture->w; - rect.h = texture->h; - SDL_SW_CopyYUVToRGB(texturedata->yuv, &rect, texturedata->format, texture->w, texture->h, texturedata->pixels, texturedata->pitch); -} - -int GAPI_Init(WINCE_RenderData* data, HWND hwnd) -{ - if(NULL == data->gapi) - { - const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER"); - if(preferably && 0 != SDL_strcasecmp(preferably, GAPI_RENDER_NAME)) return 0; - - data->gapi = (GapiInfo *) SDL_calloc(1, sizeof(GapiInfo)); - if(NULL == data->gapi) - { - SDL_OutOfMemory(); - return 0; - } - - data->gapi->hGapiLib = LoadLibrary(TEXT("\\Windows\\gx.dll")); - if(0 == data->gapi->hGapiLib) - { - data->gapi->hGapiLib = LoadLibrary(TEXT("gx.dll")); - if(0 == data->gapi->hGapiLib) return 0; - } - - // load gapi library -#define LINK(type,name,import) name=(PFN##type)GetProcAddress(data->gapi->hGapiLib,TEXT(import)) - LINK(GXOpenDisplay, data->gapi->GXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z"); - LINK(GXCloseDisplay, data->gapi->GXCloseDisplay, "?GXCloseDisplay@@YAHXZ"); - LINK(GXBeginDraw, data->gapi->GXBeginDraw, "?GXBeginDraw@@YAPAXXZ"); - LINK(GXEndDraw, data->gapi->GXEndDraw, "?GXEndDraw@@YAHXZ"); - LINK(GXGetDisplayProperties,data->gapi->GXGetDisplayProperties,"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ"); - LINK(GXSuspend, data->gapi->GXSuspend, "?GXSuspend@@YAHXZ"); - LINK(GXResume, data->gapi->GXResume, "?GXResume@@YAHXZ"); -#undef LINK - - int enable = data->gapi->GXGetDisplayProperties && data->gapi->GXCloseDisplay && data->gapi->GXOpenDisplay && - data->gapi->GXBeginDraw && data->gapi->GXEndDraw && data->gapi->GXSuspend && data->gapi->GXResume; - - if(!enable) - { - SDL_SetError("GAPI_Init: error gx.dll: internal error"); - GAPI_Quit(data); - return 0; - } - - if(0 == data->gapi->GXOpenDisplay(hwnd, GX_FULLSCREEN)) - { - SDL_SetError("GAPI_Init: couldn't initialize GAPI"); - GAPI_Quit(data); - return 0; - } - - struct GXDisplayProperties gxProperties = data->gapi->GXGetDisplayProperties(); - - // fill FrameBufferInfo - data->fb.xpitch = gxProperties.cbxPitch; - data->fb.ypitch = gxProperties.cbyPitch; - data->fb.width = gxProperties.cxWidth; - data->fb.height = gxProperties.cyHeight; - data->fb.offset = 0; - - if((gxProperties.ffFormat & kfDirect565) || 16 == gxProperties.cBPP) - data->format = SDL_PIXELFORMAT_RGB565; - else - if((gxProperties.ffFormat & kfDirect555) || 15 == gxProperties.cBPP) - data->format = SDL_PIXELFORMAT_RGB555; - else - data->format = 0; - - // get pixels - GXDeviceInfo gxInfo = { 0 }; - HDC hdc = GetDC(NULL); - - gxInfo.Version = 100; - int result = ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo), (char *) &gxInfo); - ReleaseDC(NULL, hdc); - - if(result > 0) - { - // more debug - if(data->debug) - { - printf("GXDeviceInfo.pvFrameBuffer: %p\n", gxInfo.pvFrameBuffer); - printf("GXDeviceInfo.cxWidth: %d\n", gxInfo.cxWidth); - printf("GXDeviceInfo.cyHeight: %d\n", gxInfo.cyHeight); - printf("GXDeviceInfo.cbStride: %d\n", gxInfo.cbStride); - printf("GXDeviceInfo.cBPP: %d\n", gxInfo.cBPP); - printf("GXDeviceInfo.ffFormat: 0x%x\n", gxInfo.ffFormat); - - printf("GXDeviceInfo.unk:\n"); - int ii; for(ii = 0; ii < sizeof(gxInfo.unknown); ++ii) - printf("0x%02hhX,", gxInfo.unknown[ii]); - printf("\n"); - } - - if(gxInfo.ffFormat && gxInfo.ffFormat != gxProperties.ffFormat) - { - if((gxInfo.ffFormat & kfDirect565) || 16 == gxInfo.cBPP) - data->format = SDL_PIXELFORMAT_RGB565; - else - if((gxInfo.ffFormat & kfDirect555) || 15 == gxInfo.cBPP) - data->format = SDL_PIXELFORMAT_RGB555; - } - - data->pixels = gxInfo.pvFrameBuffer; - } - else - { - data->flags |= FB_SKIP_OFFSET; - data->pixels = data->gapi->GXBeginDraw(); - data->gapi->GXEndDraw(); - - if(data->debug) - { - printf("GAPI_Init\n"); - printf("use GXBeginDraw: %p\n", data->pixels); - printf("use skip offset\n"); - } - } - - if(0 == data->format || - 0 > WINCE_FixedGeometry(&data->fb, SDL_BYTESPERPIXEL(data->format), data->debug)) - { - SDL_SetError("GAPI_Init: unknown hardware"); - GAPI_Quit(data); - return 0; - } - } - - return data->gapi && data->pixels ? 1 : 0; -} - -void GAPI_Quit(WINCE_RenderData* data) -{ - if(data->gapi) - { - if(data->gapi->GXCloseDisplay) data->gapi->GXCloseDisplay(); - if(data->gapi->hGapiLib) FreeLibrary(data->gapi->hGapiLib); - - SDL_free(data->gapi); - data->gapi = NULL; - } -} - -int RAW_Init(WINCE_RenderData* data) -{ - const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER"); - if(preferably && 0 != SDL_strcasecmp(preferably, RAW_RENDER_NAME)) return 0; - - RawFrameBufferInfo rfbi = { 0 }; - HDC hdc = GetDC(NULL); - int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi); - ReleaseDC(NULL, hdc); - - //disable - if(result == 0 || rfbi.pFramePointer == 0 || - rfbi.cxPixels == 0 || rfbi.cyPixels == 0 || - rfbi.cxStride == 0 || rfbi.cyStride == 0) return 0; - - data->flags = FB_RAW_MODE; - - // fill FrameBufferInfo - SDL_memset(&data->fb, 0, sizeof(FrameBufferInfo)); - - data->fb.xpitch = rfbi.cxStride; - data->fb.ypitch = rfbi.cyStride; - data->fb.width = rfbi.cxPixels; - data->fb.height = rfbi.cyPixels; - data->fb.offset = 0; - - if((FORMAT_565 & rfbi.wFormat) || 16 == rfbi.wBPP) - data->format = SDL_PIXELFORMAT_RGB565; - else - if((FORMAT_555 & rfbi.wFormat) || 15 == rfbi.wBPP) - data->format = SDL_PIXELFORMAT_RGB555; - else - data->format = 0; - - if(0 == data->format || - 0 > WINCE_FixedGeometry(&data->fb, SDL_BYTESPERPIXEL(data->format), data->debug)) - { - SDL_SetError("RAW_Init: unknown hardware"); - RAW_Quit(data); - return 0; - } - - data->pixels = rfbi.pFramePointer; - - return data->pixels ? 1 : 0; -} - -void RAW_Quit(WINCE_RenderData* data) -{ -} - -void FrameBufferInitialize(FrameBufferInfo* fb) -{ - int orientation = GetFrameBufferOrientation(fb); - - // set correct start offset - switch(orientation) - { - case ORIENTATION_UP: - fb->offset = 0; - break; - - case ORIENTATION_LEFT: - fb->offset = __abs(fb->ypitch * (fb->height - 1)); - break; - - case ORIENTATION_RIGHT: - fb->offset = __abs(fb->xpitch * (fb->width - 1)); - break; - - case ORIENTATION_DOWN: - fb->offset = __abs(fb->xpitch * (fb->width - 1) + - fb->ypitch * (fb->height - 1)); - break; - - default: break; - } - - //if(orientation != ORIENTATION_UP) - switch(orientation) - { - case ORIENTATION_LEFT: FrameBufferRotate(fb, ORIENTATION_RIGHT); break; - case ORIENTATION_RIGHT:FrameBufferRotate(fb, ORIENTATION_LEFT); break; - case ORIENTATION_DOWN: FrameBufferRotate(fb, ORIENTATION_DOWN); break; - - default: break; - } -} - -int GetFrameBufferOrientation(const FrameBufferInfo* src) -{ - if(src->xpitch > 0 && src->ypitch > 0) - return ORIENTATION_UP; - else - if(src->xpitch > 0 && src->ypitch < 0) - return ORIENTATION_LEFT; - else - if(src->xpitch < 0 && src->ypitch > 0) - return ORIENTATION_RIGHT; - else - if(src->xpitch < 0 && src->ypitch < 0) - return ORIENTATION_DOWN; - - return ORIENTATION_UNKNOWN; -} - -void FrameBufferRotate(FrameBufferInfo* dst, int orientation) -{ - FrameBufferInfo src; - // copy dst -> src - SDL_memcpy(&src, dst, sizeof(FrameBufferInfo)); - - switch(orientation) - { - case ORIENTATION_LEFT: - dst->width = src.height; - dst->height = src.width; - dst->xpitch = src.ypitch; - dst->ypitch = -src.xpitch; - dst->offset = src.offset + src.xpitch * (src.width - 1); - break; - - case ORIENTATION_RIGHT: - dst->width = src.height; - dst->height = src.width; - dst->xpitch = -src.ypitch; - dst->ypitch = src.xpitch; - dst->offset = src.offset + src.ypitch * (src.height - 1); - break; - - case ORIENTATION_DOWN: - FrameBufferRotate(dst, ORIENTATION_LEFT); - FrameBufferRotate(dst, ORIENTATION_LEFT); - break; - - default: - break; - } -} - -void PointerRotate(POINT* pt, const FrameBufferInfo* fb, int orientation) -{ - switch(orientation) - { - case ORIENTATION_UP: - break; - - case ORIENTATION_LEFT: - { - int temp = pt->y; - pt->y = fb->height - pt->x; - pt->x = temp; - } - break; - - case ORIENTATION_RIGHT: - { - int temp = pt->x; - pt->x = fb->width - pt->y; - pt->y = temp; - } - break; - - case ORIENTATION_DOWN: - pt->x = fb->width - pt->x; - pt->y = fb->height - pt->y; - break; - - default: break; - } -} - -const char* GetOrientationName(int orientation) -{ - switch(orientation) - { - case ORIENTATION_UP: return "UP"; - case ORIENTATION_DOWN: return "DOWN"; - case ORIENTATION_LEFT: return "LEFT"; - case ORIENTATION_RIGHT: return "RIGHT"; - default: break; - } - - return "UNKNOWN"; -} - -int WINCE_GetDMOrientation(void) -{ - DEVMODE sDevMode = {0}; - sDevMode.dmSize = sizeof(DEVMODE); - sDevMode.dmFields = DM_DISPLAYORIENTATION; - - // DMDO_0, DMDO_90, DMDO_180, DMDO_270 - if(DISP_CHANGE_BADMODE != ChangeDisplaySettingsEx(NULL, &sDevMode, 0, CDS_TEST, NULL)) - switch(sDevMode.dmDisplayOrientation) - { - case DMDO_0: return DMDO_0; - case DMDO_90: return DMDO_90; - case DMDO_180: return DMDO_180; - case DMDO_270: return DMDO_270; - default: break; - } - - SDL_SetError("WINCE_GetDMOrientation: ChangeDisplaySettingsEx return BADMODE"); - return -1; -} - -int WINCE_SetDMOrientation(int orientation) -{ - DEVMODE sDevMode = {0}; - sDevMode.dmSize = sizeof(DEVMODE); - sDevMode.dmFields = DM_DISPLAYORIENTATION; - - switch(orientation) - { - case DMDO_0: sDevMode.dmDisplayOrientation = DMDO_0; break; - case DMDO_90: sDevMode.dmDisplayOrientation = DMDO_90; break; - case DMDO_180: sDevMode.dmDisplayOrientation = DMDO_180; break; - case DMDO_270: sDevMode.dmDisplayOrientation = DMDO_270; break; - default: return 0; - } - - if(DISP_CHANGE_BADMODE != ChangeDisplaySettingsEx(NULL, &sDevMode, 0, CDS_RESET, NULL)) - return 1; - - SDL_SetError("WINCE_SetDMOrientation: ChangeDisplaySettingsEx return BADMODE"); - return -1; -} - -void FrameBufferDumpInfo(const FrameBufferInfo* fb, const char* name) -{ - printf("%s fb.width: %d\n", name, fb->width); - printf("%s fb.height: %d\n", name, fb->height); - printf("%s fb.xpitch: %d\n", name, fb->xpitch); - printf("%s fb.ypitch: %d\n", name, fb->ypitch); - printf("%s fb.offset: %d\n", name, fb->offset); - - int orientation = GetFrameBufferOrientation(fb); - printf("%s fb.orientation: %d, %s\n", name, orientation, GetOrientationName(orientation)); -} - -void UpdateLine16to16(const FrameBufferInfo* fb, const Uint16* src, Uint16* dst, Uint16 width) -{ - if(2 == fb->xpitch) - { - switch(width) - { - case 1: - *dst = *src; - break; - - case 2: - *((Uint32*) dst) = *((Uint32*) src); - break; - - default: - SDL_memcpy(dst, src, width * 2); - break; - } - } - else - if(-2 == fb->xpitch) - { - while(width--) - *dst-- = *src++; - } - else - { - while(width--) - { - *dst = *src++; - dst += fb->xpitch / 2; - } - } -} - -#endif // SDL_VIDEO_RENDER_GAPI diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_gapirender.h --- a/src/video/win32/SDL_gapirender.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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 - - Stefan Klug - klug.stefan@gmx.de -*/ -#include "SDL_config.h" - -/* SDL surface based renderer implementation */ - -#if SDL_VIDEO_RENDER_GAPI -extern void WINCE_AddRenderDriver(_THIS); -extern int WINCE_Available(void); -extern void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible); -extern int WINCE_GetDMOrientation(void); -extern int WINCE_SetDMOrientation(int orientation); -#endif - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_gapirender_c.h --- a/src/video/win32/SDL_gapirender_c.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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 - - Stefan Klug - klug.stefan@gmx.de -*/ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_gdirender.c --- a/src/video/win32/SDL_gdirender.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1127 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#if SDL_VIDEO_RENDER_GDI - -#include "SDL_win32video.h" -#include "../SDL_rect_c.h" -#include "../SDL_yuv_sw_c.h" -#include "../SDL_alphamult.h" - -#ifdef _WIN32_WCE -#define NO_GETDIBBITS 1 -#endif - -/* GDI renderer implementation */ - -static SDL_Renderer *GDI_CreateRenderer(SDL_Window * window, Uint32 flags); -static int GDI_DisplayModeChanged(SDL_Renderer * renderer); -static int GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); -static int GDI_QueryTexturePixels(SDL_Renderer * renderer, - SDL_Texture * texture, void **pixels, - int *pitch); -static int GDI_SetTexturePalette(SDL_Renderer * renderer, - SDL_Texture * texture, - const SDL_Color * colors, int firstcolor, - int ncolors); -static int GDI_GetTexturePalette(SDL_Renderer * renderer, - SDL_Texture * texture, SDL_Color * colors, - int firstcolor, int ncolors); -static int GDI_SetTextureAlphaMod(SDL_Renderer * renderer, - SDL_Texture * texture); -static int GDI_SetTextureBlendMode(SDL_Renderer * renderer, - SDL_Texture * texture); -static int GDI_SetTextureScaleMode(SDL_Renderer * renderer, - SDL_Texture * texture); -static int GDI_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, - int pitch); -static int GDI_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, - void **pixels, int *pitch); -static void GDI_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); -static int GDI_SetDrawBlendMode(SDL_Renderer * renderer); -static int GDI_RenderDrawPoints(SDL_Renderer * renderer, - const SDL_Point * points, int count); -static int GDI_RenderDrawLines(SDL_Renderer * renderer, - const SDL_Point * points, int count); -static int GDI_RenderDrawRects(SDL_Renderer * renderer, - const SDL_Rect ** rects, int count); -static int GDI_RenderFillRects(SDL_Renderer * renderer, - const SDL_Rect ** rects, int count); -static int GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect); -static int GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, void * pixels, int pitch); -static int GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, const void * pixels, int pitch); -static void GDI_RenderPresent(SDL_Renderer * renderer); -static void GDI_DestroyTexture(SDL_Renderer * renderer, - SDL_Texture * texture); -static void GDI_DestroyRenderer(SDL_Renderer * renderer); - - -SDL_RenderDriver GDI_RenderDriver = { - GDI_CreateRenderer, - { - "gdi", - (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY | - SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | - SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED), - (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_ALPHA), - (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK), - (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST), - 14, - { - SDL_PIXELFORMAT_INDEX8, - SDL_PIXELFORMAT_RGB555, - SDL_PIXELFORMAT_RGB565, - SDL_PIXELFORMAT_RGB888, - SDL_PIXELFORMAT_BGR888, - SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_RGBA8888, - SDL_PIXELFORMAT_ABGR8888, - SDL_PIXELFORMAT_BGRA8888, - SDL_PIXELFORMAT_YV12, - SDL_PIXELFORMAT_IYUV, - SDL_PIXELFORMAT_YUY2, - SDL_PIXELFORMAT_UYVY, - SDL_PIXELFORMAT_YVYU}, - 0, - 0} -}; - -typedef struct -{ - HWND hwnd; - HDC window_hdc; - HDC render_hdc; - HDC memory_hdc; - HDC current_hdc; -#ifndef NO_GETDIBBITS - LPBITMAPINFO bmi; -#endif - HBITMAP hbm[3]; - int current_hbm; - SDL_DirtyRectList dirty; - SDL_bool makedirty; -} GDI_RenderData; - -typedef struct -{ - SDL_SW_YUVTexture *yuv; - Uint32 format; - HPALETTE hpal; - HBITMAP hbm; - void *pixels; - int pitch; - SDL_bool premultiplied; -} GDI_TextureData; - -static void -UpdateYUVTextureData(SDL_Texture * texture) -{ - GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; - SDL_Rect rect; - - rect.x = 0; - rect.y = 0; - rect.w = texture->w; - rect.h = texture->h; - SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w, - texture->h, data->pixels, data->pitch); -} - -void -GDI_AddRenderDriver(_THIS) -{ - int i; - for (i = 0; i < _this->num_displays; ++i) { - SDL_AddRenderDriver(&_this->displays[i], &GDI_RenderDriver); - } -} - -SDL_Renderer * -GDI_CreateRenderer(SDL_Window * window, Uint32 flags) -{ - SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; - SDL_Renderer *renderer; - GDI_RenderData *data; - int bmi_size; - HBITMAP hbm; - int i, n; - - renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); - if (!renderer) { - SDL_OutOfMemory(); - return NULL; - } - - data = (GDI_RenderData *) SDL_calloc(1, sizeof(*data)); - if (!data) { - GDI_DestroyRenderer(renderer); - SDL_OutOfMemory(); - return NULL; - } - - windowdata->videodata->render = RENDER_GDI; - - renderer->DisplayModeChanged = GDI_DisplayModeChanged; - renderer->CreateTexture = GDI_CreateTexture; - renderer->QueryTexturePixels = GDI_QueryTexturePixels; - renderer->SetTexturePalette = GDI_SetTexturePalette; - renderer->GetTexturePalette = GDI_GetTexturePalette; - renderer->SetTextureAlphaMod = GDI_SetTextureAlphaMod; - renderer->SetTextureBlendMode = GDI_SetTextureBlendMode; - renderer->SetTextureScaleMode = GDI_SetTextureScaleMode; - renderer->UpdateTexture = GDI_UpdateTexture; - renderer->LockTexture = GDI_LockTexture; - renderer->UnlockTexture = GDI_UnlockTexture; - renderer->SetDrawBlendMode = GDI_SetDrawBlendMode; - renderer->RenderDrawPoints = GDI_RenderDrawPoints; - renderer->RenderDrawLines = GDI_RenderDrawLines; - renderer->RenderDrawRects = GDI_RenderDrawRects; - renderer->RenderFillRects = GDI_RenderFillRects; - renderer->RenderCopy = GDI_RenderCopy; - renderer->RenderReadPixels = GDI_RenderReadPixels; - renderer->RenderWritePixels = GDI_RenderWritePixels; - renderer->RenderPresent = GDI_RenderPresent; - renderer->DestroyTexture = GDI_DestroyTexture; - renderer->DestroyRenderer = GDI_DestroyRenderer; - renderer->info = GDI_RenderDriver.info; - renderer->window = window; - renderer->driverdata = data; - - renderer->info.flags = SDL_RENDERER_ACCELERATED; - - data->hwnd = windowdata->hwnd; - data->window_hdc = windowdata->hdc; - data->render_hdc = CreateCompatibleDC(data->window_hdc); - data->memory_hdc = CreateCompatibleDC(data->window_hdc); - -#ifndef NO_GETDIBBITS - /* Fill in the compatible bitmap info */ - bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); - data->bmi = (LPBITMAPINFO) SDL_calloc(1, bmi_size); - if (!data->bmi) { - GDI_DestroyRenderer(renderer); - SDL_OutOfMemory(); - return NULL; - } - data->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - - hbm = CreateCompatibleBitmap(data->window_hdc, 1, 1); - GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS); - GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS); - DeleteObject(hbm); -#endif - - if (flags & SDL_RENDERER_SINGLEBUFFER) { - renderer->info.flags |= - (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY); - n = 0; - } else if (flags & SDL_RENDERER_PRESENTFLIP2) { - renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; - n = 2; - } else if (flags & SDL_RENDERER_PRESENTFLIP3) { - renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; - n = 3; - } else { - renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; - n = 1; - } - for (i = 0; i < n; ++i) { - data->hbm[i] = - CreateCompatibleBitmap(data->window_hdc, window->w, window->h); - if (!data->hbm[i]) { - GDI_DestroyRenderer(renderer); - WIN_SetError("CreateCompatibleBitmap()"); - return NULL; - } - } - if (n > 0) { - SelectObject(data->render_hdc, data->hbm[0]); - data->current_hdc = data->render_hdc; - data->makedirty = SDL_TRUE; - } else { - data->current_hdc = data->window_hdc; - data->makedirty = SDL_FALSE; - } - data->current_hbm = 0; - -#ifdef _WIN32_WCE - // check size for GDI fullscreen and rotate - if((window->flags & SDL_WINDOW_FULLSCREEN) && - GetSystemMetrics(SM_CXSCREEN) != GetSystemMetrics(SM_CYSCREEN) && - ((GetSystemMetrics(SM_CXSCREEN) < GetSystemMetrics(SM_CYSCREEN) && window->w > window->h) || - (GetSystemMetrics(SM_CXSCREEN) > GetSystemMetrics(SM_CYSCREEN) && window->w < window->h))) - { - int orientation = WINCE_GetDMOrientation(); - switch(orientation) - { - case DMDO_0: orientation = DMDO_90; break; - case DMDO_270: orientation = DMDO_180; break; - case DMDO_90: orientation = DMDO_0; break; - case DMDO_180: orientation = DMDO_270; break; - - default: - GDI_DestroyRenderer(renderer); - return NULL; - } - - if(0 > WINCE_SetDMOrientation(orientation)) - { - GDI_DestroyRenderer(renderer); - return NULL; - } - } -#endif - - return renderer; -} - -static int -GDI_DisplayModeChanged(SDL_Renderer * renderer) -{ - GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - int i, n; - - if (renderer->info.flags & SDL_RENDERER_SINGLEBUFFER) { - n = 0; - } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) { - n = 2; - } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) { - n = 3; - } else { - n = 1; - } - for (i = 0; i < n; ++i) { - if (data->hbm[i]) { - DeleteObject(data->hbm[i]); - data->hbm[i] = NULL; - } - } - for (i = 0; i < n; ++i) { - data->hbm[i] = - CreateCompatibleBitmap(data->window_hdc, window->w, window->h); - if (!data->hbm[i]) { - WIN_SetError("CreateCompatibleBitmap()"); - return -1; - } - } - if (n > 0) { - SelectObject(data->render_hdc, data->hbm[0]); - } - data->current_hbm = 0; - - return 0; -} - -static HBITMAP -GDI_CreateDIBSection(HDC hdc, int w, int h, int pitch, Uint32 format, - HPALETTE * hpal, void ** pixels) -{ - int bmi_size; - LPBITMAPINFO bmi; - - bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); - bmi = (LPBITMAPINFO) SDL_calloc(1, bmi_size); - if (!bmi) { - SDL_OutOfMemory(); - return NULL; - } - bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi->bmiHeader.biWidth = w; - bmi->bmiHeader.biHeight = -h; /* topdown bitmap */ - bmi->bmiHeader.biPlanes = 1; - bmi->bmiHeader.biSizeImage = h * pitch; - bmi->bmiHeader.biXPelsPerMeter = 0; - bmi->bmiHeader.biYPelsPerMeter = 0; - bmi->bmiHeader.biClrUsed = 0; - bmi->bmiHeader.biClrImportant = 0; - bmi->bmiHeader.biBitCount = SDL_BYTESPERPIXEL(format) * 8; - if (SDL_ISPIXELFORMAT_INDEXED(format)) { - bmi->bmiHeader.biCompression = BI_RGB; - if (hpal) { - int i, ncolors; - LOGPALETTE *palette; - - ncolors = (1 << SDL_BITSPERPIXEL(format)); - palette = - (LOGPALETTE *) SDL_malloc(sizeof(*palette) + - ncolors * sizeof(PALETTEENTRY)); - if (!palette) { - SDL_free(bmi); - SDL_OutOfMemory(); - return NULL; - } - palette->palVersion = 0x300; - palette->palNumEntries = ncolors; - for (i = 0; i < ncolors; ++i) { - palette->palPalEntry[i].peRed = 0xFF; - palette->palPalEntry[i].peGreen = 0xFF; - palette->palPalEntry[i].peBlue = 0xFF; - palette->palPalEntry[i].peFlags = 0; - } - *hpal = CreatePalette(palette); - SDL_free(palette); - } - } else { - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - - bmi->bmiHeader.biCompression = BI_BITFIELDS; - SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, - &Amask); - ((Uint32 *) bmi->bmiColors)[0] = Rmask; - ((Uint32 *) bmi->bmiColors)[1] = Gmask; - ((Uint32 *) bmi->bmiColors)[2] = Bmask; - if (hpal) { - *hpal = NULL; - } - } - return CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, pixels, NULL, 0); -} - -static int -GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - SDL_VideoDisplay *display = window->display; - GDI_TextureData *data; - - data = (GDI_TextureData *) SDL_calloc(1, sizeof(*data)); - if (!data) { - SDL_OutOfMemory(); - return -1; - } - - texture->driverdata = data; - - if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { - data->yuv = - SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); - if (!data->yuv) { - return -1; - } - data->format = display->current_mode.format; - } else { - data->format = texture->format; - } - data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format)); - - if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING - || texture->format != display->current_mode.format) { - data->hbm = GDI_CreateDIBSection(renderdata->memory_hdc, - texture->w, texture->h, - data->pitch, data->format, - &data->hpal, &data->pixels); - } else { - data->hbm = CreateCompatibleBitmap(renderdata->window_hdc, - texture->w, texture->h); - } - if (!data->hbm) { - WIN_SetError("Couldn't create bitmap"); - return -1; - } - - return 0; -} - -static int -GDI_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, - void **pixels, int *pitch) -{ - GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; - - if (data->yuv) { - return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch); - } else { - *pixels = data->pixels; - *pitch = data->pitch; - return 0; - } -} - -static int -GDI_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Color * colors, int firstcolor, int ncolors) -{ - GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; - GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; - - if (data->yuv) { - SDL_SetError("YUV textures don't have a palette"); - return -1; - } else { - PALETTEENTRY entries[256]; - int i; - - for (i = 0; i < ncolors; ++i) { - entries[i].peRed = colors[i].r; - entries[i].peGreen = colors[i].g; - entries[i].peBlue = colors[i].b; - entries[i].peFlags = 0; - } - if (!SetPaletteEntries(data->hpal, firstcolor, ncolors, entries)) { - WIN_SetError("SetPaletteEntries()"); - return -1; - } - return 0; - } -} - -static int -GDI_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, - SDL_Color * colors, int firstcolor, int ncolors) -{ - GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; - - if (data->yuv) { - SDL_SetError("YUV textures don't have a palette"); - return -1; - } else { - PALETTEENTRY entries[256]; - int i; - - if (!GetPaletteEntries(data->hpal, firstcolor, ncolors, entries)) { - WIN_SetError("GetPaletteEntries()"); - return -1; - } - for (i = 0; i < ncolors; ++i) { - colors[i].r = entries[i].peRed; - colors[i].g = entries[i].peGreen; - colors[i].b = entries[i].peBlue; - } - return 0; - } -} - -static int -GDI_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) -{ - return 0; -} - -static int -GDI_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) -{ - GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; - - switch (texture->blendMode) { - case SDL_BLENDMODE_NONE: - if (data->premultiplied) { - /* Crap, we've lost the original pixel data... *sigh* */ - } - return 0; -#ifndef _WIN32_WCE /* WinCE has no alphablend */ - case SDL_BLENDMODE_MASK: - case SDL_BLENDMODE_BLEND: - if (!data->premultiplied && data->pixels) { - switch (texture->format) { - case SDL_PIXELFORMAT_ARGB8888: - SDL_PreMultiplyAlphaARGB8888(texture->w, texture->h, - (Uint32 *) data->pixels, - data->pitch); - data->premultiplied = SDL_TRUE; - break; - case SDL_PIXELFORMAT_RGBA8888: - SDL_PreMultiplyAlphaRGBA8888(texture->w, texture->h, - (Uint32 *) data->pixels, - data->pitch); - data->premultiplied = SDL_TRUE; - break; - case SDL_PIXELFORMAT_ABGR8888: - SDL_PreMultiplyAlphaABGR8888(texture->w, texture->h, - (Uint32 *) data->pixels, - data->pitch); - data->premultiplied = SDL_TRUE; - break; - case SDL_PIXELFORMAT_BGRA8888: - SDL_PreMultiplyAlphaBGRA8888(texture->w, texture->h, - (Uint32 *) data->pixels, - data->pitch); - data->premultiplied = SDL_TRUE; - break; - } - } - return 0; -#endif - default: - SDL_Unsupported(); - texture->blendMode = SDL_BLENDMODE_NONE; - return -1; - } -} - -static int -GDI_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) -{ - switch (texture->scaleMode) { - case SDL_SCALEMODE_NONE: - case SDL_SCALEMODE_FAST: - return 0; - case SDL_SCALEMODE_SLOW: - case SDL_SCALEMODE_BEST: - SDL_Unsupported(); - texture->scaleMode = SDL_SCALEMODE_FAST; - return -1; - default: - SDL_Unsupported(); - texture->scaleMode = SDL_SCALEMODE_NONE; - return -1; - } - return 0; -} - -static int -GDI_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, int pitch) -{ - GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; - - if (data->yuv) { - if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) { - return -1; - } - UpdateYUVTextureData(texture); - return 0; - } else { - GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; - - if (data->pixels) { - Uint8 *src, *dst; - int row; - size_t length; - - src = (Uint8 *) pixels; - dst = - (Uint8 *) data->pixels + rect->y * data->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format); - length = rect->w * SDL_BYTESPERPIXEL(texture->format); - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += pitch; - dst += data->pitch; - } - if (data->premultiplied) { - Uint32 *pixels = - (Uint32 *) data->pixels + rect->y * (data->pitch / 4) + - rect->x; - switch (texture->format) { - case SDL_PIXELFORMAT_ARGB8888: - SDL_PreMultiplyAlphaARGB8888(rect->w, rect->h, pixels, - data->pitch); - break; - case SDL_PIXELFORMAT_RGBA8888: - SDL_PreMultiplyAlphaRGBA8888(rect->w, rect->h, pixels, - data->pitch); - break; - case SDL_PIXELFORMAT_ABGR8888: - SDL_PreMultiplyAlphaABGR8888(rect->w, rect->h, pixels, - data->pitch); - break; - case SDL_PIXELFORMAT_BGRA8888: - SDL_PreMultiplyAlphaBGRA8888(rect->w, rect->h, pixels, - data->pitch); - break; - } - } - } else if (rect->w == texture->w && pitch == data->pitch) { -#ifndef NO_GETDIBBITS - if (!SetDIBits - (renderdata->window_hdc, data->hbm, rect->y, rect->h, pixels, - renderdata->bmi, DIB_RGB_COLORS)) { - WIN_SetError("SetDIBits()"); - return -1; - } -#else - SDL_SetError("FIXME: Update Texture"); - return -1; -#endif - } else { - SDL_SetError - ("FIXME: Need to allocate temporary memory and do GetDIBits() followed by SetDIBits(), since we can only set blocks of scanlines at a time"); - return -1; - } - return 0; - } -} - -static int -GDI_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, void **pixels, - int *pitch) -{ - GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; - - if (data->yuv) { - return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, - pitch); - } else if (data->pixels) { -#ifndef _WIN32_WCE - /* WinCE has no GdiFlush */ - GdiFlush(); -#endif - *pixels = - (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format)); - *pitch = data->pitch; - return 0; - } else { - SDL_SetError("No pixels available"); - return -1; - } -} - -static void -GDI_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; - - if (data->yuv) { - SDL_SW_UnlockYUVTexture(data->yuv); - UpdateYUVTextureData(texture); - } -} - -static int -GDI_SetDrawBlendMode(SDL_Renderer * renderer) -{ - switch (renderer->blendMode) { - case SDL_BLENDMODE_NONE: - return 0; - default: - SDL_Unsupported(); - renderer->blendMode = SDL_BLENDMODE_NONE; - return -1; - } -} - -static int -GDI_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, - int count) -{ - GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; - int i; - COLORREF color; - - if (data->makedirty) { - /* Get the smallest rectangle that contains everything */ - SDL_Window *window = renderer->window; - SDL_Rect rect; - - rect.x = 0; - rect.y = 0; - rect.w = window->w; - rect.h = window->h; - if (!SDL_EnclosePoints(points, count, &rect, &rect)) { - /* Nothing to draw */ - return 0; - } - - SDL_AddDirtyRect(&data->dirty, &rect); - } - - color = RGB(renderer->r, renderer->g, renderer->b); - for (i = 0; i < count; ++i) { - SetPixel(data->current_hdc, points[i].x, points[i].y, color); - } - - return 0; -} - -static int -GDI_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, - int count) -{ - GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; - HPEN pen; - BOOL status; - - if (data->makedirty) { - /* Get the smallest rectangle that contains everything */ - SDL_Window *window = renderer->window; - SDL_Rect clip, rect; - - clip.x = 0; - clip.y = 0; - clip.w = window->w; - clip.h = window->h; - SDL_EnclosePoints(points, count, NULL, &rect); - if (!SDL_IntersectRect(&rect, &clip, &rect)) { - /* Nothing to draw */ - return 0; - } - - SDL_AddDirtyRect(&data->dirty, &rect); - } - - /* Should we cache the pen? .. it looks like GDI does for us. :) */ - pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b)); - SelectObject(data->current_hdc, pen); - { - LPPOINT p = SDL_stack_alloc(POINT, count); - int i; - - for (i = 0; i < count; ++i) { - p[i].x = points[i].x; - p[i].y = points[i].y; - } - status = Polyline(data->current_hdc, p, count); - SDL_stack_free(p); - } - DeleteObject(pen); - - /* Need to close the endpoint of the line */ - if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { - SetPixel(data->current_hdc, points[count-1].x, points[count-1].y, - RGB(renderer->r, renderer->g, renderer->b)); - } - - if (!status) { - WIN_SetError("Polyline()"); - return -1; - } - return 0; -} - -static int -GDI_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, - int count) -{ - GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; - HPEN pen; - POINT vertices[5]; - int i, status = 1; - - if (data->makedirty) { - SDL_Window *window = renderer->window; - SDL_Rect clip, rect; - - clip.x = 0; - clip.y = 0; - clip.w = window->w; - clip.h = window->h; - - for (i = 0; i < count; ++i) { - if (SDL_IntersectRect(rects[i], &clip, &rect)) { - SDL_AddDirtyRect(&data->dirty, &rect); - } - } - } - - /* Should we cache the pen? .. it looks like GDI does for us. :) */ - pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b)); - SelectObject(data->current_hdc, pen); - for (i = 0; i < count; ++i) { - const SDL_Rect *rect = rects[i]; - - vertices[0].x = rect->x; - vertices[0].y = rect->y; - - vertices[1].x = rect->x+rect->w-1; - vertices[1].y = rect->y; - - vertices[2].x = rect->x+rect->w-1; - vertices[2].y = rect->y+rect->h-1; - - vertices[3].x = rect->x; - vertices[3].y = rect->y+rect->h-1; - - vertices[4].x = rect->x; - vertices[4].y = rect->y; - - status &= Polyline(data->current_hdc, vertices, 5); - } - DeleteObject(pen); - - if (!status) { - WIN_SetError("Polyline()"); - return -1; - } - return 0; -} - -static int -GDI_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, - int count) -{ - GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; - RECT rc; - HBRUSH brush; - int i, status = 1; - - if (data->makedirty) { - SDL_Window *window = renderer->window; - SDL_Rect clip, rect; - - clip.x = 0; - clip.y = 0; - clip.w = window->w; - clip.h = window->h; - - for (i = 0; i < count; ++i) { - if (SDL_IntersectRect(rects[i], &clip, &rect)) { - SDL_AddDirtyRect(&data->dirty, &rect); - } - } - } - - /* Should we cache the brushes? .. it looks like GDI does for us. :) */ - brush = CreateSolidBrush(RGB(renderer->r, renderer->g, renderer->b)); - SelectObject(data->current_hdc, brush); - for (i = 0; i < count; ++i) { - const SDL_Rect *rect = rects[i]; - - rc.left = rect->x; - rc.top = rect->y; - rc.right = rect->x + rect->w; - rc.bottom = rect->y + rect->h; - - status &= FillRect(data->current_hdc, &rc, brush); - } - DeleteObject(brush); - - if (!status) { - WIN_SetError("FillRect()"); - return -1; - } - return 0; -} - -static int -GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * dstrect) -{ - GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; - GDI_TextureData *texturedata = (GDI_TextureData *) texture->driverdata; - - if (data->makedirty) { - SDL_AddDirtyRect(&data->dirty, dstrect); - } - - SelectObject(data->memory_hdc, texturedata->hbm); - if (texturedata->hpal) { - SelectPalette(data->memory_hdc, texturedata->hpal, TRUE); - RealizePalette(data->memory_hdc); - } - if (texture->blendMode & (SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND)) { -#ifdef _WIN32_WCE - SDL_SetError("Texture has blendmode not supported under WinCE"); - return -1; -#else - BLENDFUNCTION blendFunc = { - AC_SRC_OVER, - 0, - texture->a, - AC_SRC_ALPHA - }; - if (!AlphaBlend - (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, - dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, srcrect->w, - srcrect->h, blendFunc)) { - WIN_SetError("AlphaBlend()"); - return -1; - } -#endif - } else { - if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { - if (!BitBlt - (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, - srcrect->h, data->memory_hdc, srcrect->x, srcrect->y, - SRCCOPY)) { - WIN_SetError("BitBlt()"); - return -1; - } - } else { - if (!StretchBlt - (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, - dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, - srcrect->w, srcrect->h, SRCCOPY)) { - WIN_SetError("StretchBlt()"); - return -1; - } - } - } - return 0; -} - -static int -GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, void * pixels, int pitch) -{ - GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - SDL_VideoDisplay *display = window->display; - struct { - HBITMAP hbm; - void *pixels; - int pitch; - Uint32 format; - } data; - - data.format = display->current_mode.format; - data.pitch = (rect->w * SDL_BYTESPERPIXEL(data.format)); - - data.hbm = GDI_CreateDIBSection(renderdata->memory_hdc, rect->w, rect->h, - data.pitch, data.format, NULL, - &data.pixels); - if (!data.hbm) { - WIN_SetError("Couldn't create bitmap"); - return -1; - } - - SelectObject(renderdata->memory_hdc, data.hbm); - if (!BitBlt(renderdata->memory_hdc, 0, 0, rect->w, rect->h, - renderdata->current_hdc, rect->x, rect->y, SRCCOPY)) { - WIN_SetError("BitBlt()"); - DeleteObject(data.hbm); - return -1; - } - - SDL_ConvertPixels(rect->w, rect->h, - data.format, data.pixels, data.pitch, - format, pixels, pitch); - - DeleteObject(data.hbm); - return 0; -} - -static int -GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, const void * pixels, int pitch) -{ - GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; - SDL_Window *window = renderer->window; - SDL_VideoDisplay *display = window->display; - struct { - HBITMAP hbm; - void *pixels; - int pitch; - Uint32 format; - } data; - - data.format = display->current_mode.format; - data.pitch = (rect->w * SDL_BYTESPERPIXEL(data.format)); - - data.hbm = GDI_CreateDIBSection(renderdata->memory_hdc, rect->w, rect->h, - data.pitch, data.format, - NULL, &data.pixels); - if (!data.hbm) { - WIN_SetError("Couldn't create bitmap"); - return -1; - } - - SDL_ConvertPixels(rect->w, rect->h, format, pixels, pitch, - data.format, data.pixels, data.pitch); - - SelectObject(renderdata->memory_hdc, data.hbm); - if (!BitBlt(renderdata->current_hdc, rect->x, rect->y, rect->w, rect->h, - renderdata->memory_hdc, 0, 0, SRCCOPY)) { - WIN_SetError("BitBlt()"); - DeleteObject(data.hbm); - return -1; - } - - DeleteObject(data.hbm); - return 0; -} - -static void -GDI_RenderPresent(SDL_Renderer * renderer) -{ - GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; - SDL_DirtyRect *dirty; - - /* Send the data to the display */ - if (!(renderer->info.flags & SDL_RENDERER_SINGLEBUFFER)) { - for (dirty = data->dirty.list; dirty; dirty = dirty->next) { - const SDL_Rect *rect = &dirty->rect; - BitBlt(data->window_hdc, rect->x, rect->y, rect->w, rect->h, - data->render_hdc, rect->x, rect->y, SRCCOPY); - } - SDL_ClearDirtyRects(&data->dirty); - } - - /* Update the flipping chain, if any */ - if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) { - data->current_hbm = (data->current_hbm + 1) % 2; - SelectObject(data->render_hdc, data->hbm[data->current_hbm]); - } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) { - data->current_hbm = (data->current_hbm + 1) % 3; - SelectObject(data->render_hdc, data->hbm[data->current_hbm]); - } -} - -static void -GDI_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; - - if (!data) { - return; - } - if (data->yuv) { - SDL_SW_DestroyYUVTexture(data->yuv); - } - if (data->hpal) { - DeleteObject(data->hpal); - } - if (data->hbm) { - DeleteObject(data->hbm); - } - SDL_free(data); - texture->driverdata = NULL; -} - -static void -GDI_DestroyRenderer(SDL_Renderer * renderer) -{ - GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; - int i; - - if (data) { - DeleteDC(data->render_hdc); - DeleteDC(data->memory_hdc); -#ifndef NO_GETDIBBITS - if (data->bmi) { - SDL_free(data->bmi); - } -#endif - for (i = 0; i < SDL_arraysize(data->hbm); ++i) { - if (data->hbm[i]) { - DeleteObject(data->hbm[i]); - } - } - SDL_FreeDirtyRects(&data->dirty); - SDL_free(data); - } - SDL_free(renderer); -} - -#endif /* SDL_VIDEO_RENDER_GDI */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_gdirender.h --- a/src/video/win32/SDL_gdirender.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -/* SDL surface based renderer implementation */ - -#if SDL_VIDEO_RENDER_GDI -extern void GDI_AddRenderDriver(_THIS); -#endif - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_msctf.h --- a/src/video/win32/SDL_msctf.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,221 +0,0 @@ -#ifndef _SDL_msctf_h -#define _SDL_msctf_h - -#include - -#define TF_INVALID_COOKIE (0xffffffff) -#define TF_IPSINK_FLAG_ACTIVE 0x0001 -#define TF_TMAE_UIELEMENTENABLEDONLY 0x00000004 - -typedef struct ITfThreadMgr ITfThreadMgr; -typedef struct ITfDocumentMgr ITfDocumentMgr; -typedef struct ITfClientId ITfClientId; - -typedef struct IEnumTfDocumentMgrs IEnumTfDocumentMgrs; -typedef struct IEnumTfFunctionProviders IEnumTfFunctionProviders; -typedef struct ITfFunctionProvider ITfFunctionProvider; -typedef struct ITfCompartmentMgr ITfCompartmentMgr; -typedef struct ITfContext ITfContext; -typedef struct IEnumTfContexts IEnumTfContexts; -typedef struct ITfUIElementSink ITfUIElementSink; -typedef struct ITfUIElement ITfUIElement; -typedef struct ITfUIElementMgr ITfUIElementMgr; -typedef struct IEnumTfUIElements IEnumTfUIElements; -typedef struct ITfThreadMgrEx ITfThreadMgrEx; -typedef struct ITfCandidateListUIElement ITfCandidateListUIElement; -typedef struct ITfReadingInformationUIElement ITfReadingInformationUIElement; -typedef struct ITfInputProcessorProfileActivationSink ITfInputProcessorProfileActivationSink; -typedef struct ITfSource ITfSource; - -typedef DWORD TfClientId; -typedef DWORD TfEditCookie; - -typedef struct ITfThreadMgrVtbl -{ - HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfThreadMgr *, REFIID, void **); - ULONG (STDMETHODCALLTYPE *AddRef)(ITfThreadMgr *); - ULONG (STDMETHODCALLTYPE *Release)(ITfThreadMgr *); - HRESULT (STDMETHODCALLTYPE *Activate)(ITfThreadMgr *, TfClientId *); - HRESULT (STDMETHODCALLTYPE *Deactivate)(ITfThreadMgr *); - HRESULT (STDMETHODCALLTYPE *CreateDocumentMgr)(ITfThreadMgr *); - HRESULT (STDMETHODCALLTYPE *EnumDocumentMgrs)(ITfThreadMgr *, IEnumTfDocumentMgrs **); - HRESULT (STDMETHODCALLTYPE *GetFocus)(ITfThreadMgr *, ITfDocumentMgr **); - HRESULT (STDMETHODCALLTYPE *SetFocus)(ITfThreadMgr *, ITfDocumentMgr *); - HRESULT (STDMETHODCALLTYPE *AssociateFocus)(ITfThreadMgr *, HWND, ITfDocumentMgr *, ITfDocumentMgr **); - HRESULT (STDMETHODCALLTYPE *IsThreadFocus)(ITfThreadMgr *, BOOL *); - HRESULT (STDMETHODCALLTYPE *GetFunctionProvider)(ITfThreadMgr *, REFCLSID, ITfFunctionProvider **); - HRESULT (STDMETHODCALLTYPE *EnumFunctionProviders)(ITfThreadMgr *, IEnumTfFunctionProviders **); - HRESULT (STDMETHODCALLTYPE *GetGlobalCompartment)(ITfThreadMgr *, ITfCompartmentMgr **); -} ITfThreadMgrVtbl; - -struct ITfThreadMgr -{ - const struct ITfThreadMgrVtbl *lpVtbl; -}; - -typedef struct ITfThreadMgrExVtbl -{ - HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfThreadMgrEx *, REFIID, void **); - ULONG (STDMETHODCALLTYPE *AddRef)(ITfThreadMgrEx *); - ULONG (STDMETHODCALLTYPE *Release)(ITfThreadMgrEx *); - HRESULT (STDMETHODCALLTYPE *Activate)(ITfThreadMgrEx *, TfClientId *); - HRESULT (STDMETHODCALLTYPE *Deactivate)(ITfThreadMgrEx *); - HRESULT (STDMETHODCALLTYPE *CreateDocumentMgr)(ITfThreadMgrEx *, ITfDocumentMgr **); - HRESULT (STDMETHODCALLTYPE *EnumDocumentMgrs)(ITfThreadMgrEx *, IEnumTfDocumentMgrs **); - HRESULT (STDMETHODCALLTYPE *GetFocus)(ITfThreadMgrEx *, ITfDocumentMgr **); - HRESULT (STDMETHODCALLTYPE *SetFocus)(ITfThreadMgrEx *, ITfDocumentMgr *); - HRESULT (STDMETHODCALLTYPE *AssociateFocus)(ITfThreadMgrEx *, ITfDocumentMgr *, ITfDocumentMgr **); - HRESULT (STDMETHODCALLTYPE *IsThreadFocus)(ITfThreadMgrEx *, BOOL *); - HRESULT (STDMETHODCALLTYPE *GetFunctionProvider)(ITfThreadMgrEx *, REFCLSID, ITfFunctionProvider **); - HRESULT (STDMETHODCALLTYPE *EnumFunctionProviders)(ITfThreadMgrEx *, IEnumTfFunctionProviders **); - HRESULT (STDMETHODCALLTYPE *GetGlobalCompartment)(ITfThreadMgrEx *, ITfCompartmentMgr **); - HRESULT (STDMETHODCALLTYPE *ActivateEx)(ITfThreadMgrEx *, TfClientId *, DWORD); - HRESULT (STDMETHODCALLTYPE *GetActiveFlags)(ITfThreadMgrEx *, DWORD *); -} ITfThreadMgrExVtbl; - -struct ITfThreadMgrEx -{ - const struct ITfThreadMgrExVtbl *lpVtbl; -}; - -typedef struct ITfDocumentMgrVtbl -{ - HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfDocumentMgr *, REFIID, void **); - ULONG (STDMETHODCALLTYPE *AddRef)(ITfDocumentMgr *); - ULONG (STDMETHODCALLTYPE *Release)(ITfDocumentMgr *); - HRESULT (STDMETHODCALLTYPE *CreateContext)(ITfDocumentMgr *, TfClientId, DWORD, IUnknown *, ITfContext **, TfEditCookie *); - HRESULT (STDMETHODCALLTYPE *Push)(ITfDocumentMgr *, ITfContext *); - HRESULT (STDMETHODCALLTYPE *Pop)(ITfDocumentMgr *); - HRESULT (STDMETHODCALLTYPE *GetTop)(ITfDocumentMgr *, ITfContext **); - HRESULT (STDMETHODCALLTYPE *GetBase)(ITfDocumentMgr *, ITfContext **); - HRESULT (STDMETHODCALLTYPE *EnumContexts)(ITfDocumentMgr *, IEnumTfContexts **); -} ITfDocumentMgrVtbl; - -struct ITfDocumentMgr -{ - const struct ITfDocumentMgrVtbl *lpVtbl; -}; - -typedef struct ITfUIElementSinkVtbl -{ - HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElementSink *, REFIID, void **); - ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElementSink *); - ULONG (STDMETHODCALLTYPE *Release)(ITfUIElementSink *); - HRESULT (STDMETHODCALLTYPE *BeginUIElement)(ITfUIElementSink *, DWORD, BOOL *); - HRESULT (STDMETHODCALLTYPE *UpdateUIElement)(ITfUIElementSink *, DWORD); - HRESULT (STDMETHODCALLTYPE *EndUIElement)(ITfUIElementSink *, DWORD); -} ITfUIElementSinkVtbl; - -struct ITfUIElementSink -{ - const struct ITfUIElementSinkVtbl *lpVtbl; -}; - -typedef struct ITfUIElementMgrVtbl -{ - HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElementMgr *, REFIID, void **); - ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElementMgr *); - ULONG (STDMETHODCALLTYPE *Release)(ITfUIElementMgr *); - HRESULT (STDMETHODCALLTYPE *BeginUIElement)(ITfUIElementMgr *, ITfUIElement *, BOOL *, DWORD *); - HRESULT (STDMETHODCALLTYPE *UpdateUIElement)(ITfUIElementMgr *, DWORD); - HRESULT (STDMETHODCALLTYPE *EndUIElement)(ITfUIElementMgr *, DWORD); - HRESULT (STDMETHODCALLTYPE *GetUIElement)(ITfUIElementMgr *, DWORD, ITfUIElement **); - HRESULT (STDMETHODCALLTYPE *EnumUIElements)(ITfUIElementMgr *, IEnumTfUIElements **); -} ITfUIElementMgrVtbl; - -struct ITfUIElementMgr -{ - const struct ITfUIElementMgrVtbl *lpVtbl; -}; - -typedef struct ITfCandidateListUIElementVtbl -{ - HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfCandidateListUIElement *, REFIID, void **); - ULONG (STDMETHODCALLTYPE *AddRef)(ITfCandidateListUIElement *); - ULONG (STDMETHODCALLTYPE *Release)(ITfCandidateListUIElement *); - HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfCandidateListUIElement *, BSTR *); - HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfCandidateListUIElement *, GUID *); - HRESULT (STDMETHODCALLTYPE *Show)(ITfCandidateListUIElement *, BOOL); - HRESULT (STDMETHODCALLTYPE *IsShown)(ITfCandidateListUIElement *, BOOL *); - HRESULT (STDMETHODCALLTYPE *GetUpdatedFlags)(ITfCandidateListUIElement *, DWORD *); - HRESULT (STDMETHODCALLTYPE *GetDocumentMgr)(ITfCandidateListUIElement *, ITfDocumentMgr **); - HRESULT (STDMETHODCALLTYPE *GetCount)(ITfCandidateListUIElement *, UINT *); - HRESULT (STDMETHODCALLTYPE *GetSelection)(ITfCandidateListUIElement *, UINT *); - HRESULT (STDMETHODCALLTYPE *GetString)(ITfCandidateListUIElement *, UINT, BSTR *); - HRESULT (STDMETHODCALLTYPE *GetPageIndex)(ITfCandidateListUIElement *, UINT *, UINT, UINT *); - HRESULT (STDMETHODCALLTYPE *SetPageIndex)(ITfCandidateListUIElement *, UINT *, UINT); - HRESULT (STDMETHODCALLTYPE *GetCurrentPage)(ITfCandidateListUIElement *, UINT *); -} ITfCandidateListUIElementVtbl; - -struct ITfCandidateListUIElement -{ - const struct ITfCandidateListUIElementVtbl *lpVtbl; -}; - -typedef struct ITfReadingInformationUIElementVtbl -{ - HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfReadingInformationUIElement *, REFIID, void **); - ULONG (STDMETHODCALLTYPE *AddRef)(ITfReadingInformationUIElement *); - ULONG (STDMETHODCALLTYPE *Release)(ITfReadingInformationUIElement *); - HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfReadingInformationUIElement *, BSTR *); - HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfReadingInformationUIElement *, GUID *); - HRESULT (STDMETHODCALLTYPE *Show)(ITfReadingInformationUIElement *, BOOL); - HRESULT (STDMETHODCALLTYPE *IsShown)(ITfReadingInformationUIElement *, BOOL *); - HRESULT (STDMETHODCALLTYPE *GetUpdatedFlags)(ITfReadingInformationUIElement *, DWORD *); - HRESULT (STDMETHODCALLTYPE *GetContext)(ITfReadingInformationUIElement *, ITfContext **); - HRESULT (STDMETHODCALLTYPE *GetString)(ITfReadingInformationUIElement *, BSTR *); - HRESULT (STDMETHODCALLTYPE *GetMaxReadingStringLength)(ITfReadingInformationUIElement *, UINT *); - HRESULT (STDMETHODCALLTYPE *GetErrorIndex)(ITfReadingInformationUIElement *, UINT *); - HRESULT (STDMETHODCALLTYPE *IsVerticalOrderPreferred)(ITfReadingInformationUIElement *, BOOL *); -} ITfReadingInformationUIElementVtbl; - -struct ITfReadingInformationUIElement -{ - const struct ITfReadingInformationUIElementVtbl *lpVtbl; -}; - -typedef struct ITfUIElementVtbl -{ - HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElement *, REFIID, void **); - ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElement *); - ULONG (STDMETHODCALLTYPE *Release)(ITfUIElement *); - HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfUIElement *, BSTR *); - HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfUIElement *, GUID *); - HRESULT (STDMETHODCALLTYPE *Show)(ITfUIElement *, BOOL); - HRESULT (STDMETHODCALLTYPE *IsShown)(ITfUIElement *, BOOL *); -} ITfUIElementVtbl; - -struct ITfUIElement -{ - const struct ITfUIElementVtbl *lpVtbl; -}; - -typedef struct ITfInputProcessorProfileActivationSinkVtbl -{ - HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfInputProcessorProfileActivationSink *, REFIID, void **); - ULONG (STDMETHODCALLTYPE *AddRef)(ITfInputProcessorProfileActivationSink *); - ULONG (STDMETHODCALLTYPE *Release)(ITfInputProcessorProfileActivationSink *); - HRESULT (STDMETHODCALLTYPE *OnActivated)(ITfInputProcessorProfileActivationSink *, DWORD, LANGID, REFCLSID, REFGUID, REFGUID, HKL, DWORD); - -} ITfInputProcessorProfileActivationSinkVtbl; - -struct ITfInputProcessorProfileActivationSink -{ - const struct ITfInputProcessorProfileActivationSinkVtbl *lpVtbl; -}; - -typedef struct ITfSourceVtbl -{ - HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfSource *, REFIID, void **); - ULONG (STDMETHODCALLTYPE *AddRef)(ITfSource *); - ULONG (STDMETHODCALLTYPE *Release)(ITfSource *); - HRESULT (STDMETHODCALLTYPE *AdviseSink)(ITfSource *, REFIID, IUnknown *, DWORD *); - HRESULT (STDMETHODCALLTYPE *UnadviseSink)(ITfSource *, DWORD); -} ITfSourceVtbl; - -struct ITfSource -{ - const struct ITfSourceVtbl *lpVtbl; -}; - -#endif /* _SDL_msctf_h */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_vkeys.h --- a/src/video/win32/SDL_vkeys.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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 -#define VK_OEM_102 0xE2 - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32clipboard.c --- a/src/video/win32/SDL_win32clipboard.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#include "SDL_win32video.h" -#include "SDL_win32window.h" -#include "../../events/SDL_clipboardevents_c.h" - - -#ifdef UNICODE -#define TEXT_FORMAT CF_UNICODETEXT -#else -#define TEXT_FORMAT CF_TEXT -#endif - - -/* Get any application owned window handle for clipboard association */ -static HWND -GetWindowHandle(_THIS) -{ - SDL_VideoDisplay *display; - SDL_Window *window; - - display = _this->displays; - if (display) { - window = display->windows; - if (window) { - return ((SDL_WindowData *) window->driverdata)->hwnd; - } - } - return NULL; -} - -int -WIN_SetClipboardText(_THIS, const char *text) -{ - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - int result = 0; - - if (OpenClipboard(GetWindowHandle(_this))) { - HANDLE hMem; - LPTSTR tstr; - SIZE_T i, size; - - /* Convert the text from UTF-8 to Windows Unicode */ - tstr = WIN_UTF8ToString(text); - if (!tstr) { - return -1; - } - - /* Find out the size of the data */ - for (size = 0, i = 0; tstr[i]; ++i, ++size) { - if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) { - /* We're going to insert a carriage return */ - ++size; - } - } - size = (size+1)*sizeof(*tstr); - - /* Save the data to the clipboard */ - hMem = GlobalAlloc(GMEM_MOVEABLE, size); - if (hMem) { - LPTSTR dst = (LPTSTR)GlobalLock(hMem); - /* Copy the text over, adding carriage returns as necessary */ - for (i = 0; tstr[i]; ++i) { - if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) { - *dst++ = '\r'; - } - *dst++ = tstr[i]; - } - *dst = 0; - GlobalUnlock(hMem); - - EmptyClipboard(); - if (!SetClipboardData(TEXT_FORMAT, hMem)) { - WIN_SetError("Couldn't set clipboard data"); - result = -1; - } -#ifdef _WIN32_WCE - data->clipboard_count = 0; -#else - data->clipboard_count = GetClipboardSequenceNumber(); -#endif - } - SDL_free(tstr); - - CloseClipboard(); - } else { - WIN_SetError("Couldn't open clipboard"); - result = -1; - } - return result; -} - -char * -WIN_GetClipboardText(_THIS) -{ - char *text; - - text = NULL; - if (IsClipboardFormatAvailable(TEXT_FORMAT) && - OpenClipboard(GetWindowHandle(_this))) { - HANDLE hMem; - LPTSTR tstr; - - hMem = GetClipboardData(TEXT_FORMAT); - if (hMem) { - tstr = (LPTSTR)GlobalLock(hMem); - text = WIN_StringToUTF8(tstr); - GlobalUnlock(hMem); - } else { - WIN_SetError("Couldn't get clipboard data"); - } - CloseClipboard(); - } - if (!text) { - text = SDL_strdup(""); - } - return text; -} - -SDL_bool -WIN_HasClipboardText(_THIS) -{ - if (IsClipboardFormatAvailable(TEXT_FORMAT)) { - return SDL_TRUE; - } else { - return SDL_FALSE; - } -} - -void -WIN_CheckClipboardUpdate(struct SDL_VideoData * data) -{ - DWORD count; - -#ifdef _WIN32_WCE - count = 0; -#else - count = GetClipboardSequenceNumber(); -#endif - if (count != data->clipboard_count) { - if (data->clipboard_count) { - SDL_SendClipboardUpdate(); - } - data->clipboard_count = count; - } -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32clipboard.h --- a/src/video/win32/SDL_win32clipboard.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_win32clipboard_h -#define _SDL_win32clipboard_h - -/* Forward declaration */ -struct SDL_VideoData; - -extern int WIN_SetClipboardText(_THIS, const char *text); -extern char *WIN_GetClipboardText(_THIS); -extern SDL_bool WIN_HasClipboardText(_THIS); -extern void WIN_CheckClipboardUpdate(struct SDL_VideoData * data); - -#endif /* _SDL_win32clipboard_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32events.c --- a/src/video/win32/SDL_win32events.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,712 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#include "SDL_win32video.h" -#include "SDL_win32shape.h" -#include "SDL_syswm.h" -#include "SDL_vkeys.h" -#include "../../events/SDL_events_c.h" -#include "../../events/SDL_touch_c.h" - - - -/*#define WMMSG_DEBUG*/ -#ifdef WMMSG_DEBUG -#include -#include "wmmsg.h" -#endif - -/* Masks for processing the windows KEYDOWN and KEYUP messages */ -#define REPEATED_KEYMASK (1<<30) -#define EXTENDED_KEYMASK (1<<24) - -#define VK_ENTER 10 /* Keypad Enter ... no VKEY defined? */ - -/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */ -#ifndef WM_XBUTTONDOWN -#define WM_XBUTTONDOWN 0x020B -#endif -#ifndef WM_XBUTTONUP -#define WM_XBUTTONUP 0x020C -#endif -#ifndef GET_XBUTTON_WPARAM -#define GET_XBUTTON_WPARAM(w) (HIWORD(w)) -#endif -#ifndef WM_INPUT -#define WM_INPUT 0x00ff -#endif -#ifndef WM_TOUCH -#define WM_TOUCH 0x0240 -#endif - - -static WPARAM -RemapVKEY(WPARAM wParam, LPARAM lParam) -{ - int i; - BYTE scancode = (BYTE) ((lParam >> 16) & 0xFF); - - /* Windows remaps alphabetic keys based on current layout. - We try to provide USB scancodes, so undo this mapping. - */ - if (wParam >= 'A' && wParam <= 'Z') { - if (scancode != alpha_scancodes[wParam - 'A']) { - for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) { - if (scancode == alpha_scancodes[i]) { - wParam = 'A' + i; - break; - } - } - } - } - - /* Keypad keys are a little trickier, we always scan for them. - Keypad arrow keys have the same scancode as normal arrow keys, - except they don't have the extended bit (0x1000000) set. - */ - if (!(lParam & 0x1000000)) { - if (wParam == VK_DELETE) { - wParam = VK_DECIMAL; - } else { - for (i = 0; i < SDL_arraysize(keypad_scancodes); ++i) { - if (scancode == keypad_scancodes[i]) { - wParam = VK_NUMPAD0 + i; - break; - } - } - } - } - - return wParam; -} - -LRESULT CALLBACK -WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - SDL_WindowData *data; - LRESULT returnCode = -1; - - /* Send a SDL_SYSWMEVENT if the application wants them */ - if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { - SDL_SysWMmsg wmmsg; - - SDL_VERSION(&wmmsg.version); - wmmsg.subsystem = SDL_SYSWM_WINDOWS; - wmmsg.msg.win.hwnd = hwnd; - wmmsg.msg.win.msg = msg; - wmmsg.msg.win.wParam = wParam; - wmmsg.msg.win.lParam = lParam; - SDL_SendSysWMEvent(&wmmsg); - } - - /* Get the window data for the window */ - data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData")); - if (!data) { - return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); - } - -#ifdef WMMSG_DEBUG - { - FILE *log = fopen("wmmsg.txt", "a"); - fprintf(log, "Received windows message: %p ", hwnd); - if (msg > MAX_WMMSG) { - fprintf(log, "%d", msg); - } else { - fprintf(log, "%s", wmtab[msg]); - } - fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam); - fclose(log); - } -#endif - - if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata)) - return 0; - - switch (msg) { - - case WM_SHOWWINDOW: - { - if (wParam) { - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); - } else { - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); - } - } - break; - - case WM_ACTIVATE: - { - BOOL minimized; - - minimized = HIWORD(wParam); - if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) { - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); - SDL_SendWindowEvent(data->window, - SDL_WINDOWEVENT_RESTORED, 0, 0); -#ifndef _WIN32_WCE /* WinCE misses IsZoomed() */ - if (IsZoomed(hwnd)) { - SDL_SendWindowEvent(data->window, - SDL_WINDOWEVENT_MAXIMIZED, 0, 0); - } -#endif - if (SDL_GetKeyboardFocus() != data->window) { - SDL_SetKeyboardFocus(data->window); - } - /* - * FIXME: Update keyboard state - */ - WIN_CheckClipboardUpdate(data->videodata); - } else { - if (SDL_GetKeyboardFocus() == data->window) { - SDL_SetKeyboardFocus(NULL); - } - if (minimized) { - SDL_SendWindowEvent(data->window, - SDL_WINDOWEVENT_MINIMIZED, 0, 0); - } - } - } - returnCode = 0; - break; - - case WM_MOUSEMOVE: -#ifdef _WIN32_WCE - /* transform coords for VGA, WVGA... */ - { - SDL_VideoData *videodata = data->videodata; - if(videodata->CoordTransform && - (videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW)) - { - POINT pt; - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); - videodata->CoordTransform(data->window, &pt); - SDL_SendMouseMotion(data->window, 0, pt.x, pt.y); - break; - } - } -#endif - SDL_SendMouseMotion(data->window, 0, LOWORD(lParam), HIWORD(lParam)); - break; - - case WM_LBUTTONDOWN: - SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_LEFT); - break; - - case WM_LBUTTONUP: - SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_LEFT); - break; - - case WM_RBUTTONDOWN: - SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_RIGHT); - break; - - case WM_RBUTTONUP: - SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_RIGHT); - break; - - case WM_MBUTTONDOWN: - SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_MIDDLE); - break; - - case WM_MBUTTONUP: - SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_MIDDLE); - break; - - case WM_XBUTTONDOWN: - SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_X1 + GET_XBUTTON_WPARAM(wParam) - 1); - returnCode = TRUE; - break; - - case WM_XBUTTONUP: - SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_X1 + GET_XBUTTON_WPARAM(wParam) - 1); - returnCode = TRUE; - break; - - case WM_MOUSEWHEEL: - { - int motion = (short) HIWORD(wParam); - - SDL_SendMouseWheel(data->window, 0, motion); - break; - } - - case WM_MOUSELEAVE: - if (SDL_GetMouseFocus() == data->window) { - SDL_SetMouseFocus(NULL); - } - returnCode = 0; - break; - - case WM_SYSKEYDOWN: - case WM_KEYDOWN: - { - wParam = RemapVKEY(wParam, lParam); - switch (wParam) { - case VK_CONTROL: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_RCONTROL; - else - wParam = VK_LCONTROL; - break; - case VK_SHIFT: - /* EXTENDED trick doesn't work here */ - { - Uint8 *state = SDL_GetKeyboardState(NULL); - if (state[SDL_SCANCODE_LSHIFT] == SDL_RELEASED - && (GetKeyState(VK_LSHIFT) & 0x8000)) { - wParam = VK_LSHIFT; - } else if (state[SDL_SCANCODE_RSHIFT] == SDL_RELEASED - && (GetKeyState(VK_RSHIFT) & 0x8000)) { - wParam = VK_RSHIFT; - } else { - /* Probably a key repeat */ - wParam = 256; - } - } - break; - case VK_MENU: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_RMENU; - else - wParam = VK_LMENU; - break; - case VK_RETURN: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_ENTER; - break; - } - if (wParam < 256) { - SDL_SendKeyboardKey(SDL_PRESSED, - data->videodata->key_layout[wParam]); - } - } - returnCode = 0; - break; - - case WM_SYSKEYUP: - case WM_KEYUP: - { - wParam = RemapVKEY(wParam, lParam); - switch (wParam) { - case VK_CONTROL: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_RCONTROL; - else - wParam = VK_LCONTROL; - break; - case VK_SHIFT: - /* EXTENDED trick doesn't work here */ - { - Uint8 *state = SDL_GetKeyboardState(NULL); - if (state[SDL_SCANCODE_LSHIFT] == SDL_PRESSED - && !(GetKeyState(VK_LSHIFT) & 0x8000)) { - wParam = VK_LSHIFT; - } else if (state[SDL_SCANCODE_RSHIFT] == SDL_PRESSED - && !(GetKeyState(VK_RSHIFT) & 0x8000)) { - wParam = VK_RSHIFT; - } else { - /* Probably a key repeat */ - wParam = 256; - } - } - break; - case VK_MENU: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_RMENU; - else - wParam = VK_LMENU; - break; - case VK_RETURN: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_ENTER; - break; - } - - /* Windows only reports keyup for print screen */ - if (wParam == VK_SNAPSHOT - && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] == - SDL_RELEASED) { - SDL_SendKeyboardKey(SDL_PRESSED, - data->videodata->key_layout[wParam]); - } - if (wParam < 256) { - SDL_SendKeyboardKey(SDL_RELEASED, - data->videodata->key_layout[wParam]); - } - } - returnCode = 0; - break; - - case WM_CHAR: - { - char text[4]; - - /* Convert to UTF-8 and send it on... */ - if (wParam <= 0x7F) { - text[0] = (char) wParam; - text[1] = '\0'; - } else if (wParam <= 0x7FF) { - text[0] = 0xC0 | (char) ((wParam >> 6) & 0x1F); - text[1] = 0x80 | (char) (wParam & 0x3F); - text[2] = '\0'; - } else { - text[0] = 0xE0 | (char) ((wParam >> 12) & 0x0F); - text[1] = 0x80 | (char) ((wParam >> 6) & 0x3F); - text[2] = 0x80 | (char) (wParam & 0x3F); - text[3] = '\0'; - } - SDL_SendKeyboardText(text); - } - returnCode = 0; - break; - - case WM_INPUTLANGCHANGE: - { - WIN_UpdateKeymap(); - } - returnCode = 1; - break; - - case WM_GETMINMAXINFO: - { - MINMAXINFO *info; - RECT size; - int x, y; - int w, h; - int style; - BOOL menu; - - /* If we allow resizing, let the resize happen naturally */ - if(SDL_IsShapedWindow(data->window)) - Win32_ResizeWindowShape(data->window); - if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) { - returnCode = 0; - break; - } - - /* Get the current position of our window */ - GetWindowRect(hwnd, &size); - x = size.left; - y = size.top; - - /* Calculate current size of our window */ - SDL_GetWindowSize(data->window, &w, &h); - size.top = 0; - size.left = 0; - size.bottom = h; - size.right = w; - - - style = GetWindowLong(hwnd, GWL_STYLE); -#ifdef _WIN32_WCE - menu = FALSE; -#else - /* DJM - according to the docs for GetMenu(), the - return value is undefined if hwnd is a child window. - Aparently it's too difficult for MS to check - inside their function, so I have to do it here. - */ - menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); -#endif - AdjustWindowRectEx(&size, style, menu, 0); - w = size.right - size.left; - h = size.bottom - size.top; - - /* Fix our size to the current size */ - info = (MINMAXINFO *) lParam; - info->ptMaxSize.x = w; - info->ptMaxSize.y = h; - info->ptMaxPosition.x = x; - info->ptMaxPosition.y = y; - info->ptMinTrackSize.x = w; - info->ptMinTrackSize.y = h; - info->ptMaxTrackSize.x = w; - info->ptMaxTrackSize.y = h; - } - returnCode = 0; - break; - - case WM_WINDOWPOSCHANGED: - { - RECT rect; - int x, y; - int w, h; - Uint32 window_flags; - - if (!GetClientRect(hwnd, &rect) || - (rect.right == rect.left && rect.bottom == rect.top)) { - break; - } - ClientToScreen(hwnd, (LPPOINT) & rect); - ClientToScreen(hwnd, (LPPOINT) & rect + 1); - - window_flags = SDL_GetWindowFlags(data->window); - if ((window_flags & SDL_WINDOW_INPUT_GRABBED) && - (window_flags & SDL_WINDOW_INPUT_FOCUS)) { - ClipCursor(&rect); - } - - x = rect.left; - y = rect.top; - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y); - - w = rect.right - rect.left; - h = rect.bottom - rect.top; - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w, - h); - } - break; - - case WM_SETCURSOR: - { - Uint16 hittest; - - hittest = LOWORD(lParam); - if (hittest == HTCLIENT) { - /* FIXME: Implement the cursor API */ - static HCURSOR cursor; - if (!cursor) { - cursor = LoadCursor(NULL, IDC_ARROW); - } - SetCursor(cursor); - returnCode = TRUE; - } - } - break; - - /* We are about to get palette focus! */ - case WM_QUERYNEWPALETTE: - { - /* - WIN_RealizePalette(current_video); - returnCode = TRUE; - */ - } - break; - - /* Another application changed the palette */ - case WM_PALETTECHANGED: - { - /* - WIN_PaletteChanged(current_video, (HWND) wParam); - */ - } - break; - - /* We were occluded, refresh our display */ - case WM_PAINT: - { - RECT rect; - if (GetUpdateRect(hwnd, &rect, FALSE)) { - ValidateRect(hwnd, &rect); - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, - 0, 0); - } - } - returnCode = 0; - break; - - /* We'll do our own drawing, prevent flicker */ - case WM_ERASEBKGND: - { - } - return (1); - - case WM_SYSCOMMAND: - { - /* Don't start the screensaver or blank the monitor in fullscreen apps */ - if ((wParam & 0xFFF0) == SC_SCREENSAVE || - (wParam & 0xFFF0) == SC_MONITORPOWER) { - if (SDL_GetVideoDevice()->suspend_screensaver) { - return (0); - } - } - } - break; - - case WM_CLOSE: - { - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); - } - returnCode = 0; - break; - - case WM_TOUCH: - { - UINT i, num_inputs = LOWORD(wParam); - PTOUCHINPUT inputs = SDL_stack_alloc(TOUCHINPUT, num_inputs); - if (data->videodata->GetTouchInputInfo((HTOUCHINPUT)lParam, num_inputs, inputs, sizeof(TOUCHINPUT))) { - RECT rect; - float x, y; - - if (!GetClientRect(hwnd, &rect) || - (rect.right == rect.left && rect.bottom == rect.top)) { - break; - } - ClientToScreen(hwnd, (LPPOINT) & rect); - ClientToScreen(hwnd, (LPPOINT) & rect + 1); - rect.top *= 100; - rect.left *= 100; - rect.bottom *= 100; - rect.right *= 100; - - for (i = 0; i < num_inputs; ++i) { - PTOUCHINPUT input = &inputs[i]; - - SDL_TouchID touchId = (SDL_TouchID)input->hSource; - if (!SDL_GetTouch(touchId)) { - SDL_Touch touch; - - touch.id = touchId; - touch.x_min = 0; - touch.x_max = 1; - touch.native_xres = touch.x_max - touch.x_min; - touch.y_min = 0; - touch.y_max = 1; - touch.native_yres = touch.y_max - touch.y_min; - touch.pressure_min = 0; - touch.pressure_max = 1; - touch.native_pressureres = touch.pressure_max - touch.pressure_min; - - if (SDL_AddTouch(&touch, "") < 0) { - continue; - } - } - - // Get the normalized coordinates for the window - x = (float)(input->x - rect.left)/(rect.right - rect.left); - y = (float)(input->y - rect.top)/(rect.bottom - rect.top); - - if (input->dwFlags & TOUCHEVENTF_DOWN) { - SDL_SendFingerDown(touchId, input->dwID, SDL_TRUE, x, y, 1); - } - if (input->dwFlags & TOUCHEVENTF_MOVE) { - SDL_SendTouchMotion(touchId, input->dwID, SDL_FALSE, x, y, 1); - } - if (input->dwFlags & TOUCHEVENTF_UP) { - SDL_SendFingerDown(touchId, input->dwID, SDL_FALSE, x, y, 1); - } - } - } - SDL_stack_free(inputs); - - data->videodata->CloseTouchInputHandle((HTOUCHINPUT)lParam); - return 0; - } - break; - } - - /* If there's a window proc, assume it's going to handle messages */ - if (data->wndproc) { - return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam); - } else if (returnCode >= 0) { - return returnCode; - } else { - return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); - } -} - -void -WIN_PumpEvents(_THIS) -{ - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -static int app_registered = 0; -LPTSTR SDL_Appname = NULL; -Uint32 SDL_Appstyle = 0; -HINSTANCE SDL_Instance = NULL; - -/* Register the class for this application */ -int -SDL_RegisterApp(char *name, Uint32 style, void *hInst) -{ - WNDCLASS class; - - /* Only do this once... */ - if (app_registered) { - ++app_registered; - return (0); - } - if (!name && !SDL_Appname) { - name = "SDL_app"; - SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC); - SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); - } - - if (name) { - SDL_Appname = WIN_UTF8ToString(name); - SDL_Appstyle = style; - SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); - } - - /* Register the application class */ - class.hCursor = NULL; - class.hIcon = - LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0, - LR_DEFAULTCOLOR); - class.lpszMenuName = NULL; - class.lpszClassName = SDL_Appname; - class.hbrBackground = NULL; - class.hInstance = SDL_Instance; - class.style = SDL_Appstyle; - class.lpfnWndProc = WIN_WindowProc; - class.cbWndExtra = 0; - class.cbClsExtra = 0; - if (!RegisterClass(&class)) { - SDL_SetError("Couldn't register application class"); - return (-1); - } - - app_registered = 1; - return (0); -} - -/* Unregisters the windowclass registered in SDL_RegisterApp above. */ -void -SDL_UnregisterApp() -{ - WNDCLASS class; - - /* SDL_RegisterApp might not have been called before */ - if (!app_registered) { - return; - } - --app_registered; - if (app_registered == 0) { - /* Check for any registered window classes. */ - if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) { - UnregisterClass(SDL_Appname, SDL_Instance); - } - SDL_free(SDL_Appname); - SDL_Appname = NULL; - } -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32events.h --- a/src/video/win32/SDL_win32events.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_win32events_h -#define _SDL_win32events_h - -extern LPTSTR SDL_Appname; -extern Uint32 SDL_Appstyle; -extern HINSTANCE SDL_Instance; - -extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, - LPARAM lParam); -extern void WIN_PumpEvents(_THIS); - -#endif /* _SDL_win32events_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32gamma.c --- a/src/video/win32/SDL_win32gamma.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#include "SDL_win32video.h" - - -int -WIN_SetDisplayGammaRamp(_THIS, SDL_VideoDisplay * display, Uint16 * ramp) -{ -#ifdef _WIN32_WCE - return -1; -#else - SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; - HDC hdc; - BOOL succeeded = FALSE; - - hdc = CreateDC(data->DeviceName, NULL, NULL, NULL); - if (hdc) { - succeeded = SetDeviceGammaRamp(hdc, ramp); - if (!succeeded) { - WIN_SetError("SetDeviceGammaRamp()"); - } - DeleteDC(hdc); - } - return succeeded ? 0 : -1; -#endif -} - -int -WIN_GetDisplayGammaRamp(_THIS, SDL_VideoDisplay * display, Uint16 * ramp) -{ -#ifdef _WIN32_WCE - return -1; -#else - SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; - HDC hdc; - BOOL succeeded = FALSE; - - hdc = CreateDC(data->DeviceName, NULL, NULL, NULL); - if (hdc) { - succeeded = GetDeviceGammaRamp(hdc, ramp); - if (!succeeded) { - WIN_SetError("GetDeviceGammaRamp()"); - } - DeleteDC(hdc); - } - return succeeded ? 0 : -1; -#endif -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32gamma.h --- a/src/video/win32/SDL_win32gamma.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_win32gamma_h -#define _SDL_win32gamma_h - -extern int WIN_SetDisplayGammaRamp(_THIS, SDL_VideoDisplay * display, Uint16 * ramp); -extern int WIN_GetDisplayGammaRamp(_THIS, SDL_VideoDisplay * display, Uint16 * ramp); - -#endif /* _SDL_win32gamma_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32keyboard.c --- a/src/video/win32/SDL_win32keyboard.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1555 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#include "SDL_win32video.h" - -#include "../../events/SDL_keyboard_c.h" -#include "../../events/scancodes_win32.h" - -#include -#include - -static void IME_Init(SDL_VideoData *videodata, HWND hwnd); -static void IME_Enable(SDL_VideoData *videodata, HWND hwnd); -static void IME_Disable(SDL_VideoData *videodata, HWND hwnd); -static void IME_Quit(SDL_VideoData *videodata); - -#ifndef MAPVK_VK_TO_VSC -#define MAPVK_VK_TO_VSC 0 -#endif -#ifndef MAPVK_VSC_TO_VK -#define MAPVK_VSC_TO_VK 1 -#endif -#ifndef MAPVK_VK_TO_CHAR -#define MAPVK_VK_TO_CHAR 2 -#endif - -/* Alphabetic scancodes for PC keyboards */ -BYTE alpha_scancodes[26] = { - 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50, 49, 24, - 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44 -}; - -BYTE keypad_scancodes[10] = { - 82, 79, 80, 81, 75, 76, 77, 71, 72, 73 -}; - -void -WIN_InitKeyboard(_THIS) -{ - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - int i; - - /* Make sure the alpha scancodes are correct. T isn't usually remapped */ - if (MapVirtualKey('T', MAPVK_VK_TO_VSC) != alpha_scancodes['T' - 'A']) { -#if 0 - printf - ("Fixing alpha scancode map, assuming US QWERTY layout!\nPlease send the following 26 lines of output to the SDL mailing list , including a description of your keyboard hardware.\n"); -#endif - for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) { - alpha_scancodes[i] = MapVirtualKey('A' + i, MAPVK_VK_TO_VSC); -#if 0 - printf("%d = %d\n", i, alpha_scancodes[i]); -#endif - } - } - if (MapVirtualKey(VK_NUMPAD0, MAPVK_VK_TO_VSC) != keypad_scancodes[0]) { -#if 0 - printf - ("Fixing keypad scancode map!\nPlease send the following 10 lines of output to the SDL mailing list , including a description of your keyboard hardware.\n"); -#endif - for (i = 0; i < SDL_arraysize(keypad_scancodes); ++i) { - keypad_scancodes[i] = - MapVirtualKey(VK_NUMPAD0 + i, MAPVK_VK_TO_VSC); -#if 0 - printf("%d = %d\n", i, keypad_scancodes[i]); -#endif - } - } - - data->key_layout = win32_scancode_table; - - data->ime_com_initialized = SDL_FALSE; - data->ime_threadmgr = 0; - data->ime_initialized = SDL_FALSE; - data->ime_enabled = SDL_FALSE; - data->ime_available = SDL_FALSE; - data->ime_hwnd_main = 0; - data->ime_hwnd_current = 0; - data->ime_himc = 0; - data->ime_composition[0] = 0; - data->ime_readingstring[0] = 0; - data->ime_cursor = 0; - - data->ime_candlist = SDL_FALSE; - SDL_memset(data->ime_candidates, 0, sizeof(data->ime_candidates)); - data->ime_candcount = 0; - data->ime_candref = 0; - data->ime_candsel = 0; - data->ime_candpgsize = 0; - data->ime_candlistindexbase = 0; - data->ime_candvertical = SDL_TRUE; - - data->ime_candtex = NULL; - data->ime_dirty = SDL_FALSE; - SDL_memset(&data->ime_rect, 0, sizeof(data->ime_rect)); - SDL_memset(&data->ime_candlistrect, 0, sizeof(data->ime_candlistrect)); - data->ime_winwidth = 0; - data->ime_winheight = 0; - - data->ime_hkl = 0; - data->ime_himm32 = 0; - data->GetReadingString = 0; - data->ShowReadingWindow = 0; - data->ImmLockIMC = 0; - data->ImmUnlockIMC = 0; - data->ImmLockIMCC = 0; - data->ImmUnlockIMCC = 0; - data->ime_uiless = SDL_FALSE; - data->ime_threadmgrex = 0; - data->ime_uielemsinkcookie = TF_INVALID_COOKIE; - data->ime_alpnsinkcookie = TF_INVALID_COOKIE; - data->ime_openmodesinkcookie = TF_INVALID_COOKIE; - data->ime_convmodesinkcookie = TF_INVALID_COOKIE; - data->ime_uielemsink = 0; - data->ime_ippasink = 0; - - WIN_UpdateKeymap(); - - SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu"); - SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Windows"); - SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Windows"); -} - -void -WIN_UpdateKeymap() -{ - int i; - SDL_scancode scancode; - SDLKey keymap[SDL_NUM_SCANCODES]; - - SDL_GetDefaultKeymap(keymap); - - for (i = 0; i < SDL_arraysize(win32_scancode_table); i++) { - - /* Make sure this scancode is a valid character scancode */ - scancode = win32_scancode_table[i]; - if (scancode == SDL_SCANCODE_UNKNOWN || keymap[scancode] >= 127) { - continue; - } - - /* Alphabetic keys are handled specially, since Windows remaps them */ - if (i >= 'A' && i <= 'Z') { - BYTE vsc = alpha_scancodes[i - 'A']; - keymap[scancode] = MapVirtualKey(vsc, MAPVK_VSC_TO_VK) + 0x20; - } else { - keymap[scancode] = (MapVirtualKey(i, MAPVK_VK_TO_CHAR) & 0x7FFF); - } - } - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); -} - -void -WIN_QuitKeyboard(_THIS) -{ - IME_Quit((SDL_VideoData *)_this->driverdata); -} - -void -WIN_StartTextInput(_THIS) -{ - SDL_Window *window = SDL_GetKeyboardFocus(); - if (window) { - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; - SDL_GetWindowSize(window, &videodata->ime_winwidth, &videodata->ime_winheight); - IME_Init(videodata, hwnd); - IME_Enable(videodata, hwnd); - } -} - -void -WIN_StopTextInput(_THIS) -{ - SDL_Window *window = SDL_GetKeyboardFocus(); - if (window) { - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; - IME_Init(videodata, hwnd); - IME_Disable(videodata, hwnd); - } -} - -void -WIN_SetTextInputRect(_THIS, SDL_Rect *rect) -{ - SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; - videodata->ime_rect = *rect; -} - -#ifdef __GNUC__ -#undef DEFINE_GUID -#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) static const GUID n = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} -DEFINE_GUID(IID_ITfInputProcessorProfileActivationSink, 0x71C6E74E,0x0F28,0x11D8,0xA8,0x2A,0x00,0x06,0x5B,0x84,0x43,0x5C); -DEFINE_GUID(IID_ITfUIElementSink, 0xEA1EA136,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); -DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745C63,0xB2F0,0x4784,0x8B,0x67,0x5E,0x12,0xC8,0x70,0x1A,0x31); -DEFINE_GUID(IID_ITfSource, 0x4EA48A35,0x60AE,0x446F,0x8F,0xD6,0xE6,0xA8,0xD8,0x24,0x59,0xF7); -DEFINE_GUID(IID_ITfUIElementMgr, 0xEA1EA135,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); -DEFINE_GUID(IID_ITfCandidateListUIElement, 0xEA1EA138,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); -DEFINE_GUID(IID_ITfReadingInformationUIElement, 0xEA1EA139,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); -DEFINE_GUID(IID_ITfThreadMgr, 0xAA80E801,0x2021,0x11D2,0x93,0xE0,0x00,0x60,0xB0,0x67,0xB8,0x6E); -DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529A9E6B,0x6587,0x4F23,0xAB,0x9E,0x9C,0x7D,0x68,0x3E,0x3C,0x50); -DEFINE_GUID(IID_ITfThreadMgrEx, 0x3E90ADE3,0x7594,0x4CB0,0xBB,0x58,0x69,0x62,0x8F,0x5F,0x45,0x8C); -#endif - -#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) -#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) - -#define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) )) -#define IMEID_VER(id) ((id) & 0xffff0000) -#define IMEID_LANG(id) ((id) & 0x0000ffff) - -#define CHT_HKL_DAYI ((HKL)0xE0060404) -#define CHT_HKL_NEW_PHONETIC ((HKL)0xE0080404) -#define CHT_HKL_NEW_CHANG_JIE ((HKL)0xE0090404) -#define CHT_HKL_NEW_QUICK ((HKL)0xE00A0404) -#define CHT_HKL_HK_CANTONESE ((HKL)0xE00B0404) -#define CHT_IMEFILENAME1 "TINTLGNT.IME" -#define CHT_IMEFILENAME2 "CINTLGNT.IME" -#define CHT_IMEFILENAME3 "MSTCIPHA.IME" -#define IMEID_CHT_VER42 (LANG_CHT | MAKEIMEVERSION(4, 2)) -#define IMEID_CHT_VER43 (LANG_CHT | MAKEIMEVERSION(4, 3)) -#define IMEID_CHT_VER44 (LANG_CHT | MAKEIMEVERSION(4, 4)) -#define IMEID_CHT_VER50 (LANG_CHT | MAKEIMEVERSION(5, 0)) -#define IMEID_CHT_VER51 (LANG_CHT | MAKEIMEVERSION(5, 1)) -#define IMEID_CHT_VER52 (LANG_CHT | MAKEIMEVERSION(5, 2)) -#define IMEID_CHT_VER60 (LANG_CHT | MAKEIMEVERSION(6, 0)) -#define IMEID_CHT_VER_VISTA (LANG_CHT | MAKEIMEVERSION(7, 0)) - -#define CHS_HKL ((HKL)0xE00E0804) -#define CHS_IMEFILENAME1 "PINTLGNT.IME" -#define CHS_IMEFILENAME2 "MSSCIPYA.IME" -#define IMEID_CHS_VER41 (LANG_CHS | MAKEIMEVERSION(4, 1)) -#define IMEID_CHS_VER42 (LANG_CHS | MAKEIMEVERSION(4, 2)) -#define IMEID_CHS_VER53 (LANG_CHS | MAKEIMEVERSION(5, 3)) - -#define LANG() LOWORD((videodata->ime_hkl)) -#define PRIMLANG() ((WORD)PRIMARYLANGID(LANG())) -#define SUBLANG() SUBLANGID(LANG()) - -static void IME_UpdateInputLocale(SDL_VideoData *videodata); -static void IME_ClearComposition(SDL_VideoData *videodata); -static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd); -static void IME_SetupAPI(SDL_VideoData *videodata); -static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex); -static void IME_SendEditingEvent(SDL_VideoData *videodata); -static void IME_DestroyTextures(SDL_VideoData *videodata); - -#define SDL_IsEqualIID(riid1, riid2) SDL_IsEqualGUID(riid1, riid2) -#define SDL_IsEqualGUID(rguid1, rguid2) (!SDL_memcmp(rguid1, rguid2, sizeof(GUID))) - -static SDL_bool UILess_SetupSinks(SDL_VideoData *videodata); -static void UILess_ReleaseSinks(SDL_VideoData *videodata); -static void UILess_EnableUIUpdates(SDL_VideoData *videodata); -static void UILess_DisableUIUpdates(SDL_VideoData *videodata); - -static void -IME_Init(SDL_VideoData *videodata, HWND hwnd) -{ - if (videodata->ime_initialized) - return; - - videodata->ime_hwnd_main = hwnd; - if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) { - videodata->ime_com_initialized = SDL_TRUE; - CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (LPVOID *)&videodata->ime_threadmgr); - } - videodata->ime_initialized = SDL_TRUE; - videodata->ime_himm32 = LoadLibraryA("imm32.dll"); - if (!videodata->ime_himm32) { - videodata->ime_available = SDL_FALSE; - return; - } - videodata->ImmLockIMC = (LPINPUTCONTEXT2 (WINAPI *)(HIMC))GetProcAddress(videodata->ime_himm32, "ImmLockIMC"); - videodata->ImmUnlockIMC = (BOOL (WINAPI *)(HIMC))GetProcAddress(videodata->ime_himm32, "ImmUnlockIMC"); - videodata->ImmLockIMCC = (LPVOID (WINAPI *)(HIMCC))GetProcAddress(videodata->ime_himm32, "ImmLockIMCC"); - videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))GetProcAddress(videodata->ime_himm32, "ImmUnlockIMCC"); - - IME_SetWindow(videodata, hwnd); - videodata->ime_himc = ImmGetContext(hwnd); - ImmReleaseContext(hwnd, videodata->ime_himc); - if (!videodata->ime_himc) { - videodata->ime_available = SDL_FALSE; - IME_Disable(videodata, hwnd); - return; - } - videodata->ime_available = SDL_TRUE; - IME_UpdateInputLocale(videodata); - IME_SetupAPI(videodata); - videodata->ime_uiless = UILess_SetupSinks(videodata); - IME_UpdateInputLocale(videodata); - IME_Disable(videodata, hwnd); -} - -static void -IME_Enable(SDL_VideoData *videodata, HWND hwnd) -{ - if (!videodata->ime_initialized || !videodata->ime_hwnd_current) - return; - - if (!videodata->ime_available) { - IME_Disable(videodata, hwnd); - return; - } - if (videodata->ime_hwnd_current == videodata->ime_hwnd_main) - ImmAssociateContext(videodata->ime_hwnd_current, videodata->ime_himc); - - videodata->ime_enabled = SDL_TRUE; - IME_UpdateInputLocale(videodata); - UILess_EnableUIUpdates(videodata); -} - -static void -IME_Disable(SDL_VideoData *videodata, HWND hwnd) -{ - if (!videodata->ime_initialized || !videodata->ime_hwnd_current) - return; - - IME_ClearComposition(videodata); - if (videodata->ime_hwnd_current == videodata->ime_hwnd_main) - ImmAssociateContext(videodata->ime_hwnd_current, (HIMC)0); - - videodata->ime_enabled = SDL_FALSE; - UILess_DisableUIUpdates(videodata); -} - -static void -IME_Quit(SDL_VideoData *videodata) -{ - if (!videodata->ime_initialized) - return; - - UILess_ReleaseSinks(videodata); - if (videodata->ime_hwnd_main) - ImmAssociateContext(videodata->ime_hwnd_main, videodata->ime_himc); - - videodata->ime_hwnd_main = 0; - videodata->ime_himc = 0; - if (videodata->ime_himm32) { - FreeLibrary(videodata->ime_himm32); - videodata->ime_himm32 = 0; - } - if (videodata->ime_threadmgr) { - videodata->ime_threadmgr->lpVtbl->Release(videodata->ime_threadmgr); - videodata->ime_threadmgr = 0; - } - if (videodata->ime_com_initialized) { - CoUninitialize(); - videodata->ime_com_initialized = SDL_FALSE; - } - IME_DestroyTextures(videodata); - videodata->ime_initialized = SDL_FALSE; -} - -static void -IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) -{ - DWORD id = 0; - HIMC himc = 0; - WCHAR buffer[16]; - WCHAR *s = buffer; - DWORD len = 0; - INT err = 0; - BOOL vertical = FALSE; - UINT maxuilen = 0; - static OSVERSIONINFOA osversion = {0}; - if (videodata->ime_uiless) - return; - - videodata->ime_readingstring[0] = 0; - if (!osversion.dwOSVersionInfoSize) { - osversion.dwOSVersionInfoSize = sizeof(osversion); - GetVersionExA(&osversion); - } - id = IME_GetId(videodata, 0); - if (!id) - return; - - himc = ImmGetContext(hwnd); - if (!himc) - return; - - if (videodata->GetReadingString) { - len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen); - if (len) { - if (len > SDL_arraysize(buffer)) - len = SDL_arraysize(buffer); - - len = videodata->GetReadingString(himc, len, s, &err, &vertical, &maxuilen); - } - SDL_wcslcpy(videodata->ime_readingstring, s, len); - } - else { - LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc); - LPBYTE p = 0; - s = 0; - switch (id) - { - case IMEID_CHT_VER42: - case IMEID_CHT_VER43: - case IMEID_CHT_VER44: - p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 24); - if (!p) - break; - - len = *(DWORD *)(p + 7*4 + 32*4); - s = (WCHAR *)(p + 56); - break; - case IMEID_CHT_VER51: - case IMEID_CHT_VER52: - case IMEID_CHS_VER53: - p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 4); - if (!p) - break; - - p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4); - if (!p) - break; - - len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2); - s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4); - break; - case IMEID_CHS_VER41: - { - int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7; - p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4); - if (!p) - break; - - len = *(DWORD *)(p + 7*4 + 16*2*4); - s = (WCHAR *)(p + 6*4 + 16*2*1); - } - break; - case IMEID_CHS_VER42: - if (osversion.dwPlatformId != VER_PLATFORM_WIN32_NT) - break; - - p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1*4 + 1*4 + 6*4); - if (!p) - break; - - len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2); - s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4); - break; - } - if (s) - SDL_wcslcpy(videodata->ime_readingstring, s, len + 1); - - videodata->ImmUnlockIMCC(lpimc->hPrivate); - videodata->ImmUnlockIMC(himc); - } - ImmReleaseContext(hwnd, himc); - IME_SendEditingEvent(videodata); -} - -static void -IME_InputLangChanged(SDL_VideoData *videodata) -{ - UINT lang = PRIMLANG(); - IME_UpdateInputLocale(videodata); - if (!videodata->ime_uiless) - videodata->ime_candlistindexbase = (videodata->ime_hkl == CHT_HKL_DAYI) ? 0 : 1; - - IME_SetupAPI(videodata); - if (lang != PRIMLANG()) { - IME_ClearComposition(videodata); - } -} - -static DWORD -IME_GetId(SDL_VideoData *videodata, UINT uIndex) -{ - static HKL hklprev = 0; - static DWORD dwRet[2] = {0}; - DWORD dwVerSize = 0; - DWORD dwVerHandle = 0; - LPVOID lpVerBuffer = 0; - LPVOID lpVerData = 0; - UINT cbVerData = 0; - char szTemp[256]; - HKL hkl = 0; - DWORD dwLang = 0; - if (uIndex >= sizeof(dwRet) / sizeof(dwRet[0])) - return 0; - - hkl = videodata->ime_hkl; - if (hklprev == hkl) - return dwRet[uIndex]; - - hklprev = hkl; - dwLang = ((DWORD)hkl & 0xffff); - if (videodata->ime_uiless && LANG() == LANG_CHT) { - dwRet[0] = IMEID_CHT_VER_VISTA; - dwRet[1] = 0; - return dwRet[0]; - } - if (hkl != CHT_HKL_NEW_PHONETIC - && hkl != CHT_HKL_NEW_CHANG_JIE - && hkl != CHT_HKL_NEW_QUICK - && hkl != CHT_HKL_HK_CANTONESE - && hkl != CHS_HKL) { - dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; - } - if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) { - dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; - } - if (!videodata->GetReadingString) { - #define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) - if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2 - && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2 - && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2 - && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2 - && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) { - dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; - } - #undef LCID_INVARIANT - dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle); - if (dwVerSize) { - lpVerBuffer = SDL_malloc(dwVerSize); - if (lpVerBuffer) { - if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) { - if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData)) { - #define pVerFixedInfo ((VS_FIXEDFILEINFO FAR*)lpVerData) - DWORD dwVer = pVerFixedInfo->dwFileVersionMS; - dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16; - if (videodata->GetReadingString || - dwLang == LANG_CHT && ( - dwVer == MAKEIMEVERSION(4, 2) || - dwVer == MAKEIMEVERSION(4, 3) || - dwVer == MAKEIMEVERSION(4, 4) || - dwVer == MAKEIMEVERSION(5, 0) || - dwVer == MAKEIMEVERSION(5, 1) || - dwVer == MAKEIMEVERSION(5, 2) || - dwVer == MAKEIMEVERSION(6, 0)) - || - dwLang == LANG_CHS && ( - dwVer == MAKEIMEVERSION(4, 1) || - dwVer == MAKEIMEVERSION(4, 2) || - dwVer == MAKEIMEVERSION(5, 3))) { - dwRet[0] = dwVer | dwLang; - dwRet[1] = pVerFixedInfo->dwFileVersionLS; - SDL_free(lpVerBuffer); - return dwRet[0]; - } - #undef pVerFixedInfo - } - } - } - SDL_free(lpVerBuffer); - } - } - dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; -} - -static void -IME_SetupAPI(SDL_VideoData *videodata) -{ - char ime_file[MAX_PATH + 1]; - HMODULE hime = 0; - HKL hkl = 0; - videodata->GetReadingString = 0; - videodata->ShowReadingWindow = 0; - if (videodata->ime_uiless) - return; - - hkl = videodata->ime_hkl; - if (ImmGetIMEFileNameA(hkl, ime_file, sizeof(ime_file) - 1) <= 0) - return; - - hime = LoadLibraryA(ime_file); - if (!hime) - return; - - videodata->GetReadingString = (UINT (WINAPI *)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT)) - GetProcAddress(hime, "GetReadingString"); - videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL)) - GetProcAddress(hime, "ShowReadingWindow"); - - if (videodata->ShowReadingWindow) { - HIMC himc = ImmGetContext(videodata->ime_hwnd_current); - if (himc) { - videodata->ShowReadingWindow(himc, FALSE); - ImmReleaseContext(videodata->ime_hwnd_current, himc); - } - } -} - -static void -IME_SetWindow(SDL_VideoData* videodata, HWND hwnd) -{ - videodata->ime_hwnd_current = hwnd; - if (videodata->ime_threadmgr) { - struct ITfDocumentMgr *document_mgr = 0; - if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) { - if (document_mgr) - document_mgr->lpVtbl->Release(document_mgr); - } - } -} - -static void -IME_UpdateInputLocale(SDL_VideoData *videodata) -{ - static HKL hklprev = 0; - videodata->ime_hkl = GetKeyboardLayout(0); - if (hklprev == videodata->ime_hkl) - return; - - hklprev = videodata->ime_hkl; - switch (PRIMLANG()) { - case LANG_CHINESE: - videodata->ime_candvertical = SDL_TRUE; - if (SUBLANG() == SUBLANG_CHINESE_SIMPLIFIED) - videodata->ime_candvertical = SDL_FALSE; - - break; - case LANG_JAPANESE: - videodata->ime_candvertical = SDL_TRUE; - break; - case LANG_KOREAN: - videodata->ime_candvertical = SDL_FALSE; - break; - } -} - -static void -IME_ClearComposition(SDL_VideoData *videodata) -{ - HIMC himc = 0; - if (!videodata->ime_initialized) - return; - - himc = ImmGetContext(videodata->ime_hwnd_current); - if (!himc) - return; - - ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); - if (videodata->ime_uiless) - ImmSetCompositionString(himc, SCS_SETSTR, TEXT(""), sizeof(TCHAR), TEXT(""), sizeof(TCHAR)); - - ImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0); - ImmReleaseContext(videodata->ime_hwnd_current, himc); - SDL_SendEditingText("", 0, 0); -} - -static void -IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string) -{ - LONG length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition)); - if (length < 0) - length = 0; - - length /= sizeof(videodata->ime_composition[0]); - videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0)); - if (videodata->ime_composition[videodata->ime_cursor] == 0x3000) { - int i; - for (i = videodata->ime_cursor + 1; i < length; ++i) - videodata->ime_composition[i - 1] = videodata->ime_composition[i]; - - --length; - } - videodata->ime_composition[length] = 0; -} - -static void -IME_SendInputEvent(SDL_VideoData *videodata) -{ - char *s = 0; - s = WIN_StringToUTF8(videodata->ime_composition); - SDL_SendKeyboardText(s); - SDL_free(s); - - videodata->ime_composition[0] = 0; - videodata->ime_readingstring[0] = 0; - videodata->ime_cursor = 0; -} - -static void -IME_SendEditingEvent(SDL_VideoData *videodata) -{ - char *s = 0; - WCHAR buffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; - buffer[0] = 0; - if (videodata->ime_readingstring[0]) { - size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor); - SDL_wcslcpy(buffer, videodata->ime_composition, len + 1); - SDL_wcslcat(buffer, videodata->ime_readingstring, sizeof(buffer)); - SDL_wcslcat(buffer, &videodata->ime_composition[len], sizeof(buffer) - len); - } - else { - SDL_wcslcpy(buffer, videodata->ime_composition, sizeof(videodata->ime_composition)); - } - s = WIN_StringToUTF8(buffer); - SDL_SendEditingText(s, videodata->ime_cursor + SDL_wcslen(videodata->ime_readingstring), 0); - SDL_free(s); -} - -static void -IME_AddCandidate(SDL_VideoData *videodata, UINT i, LPCWSTR candidate) -{ - LPWSTR dst = videodata->ime_candidates[i]; - *dst++ = (WCHAR)(TEXT('0') + ((i + videodata->ime_candlistindexbase) % 10)); - if (videodata->ime_candvertical) - *dst++ = TEXT(' '); - - while (*candidate && (SDL_arraysize(videodata->ime_candidates[i]) > (dst - videodata->ime_candidates[i]))) - *dst++ = *candidate++; - - *dst = (WCHAR)'\0'; -} - -static void -IME_GetCandidateList(HIMC himc, SDL_VideoData *videodata) -{ - LPCANDIDATELIST cand_list = 0; - DWORD size = ImmGetCandidateListW(himc, 0, 0, 0); - if (size) { - cand_list = (LPCANDIDATELIST)SDL_malloc(size); - if (cand_list) { - size = ImmGetCandidateListW(himc, 0, cand_list, size); - if (size) { - int i = 0; - int j = 0; - int page_start = 0; - videodata->ime_candsel = cand_list->dwSelection; - videodata->ime_candcount = cand_list->dwCount; - - if (LANG() == LANG_CHS && IME_GetId(videodata, 0)) { - const UINT maxcandchar = 18; - UINT i = 0; - UINT cchars = 0; - - for (; i < videodata->ime_candcount; ++i) { - UINT len = SDL_wcslen((LPWSTR)((DWORD)cand_list + cand_list->dwOffset[i])) + 1; - if (len + cchars > maxcandchar) { - if (i > cand_list->dwSelection) - break; - - page_start = i; - cchars = len; - } - else { - cchars += len; - } - } - videodata->ime_candpgsize = i - page_start; - } - else { - videodata->ime_candpgsize = SDL_min(cand_list->dwPageSize, MAX_CANDLIST); - page_start = (cand_list->dwSelection / videodata->ime_candpgsize) * videodata->ime_candpgsize; - } - SDL_memset(&videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); - for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < (int)videodata->ime_candpgsize; i++, j++) { - LPCWSTR candidate = (LPCWSTR)((DWORD)cand_list + cand_list->dwOffset[i]); - IME_AddCandidate(videodata, j, candidate); - } - if (PRIMLANG() == LANG_KOREAN || (PRIMLANG() == LANG_CHT && !IME_GetId(videodata, 0))) - videodata->ime_candsel = -1; - - } - SDL_free(cand_list); - } - } -} - -static void -IME_ShowCandidateList(SDL_VideoData *videodata) -{ - videodata->ime_dirty = SDL_TRUE; - videodata->ime_candlist = SDL_TRUE; - IME_DestroyTextures(videodata); - IME_SendEditingEvent(videodata); -} - -static void -IME_HideCandidateList(SDL_VideoData *videodata) -{ - videodata->ime_dirty = SDL_FALSE; - videodata->ime_candlist = SDL_FALSE; - IME_DestroyTextures(videodata); - IME_SendEditingEvent(videodata); -} - -SDL_bool -IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata) -{ - SDL_bool trap = SDL_FALSE; - HIMC himc = 0; - if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled) - return SDL_FALSE; - - switch (msg) { - case WM_INPUTLANGCHANGE: - IME_InputLangChanged(videodata); - break; - case WM_IME_SETCONTEXT: - *lParam = 0; - break; - case WM_IME_STARTCOMPOSITION: - trap = SDL_TRUE; - break; - case WM_IME_COMPOSITION: - trap = SDL_TRUE; - himc = ImmGetContext(hwnd); - if (*lParam & GCS_RESULTSTR) { - IME_GetCompositionString(videodata, himc, GCS_RESULTSTR); - IME_SendInputEvent(videodata); - } - if (*lParam & GCS_COMPSTR) { - if (!videodata->ime_uiless) - videodata->ime_readingstring[0] = 0; - - IME_GetCompositionString(videodata, himc, GCS_COMPSTR); - IME_SendEditingEvent(videodata); - } - ImmReleaseContext(hwnd, himc); - break; - case WM_IME_ENDCOMPOSITION: - videodata->ime_composition[0] = 0; - videodata->ime_readingstring[0] = 0; - videodata->ime_cursor = 0; - SDL_SendEditingText("", 0, 0); - break; - case WM_IME_NOTIFY: - switch (wParam) { - case IMN_SETCONVERSIONMODE: - case IMN_SETOPENSTATUS: - IME_UpdateInputLocale(videodata); - break; - case IMN_OPENCANDIDATE: - case IMN_CHANGECANDIDATE: - if (videodata->ime_uiless) - break; - - trap = SDL_TRUE; - IME_ShowCandidateList(videodata); - himc = ImmGetContext(hwnd); - if (!himc) - break; - - IME_GetCandidateList(himc, videodata); - ImmReleaseContext(hwnd, himc); - break; - case IMN_CLOSECANDIDATE: - trap = SDL_TRUE; - IME_HideCandidateList(videodata); - break; - case IMN_PRIVATE: - { - DWORD dwId = IME_GetId(videodata, 0); - IME_GetReadingString(videodata, hwnd); - switch (dwId) - { - case IMEID_CHT_VER42: - case IMEID_CHT_VER43: - case IMEID_CHT_VER44: - case IMEID_CHS_VER41: - case IMEID_CHS_VER42: - if (*lParam == 1 || *lParam == 2) - trap = SDL_TRUE; - - break; - case IMEID_CHT_VER50: - case IMEID_CHT_VER51: - case IMEID_CHT_VER52: - case IMEID_CHT_VER60: - case IMEID_CHS_VER53: - if (*lParam == 16 - || *lParam == 17 - || *lParam == 26 - || *lParam == 27 - || *lParam == 28) - trap = SDL_TRUE; - break; - } - } - break; - default: - trap = SDL_TRUE; - break; - } - break; - } - return trap; -} - -static void -IME_CloseCandidateList(SDL_VideoData *videodata) -{ - IME_HideCandidateList(videodata); - videodata->ime_candcount = 0; - SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); -} - -static void -UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pcandlist) -{ - UINT selection = 0; - UINT count = 0; - UINT page = 0; - UINT pgcount = 0; - DWORD pgstart = 0; - DWORD pgsize = 0; - UINT i, j; - pcandlist->lpVtbl->GetSelection(pcandlist, &selection); - pcandlist->lpVtbl->GetCount(pcandlist, &count); - pcandlist->lpVtbl->GetCurrentPage(pcandlist, &page); - - videodata->ime_candsel = selection; - videodata->ime_candcount = count; - IME_ShowCandidateList(videodata); - - pcandlist->lpVtbl->GetPageIndex(pcandlist, 0, 0, &pgcount); - if (pgcount > 0) { - UINT *idxlist = SDL_malloc(sizeof(UINT) * pgcount); - if (idxlist) { - pcandlist->lpVtbl->GetPageIndex(pcandlist, idxlist, pgcount, &pgcount); - pgstart = idxlist[page]; - if (page < pgcount - 1) - pgsize = SDL_min(count, idxlist[page + 1]) - pgstart; - else - pgsize = count - pgstart; - - SDL_free(idxlist); - } - } - videodata->ime_candpgsize = SDL_min(pgsize, MAX_CANDLIST); - videodata->ime_candsel = videodata->ime_candsel - pgstart; - - SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); - for (i = pgstart, j = 0; (DWORD)i < count && j < videodata->ime_candpgsize; i++, j++) { - BSTR bstr; - if (SUCCEEDED(pcandlist->lpVtbl->GetString(pcandlist, i, &bstr))) { - if (bstr) { - IME_AddCandidate(videodata, j, bstr); - SysFreeString(bstr); - } - } - } - if (PRIMLANG() == LANG_KOREAN) - videodata->ime_candsel = -1; -} - -STDMETHODIMP_(ULONG) TSFSink_AddRef(TSFSink *sink) -{ - return ++sink->refcount; -} - -STDMETHODIMP_(ULONG)TSFSink_Release(TSFSink *sink) -{ - --sink->refcount; - if (sink->refcount == 0) { - SDL_free(sink); - return 0; - } - return sink->refcount; -} - -STDMETHODIMP UIElementSink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv) -{ - if (!ppv) - return E_INVALIDARG; - - *ppv = 0; - if (SDL_IsEqualIID(riid, &IID_IUnknown)) - *ppv = (IUnknown *)sink; - else if (SDL_IsEqualIID(riid, &IID_ITfUIElementSink)) - *ppv = (ITfUIElementSink *)sink; - - if (*ppv) { - TSFSink_AddRef(sink); - return S_OK; - } - return E_NOINTERFACE; -} - -ITfUIElement *UILess_GetUIElement(SDL_VideoData *videodata, DWORD dwUIElementId) -{ - ITfUIElementMgr *puiem = 0; - ITfUIElement *pelem = 0; - ITfThreadMgrEx *threadmgrex = videodata->ime_threadmgrex; - - if (SUCCEEDED(threadmgrex->lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem))) { - puiem->lpVtbl->GetUIElement(puiem, dwUIElementId, &pelem); - puiem->lpVtbl->Release(puiem); - } - return pelem; -} - -STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BOOL *pbShow) -{ - ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); - ITfReadingInformationUIElement *preading = 0; - ITfCandidateListUIElement *pcandlist = 0; - SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - if (!element) - return E_INVALIDARG; - - *pbShow = FALSE; - if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { - BSTR bstr; - if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) { - WCHAR *s = (WCHAR *)bstr; - SysFreeString(bstr); - } - preading->lpVtbl->Release(preading); - } - else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { - videodata->ime_candref++; - UILess_GetCandidateList(videodata, pcandlist); - pcandlist->lpVtbl->Release(pcandlist); - } - return S_OK; -} - -STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId) -{ - ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); - ITfReadingInformationUIElement *preading = 0; - ITfCandidateListUIElement *pcandlist = 0; - SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - if (!element) - return E_INVALIDARG; - - if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { - BSTR bstr; - if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) { - WCHAR *s = (WCHAR *)bstr; - SDL_wcslcpy(videodata->ime_readingstring, s, sizeof(videodata->ime_readingstring)); - IME_SendEditingEvent(videodata); - SysFreeString(bstr); - } - preading->lpVtbl->Release(preading); - } - else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { - UILess_GetCandidateList(videodata, pcandlist); - pcandlist->lpVtbl->Release(pcandlist); - } - return S_OK; -} - -STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId) -{ - ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); - ITfReadingInformationUIElement *preading = 0; - ITfCandidateListUIElement *pcandlist = 0; - SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - if (!element) - return E_INVALIDARG; - - if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { - videodata->ime_readingstring[0] = 0; - IME_SendEditingEvent(videodata); - preading->lpVtbl->Release(preading); - } - if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { - videodata->ime_candref--; - if (videodata->ime_candref == 0) - IME_CloseCandidateList(videodata); - - pcandlist->lpVtbl->Release(pcandlist); - } - return S_OK; -} - -STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv) -{ - if (!ppv) - return E_INVALIDARG; - - *ppv = 0; - if (SDL_IsEqualIID(riid, &IID_IUnknown)) - *ppv = (IUnknown *)sink; - else if (SDL_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink)) - *ppv = (ITfInputProcessorProfileActivationSink *)sink; - - if (*ppv) { - TSFSink_AddRef(sink); - return S_OK; - } - return E_NOINTERFACE; -} - -STDMETHODIMP IPPASink_OnActivated(TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags) -{ - static GUID TF_PROFILE_DAYI = {0x037B2C25, 0x480C, 0x4D7F, 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A}; - SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - videodata->ime_candlistindexbase = SDL_IsEqualGUID(&TF_PROFILE_DAYI, guidProfile) ? 0 : 1; - if (SDL_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE)) - IME_InputLangChanged((SDL_VideoData *)sink->data); - - IME_HideCandidateList(videodata); - return S_OK; -} - -static void *vtUIElementSink[] = { - (void *)(UIElementSink_QueryInterface), - (void *)(TSFSink_AddRef), - (void *)(TSFSink_Release), - (void *)(UIElementSink_BeginUIElement), - (void *)(UIElementSink_UpdateUIElement), - (void *)(UIElementSink_EndUIElement) -}; - -static void *vtIPPASink[] = { - (void *)(IPPASink_QueryInterface), - (void *)(TSFSink_AddRef), - (void *)(TSFSink_Release), - (void *)(IPPASink_OnActivated) -}; - -static void -UILess_EnableUIUpdates(SDL_VideoData *videodata) -{ - ITfSource *source = 0; - if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie != TF_INVALID_COOKIE) - return; - - if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { - source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie); - source->lpVtbl->Release(source); - } -} - -static void -UILess_DisableUIUpdates(SDL_VideoData *videodata) -{ - ITfSource *source = 0; - if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie == TF_INVALID_COOKIE) - return; - - if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { - source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie); - videodata->ime_uielemsinkcookie = TF_INVALID_COOKIE; - source->lpVtbl->Release(source); - } -} - -static SDL_bool -UILess_SetupSinks(SDL_VideoData *videodata) -{ - TfClientId clientid = 0; - SDL_bool result = SDL_FALSE; - ITfSource *source = 0; - if (FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, (LPVOID *)&videodata->ime_threadmgrex))) - return SDL_FALSE; - - if (FAILED(videodata->ime_threadmgrex->lpVtbl->ActivateEx(videodata->ime_threadmgrex, &clientid, TF_TMAE_UIELEMENTENABLEDONLY))) - return SDL_FALSE; - - videodata->ime_uielemsink = SDL_malloc(sizeof(TSFSink)); - videodata->ime_ippasink = SDL_malloc(sizeof(TSFSink)); - - videodata->ime_uielemsink->lpVtbl = vtUIElementSink; - videodata->ime_uielemsink->refcount = 1; - videodata->ime_uielemsink->data = videodata; - - videodata->ime_ippasink->lpVtbl = vtIPPASink; - videodata->ime_ippasink->refcount = 1; - videodata->ime_ippasink->data = videodata; - - if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { - if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie))) { - if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfInputProcessorProfileActivationSink, (IUnknown *)videodata->ime_ippasink, &videodata->ime_alpnsinkcookie))) { - result = SDL_TRUE; - } - } - source->lpVtbl->Release(source); - } - return result; -} - -#define SAFE_RELEASE(p) \ -{ \ - if (p) { \ - (p)->lpVtbl->Release((p)); \ - (p) = 0; \ - } \ -} - -static void -UILess_ReleaseSinks(SDL_VideoData *videodata) -{ - ITfSource *source = 0; - if (videodata->ime_threadmgrex && SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { - source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie); - source->lpVtbl->UnadviseSink(source, videodata->ime_alpnsinkcookie); - SAFE_RELEASE(source); - videodata->ime_threadmgrex->lpVtbl->Deactivate(videodata->ime_threadmgrex); - SAFE_RELEASE(videodata->ime_threadmgrex); - TSFSink_Release(videodata->ime_uielemsink); - videodata->ime_uielemsink = 0; - TSFSink_Release(videodata->ime_ippasink); - videodata->ime_ippasink = 0; - } -} - -static void * -StartDrawToBitmap(HDC hdc, HBITMAP *hhbm, int width, int height) -{ - BITMAPINFO info = {0}; - BITMAPINFOHEADER *infoHeader = &info.bmiHeader; - BYTE *bits = NULL; - if (hhbm) { - infoHeader->biSize = sizeof(BITMAPINFOHEADER); - infoHeader->biWidth = width; - infoHeader->biHeight = -1 * SDL_abs(height); - infoHeader->biPlanes = 1; - infoHeader->biBitCount = 32; - infoHeader->biCompression = BI_RGB; - *hhbm = CreateDIBSection(hdc, &info, DIB_RGB_COLORS, (void **)&bits, 0, 0); - if (*hhbm) - SelectObject(hdc, *hhbm); - } - return bits; -} - -static void -StopDrawToBitmap(HDC hdc, HBITMAP *hhbm) -{ - if (hhbm && *hhbm) { - DeleteObject(*hhbm); - *hhbm = NULL; - } -} - -static void -BitmapToTexture(HBITMAP hbm, BYTE *bits, int width, int height, SDL_Texture **texture) -{ - SDL_Surface *surface = NULL; - BITMAP bm = {0}; - - if (GetObject(hbm, sizeof(bm), &bm) == 0) - return; - - if (bits && texture) { - /* - For transparency: - - const Uint8 alpha = 130; - unsigned long *p = (unsigned long *)bits; - unsigned long *end = (unsigned long *)(bits + (bm.bmWidthBytes * bm.bmHeight)); - while (p < end) { - *p = RGB(GetRValue(*p), GetGValue(*p), GetBValue(*p)) | (alpha << 24); - ++p; - } - surface = SDL_CreateRGBSurfaceFrom(bits, width, height, bm.bmBitsPixel, bm.bmWidthBytes, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); - */ - surface = SDL_CreateRGBSurfaceFrom(bits, width, height, bm.bmBitsPixel, bm.bmWidthBytes, 0x00ff0000, 0x0000ff00, 0x000000ff, 0); - if (surface) { - *texture = SDL_CreateTextureFromSurface(0, surface); - SDL_FreeSurface(surface); - } - } -} - -/* This draws only within the specified area and fills the entire region. */ -static void -DrawRect(HDC hdc, int left, int top, int right, int bottom, int pensize) -{ - /* The case of no pen (PenSize = 0) is automatically taken care of. */ - const int penadjust = (int)SDL_floor(pensize / 2.0f - 0.5f); - left += pensize / 2; - top += pensize / 2; - right -= penadjust; - bottom -= penadjust; - Rectangle(hdc, left, top, right, bottom); -} - -static void -DestroyTexture(SDL_Texture **texture) -{ - if (texture && *texture) { - SDL_DestroyTexture(*texture); - *texture = NULL; - } -} - -static void -IME_DestroyTextures(SDL_VideoData *videodata) -{ - DestroyTexture(&videodata->ime_candtex); -} - -#define SDL_swap(a,b) { \ - int c = (a); \ - (a) = (b); \ - (b) = c; \ - } - -static void -IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size) -{ - int left, top, right, bottom; - SDL_bool ok = SDL_FALSE; - int winw = videodata->ime_winwidth; - int winh = videodata->ime_winheight; - - /* Bottom */ - left = videodata->ime_rect.x; - top = videodata->ime_rect.y + videodata->ime_rect.h; - right = left + size.cx; - bottom = top + size.cy; - if (right >= winw) { - left -= right - winw; - right = winw; - } - if (bottom < winh) - ok = SDL_TRUE; - - /* Top */ - if (!ok) { - left = videodata->ime_rect.x; - top = videodata->ime_rect.y - size.cy; - right = left + size.cx; - bottom = videodata->ime_rect.y; - if (right >= winw) { - left -= right - winw; - right = winw; - } - if (top >= 0) - ok = SDL_TRUE; - } - - /* Right */ - if (!ok) { - left = videodata->ime_rect.x + size.cx; - top = 0; - right = left + size.cx; - bottom = size.cy; - if (right < winw) - ok = SDL_TRUE; - } - - /* Left */ - if (!ok) { - left = videodata->ime_rect.x - size.cx; - top = 0; - right = videodata->ime_rect.x; - bottom = size.cy; - if (right >= 0) - ok = SDL_TRUE; - } - - /* Window too small, show at (0,0) */ - if (!ok) { - left = 0; - top = 0; - right = size.cx; - bottom = size.cy; - } - - videodata->ime_candlistrect.x = left; - videodata->ime_candlistrect.y = top; - videodata->ime_candlistrect.w = right - left; - videodata->ime_candlistrect.h = bottom - top; -} - -static void -IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) -{ - int i, j; - SIZE size = {0}; - SIZE candsizes[MAX_CANDLIST]; - SIZE maxcandsize = {0}; - HBITMAP hbm = NULL; - BYTE *bits = NULL; - const int candcount = SDL_min(SDL_min(MAX_CANDLIST, videodata->ime_candcount), videodata->ime_candpgsize); - SDL_bool vertical = videodata->ime_candvertical; - - const int listborder = 1; - const int listpadding = 0; - const int listbordercolor = RGB(0xB4, 0xC7, 0xAA); - const int listfillcolor = RGB(255, 255, 255); - - const int candborder = 1; - const int candpadding = 0; - const int candmargin = 1; - const COLORREF candbordercolor = RGB(255, 255, 255); - const COLORREF candfillcolor = RGB(255, 255, 255); - const COLORREF candtextcolor = RGB(0, 0, 0); - const COLORREF selbordercolor = RGB(0x84, 0xAC, 0xDD); - const COLORREF selfillcolor = RGB(0xD2, 0xE6, 0xFF); - const COLORREF seltextcolor = RGB(0, 0, 0); - const int horzcandspacing = 5; - - HPEN listpen = listborder != 0 ? CreatePen(PS_SOLID, listborder, listbordercolor) : (HPEN)GetStockObject(NULL_PEN); - HBRUSH listbrush = CreateSolidBrush(listfillcolor); - HPEN candpen = candborder != 0 ? CreatePen(PS_SOLID, candborder, candbordercolor) : (HPEN)GetStockObject(NULL_PEN); - HBRUSH candbrush = CreateSolidBrush(candfillcolor); - HPEN selpen = candborder != 0 ? CreatePen(PS_DOT, candborder, selbordercolor) : (HPEN)GetStockObject(NULL_PEN); - HBRUSH selbrush = CreateSolidBrush(selfillcolor); - HFONT font = CreateFont((int)(1 + videodata->ime_rect.h * 0.75f), 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_SWISS, TEXT("Microsoft Sans Serif")); - - SetBkMode(hdc, TRANSPARENT); - SelectObject(hdc, font); - - for (i = 0; i < candcount; ++i) { - const WCHAR *s = videodata->ime_candidates[i]; - if (!*s) - break; - - GetTextExtentPoint32W(hdc, s, SDL_wcslen(s), &candsizes[i]); - maxcandsize.cx = SDL_max(maxcandsize.cx, candsizes[i].cx); - maxcandsize.cy = SDL_max(maxcandsize.cy, candsizes[i].cy); - - } - if (vertical) { - size.cx = - (listborder * 2) + - (listpadding * 2) + - (candmargin * 2) + - (candborder * 2) + - (candpadding * 2) + - (maxcandsize.cx) - ; - size.cy = - (listborder * 2) + - (listpadding * 2) + - ((candcount + 1) * candmargin) + - (candcount * candborder * 2) + - (candcount * candpadding * 2) + - (candcount * maxcandsize.cy) - ; - } - else { - size.cx = - (listborder * 2) + - (listpadding * 2) + - ((candcount + 1) * candmargin) + - (candcount * candborder * 2) + - (candcount * candpadding * 2) + - ((candcount - 1) * horzcandspacing); - ; - - for (i = 0; i < candcount; ++i) - size.cx += candsizes[i].cx; - - size.cy = - (listborder * 2) + - (listpadding * 2) + - (candmargin * 2) + - (candborder * 2) + - (candpadding * 2) + - (maxcandsize.cy) - ; - } - - bits = StartDrawToBitmap(hdc, &hbm, size.cx, size.cy); - - SelectObject(hdc, listpen); - SelectObject(hdc, listbrush); - DrawRect(hdc, 0, 0, size.cx, size.cy, listborder); - - SelectObject(hdc, candpen); - SelectObject(hdc, candbrush); - SetTextColor(hdc, candtextcolor); - SetBkMode(hdc, TRANSPARENT); - - for (i = 0; i < candcount; ++i) { - const WCHAR *s = videodata->ime_candidates[i]; - int left, top, right, bottom; - if (!*s) - break; - - if (vertical) { - left = listborder + listpadding + candmargin; - top = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * maxcandsize.cy); - right = size.cx - listborder - listpadding - candmargin; - bottom = top + maxcandsize.cy + (candpadding * 2) + (candborder * 2); - } - else { - left = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * horzcandspacing); - - for (j = 0; j < i; ++j) - left += candsizes[j].cx; - - top = listborder + listpadding + candmargin; - right = left + candsizes[i].cx + (candpadding * 2) + (candborder * 2); - bottom = size.cy - listborder - listpadding - candmargin; - } - - if (i == videodata->ime_candsel) { - SelectObject(hdc, selpen); - SelectObject(hdc, selbrush); - SetTextColor(hdc, seltextcolor); - } - else { - SelectObject(hdc, candpen); - SelectObject(hdc, candbrush); - SetTextColor(hdc, candtextcolor); - } - - DrawRect(hdc, left, top, right, bottom, candborder); - ExtTextOutW(hdc, left + candborder + candpadding, top + candborder + candpadding, 0, NULL, s, SDL_wcslen(s), NULL); - } - BitmapToTexture(hbm, bits, size.cx, size.cy, &videodata->ime_candtex); - StopDrawToBitmap(hdc, &hbm); - - DeleteObject(listpen); - DeleteObject(listbrush); - DeleteObject(candpen); - DeleteObject(candbrush); - DeleteObject(selpen); - DeleteObject(selbrush); - DeleteObject(font); - - IME_PositionCandidateList(videodata, size); -} - -static void -IME_Render(SDL_VideoData *videodata) -{ - HDC hdc = CreateCompatibleDC(NULL); - - if (videodata->ime_candlist) - IME_RenderCandidateList(videodata, hdc); - - DeleteDC(hdc); - - videodata->ime_dirty = SDL_FALSE; -} - -void IME_Present(SDL_VideoData *videodata) -{ - if (videodata->ime_dirty) - IME_Render(videodata); - - SDL_RenderCopy(videodata->ime_candtex, NULL, &videodata->ime_candlistrect); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32keyboard.h --- a/src/video/win32/SDL_win32keyboard.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_win32keyboard_h -#define _SDL_win32keyboard_h - -extern BYTE alpha_scancodes[26]; -extern BYTE keypad_scancodes[10]; - -extern void WIN_InitKeyboard(_THIS); -extern void WIN_UpdateKeymap(void); -extern void WIN_QuitKeyboard(_THIS); - -extern void WIN_StartTextInput(_THIS); -extern void WIN_StopTextInput(_THIS); -extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect); - -extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata); - -#endif /* _SDL_win32keyboard_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32modes.c --- a/src/video/win32/SDL_win32modes.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,287 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#include "SDL_win32video.h" - - -static SDL_bool -WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) -{ - SDL_DisplayModeData *data; - DEVMODE devmode; - HDC hdc; - - devmode.dmSize = sizeof(devmode); - devmode.dmDriverExtra = 0; - if (!EnumDisplaySettings(deviceName, index, &devmode)) { - return SDL_FALSE; - } - - data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data)); - if (!data) { - return SDL_FALSE; - } - data->DeviceMode = devmode; - data->DeviceMode.dmFields = - (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY | - DM_DISPLAYFLAGS); - - /* Fill in the mode information */ - mode->format = SDL_PIXELFORMAT_UNKNOWN; - mode->w = devmode.dmPelsWidth; - mode->h = devmode.dmPelsHeight; - mode->refresh_rate = devmode.dmDisplayFrequency; - mode->driverdata = data; -#ifdef _WIN32_WCE - /* In WinCE EnumDisplaySettings(ENUM_CURRENT_SETTINGS) doesn't take the user defined orientation - into account but GetSystemMetrics does. */ - if (index == ENUM_CURRENT_SETTINGS) { - mode->w = GetSystemMetrics(SM_CXSCREEN); - mode->h = GetSystemMetrics(SM_CYSCREEN); - } -#endif - -/* WinCE has no GetDIBits, therefore we can't use it to get the display format */ -#ifndef _WIN32_WCE - if (index == ENUM_CURRENT_SETTINGS - && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) { - char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)]; - LPBITMAPINFO bmi; - HBITMAP hbm; - - SDL_zero(bmi_data); - bmi = (LPBITMAPINFO) bmi_data; - bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - - hbm = CreateCompatibleBitmap(hdc, 1, 1); - GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS); - GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS); - DeleteObject(hbm); - DeleteDC(hdc); - if (bmi->bmiHeader.biCompression == BI_BITFIELDS) { - switch (*(Uint32 *) bmi->bmiColors) { - case 0x00FF0000: - mode->format = SDL_PIXELFORMAT_RGB888; - break; - case 0x000000FF: - mode->format = SDL_PIXELFORMAT_BGR888; - break; - case 0xF800: - mode->format = SDL_PIXELFORMAT_RGB565; - break; - case 0x7C00: - mode->format = SDL_PIXELFORMAT_RGB555; - break; - } - } else if (bmi->bmiHeader.biBitCount == 8) { - mode->format = SDL_PIXELFORMAT_INDEX8; - } else if (bmi->bmiHeader.biBitCount == 4) { - mode->format = SDL_PIXELFORMAT_INDEX4LSB; - } - } else -#endif /* _WIN32_WCE */ - { - /* FIXME: Can we tell what this will be? */ - if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) { - switch (devmode.dmBitsPerPel) { - case 32: - mode->format = SDL_PIXELFORMAT_RGB888; - break; - case 24: - mode->format = SDL_PIXELFORMAT_RGB24; - break; - case 16: - mode->format = SDL_PIXELFORMAT_RGB565; - break; - case 15: - mode->format = SDL_PIXELFORMAT_RGB555; - break; - case 8: - mode->format = SDL_PIXELFORMAT_INDEX8; - break; - case 4: - mode->format = SDL_PIXELFORMAT_INDEX4LSB; - break; - } - } - } - return SDL_TRUE; -} - -static SDL_bool -WIN_AddDisplay(LPTSTR DeviceName) -{ - SDL_VideoDisplay display; - SDL_DisplayData *displaydata; - SDL_DisplayMode mode; - -#ifdef DEBUG_MODES - printf("Display: %s\n", WIN_StringToUTF8(DeviceName)); -#endif - if (!WIN_GetDisplayMode(DeviceName, ENUM_CURRENT_SETTINGS, &mode)) { - return SDL_FALSE; - } - - displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata)); - if (!displaydata) { - return SDL_FALSE; - } - SDL_memcpy(displaydata->DeviceName, DeviceName, - sizeof(displaydata->DeviceName)); - - SDL_zero(display); - display.desktop_mode = mode; - display.current_mode = mode; - display.driverdata = displaydata; - SDL_AddVideoDisplay(&display); - return SDL_TRUE; -} - -int -WIN_InitModes(_THIS) -{ - DWORD i, j, count; - DISPLAY_DEVICE device; - - device.cb = sizeof(device); - for (i = 0;; ++i) { - TCHAR DeviceName[32]; - - if (!EnumDisplayDevices(NULL, i, &device, 0)) { - break; - } - if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { - continue; - } - SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName)); -#ifdef DEBUG_MODES - printf("Device: %s\n", WIN_StringToUTF8(DeviceName)); -#endif - count = 0; - for (j = 0;; ++j) { - if (!EnumDisplayDevices(DeviceName, j, &device, 0)) { - break; - } - if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { - continue; - } - count += WIN_AddDisplay(device.DeviceName); - } - if (count == 0) { - WIN_AddDisplay(DeviceName); - } - } - if (_this->num_displays == 0) { - SDL_SetError("No displays available"); - return -1; - } - return 0; -} - -int -WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) -{ - SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->desktop_mode.driverdata; - -#ifdef _WIN32_WCE - // WINCE: DEVMODE.dmPosition not found, or may be mingw32ce bug - rect->x = 0; - rect->y = 0; - rect->w = display->windows->w; - rect->h = display->windows->h; -#else - rect->x = (int)data->DeviceMode.dmPosition.x; - rect->y = (int)data->DeviceMode.dmPosition.y; - rect->w = data->DeviceMode.dmPelsWidth; - rect->h = data->DeviceMode.dmPelsHeight; -#endif - return 0; -} - -void -WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display) -{ - SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; - DWORD i; - SDL_DisplayMode mode; - - for (i = 0;; ++i) { - if (!WIN_GetDisplayMode(data->DeviceName, i, &mode)) { - break; - } - if (mode.format != SDL_PIXELFORMAT_UNKNOWN) { - if (!SDL_AddDisplayMode(display, &mode)) { - SDL_free(mode.driverdata); - } - } - } -} - -int -WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) -{ - SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; - SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata; - LONG status; - -#ifdef _WIN32_WCE - /* TODO: implement correctly. - On my Asus MyPAL, if I execute the code below - I get DISP_CHANGE_BADFLAGS and the Titlebar of the fullscreen window stays - visible ... (SDL_RaiseWindow() would fix that one) */ - return 0; -#endif - - status = - ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode, - NULL, CDS_FULLSCREEN, NULL); - if (status == DISP_CHANGE_SUCCESSFUL) { - return 0; - } else { - const char *reason = "Unknown reason"; - switch (status) { - case DISP_CHANGE_BADFLAGS: - reason = "DISP_CHANGE_BADFLAGS"; - break; - case DISP_CHANGE_BADMODE: - reason = "DISP_CHANGE_BADMODE"; - break; - case DISP_CHANGE_BADPARAM: - reason = "DISP_CHANGE_BADPARAM"; - break; - case DISP_CHANGE_FAILED: - reason = "DISP_CHANGE_FAILED"; - break; - } - SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason); - return -1; - } -} - -void -WIN_QuitModes(_THIS) -{ - ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32modes.h --- a/src/video/win32/SDL_win32modes.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_win32modes_h -#define _SDL_win32modes_h - -typedef struct -{ - TCHAR DeviceName[32]; -} SDL_DisplayData; - -typedef struct -{ - DEVMODE DeviceMode; -} SDL_DisplayModeData; - -extern int WIN_InitModes(_THIS); -extern int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); -extern void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display); -extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); -extern void WIN_QuitModes(_THIS); - -#endif /* _SDL_win32modes_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32mouse.c --- a/src/video/win32/SDL_win32mouse.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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 -*/ - -/* we need to define it, so that raw input is included*/ - -#if (_WIN32_WINNT < 0x0501) -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0501 -#endif - -#include "SDL_config.h" - -#include "SDL_win32video.h" - -void -WIN_InitMouse(_THIS) -{ -} - -void -WIN_QuitMouse(_THIS) -{ -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32mouse.h --- a/src/video/win32/SDL_win32mouse.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_win32mouse_h -#define _SDL_win32mouse_h - -extern void WIN_InitMouse(_THIS); -extern void WIN_QuitMouse(_THIS); - -#endif /* _SDL_win32mouse_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32opengl.c --- a/src/video/win32/SDL_win32opengl.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,612 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#include "SDL_win32video.h" - -/* WGL implementation of SDL OpenGL support */ - -#if SDL_VIDEO_OPENGL_WGL -#include "SDL_opengl.h" - -#define DEFAULT_OPENGL "OPENGL32.DLL" - -#ifndef WGL_ARB_create_context -#define WGL_ARB_create_context -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 -#define WGL_CONTEXT_FLAGS_ARB 0x2093 -#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 -#endif - -typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, - HGLRC - hShareContext, - const int - *attribList); - -int -WIN_GL_LoadLibrary(_THIS, const char *path) -{ - LPTSTR wpath; - HANDLE handle; - - if (path == NULL) { - path = SDL_getenv("SDL_OPENGL_LIBRARY"); - } - if (path == NULL) { - path = DEFAULT_OPENGL; - } - wpath = WIN_UTF8ToString(path); - _this->gl_config.dll_handle = LoadLibrary(wpath); - SDL_free(wpath); - if (!_this->gl_config.dll_handle) { - char message[1024]; - SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")", - path); - WIN_SetError(message); - return -1; - } - SDL_strlcpy(_this->gl_config.driver_path, path, - SDL_arraysize(_this->gl_config.driver_path)); - - /* Allocate OpenGL memory */ - _this->gl_data = - (struct SDL_GLDriverData *) SDL_calloc(1, - sizeof(struct - SDL_GLDriverData)); - if (!_this->gl_data) { - SDL_OutOfMemory(); - return -1; - } - - /* Load function pointers */ - handle = _this->gl_config.dll_handle; - _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *)) - GetProcAddress(handle, "wglGetProcAddress"); - _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC)) - GetProcAddress(handle, "wglCreateContext"); - _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC)) - GetProcAddress(handle, "wglDeleteContext"); - _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC)) - GetProcAddress(handle, "wglMakeCurrent"); - _this->gl_data->wglSwapIntervalEXT = (void (WINAPI *) (int)) - GetProcAddress(handle, "wglSwapIntervalEXT"); - _this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *) (void)) - GetProcAddress(handle, "wglGetSwapIntervalEXT"); - - if (!_this->gl_data->wglGetProcAddress || - !_this->gl_data->wglCreateContext || - !_this->gl_data->wglDeleteContext || - !_this->gl_data->wglMakeCurrent) { - SDL_SetError("Could not retrieve OpenGL functions"); - FreeLibrary(handle); - return -1; - } - - return 0; -} - -void * -WIN_GL_GetProcAddress(_THIS, const char *proc) -{ - void *func; - - /* This is to pick up extensions */ - func = _this->gl_data->wglGetProcAddress(proc); - if (!func) { - /* This is probably a normal GL function */ - func = GetProcAddress(_this->gl_config.dll_handle, proc); - } - return func; -} - -void -WIN_GL_UnloadLibrary(_THIS) -{ - FreeLibrary((HMODULE) _this->gl_config.dll_handle); - _this->gl_config.dll_handle = NULL; - - /* Free OpenGL memory */ - SDL_free(_this->gl_data); - _this->gl_data = NULL; -} - -static void -WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd) -{ - SDL_zerop(pfd); - pfd->nSize = sizeof(*pfd); - pfd->nVersion = 1; - pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL); - if (_this->gl_config.double_buffer) { - pfd->dwFlags |= PFD_DOUBLEBUFFER; - } - if (_this->gl_config.stereo) { - pfd->dwFlags |= PFD_STEREO; - } - pfd->iLayerType = PFD_MAIN_PLANE; - pfd->iPixelType = PFD_TYPE_RGBA; - pfd->cRedBits = _this->gl_config.red_size; - pfd->cGreenBits = _this->gl_config.green_size; - pfd->cBlueBits = _this->gl_config.blue_size; - pfd->cAlphaBits = _this->gl_config.alpha_size; - if (_this->gl_config.buffer_size) { - pfd->cColorBits = - _this->gl_config.buffer_size - _this->gl_config.alpha_size; - } else { - pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits); - } - pfd->cAccumRedBits = _this->gl_config.accum_red_size; - pfd->cAccumGreenBits = _this->gl_config.accum_green_size; - pfd->cAccumBlueBits = _this->gl_config.accum_blue_size; - pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size; - pfd->cAccumBits = - (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits + - pfd->cAccumAlphaBits); - pfd->cDepthBits = _this->gl_config.depth_size; - pfd->cStencilBits = _this->gl_config.stencil_size; -} - -/* Choose the closest pixel format that meets or exceeds the target. - FIXME: Should we weight any particular attribute over any other? -*/ -static int -WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target) -{ - PIXELFORMATDESCRIPTOR pfd; - int count, index, best = 0; - unsigned int dist, best_dist = ~0U; - - count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL); - - for (index = 1; index <= count; index++) { - - if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) { - continue; - } - - if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) { - continue; - } - - if (pfd.iLayerType != target->iLayerType) { - continue; - } - if (pfd.iPixelType != target->iPixelType) { - continue; - } - - dist = 0; - - if (pfd.cColorBits < target->cColorBits) { - continue; - } else { - dist += (pfd.cColorBits - target->cColorBits); - } - if (pfd.cRedBits < target->cRedBits) { - continue; - } else { - dist += (pfd.cRedBits - target->cRedBits); - } - if (pfd.cGreenBits < target->cGreenBits) { - continue; - } else { - dist += (pfd.cGreenBits - target->cGreenBits); - } - if (pfd.cBlueBits < target->cBlueBits) { - continue; - } else { - dist += (pfd.cBlueBits - target->cBlueBits); - } - if (pfd.cAlphaBits < target->cAlphaBits) { - continue; - } else { - dist += (pfd.cAlphaBits - target->cAlphaBits); - } - if (pfd.cAccumBits < target->cAccumBits) { - continue; - } else { - dist += (pfd.cAccumBits - target->cAccumBits); - } - if (pfd.cAccumRedBits < target->cAccumRedBits) { - continue; - } else { - dist += (pfd.cAccumRedBits - target->cAccumRedBits); - } - if (pfd.cAccumGreenBits < target->cAccumGreenBits) { - continue; - } else { - dist += (pfd.cAccumGreenBits - target->cAccumGreenBits); - } - if (pfd.cAccumBlueBits < target->cAccumBlueBits) { - continue; - } else { - dist += (pfd.cAccumBlueBits - target->cAccumBlueBits); - } - if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) { - continue; - } else { - dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits); - } - if (pfd.cDepthBits < target->cDepthBits) { - continue; - } else { - dist += (pfd.cDepthBits - target->cDepthBits); - } - if (pfd.cStencilBits < target->cStencilBits) { - continue; - } else { - dist += (pfd.cStencilBits - target->cStencilBits); - } - - if (dist < best_dist) { - best = index; - best_dist = dist; - } - } - - return best; -} - -static SDL_bool -HasExtension(const char *extension, const char *extensions) -{ - const char *start; - const char *where, *terminator; - - /* Extension names should not have spaces. */ - where = SDL_strchr(extension, ' '); - if (where || *extension == '\0') - return SDL_FALSE; - - if (!extensions) - return SDL_FALSE; - - /* It takes a bit of care to be fool-proof about parsing the - * OpenGL extensions string. Don't be fooled by sub-strings, - * etc. */ - - start = extensions; - - for (;;) { - where = SDL_strstr(start, extension); - if (!where) - break; - - terminator = where + SDL_strlen(extension); - if (where == start || *(where - 1) == ' ') - if (*terminator == ' ' || *terminator == '\0') - return SDL_TRUE; - - start = terminator; - } - return SDL_FALSE; -} - -static void -WIN_GL_InitExtensions(_THIS, HDC hdc) -{ - const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0; - const char *extensions; - - wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC)) - _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB"); - if (wglGetExtensionsStringARB) { - extensions = wglGetExtensionsStringARB(hdc); - } else { - extensions = NULL; - } - - /* Check for WGL_ARB_pixel_format */ - _this->gl_data->WGL_ARB_pixel_format = 0; - if (HasExtension("WGL_ARB_pixel_format", extensions)) { - _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *) - (HDC, const int *, - const FLOAT *, UINT, - int *, UINT *)) - WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB"); - _this->gl_data->wglGetPixelFormatAttribivARB = - (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *)) - WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB"); - - if ((_this->gl_data->wglChoosePixelFormatARB != NULL) && - (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) { - _this->gl_data->WGL_ARB_pixel_format = 1; - } - } - - /* Check for WGL_EXT_swap_control */ - if (HasExtension("WGL_EXT_swap_control", extensions)) { - _this->gl_data->wglSwapIntervalEXT = - WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT"); - _this->gl_data->wglGetSwapIntervalEXT = - WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT"); - } else { - _this->gl_data->wglSwapIntervalEXT = NULL; - _this->gl_data->wglGetSwapIntervalEXT = NULL; - } -} - -static int -WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs) -{ - HWND hwnd; - HDC hdc; - PIXELFORMATDESCRIPTOR pfd; - HGLRC hglrc; - int pixel_format = 0; - unsigned int matching; - - hwnd = - CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0, - 10, 10, NULL, NULL, SDL_Instance, NULL); - WIN_PumpEvents(_this); - - hdc = GetDC(hwnd); - - WIN_GL_SetupPixelFormat(_this, &pfd); - - SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd); - - hglrc = _this->gl_data->wglCreateContext(hdc); - if (hglrc) { - _this->gl_data->wglMakeCurrent(hdc, hglrc); - - WIN_GL_InitExtensions(_this, hdc); - - if (_this->gl_data->WGL_ARB_pixel_format) { - _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, - 1, &pixel_format, - &matching); - } - - _this->gl_data->wglMakeCurrent(NULL, NULL); - _this->gl_data->wglDeleteContext(hglrc); - } - ReleaseDC(hwnd, hdc); - DestroyWindow(hwnd); - WIN_PumpEvents(_this); - - return pixel_format; -} - -int -WIN_GL_SetupWindow(_THIS, SDL_Window * window) -{ - HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; - PIXELFORMATDESCRIPTOR pfd; - int pixel_format; - int iAttribs[64]; - int *iAttr; - float fAttribs[1] = { 0 }; - - WIN_GL_SetupPixelFormat(_this, &pfd); - - /* setup WGL_ARB_pixel_format attribs */ - iAttr = &iAttribs[0]; - - *iAttr++ = WGL_DRAW_TO_WINDOW_ARB; - *iAttr++ = GL_TRUE; - *iAttr++ = WGL_ACCELERATION_ARB; - *iAttr++ = WGL_FULL_ACCELERATION_ARB; - *iAttr++ = WGL_RED_BITS_ARB; - *iAttr++ = _this->gl_config.red_size; - *iAttr++ = WGL_GREEN_BITS_ARB; - *iAttr++ = _this->gl_config.green_size; - *iAttr++ = WGL_BLUE_BITS_ARB; - *iAttr++ = _this->gl_config.blue_size; - - if (_this->gl_config.alpha_size) { - *iAttr++ = WGL_ALPHA_BITS_ARB; - *iAttr++ = _this->gl_config.alpha_size; - } - - *iAttr++ = WGL_DOUBLE_BUFFER_ARB; - *iAttr++ = _this->gl_config.double_buffer; - - *iAttr++ = WGL_DEPTH_BITS_ARB; - *iAttr++ = _this->gl_config.depth_size; - - if (_this->gl_config.stencil_size) { - *iAttr++ = WGL_STENCIL_BITS_ARB; - *iAttr++ = _this->gl_config.stencil_size; - } - - if (_this->gl_config.accum_red_size) { - *iAttr++ = WGL_ACCUM_RED_BITS_ARB; - *iAttr++ = _this->gl_config.accum_red_size; - } - - if (_this->gl_config.accum_green_size) { - *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB; - *iAttr++ = _this->gl_config.accum_green_size; - } - - if (_this->gl_config.accum_blue_size) { - *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB; - *iAttr++ = _this->gl_config.accum_blue_size; - } - - if (_this->gl_config.accum_alpha_size) { - *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB; - *iAttr++ = _this->gl_config.accum_alpha_size; - } - - if (_this->gl_config.stereo) { - *iAttr++ = WGL_STEREO_ARB; - *iAttr++ = GL_TRUE; - } - - if (_this->gl_config.multisamplebuffers) { - *iAttr++ = WGL_SAMPLE_BUFFERS_ARB; - *iAttr++ = _this->gl_config.multisamplebuffers; - } - - if (_this->gl_config.multisamplesamples) { - *iAttr++ = WGL_SAMPLES_ARB; - *iAttr++ = _this->gl_config.multisamplesamples; - } - - if (_this->gl_config.accelerated >= 0) { - *iAttr++ = WGL_ACCELERATION_ARB; - *iAttr++ = - (_this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : - WGL_NO_ACCELERATION_ARB); - } - - *iAttr = 0; - - /* Choose and set the closest available pixel format */ - pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs); - if (!pixel_format) { - pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd); - } - if (!pixel_format) { - SDL_SetError("No matching GL pixel format available"); - return -1; - } - if (!SetPixelFormat(hdc, pixel_format, &pfd)) { - WIN_SetError("SetPixelFormat()"); - return (-1); - } - return 0; -} - -SDL_GLContext -WIN_GL_CreateContext(_THIS, SDL_Window * window) -{ - HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; - HGLRC context; - - if (_this->gl_config.major_version < 3) { - context = _this->gl_data->wglCreateContext(hdc); - } else { - PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; - HGLRC temp_context = _this->gl_data->wglCreateContext(hdc); - if (!temp_context) { - SDL_SetError("Could not create GL context"); - return NULL; - } - - /* Make the context current */ - if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) { - WIN_GL_DeleteContext(_this, temp_context); - return NULL; - } - - wglCreateContextAttribsARB = - (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data-> - wglGetProcAddress("wglCreateContextAttribsARB"); - if (!wglCreateContextAttribsARB) { - SDL_SetError("GL 3.x is not supported"); - context = temp_context; - } else { - int attribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version, - WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version, - 0 - }; - /* Create the GL 3.x context */ - context = wglCreateContextAttribsARB(hdc, 0, attribs); - /* Delete the GL 2.x context */ - _this->gl_data->wglDeleteContext(temp_context); - } - } - - if (!context) { - WIN_SetError("Could not create GL context"); - return NULL; - } - - if (WIN_GL_MakeCurrent(_this, window, context) < 0) { - WIN_GL_DeleteContext(_this, context); - return NULL; - } - - WIN_GL_InitExtensions(_this, hdc); - - return context; -} - -int -WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) -{ - HDC hdc; - int status; - - if (window) { - hdc = ((SDL_WindowData *) window->driverdata)->hdc; - } else { - hdc = NULL; - } - if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) { - WIN_SetError("wglMakeCurrent()"); - status = -1; - } else { - status = 0; - } - return status; -} - -int -WIN_GL_SetSwapInterval(_THIS, int interval) -{ - if (_this->gl_data->wglSwapIntervalEXT) { - _this->gl_data->wglSwapIntervalEXT(interval); - return 0; - } else { - SDL_Unsupported(); - return -1; - } -} - -int -WIN_GL_GetSwapInterval(_THIS) -{ - if (_this->gl_data->wglGetSwapIntervalEXT) { - return _this->gl_data->wglGetSwapIntervalEXT(); - } else { - SDL_Unsupported(); - return -1; - } -} - -void -WIN_GL_SwapWindow(_THIS, SDL_Window * window) -{ - HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; - - SwapBuffers(hdc); -} - -void -WIN_GL_DeleteContext(_THIS, SDL_GLContext context) -{ - _this->gl_data->wglDeleteContext((HGLRC) context); -} - -#endif /* SDL_VIDEO_OPENGL_WGL */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32opengl.h --- a/src/video/win32/SDL_win32opengl.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_win32opengl_h -#define _SDL_win32opengl_h - -#if SDL_VIDEO_OPENGL_WGL - -struct SDL_GLDriverData -{ - int WGL_ARB_pixel_format; - - void *(WINAPI * wglGetProcAddress) (const char *proc); - HGLRC(WINAPI * wglCreateContext) (HDC hdc); - BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc); - BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc); - BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc, - const int *piAttribIList, - const FLOAT * pfAttribFList, - UINT nMaxFormats, - int *piFormats, - UINT * nNumFormats); - BOOL(WINAPI * wglGetPixelFormatAttribivARB) (HDC hdc, int iPixelFormat, - int iLayerPlane, - UINT nAttributes, - const int *piAttributes, - int *piValues); - void (WINAPI * wglSwapIntervalEXT) (int interval); - int (WINAPI * wglGetSwapIntervalEXT) (void); -}; - -/* OpenGL functions */ -extern int WIN_GL_LoadLibrary(_THIS, const char *path); -extern void *WIN_GL_GetProcAddress(_THIS, const char *proc); -extern void WIN_GL_UnloadLibrary(_THIS); -extern int WIN_GL_SetupWindow(_THIS, SDL_Window * window); -extern SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window * window); -extern int WIN_GL_MakeCurrent(_THIS, SDL_Window * window, - SDL_GLContext context); -extern int WIN_GL_SetSwapInterval(_THIS, int interval); -extern int WIN_GL_GetSwapInterval(_THIS); -extern void WIN_GL_SwapWindow(_THIS, SDL_Window * window); -extern void WIN_GL_DeleteContext(_THIS, SDL_GLContext context); - -#ifndef WGL_ARB_pixel_format -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -#endif - -#ifndef WGL_ARB_multisample -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 -#endif - -#endif /* SDL_VIDEO_OPENGL_WGL */ - -#endif /* _SDL_win32opengl_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32shape.c --- a/src/video/win32/SDL_win32shape.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 2010 Eli Gottlieb - - 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 - - Eli Gottlieb - eligottlieb@gmail.com -*/ - -#include -#include "SDL_assert.h" -#include "SDL_win32shape.h" -#include "SDL_win32video.h" - -SDL_WindowShaper* -Win32_CreateShaper(SDL_Window * window) { - int resized_properly; - SDL_WindowShaper* result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper)); - result->window = window; - result->mode.mode = ShapeModeDefault; - result->mode.parameters.binarizationCutoff = 1; - result->userx = result->usery = 0; - result->driverdata = (SDL_ShapeData*)SDL_malloc(sizeof(SDL_ShapeData)); - ((SDL_ShapeData*)result->driverdata)->mask_tree = NULL; - //Put some driver-data here. - window->shaper = result; - resized_properly = Win32_ResizeWindowShape(window); - if (resized_properly != 0) - return NULL; - - return result; -} - -void -CombineRectRegions(SDL_ShapeTree* node,void* closure) { - HRGN mask_region = *((HRGN*)closure),temp_region = NULL; - if(node->kind == OpaqueShape) { - //Win32 API regions exclude their outline, so we widen the region by one pixel in each direction to include the real outline. - temp_region = CreateRectRgn(node->data.shape.x,node->data.shape.y,node->data.shape.x + node->data.shape.w + 1,node->data.shape.y + node->data.shape.h + 1); - if(mask_region != NULL) { - CombineRgn(mask_region,mask_region,temp_region,RGN_OR); - DeleteObject(temp_region); - } - else - *((HRGN*)closure) = temp_region; - } -} - -int -Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { - SDL_ShapeData *data; - HRGN mask_region = NULL; - - if (shaper == NULL || shape == NULL) - return SDL_INVALID_SHAPE_ARGUMENT; - if(shape->format->Amask == 0 && shape_mode->mode != ShapeModeColorKey || shape->w != shaper->window->w || shape->h != shaper->window->h) - return SDL_INVALID_SHAPE_ARGUMENT; - - data = (SDL_ShapeData*)shaper->driverdata; - if(data->mask_tree != NULL) - SDL_FreeShapeTree(&data->mask_tree); - data->mask_tree = SDL_CalculateShapeTree(*shape_mode,shape); - - SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&mask_region); - SDL_assert(mask_region != NULL); - - SetWindowRgn(((SDL_WindowData *)(shaper->window->driverdata))->hwnd, mask_region, TRUE); - - return 0; -} - -int -Win32_ResizeWindowShape(SDL_Window *window) { - SDL_ShapeData* data; - - if (window == NULL) - return -1; - data = (SDL_ShapeData *)window->shaper->driverdata; - if (data == NULL) - return -1; - - if(data->mask_tree != NULL) - SDL_FreeShapeTree(&data->mask_tree); - if(window->shaper->hasshape == SDL_TRUE) { - window->shaper->userx = window->x; - window->shaper->usery = window->y; - SDL_SetWindowPosition(window,-1000,-1000); - } - - return 0; -} diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32shape.h --- a/src/video/win32/SDL_win32shape.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 2010 Eli Gottlieb - - 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 - - Eli Gottlieb - eligottlieb@gmail.com -*/ - -#include "SDL_config.h" - -#ifndef _SDL_win32shape_h -#define _SDL_win32shape_h - -#include "SDL_video.h" -#include "SDL_shape.h" -#include "../SDL_sysvideo.h" -#include "../SDL_shape_internals.h" - -typedef struct { - SDL_ShapeTree *mask_tree; -} SDL_ShapeData; - -extern SDL_WindowShaper* Win32_CreateShaper(SDL_Window * window); -extern int Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); -extern int Win32_ResizeWindowShape(SDL_Window *window); - -#endif /* _SDL_win32shape_h */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32video.c --- a/src/video/win32/SDL_win32video.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,266 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#include "SDL_main.h" -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" - -#include "SDL_win32video.h" -#include "SDL_win32shape.h" -#include "SDL_d3drender.h" -#include "SDL_gdirender.h" -#include "SDL_gapirender.h" - -/* Initialization/Query functions */ -static int WIN_VideoInit(_THIS); -static void WIN_VideoQuit(_THIS); - -/* Sets an error message based on GetLastError() */ -void -WIN_SetError(const char *prefix) -{ - TCHAR buffer[1024]; - char *message; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, - buffer, SDL_arraysize(buffer), NULL); - message = WIN_StringToUTF8(buffer); - SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message); - SDL_free(message); -} - - -/* WIN32 driver bootstrap functions */ - -static int -WIN_Available(void) -{ - return (1); -} - -static void -WIN_DeleteDevice(SDL_VideoDevice * device) -{ - SDL_VideoData *data = (SDL_VideoData *) device->driverdata; - - SDL_UnregisterApp(); -#if SDL_VIDEO_RENDER_D3D - if (data->d3d) { - IDirect3D9_Release(data->d3d); - FreeLibrary(data->d3dDLL); - } -#endif -#if SDL_VIDEO_RENDER_DDRAW - if (data->ddraw) { - data->ddraw->lpVtbl->Release(data->ddraw); - FreeLibrary(data->ddrawDLL); - } -#endif -#ifdef _WIN32_WCE - if(data->hAygShell) { - FreeLibrary(data->hAygShell); - } -#endif - if (data->userDLL) { - FreeLibrary(data->userDLL); - } - - SDL_free(device->driverdata); - SDL_free(device); -} - -static SDL_VideoDevice * -WIN_CreateDevice(int devindex) -{ - SDL_VideoDevice *device; - SDL_VideoData *data; - - SDL_RegisterApp(NULL, 0, NULL); - - /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (device) { - data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); - } else { - data = NULL; - } - if (!data) { - SDL_OutOfMemory(); - if (device) { - SDL_free(device); - } - return NULL; - } - device->driverdata = data; - -#if SDL_VIDEO_RENDER_D3D - data->d3dDLL = LoadLibrary(TEXT("D3D9.DLL")); - if (data->d3dDLL) { - IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion); - - D3DCreate = - (IDirect3D9 * (WINAPI *) (UINT)) GetProcAddress(data->d3dDLL, - "Direct3DCreate9"); - if (D3DCreate) { - data->d3d = D3DCreate(D3D_SDK_VERSION); - } - if (!data->d3d) { - FreeLibrary(data->d3dDLL); - data->d3dDLL = NULL; - } - } -#endif /* SDL_VIDEO_RENDER_D3D */ -#if SDL_VIDEO_RENDER_DDRAW - data->ddrawDLL = LoadLibrary(TEXT("ddraw.dll")); - if (data->ddrawDLL) { - IDirectDraw *(WINAPI * DDCreate) (GUID FAR * lpGUID, - LPDIRECTDRAW FAR * lplpDD, - IUnknown FAR * pUnkOuter); - - DDCreate = - (IDirectDraw * - (WINAPI *) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *)) - GetProcAddress(data->ddrawDLL, TEXT("DirectDrawCreate")); - if (!DDCreate || DDCreate(NULL, &data->ddraw, NULL) != DD_OK) { - FreeLibrary(data->ddrawDLL); - data->ddrawDLL = NULL; - data->ddraw = NULL; - } - } -#endif /* SDL_VIDEO_RENDER_DDRAW */ - -#ifdef _WIN32_WCE - data->hAygShell = LoadLibrary(TEXT("\\windows\\aygshell.dll")); - if(0 == data->hAygShell) - data->hAygShell = LoadLibrary(TEXT("aygshell.dll")); - data->SHFullScreen = (0 != data->hAygShell ? - (PFNSHFullScreen) GetProcAddress(data->hAygShell, TEXT("SHFullScreen")) : 0); - data->CoordTransform = NULL; -#endif - - data->userDLL = LoadLibrary(TEXT("USER32.DLL")); - if (data->userDLL) { - data->CloseTouchInputHandle = (BOOL (WINAPI *)( HTOUCHINPUT )) GetProcAddress(data->userDLL, "CloseTouchInputHandle"); - data->GetTouchInputInfo = (BOOL (WINAPI *)( HTOUCHINPUT, UINT, PTOUCHINPUT, int )) GetProcAddress(data->userDLL, "GetTouchInputInfo"); - data->RegisterTouchWindow = (BOOL (WINAPI *)( HWND, ULONG )) GetProcAddress(data->userDLL, "RegisterTouchWindow"); - } - - /* Set the function pointers */ - device->VideoInit = WIN_VideoInit; - device->VideoQuit = WIN_VideoQuit; - device->GetDisplayBounds = WIN_GetDisplayBounds; - device->GetDisplayModes = WIN_GetDisplayModes; - device->SetDisplayMode = WIN_SetDisplayMode; - device->SetDisplayGammaRamp = WIN_SetDisplayGammaRamp; - device->GetDisplayGammaRamp = WIN_GetDisplayGammaRamp; - device->PumpEvents = WIN_PumpEvents; - -#undef CreateWindow - device->CreateWindow = WIN_CreateWindow; - device->CreateWindowFrom = WIN_CreateWindowFrom; - device->SetWindowTitle = WIN_SetWindowTitle; - device->SetWindowIcon = WIN_SetWindowIcon; - device->SetWindowPosition = WIN_SetWindowPosition; - device->SetWindowSize = WIN_SetWindowSize; - device->ShowWindow = WIN_ShowWindow; - device->HideWindow = WIN_HideWindow; - device->RaiseWindow = WIN_RaiseWindow; - device->MaximizeWindow = WIN_MaximizeWindow; - device->MinimizeWindow = WIN_MinimizeWindow; - device->RestoreWindow = WIN_RestoreWindow; - device->SetWindowGrab = WIN_SetWindowGrab; - device->DestroyWindow = WIN_DestroyWindow; - device->GetWindowWMInfo = WIN_GetWindowWMInfo; - - device->shape_driver.CreateShaper = Win32_CreateShaper; - device->shape_driver.SetWindowShape = Win32_SetWindowShape; - device->shape_driver.ResizeWindowShape = Win32_ResizeWindowShape; - -#ifdef SDL_VIDEO_OPENGL_WGL - device->GL_LoadLibrary = WIN_GL_LoadLibrary; - device->GL_GetProcAddress = WIN_GL_GetProcAddress; - device->GL_UnloadLibrary = WIN_GL_UnloadLibrary; - device->GL_CreateContext = WIN_GL_CreateContext; - device->GL_MakeCurrent = WIN_GL_MakeCurrent; - device->GL_SetSwapInterval = WIN_GL_SetSwapInterval; - device->GL_GetSwapInterval = WIN_GL_GetSwapInterval; - device->GL_SwapWindow = WIN_GL_SwapWindow; - device->GL_DeleteContext = WIN_GL_DeleteContext; -#endif - device->StartTextInput = WIN_StartTextInput; - device->StopTextInput = WIN_StopTextInput; - device->SetTextInputRect = WIN_SetTextInputRect; - - device->SetClipboardText = WIN_SetClipboardText; - device->GetClipboardText = WIN_GetClipboardText; - device->HasClipboardText = WIN_HasClipboardText; - - device->free = WIN_DeleteDevice; - - return device; -} - -VideoBootStrap WIN32_bootstrap = { -#ifdef _WIN32_WCE - "wince", "SDL WinCE video driver", WINCE_Available, WIN_CreateDevice -#else - "win32", "SDL Win32/64 video driver", WIN_Available, WIN_CreateDevice -#endif -}; - -int -WIN_VideoInit(_THIS) -{ - if (WIN_InitModes(_this) < 0) { - return -1; - } - -#if SDL_VIDEO_RENDER_D3D - D3D_AddRenderDriver(_this); -#endif -#if SDL_VIDEO_RENDER_DDRAW - DDRAW_AddRenderDriver(_this); -#endif -#if SDL_VIDEO_RENDER_GDI - GDI_AddRenderDriver(_this); -#endif -#if SDL_VIDEO_RENDER_GAPI - WINCE_AddRenderDriver(_this); -#endif - - WIN_InitKeyboard(_this); - WIN_InitMouse(_this); - - return 0; -} - -void -WIN_VideoQuit(_THIS) -{ - WIN_QuitModes(_this); - WIN_QuitKeyboard(_this); - WIN_QuitMouse(_this); -} - -/* vim: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32video.h --- a/src/video/win32/SDL_win32video.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,222 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_win32video_h -#define _SDL_win32video_h - -#include "../SDL_sysvideo.h" - -#define WIN32_LEAN_AND_MEAN -#define STRICT -#ifndef UNICODE -#define UNICODE -#endif -#undef WINVER -#define WINVER 0x500 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */ - -#include - -#ifndef __GNUC__ -#include -#else -#include "SDL_msctf.h" -#endif - -#include - -#define MAX_CANDLIST 10 -#define MAX_CANDLENGTH 256 - -#if SDL_VIDEO_RENDER_D3D -//#include -#define D3D_DEBUG_INFO -#include "d3d9.h" -#endif - -#if SDL_VIDEO_RENDER_DDRAW -/* WIN32_LEAN_AND_MEAN was defined, so we have to include this by hand */ -#include -#include "ddraw.h" -#endif - -#include "SDL_win32clipboard.h" -#include "SDL_win32events.h" -#include "SDL_win32gamma.h" -#include "SDL_win32keyboard.h" -#include "SDL_win32modes.h" -#include "SDL_win32mouse.h" -#include "SDL_win32opengl.h" -#include "SDL_win32window.h" -#include "SDL_events.h" - -#ifdef UNICODE -#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UCS-2", (char *)S, (SDL_wcslen(S)+1)*sizeof(WCHAR)) -#define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UCS-2", "UTF-8", (char *)S, SDL_strlen(S)+1) -#else -#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "ASCII", (char *)S, (SDL_strlen(S)+1)) -#define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)S, SDL_strlen(S)+1) -#endif -extern void WIN_SetError(const char *prefix); - -enum { RENDER_NONE, RENDER_D3D, RENDER_DDRAW, RENDER_GDI, RENDER_GAPI, RENDER_RAW }; - -#if WINVER < 0x0601 -/* Touch input definitions */ -#define TWF_FINETOUCH 1 -#define TWF_WANTPALM 2 - -#define TOUCHEVENTF_MOVE 0x0001 -#define TOUCHEVENTF_DOWN 0x0002 -#define TOUCHEVENTF_UP 0x0004 - -DECLARE_HANDLE(HTOUCHINPUT); - -typedef struct _TOUCHINPUT { - LONG x; - LONG y; - HANDLE hSource; - DWORD dwID; - DWORD dwFlags; - DWORD dwMask; - DWORD dwTime; - ULONG_PTR dwExtraInfo; - DWORD cxContact; - DWORD cyContact; -} TOUCHINPUT, *PTOUCHINPUT; - -#endif /* WINVER < 0x0601 */ - -typedef BOOL (*PFNSHFullScreen)(HWND, DWORD); -typedef void (*PFCoordTransform)(SDL_Window*, POINT*); - -typedef struct -{ - void **lpVtbl; - int refcount; - void *data; -} TSFSink; - -/* Definition from Win98DDK version of IMM.H */ -typedef struct tagINPUTCONTEXT2 { - HWND hWnd; - BOOL fOpen; - POINT ptStatusWndPos; - POINT ptSoftKbdPos; - DWORD fdwConversion; - DWORD fdwSentence; - union { - LOGFONTA A; - LOGFONTW W; - } lfFont; - COMPOSITIONFORM cfCompForm; - CANDIDATEFORM cfCandForm[4]; - HIMCC hCompStr; - HIMCC hCandInfo; - HIMCC hGuideLine; - HIMCC hPrivate; - DWORD dwNumMsgBuf; - HIMCC hMsgBuf; - DWORD fdwInit; - DWORD dwReserve[3]; -} INPUTCONTEXT2, *PINPUTCONTEXT2, NEAR *NPINPUTCONTEXT2, FAR *LPINPUTCONTEXT2; - -/* Private display data */ - -typedef struct SDL_VideoData -{ - int render; - -#if SDL_VIDEO_RENDER_D3D - HANDLE d3dDLL; - IDirect3D9 *d3d; -#endif -#if SDL_VIDEO_RENDER_DDRAW - HANDLE ddrawDLL; - IDirectDraw *ddraw; -#endif -#ifdef _WIN32_WCE - HMODULE hAygShell; - PFNSHFullScreen SHFullScreen; - PFCoordTransform CoordTransform; -#endif - - const SDL_scancode *key_layout; - DWORD clipboard_count; - - /* Touch input functions */ - HANDLE userDLL; - BOOL (WINAPI *CloseTouchInputHandle)( HTOUCHINPUT ); - BOOL (WINAPI *GetTouchInputInfo)( HTOUCHINPUT, UINT, PTOUCHINPUT, int ); - BOOL (WINAPI *RegisterTouchWindow)( HWND, ULONG ); - - SDL_bool ime_com_initialized; - struct ITfThreadMgr *ime_threadmgr; - SDL_bool ime_initialized; - SDL_bool ime_enabled; - SDL_bool ime_available; - HWND ime_hwnd_main; - HWND ime_hwnd_current; - HIMC ime_himc; - - WCHAR ime_composition[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; - WCHAR ime_readingstring[16]; - int ime_cursor; - - SDL_bool ime_candlist; - WCHAR ime_candidates[MAX_CANDLIST][MAX_CANDLENGTH]; - DWORD ime_candcount; - DWORD ime_candref; - DWORD ime_candsel; - UINT ime_candpgsize; - int ime_candlistindexbase; - SDL_bool ime_candvertical; - - SDL_Texture *ime_candtex; - SDL_bool ime_dirty; - SDL_Rect ime_rect; - SDL_Rect ime_candlistrect; - int ime_winwidth; - int ime_winheight; - - HKL ime_hkl; - HMODULE ime_himm32; - UINT (WINAPI *GetReadingString)(HIMC himc, UINT uReadingBufLen, LPWSTR lpwReadingBuf, PINT pnErrorIndex, BOOL *pfIsVertical, PUINT puMaxReadingLen); - BOOL (WINAPI *ShowReadingWindow)(HIMC himc, BOOL bShow); - LPINPUTCONTEXT2 (WINAPI *ImmLockIMC)(HIMC himc); - BOOL (WINAPI *ImmUnlockIMC)(HIMC himc); - LPVOID (WINAPI *ImmLockIMCC)(HIMCC himcc); - BOOL (WINAPI *ImmUnlockIMCC)(HIMCC himcc); - - SDL_bool ime_uiless; - struct ITfThreadMgrEx *ime_threadmgrex; - DWORD ime_uielemsinkcookie; - DWORD ime_alpnsinkcookie; - DWORD ime_openmodesinkcookie; - DWORD ime_convmodesinkcookie; - TSFSink *ime_uielemsink; - TSFSink *ime_ippasink; -} SDL_VideoData; - -#endif /* _SDL_win32video_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32window.c --- a/src/video/win32/SDL_win32window.c Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,639 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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" - -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "../../events/SDL_keyboard_c.h" - -#include "SDL_win32video.h" -#include "SDL_win32window.h" - -/* This is included after SDL_win32video.h, which includes windows.h */ -#include "SDL_syswm.h" -#include "SDL_gapirender.h" - - -/* Fake window to help with DirectInput events. */ -HWND SDL_HelperWindow = NULL; -static WCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher"); -static WCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow"); -static ATOM SDL_HelperWindowClass = 0; - -static int -SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created) -{ - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - SDL_VideoDisplay *display = window->display; - SDL_WindowData *data; - - /* Allocate the window data */ - data = (SDL_WindowData *) SDL_malloc(sizeof(*data)); - if (!data) { - SDL_OutOfMemory(); - return -1; - } - data->window = window; - data->hwnd = hwnd; - data->hdc = GetDC(hwnd); - data->created = created; - data->mouse_pressed = SDL_FALSE; - data->videodata = videodata; - - /* Associate the data with the window */ - if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) { - ReleaseDC(hwnd, data->hdc); - SDL_free(data); - WIN_SetError("SetProp() failed"); - return -1; - } - - /* Set up the window proc function */ - data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC); - if (data->wndproc == WIN_WindowProc) { - data->wndproc = NULL; - } - else { - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc); - } - - /* Fill in the SDL window with the window data */ - { - POINT point; - point.x = 0; - point.y = 0; - if (ClientToScreen(hwnd, &point)) { - SDL_Rect bounds; - WIN_GetDisplayBounds(_this, display, &bounds); - window->x = point.x - bounds.x; - window->y = point.y - bounds.y; - } - } - { - RECT rect; - if (GetClientRect(hwnd, &rect)) { - window->w = rect.right; - window->h = rect.bottom; - } - } - { - DWORD style = GetWindowLong(hwnd, GWL_STYLE); - if (style & WS_VISIBLE) { - window->flags |= SDL_WINDOW_SHOWN; - } else { - window->flags &= ~SDL_WINDOW_SHOWN; - } - if (style & (WS_BORDER | WS_THICKFRAME)) { - window->flags &= ~SDL_WINDOW_BORDERLESS; - } else { - window->flags |= SDL_WINDOW_BORDERLESS; - } - if (style & WS_THICKFRAME) { - window->flags |= SDL_WINDOW_RESIZABLE; - } else { - window->flags &= ~SDL_WINDOW_RESIZABLE; - } - if (style & WS_MAXIMIZE) { - window->flags |= SDL_WINDOW_MAXIMIZED; - } else { - window->flags &= ~SDL_WINDOW_MAXIMIZED; - } - if (style & WS_MINIMIZE) { - window->flags |= SDL_WINDOW_MINIMIZED; - } else { - window->flags &= ~SDL_WINDOW_MINIMIZED; - } - } - if (GetFocus() == hwnd) { - window->flags |= SDL_WINDOW_INPUT_FOCUS; - SDL_SetKeyboardFocus(data->window); - - if (window->flags & SDL_WINDOW_INPUT_GRABBED) { - RECT rect; - GetClientRect(hwnd, &rect); - ClientToScreen(hwnd, (LPPOINT) & rect); - ClientToScreen(hwnd, (LPPOINT) & rect + 1); - ClipCursor(&rect); - } - } - - /* Enable multi-touch */ - if (videodata->RegisterTouchWindow) { - videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH|TWF_WANTPALM)); - } - - /* All done! */ - window->driverdata = data; - return 0; -} - -int -WIN_CreateWindow(_THIS, SDL_Window * window) -{ - SDL_VideoDisplay *display = window->display; - HWND hwnd; - RECT rect; - SDL_Rect bounds; - DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN); - int x, y; - int w, h; - - if (window->flags & (SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN)) { - style |= WS_POPUP; - } else { - style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX); - } - if ((window->flags & SDL_WINDOW_RESIZABLE) - && !(window->flags & SDL_WINDOW_FULLSCREEN)) { - style |= (WS_THICKFRAME | WS_MAXIMIZEBOX); - } - - /* Figure out what the window area will be */ - rect.left = 0; - rect.top = 0; - rect.right = window->w; - rect.bottom = window->h; - AdjustWindowRectEx(&rect, style, FALSE, 0); - w = (rect.right - rect.left); - h = (rect.bottom - rect.top); - - WIN_GetDisplayBounds(_this, display, &bounds); - if (window->flags & SDL_WINDOW_FULLSCREEN) { - /* The bounds when this window is visible is the fullscreen mode */ - SDL_DisplayMode fullscreen_mode; - if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { - bounds.w = fullscreen_mode.w; - bounds.h = fullscreen_mode.h; - } - } - if ((window->flags & SDL_WINDOW_FULLSCREEN) - || window->x == SDL_WINDOWPOS_CENTERED) { - x = bounds.x + (bounds.w - w) / 2; - } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { - if (bounds.x == 0) { - x = CW_USEDEFAULT; - } else { - x = bounds.x; - } - } else { - x = bounds.x + window->x + rect.left; - } - if ((window->flags & SDL_WINDOW_FULLSCREEN) - || window->y == SDL_WINDOWPOS_CENTERED) { - y = bounds.y + (bounds.h - h) / 2; - } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { - if (bounds.x == 0) { - y = CW_USEDEFAULT; - } else { - y = bounds.y; - } - } else { - y = bounds.y + window->y + rect.top; - } - - hwnd = - CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL, - SDL_Instance, NULL); - if (!hwnd) { - WIN_SetError("Couldn't create window"); - return -1; - } - //RegisterTouchWindow(hwnd, 0); - - WIN_PumpEvents(_this); - - if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) { - DestroyWindow(hwnd); - return -1; - } -#ifdef SDL_VIDEO_OPENGL_WGL - if (window->flags & SDL_WINDOW_OPENGL) { - if (WIN_GL_SetupWindow(_this, window) < 0) { - WIN_DestroyWindow(_this, window); - return -1; - } - } -#endif - return 0; -} - -int -WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) -{ - HWND hwnd = (HWND) data; - LPTSTR title; - int titleLen; - - /* Query the title from the existing window */ - titleLen = GetWindowTextLength(hwnd); - title = SDL_stack_alloc(TCHAR, titleLen + 1); - if (title) { - titleLen = GetWindowText(hwnd, title, titleLen); - } else { - titleLen = 0; - } - if (titleLen > 0) { - window->title = WIN_StringToUTF8(title); - } - if (title) { - SDL_stack_free(title); - } - - if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) { - return -1; - } - return 0; -} - -void -WIN_SetWindowTitle(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - LPTSTR title; - - if (window->title) { - title = WIN_UTF8ToString(window->title); - } else { - title = NULL; - } - SetWindowText(hwnd, title ? title : TEXT("")); - if (title) { - SDL_free(title); - } -} - -void -WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - HICON hicon = NULL; - - if (icon) { - BYTE *icon_bmp; - int icon_len; - SDL_RWops *dst; - SDL_PixelFormat format; - SDL_Surface *surface; - - /* Create temporary bitmap buffer */ - icon_len = 40 + icon->h * icon->w * 4; - icon_bmp = SDL_stack_alloc(BYTE, icon_len); - dst = SDL_RWFromMem(icon_bmp, icon_len); - if (!dst) { - SDL_stack_free(icon_bmp); - return; - } - - /* Write the BITMAPINFO header */ - SDL_WriteLE32(dst, 40); - SDL_WriteLE32(dst, icon->w); - SDL_WriteLE32(dst, icon->h * 2); - SDL_WriteLE16(dst, 1); - SDL_WriteLE16(dst, 32); - SDL_WriteLE32(dst, BI_RGB); - SDL_WriteLE32(dst, icon->h * icon->w * 4); - SDL_WriteLE32(dst, 0); - SDL_WriteLE32(dst, 0); - SDL_WriteLE32(dst, 0); - SDL_WriteLE32(dst, 0); - - /* Convert the icon to a 32-bit surface with alpha channel */ - SDL_InitFormat(&format, 32, - 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); - surface = SDL_ConvertSurface(icon, &format, 0); - if (surface) { - /* Write the pixels upside down into the bitmap buffer */ - int y = surface->h; - while (y--) { - Uint8 *src = (Uint8 *) surface->pixels + y * surface->pitch; - SDL_RWwrite(dst, src, surface->pitch, 1); - } - SDL_FreeSurface(surface); - -/* TODO: create the icon in WinCE (CreateIconFromResource isn't available) */ -#ifndef _WIN32_WCE - hicon = - CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000); -#endif - } - SDL_RWclose(dst); - SDL_stack_free(icon_bmp); - } - - /* Set the icon for the window */ - SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon); - - /* Set the icon in the task manager (should we do this?) */ - SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon); -} - -void -WIN_SetWindowPosition(_THIS, SDL_Window * window) -{ - SDL_VideoDisplay *display = window->display; - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - RECT rect; - SDL_Rect bounds; - DWORD style; - HWND top; - BOOL menu; - int x, y; - int w, h; - - /* Figure out what the window area will be */ - if (window->flags & SDL_WINDOW_FULLSCREEN) { - top = HWND_TOPMOST; - } else { - top = HWND_NOTOPMOST; - } - style = GetWindowLong(hwnd, GWL_STYLE); - rect.left = 0; - rect.top = 0; - rect.right = window->w; - rect.bottom = window->h; -#ifdef _WIN32_WCE - menu = FALSE; -#else - menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); -#endif - AdjustWindowRectEx(&rect, style, menu, 0); - w = (rect.right - rect.left); - h = (rect.bottom - rect.top); - - WIN_GetDisplayBounds(_this, display, &bounds); - if (window->flags & SDL_WINDOW_FULLSCREEN) { - /* The bounds when this window is visible is the fullscreen mode */ - SDL_DisplayMode fullscreen_mode; - if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { - bounds.w = fullscreen_mode.w; - bounds.h = fullscreen_mode.h; - } - } - if ((window->flags & SDL_WINDOW_FULLSCREEN) - || window->x == SDL_WINDOWPOS_CENTERED) { - x = bounds.x + (bounds.w - w) / 2; - } else { - x = bounds.x + window->x + rect.left; - } - if ((window->flags & SDL_WINDOW_FULLSCREEN) - || window->y == SDL_WINDOWPOS_CENTERED) { - y = bounds.y + (bounds.h - h) / 2; - } else { - y = bounds.y + window->y + rect.top; - } - - SetWindowPos(hwnd, top, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE)); -} - -void -WIN_SetWindowSize(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - RECT rect; - DWORD style; - HWND top; - BOOL menu; - int w, h; - - /* Figure out what the window area will be */ - if (window->flags & SDL_WINDOW_FULLSCREEN) { - top = HWND_TOPMOST; - } else { - top = HWND_NOTOPMOST; - } - style = GetWindowLong(hwnd, GWL_STYLE); - rect.left = 0; - rect.top = 0; - rect.right = window->w; - rect.bottom = window->h; -#ifdef _WIN32_WCE - menu = FALSE; -#else - menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); -#endif - AdjustWindowRectEx(&rect, style, menu, 0); - w = (rect.right - rect.left); - h = (rect.bottom - rect.top); - - SetWindowPos(hwnd, top, 0, 0, w, h, (SWP_NOCOPYBITS | SWP_NOMOVE)); -} - -void -WIN_ShowWindow(_THIS, SDL_Window * window) -{ -#ifdef _WIN32_WCE - WINCE_ShowWindow(_this, window, 1); -#else - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - ShowWindow(hwnd, SW_SHOW); -#endif -} - -void -WIN_HideWindow(_THIS, SDL_Window * window) -{ -#ifdef _WIN32_WCE - WINCE_ShowWindow(_this, window, 0); -#else - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - ShowWindow(hwnd, SW_HIDE); -#endif -} - -void -WIN_RaiseWindow(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - HWND top; - - if (window->flags & SDL_WINDOW_FULLSCREEN) { - top = HWND_TOPMOST; - } else { - top = HWND_NOTOPMOST; - } - SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE)); -} - -void -WIN_MaximizeWindow(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - -#ifdef _WIN32_WCE - if((window->flags & SDL_WINDOW_FULLSCREEN) && videodata->SHFullScreen) - videodata->SHFullScreen(hwnd, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON); -#endif - - ShowWindow(hwnd, SW_MAXIMIZE); -} - -void -WIN_MinimizeWindow(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - - ShowWindow(hwnd, SW_MINIMIZE); - -#ifdef _WIN32_WCE - if((window->flags & SDL_WINDOW_FULLSCREEN) && videodata->SHFullScreen) - videodata->SHFullScreen(hwnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON); -#endif -} - -void -WIN_RestoreWindow(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - - ShowWindow(hwnd, SW_RESTORE); -} - -void -WIN_SetWindowGrab(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - - if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) - && (window->flags & SDL_WINDOW_INPUT_FOCUS)) { - RECT rect; - GetClientRect(hwnd, &rect); - ClientToScreen(hwnd, (LPPOINT) & rect); - ClientToScreen(hwnd, (LPPOINT) & rect + 1); - ClipCursor(&rect); - } else { - ClipCursor(NULL); - } -} - -void -WIN_DestroyWindow(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - - if (data) { -#ifdef _WIN32_WCE - WINCE_ShowWindow(_this, window, 0); -#endif - ReleaseDC(data->hwnd, data->hdc); - if (data->created) { - DestroyWindow(data->hwnd); - } - SDL_free(data); - } -} - -SDL_bool -WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - if (info->version.major <= SDL_MAJOR_VERSION) { - info->subsystem = SDL_SYSWM_WINDOWS; - info->info.win.window = hwnd; - return SDL_TRUE; - } else { - SDL_SetError("Application not compiled with SDL %d.%d\n", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); - return SDL_FALSE; - } -} - - -/* - * Creates a HelperWindow used for DirectInput events. - */ -int -SDL_HelperWindowCreate(void) -{ - HINSTANCE hInstance = GetModuleHandle(NULL); - WNDCLASS wce; - HWND hWndParent = NULL; - - /* Make sure window isn't created twice. */ - if (SDL_HelperWindow != NULL) { - return 0; - } - - /* Create the class. */ - SDL_zero(wce); - wce.lpfnWndProc = DefWindowProc; - wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName; - wce.hInstance = hInstance; - - /* Register the class. */ - SDL_HelperWindowClass = RegisterClass(&wce); - if (SDL_HelperWindowClass == 0) { - WIN_SetError("Unable to create Helper Window Class"); - return -1; - } - -#ifndef _WIN32_WCE - /* WinCE doesn't have HWND_MESSAGE */ - hWndParent = HWND_MESSAGE; -#endif - - /* Create the window. */ - SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName, - SDL_HelperWindowName, - WS_OVERLAPPED, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, hWndParent, NULL, - hInstance, NULL); - if (SDL_HelperWindow == NULL) { - UnregisterClass(SDL_HelperWindowClassName, hInstance); - WIN_SetError("Unable to create Helper Window"); - return -1; - } - - return 0; -} - - -/* - * Destroys the HelperWindow previously created with SDL_HelperWindowCreate. - */ -void -SDL_HelperWindowDestroy(void) -{ - HINSTANCE hInstance = GetModuleHandle(NULL); - - /* Destroy the window. */ - if (SDL_HelperWindow != NULL) { - if (DestroyWindow(SDL_HelperWindow) == 0) { - WIN_SetError("Unable to destroy Helper Window"); - return; - } - SDL_HelperWindow = NULL; - } - - /* Unregister the class. */ - if (SDL_HelperWindowClass != 0) { - if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) { - WIN_SetError("Unable to destroy Helper Window Class"); - return; - } - SDL_HelperWindowClass = 0; - } -} - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/SDL_win32window.h --- a/src/video/win32/SDL_win32window.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2010 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_win32window_h -#define _SDL_win32window_h - -#ifdef _WIN32_WCE -#define SHFS_SHOWTASKBAR 0x0001 -#define SHFS_HIDETASKBAR 0x0002 -#define SHFS_SHOWSIPBUTTON 0x0004 -#define SHFS_HIDESIPBUTTON 0x0008 -#define SHFS_SHOWSTARTICON 0x0010 -#define SHFS_HIDESTARTICON 0x0020 -#endif - -typedef struct -{ - SDL_Window *window; - HWND hwnd; - HDC hdc; - WNDPROC wndproc; - SDL_bool created; - int mouse_pressed; - struct SDL_VideoData *videodata; -} SDL_WindowData; - -extern int WIN_CreateWindow(_THIS, SDL_Window * window); -extern int WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); -extern void WIN_SetWindowTitle(_THIS, SDL_Window * window); -extern void WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); -extern void WIN_SetWindowPosition(_THIS, SDL_Window * window); -extern void WIN_SetWindowSize(_THIS, SDL_Window * window); -extern void WIN_ShowWindow(_THIS, SDL_Window * window); -extern void WIN_HideWindow(_THIS, SDL_Window * window); -extern void WIN_RaiseWindow(_THIS, SDL_Window * window); -extern void WIN_MaximizeWindow(_THIS, SDL_Window * window); -extern void WIN_MinimizeWindow(_THIS, SDL_Window * window); -extern void WIN_RestoreWindow(_THIS, SDL_Window * window); -extern void WIN_SetWindowGrab(_THIS, SDL_Window * window); -extern void WIN_DestroyWindow(_THIS, SDL_Window * window); -extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window, - struct SDL_SysWMinfo *info); - -#endif /* _SDL_win32window_h */ - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/win32/wmmsg.h --- a/src/video/win32/wmmsg.h Thu Jan 20 17:33:06 2011 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1032 +0,0 @@ - -#define MAX_WMMSG (sizeof(wmtab)/sizeof(wmtab[0])) - -char *wmtab[] = { - "WM_NULL", - "WM_CREATE", - "WM_DESTROY", - "WM_MOVE", - "UNKNOWN (4)", - "WM_SIZE", - "WM_ACTIVATE", - "WM_SETFOCUS", - "WM_KILLFOCUS", - "UNKNOWN (9)", - "WM_ENABLE", - "WM_SETREDRAW", - "WM_SETTEXT", - "WM_GETTEXT", - "WM_GETTEXTLENGTH", - "WM_PAINT", - "WM_CLOSE", - "WM_QUERYENDSESSION", - "WM_QUIT", - "WM_QUERYOPEN", - "WM_ERASEBKGND", - "WM_SYSCOLORCHANGE", - "WM_ENDSESSION", - "UNKNOWN (23)", - "WM_SHOWWINDOW", - "UNKNOWN (25)", - "WM_SETTINGCHANGE", - "WM_DEVMODECHANGE", - "WM_ACTIVATEAPP", - "WM_FONTCHANGE", - "WM_TIMECHANGE", - "WM_CANCELMODE", - "WM_SETCURSOR", - "WM_MOUSEACTIVATE", - "WM_CHILDACTIVATE", - "WM_QUEUESYNC", - "WM_GETMINMAXINFO", - "UNKNOWN (37)", - "WM_PAINTICON", - "WM_ICONERASEBKGND", - "WM_NEXTDLGCTL", - "UNKNOWN (41)", - "WM_SPOOLERSTATUS", - "WM_DRAWITEM", - "WM_MEASUREITEM", - "WM_DELETEITEM", - "WM_VKEYTOITEM", - "WM_CHARTOITEM", - "WM_SETFONT", - "WM_GETFONT", - "WM_SETHOTKEY", - "WM_GETHOTKEY", - "UNKNOWN (52)", - "UNKNOWN (53)", - "UNKNOWN (54)", - "WM_QUERYDRAGICON", - "UNKNOWN (56)", - "WM_COMPAREITEM", - "UNKNOWN (58)", - "UNKNOWN (59)", - "UNKNOWN (60)", - "WM_GETOBJECT", - "UNKNOWN (62)", - "UNKNOWN (63)", - "UNKNOWN (64)", - "WM_COMPACTING", - "UNKNOWN (66)", - "UNKNOWN (67)", - "WM_COMMNOTIFY", - "UNKNOWN (69)", - "WM_WINDOWPOSCHANGING", - "WM_WINDOWPOSCHANGED", - "WM_POWER", - "UNKNOWN (73)", - "WM_COPYDATA", - "WM_CANCELJOURNAL", - "UNKNOWN (76)", - "UNKNOWN (77)", - "WM_NOTIFY", - "UNKNOWN (79)", - "WM_INPUTLANGCHANGEREQUEST", - "WM_INPUTLANGCHANGE", - "WM_TCARD", - "WM_HELP", - "WM_USERCHANGED", - "WM_NOTIFYFORMAT", - "UNKNOWN (86)", - "UNKNOWN (87)", - "UNKNOWN (88)", - "UNKNOWN (89)", - "UNKNOWN (90)", - "UNKNOWN (91)", - "UNKNOWN (92)", - "UNKNOWN (93)", - "UNKNOWN (94)", - "UNKNOWN (95)", - "UNKNOWN (96)", - "UNKNOWN (97)", - "UNKNOWN (98)", - "UNKNOWN (99)", - "UNKNOWN (100)", - "UNKNOWN (101)", - "UNKNOWN (102)", - "UNKNOWN (103)", - "UNKNOWN (104)", - "UNKNOWN (105)", - "UNKNOWN (106)", - "UNKNOWN (107)", - "UNKNOWN (108)", - "UNKNOWN (109)", - "UNKNOWN (110)", - "UNKNOWN (111)", - "UNKNOWN (112)", - "UNKNOWN (113)", - "UNKNOWN (114)", - "UNKNOWN (115)", - "UNKNOWN (116)", - "UNKNOWN (117)", - "UNKNOWN (118)", - "UNKNOWN (119)", - "UNKNOWN (120)", - "UNKNOWN (121)", - "UNKNOWN (122)", - "WM_CONTEXTMENU", - "WM_STYLECHANGING", - "WM_STYLECHANGED", - "WM_DISPLAYCHANGE", - "WM_GETICON", - "WM_SETICON", - "WM_NCCREATE", - "WM_NCDESTROY", - "WM_NCCALCSIZE", - "WM_NCHITTEST", - "WM_NCPAINT", - "WM_NCACTIVATE", - "WM_GETDLGCODE", - "WM_SYNCPAINT", - "UNKNOWN (137)", - "UNKNOWN (138)", - "UNKNOWN (139)", - "UNKNOWN (140)", - "UNKNOWN (141)", - "UNKNOWN (142)", - "UNKNOWN (143)", - "UNKNOWN (144)", - "UNKNOWN (145)", - "UNKNOWN (146)", - "UNKNOWN (147)", - "UNKNOWN (148)", - "UNKNOWN (149)", - "UNKNOWN (150)", - "UNKNOWN (151)", - "UNKNOWN (152)", - "UNKNOWN (153)", - "UNKNOWN (154)", - "UNKNOWN (155)", - "UNKNOWN (156)", - "UNKNOWN (157)", - "UNKNOWN (158)", - "UNKNOWN (159)", - "WM_NCMOUSEMOVE", - "WM_NCLBUTTONDOWN", - "WM_NCLBUTTONUP", - "WM_NCLBUTTONDBLCLK", - "WM_NCRBUTTONDOWN", - "WM_NCRBUTTONUP", - "WM_NCRBUTTONDBLCLK", - "WM_NCMBUTTONDOWN", - "WM_NCMBUTTONUP", - "WM_NCMBUTTONDBLCLK", - "UNKNOWN (170)", - "UNKNOWN (171)", - "UNKNOWN (172)", - "UNKNOWN (173)", - "UNKNOWN (174)", - "UNKNOWN (175)", - "UNKNOWN (176)", - "UNKNOWN (177)", - "UNKNOWN (178)", - "UNKNOWN (179)", - "UNKNOWN (180)", - "UNKNOWN (181)", - "UNKNOWN (182)", - "UNKNOWN (183)", - "UNKNOWN (184)", - "UNKNOWN (185)", - "UNKNOWN (186)", - "UNKNOWN (187)", - "UNKNOWN (188)", - "UNKNOWN (189)", - "UNKNOWN (190)", - "UNKNOWN (191)", - "UNKNOWN (192)", - "UNKNOWN (193)", - "UNKNOWN (194)", - "UNKNOWN (195)", - "UNKNOWN (196)", - "UNKNOWN (197)", - "UNKNOWN (198)", - "UNKNOWN (199)", - "UNKNOWN (200)", - "UNKNOWN (201)", - "UNKNOWN (202)", - "UNKNOWN (203)", - "UNKNOWN (204)", - "UNKNOWN (205)", - "UNKNOWN (206)", - "UNKNOWN (207)", - "UNKNOWN (208)", - "UNKNOWN (209)", - "UNKNOWN (210)", - "UNKNOWN (211)", - "UNKNOWN (212)", - "UNKNOWN (213)", - "UNKNOWN (214)", - "UNKNOWN (215)", - "UNKNOWN (216)", - "UNKNOWN (217)", - "UNKNOWN (218)", - "UNKNOWN (219)", - "UNKNOWN (220)", - "UNKNOWN (221)", - "UNKNOWN (222)", - "UNKNOWN (223)", - "UNKNOWN (224)", - "UNKNOWN (225)", - "UNKNOWN (226)", - "UNKNOWN (227)", - "UNKNOWN (228)", - "UNKNOWN (229)", - "UNKNOWN (230)", - "UNKNOWN (231)", - "UNKNOWN (232)", - "UNKNOWN (233)", - "UNKNOWN (234)", - "UNKNOWN (235)", - "UNKNOWN (236)", - "UNKNOWN (237)", - "UNKNOWN (238)", - "UNKNOWN (239)", - "UNKNOWN (240)", - "UNKNOWN (241)", - "UNKNOWN (242)", - "UNKNOWN (243)", - "UNKNOWN (244)", - "UNKNOWN (245)", - "UNKNOWN (246)", - "UNKNOWN (247)", - "UNKNOWN (248)", - "UNKNOWN (249)", - "UNKNOWN (250)", - "UNKNOWN (251)", - "UNKNOWN (252)", - "UNKNOWN (253)", - "UNKNOWN (254)", - "UNKNOWN (255)", - "WM_KEYDOWN", - "WM_KEYUP", - "WM_CHAR", - "WM_DEADCHAR", - "WM_SYSKEYDOWN", - "WM_SYSKEYUP", - "WM_SYSCHAR", - "WM_SYSDEADCHAR", - "WM_KEYLAST", - "UNKNOWN (265)", - "UNKNOWN (266)", - "UNKNOWN (267)", - "UNKNOWN (268)", - "UNKNOWN (269)", - "UNKNOWN (270)", - "UNKNOWN (271)", - "WM_INITDIALOG", - "WM_COMMAND", - "WM_SYSCOMMAND", - "WM_TIMER", - "WM_HSCROLL", - "WM_VSCROLL", - "WM_INITMENU", - "WM_INITMENUPOPUP", - "UNKNOWN (280)", - "WM_GESTURE", - "UNKNOWN (282)", - "UNKNOWN (283)", - "UNKNOWN (284)", - "UNKNOWN (285)", - "UNKNOWN (286)", - "WM_MENUSELECT", - "WM_MENUCHAR", - "WM_ENTERIDLE", - "WM_MENURBUTTONUP", - "WM_MENUDRAG", - "WM_MENUGETOBJECT", - "WM_UNINITMENUPOPUP", - "WM_MENUCOMMAND", - "UNKNOWN (295)", - "UNKNOWN (296)", - "UNKNOWN (297)", - "UNKNOWN (298)", - "UNKNOWN (299)", - "UNKNOWN (300)", - "UNKNOWN (301)", - "UNKNOWN (302)", - "UNKNOWN (303)", - "UNKNOWN (304)", - "UNKNOWN (305)", - "WM_CTLCOLORMSGBOX", - "WM_CTLCOLOREDIT", - "WM_CTLCOLORLISTBOX", - "WM_CTLCOLORBTN", - "WM_CTLCOLORDLG", - "WM_CTLCOLORSCROLLBAR", - "WM_CTLCOLORSTATIC", - "UNKNOWN (313)", - "UNKNOWN (314)", - "UNKNOWN (315)", - "UNKNOWN (316)", - "UNKNOWN (317)", - "UNKNOWN (318)", - "UNKNOWN (319)", - "UNKNOWN (320)", - "UNKNOWN (321)", - "UNKNOWN (322)", - "UNKNOWN (323)", - "UNKNOWN (324)", - "UNKNOWN (325)", - "UNKNOWN (326)", - "UNKNOWN (327)", - "UNKNOWN (328)", - "UNKNOWN (329)", - "UNKNOWN (330)", - "UNKNOWN (331)", - "UNKNOWN (332)", - "UNKNOWN (333)", - "UNKNOWN (334)", - "UNKNOWN (335)", - "UNKNOWN (336)", - "UNKNOWN (337)", - "UNKNOWN (338)", - "UNKNOWN (339)", - "UNKNOWN (340)", - "UNKNOWN (341)", - "UNKNOWN (342)", - "UNKNOWN (343)", - "UNKNOWN (344)", - "UNKNOWN (345)", - "UNKNOWN (346)", - "UNKNOWN (347)", - "UNKNOWN (348)", - "UNKNOWN (349)", - "UNKNOWN (350)", - "UNKNOWN (351)", - "UNKNOWN (352)", - "UNKNOWN (353)", - "UNKNOWN (354)", - "UNKNOWN (355)", - "UNKNOWN (356)", - "UNKNOWN (357)", - "UNKNOWN (358)", - "UNKNOWN (359)", - "UNKNOWN (360)", - "UNKNOWN (361)", - "UNKNOWN (362)", - "UNKNOWN (363)", - "UNKNOWN (364)", - "UNKNOWN (365)", - "UNKNOWN (366)", - "UNKNOWN (367)", - "UNKNOWN (368)", - "UNKNOWN (369)", - "UNKNOWN (370)", - "UNKNOWN (371)", - "UNKNOWN (372)", - "UNKNOWN (373)", - "UNKNOWN (374)", - "UNKNOWN (375)", - "UNKNOWN (376)", - "UNKNOWN (377)", - "UNKNOWN (378)", - "UNKNOWN (379)", - "UNKNOWN (380)", - "UNKNOWN (381)", - "UNKNOWN (382)", - "UNKNOWN (383)", - "UNKNOWN (384)", - "UNKNOWN (385)", - "UNKNOWN (386)", - "UNKNOWN (387)", - "UNKNOWN (388)", - "UNKNOWN (389)", - "UNKNOWN (390)", - "UNKNOWN (391)", - "UNKNOWN (392)", - "UNKNOWN (393)", - "UNKNOWN (394)", - "UNKNOWN (395)", - "UNKNOWN (396)", - "UNKNOWN (397)", - "UNKNOWN (398)", - "UNKNOWN (399)", - "UNKNOWN (400)", - "UNKNOWN (401)", - "UNKNOWN (402)", - "UNKNOWN (403)", - "UNKNOWN (404)", - "UNKNOWN (405)", - "UNKNOWN (406)", - "UNKNOWN (407)", - "UNKNOWN (408)", - "UNKNOWN (409)", - "UNKNOWN (410)", - "UNKNOWN (411)", - "UNKNOWN (412)", - "UNKNOWN (413)", - "UNKNOWN (414)", - "UNKNOWN (415)", - "UNKNOWN (416)", - "UNKNOWN (417)", - "UNKNOWN (418)", - "UNKNOWN (419)", - "UNKNOWN (420)", - "UNKNOWN (421)", - "UNKNOWN (422)", - "UNKNOWN (423)", - "UNKNOWN (424)", - "UNKNOWN (425)", - "UNKNOWN (426)", - "UNKNOWN (427)", - "UNKNOWN (428)", - "UNKNOWN (429)", - "UNKNOWN (430)", - "UNKNOWN (431)", - "UNKNOWN (432)", - "UNKNOWN (433)", - "UNKNOWN (434)", - "UNKNOWN (435)", - "UNKNOWN (436)", - "UNKNOWN (437)", - "UNKNOWN (438)", - "UNKNOWN (439)", - "UNKNOWN (440)", - "UNKNOWN (441)", - "UNKNOWN (442)", - "UNKNOWN (443)", - "UNKNOWN (444)", - "UNKNOWN (445)", - "UNKNOWN (446)", - "UNKNOWN (447)", - "UNKNOWN (448)", - "UNKNOWN (449)", - "UNKNOWN (450)", - "UNKNOWN (451)", - "UNKNOWN (452)", - "UNKNOWN (453)", - "UNKNOWN (454)", - "UNKNOWN (455)", - "UNKNOWN (456)", - "UNKNOWN (457)", - "UNKNOWN (458)", - "UNKNOWN (459)", - "UNKNOWN (460)", - "UNKNOWN (461)", - "UNKNOWN (462)", - "UNKNOWN (463)", - "UNKNOWN (464)", - "UNKNOWN (465)", - "UNKNOWN (466)", - "UNKNOWN (467)", - "UNKNOWN (468)", - "UNKNOWN (469)", - "UNKNOWN (470)", - "UNKNOWN (471)", - "UNKNOWN (472)", - "UNKNOWN (473)", - "UNKNOWN (474)", - "UNKNOWN (475)", - "UNKNOWN (476)", - "UNKNOWN (477)", - "UNKNOWN (478)", - "UNKNOWN (479)", - "UNKNOWN (480)", - "UNKNOWN (481)", - "UNKNOWN (482)", - "UNKNOWN (483)", - "UNKNOWN (484)", - "UNKNOWN (485)", - "UNKNOWN (486)", - "UNKNOWN (487)", - "UNKNOWN (488)", - "UNKNOWN (489)", - "UNKNOWN (490)", - "UNKNOWN (491)", - "UNKNOWN (492)", - "UNKNOWN (493)", - "UNKNOWN (494)", - "UNKNOWN (495)", - "UNKNOWN (496)", - "UNKNOWN (497)", - "UNKNOWN (498)", - "UNKNOWN (499)", - "UNKNOWN (500)", - "UNKNOWN (501)", - "UNKNOWN (502)", - "UNKNOWN (503)", - "UNKNOWN (504)", - "UNKNOWN (505)", - "UNKNOWN (506)", - "UNKNOWN (507)", - "UNKNOWN (508)", - "UNKNOWN (509)", - "UNKNOWN (510)", - "UNKNOWN (511)", - "WM_MOUSEMOVE", - "WM_LBUTTONDOWN", - "WM_LBUTTONUP", - "WM_LBUTTONDBLCLK", - "WM_RBUTTONDOWN", - "WM_RBUTTONUP", - "WM_RBUTTONDBLCLK", - "WM_MBUTTONDOWN", - "WM_MBUTTONUP", - "WM_MOUSELAST", - "WM_MOUSEWHEEL", - "WM_XBUTTONDOWN", - "WM_XBUTTONUP", - "UNKNOWN (525)", - "UNKNOWN (526)", - "UNKNOWN (527)", - "WM_PARENTNOTIFY", - "WM_ENTERMENULOOP", - "WM_EXITMENULOOP", - "WM_NEXTMENU", - "WM_SIZING", - "WM_CAPTURECHANGED", - "WM_MOVING", - "UNKNOWN (535)", - "WM_POWERBROADCAST", - "WM_DEVICECHANGE", - "UNKNOWN (538)", - "UNKNOWN (539)", - "UNKNOWN (540)", - "UNKNOWN (541)", - "UNKNOWN (542)", - "UNKNOWN (543)", - "WM_MDICREATE", - "WM_MDIDESTROY", - "WM_MDIACTIVATE", - "WM_MDIRESTORE", - "WM_MDINEXT", - "WM_MDIMAXIMIZE", - "WM_MDITILE", - "WM_MDICASCADE", - "WM_MDIICONARRANGE", - "WM_MDIGETACTIVE", - "UNKNOWN (554)", - "UNKNOWN (555)", - "UNKNOWN (556)", - "UNKNOWN (557)", - "UNKNOWN (558)", - "UNKNOWN (559)", - "WM_MDISETMENU", - "WM_ENTERSIZEMOVE", - "WM_EXITSIZEMOVE", - "WM_DROPFILES", - "WM_MDIREFRESHMENU", - "UNKNOWN (565)", - "UNKNOWN (566)", - "UNKNOWN (567)", - "UNKNOWN (568)", - "UNKNOWN (569)", - "UNKNOWN (570)", - "UNKNOWN (571)", - "UNKNOWN (572)", - "UNKNOWN (573)", - "UNKNOWN (574)", - "UNKNOWN (575)", - "WM_TOUCH", - "UNKNOWN (577)", - "UNKNOWN (578)", - "UNKNOWN (579)", - "UNKNOWN (580)", - "UNKNOWN (581)", - "UNKNOWN (582)", - "UNKNOWN (583)", - "UNKNOWN (584)", - "UNKNOWN (585)", - "UNKNOWN (586)", - "UNKNOWN (587)", - "UNKNOWN (588)", - "UNKNOWN (589)", - "UNKNOWN (590)", - "UNKNOWN (591)", - "UNKNOWN (592)", - "UNKNOWN (593)", - "UNKNOWN (594)", - "UNKNOWN (595)", - "UNKNOWN (596)", - "UNKNOWN (597)", - "UNKNOWN (598)", - "UNKNOWN (599)", - "UNKNOWN (600)", - "UNKNOWN (601)", - "UNKNOWN (602)", - "UNKNOWN (603)", - "UNKNOWN (604)", - "UNKNOWN (605)", - "UNKNOWN (606)", - "UNKNOWN (607)", - "UNKNOWN (608)", - "UNKNOWN (609)", - "UNKNOWN (610)", - "UNKNOWN (611)", - "UNKNOWN (612)", - "UNKNOWN (613)", - "UNKNOWN (614)", - "UNKNOWN (615)", - "UNKNOWN (616)", - "UNKNOWN (617)", - "UNKNOWN (618)", - "UNKNOWN (619)", - "UNKNOWN (620)", - "UNKNOWN (621)", - "UNKNOWN (622)", - "UNKNOWN (623)", - "UNKNOWN (624)", - "UNKNOWN (625)", - "UNKNOWN (626)", - "UNKNOWN (627)", - "UNKNOWN (628)", - "UNKNOWN (629)", - "UNKNOWN (630)", - "UNKNOWN (631)", - "UNKNOWN (632)", - "UNKNOWN (633)", - "UNKNOWN (634)", - "UNKNOWN (635)", - "UNKNOWN (636)", - "UNKNOWN (637)", - "UNKNOWN (638)", - "UNKNOWN (639)", - "UNKNOWN (640)", - "UNKNOWN (641)", - "UNKNOWN (642)", - "UNKNOWN (643)", - "UNKNOWN (644)", - "UNKNOWN (645)", - "UNKNOWN (646)", - "UNKNOWN (647)", - "UNKNOWN (648)", - "UNKNOWN (649)", - "UNKNOWN (650)", - "UNKNOWN (651)", - "UNKNOWN (652)", - "UNKNOWN (653)", - "UNKNOWN (654)", - "UNKNOWN (655)", - "UNKNOWN (656)", - "UNKNOWN (657)", - "UNKNOWN (658)", - "UNKNOWN (659)", - "UNKNOWN (660)", - "UNKNOWN (661)", - "UNKNOWN (662)", - "UNKNOWN (663)", - "UNKNOWN (664)", - "UNKNOWN (665)", - "UNKNOWN (666)", - "UNKNOWN (667)", - "UNKNOWN (668)", - "UNKNOWN (669)", - "UNKNOWN (670)", - "UNKNOWN (671)", - "UNKNOWN (672)", - "WM_MOUSEHOVER", - "UNKNOWN (674)", - "WM_MOUSELEAVE", - "UNKNOWN (676)", - "UNKNOWN (677)", - "UNKNOWN (678)", - "UNKNOWN (679)", - "UNKNOWN (680)", - "UNKNOWN (681)", - "UNKNOWN (682)", - "UNKNOWN (683)", - "UNKNOWN (684)", - "UNKNOWN (685)", - "UNKNOWN (686)", - "UNKNOWN (687)", - "UNKNOWN (688)", - "UNKNOWN (689)", - "UNKNOWN (690)", - "UNKNOWN (691)", - "UNKNOWN (692)", - "UNKNOWN (693)", - "UNKNOWN (694)", - "UNKNOWN (695)", - "UNKNOWN (696)", - "UNKNOWN (697)", - "UNKNOWN (698)", - "UNKNOWN (699)", - "UNKNOWN (700)", - "UNKNOWN (701)", - "UNKNOWN (702)", - "UNKNOWN (703)", - "UNKNOWN (704)", - "UNKNOWN (705)", - "UNKNOWN (706)", - "UNKNOWN (707)", - "UNKNOWN (708)", - "UNKNOWN (709)", - "UNKNOWN (710)", - "UNKNOWN (711)", - "UNKNOWN (712)", - "UNKNOWN (713)", - "UNKNOWN (714)", - "UNKNOWN (715)", - "UNKNOWN (716)", - "UNKNOWN (717)", - "UNKNOWN (718)", - "UNKNOWN (719)", - "UNKNOWN (720)", - "UNKNOWN (721)", - "UNKNOWN (722)", - "UNKNOWN (723)", - "UNKNOWN (724)", - "UNKNOWN (725)", - "UNKNOWN (726)", - "UNKNOWN (727)", - "UNKNOWN (728)", - "UNKNOWN (729)", - "UNKNOWN (730)", - "UNKNOWN (731)", - "UNKNOWN (732)", - "UNKNOWN (733)", - "UNKNOWN (734)", - "UNKNOWN (735)", - "UNKNOWN (736)", - "UNKNOWN (737)", - "UNKNOWN (738)", - "UNKNOWN (739)", - "UNKNOWN (740)", - "UNKNOWN (741)", - "UNKNOWN (742)", - "UNKNOWN (743)", - "UNKNOWN (744)", - "UNKNOWN (745)", - "UNKNOWN (746)", - "UNKNOWN (747)", - "UNKNOWN (748)", - "UNKNOWN (749)", - "UNKNOWN (750)", - "UNKNOWN (751)", - "UNKNOWN (752)", - "UNKNOWN (753)", - "UNKNOWN (754)", - "UNKNOWN (755)", - "UNKNOWN (756)", - "UNKNOWN (757)", - "UNKNOWN (758)", - "UNKNOWN (759)", - "UNKNOWN (760)", - "UNKNOWN (761)", - "UNKNOWN (762)", - "UNKNOWN (763)", - "UNKNOWN (764)", - "UNKNOWN (765)", - "UNKNOWN (766)", - "UNKNOWN (767)", - "WM_CUT", - "WM_COPY", - "WM_PASTE", - "WM_CLEAR", - "WM_UNDO", - "WM_RENDERFORMAT", - "WM_RENDERALLFORMATS", - "WM_DESTROYCLIPBOARD", - "WM_DRAWCLIPBOARD", - "WM_PAINTCLIPBOARD", - "WM_VSCROLLCLIPBOARD", - "WM_SIZECLIPBOARD", - "WM_ASKCBFORMATNAME", - "WM_CHANGECBCHAIN", - "WM_HSCROLLCLIPBOARD", - "WM_QUERYNEWPALETTE", - "WM_PALETTEISCHANGING", - "WM_PALETTECHANGED", - "WM_HOTKEY", - "UNKNOWN (787)", - "UNKNOWN (788)", - "UNKNOWN (789)", - "UNKNOWN (790)", - "WM_PRINT", - "WM_PRINTCLIENT", - "UNKNOWN (793)", - "UNKNOWN (794)", - "UNKNOWN (795)", - "UNKNOWN (796)", - "UNKNOWN (797)", - "UNKNOWN (798)", - "UNKNOWN (799)", - "UNKNOWN (800)", - "UNKNOWN (801)", - "UNKNOWN (802)", - "UNKNOWN (803)", - "UNKNOWN (804)", - "UNKNOWN (805)", - "UNKNOWN (806)", - "UNKNOWN (807)", - "UNKNOWN (808)", - "UNKNOWN (809)", - "UNKNOWN (810)", - "UNKNOWN (811)", - "UNKNOWN (812)", - "UNKNOWN (813)", - "UNKNOWN (814)", - "UNKNOWN (815)", - "UNKNOWN (816)", - "UNKNOWN (817)", - "UNKNOWN (818)", - "UNKNOWN (819)", - "UNKNOWN (820)", - "UNKNOWN (821)", - "UNKNOWN (822)", - "UNKNOWN (823)", - "UNKNOWN (824)", - "UNKNOWN (825)", - "UNKNOWN (826)", - "UNKNOWN (827)", - "UNKNOWN (828)", - "UNKNOWN (829)", - "UNKNOWN (830)", - "UNKNOWN (831)", - "UNKNOWN (832)", - "UNKNOWN (833)", - "UNKNOWN (834)", - "UNKNOWN (835)", - "UNKNOWN (836)", - "UNKNOWN (837)", - "UNKNOWN (838)", - "UNKNOWN (839)", - "UNKNOWN (840)", - "UNKNOWN (841)", - "UNKNOWN (842)", - "UNKNOWN (843)", - "UNKNOWN (844)", - "UNKNOWN (845)", - "UNKNOWN (846)", - "UNKNOWN (847)", - "UNKNOWN (848)", - "UNKNOWN (849)", - "UNKNOWN (850)", - "UNKNOWN (851)", - "UNKNOWN (852)", - "UNKNOWN (853)", - "UNKNOWN (854)", - "UNKNOWN (855)", - "WM_HANDHELDFIRST", - "UNKNOWN (857)", - "UNKNOWN (858)", - "UNKNOWN (859)", - "UNKNOWN (860)", - "UNKNOWN (861)", - "UNKNOWN (862)", - "WM_HANDHELDLAST", - "WM_AFXFIRST", - "UNKNOWN (865)", - "UNKNOWN (866)", - "UNKNOWN (867)", - "UNKNOWN (868)", - "UNKNOWN (869)", - "UNKNOWN (870)", - "UNKNOWN (871)", - "UNKNOWN (872)", - "UNKNOWN (873)", - "UNKNOWN (874)", - "UNKNOWN (875)", - "UNKNOWN (876)", - "UNKNOWN (877)", - "UNKNOWN (878)", - "UNKNOWN (879)", - "UNKNOWN (880)", - "UNKNOWN (881)", - "UNKNOWN (882)", - "UNKNOWN (883)", - "UNKNOWN (884)", - "UNKNOWN (885)", - "UNKNOWN (886)", - "UNKNOWN (887)", - "UNKNOWN (888)", - "UNKNOWN (889)", - "UNKNOWN (890)", - "UNKNOWN (891)", - "UNKNOWN (892)", - "UNKNOWN (893)", - "UNKNOWN (894)", - "WM_AFXLAST", - "WM_PENWINFIRST", - "UNKNOWN (897)", - "UNKNOWN (898)", - "UNKNOWN (899)", - "UNKNOWN (900)", - "UNKNOWN (901)", - "UNKNOWN (902)", - "UNKNOWN (903)", - "UNKNOWN (904)", - "UNKNOWN (905)", - "UNKNOWN (906)", - "UNKNOWN (907)", - "UNKNOWN (908)", - "UNKNOWN (909)", - "UNKNOWN (910)", - "WM_PENWINLAST", - "UNKNOWN (912)", - "UNKNOWN (913)", - "UNKNOWN (914)", - "UNKNOWN (915)", - "UNKNOWN (916)", - "UNKNOWN (917)", - "UNKNOWN (918)", - "UNKNOWN (919)", - "UNKNOWN (920)", - "UNKNOWN (921)", - "UNKNOWN (922)", - "UNKNOWN (923)", - "UNKNOWN (924)", - "UNKNOWN (925)", - "UNKNOWN (926)", - "UNKNOWN (927)", - "UNKNOWN (928)", - "UNKNOWN (929)", - "UNKNOWN (930)", - "UNKNOWN (931)", - "UNKNOWN (932)", - "UNKNOWN (933)", - "UNKNOWN (934)", - "UNKNOWN (935)", - "UNKNOWN (936)", - "UNKNOWN (937)", - "UNKNOWN (938)", - "UNKNOWN (939)", - "UNKNOWN (940)", - "UNKNOWN (941)", - "UNKNOWN (942)", - "UNKNOWN (943)", - "UNKNOWN (944)", - "UNKNOWN (945)", - "UNKNOWN (946)", - "UNKNOWN (947)", - "UNKNOWN (948)", - "UNKNOWN (949)", - "UNKNOWN (950)", - "UNKNOWN (951)", - "UNKNOWN (952)", - "UNKNOWN (953)", - "UNKNOWN (954)", - "UNKNOWN (955)", - "UNKNOWN (956)", - "UNKNOWN (957)", - "UNKNOWN (958)", - "UNKNOWN (959)", - "UNKNOWN (960)", - "UNKNOWN (961)", - "UNKNOWN (962)", - "UNKNOWN (963)", - "UNKNOWN (964)", - "UNKNOWN (965)", - "UNKNOWN (966)", - "UNKNOWN (967)", - "UNKNOWN (968)", - "UNKNOWN (969)", - "UNKNOWN (970)", - "UNKNOWN (971)", - "UNKNOWN (972)", - "UNKNOWN (973)", - "UNKNOWN (974)", - "UNKNOWN (975)", - "UNKNOWN (976)", - "UNKNOWN (977)", - "UNKNOWN (978)", - "UNKNOWN (979)", - "UNKNOWN (980)", - "UNKNOWN (981)", - "UNKNOWN (982)", - "UNKNOWN (983)", - "UNKNOWN (984)", - "UNKNOWN (985)", - "UNKNOWN (986)", - "UNKNOWN (987)", - "UNKNOWN (988)", - "UNKNOWN (989)", - "UNKNOWN (990)", - "UNKNOWN (991)", - "UNKNOWN (992)", - "UNKNOWN (993)", - "UNKNOWN (994)", - "UNKNOWN (995)", - "UNKNOWN (996)", - "UNKNOWN (997)", - "UNKNOWN (998)", - "UNKNOWN (999)", - "UNKNOWN (1000)", - "UNKNOWN (1001)", - "UNKNOWN (1002)", - "UNKNOWN (1003)", - "UNKNOWN (1004)", - "UNKNOWN (1005)", - "UNKNOWN (1006)", - "UNKNOWN (1007)", - "UNKNOWN (1008)", - "UNKNOWN (1009)", - "UNKNOWN (1010)", - "UNKNOWN (1011)", - "UNKNOWN (1012)", - "UNKNOWN (1013)", - "UNKNOWN (1014)", - "UNKNOWN (1015)", - "UNKNOWN (1016)", - "UNKNOWN (1017)", - "UNKNOWN (1018)", - "UNKNOWN (1019)", - "UNKNOWN (1020)", - "UNKNOWN (1021)", - "UNKNOWN (1022)", - "UNKNOWN (1023)", - "WM_USER" -}; - -/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_ceddrawrender.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_ceddrawrender.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,835 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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 + + Stefan Klug + klug.stefan@gmx.de +*/ +#include "SDL_config.h" + +#if SDL_VIDEO_RENDER_DDRAW + +#include "SDL_windowsvideo.h" +#include "../SDL_yuv_sw_c.h" + +#if 0 +#define DDRAW_LOG(...) printf(__VA_ARGS__) +#else +#define DDRAW_LOG(...) +#endif + + +/* DirectDraw renderer implementation */ + +static SDL_Renderer *DDRAW_CreateRenderer(SDL_Window * window, Uint32 flags); +static int DDRAW_DisplayModeChanged(SDL_Renderer * renderer); +static int DDRAW_CreateTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static int DDRAW_QueryTexturePixels(SDL_Renderer * renderer, + SDL_Texture * texture, void **pixels, + int *pitch); +static int DDRAW_SetTextureColorMod(SDL_Renderer * renderer, + SDL_Texture * texture); +static int DDRAW_SetTextureAlphaMod(SDL_Renderer * renderer, + SDL_Texture * texture); +static int DDRAW_SetTextureBlendMode(SDL_Renderer * renderer, + SDL_Texture * texture); +static int DDRAW_SetTextureScaleMode(SDL_Renderer * renderer, + SDL_Texture * texture); +static int DDRAW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, + int pitch); +static int DDRAW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, + void **pixels, int *pitch); +static void DDRAW_UnlockTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static void DDRAW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, + int numrects, const SDL_Rect * rects); +static int DDRAW_RenderPoint(SDL_Renderer * renderer, int x, int y); +static int DDRAW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, + int y2); +static int DDRAW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect); +static int DDRAW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect); +static void DDRAW_RenderPresent(SDL_Renderer * renderer); +static void DDRAW_DestroyTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static void DDRAW_DestroyRenderer(SDL_Renderer * renderer); + + +SDL_RenderDriver DDRAW_RenderDriver = { + DDRAW_CreateRenderer, + { + "ddraw", + (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY | + SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | + SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED), + (SDL_TEXTUREMODULATE_NONE), + (SDL_BLENDMODE_NONE), + (SDL_SCALEMODE_NONE), + 0, + {0}, + 0, + 0} +}; + +typedef struct +{ + IDirectDraw *ddraw; + IDirectDrawSurface *primary; +} DDRAW_RenderData; + +typedef struct +{ + RECT lock; + IDirectDrawSurface *surface; +} DDRAW_TextureData; + + +static void +DDRAW_SetError(const char *prefix, HRESULT result) +{ + const char *error; + + switch (result) { + case DDERR_CANTCREATEDC: + error = "CANTCREATEDC"; + break; + case DDERR_CANTLOCKSURFACE: + error = "CANTLOCKSURFACE"; + break; + case DDERR_CLIPPERISUSINGHWND: + error = "CLIPPERISUSINGHWND"; + break; + case DDERR_COLORKEYNOTSET: + error = "COLORKEYNOTSET"; + break; + case DDERR_CURRENTLYNOTAVAIL: + error = "CURRENTLYNOTAVAIL"; + break; + case DDERR_DCALREADYCREATED: + error = "DCALREADYCREATED"; + break; + case DDERR_DEVICEDOESNTOWNSURFACE: + error = "DEVICEDOESNTOWNSURFACE"; + break; + case DDERR_DIRECTDRAWALREADYCREATED: + error = "DIRECTDRAWALREADYCREATED"; + break; + case DDERR_EXCLUSIVEMODEALREADYSET: + error = "EXCLUSIVEMODEALREADYSET"; + break; + case DDERR_GENERIC: + error = "GENERIC"; + break; + case DDERR_HEIGHTALIGN: + error = "HEIGHTALIGN"; + break; + case DDERR_IMPLICITLYCREATED: + error = "IMPLICITLYCREATED"; + break; + case DDERR_INCOMPATIBLEPRIMARY: + error = "INCOMPATIBLEPRIMARY"; + break; + case DDERR_INVALIDCAPS: + error = "INVALIDCAPS"; + break; + case DDERR_INVALIDCLIPLIST: + error = "INVALIDCLIPLIST"; + break; + case DDERR_INVALIDMODE: + error = "INVALIDMODE"; + break; + case DDERR_INVALIDOBJECT: + error = "INVALIDOBJECT"; + break; + case DDERR_INVALIDPARAMS: + error = "INVALIDPARAMS"; + break; + case DDERR_INVALIDPIXELFORMAT: + error = "INVALIDPIXELFORMAT"; + break; + case DDERR_INVALIDPOSITION: + error = "INVALIDPOSITION"; + break; + case DDERR_INVALIDRECT: + error = "INVALIDRECT"; + break; + case DDERR_LOCKEDSURFACES: + error = "LOCKEDSURFACES"; + break; + case DDERR_MOREDATA: + error = "MOREDATA"; + break; + case DDERR_NOALPHAHW: + error = "NOALPHAHW"; + break; + case DDERR_NOBLTHW: + error = "NOBLTHW"; + break; + case DDERR_NOCLIPLIST: + error = "NOCLIPLIST"; + break; + case DDERR_NOCLIPPERATTACHED: + error = "NOCLIPPERATTACHED"; + break; + case DDERR_NOCOLORCONVHW: + error = "NOCOLORCONVHW"; + break; + case DDERR_NOCOLORKEYHW: + error = "NOCOLORKEYHW"; + break; + case DDERR_NOCOOPERATIVELEVELSET: + error = "NOCOOPERATIVELEVELSET"; + break; + case DDERR_NODC: + error = "NODC"; + break; + case DDERR_NOFLIPHW: + error = "NOFLIPHW"; + break; + case DDERR_NOOVERLAYDEST: + error = "NOOVERLAYDEST"; + break; + case DDERR_NOOVERLAYHW: + error = "NOOVERLAYHW"; + break; + case DDERR_NOPALETTEATTACHED: + error = "NOPALETTEATTACHED"; + break; + case DDERR_NOPALETTEHW: + error = "NOPALETTEHW"; + break; + case DDERR_NORASTEROPHW: + error = "NORASTEROPHW"; + break; + case DDERR_NOSTRETCHHW: + error = "NOSTRETCHHW"; + break; + case DDERR_NOTAOVERLAYSURFACE: + error = "NOTAOVERLAYSURFACE"; + break; + case DDERR_NOTFLIPPABLE: + error = "NOTFLIPPABLE"; + break; + case DDERR_NOTFOUND: + error = "NOTFOUND"; + break; + case DDERR_NOTLOCKED: + error = "NOTLOCKED"; + break; + case DDERR_NOTPALETTIZED: + error = "NOTPALETTIZED"; + break; + case DDERR_NOVSYNCHW: + error = "NOVSYNCHW"; + break; + case DDERR_NOZOVERLAYHW: + error = "NOZOVERLAYHW"; + break; + case DDERR_OUTOFCAPS: + error = "OUTOFCAPS"; + break; + case DDERR_OUTOFMEMORY: + error = "OUTOFMEMORY"; + break; + case DDERR_OUTOFVIDEOMEMORY: + error = "OUTOFVIDEOMEMORY"; + break; + case DDERR_OVERLAPPINGRECTS: + error = "OVERLAPPINGRECTS"; + break; + case DDERR_OVERLAYNOTVISIBLE: + error = "OVERLAYNOTVISIBLE"; + break; + case DDERR_PALETTEBUSY: + error = "PALETTEBUSY"; + break; + case DDERR_PRIMARYSURFACEALREADYEXISTS: + error = "PRIMARYSURFACEALREADYEXISTS"; + break; + case DDERR_REGIONTOOSMALL: + error = "REGIONTOOSMALL"; + break; + case DDERR_SURFACEBUSY: + error = "SURFACEBUSY"; + break; + case DDERR_SURFACELOST: + error = "SURFACELOST"; + break; + case DDERR_TOOBIGHEIGHT: + error = "TOOBIGHEIGHT"; + break; + case DDERR_TOOBIGSIZE: + error = "TOOBIGSIZE"; + break; + case DDERR_TOOBIGWIDTH: + error = "TOOBIGWIDTH"; + break; + case DDERR_UNSUPPORTED: + error = "UNSUPPORTED"; + break; + case DDERR_UNSUPPORTEDFORMAT: + error = "UNSUPPORTEDFORMAT"; + break; + case DDERR_VERTICALBLANKINPROGRESS: + error = "VERTICALBLANKINPROGRESS"; + break; + case DDERR_VIDEONOTACTIVE: + error = "VIDEONOTACTIVE"; + break; + case DDERR_WASSTILLDRAWING: + error = "WASSTILLDRAWING"; + break; + case DDERR_WRONGMODE: + error = "WRONGMODE"; + break; + default: + error = "UNKNOWN"; + break; + } + SDL_SetError("%s: %s", prefix, error); +} + +static SDL_bool +PixelFormatToDDPIXELFORMAT(Uint32 format, LPDDPIXELFORMAT dst) +{ + SDL_zerop(dst); + dst->dwSize = sizeof(*dst); + + if (SDL_ISPIXELFORMAT_FOURCC(format)) { + dst->dwFlags = DDPF_FOURCC; + dst->dwFourCC = format; + } else if (SDL_ISPIXELFORMAT_INDEXED(format)) { + SDL_SetError("Indexed pixelformats are not supported."); + return SDL_FALSE; + } else { + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + if (!SDL_PixelFormatEnumToMasks + (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + SDL_SetError("pixelformat not supported"); + return SDL_FALSE; + } + + if (!Rmask && !Gmask && !Bmask) { + dst->dwFlags = DDPF_ALPHA; + dst->dwAlphaBitDepth = bpp; + } else { + dst->dwFlags = DDPF_RGB; + dst->dwRGBBitCount = bpp; + dst->dwRBitMask = Rmask; + dst->dwGBitMask = Gmask; + dst->dwBBitMask = Bmask; + + if (Amask) { + dst->dwFlags |= DDPF_ALPHAPIXELS; + dst->dwRGBAlphaBitMask = Amask; + } + } + } + + return SDL_TRUE; +} + +static SDL_bool +DDRAW_IsTextureFormatAvailable(IDirectDraw * ddraw, Uint32 display_format, + Uint32 texture_format) +{ + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + if (SDL_ISPIXELFORMAT_FOURCC(texture_format)) { + //TODO I don't expect DDRAW to support all 4CC formats, but I don't know which ones + return SDL_TRUE; + } + //These are only basic checks + if (SDL_ISPIXELFORMAT_INDEXED(texture_format)) { + return SDL_FALSE; + } + + if (!SDL_PixelFormatEnumToMasks + (texture_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + return SDL_FALSE; + } + + switch (bpp) { + case 4: + case 8: + case 16: + case 24: + case 32: + break; + default: + return SDL_FALSE; + } + + return SDL_TRUE; +} + +void +DDRAW_AddRenderDriver(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_RendererInfo *info = &DDRAW_RenderDriver.info; + SDL_DisplayMode *mode = &SDL_CurrentDisplay->desktop_mode; + + if (data->ddraw) { + int i; + int formats[] = { + SDL_PIXELFORMAT_INDEX8, + SDL_PIXELFORMAT_RGB332, + SDL_PIXELFORMAT_RGB444, + SDL_PIXELFORMAT_RGB555, + SDL_PIXELFORMAT_ARGB4444, + SDL_PIXELFORMAT_ARGB1555, + SDL_PIXELFORMAT_RGB565, + SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ARGB2101010, + }; + + for (i = 0; i < SDL_arraysize(formats); ++i) { + if (DDRAW_IsTextureFormatAvailable + (data->ddraw, mode->format, formats[i])) { + info->texture_formats[info->num_texture_formats++] = + formats[i]; + } + } + + //TODO the fourcc formats should get fetched from IDirectDraw::GetFourCCCodes + info->texture_formats[info->num_texture_formats++] = + SDL_PIXELFORMAT_YV12; + info->texture_formats[info->num_texture_formats++] = + SDL_PIXELFORMAT_IYUV; + info->texture_formats[info->num_texture_formats++] = + SDL_PIXELFORMAT_YUY2; + info->texture_formats[info->num_texture_formats++] = + SDL_PIXELFORMAT_UYVY; + info->texture_formats[info->num_texture_formats++] = + SDL_PIXELFORMAT_YVYU; + + for (i = 0; i < _this->num_displays; ++i) + SDL_AddRenderDriver(&_this->displays[i], &DDRAW_RenderDriver); + } + } +} + +SDL_Renderer * +DDRAW_CreateRenderer(SDL_Window * window, Uint32 flags) +{ + SDL_VideoDisplay *display = window->display; + SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata; + SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; + SDL_Renderer *renderer; + DDRAW_RenderData *data; + HRESULT result; + DDSURFACEDESC ddsd; + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (DDRAW_RenderData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + DDRAW_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + data->ddraw = videodata->ddraw; + + videodata->render = RENDER_DDRAW; + + renderer->DisplayModeChanged = DDRAW_DisplayModeChanged; + renderer->CreateTexture = DDRAW_CreateTexture; + renderer->QueryTexturePixels = DDRAW_QueryTexturePixels; + + renderer->SetTextureColorMod = DDRAW_SetTextureColorMod; + renderer->SetTextureAlphaMod = DDRAW_SetTextureAlphaMod; + renderer->SetTextureBlendMode = DDRAW_SetTextureBlendMode; + renderer->SetTextureScaleMode = DDRAW_SetTextureScaleMode; + renderer->UpdateTexture = DDRAW_UpdateTexture; + renderer->LockTexture = DDRAW_LockTexture; + renderer->UnlockTexture = DDRAW_UnlockTexture; + renderer->DirtyTexture = DDRAW_DirtyTexture; + renderer->RenderPoint = DDRAW_RenderPoint; + renderer->RenderLine = DDRAW_RenderLine; + renderer->RenderFill = DDRAW_RenderFill; + renderer->RenderCopy = DDRAW_RenderCopy; + renderer->RenderPresent = DDRAW_RenderPresent; + renderer->DestroyTexture = DDRAW_DestroyTexture; + renderer->DestroyRenderer = DDRAW_DestroyRenderer; + renderer->info = DDRAW_RenderDriver.info; + renderer->window = window; + renderer->driverdata = data; + + renderer->info.flags = SDL_RENDERER_ACCELERATED; + + SDL_zero(ddsd); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS; + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + } else { + //TODO handle non fullscreen + SDL_SetError("DirectDraw renderer has only fullscreen implemented"); + DDRAW_DestroyRenderer(renderer); + return NULL; + } + + if (flags & SDL_RENDERER_PRESENTFLIP2) { + ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; + ddsd.dwBackBufferCount = 2; + } else if (flags & SDL_RENDERER_PRESENTFLIP3) { + ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; + ddsd.dwBackBufferCount = 3; + } else if (flags & SDL_RENDERER_PRESENTCOPY) { + //TODO what is the best approximation to this mode + } else { + + } + + if (flags & SDL_RENDERER_PRESENTVSYNC) { + SDL_SetError("DirectDraw renderer with v-sync is not implemented"); + DDRAW_DestroyRenderer(renderer); + return NULL; + } + + result = + data->ddraw->lpVtbl->SetCooperativeLevel(data->ddraw, + windowdata->hwnd, + DDSCL_NORMAL); + if (result != DD_OK) { + DDRAW_SetError("CreateDevice()", result); + DDRAW_DestroyRenderer(renderer); + return NULL; + } + + result = + data->ddraw->lpVtbl->CreateSurface(data->ddraw, &ddsd, &data->primary, + NULL); + if (result != DD_OK) { + DDRAW_SetError("CreateDevice()", result); + DDRAW_DestroyRenderer(renderer); + return NULL; + } + + return renderer; +} + +static int +DDRAW_Reset(SDL_Renderer * renderer) +{ + //TODO implement + /*D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + HRESULT result; + + result = IDirect3DDevice9_Reset(data->device, &data->pparams); + if (FAILED(result)) { + if (result == D3DERR_DEVICELOST) { + /* Don't worry about it, we'll reset later... * + return 0; + } else { + D3D_SetError("Reset()", result); + return -1; + } + } + IDirect3DDevice9_SetVertexShader(data->device, NULL); + IDirect3DDevice9_SetFVF(data->device, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, + D3DCULL_NONE); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); */ + return 0; +} + +static int +DDRAW_DisplayModeChanged(SDL_Renderer * renderer) +{ + //TODO implement + /*D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + + data->pparams.BackBufferWidth = window->w; + data->pparams.BackBufferHeight = window->h; + if (window->flags & SDL_WINDOW_FULLSCREEN) { + data->pparams.BackBufferFormat = + PixelFormatToD3DFMT(display->fullscreen_mode.format); + } else { + data->pparams.BackBufferFormat = D3DFMT_UNKNOWN; + } + return D3D_Reset(renderer); */ + return 0; +} + +static int +DDRAW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + DDRAW_RenderData *renderdata = (DDRAW_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + Uint32 display_format = display->current_mode.format; + DDRAW_TextureData *data; + DDSURFACEDESC ddsd; + HRESULT result; + + data = (DDRAW_TextureData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + SDL_OutOfMemory(); + return -1; + } + + SDL_zero(ddsd); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_HEIGHT | DDSD_WIDTH; + ddsd.dwWidth = texture->w; + ddsd.dwHeight = texture->h; + + + if (!PixelFormatToDDPIXELFORMAT(texture->format, &ddsd.ddpfPixelFormat)) { + SDL_free(data); + return -1; + } + + texture->driverdata = data; + + result = + renderdata->ddraw->lpVtbl->CreateSurface(renderdata->ddraw, &ddsd, + &data->surface, NULL); + if (result != DD_OK) { + SDL_free(data); + DDRAW_SetError("CreateTexture", result); + return -1; + } + + return 0; +} + +static int +DDRAW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, + void **pixels, int *pitch) +{ + //TODO implement + SDL_SetError("QueryTexturePixels is not implemented"); + return -1; +} + +static int +DDRAW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + return 0; +} + +static int +DDRAW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + return 0; +} + +static int +DDRAW_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) +{ + switch (texture->blendMode) { + case SDL_BLENDMODE_NONE: + return 0; + default: + SDL_Unsupported(); + texture->blendMode = SDL_BLENDMODE_NONE; + return -1; + } +} + +static int +DDRAW_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) +{ + switch (texture->scaleMode) { + case SDL_SCALEMODE_NONE: + default: + SDL_Unsupported(); + texture->scaleMode = SDL_SCALEMODE_NONE; + return -1; + } + return 0; +} + +static int +DDRAW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, int pitch) +{ + DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata; + + //TODO implement + SDL_SetError("UpdateTexture is not implemented"); + return 0; +} + +static int +DDRAW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, void **pixels, + int *pitch) +{ + DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata; + HRESULT result; + DDSURFACEDESC ddsd; + + SDL_zero(ddsd); + ddsd.dwSize = sizeof(ddsd); + + /** + * On a Axim x51v locking a subrect returns the startaddress of the whole surface, + * wheras on my ASUS MyPal 696 the startaddress of the locked area is returned, + * thats why I always lock the whole surface and calculate the pixels pointer by hand. + * This shouldn't be a speed problem, as multiple locks aren't available on DDraw Mobile + * see http://msdn.microsoft.com/en-us/library/ms858221.aspx + */ + + result = data->surface->lpVtbl->Lock(data->surface, NULL, &ddsd, 0, NULL); + if (result != DD_OK) { + DDRAW_SetError("LockRect()", result); + return -1; + } + + *pixels = ddsd.lpSurface + rect->y * ddsd.lPitch + rect->x * ddsd.lXPitch; + *pitch = ddsd.lPitch; + return 0; +} + +static void +DDRAW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata; + + data->surface->lpVtbl->Unlock(data->surface, NULL); +} + +static void +DDRAW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, + int numrects, const SDL_Rect * rects) +{ +} + +static void +DDRAW_SetBlendMode(DDRAW_RenderData * data, int blendMode) +{ + switch (blendMode) { + + } +} + +static int +DDRAW_RenderPoint(SDL_Renderer * renderer, int x, int y) +{ + return -1; +} + +static int +DDRAW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) +{ + return -1; +} + +static int +DDRAW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect) +{ + return -1; +} + +static int +DDRAW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect) +{ + DDRAW_RenderData *data = (DDRAW_RenderData *) renderer->driverdata; + DDRAW_TextureData *texturedata = + (DDRAW_TextureData *) texture->driverdata; + HRESULT result; + RECT srcr; + RECT dstr; + DDBLTFX bltfx; + + srcr.left = srcrect->x; + srcr.top = srcrect->y; + srcr.right = srcrect->x + srcrect->w; + srcr.bottom = srcrect->y + srcrect->h; + + dstr.left = dstrect->x; + dstr.top = dstrect->y; + dstr.right = dstrect->x + dstrect->w; + dstr.bottom = dstrect->y + dstrect->h; + + SDL_zero(bltfx); + bltfx.dwSize = sizeof(bltfx); + bltfx.dwROP = SRCCOPY; + + data->primary->lpVtbl->Blt(data->primary, &dstr, texturedata->surface, + &srcr, DDBLT_ROP, &bltfx); + + return 0; +} + +static void +DDRAW_RenderPresent(SDL_Renderer * renderer) +{ + DDRAW_RenderData *data = (DDRAW_RenderData *) renderer->driverdata; + HRESULT result; + + return; + + result = + data->primary->lpVtbl->Flip(data->primary, NULL, DDFLIP_INTERVAL1); + if (result != DD_OK) { + DDRAW_SetError("Present()", result); + } +} + +static void +DDRAW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata; + + if (!data) { + return; + } + + data->surface->lpVtbl->Release(data->surface); + SDL_free(data); + texture->driverdata = NULL; +} + +static void +DDRAW_DestroyRenderer(SDL_Renderer * renderer) +{ + DDRAW_RenderData *data = (DDRAW_RenderData *) renderer->driverdata; + + if (data) { + data->primary->lpVtbl->Release(data->primary); + SDL_free(data); + } + SDL_free(renderer); +} + +#endif /* SDL_VIDEO_RENDER_DDRAW */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_ceddrawrender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_ceddrawrender.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,31 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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 + + Stefan Klug + klug.stefan@gmx.de +*/ +#include "SDL_config.h" + +#if SDL_VIDEO_RENDER_DDRAW +extern void DDRAW_AddRenderDriver(_THIS); +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_d3drender.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_d3drender.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,1533 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#if SDL_VIDEO_RENDER_D3D + +#include "SDL_windowsvideo.h" +#include "../SDL_yuv_sw_c.h" + +#ifdef ASSEMBLE_SHADER +/////////////////////////////////////////////////////////////////////////// +// ID3DXBuffer: +// ------------ +// The buffer object is used by D3DX to return arbitrary size data. +// +// GetBufferPointer - +// Returns a pointer to the beginning of the buffer. +// +// GetBufferSize - +// Returns the size of the buffer, in bytes. +/////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXBuffer ID3DXBuffer; +typedef interface ID3DXBuffer *LPD3DXBUFFER; + +// {8BA5FB08-5195-40e2-AC58-0D989C3A0102} +DEFINE_GUID(IID_ID3DXBuffer, +0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2); + +#undef INTERFACE +#define INTERFACE ID3DXBuffer + +typedef interface ID3DXBuffer { + const struct ID3DXBufferVtbl FAR* lpVtbl; +} ID3DXBuffer; +typedef const struct ID3DXBufferVtbl ID3DXBufferVtbl; +const struct ID3DXBufferVtbl +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBuffer + STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE; + STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE; +}; + +HRESULT WINAPI + D3DXAssembleShader( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST LPVOID* pDefines, + LPVOID pInclude, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs); + +#endif /* ASSEMBLE_SHADER */ + + +/* Direct3D renderer implementation */ + +#if 1 /* This takes more memory but you won't lose your texture data */ +#define D3DPOOL_SDL D3DPOOL_MANAGED +#define SDL_MEMORY_POOL_MANAGED +#else +#define D3DPOOL_SDL D3DPOOL_DEFAULT +#define SDL_MEMORY_POOL_DEFAULT +#endif + +static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags); +static int D3D_DisplayModeChanged(SDL_Renderer * renderer); +static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static int D3D_QueryTexturePixels(SDL_Renderer * renderer, + SDL_Texture * texture, void **pixels, + int *pitch); +static int D3D_SetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, + int ncolors); +static int D3D_GetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, SDL_Color * colors, + int firstcolor, int ncolors); +static int D3D_SetTextureColorMod(SDL_Renderer * renderer, + SDL_Texture * texture); +static int D3D_SetTextureAlphaMod(SDL_Renderer * renderer, + SDL_Texture * texture); +static int D3D_SetTextureBlendMode(SDL_Renderer * renderer, + SDL_Texture * texture); +static int D3D_SetTextureScaleMode(SDL_Renderer * renderer, + SDL_Texture * texture); +static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, + int pitch); +static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, + void **pixels, int *pitch); +static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static void D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, + int numrects, const SDL_Rect * rects); +static int D3D_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, int count); +static int D3D_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, int count); +static int D3D_RenderDrawRects(SDL_Renderer * renderer, + const SDL_Rect ** rects, int count); +static int D3D_RenderFillRects(SDL_Renderer * renderer, + const SDL_Rect ** rects, int count); +static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect); +static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, void * pixels, int pitch); +static int D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, const void * pixels, int pitch); +static void D3D_RenderPresent(SDL_Renderer * renderer); +static void D3D_DestroyTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static void D3D_DestroyRenderer(SDL_Renderer * renderer); + + +SDL_RenderDriver D3D_RenderDriver = { + D3D_CreateRenderer, + { + "d3d", + (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY | + SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | + SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_PRESENTVSYNC | + SDL_RENDERER_ACCELERATED), + (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR | + SDL_TEXTUREMODULATE_ALPHA), + (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | + SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD), + (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST | + SDL_SCALEMODE_SLOW | SDL_SCALEMODE_BEST), + 0, + {0}, + 0, + 0} +}; + +typedef struct +{ + IDirect3D9 *d3d; + IDirect3DDevice9 *device; + UINT adapter; + D3DPRESENT_PARAMETERS pparams; + LPDIRECT3DPIXELSHADER9 ps_mask; + SDL_bool beginScene; +} D3D_RenderData; + +typedef struct +{ + SDL_SW_YUVTexture *yuv; + Uint32 format; + IDirect3DTexture9 *texture; +} D3D_TextureData; + +typedef struct +{ + float x, y, z; + float rhw; + DWORD color; + float u, v; +} Vertex; + +static void +D3D_SetError(const char *prefix, HRESULT result) +{ + const char *error; + + switch (result) { + case D3DERR_WRONGTEXTUREFORMAT: + error = "WRONGTEXTUREFORMAT"; + break; + case D3DERR_UNSUPPORTEDCOLOROPERATION: + error = "UNSUPPORTEDCOLOROPERATION"; + break; + case D3DERR_UNSUPPORTEDCOLORARG: + error = "UNSUPPORTEDCOLORARG"; + break; + case D3DERR_UNSUPPORTEDALPHAOPERATION: + error = "UNSUPPORTEDALPHAOPERATION"; + break; + case D3DERR_UNSUPPORTEDALPHAARG: + error = "UNSUPPORTEDALPHAARG"; + break; + case D3DERR_TOOMANYOPERATIONS: + error = "TOOMANYOPERATIONS"; + break; + case D3DERR_CONFLICTINGTEXTUREFILTER: + error = "CONFLICTINGTEXTUREFILTER"; + break; + case D3DERR_UNSUPPORTEDFACTORVALUE: + error = "UNSUPPORTEDFACTORVALUE"; + break; + case D3DERR_CONFLICTINGRENDERSTATE: + error = "CONFLICTINGRENDERSTATE"; + break; + case D3DERR_UNSUPPORTEDTEXTUREFILTER: + error = "UNSUPPORTEDTEXTUREFILTER"; + break; + case D3DERR_CONFLICTINGTEXTUREPALETTE: + error = "CONFLICTINGTEXTUREPALETTE"; + break; + case D3DERR_DRIVERINTERNALERROR: + error = "DRIVERINTERNALERROR"; + break; + case D3DERR_NOTFOUND: + error = "NOTFOUND"; + break; + case D3DERR_MOREDATA: + error = "MOREDATA"; + break; + case D3DERR_DEVICELOST: + error = "DEVICELOST"; + break; + case D3DERR_DEVICENOTRESET: + error = "DEVICENOTRESET"; + break; + case D3DERR_NOTAVAILABLE: + error = "NOTAVAILABLE"; + break; + case D3DERR_OUTOFVIDEOMEMORY: + error = "OUTOFVIDEOMEMORY"; + break; + case D3DERR_INVALIDDEVICE: + error = "INVALIDDEVICE"; + break; + case D3DERR_INVALIDCALL: + error = "INVALIDCALL"; + break; + case D3DERR_DRIVERINVALIDCALL: + error = "DRIVERINVALIDCALL"; + break; + case D3DERR_WASSTILLDRAWING: + error = "WASSTILLDRAWING"; + break; + default: + error = "UNKNOWN"; + break; + } + SDL_SetError("%s: %s", prefix, error); +} + +static D3DFORMAT +PixelFormatToD3DFMT(Uint32 format) +{ + switch (format) { + case SDL_PIXELFORMAT_INDEX8: + return D3DFMT_P8; + case SDL_PIXELFORMAT_RGB332: + return D3DFMT_R3G3B2; + case SDL_PIXELFORMAT_RGB444: + return D3DFMT_X4R4G4B4; + case SDL_PIXELFORMAT_RGB555: + return D3DFMT_X1R5G5B5; + case SDL_PIXELFORMAT_ARGB4444: + return D3DFMT_A4R4G4B4; + case SDL_PIXELFORMAT_ARGB1555: + return D3DFMT_A1R5G5B5; + case SDL_PIXELFORMAT_RGB565: + return D3DFMT_R5G6B5; + case SDL_PIXELFORMAT_RGB888: + return D3DFMT_X8R8G8B8; + case SDL_PIXELFORMAT_ARGB8888: + return D3DFMT_A8R8G8B8; + case SDL_PIXELFORMAT_ARGB2101010: + return D3DFMT_A2R10G10B10; + case SDL_PIXELFORMAT_YV12: + return MAKEFOURCC('Y','V','1','2'); + case SDL_PIXELFORMAT_IYUV: + return MAKEFOURCC('I','4','2','0'); + case SDL_PIXELFORMAT_UYVY: + return D3DFMT_UYVY; + case SDL_PIXELFORMAT_YUY2: + return D3DFMT_YUY2; + default: + return D3DFMT_UNKNOWN; + } +} + +static UINT D3D_FindAdapter(IDirect3D9 * d3d, SDL_VideoDisplay * display) +{ + SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; + UINT adapter, count; + + count = IDirect3D9_GetAdapterCount(d3d); + for (adapter = 0; adapter < count; ++adapter) { + HRESULT result; + D3DADAPTER_IDENTIFIER9 info; + char *name; + + result = IDirect3D9_GetAdapterIdentifier(d3d, adapter, 0, &info); + if (FAILED(result)) { + continue; + } + name = WIN_StringToUTF8(displaydata->DeviceName); + if (SDL_strcmp(name, info.DeviceName) == 0) { + SDL_free(name); + return adapter; + } + SDL_free(name); + } + + /* This should never happen, but just in case... */ + return D3DADAPTER_DEFAULT; +} + +static SDL_bool +D3D_IsTextureFormatAvailable(IDirect3D9 * d3d, UINT adapter, + Uint32 display_format, + Uint32 texture_format) +{ + HRESULT result; + + result = IDirect3D9_CheckDeviceFormat(d3d, adapter, + D3DDEVTYPE_HAL, + PixelFormatToD3DFMT(display_format), + 0, + D3DRTYPE_TEXTURE, + PixelFormatToD3DFMT + (texture_format)); + return FAILED(result) ? SDL_FALSE : SDL_TRUE; +} + +static void +UpdateYUVTextureData(SDL_Texture * texture) +{ + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + SDL_Rect rect; + RECT d3drect; + D3DLOCKED_RECT locked; + HRESULT result; + + d3drect.left = 0; + d3drect.right = texture->w; + d3drect.top = 0; + d3drect.bottom = texture->h; + + result = + IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0); + if (FAILED(result)) { + return; + } + + rect.x = 0; + rect.y = 0; + rect.w = texture->w; + rect.h = texture->h; + SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w, + texture->h, locked.pBits, locked.Pitch); + + IDirect3DTexture9_UnlockRect(data->texture, 0); +} + +void +D3D_AddRenderDriver(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_RendererInfo *info = &D3D_RenderDriver.info; + + if (data->d3d) { + int i, j; + int formats[] = { + SDL_PIXELFORMAT_INDEX8, + SDL_PIXELFORMAT_RGB332, + SDL_PIXELFORMAT_RGB444, + SDL_PIXELFORMAT_RGB555, + SDL_PIXELFORMAT_ARGB4444, + SDL_PIXELFORMAT_ARGB1555, + SDL_PIXELFORMAT_RGB565, + SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ARGB2101010, + }; + + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + SDL_DisplayMode *mode = &display->desktop_mode; + UINT adapter = D3D_FindAdapter(data->d3d, display); + + /* Get the matching D3D adapter for this display */ + info->num_texture_formats = 0; + for (j = 0; j < SDL_arraysize(formats); ++j) { + if (D3D_IsTextureFormatAvailable + (data->d3d, adapter, mode->format, formats[j])) { + info->texture_formats[info->num_texture_formats++] = + formats[j]; + } + } + info->texture_formats[info->num_texture_formats++] = + SDL_PIXELFORMAT_YV12; + info->texture_formats[info->num_texture_formats++] = + SDL_PIXELFORMAT_IYUV; + info->texture_formats[info->num_texture_formats++] = + SDL_PIXELFORMAT_YUY2; + info->texture_formats[info->num_texture_formats++] = + SDL_PIXELFORMAT_UYVY; + info->texture_formats[info->num_texture_formats++] = + SDL_PIXELFORMAT_YVYU; + + SDL_AddRenderDriver(display, &D3D_RenderDriver); + } + } +} + +SDL_Renderer * +D3D_CreateRenderer(SDL_Window * window, Uint32 flags) +{ + SDL_VideoDisplay *display = window->display; + SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata; + SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; + SDL_Renderer *renderer; + D3D_RenderData *data; + HRESULT result; + D3DPRESENT_PARAMETERS pparams; + IDirect3DSwapChain9 *chain; + D3DCAPS9 caps; + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + D3D_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + data->d3d = videodata->d3d; + + videodata->render = RENDER_D3D; + + renderer->DisplayModeChanged = D3D_DisplayModeChanged; + renderer->CreateTexture = D3D_CreateTexture; + renderer->QueryTexturePixels = D3D_QueryTexturePixels; + renderer->SetTexturePalette = D3D_SetTexturePalette; + renderer->GetTexturePalette = D3D_GetTexturePalette; + renderer->SetTextureColorMod = D3D_SetTextureColorMod; + renderer->SetTextureAlphaMod = D3D_SetTextureAlphaMod; + renderer->SetTextureBlendMode = D3D_SetTextureBlendMode; + renderer->SetTextureScaleMode = D3D_SetTextureScaleMode; + renderer->UpdateTexture = D3D_UpdateTexture; + renderer->LockTexture = D3D_LockTexture; + renderer->UnlockTexture = D3D_UnlockTexture; + renderer->DirtyTexture = D3D_DirtyTexture; + renderer->RenderDrawPoints = D3D_RenderDrawPoints; + renderer->RenderDrawLines = D3D_RenderDrawLines; + renderer->RenderDrawRects = D3D_RenderDrawRects; + renderer->RenderFillRects = D3D_RenderFillRects; + renderer->RenderCopy = D3D_RenderCopy; + renderer->RenderReadPixels = D3D_RenderReadPixels; + renderer->RenderWritePixels = D3D_RenderWritePixels; + renderer->RenderPresent = D3D_RenderPresent; + renderer->DestroyTexture = D3D_DestroyTexture; + renderer->DestroyRenderer = D3D_DestroyRenderer; + renderer->info = D3D_RenderDriver.info; + renderer->window = window; + renderer->driverdata = data; + + renderer->info.flags = SDL_RENDERER_ACCELERATED; + + SDL_zero(pparams); + pparams.BackBufferWidth = window->w; + pparams.BackBufferHeight = window->h; + if (window->flags & SDL_WINDOW_FULLSCREEN) { + pparams.BackBufferFormat = + PixelFormatToD3DFMT(window->fullscreen_mode.format); + } else { + pparams.BackBufferFormat = D3DFMT_UNKNOWN; + } + if (flags & SDL_RENDERER_PRESENTFLIP2) { + pparams.BackBufferCount = 2; + pparams.SwapEffect = D3DSWAPEFFECT_FLIP; + } else if (flags & SDL_RENDERER_PRESENTFLIP3) { + pparams.BackBufferCount = 3; + pparams.SwapEffect = D3DSWAPEFFECT_FLIP; + } else if (flags & SDL_RENDERER_PRESENTCOPY) { + pparams.BackBufferCount = 1; + pparams.SwapEffect = D3DSWAPEFFECT_COPY; + } else { + pparams.BackBufferCount = 1; + pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; + } + if (window->flags & SDL_WINDOW_FULLSCREEN) { + pparams.Windowed = FALSE; + pparams.FullScreen_RefreshRateInHz = + window->fullscreen_mode.refresh_rate; + } else { + pparams.Windowed = TRUE; + pparams.FullScreen_RefreshRateInHz = 0; + } + if (flags & SDL_RENDERER_PRESENTVSYNC) { + pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } else { + pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + + data->adapter = D3D_FindAdapter(videodata->d3d, display); + IDirect3D9_GetDeviceCaps(videodata->d3d, data->adapter, + D3DDEVTYPE_HAL, &caps); + + result = IDirect3D9_CreateDevice(videodata->d3d, data->adapter, + D3DDEVTYPE_HAL, + windowdata->hwnd, + (caps. + DevCaps & + D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? + D3DCREATE_HARDWARE_VERTEXPROCESSING : + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &pparams, &data->device); + if (FAILED(result)) { + D3D_DestroyRenderer(renderer); + D3D_SetError("CreateDevice()", result); + return NULL; + } + data->beginScene = SDL_TRUE; + + /* Get presentation parameters to fill info */ + result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); + if (FAILED(result)) { + D3D_DestroyRenderer(renderer); + D3D_SetError("GetSwapChain()", result); + return NULL; + } + result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); + if (FAILED(result)) { + IDirect3DSwapChain9_Release(chain); + D3D_DestroyRenderer(renderer); + D3D_SetError("GetPresentParameters()", result); + return NULL; + } + IDirect3DSwapChain9_Release(chain); + switch (pparams.SwapEffect) { + case D3DSWAPEFFECT_COPY: + renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; + break; + case D3DSWAPEFFECT_FLIP: + switch (pparams.BackBufferCount) { + case 2: + renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; + break; + case 3: + renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; + break; + } + break; + case D3DSWAPEFFECT_DISCARD: + renderer->info.flags |= SDL_RENDERER_PRESENTDISCARD; + break; + } + if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } + data->pparams = pparams; + + IDirect3DDevice9_GetDeviceCaps(data->device, &caps); + renderer->info.max_texture_width = caps.MaxTextureWidth; + renderer->info.max_texture_height = caps.MaxTextureHeight; + + /* Set up parameters for rendering */ + IDirect3DDevice9_SetVertexShader(data->device, NULL); + IDirect3DDevice9_SetFVF(data->device, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, + D3DCULL_NONE); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); + /* Enable color modulation by diffuse color */ + IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP, + D3DTOP_MODULATE); + IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1, + D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2, + D3DTA_DIFFUSE); + /* Enable alpha modulation by diffuse alpha */ + IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP, + D3DTOP_MODULATE); + IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1, + D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2, + D3DTA_DIFFUSE); + /* Disable second texture stage, since we're done */ + IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP, + D3DTOP_DISABLE); + IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP, + D3DTOP_DISABLE); + + { +#ifdef ASSEMBLE_SHADER + const char *shader_text = +"ps_1_1\n" +"def c0, 0, 0, 0, 0.496\n" +"def c1, 0, 0, 0, 1\n" +"def c2, 0, 0, 0, -1\n" +"tex t0\n" +"mul r1, t0, v0\n" +"add r0, r1, c0\n" +"cnd r0, r0.a, c1, c2\n" +"add r0, r0, r1\n"; + LPD3DXBUFFER pCode; // buffer with the assembled shader code + LPD3DXBUFFER pErrorMsgs; // buffer with error messages + LPDWORD shader_data; + DWORD shader_size; + result = D3DXAssembleShader( shader_text, SDL_strlen(shader_text), NULL, NULL, 0, &pCode, &pErrorMsgs ); + if (FAILED(result)) { + D3D_SetError("D3DXAssembleShader()", result); + } + shader_data = (DWORD*)pCode->lpVtbl->GetBufferPointer(pCode); + shader_size = pCode->lpVtbl->GetBufferSize(pCode); +#else + const DWORD shader_data[] = { + 0xffff0101,0x00000051,0xa00f0000,0x00000000,0x00000000,0x00000000, + 0x3efdf3b6,0x00000051,0xa00f0001,0x00000000,0x00000000,0x00000000, + 0x3f800000,0x00000051,0xa00f0002,0x00000000,0x00000000,0x00000000, + 0xbf800000,0x00000042,0xb00f0000,0x00000005,0x800f0001,0xb0e40000, + 0x90e40000,0x00000002,0x800f0000,0x80e40001,0xa0e40000,0x00000050, + 0x800f0000,0x80ff0000,0xa0e40001,0xa0e40002,0x00000002,0x800f0000, + 0x80e40000,0x80e40001,0x0000ffff + }; +#endif + result = IDirect3DDevice9_CreatePixelShader(data->device, shader_data, &data->ps_mask); + if (FAILED(result)) { + D3D_SetError("CreatePixelShader()", result); + } + } + + return renderer; +} + +static int +D3D_Reset(SDL_Renderer * renderer) +{ + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + HRESULT result; + + result = IDirect3DDevice9_Reset(data->device, &data->pparams); + if (FAILED(result)) { + if (result == D3DERR_DEVICELOST) { + /* Don't worry about it, we'll reset later... */ + return 0; + } else { + D3D_SetError("Reset()", result); + return -1; + } + } + IDirect3DDevice9_SetVertexShader(data->device, NULL); + IDirect3DDevice9_SetFVF(data->device, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, + D3DCULL_NONE); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); + return 0; +} + +static int +D3D_DisplayModeChanged(SDL_Renderer * renderer) +{ + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + + data->pparams.BackBufferWidth = window->w; + data->pparams.BackBufferHeight = window->h; + if (window->flags & SDL_WINDOW_FULLSCREEN) { + data->pparams.BackBufferFormat = + PixelFormatToD3DFMT(window->fullscreen_mode.format); + } else { + data->pparams.BackBufferFormat = D3DFMT_UNKNOWN; + } + return D3D_Reset(renderer); +} + +static int +D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + Uint32 display_format = display->current_mode.format; + D3D_TextureData *data; + HRESULT result; + + data = (D3D_TextureData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + SDL_OutOfMemory(); + return -1; + } + + texture->driverdata = data; + + if (SDL_ISPIXELFORMAT_FOURCC(texture->format) && + (texture->format != SDL_PIXELFORMAT_YUY2 || + !D3D_IsTextureFormatAvailable(renderdata->d3d, renderdata->adapter, + display_format, texture->format)) + && (texture->format != SDL_PIXELFORMAT_YVYU + || !D3D_IsTextureFormatAvailable(renderdata->d3d, renderdata->adapter, + display_format, texture->format))) { + data->yuv = + SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); + if (!data->yuv) { + return -1; + } + data->format = display->current_mode.format; + } else { + data->format = texture->format; + } + + result = + IDirect3DDevice9_CreateTexture(renderdata->device, texture->w, + texture->h, 1, 0, + PixelFormatToD3DFMT(data->format), + D3DPOOL_SDL, &data->texture, NULL); + if (FAILED(result)) { + D3D_SetError("CreateTexture()", result); + return -1; + } + + return 0; +} + +static int +D3D_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, + void **pixels, int *pitch) +{ + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + + if (data->yuv) { + return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch); + } else { + /* D3D textures don't have their pixels hanging out */ + return -1; + } +} + +static int +D3D_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, int ncolors) +{ + D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + + return 0; +} + +static int +D3D_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + SDL_Color * colors, int firstcolor, int ncolors) +{ + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + + return 0; +} + +static int +D3D_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + return 0; +} + +static int +D3D_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + return 0; +} + +static int +D3D_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) +{ + switch (texture->blendMode) { + case SDL_BLENDMODE_NONE: + case SDL_BLENDMODE_MASK: + case SDL_BLENDMODE_BLEND: + case SDL_BLENDMODE_ADD: + case SDL_BLENDMODE_MOD: + return 0; + default: + SDL_Unsupported(); + texture->blendMode = SDL_BLENDMODE_NONE; + return -1; + } +} + +static int +D3D_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) +{ + switch (texture->scaleMode) { + case SDL_SCALEMODE_NONE: + case SDL_SCALEMODE_FAST: + case SDL_SCALEMODE_SLOW: + case SDL_SCALEMODE_BEST: + return 0; + default: + SDL_Unsupported(); + texture->scaleMode = SDL_SCALEMODE_NONE; + return -1; + } + return 0; +} + +static int +D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, int pitch) +{ + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; + + if (data->yuv) { + if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) { + return -1; + } + UpdateYUVTextureData(texture); + return 0; + } else { +#ifdef SDL_MEMORY_POOL_DEFAULT + IDirect3DTexture9 *temp; + RECT d3drect; + D3DLOCKED_RECT locked; + const Uint8 *src; + Uint8 *dst; + int row, length; + HRESULT result; + + result = + IDirect3DDevice9_CreateTexture(renderdata->device, texture->w, + texture->h, 1, 0, + PixelFormatToD3DFMT(texture-> + format), + D3DPOOL_SYSTEMMEM, &temp, NULL); + if (FAILED(result)) { + D3D_SetError("CreateTexture()", result); + return -1; + } + + d3drect.left = rect->x; + d3drect.right = rect->x + rect->w; + d3drect.top = rect->y; + d3drect.bottom = rect->y + rect->h; + + result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0); + if (FAILED(result)) { + IDirect3DTexture9_Release(temp); + D3D_SetError("LockRect()", result); + return -1; + } + + src = pixels; + dst = locked.pBits; + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += locked.Pitch; + } + IDirect3DTexture9_UnlockRect(temp, 0); + + result = + IDirect3DDevice9_UpdateTexture(renderdata->device, + (IDirect3DBaseTexture9 *) temp, + (IDirect3DBaseTexture9 *) + data->texture); + IDirect3DTexture9_Release(temp); + if (FAILED(result)) { + D3D_SetError("UpdateTexture()", result); + return -1; + } +#else + RECT d3drect; + D3DLOCKED_RECT locked; + const Uint8 *src; + Uint8 *dst; + int row, length; + HRESULT result; + + d3drect.left = rect->x; + d3drect.right = rect->x + rect->w; + d3drect.top = rect->y; + d3drect.bottom = rect->y + rect->h; + + result = + IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, + 0); + if (FAILED(result)) { + D3D_SetError("LockRect()", result); + return -1; + } + + src = pixels; + dst = locked.pBits; + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += locked.Pitch; + } + IDirect3DTexture9_UnlockRect(data->texture, 0); +#endif // SDL_MEMORY_POOL_DEFAULT + + return 0; + } +} + +static int +D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, void **pixels, + int *pitch) +{ + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + + if (data->yuv) { + return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, + pitch); + } else { + RECT d3drect; + D3DLOCKED_RECT locked; + HRESULT result; + + d3drect.left = rect->x; + d3drect.right = rect->x + rect->w; + d3drect.top = rect->y; + d3drect.bottom = rect->y + rect->h; + + result = + IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, + markDirty ? 0 : + D3DLOCK_NO_DIRTY_UPDATE); + if (FAILED(result)) { + D3D_SetError("LockRect()", result); + return -1; + } + *pixels = locked.pBits; + *pitch = locked.Pitch; + return 0; + } +} + +static void +D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + + if (data->yuv) { + SDL_SW_UnlockYUVTexture(data->yuv); + UpdateYUVTextureData(texture); + } else { + IDirect3DTexture9_UnlockRect(data->texture, 0); + } +} + +static void +D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, + const SDL_Rect * rects) +{ + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + RECT d3drect; + int i; + + for (i = 0; i < numrects; ++i) { + const SDL_Rect *rect = &rects[i]; + + d3drect.left = rect->x; + d3drect.right = rect->x + rect->w; + d3drect.top = rect->y; + d3drect.bottom = rect->y + rect->h; + + IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect); + } +} + +static void +D3D_SetBlendMode(D3D_RenderData * data, int blendMode) +{ + switch (blendMode) { + case SDL_BLENDMODE_NONE: + IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE, + FALSE); + break; + case SDL_BLENDMODE_MASK: + case SDL_BLENDMODE_BLEND: + IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE, + TRUE); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND, + D3DBLEND_SRCALPHA); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND, + D3DBLEND_INVSRCALPHA); + break; + case SDL_BLENDMODE_ADD: + IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE, + TRUE); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND, + D3DBLEND_SRCALPHA); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND, + D3DBLEND_ONE); + break; + case SDL_BLENDMODE_MOD: + IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE, + TRUE); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND, + D3DBLEND_ZERO); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND, + D3DBLEND_SRCCOLOR); + break; + } +} + +static int +D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, + int count) +{ + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + DWORD color; + Vertex *vertices; + int i; + HRESULT result; + + if (data->beginScene) { + IDirect3DDevice9_BeginScene(data->device); + data->beginScene = SDL_FALSE; + } + + D3D_SetBlendMode(data, renderer->blendMode); + + result = + IDirect3DDevice9_SetTexture(data->device, 0, + (IDirect3DBaseTexture9 *) 0); + if (FAILED(result)) { + D3D_SetError("SetTexture()", result); + return -1; + } + + color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b); + + vertices = SDL_stack_alloc(Vertex, count); + for (i = 0; i < count; ++i) { + vertices[i].x = (float) points[i].x; + vertices[i].y = (float) points[i].y; + vertices[i].z = 0.0f; + vertices[i].rhw = 1.0f; + vertices[i].color = color; + vertices[i].u = 0.0f; + vertices[i].v = 0.0f; + } + result = + IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, count, + vertices, sizeof(*vertices)); + SDL_stack_free(vertices); + if (FAILED(result)) { + D3D_SetError("DrawPrimitiveUP()", result); + return -1; + } + return 0; +} + +static int +D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, + int count) +{ + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + DWORD color; + Vertex *vertices; + int i; + HRESULT result; + + if (data->beginScene) { + IDirect3DDevice9_BeginScene(data->device); + data->beginScene = SDL_FALSE; + } + + D3D_SetBlendMode(data, renderer->blendMode); + + result = + IDirect3DDevice9_SetTexture(data->device, 0, + (IDirect3DBaseTexture9 *) 0); + if (FAILED(result)) { + D3D_SetError("SetTexture()", result); + return -1; + } + + color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b); + + vertices = SDL_stack_alloc(Vertex, count); + for (i = 0; i < count; ++i) { + vertices[i].x = (float) points[i].x; + vertices[i].y = (float) points[i].y; + vertices[i].z = 0.0f; + vertices[i].rhw = 1.0f; + vertices[i].color = color; + vertices[i].u = 0.0f; + vertices[i].v = 0.0f; + } + result = + IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, count-1, + vertices, sizeof(*vertices)); + + /* DirectX 9 has the same line rasterization semantics as GDI, + so we need to close the endpoint of the line */ + if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { + vertices[0].x = (float) points[count-1].x; + vertices[0].y = (float) points[count-1].y; + result = IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, vertices, sizeof(*vertices)); + } + + SDL_stack_free(vertices); + if (FAILED(result)) { + D3D_SetError("DrawPrimitiveUP()", result); + return -1; + } + return 0; +} + +static int +D3D_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, + int count) +{ + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + DWORD color; + int i; + Vertex vertices[5]; + HRESULT result; + + if (data->beginScene) { + IDirect3DDevice9_BeginScene(data->device); + data->beginScene = SDL_FALSE; + } + + D3D_SetBlendMode(data, renderer->blendMode); + + result = + IDirect3DDevice9_SetTexture(data->device, 0, + (IDirect3DBaseTexture9 *) 0); + if (FAILED(result)) { + D3D_SetError("SetTexture()", result); + return -1; + } + + color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b); + + for (i = 0; i < SDL_arraysize(vertices); ++i) { + vertices[i].z = 0.0f; + vertices[i].rhw = 1.0f; + vertices[i].color = color; + vertices[i].u = 0.0f; + vertices[i].v = 0.0f; + } + + for (i = 0; i < count; ++i) { + const SDL_Rect *rect = rects[i]; + + vertices[0].x = (float) rect->x; + vertices[0].y = (float) rect->y; + + vertices[1].x = (float) rect->x+rect->w-1; + vertices[1].y = (float) rect->y; + + vertices[2].x = (float) rect->x+rect->w-1; + vertices[2].y = (float) rect->y+rect->h-1; + + vertices[3].x = (float) rect->x; + vertices[3].y = (float) rect->y+rect->h-1; + + vertices[4].x = (float) rect->x; + vertices[4].y = (float) rect->y; + + result = + IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, 4, + vertices, sizeof(*vertices)); + + if (FAILED(result)) { + D3D_SetError("DrawPrimitiveUP()", result); + return -1; + } + } + return 0; +} + +static int +D3D_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, + int count) +{ + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + DWORD color; + int i; + float minx, miny, maxx, maxy; + Vertex vertices[4]; + HRESULT result; + + if (data->beginScene) { + IDirect3DDevice9_BeginScene(data->device); + data->beginScene = SDL_FALSE; + } + + D3D_SetBlendMode(data, renderer->blendMode); + + result = + IDirect3DDevice9_SetTexture(data->device, 0, + (IDirect3DBaseTexture9 *) 0); + if (FAILED(result)) { + D3D_SetError("SetTexture()", result); + return -1; + } + + color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b); + + for (i = 0; i < count; ++i) { + const SDL_Rect *rect = rects[i]; + + minx = (float) rect->x; + miny = (float) rect->y; + maxx = (float) rect->x + rect->w; + maxy = (float) rect->y + rect->h; + + vertices[0].x = minx; + vertices[0].y = miny; + vertices[0].z = 0.0f; + vertices[0].rhw = 1.0f; + vertices[0].color = color; + vertices[0].u = 0.0f; + vertices[0].v = 0.0f; + + vertices[1].x = maxx; + vertices[1].y = miny; + vertices[1].z = 0.0f; + vertices[1].rhw = 1.0f; + vertices[1].color = color; + vertices[1].u = 0.0f; + vertices[1].v = 0.0f; + + vertices[2].x = maxx; + vertices[2].y = maxy; + vertices[2].z = 0.0f; + vertices[2].rhw = 1.0f; + vertices[2].color = color; + vertices[2].u = 0.0f; + vertices[2].v = 0.0f; + + vertices[3].x = minx; + vertices[3].y = maxy; + vertices[3].z = 0.0f; + vertices[3].rhw = 1.0f; + vertices[3].color = color; + vertices[3].u = 0.0f; + vertices[3].v = 0.0f; + + result = + IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, + 2, vertices, sizeof(*vertices)); + if (FAILED(result)) { + D3D_SetError("DrawPrimitiveUP()", result); + return -1; + } + } + return 0; +} + +static int +D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect) +{ + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; + LPDIRECT3DPIXELSHADER9 shader = NULL; + float minx, miny, maxx, maxy; + float minu, maxu, minv, maxv; + DWORD color; + Vertex vertices[4]; + HRESULT result; + + if (data->beginScene) { + IDirect3DDevice9_BeginScene(data->device); + data->beginScene = SDL_FALSE; + } + + minx = (float) dstrect->x - 0.5f; + miny = (float) dstrect->y - 0.5f; + maxx = (float) dstrect->x + dstrect->w - 0.5f; + maxy = (float) dstrect->y + dstrect->h - 0.5f; + + minu = (float) srcrect->x / texture->w; + maxu = (float) (srcrect->x + srcrect->w) / texture->w; + minv = (float) srcrect->y / texture->h; + maxv = (float) (srcrect->y + srcrect->h) / texture->h; + + color = D3DCOLOR_ARGB(texture->a, texture->r, texture->g, texture->b); + + vertices[0].x = minx; + vertices[0].y = miny; + vertices[0].z = 0.0f; + vertices[0].rhw = 1.0f; + vertices[0].color = color; + vertices[0].u = minu; + vertices[0].v = minv; + + vertices[1].x = maxx; + vertices[1].y = miny; + vertices[1].z = 0.0f; + vertices[1].rhw = 1.0f; + vertices[1].color = color; + vertices[1].u = maxu; + vertices[1].v = minv; + + vertices[2].x = maxx; + vertices[2].y = maxy; + vertices[2].z = 0.0f; + vertices[2].rhw = 1.0f; + vertices[2].color = color; + vertices[2].u = maxu; + vertices[2].v = maxv; + + vertices[3].x = minx; + vertices[3].y = maxy; + vertices[3].z = 0.0f; + vertices[3].rhw = 1.0f; + vertices[3].color = color; + vertices[3].u = minu; + vertices[3].v = maxv; + + D3D_SetBlendMode(data, texture->blendMode); + + if (texture->blendMode == SDL_BLENDMODE_MASK) { + shader = data->ps_mask; + } + + switch (texture->scaleMode) { + case SDL_SCALEMODE_NONE: + case SDL_SCALEMODE_FAST: + IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER, + D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER, + D3DTEXF_POINT); + break; + case SDL_SCALEMODE_SLOW: + IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER, + D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER, + D3DTEXF_LINEAR); + break; + case SDL_SCALEMODE_BEST: + IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER, + D3DTEXF_GAUSSIANQUAD); + IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER, + D3DTEXF_GAUSSIANQUAD); + break; + } + + result = + IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *) + texturedata->texture); + if (FAILED(result)) { + D3D_SetError("SetTexture()", result); + return -1; + } + if (shader) { + result = IDirect3DDevice9_SetPixelShader(data->device, shader); + if (FAILED(result)) { + D3D_SetError("SetShader()", result); + return -1; + } + } + result = + IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, + vertices, sizeof(*vertices)); + if (FAILED(result)) { + D3D_SetError("DrawPrimitiveUP()", result); + return -1; + } + if (shader) { + result = IDirect3DDevice9_SetPixelShader(data->device, NULL); + if (FAILED(result)) { + D3D_SetError("SetShader()", result); + return -1; + } + } + return 0; +} + +static int +D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, void * pixels, int pitch) +{ + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + D3DSURFACE_DESC desc; + LPDIRECT3DSURFACE9 backBuffer; + LPDIRECT3DSURFACE9 surface; + RECT d3drect; + D3DLOCKED_RECT locked; + HRESULT result; + + result = IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer); + if (FAILED(result)) { + D3D_SetError("GetBackBuffer()", result); + return -1; + } + + result = IDirect3DSurface9_GetDesc(backBuffer, &desc); + if (FAILED(result)) { + D3D_SetError("GetDesc()", result); + IDirect3DSurface9_Release(backBuffer); + return -1; + } + + result = IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL); + if (FAILED(result)) { + D3D_SetError("CreateOffscreenPlainSurface()", result); + IDirect3DSurface9_Release(backBuffer); + return -1; + } + + result = IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, surface); + if (FAILED(result)) { + D3D_SetError("GetRenderTargetData()", result); + IDirect3DSurface9_Release(surface); + IDirect3DSurface9_Release(backBuffer); + return -1; + } + + d3drect.left = rect->x; + d3drect.right = rect->x + rect->w; + d3drect.top = rect->y; + d3drect.bottom = rect->y + rect->h; + + result = IDirect3DSurface9_LockRect(surface, &locked, &d3drect, D3DLOCK_READONLY); + if (FAILED(result)) { + D3D_SetError("LockRect()", result); + IDirect3DSurface9_Release(surface); + IDirect3DSurface9_Release(backBuffer); + return -1; + } + + SDL_ConvertPixels(rect->w, rect->h, + display->current_mode.format, locked.pBits, locked.Pitch, + format, pixels, pitch); + + IDirect3DSurface9_UnlockRect(surface); + + IDirect3DSurface9_Release(surface); + IDirect3DSurface9_Release(backBuffer); + + return 0; +} + +static int +D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, const void * pixels, int pitch) +{ + /* Work in progress */ + SDL_Unsupported(); + return -1; +} + +static void +D3D_RenderPresent(SDL_Renderer * renderer) +{ + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + HRESULT result; + + if (!data->beginScene) { + IDirect3DDevice9_EndScene(data->device); + data->beginScene = SDL_TRUE; + } + + result = IDirect3DDevice9_TestCooperativeLevel(data->device); + if (result == D3DERR_DEVICELOST) { + /* We'll reset later */ + return; + } + if (result == D3DERR_DEVICENOTRESET) { + D3D_Reset(renderer); + } + result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL); + if (FAILED(result)) { + D3D_SetError("Present()", result); + } +} + +static void +D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + + if (!data) { + return; + } + if (data->yuv) { + SDL_SW_DestroyYUVTexture(data->yuv); + } + if (data->texture) { + IDirect3DTexture9_Release(data->texture); + } + SDL_free(data); + texture->driverdata = NULL; +} + +static void +D3D_DestroyRenderer(SDL_Renderer * renderer) +{ + D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + + if (data) { + if (data->device) { + IDirect3DDevice9_Release(data->device); + } + SDL_free(data); + } + SDL_free(renderer); +} + +#endif /* SDL_VIDEO_RENDER_D3D */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_d3drender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_d3drender.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,28 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#if SDL_VIDEO_RENDER_D3D +extern void D3D_AddRenderDriver(_THIS); +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_gapirender.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_gapirender.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,1281 @@ +/*************************************************************************** + * Copyright (C) 2010 by Andrey Afletdinov * + * * + * WinCE RAW/GAPI video driver * + * * + * Part of the SDL - (Simple DirectMedia Layer) * + * http://www.libsdl.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "SDL_config.h" + +#if SDL_VIDEO_RENDER_GAPI + +#include "SDL_windowsvideo.h" +#include "SDL_windowswindow.h" +#include "../SDL_yuv_sw_c.h" + +// RawFrameBufferInfo +typedef struct +{ + WORD wFormat; + WORD wBPP; + VOID *pFramePointer; + int cxStride; + int cyStride; + int cxPixels; + int cyPixels; +} RawFrameBufferInfo; + +// GXDeviceInfo +typedef struct +{ + long Version; + void* pvFrameBuffer; + unsigned long cbStride; + unsigned long cxWidth; + unsigned long cyHeight; + unsigned long cBPP; + unsigned long ffFormat; + char unknown[0x84 - 7 * 4]; +} GXDeviceInfo; + +// wince: GXDisplayProperties +struct GXDisplayProperties +{ + DWORD cxWidth; + DWORD cyHeight; + long cbxPitch; + long cbyPitch; + long cBPP; + DWORD ffFormat; +}; + +// gx.dll +typedef int (*PFNGXOpenDisplay)(HWND hWnd, DWORD dwFlags); +typedef int (*PFNGXCloseDisplay)(); +typedef void* (*PFNGXBeginDraw)(); +typedef int (*PFNGXEndDraw)(); +typedef struct GXDisplayProperties (*PFNGXGetDisplayProperties)(); +typedef int (*PFNGXSuspend)(); +typedef int (*PFNGXResume)(); + +typedef struct +{ + // gx.dll + HMODULE hGapiLib; + PFNGXOpenDisplay GXOpenDisplay; + PFNGXCloseDisplay GXCloseDisplay; + PFNGXBeginDraw GXBeginDraw; + PFNGXEndDraw GXEndDraw; + PFNGXGetDisplayProperties GXGetDisplayProperties; + PFNGXSuspend GXSuspend; + PFNGXResume GXResume; +} GapiInfo; + +//#ifndef DM_DISPLAYORIENTATION +//#define DM_DISPLAYORIENTATION 0x00800000L +//#endif + +#define FORMAT_565 1 +#define FORMAT_555 2 +#define FORMAT_OTHER 3 + +#define GETRAWFRAMEBUFFER 0x00020001 +#define GETGXINFO 0x00020000 + +#define kfPalette 0x10 +#define kfDirect 0x20 +#define kfDirect555 0x40 +#define kfDirect565 0x80 + +#define GX_FULLSCREEN 0x01 + +enum ScreenOrientation { ORIENTATION_UNKNOWN = -1, ORIENTATION_UP = DMDO_0, ORIENTATION_DOWN = DMDO_180, ORIENTATION_LEFT = DMDO_270, ORIENTATION_RIGHT = DMDO_90 }; +enum ScreenGeometry { GEOMETRY_UNKNOWN, GEOMETRY_PORTRAIT, GEOMETRY_LANDSCAPE, GEOMETRY_SQUARE }; +enum FrameBufferFlags { FB_SKIP_OFFSET = 0x0001, FB_RAW_MODE = 0x0002, FB_SUSPENDED = 0x0004 }; + +// private framebuffer info +typedef struct +{ + int width; + int height; + int xpitch; + int ypitch; + int offset; +} FrameBufferInfo; + +// private display data +typedef struct +{ + unsigned char* pixels; // video memory + int format; // video format + FrameBufferInfo fb; // framebuffer geometry + GapiInfo* gapi; // GAPI module + int userOrientation; + int systemOrientation; + int hardwareGeometry; + int flags; // fb flags + float scale; // scale pointer position + int debug; + +} WINCE_RenderData; + +typedef struct +{ + SDL_SW_YUVTexture *yuv; + Uint32 format; + void *pixels; + int pitch; + +} WINCE_TextureData; + + +// system func +SDL_Renderer* WINCE_CreateRenderer(SDL_Window* window, Uint32 flags); +void WINCE_DestroyRenderer(SDL_Renderer* renderer); + +int WINCE_CreateTexture(SDL_Renderer* renderer, SDL_Texture* texture); +void WINCE_DestroyTexture(SDL_Renderer* renderer, SDL_Texture* texture); +int WINCE_QueryTexturePixels(SDL_Renderer* renderer, SDL_Texture* texture, void** pixels, int* pitch); +int WINCE_UpdateTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, const void* pixels, int pitch); +int WINCE_LockTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, int dirty, void** pixels, int* pitch); +void WINCE_UnlockTexture(SDL_Renderer* renderer, SDL_Texture* texture); + +int WINCE_Available(void); +void WINCE_SetupOrientation(WINCE_RenderData* data, int width, int height); + +int WINCE_RenderCopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srect, const SDL_Rect* drect); +void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible); + +void WINCE_RenderPresent(SDL_Renderer* renderer); +int WINCE_RenderDrawPoints(SDL_Renderer* renderer, const SDL_Point* points, int count); +int WINCE_RenderDrawLines(SDL_Renderer* renderer, const SDL_Point* points, int count); +int WINCE_RenderDrawRects(SDL_Renderer* renderer, const SDL_Rect ** rects, int count); +int WINCE_RenderFillRects(SDL_Renderer* renderer, const SDL_Rect** rects, int count); + +void WINCE_PointerCoordinateTransform(SDL_Window* window, POINT* pt); +void WINCE_DumpVideoInfo(WINCE_RenderData* data); +void WINCE_PortraitTransform(WINCE_RenderData* data, int width, int height); +void WINCE_LandscapeTransform(WINCE_RenderData* data, int width, int height); +void WINCE_SquareTransform(WINCE_RenderData* data, int width, int height); +int WINCE_FixedGeometry(FrameBufferInfo* fb, int bpp, int debug); +int WINCE_GetDMOrientation(void); +int WINCE_SetDMOrientation(int orientation); +void WINCE_UpdateYUVTextureData(SDL_Texture* texture); + +// gapi engine specific +int GAPI_Init(WINCE_RenderData* data, HWND hwnd); +void GAPI_Quit(WINCE_RenderData* data); + +// raw engine specific +int RAW_Init(WINCE_RenderData* data); +void RAW_Quit(WINCE_RenderData* data); + +// tools +void FrameBufferRotate(FrameBufferInfo* src, int orientation); +int GetFrameBufferOrientation(const FrameBufferInfo* src); +void PointerRotate(POINT* pt, const FrameBufferInfo* fb, int orientation); +void FrameBufferInitialize(FrameBufferInfo* fb); +void FrameBufferDumpInfo(const FrameBufferInfo* fb, const char*); +const char* GetOrientationName(int orientation); +void UpdateLine16to16(const FrameBufferInfo* fb, const Uint16* src, Uint16* dst, Uint16 width); + +// stdlib +inline int __abs(int x){ return x < 0 ? -x : x; }; +inline void __swap(int* a, int* b){ int t = *a; *a = *b; *b = t; }; + +#define GAPI_RENDER_NAME "gapi" +#define RAW_RENDER_NAME "raw" +// +SDL_RenderDriver GAPI_RenderDriver = { + WINCE_CreateRenderer, + { + GAPI_RENDER_NAME, + (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD), + (SDL_TEXTUREMODULATE_NONE), + (SDL_BLENDMODE_NONE), + (SDL_SCALEMODE_NONE), + 7, + { + SDL_PIXELFORMAT_RGB555, + SDL_PIXELFORMAT_RGB565, + SDL_PIXELFORMAT_YV12, + SDL_PIXELFORMAT_IYUV, + SDL_PIXELFORMAT_YUY2, + SDL_PIXELFORMAT_UYVY, + SDL_PIXELFORMAT_YVYU + }, + 0, + 0 + } +}; + +SDL_RenderDriver RAW_RenderDriver = { + WINCE_CreateRenderer, + { + RAW_RENDER_NAME, + (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD), + (SDL_TEXTUREMODULATE_NONE), + (SDL_BLENDMODE_NONE), + (SDL_SCALEMODE_NONE), + 7, + { + SDL_PIXELFORMAT_RGB555, + SDL_PIXELFORMAT_RGB565, + SDL_PIXELFORMAT_YV12, + SDL_PIXELFORMAT_IYUV, + SDL_PIXELFORMAT_YUY2, + SDL_PIXELFORMAT_UYVY, + SDL_PIXELFORMAT_YVYU + }, + 0, + 0 + } +}; + +int WINCE_Available(void) +{ + const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER"); + + // raw check + RawFrameBufferInfo rfbi = { 0 }; + HDC hdc = GetDC(NULL); + int render_raw = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi); + ReleaseDC(NULL, hdc); + + if(render_raw != 0 && rfbi.cxPixels != 0 && rfbi.cyPixels != 0 && + rfbi.pFramePointer != 0 && rfbi.cxStride != 0 && rfbi.cyStride != 0) + render_raw = 1; + + if(preferably && 0 == SDL_strcasecmp(preferably, RAW_RENDER_NAME)) return 0 != render_raw; + + // gapi check + HMODULE render_gapi = LoadLibrary(TEXT("\\Windows\\gx.dll")); + if(0 == render_gapi) + render_gapi = LoadLibrary(TEXT("gx.dll")); + FreeLibrary(render_gapi); + + if(preferably && 0 == SDL_strcasecmp(preferably, GAPI_RENDER_NAME)) return 0 != render_gapi; + + return 0 != render_raw || 0 != render_gapi; +} + +void WINCE_AddRenderDriver(_THIS) +{ + HDC hdc; + HMODULE render_gapi; + int render_raw, ii; + const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER"); + + // raw check + RawFrameBufferInfo rfbi = { 0 }; + hdc = GetDC(NULL); + render_raw = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi); + ReleaseDC(NULL, hdc); + + if(render_raw != 0 && rfbi.cxPixels != 0 && rfbi.cyPixels != 0 && + rfbi.pFramePointer != 0 && rfbi.cxStride != 0 && rfbi.cyStride != 0) + render_raw = 1; + + // gapi check + render_gapi = LoadLibrary(TEXT("\\Windows\\gx.dll")); + if(0 == render_gapi) + render_gapi = LoadLibrary(TEXT("gx.dll")); + + if(render_gapi) + FreeLibrary(render_gapi); + + for(ii = 0; ii < _this->num_displays; ++ii) + { + if(preferably) + { + if(0 == SDL_strcasecmp(preferably, RAW_RENDER_NAME) && render_raw) + SDL_AddRenderDriver(&_this->displays[ii], &RAW_RenderDriver); + else + if(0 == SDL_strcasecmp(preferably, GAPI_RENDER_NAME) && render_gapi) + SDL_AddRenderDriver(&_this->displays[ii], &GAPI_RenderDriver); + } + else + { + if(render_raw) + SDL_AddRenderDriver(&_this->displays[ii], &RAW_RenderDriver); + if(render_gapi) + SDL_AddRenderDriver(&_this->displays[ii], &GAPI_RenderDriver); + } + } +} + +SDL_Renderer* WINCE_CreateRenderer(SDL_Window* window, Uint32 flags) +{ + SDL_VideoDisplay* display = window->display; + SDL_DisplayMode* displayMode = &display->current_mode; + SDL_WindowData* windowdata = (SDL_WindowData *) window->driverdata; + SDL_Renderer* renderer; + WINCE_RenderData* data; + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + if(!(window->flags & SDL_WINDOW_FULLSCREEN)) + window->flags |= SDL_WINDOW_FULLSCREEN; + + if(!SDL_PixelFormatEnumToMasks(displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) + { + SDL_SetError("Unknown display format"); + return NULL; + } + + switch(window->fullscreen_mode.format) + { + case SDL_PIXELFORMAT_RGB555: + case SDL_PIXELFORMAT_RGB565: + break; + + default: + SDL_SetError("Support only 16 or 15 bpp"); + return NULL; + } + + renderer = (SDL_Renderer*) SDL_calloc(1, sizeof(SDL_Renderer)); + if(!renderer) + { + SDL_OutOfMemory(); + return NULL; + } + + data = (WINCE_RenderData*) SDL_calloc(1, sizeof(WINCE_RenderData)); + if(!data) + { + WINCE_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + + // initialize internal engine + if(!RAW_Init(data) && !GAPI_Init(data, windowdata->hwnd)) + { + WINCE_DestroyRenderer(renderer); + return NULL; + } + + + // set debug + data->debug = SDL_getenv("DEBUG_VIDEO_GAPI") || SDL_getenv("GAPI_RENDERER_DEBUG") ? 1 : 0; +#if defined(DEBUG_VIDEO_GAPI) || defined(GAPI_RENDERER_DEBUG) + data->debug = 1; +#endif + + windowdata->videodata->render = data->gapi ? RENDER_GAPI : RENDER_RAW; + windowdata->videodata->CoordTransform = WINCE_PointerCoordinateTransform; + + window->display->device->MaximizeWindow = NULL; + window->display->device->MinimizeWindow = NULL; + + WINCE_SetupOrientation(data, window->w, window->h); + + renderer->CreateTexture = WINCE_CreateTexture; + renderer->DestroyTexture = WINCE_DestroyTexture; + renderer->QueryTexturePixels = WINCE_QueryTexturePixels; + renderer->UpdateTexture = WINCE_UpdateTexture; + renderer->LockTexture = WINCE_LockTexture; + renderer->UnlockTexture = WINCE_UnlockTexture; + + renderer->RenderCopy = WINCE_RenderCopy; + renderer->DestroyRenderer = WINCE_DestroyRenderer; + + renderer->RenderPresent = WINCE_RenderPresent; + renderer->RenderDrawPoints = WINCE_RenderDrawPoints; + renderer->RenderDrawLines = WINCE_RenderDrawLines; + renderer->RenderDrawRects = WINCE_RenderDrawRects; + renderer->RenderFillRects = WINCE_RenderFillRects; + + renderer->info = data->gapi ? GAPI_RenderDriver.info : RAW_RenderDriver.info; + + renderer->window = window; + renderer->driverdata = data; + + return renderer; +} + +void WINCE_DestroyRenderer(SDL_Renderer* renderer) +{ + WINCE_RenderData *renderdata = (WINCE_RenderData*) renderer->driverdata; + + if(renderdata) + { + if(renderdata->gapi) + GAPI_Quit(renderdata); + else + RAW_Quit(renderdata); + + SDL_free(renderdata); + } + + SDL_free(renderer); +} + +int WINCE_CreateTexture(SDL_Renderer* renderer, SDL_Texture* texture) +{ + WINCE_TextureData* texturedata = (WINCE_TextureData*) SDL_calloc(1, sizeof(WINCE_TextureData)); + if(NULL == texturedata) + { + SDL_OutOfMemory(); + return -1; + } + + texturedata->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); + texturedata->pixels = SDL_malloc(texture->h * texturedata->pitch); + if(NULL == texturedata->pixels) + { + SDL_OutOfMemory(); + return -1; + } + + if(SDL_ISPIXELFORMAT_FOURCC(texture->format)) + { + texturedata->yuv = SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); + if(NULL == texturedata->yuv) + { + SDL_OutOfMemory(); + return -1; + } + SDL_Window* window = renderer->window; + SDL_VideoDisplay* display = window->display; + texturedata->format = display->current_mode.format; + } + else + { + texturedata->yuv = NULL; + texturedata->format = texture->format; + } + + texture->driverdata = texturedata; + + return 0; +} + +void WINCE_DestroyTexture(SDL_Renderer* renderer, SDL_Texture* texture) +{ + WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata; + + if(texturedata) + { + if(texturedata->yuv) SDL_SW_DestroyYUVTexture(texturedata->yuv); + if(texturedata->pixels) SDL_free(texturedata->pixels); + SDL_free(texturedata); + texture->driverdata = NULL; + } +} + +int WINCE_QueryTexturePixels(SDL_Renderer* renderer, SDL_Texture* texture, void** pixels, int* pitch) +{ + WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata; + + if(texturedata->yuv) + return SDL_SW_QueryYUVTexturePixels(texturedata->yuv, pixels, pitch); + + *pixels = texturedata->pixels; + *pitch = texturedata->pitch; + + return 0; +} + +int WINCE_UpdateTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, const void* pixels, int pitch) +{ + WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata; + + if(texturedata->yuv) + { + if(SDL_SW_UpdateYUVTexture(texturedata->yuv, rect, pixels, pitch) < 0) + return -1; + WINCE_UpdateYUVTextureData(texture); + return 0; + } + + if(0 < rect->w && 0 < rect->h) + { + const unsigned char *src = ((const unsigned char*) pixels); + unsigned char *dst = ((unsigned char*) texturedata->pixels) + + rect->y * texturedata->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format); + int length = rect->w * SDL_BYTESPERPIXEL(texture->format); + int height = rect->h; + + while(height--) + { + SDL_memcpy(dst, src, length); + dst += texturedata->pitch; + src += pitch; + } + } + + return 0; +} + +int WINCE_LockTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, int dirty, void** pixels, int* pitch) +{ + WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata; + + if(texturedata->yuv) + return SDL_SW_LockYUVTexture(texturedata->yuv, rect, dirty, pixels, pitch); + + *pixels = (void *) ((unsigned char*) texturedata->pixels + + rect->y * texturedata->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = texturedata->pitch; +} + +void WINCE_UnlockTexture(SDL_Renderer* renderer, SDL_Texture* texture) +{ + WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata; + + if(texturedata->yuv) + { + SDL_SW_UnlockYUVTexture(texturedata->yuv); + WINCE_UpdateYUVTextureData(texture); + } +} + +int WINCE_RenderCopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srect, const SDL_Rect* drect) +{ + WINCE_RenderData* dstdata = (WINCE_RenderData*) renderer->driverdata; + WINCE_TextureData* srcdata = (WINCE_TextureData*) texture->driverdata; + + if((dstdata->flags & FB_SUSPENDED) || + 0 >= srect->w || 0 >= srect->h) return; + + // lock gapi + if(dstdata->gapi) dstdata->gapi->GXBeginDraw(); + + const unsigned char *src = ((const unsigned char*) srcdata->pixels); + unsigned char *dst = dstdata->pixels + (dstdata->flags & FB_SKIP_OFFSET ? 0 : dstdata->fb.offset) + + drect->y * dstdata->fb.ypitch + + drect->x * dstdata->fb.xpitch; + if(srcdata->yuv) + { + return SDL_SW_CopyYUVToRGB(srcdata->yuv, + srect, srcdata->format, + drect->w, drect->h, dst, + dstdata->fb.ypitch); + } + else + { + int height = drect->h; + int length = drect->w * SDL_BYTESPERPIXEL(texture->format); // in bytes + + while(height--) + { + switch(SDL_BYTESPERPIXEL(texture->format)) + { + case 2: UpdateLine16to16(&dstdata->fb, (Uint16*) src, (Uint16*) dst, length >> 1); break; + + default: break; + } + + dst += dstdata->fb.ypitch; + src += srcdata->pitch; + } + } + + // unlock gapi + if(dstdata->gapi) dstdata->gapi->GXEndDraw(); + + return 0; +} + +void WINCE_RenderPresent(SDL_Renderer* renderer) +{ +} + +int WINCE_RenderDrawPoints(SDL_Renderer* renderer, const SDL_Point* points, int count) +{ + SDL_Unsupported(); + return -1; +} + +int WINCE_RenderDrawLines(SDL_Renderer* renderer, const SDL_Point* points, int count) +{ + SDL_Unsupported(); + return -1; +} + +int WINCE_RenderDrawRects(SDL_Renderer* renderer, const SDL_Rect ** rects, int count) +{ + SDL_Unsupported(); + return -1; +} + +int WINCE_RenderFillRects(SDL_Renderer* renderer, const SDL_Rect** rects, int count) +{ + SDL_Unsupported(); + return -1; +} + + + +void WINCE_SetupOrientation(WINCE_RenderData* data, int width, int height) +{ + const float maxW1 = GetSystemMetrics(SM_CXSCREEN) > GetSystemMetrics(SM_CYSCREEN) ? GetSystemMetrics(SM_CXSCREEN) : GetSystemMetrics(SM_CYSCREEN); + const float maxW2 = data->fb.width > data->fb.height ? data->fb.width : data->fb.height; + + // scale define + data->scale = maxW2 / maxW1; + + // init fb values + FrameBufferInitialize(&data->fb); + + // orientation values + data->userOrientation = ORIENTATION_UP; + data->systemOrientation = WINCE_GetDMOrientation(); + data->hardwareGeometry = data->fb.width == data->fb.height ? GEOMETRY_SQUARE : + (data->fb.width < data->fb.height ? GEOMETRY_PORTRAIT : GEOMETRY_LANDSCAPE); + + if(data->debug) + WINCE_DumpVideoInfo(data); + + if(data->systemOrientation == ORIENTATION_UNKNOWN) + data->systemOrientation == ORIENTATION_UP; + + data->userOrientation = ORIENTATION_UP; + + switch(data->hardwareGeometry) + { + case GEOMETRY_PORTRAIT: WINCE_PortraitTransform(data, width, height); break; + case GEOMETRY_LANDSCAPE: WINCE_LandscapeTransform(data, width, height); break; + case GEOMETRY_SQUARE: WINCE_SquareTransform(data, width, height); break; + default: break; + } + + // debug + if(data->debug) + { + printf("\n"); + printf("user video width: %d\n", width); + printf("user video height: %d\n", height); + FrameBufferDumpInfo(&data->fb, "user"); + } +} + +void WINCE_DumpVideoInfo(WINCE_RenderData* data) +{ + // get oem info + WCHAR oemInfo[48]; + SDL_memset(oemInfo, 0, sizeof(oemInfo)); + SystemParametersInfo(SPI_GETOEMINFO, sizeof(oemInfo) - sizeof(WCHAR), oemInfo, 0); + + printf("hardware oem: "); + wprintf(oemInfo); + printf("\n"); + + printf("video driver mode: %s\n", (data->flags & FB_RAW_MODE ? RAW_RENDER_NAME : GAPI_RENDER_NAME)); + printf("GetSystemMetrics(SM_CXSCREEN): %d\n", GetSystemMetrics(SM_CXSCREEN)); + printf("GetSystemMetrics(SM_CYSCREEN): %d\n", GetSystemMetrics(SM_CYSCREEN)); + printf("scale coord: %f\n", data->scale); + + FrameBufferDumpInfo(&data->fb, "hardware"); + + printf("display format: %p\n", data->format); + printf("display bits per pixel: %d\n", SDL_BITSPERPIXEL(data->format)); + printf("display bytes per pixel: %d\n", SDL_BYTESPERPIXEL(data->format)); + printf("display memory: %p\n", data->pixels); + printf("system orientation: %d, %s\n", data->systemOrientation, GetOrientationName(data->systemOrientation)); + printf("hardware geometry: %d\n", data->hardwareGeometry); +} + +void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible) +{ + SDL_WindowData* windowdata = (SDL_WindowData*) window->driverdata; + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_Renderer* renderer = (SDL_Renderer*) window->renderer; + + if(visible) + { + if(window->flags & SDL_WINDOW_FULLSCREEN) + { + if(videodata->SHFullScreen) + videodata->SHFullScreen(windowdata->hwnd, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON); + ShowWindow(FindWindow(TEXT("HHTaskBar"), NULL), SW_HIDE); + } + + ShowWindow(windowdata->hwnd, SW_SHOW); + SetForegroundWindow(windowdata->hwnd); + + if(renderer && + (videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW)) + { + WINCE_RenderData* renderdata = (WINCE_RenderData*) renderer->driverdata; + renderdata->flags &= ~FB_SUSPENDED; + if(renderdata->gapi) renderdata->gapi->GXResume(); + } + } + else + { + if(renderer && + (videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW)) + { + WINCE_RenderData* renderdata = (WINCE_RenderData*) renderer->driverdata; + if(renderdata->gapi) renderdata->gapi->GXSuspend(); + renderdata->flags |= FB_SUSPENDED; + } + + ShowWindow(windowdata->hwnd, SW_HIDE); + + if(window->flags & SDL_WINDOW_FULLSCREEN) + { + if(videodata->SHFullScreen) + videodata->SHFullScreen(windowdata->hwnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON); + ShowWindow(FindWindow(TEXT("HHTaskBar"), NULL), SW_SHOW); + } + } +} + + +void WINCE_PointerCoordinateTransform(SDL_Window* window, POINT* pt) +{ + WINCE_RenderData* data = (WINCE_RenderData*) window->renderer->driverdata; + + pt->x *= data->scale; + pt->y *= data->scale; + + PointerRotate(pt, &data->fb, data->userOrientation); +} + +void WINCE_PortraitTransform(WINCE_RenderData* data, int width, int height) +{ + if(data->systemOrientation != ORIENTATION_UP) + FrameBufferRotate(&data->fb, data->systemOrientation); + + if(data->fb.width != width || data->fb.height != height) + switch(data->systemOrientation) + { + case ORIENTATION_UP: + case ORIENTATION_LEFT: data->userOrientation = ORIENTATION_RIGHT; break; + case ORIENTATION_RIGHT: + case ORIENTATION_DOWN: data->userOrientation = ORIENTATION_LEFT; break; + default: break; + } + + if(data->userOrientation != ORIENTATION_UP) + FrameBufferRotate(&data->fb, data->userOrientation); +} + +void WINCE_LandscapeTransform(WINCE_RenderData* data, int width, int height) +{ + switch(data->systemOrientation) + { + case ORIENTATION_UP: FrameBufferRotate(&data->fb, ORIENTATION_LEFT); break; + case ORIENTATION_LEFT:FrameBufferRotate(&data->fb, ORIENTATION_DOWN); break; + case ORIENTATION_DOWN:FrameBufferRotate(&data->fb, ORIENTATION_RIGHT); break; + default: break; + } + + if(data->fb.width != width || data->fb.height != height) + switch(data->systemOrientation) + { + case ORIENTATION_UP: + case ORIENTATION_LEFT: data->userOrientation = ORIENTATION_RIGHT; break; + case ORIENTATION_RIGHT: + case ORIENTATION_DOWN: data->userOrientation = ORIENTATION_LEFT; break; + default: break; + } + + if(data->userOrientation != ORIENTATION_UP) + FrameBufferRotate(&data->fb, data->userOrientation); +} + +void WINCE_SquareTransform(WINCE_RenderData* data, int width, int height) +{ + WINCE_PortraitTransform(data, width, height); +} + +int WINCE_FixedGeometry(FrameBufferInfo* fb, int bpp, int debug) +{ + // check square + if(GetSystemMetrics(SM_CXSCREEN) == GetSystemMetrics(SM_CYSCREEN) && + fb->width != fb->height) + { + if(fb->width < fb->height) + fb->height = fb->width; + else + if(fb->height < fb->width) + fb->width = fb->height; + } + + // check width + if(__abs(fb->xpitch) == bpp && + fb->width != __abs(fb->ypitch) / bpp) + { + if(fb->height == __abs(fb->ypitch) / bpp) + { + __swap(&fb->width, &fb->height); + + if(debug) + printf("WINCE_FixedGeometry: width: %d, height: %d\n", fb->width, fb->height); + } + else + return -1; + } + else + // check height + if(__abs(fb->ypitch) == bpp && + fb->height != __abs(fb->xpitch) / bpp) + { + if(fb->width == __abs(fb->xpitch) / bpp) + { + __swap(&fb->width, &fb->height); + + if(debug) + printf("WINCE_FixedGeometry: width: %d, height: %d\n", fb->width, fb->height); + } + else + return -1; + } + + return 0; +} + +void WINCE_UpdateYUVTextureData(SDL_Texture* texture) +{ + WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata; + SDL_Rect rect; + + rect.x = 0; + rect.y = 0; + rect.w = texture->w; + rect.h = texture->h; + SDL_SW_CopyYUVToRGB(texturedata->yuv, &rect, texturedata->format, texture->w, texture->h, texturedata->pixels, texturedata->pitch); +} + +int GAPI_Init(WINCE_RenderData* data, HWND hwnd) +{ + if(NULL == data->gapi) + { + const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER"); + if(preferably && 0 != SDL_strcasecmp(preferably, GAPI_RENDER_NAME)) return 0; + + data->gapi = (GapiInfo *) SDL_calloc(1, sizeof(GapiInfo)); + if(NULL == data->gapi) + { + SDL_OutOfMemory(); + return 0; + } + + data->gapi->hGapiLib = LoadLibrary(TEXT("\\Windows\\gx.dll")); + if(0 == data->gapi->hGapiLib) + { + data->gapi->hGapiLib = LoadLibrary(TEXT("gx.dll")); + if(0 == data->gapi->hGapiLib) return 0; + } + + // load gapi library +#define LINK(type,name,import) name=(PFN##type)GetProcAddress(data->gapi->hGapiLib,TEXT(import)) + LINK(GXOpenDisplay, data->gapi->GXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z"); + LINK(GXCloseDisplay, data->gapi->GXCloseDisplay, "?GXCloseDisplay@@YAHXZ"); + LINK(GXBeginDraw, data->gapi->GXBeginDraw, "?GXBeginDraw@@YAPAXXZ"); + LINK(GXEndDraw, data->gapi->GXEndDraw, "?GXEndDraw@@YAHXZ"); + LINK(GXGetDisplayProperties,data->gapi->GXGetDisplayProperties,"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ"); + LINK(GXSuspend, data->gapi->GXSuspend, "?GXSuspend@@YAHXZ"); + LINK(GXResume, data->gapi->GXResume, "?GXResume@@YAHXZ"); +#undef LINK + + int enable = data->gapi->GXGetDisplayProperties && data->gapi->GXCloseDisplay && data->gapi->GXOpenDisplay && + data->gapi->GXBeginDraw && data->gapi->GXEndDraw && data->gapi->GXSuspend && data->gapi->GXResume; + + if(!enable) + { + SDL_SetError("GAPI_Init: error gx.dll: internal error"); + GAPI_Quit(data); + return 0; + } + + if(0 == data->gapi->GXOpenDisplay(hwnd, GX_FULLSCREEN)) + { + SDL_SetError("GAPI_Init: couldn't initialize GAPI"); + GAPI_Quit(data); + return 0; + } + + struct GXDisplayProperties gxProperties = data->gapi->GXGetDisplayProperties(); + + // fill FrameBufferInfo + data->fb.xpitch = gxProperties.cbxPitch; + data->fb.ypitch = gxProperties.cbyPitch; + data->fb.width = gxProperties.cxWidth; + data->fb.height = gxProperties.cyHeight; + data->fb.offset = 0; + + if((gxProperties.ffFormat & kfDirect565) || 16 == gxProperties.cBPP) + data->format = SDL_PIXELFORMAT_RGB565; + else + if((gxProperties.ffFormat & kfDirect555) || 15 == gxProperties.cBPP) + data->format = SDL_PIXELFORMAT_RGB555; + else + data->format = 0; + + // get pixels + GXDeviceInfo gxInfo = { 0 }; + HDC hdc = GetDC(NULL); + + gxInfo.Version = 100; + int result = ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo), (char *) &gxInfo); + ReleaseDC(NULL, hdc); + + if(result > 0) + { + // more debug + if(data->debug) + { + printf("GXDeviceInfo.pvFrameBuffer: %p\n", gxInfo.pvFrameBuffer); + printf("GXDeviceInfo.cxWidth: %d\n", gxInfo.cxWidth); + printf("GXDeviceInfo.cyHeight: %d\n", gxInfo.cyHeight); + printf("GXDeviceInfo.cbStride: %d\n", gxInfo.cbStride); + printf("GXDeviceInfo.cBPP: %d\n", gxInfo.cBPP); + printf("GXDeviceInfo.ffFormat: 0x%x\n", gxInfo.ffFormat); + + printf("GXDeviceInfo.unk:\n"); + int ii; for(ii = 0; ii < sizeof(gxInfo.unknown); ++ii) + printf("0x%02hhX,", gxInfo.unknown[ii]); + printf("\n"); + } + + if(gxInfo.ffFormat && gxInfo.ffFormat != gxProperties.ffFormat) + { + if((gxInfo.ffFormat & kfDirect565) || 16 == gxInfo.cBPP) + data->format = SDL_PIXELFORMAT_RGB565; + else + if((gxInfo.ffFormat & kfDirect555) || 15 == gxInfo.cBPP) + data->format = SDL_PIXELFORMAT_RGB555; + } + + data->pixels = gxInfo.pvFrameBuffer; + } + else + { + data->flags |= FB_SKIP_OFFSET; + data->pixels = data->gapi->GXBeginDraw(); + data->gapi->GXEndDraw(); + + if(data->debug) + { + printf("GAPI_Init\n"); + printf("use GXBeginDraw: %p\n", data->pixels); + printf("use skip offset\n"); + } + } + + if(0 == data->format || + 0 > WINCE_FixedGeometry(&data->fb, SDL_BYTESPERPIXEL(data->format), data->debug)) + { + SDL_SetError("GAPI_Init: unknown hardware"); + GAPI_Quit(data); + return 0; + } + } + + return data->gapi && data->pixels ? 1 : 0; +} + +void GAPI_Quit(WINCE_RenderData* data) +{ + if(data->gapi) + { + if(data->gapi->GXCloseDisplay) data->gapi->GXCloseDisplay(); + if(data->gapi->hGapiLib) FreeLibrary(data->gapi->hGapiLib); + + SDL_free(data->gapi); + data->gapi = NULL; + } +} + +int RAW_Init(WINCE_RenderData* data) +{ + const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER"); + if(preferably && 0 != SDL_strcasecmp(preferably, RAW_RENDER_NAME)) return 0; + + RawFrameBufferInfo rfbi = { 0 }; + HDC hdc = GetDC(NULL); + int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi); + ReleaseDC(NULL, hdc); + + //disable + if(result == 0 || rfbi.pFramePointer == 0 || + rfbi.cxPixels == 0 || rfbi.cyPixels == 0 || + rfbi.cxStride == 0 || rfbi.cyStride == 0) return 0; + + data->flags = FB_RAW_MODE; + + // fill FrameBufferInfo + SDL_memset(&data->fb, 0, sizeof(FrameBufferInfo)); + + data->fb.xpitch = rfbi.cxStride; + data->fb.ypitch = rfbi.cyStride; + data->fb.width = rfbi.cxPixels; + data->fb.height = rfbi.cyPixels; + data->fb.offset = 0; + + if((FORMAT_565 & rfbi.wFormat) || 16 == rfbi.wBPP) + data->format = SDL_PIXELFORMAT_RGB565; + else + if((FORMAT_555 & rfbi.wFormat) || 15 == rfbi.wBPP) + data->format = SDL_PIXELFORMAT_RGB555; + else + data->format = 0; + + if(0 == data->format || + 0 > WINCE_FixedGeometry(&data->fb, SDL_BYTESPERPIXEL(data->format), data->debug)) + { + SDL_SetError("RAW_Init: unknown hardware"); + RAW_Quit(data); + return 0; + } + + data->pixels = rfbi.pFramePointer; + + return data->pixels ? 1 : 0; +} + +void RAW_Quit(WINCE_RenderData* data) +{ +} + +void FrameBufferInitialize(FrameBufferInfo* fb) +{ + int orientation = GetFrameBufferOrientation(fb); + + // set correct start offset + switch(orientation) + { + case ORIENTATION_UP: + fb->offset = 0; + break; + + case ORIENTATION_LEFT: + fb->offset = __abs(fb->ypitch * (fb->height - 1)); + break; + + case ORIENTATION_RIGHT: + fb->offset = __abs(fb->xpitch * (fb->width - 1)); + break; + + case ORIENTATION_DOWN: + fb->offset = __abs(fb->xpitch * (fb->width - 1) + + fb->ypitch * (fb->height - 1)); + break; + + default: break; + } + + //if(orientation != ORIENTATION_UP) + switch(orientation) + { + case ORIENTATION_LEFT: FrameBufferRotate(fb, ORIENTATION_RIGHT); break; + case ORIENTATION_RIGHT:FrameBufferRotate(fb, ORIENTATION_LEFT); break; + case ORIENTATION_DOWN: FrameBufferRotate(fb, ORIENTATION_DOWN); break; + + default: break; + } +} + +int GetFrameBufferOrientation(const FrameBufferInfo* src) +{ + if(src->xpitch > 0 && src->ypitch > 0) + return ORIENTATION_UP; + else + if(src->xpitch > 0 && src->ypitch < 0) + return ORIENTATION_LEFT; + else + if(src->xpitch < 0 && src->ypitch > 0) + return ORIENTATION_RIGHT; + else + if(src->xpitch < 0 && src->ypitch < 0) + return ORIENTATION_DOWN; + + return ORIENTATION_UNKNOWN; +} + +void FrameBufferRotate(FrameBufferInfo* dst, int orientation) +{ + FrameBufferInfo src; + // copy dst -> src + SDL_memcpy(&src, dst, sizeof(FrameBufferInfo)); + + switch(orientation) + { + case ORIENTATION_LEFT: + dst->width = src.height; + dst->height = src.width; + dst->xpitch = src.ypitch; + dst->ypitch = -src.xpitch; + dst->offset = src.offset + src.xpitch * (src.width - 1); + break; + + case ORIENTATION_RIGHT: + dst->width = src.height; + dst->height = src.width; + dst->xpitch = -src.ypitch; + dst->ypitch = src.xpitch; + dst->offset = src.offset + src.ypitch * (src.height - 1); + break; + + case ORIENTATION_DOWN: + FrameBufferRotate(dst, ORIENTATION_LEFT); + FrameBufferRotate(dst, ORIENTATION_LEFT); + break; + + default: + break; + } +} + +void PointerRotate(POINT* pt, const FrameBufferInfo* fb, int orientation) +{ + switch(orientation) + { + case ORIENTATION_UP: + break; + + case ORIENTATION_LEFT: + { + int temp = pt->y; + pt->y = fb->height - pt->x; + pt->x = temp; + } + break; + + case ORIENTATION_RIGHT: + { + int temp = pt->x; + pt->x = fb->width - pt->y; + pt->y = temp; + } + break; + + case ORIENTATION_DOWN: + pt->x = fb->width - pt->x; + pt->y = fb->height - pt->y; + break; + + default: break; + } +} + +const char* GetOrientationName(int orientation) +{ + switch(orientation) + { + case ORIENTATION_UP: return "UP"; + case ORIENTATION_DOWN: return "DOWN"; + case ORIENTATION_LEFT: return "LEFT"; + case ORIENTATION_RIGHT: return "RIGHT"; + default: break; + } + + return "UNKNOWN"; +} + +int WINCE_GetDMOrientation(void) +{ + DEVMODE sDevMode = {0}; + sDevMode.dmSize = sizeof(DEVMODE); + sDevMode.dmFields = DM_DISPLAYORIENTATION; + + // DMDO_0, DMDO_90, DMDO_180, DMDO_270 + if(DISP_CHANGE_BADMODE != ChangeDisplaySettingsEx(NULL, &sDevMode, 0, CDS_TEST, NULL)) + switch(sDevMode.dmDisplayOrientation) + { + case DMDO_0: return DMDO_0; + case DMDO_90: return DMDO_90; + case DMDO_180: return DMDO_180; + case DMDO_270: return DMDO_270; + default: break; + } + + SDL_SetError("WINCE_GetDMOrientation: ChangeDisplaySettingsEx return BADMODE"); + return -1; +} + +int WINCE_SetDMOrientation(int orientation) +{ + DEVMODE sDevMode = {0}; + sDevMode.dmSize = sizeof(DEVMODE); + sDevMode.dmFields = DM_DISPLAYORIENTATION; + + switch(orientation) + { + case DMDO_0: sDevMode.dmDisplayOrientation = DMDO_0; break; + case DMDO_90: sDevMode.dmDisplayOrientation = DMDO_90; break; + case DMDO_180: sDevMode.dmDisplayOrientation = DMDO_180; break; + case DMDO_270: sDevMode.dmDisplayOrientation = DMDO_270; break; + default: return 0; + } + + if(DISP_CHANGE_BADMODE != ChangeDisplaySettingsEx(NULL, &sDevMode, 0, CDS_RESET, NULL)) + return 1; + + SDL_SetError("WINCE_SetDMOrientation: ChangeDisplaySettingsEx return BADMODE"); + return -1; +} + +void FrameBufferDumpInfo(const FrameBufferInfo* fb, const char* name) +{ + printf("%s fb.width: %d\n", name, fb->width); + printf("%s fb.height: %d\n", name, fb->height); + printf("%s fb.xpitch: %d\n", name, fb->xpitch); + printf("%s fb.ypitch: %d\n", name, fb->ypitch); + printf("%s fb.offset: %d\n", name, fb->offset); + + int orientation = GetFrameBufferOrientation(fb); + printf("%s fb.orientation: %d, %s\n", name, orientation, GetOrientationName(orientation)); +} + +void UpdateLine16to16(const FrameBufferInfo* fb, const Uint16* src, Uint16* dst, Uint16 width) +{ + if(2 == fb->xpitch) + { + switch(width) + { + case 1: + *dst = *src; + break; + + case 2: + *((Uint32*) dst) = *((Uint32*) src); + break; + + default: + SDL_memcpy(dst, src, width * 2); + break; + } + } + else + if(-2 == fb->xpitch) + { + while(width--) + *dst-- = *src++; + } + else + { + while(width--) + { + *dst = *src++; + dst += fb->xpitch / 2; + } + } +} + +#endif // SDL_VIDEO_RENDER_GAPI diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_gapirender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_gapirender.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,37 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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 + + Stefan Klug + klug.stefan@gmx.de +*/ +#include "SDL_config.h" + +/* SDL surface based renderer implementation */ + +#if SDL_VIDEO_RENDER_GAPI +extern void WINCE_AddRenderDriver(_THIS); +extern int WINCE_Available(void); +extern void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible); +extern int WINCE_GetDMOrientation(void); +extern int WINCE_SetDMOrientation(int orientation); +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_gapirender_c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_gapirender_c.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,24 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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 + + Stefan Klug + klug.stefan@gmx.de +*/ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_gdirender.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_gdirender.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,1127 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#if SDL_VIDEO_RENDER_GDI + +#include "SDL_windowsvideo.h" +#include "../SDL_rect_c.h" +#include "../SDL_yuv_sw_c.h" +#include "../SDL_alphamult.h" + +#ifdef _WIN32_WCE +#define NO_GETDIBBITS 1 +#endif + +/* GDI renderer implementation */ + +static SDL_Renderer *GDI_CreateRenderer(SDL_Window * window, Uint32 flags); +static int GDI_DisplayModeChanged(SDL_Renderer * renderer); +static int GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static int GDI_QueryTexturePixels(SDL_Renderer * renderer, + SDL_Texture * texture, void **pixels, + int *pitch); +static int GDI_SetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, + int ncolors); +static int GDI_GetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, SDL_Color * colors, + int firstcolor, int ncolors); +static int GDI_SetTextureAlphaMod(SDL_Renderer * renderer, + SDL_Texture * texture); +static int GDI_SetTextureBlendMode(SDL_Renderer * renderer, + SDL_Texture * texture); +static int GDI_SetTextureScaleMode(SDL_Renderer * renderer, + SDL_Texture * texture); +static int GDI_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, + int pitch); +static int GDI_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, + void **pixels, int *pitch); +static void GDI_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static int GDI_SetDrawBlendMode(SDL_Renderer * renderer); +static int GDI_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, int count); +static int GDI_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, int count); +static int GDI_RenderDrawRects(SDL_Renderer * renderer, + const SDL_Rect ** rects, int count); +static int GDI_RenderFillRects(SDL_Renderer * renderer, + const SDL_Rect ** rects, int count); +static int GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect); +static int GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, void * pixels, int pitch); +static int GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, const void * pixels, int pitch); +static void GDI_RenderPresent(SDL_Renderer * renderer); +static void GDI_DestroyTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static void GDI_DestroyRenderer(SDL_Renderer * renderer); + + +SDL_RenderDriver GDI_RenderDriver = { + GDI_CreateRenderer, + { + "gdi", + (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY | + SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | + SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED), + (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_ALPHA), + (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK), + (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST), + 14, + { + SDL_PIXELFORMAT_INDEX8, + SDL_PIXELFORMAT_RGB555, + SDL_PIXELFORMAT_RGB565, + SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_BGR888, + SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_RGBA8888, + SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_YV12, + SDL_PIXELFORMAT_IYUV, + SDL_PIXELFORMAT_YUY2, + SDL_PIXELFORMAT_UYVY, + SDL_PIXELFORMAT_YVYU}, + 0, + 0} +}; + +typedef struct +{ + HWND hwnd; + HDC window_hdc; + HDC render_hdc; + HDC memory_hdc; + HDC current_hdc; +#ifndef NO_GETDIBBITS + LPBITMAPINFO bmi; +#endif + HBITMAP hbm[3]; + int current_hbm; + SDL_DirtyRectList dirty; + SDL_bool makedirty; +} GDI_RenderData; + +typedef struct +{ + SDL_SW_YUVTexture *yuv; + Uint32 format; + HPALETTE hpal; + HBITMAP hbm; + void *pixels; + int pitch; + SDL_bool premultiplied; +} GDI_TextureData; + +static void +UpdateYUVTextureData(SDL_Texture * texture) +{ + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; + SDL_Rect rect; + + rect.x = 0; + rect.y = 0; + rect.w = texture->w; + rect.h = texture->h; + SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w, + texture->h, data->pixels, data->pitch); +} + +void +GDI_AddRenderDriver(_THIS) +{ + int i; + for (i = 0; i < _this->num_displays; ++i) { + SDL_AddRenderDriver(&_this->displays[i], &GDI_RenderDriver); + } +} + +SDL_Renderer * +GDI_CreateRenderer(SDL_Window * window, Uint32 flags) +{ + SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; + SDL_Renderer *renderer; + GDI_RenderData *data; + int bmi_size; + HBITMAP hbm; + int i, n; + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (GDI_RenderData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + GDI_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + + windowdata->videodata->render = RENDER_GDI; + + renderer->DisplayModeChanged = GDI_DisplayModeChanged; + renderer->CreateTexture = GDI_CreateTexture; + renderer->QueryTexturePixels = GDI_QueryTexturePixels; + renderer->SetTexturePalette = GDI_SetTexturePalette; + renderer->GetTexturePalette = GDI_GetTexturePalette; + renderer->SetTextureAlphaMod = GDI_SetTextureAlphaMod; + renderer->SetTextureBlendMode = GDI_SetTextureBlendMode; + renderer->SetTextureScaleMode = GDI_SetTextureScaleMode; + renderer->UpdateTexture = GDI_UpdateTexture; + renderer->LockTexture = GDI_LockTexture; + renderer->UnlockTexture = GDI_UnlockTexture; + renderer->SetDrawBlendMode = GDI_SetDrawBlendMode; + renderer->RenderDrawPoints = GDI_RenderDrawPoints; + renderer->RenderDrawLines = GDI_RenderDrawLines; + renderer->RenderDrawRects = GDI_RenderDrawRects; + renderer->RenderFillRects = GDI_RenderFillRects; + renderer->RenderCopy = GDI_RenderCopy; + renderer->RenderReadPixels = GDI_RenderReadPixels; + renderer->RenderWritePixels = GDI_RenderWritePixels; + renderer->RenderPresent = GDI_RenderPresent; + renderer->DestroyTexture = GDI_DestroyTexture; + renderer->DestroyRenderer = GDI_DestroyRenderer; + renderer->info = GDI_RenderDriver.info; + renderer->window = window; + renderer->driverdata = data; + + renderer->info.flags = SDL_RENDERER_ACCELERATED; + + data->hwnd = windowdata->hwnd; + data->window_hdc = windowdata->hdc; + data->render_hdc = CreateCompatibleDC(data->window_hdc); + data->memory_hdc = CreateCompatibleDC(data->window_hdc); + +#ifndef NO_GETDIBBITS + /* Fill in the compatible bitmap info */ + bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); + data->bmi = (LPBITMAPINFO) SDL_calloc(1, bmi_size); + if (!data->bmi) { + GDI_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + data->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + + hbm = CreateCompatibleBitmap(data->window_hdc, 1, 1); + GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS); + GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS); + DeleteObject(hbm); +#endif + + if (flags & SDL_RENDERER_SINGLEBUFFER) { + renderer->info.flags |= + (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY); + n = 0; + } else if (flags & SDL_RENDERER_PRESENTFLIP2) { + renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; + n = 2; + } else if (flags & SDL_RENDERER_PRESENTFLIP3) { + renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; + n = 3; + } else { + renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; + n = 1; + } + for (i = 0; i < n; ++i) { + data->hbm[i] = + CreateCompatibleBitmap(data->window_hdc, window->w, window->h); + if (!data->hbm[i]) { + GDI_DestroyRenderer(renderer); + WIN_SetError("CreateCompatibleBitmap()"); + return NULL; + } + } + if (n > 0) { + SelectObject(data->render_hdc, data->hbm[0]); + data->current_hdc = data->render_hdc; + data->makedirty = SDL_TRUE; + } else { + data->current_hdc = data->window_hdc; + data->makedirty = SDL_FALSE; + } + data->current_hbm = 0; + +#ifdef _WIN32_WCE + // check size for GDI fullscreen and rotate + if((window->flags & SDL_WINDOW_FULLSCREEN) && + GetSystemMetrics(SM_CXSCREEN) != GetSystemMetrics(SM_CYSCREEN) && + ((GetSystemMetrics(SM_CXSCREEN) < GetSystemMetrics(SM_CYSCREEN) && window->w > window->h) || + (GetSystemMetrics(SM_CXSCREEN) > GetSystemMetrics(SM_CYSCREEN) && window->w < window->h))) + { + int orientation = WINCE_GetDMOrientation(); + switch(orientation) + { + case DMDO_0: orientation = DMDO_90; break; + case DMDO_270: orientation = DMDO_180; break; + case DMDO_90: orientation = DMDO_0; break; + case DMDO_180: orientation = DMDO_270; break; + + default: + GDI_DestroyRenderer(renderer); + return NULL; + } + + if(0 > WINCE_SetDMOrientation(orientation)) + { + GDI_DestroyRenderer(renderer); + return NULL; + } + } +#endif + + return renderer; +} + +static int +GDI_DisplayModeChanged(SDL_Renderer * renderer) +{ + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + int i, n; + + if (renderer->info.flags & SDL_RENDERER_SINGLEBUFFER) { + n = 0; + } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) { + n = 2; + } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) { + n = 3; + } else { + n = 1; + } + for (i = 0; i < n; ++i) { + if (data->hbm[i]) { + DeleteObject(data->hbm[i]); + data->hbm[i] = NULL; + } + } + for (i = 0; i < n; ++i) { + data->hbm[i] = + CreateCompatibleBitmap(data->window_hdc, window->w, window->h); + if (!data->hbm[i]) { + WIN_SetError("CreateCompatibleBitmap()"); + return -1; + } + } + if (n > 0) { + SelectObject(data->render_hdc, data->hbm[0]); + } + data->current_hbm = 0; + + return 0; +} + +static HBITMAP +GDI_CreateDIBSection(HDC hdc, int w, int h, int pitch, Uint32 format, + HPALETTE * hpal, void ** pixels) +{ + int bmi_size; + LPBITMAPINFO bmi; + + bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); + bmi = (LPBITMAPINFO) SDL_calloc(1, bmi_size); + if (!bmi) { + SDL_OutOfMemory(); + return NULL; + } + bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi->bmiHeader.biWidth = w; + bmi->bmiHeader.biHeight = -h; /* topdown bitmap */ + bmi->bmiHeader.biPlanes = 1; + bmi->bmiHeader.biSizeImage = h * pitch; + bmi->bmiHeader.biXPelsPerMeter = 0; + bmi->bmiHeader.biYPelsPerMeter = 0; + bmi->bmiHeader.biClrUsed = 0; + bmi->bmiHeader.biClrImportant = 0; + bmi->bmiHeader.biBitCount = SDL_BYTESPERPIXEL(format) * 8; + if (SDL_ISPIXELFORMAT_INDEXED(format)) { + bmi->bmiHeader.biCompression = BI_RGB; + if (hpal) { + int i, ncolors; + LOGPALETTE *palette; + + ncolors = (1 << SDL_BITSPERPIXEL(format)); + palette = + (LOGPALETTE *) SDL_malloc(sizeof(*palette) + + ncolors * sizeof(PALETTEENTRY)); + if (!palette) { + SDL_free(bmi); + SDL_OutOfMemory(); + return NULL; + } + palette->palVersion = 0x300; + palette->palNumEntries = ncolors; + for (i = 0; i < ncolors; ++i) { + palette->palPalEntry[i].peRed = 0xFF; + palette->palPalEntry[i].peGreen = 0xFF; + palette->palPalEntry[i].peBlue = 0xFF; + palette->palPalEntry[i].peFlags = 0; + } + *hpal = CreatePalette(palette); + SDL_free(palette); + } + } else { + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + bmi->bmiHeader.biCompression = BI_BITFIELDS; + SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, + &Amask); + ((Uint32 *) bmi->bmiColors)[0] = Rmask; + ((Uint32 *) bmi->bmiColors)[1] = Gmask; + ((Uint32 *) bmi->bmiColors)[2] = Bmask; + if (hpal) { + *hpal = NULL; + } + } + return CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, pixels, NULL, 0); +} + +static int +GDI_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + GDI_TextureData *data; + + data = (GDI_TextureData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + SDL_OutOfMemory(); + return -1; + } + + texture->driverdata = data; + + if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { + data->yuv = + SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h); + if (!data->yuv) { + return -1; + } + data->format = display->current_mode.format; + } else { + data->format = texture->format; + } + data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format)); + + if (data->yuv || texture->access == SDL_TEXTUREACCESS_STREAMING + || texture->format != display->current_mode.format) { + data->hbm = GDI_CreateDIBSection(renderdata->memory_hdc, + texture->w, texture->h, + data->pitch, data->format, + &data->hpal, &data->pixels); + } else { + data->hbm = CreateCompatibleBitmap(renderdata->window_hdc, + texture->w, texture->h); + } + if (!data->hbm) { + WIN_SetError("Couldn't create bitmap"); + return -1; + } + + return 0; +} + +static int +GDI_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, + void **pixels, int *pitch) +{ + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; + + if (data->yuv) { + return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch); + } else { + *pixels = data->pixels; + *pitch = data->pitch; + return 0; + } +} + +static int +GDI_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, int ncolors) +{ + GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; + + if (data->yuv) { + SDL_SetError("YUV textures don't have a palette"); + return -1; + } else { + PALETTEENTRY entries[256]; + int i; + + for (i = 0; i < ncolors; ++i) { + entries[i].peRed = colors[i].r; + entries[i].peGreen = colors[i].g; + entries[i].peBlue = colors[i].b; + entries[i].peFlags = 0; + } + if (!SetPaletteEntries(data->hpal, firstcolor, ncolors, entries)) { + WIN_SetError("SetPaletteEntries()"); + return -1; + } + return 0; + } +} + +static int +GDI_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + SDL_Color * colors, int firstcolor, int ncolors) +{ + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; + + if (data->yuv) { + SDL_SetError("YUV textures don't have a palette"); + return -1; + } else { + PALETTEENTRY entries[256]; + int i; + + if (!GetPaletteEntries(data->hpal, firstcolor, ncolors, entries)) { + WIN_SetError("GetPaletteEntries()"); + return -1; + } + for (i = 0; i < ncolors; ++i) { + colors[i].r = entries[i].peRed; + colors[i].g = entries[i].peGreen; + colors[i].b = entries[i].peBlue; + } + return 0; + } +} + +static int +GDI_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + return 0; +} + +static int +GDI_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) +{ + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; + + switch (texture->blendMode) { + case SDL_BLENDMODE_NONE: + if (data->premultiplied) { + /* Crap, we've lost the original pixel data... *sigh* */ + } + return 0; +#ifndef _WIN32_WCE /* WinCE has no alphablend */ + case SDL_BLENDMODE_MASK: + case SDL_BLENDMODE_BLEND: + if (!data->premultiplied && data->pixels) { + switch (texture->format) { + case SDL_PIXELFORMAT_ARGB8888: + SDL_PreMultiplyAlphaARGB8888(texture->w, texture->h, + (Uint32 *) data->pixels, + data->pitch); + data->premultiplied = SDL_TRUE; + break; + case SDL_PIXELFORMAT_RGBA8888: + SDL_PreMultiplyAlphaRGBA8888(texture->w, texture->h, + (Uint32 *) data->pixels, + data->pitch); + data->premultiplied = SDL_TRUE; + break; + case SDL_PIXELFORMAT_ABGR8888: + SDL_PreMultiplyAlphaABGR8888(texture->w, texture->h, + (Uint32 *) data->pixels, + data->pitch); + data->premultiplied = SDL_TRUE; + break; + case SDL_PIXELFORMAT_BGRA8888: + SDL_PreMultiplyAlphaBGRA8888(texture->w, texture->h, + (Uint32 *) data->pixels, + data->pitch); + data->premultiplied = SDL_TRUE; + break; + } + } + return 0; +#endif + default: + SDL_Unsupported(); + texture->blendMode = SDL_BLENDMODE_NONE; + return -1; + } +} + +static int +GDI_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) +{ + switch (texture->scaleMode) { + case SDL_SCALEMODE_NONE: + case SDL_SCALEMODE_FAST: + return 0; + case SDL_SCALEMODE_SLOW: + case SDL_SCALEMODE_BEST: + SDL_Unsupported(); + texture->scaleMode = SDL_SCALEMODE_FAST; + return -1; + default: + SDL_Unsupported(); + texture->scaleMode = SDL_SCALEMODE_NONE; + return -1; + } + return 0; +} + +static int +GDI_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, int pitch) +{ + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; + + if (data->yuv) { + if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) { + return -1; + } + UpdateYUVTextureData(texture); + return 0; + } else { + GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; + + if (data->pixels) { + Uint8 *src, *dst; + int row; + size_t length; + + src = (Uint8 *) pixels; + dst = + (Uint8 *) data->pixels + rect->y * data->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format); + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += data->pitch; + } + if (data->premultiplied) { + Uint32 *pixels = + (Uint32 *) data->pixels + rect->y * (data->pitch / 4) + + rect->x; + switch (texture->format) { + case SDL_PIXELFORMAT_ARGB8888: + SDL_PreMultiplyAlphaARGB8888(rect->w, rect->h, pixels, + data->pitch); + break; + case SDL_PIXELFORMAT_RGBA8888: + SDL_PreMultiplyAlphaRGBA8888(rect->w, rect->h, pixels, + data->pitch); + break; + case SDL_PIXELFORMAT_ABGR8888: + SDL_PreMultiplyAlphaABGR8888(rect->w, rect->h, pixels, + data->pitch); + break; + case SDL_PIXELFORMAT_BGRA8888: + SDL_PreMultiplyAlphaBGRA8888(rect->w, rect->h, pixels, + data->pitch); + break; + } + } + } else if (rect->w == texture->w && pitch == data->pitch) { +#ifndef NO_GETDIBBITS + if (!SetDIBits + (renderdata->window_hdc, data->hbm, rect->y, rect->h, pixels, + renderdata->bmi, DIB_RGB_COLORS)) { + WIN_SetError("SetDIBits()"); + return -1; + } +#else + SDL_SetError("FIXME: Update Texture"); + return -1; +#endif + } else { + SDL_SetError + ("FIXME: Need to allocate temporary memory and do GetDIBits() followed by SetDIBits(), since we can only set blocks of scanlines at a time"); + return -1; + } + return 0; + } +} + +static int +GDI_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, void **pixels, + int *pitch) +{ + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; + + if (data->yuv) { + return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, + pitch); + } else if (data->pixels) { +#ifndef _WIN32_WCE + /* WinCE has no GdiFlush */ + GdiFlush(); +#endif + *pixels = + (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = data->pitch; + return 0; + } else { + SDL_SetError("No pixels available"); + return -1; + } +} + +static void +GDI_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; + + if (data->yuv) { + SDL_SW_UnlockYUVTexture(data->yuv); + UpdateYUVTextureData(texture); + } +} + +static int +GDI_SetDrawBlendMode(SDL_Renderer * renderer) +{ + switch (renderer->blendMode) { + case SDL_BLENDMODE_NONE: + return 0; + default: + SDL_Unsupported(); + renderer->blendMode = SDL_BLENDMODE_NONE; + return -1; + } +} + +static int +GDI_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, + int count) +{ + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; + int i; + COLORREF color; + + if (data->makedirty) { + /* Get the smallest rectangle that contains everything */ + SDL_Window *window = renderer->window; + SDL_Rect rect; + + rect.x = 0; + rect.y = 0; + rect.w = window->w; + rect.h = window->h; + if (!SDL_EnclosePoints(points, count, &rect, &rect)) { + /* Nothing to draw */ + return 0; + } + + SDL_AddDirtyRect(&data->dirty, &rect); + } + + color = RGB(renderer->r, renderer->g, renderer->b); + for (i = 0; i < count; ++i) { + SetPixel(data->current_hdc, points[i].x, points[i].y, color); + } + + return 0; +} + +static int +GDI_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, + int count) +{ + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; + HPEN pen; + BOOL status; + + if (data->makedirty) { + /* Get the smallest rectangle that contains everything */ + SDL_Window *window = renderer->window; + SDL_Rect clip, rect; + + clip.x = 0; + clip.y = 0; + clip.w = window->w; + clip.h = window->h; + SDL_EnclosePoints(points, count, NULL, &rect); + if (!SDL_IntersectRect(&rect, &clip, &rect)) { + /* Nothing to draw */ + return 0; + } + + SDL_AddDirtyRect(&data->dirty, &rect); + } + + /* Should we cache the pen? .. it looks like GDI does for us. :) */ + pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b)); + SelectObject(data->current_hdc, pen); + { + LPPOINT p = SDL_stack_alloc(POINT, count); + int i; + + for (i = 0; i < count; ++i) { + p[i].x = points[i].x; + p[i].y = points[i].y; + } + status = Polyline(data->current_hdc, p, count); + SDL_stack_free(p); + } + DeleteObject(pen); + + /* Need to close the endpoint of the line */ + if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { + SetPixel(data->current_hdc, points[count-1].x, points[count-1].y, + RGB(renderer->r, renderer->g, renderer->b)); + } + + if (!status) { + WIN_SetError("Polyline()"); + return -1; + } + return 0; +} + +static int +GDI_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, + int count) +{ + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; + HPEN pen; + POINT vertices[5]; + int i, status = 1; + + if (data->makedirty) { + SDL_Window *window = renderer->window; + SDL_Rect clip, rect; + + clip.x = 0; + clip.y = 0; + clip.w = window->w; + clip.h = window->h; + + for (i = 0; i < count; ++i) { + if (SDL_IntersectRect(rects[i], &clip, &rect)) { + SDL_AddDirtyRect(&data->dirty, &rect); + } + } + } + + /* Should we cache the pen? .. it looks like GDI does for us. :) */ + pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b)); + SelectObject(data->current_hdc, pen); + for (i = 0; i < count; ++i) { + const SDL_Rect *rect = rects[i]; + + vertices[0].x = rect->x; + vertices[0].y = rect->y; + + vertices[1].x = rect->x+rect->w-1; + vertices[1].y = rect->y; + + vertices[2].x = rect->x+rect->w-1; + vertices[2].y = rect->y+rect->h-1; + + vertices[3].x = rect->x; + vertices[3].y = rect->y+rect->h-1; + + vertices[4].x = rect->x; + vertices[4].y = rect->y; + + status &= Polyline(data->current_hdc, vertices, 5); + } + DeleteObject(pen); + + if (!status) { + WIN_SetError("Polyline()"); + return -1; + } + return 0; +} + +static int +GDI_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, + int count) +{ + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; + RECT rc; + HBRUSH brush; + int i, status = 1; + + if (data->makedirty) { + SDL_Window *window = renderer->window; + SDL_Rect clip, rect; + + clip.x = 0; + clip.y = 0; + clip.w = window->w; + clip.h = window->h; + + for (i = 0; i < count; ++i) { + if (SDL_IntersectRect(rects[i], &clip, &rect)) { + SDL_AddDirtyRect(&data->dirty, &rect); + } + } + } + + /* Should we cache the brushes? .. it looks like GDI does for us. :) */ + brush = CreateSolidBrush(RGB(renderer->r, renderer->g, renderer->b)); + SelectObject(data->current_hdc, brush); + for (i = 0; i < count; ++i) { + const SDL_Rect *rect = rects[i]; + + rc.left = rect->x; + rc.top = rect->y; + rc.right = rect->x + rect->w; + rc.bottom = rect->y + rect->h; + + status &= FillRect(data->current_hdc, &rc, brush); + } + DeleteObject(brush); + + if (!status) { + WIN_SetError("FillRect()"); + return -1; + } + return 0; +} + +static int +GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect) +{ + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; + GDI_TextureData *texturedata = (GDI_TextureData *) texture->driverdata; + + if (data->makedirty) { + SDL_AddDirtyRect(&data->dirty, dstrect); + } + + SelectObject(data->memory_hdc, texturedata->hbm); + if (texturedata->hpal) { + SelectPalette(data->memory_hdc, texturedata->hpal, TRUE); + RealizePalette(data->memory_hdc); + } + if (texture->blendMode & (SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND)) { +#ifdef _WIN32_WCE + SDL_SetError("Texture has blendmode not supported under WinCE"); + return -1; +#else + BLENDFUNCTION blendFunc = { + AC_SRC_OVER, + 0, + texture->a, + AC_SRC_ALPHA + }; + if (!AlphaBlend + (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, + dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, srcrect->w, + srcrect->h, blendFunc)) { + WIN_SetError("AlphaBlend()"); + return -1; + } +#endif + } else { + if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { + if (!BitBlt + (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, + srcrect->h, data->memory_hdc, srcrect->x, srcrect->y, + SRCCOPY)) { + WIN_SetError("BitBlt()"); + return -1; + } + } else { + if (!StretchBlt + (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, + dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, + srcrect->w, srcrect->h, SRCCOPY)) { + WIN_SetError("StretchBlt()"); + return -1; + } + } + } + return 0; +} + +static int +GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, void * pixels, int pitch) +{ + GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + struct { + HBITMAP hbm; + void *pixels; + int pitch; + Uint32 format; + } data; + + data.format = display->current_mode.format; + data.pitch = (rect->w * SDL_BYTESPERPIXEL(data.format)); + + data.hbm = GDI_CreateDIBSection(renderdata->memory_hdc, rect->w, rect->h, + data.pitch, data.format, NULL, + &data.pixels); + if (!data.hbm) { + WIN_SetError("Couldn't create bitmap"); + return -1; + } + + SelectObject(renderdata->memory_hdc, data.hbm); + if (!BitBlt(renderdata->memory_hdc, 0, 0, rect->w, rect->h, + renderdata->current_hdc, rect->x, rect->y, SRCCOPY)) { + WIN_SetError("BitBlt()"); + DeleteObject(data.hbm); + return -1; + } + + SDL_ConvertPixels(rect->w, rect->h, + data.format, data.pixels, data.pitch, + format, pixels, pitch); + + DeleteObject(data.hbm); + return 0; +} + +static int +GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, const void * pixels, int pitch) +{ + GDI_RenderData *renderdata = (GDI_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SDL_VideoDisplay *display = window->display; + struct { + HBITMAP hbm; + void *pixels; + int pitch; + Uint32 format; + } data; + + data.format = display->current_mode.format; + data.pitch = (rect->w * SDL_BYTESPERPIXEL(data.format)); + + data.hbm = GDI_CreateDIBSection(renderdata->memory_hdc, rect->w, rect->h, + data.pitch, data.format, + NULL, &data.pixels); + if (!data.hbm) { + WIN_SetError("Couldn't create bitmap"); + return -1; + } + + SDL_ConvertPixels(rect->w, rect->h, format, pixels, pitch, + data.format, data.pixels, data.pitch); + + SelectObject(renderdata->memory_hdc, data.hbm); + if (!BitBlt(renderdata->current_hdc, rect->x, rect->y, rect->w, rect->h, + renderdata->memory_hdc, 0, 0, SRCCOPY)) { + WIN_SetError("BitBlt()"); + DeleteObject(data.hbm); + return -1; + } + + DeleteObject(data.hbm); + return 0; +} + +static void +GDI_RenderPresent(SDL_Renderer * renderer) +{ + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; + SDL_DirtyRect *dirty; + + /* Send the data to the display */ + if (!(renderer->info.flags & SDL_RENDERER_SINGLEBUFFER)) { + for (dirty = data->dirty.list; dirty; dirty = dirty->next) { + const SDL_Rect *rect = &dirty->rect; + BitBlt(data->window_hdc, rect->x, rect->y, rect->w, rect->h, + data->render_hdc, rect->x, rect->y, SRCCOPY); + } + SDL_ClearDirtyRects(&data->dirty); + } + + /* Update the flipping chain, if any */ + if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) { + data->current_hbm = (data->current_hbm + 1) % 2; + SelectObject(data->render_hdc, data->hbm[data->current_hbm]); + } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) { + data->current_hbm = (data->current_hbm + 1) % 3; + SelectObject(data->render_hdc, data->hbm[data->current_hbm]); + } +} + +static void +GDI_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + GDI_TextureData *data = (GDI_TextureData *) texture->driverdata; + + if (!data) { + return; + } + if (data->yuv) { + SDL_SW_DestroyYUVTexture(data->yuv); + } + if (data->hpal) { + DeleteObject(data->hpal); + } + if (data->hbm) { + DeleteObject(data->hbm); + } + SDL_free(data); + texture->driverdata = NULL; +} + +static void +GDI_DestroyRenderer(SDL_Renderer * renderer) +{ + GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata; + int i; + + if (data) { + DeleteDC(data->render_hdc); + DeleteDC(data->memory_hdc); +#ifndef NO_GETDIBBITS + if (data->bmi) { + SDL_free(data->bmi); + } +#endif + for (i = 0; i < SDL_arraysize(data->hbm); ++i) { + if (data->hbm[i]) { + DeleteObject(data->hbm[i]); + } + } + SDL_FreeDirtyRects(&data->dirty); + SDL_free(data); + } + SDL_free(renderer); +} + +#endif /* SDL_VIDEO_RENDER_GDI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_gdirender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_gdirender.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,30 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +/* SDL surface based renderer implementation */ + +#if SDL_VIDEO_RENDER_GDI +extern void GDI_AddRenderDriver(_THIS); +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_msctf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_msctf.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,221 @@ +#ifndef _SDL_msctf_h +#define _SDL_msctf_h + +#include + +#define TF_INVALID_COOKIE (0xffffffff) +#define TF_IPSINK_FLAG_ACTIVE 0x0001 +#define TF_TMAE_UIELEMENTENABLEDONLY 0x00000004 + +typedef struct ITfThreadMgr ITfThreadMgr; +typedef struct ITfDocumentMgr ITfDocumentMgr; +typedef struct ITfClientId ITfClientId; + +typedef struct IEnumTfDocumentMgrs IEnumTfDocumentMgrs; +typedef struct IEnumTfFunctionProviders IEnumTfFunctionProviders; +typedef struct ITfFunctionProvider ITfFunctionProvider; +typedef struct ITfCompartmentMgr ITfCompartmentMgr; +typedef struct ITfContext ITfContext; +typedef struct IEnumTfContexts IEnumTfContexts; +typedef struct ITfUIElementSink ITfUIElementSink; +typedef struct ITfUIElement ITfUIElement; +typedef struct ITfUIElementMgr ITfUIElementMgr; +typedef struct IEnumTfUIElements IEnumTfUIElements; +typedef struct ITfThreadMgrEx ITfThreadMgrEx; +typedef struct ITfCandidateListUIElement ITfCandidateListUIElement; +typedef struct ITfReadingInformationUIElement ITfReadingInformationUIElement; +typedef struct ITfInputProcessorProfileActivationSink ITfInputProcessorProfileActivationSink; +typedef struct ITfSource ITfSource; + +typedef DWORD TfClientId; +typedef DWORD TfEditCookie; + +typedef struct ITfThreadMgrVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfThreadMgr *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfThreadMgr *); + ULONG (STDMETHODCALLTYPE *Release)(ITfThreadMgr *); + HRESULT (STDMETHODCALLTYPE *Activate)(ITfThreadMgr *, TfClientId *); + HRESULT (STDMETHODCALLTYPE *Deactivate)(ITfThreadMgr *); + HRESULT (STDMETHODCALLTYPE *CreateDocumentMgr)(ITfThreadMgr *); + HRESULT (STDMETHODCALLTYPE *EnumDocumentMgrs)(ITfThreadMgr *, IEnumTfDocumentMgrs **); + HRESULT (STDMETHODCALLTYPE *GetFocus)(ITfThreadMgr *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *SetFocus)(ITfThreadMgr *, ITfDocumentMgr *); + HRESULT (STDMETHODCALLTYPE *AssociateFocus)(ITfThreadMgr *, HWND, ITfDocumentMgr *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *IsThreadFocus)(ITfThreadMgr *, BOOL *); + HRESULT (STDMETHODCALLTYPE *GetFunctionProvider)(ITfThreadMgr *, REFCLSID, ITfFunctionProvider **); + HRESULT (STDMETHODCALLTYPE *EnumFunctionProviders)(ITfThreadMgr *, IEnumTfFunctionProviders **); + HRESULT (STDMETHODCALLTYPE *GetGlobalCompartment)(ITfThreadMgr *, ITfCompartmentMgr **); +} ITfThreadMgrVtbl; + +struct ITfThreadMgr +{ + const struct ITfThreadMgrVtbl *lpVtbl; +}; + +typedef struct ITfThreadMgrExVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfThreadMgrEx *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfThreadMgrEx *); + ULONG (STDMETHODCALLTYPE *Release)(ITfThreadMgrEx *); + HRESULT (STDMETHODCALLTYPE *Activate)(ITfThreadMgrEx *, TfClientId *); + HRESULT (STDMETHODCALLTYPE *Deactivate)(ITfThreadMgrEx *); + HRESULT (STDMETHODCALLTYPE *CreateDocumentMgr)(ITfThreadMgrEx *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *EnumDocumentMgrs)(ITfThreadMgrEx *, IEnumTfDocumentMgrs **); + HRESULT (STDMETHODCALLTYPE *GetFocus)(ITfThreadMgrEx *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *SetFocus)(ITfThreadMgrEx *, ITfDocumentMgr *); + HRESULT (STDMETHODCALLTYPE *AssociateFocus)(ITfThreadMgrEx *, ITfDocumentMgr *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *IsThreadFocus)(ITfThreadMgrEx *, BOOL *); + HRESULT (STDMETHODCALLTYPE *GetFunctionProvider)(ITfThreadMgrEx *, REFCLSID, ITfFunctionProvider **); + HRESULT (STDMETHODCALLTYPE *EnumFunctionProviders)(ITfThreadMgrEx *, IEnumTfFunctionProviders **); + HRESULT (STDMETHODCALLTYPE *GetGlobalCompartment)(ITfThreadMgrEx *, ITfCompartmentMgr **); + HRESULT (STDMETHODCALLTYPE *ActivateEx)(ITfThreadMgrEx *, TfClientId *, DWORD); + HRESULT (STDMETHODCALLTYPE *GetActiveFlags)(ITfThreadMgrEx *, DWORD *); +} ITfThreadMgrExVtbl; + +struct ITfThreadMgrEx +{ + const struct ITfThreadMgrExVtbl *lpVtbl; +}; + +typedef struct ITfDocumentMgrVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfDocumentMgr *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfDocumentMgr *); + ULONG (STDMETHODCALLTYPE *Release)(ITfDocumentMgr *); + HRESULT (STDMETHODCALLTYPE *CreateContext)(ITfDocumentMgr *, TfClientId, DWORD, IUnknown *, ITfContext **, TfEditCookie *); + HRESULT (STDMETHODCALLTYPE *Push)(ITfDocumentMgr *, ITfContext *); + HRESULT (STDMETHODCALLTYPE *Pop)(ITfDocumentMgr *); + HRESULT (STDMETHODCALLTYPE *GetTop)(ITfDocumentMgr *, ITfContext **); + HRESULT (STDMETHODCALLTYPE *GetBase)(ITfDocumentMgr *, ITfContext **); + HRESULT (STDMETHODCALLTYPE *EnumContexts)(ITfDocumentMgr *, IEnumTfContexts **); +} ITfDocumentMgrVtbl; + +struct ITfDocumentMgr +{ + const struct ITfDocumentMgrVtbl *lpVtbl; +}; + +typedef struct ITfUIElementSinkVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElementSink *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElementSink *); + ULONG (STDMETHODCALLTYPE *Release)(ITfUIElementSink *); + HRESULT (STDMETHODCALLTYPE *BeginUIElement)(ITfUIElementSink *, DWORD, BOOL *); + HRESULT (STDMETHODCALLTYPE *UpdateUIElement)(ITfUIElementSink *, DWORD); + HRESULT (STDMETHODCALLTYPE *EndUIElement)(ITfUIElementSink *, DWORD); +} ITfUIElementSinkVtbl; + +struct ITfUIElementSink +{ + const struct ITfUIElementSinkVtbl *lpVtbl; +}; + +typedef struct ITfUIElementMgrVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElementMgr *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElementMgr *); + ULONG (STDMETHODCALLTYPE *Release)(ITfUIElementMgr *); + HRESULT (STDMETHODCALLTYPE *BeginUIElement)(ITfUIElementMgr *, ITfUIElement *, BOOL *, DWORD *); + HRESULT (STDMETHODCALLTYPE *UpdateUIElement)(ITfUIElementMgr *, DWORD); + HRESULT (STDMETHODCALLTYPE *EndUIElement)(ITfUIElementMgr *, DWORD); + HRESULT (STDMETHODCALLTYPE *GetUIElement)(ITfUIElementMgr *, DWORD, ITfUIElement **); + HRESULT (STDMETHODCALLTYPE *EnumUIElements)(ITfUIElementMgr *, IEnumTfUIElements **); +} ITfUIElementMgrVtbl; + +struct ITfUIElementMgr +{ + const struct ITfUIElementMgrVtbl *lpVtbl; +}; + +typedef struct ITfCandidateListUIElementVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfCandidateListUIElement *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfCandidateListUIElement *); + ULONG (STDMETHODCALLTYPE *Release)(ITfCandidateListUIElement *); + HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfCandidateListUIElement *, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfCandidateListUIElement *, GUID *); + HRESULT (STDMETHODCALLTYPE *Show)(ITfCandidateListUIElement *, BOOL); + HRESULT (STDMETHODCALLTYPE *IsShown)(ITfCandidateListUIElement *, BOOL *); + HRESULT (STDMETHODCALLTYPE *GetUpdatedFlags)(ITfCandidateListUIElement *, DWORD *); + HRESULT (STDMETHODCALLTYPE *GetDocumentMgr)(ITfCandidateListUIElement *, ITfDocumentMgr **); + HRESULT (STDMETHODCALLTYPE *GetCount)(ITfCandidateListUIElement *, UINT *); + HRESULT (STDMETHODCALLTYPE *GetSelection)(ITfCandidateListUIElement *, UINT *); + HRESULT (STDMETHODCALLTYPE *GetString)(ITfCandidateListUIElement *, UINT, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetPageIndex)(ITfCandidateListUIElement *, UINT *, UINT, UINT *); + HRESULT (STDMETHODCALLTYPE *SetPageIndex)(ITfCandidateListUIElement *, UINT *, UINT); + HRESULT (STDMETHODCALLTYPE *GetCurrentPage)(ITfCandidateListUIElement *, UINT *); +} ITfCandidateListUIElementVtbl; + +struct ITfCandidateListUIElement +{ + const struct ITfCandidateListUIElementVtbl *lpVtbl; +}; + +typedef struct ITfReadingInformationUIElementVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfReadingInformationUIElement *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfReadingInformationUIElement *); + ULONG (STDMETHODCALLTYPE *Release)(ITfReadingInformationUIElement *); + HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfReadingInformationUIElement *, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfReadingInformationUIElement *, GUID *); + HRESULT (STDMETHODCALLTYPE *Show)(ITfReadingInformationUIElement *, BOOL); + HRESULT (STDMETHODCALLTYPE *IsShown)(ITfReadingInformationUIElement *, BOOL *); + HRESULT (STDMETHODCALLTYPE *GetUpdatedFlags)(ITfReadingInformationUIElement *, DWORD *); + HRESULT (STDMETHODCALLTYPE *GetContext)(ITfReadingInformationUIElement *, ITfContext **); + HRESULT (STDMETHODCALLTYPE *GetString)(ITfReadingInformationUIElement *, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetMaxReadingStringLength)(ITfReadingInformationUIElement *, UINT *); + HRESULT (STDMETHODCALLTYPE *GetErrorIndex)(ITfReadingInformationUIElement *, UINT *); + HRESULT (STDMETHODCALLTYPE *IsVerticalOrderPreferred)(ITfReadingInformationUIElement *, BOOL *); +} ITfReadingInformationUIElementVtbl; + +struct ITfReadingInformationUIElement +{ + const struct ITfReadingInformationUIElementVtbl *lpVtbl; +}; + +typedef struct ITfUIElementVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfUIElement *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfUIElement *); + ULONG (STDMETHODCALLTYPE *Release)(ITfUIElement *); + HRESULT (STDMETHODCALLTYPE *GetDescription)(ITfUIElement *, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetGUID)(ITfUIElement *, GUID *); + HRESULT (STDMETHODCALLTYPE *Show)(ITfUIElement *, BOOL); + HRESULT (STDMETHODCALLTYPE *IsShown)(ITfUIElement *, BOOL *); +} ITfUIElementVtbl; + +struct ITfUIElement +{ + const struct ITfUIElementVtbl *lpVtbl; +}; + +typedef struct ITfInputProcessorProfileActivationSinkVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfInputProcessorProfileActivationSink *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfInputProcessorProfileActivationSink *); + ULONG (STDMETHODCALLTYPE *Release)(ITfInputProcessorProfileActivationSink *); + HRESULT (STDMETHODCALLTYPE *OnActivated)(ITfInputProcessorProfileActivationSink *, DWORD, LANGID, REFCLSID, REFGUID, REFGUID, HKL, DWORD); + +} ITfInputProcessorProfileActivationSinkVtbl; + +struct ITfInputProcessorProfileActivationSink +{ + const struct ITfInputProcessorProfileActivationSinkVtbl *lpVtbl; +}; + +typedef struct ITfSourceVtbl +{ + HRESULT (STDMETHODCALLTYPE *QueryInterface)(ITfSource *, REFIID, void **); + ULONG (STDMETHODCALLTYPE *AddRef)(ITfSource *); + ULONG (STDMETHODCALLTYPE *Release)(ITfSource *); + HRESULT (STDMETHODCALLTYPE *AdviseSink)(ITfSource *, REFIID, IUnknown *, DWORD *); + HRESULT (STDMETHODCALLTYPE *UnadviseSink)(ITfSource *, DWORD); +} ITfSourceVtbl; + +struct ITfSource +{ + const struct ITfSourceVtbl *lpVtbl; +}; + +#endif /* _SDL_msctf_h */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_vkeys.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_vkeys.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,77 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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 +#define VK_OEM_102 0xE2 + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsclipboard.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsclipboard.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,169 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#include "SDL_windowsvideo.h" +#include "SDL_windowswindow.h" +#include "../../events/SDL_clipboardevents_c.h" + + +#ifdef UNICODE +#define TEXT_FORMAT CF_UNICODETEXT +#else +#define TEXT_FORMAT CF_TEXT +#endif + + +/* Get any application owned window handle for clipboard association */ +static HWND +GetWindowHandle(_THIS) +{ + SDL_VideoDisplay *display; + SDL_Window *window; + + display = _this->displays; + if (display) { + window = display->windows; + if (window) { + return ((SDL_WindowData *) window->driverdata)->hwnd; + } + } + return NULL; +} + +int +WIN_SetClipboardText(_THIS, const char *text) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + int result = 0; + + if (OpenClipboard(GetWindowHandle(_this))) { + HANDLE hMem; + LPTSTR tstr; + SIZE_T i, size; + + /* Convert the text from UTF-8 to Windows Unicode */ + tstr = WIN_UTF8ToString(text); + if (!tstr) { + return -1; + } + + /* Find out the size of the data */ + for (size = 0, i = 0; tstr[i]; ++i, ++size) { + if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) { + /* We're going to insert a carriage return */ + ++size; + } + } + size = (size+1)*sizeof(*tstr); + + /* Save the data to the clipboard */ + hMem = GlobalAlloc(GMEM_MOVEABLE, size); + if (hMem) { + LPTSTR dst = (LPTSTR)GlobalLock(hMem); + /* Copy the text over, adding carriage returns as necessary */ + for (i = 0; tstr[i]; ++i) { + if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) { + *dst++ = '\r'; + } + *dst++ = tstr[i]; + } + *dst = 0; + GlobalUnlock(hMem); + + EmptyClipboard(); + if (!SetClipboardData(TEXT_FORMAT, hMem)) { + WIN_SetError("Couldn't set clipboard data"); + result = -1; + } +#ifdef _WIN32_WCE + data->clipboard_count = 0; +#else + data->clipboard_count = GetClipboardSequenceNumber(); +#endif + } + SDL_free(tstr); + + CloseClipboard(); + } else { + WIN_SetError("Couldn't open clipboard"); + result = -1; + } + return result; +} + +char * +WIN_GetClipboardText(_THIS) +{ + char *text; + + text = NULL; + if (IsClipboardFormatAvailable(TEXT_FORMAT) && + OpenClipboard(GetWindowHandle(_this))) { + HANDLE hMem; + LPTSTR tstr; + + hMem = GetClipboardData(TEXT_FORMAT); + if (hMem) { + tstr = (LPTSTR)GlobalLock(hMem); + text = WIN_StringToUTF8(tstr); + GlobalUnlock(hMem); + } else { + WIN_SetError("Couldn't get clipboard data"); + } + CloseClipboard(); + } + if (!text) { + text = SDL_strdup(""); + } + return text; +} + +SDL_bool +WIN_HasClipboardText(_THIS) +{ + if (IsClipboardFormatAvailable(TEXT_FORMAT)) { + return SDL_TRUE; + } else { + return SDL_FALSE; + } +} + +void +WIN_CheckClipboardUpdate(struct SDL_VideoData * data) +{ + DWORD count; + +#ifdef _WIN32_WCE + count = 0; +#else + count = GetClipboardSequenceNumber(); +#endif + if (count != data->clipboard_count) { + if (data->clipboard_count) { + SDL_SendClipboardUpdate(); + } + data->clipboard_count = count; + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsclipboard.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsclipboard.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,37 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_windowsclipboard_h +#define _SDL_windowsclipboard_h + +/* Forward declaration */ +struct SDL_VideoData; + +extern int WIN_SetClipboardText(_THIS, const char *text); +extern char *WIN_GetClipboardText(_THIS); +extern SDL_bool WIN_HasClipboardText(_THIS); +extern void WIN_CheckClipboardUpdate(struct SDL_VideoData * data); + +#endif /* _SDL_windowsclipboard_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsevents.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsevents.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,712 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#include "SDL_windowsvideo.h" +#include "SDL_windowsshape.h" +#include "SDL_syswm.h" +#include "SDL_vkeys.h" +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_touch_c.h" + + + +/*#define WMMSG_DEBUG*/ +#ifdef WMMSG_DEBUG +#include +#include "wmmsg.h" +#endif + +/* Masks for processing the windows KEYDOWN and KEYUP messages */ +#define REPEATED_KEYMASK (1<<30) +#define EXTENDED_KEYMASK (1<<24) + +#define VK_ENTER 10 /* Keypad Enter ... no VKEY defined? */ + +/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */ +#ifndef WM_XBUTTONDOWN +#define WM_XBUTTONDOWN 0x020B +#endif +#ifndef WM_XBUTTONUP +#define WM_XBUTTONUP 0x020C +#endif +#ifndef GET_XBUTTON_WPARAM +#define GET_XBUTTON_WPARAM(w) (HIWORD(w)) +#endif +#ifndef WM_INPUT +#define WM_INPUT 0x00ff +#endif +#ifndef WM_TOUCH +#define WM_TOUCH 0x0240 +#endif + + +static WPARAM +RemapVKEY(WPARAM wParam, LPARAM lParam) +{ + int i; + BYTE scancode = (BYTE) ((lParam >> 16) & 0xFF); + + /* Windows remaps alphabetic keys based on current layout. + We try to provide USB scancodes, so undo this mapping. + */ + if (wParam >= 'A' && wParam <= 'Z') { + if (scancode != alpha_scancodes[wParam - 'A']) { + for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) { + if (scancode == alpha_scancodes[i]) { + wParam = 'A' + i; + break; + } + } + } + } + + /* Keypad keys are a little trickier, we always scan for them. + Keypad arrow keys have the same scancode as normal arrow keys, + except they don't have the extended bit (0x1000000) set. + */ + if (!(lParam & 0x1000000)) { + if (wParam == VK_DELETE) { + wParam = VK_DECIMAL; + } else { + for (i = 0; i < SDL_arraysize(keypad_scancodes); ++i) { + if (scancode == keypad_scancodes[i]) { + wParam = VK_NUMPAD0 + i; + break; + } + } + } + } + + return wParam; +} + +LRESULT CALLBACK +WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + SDL_WindowData *data; + LRESULT returnCode = -1; + + /* Send a SDL_SYSWMEVENT if the application wants them */ + if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { + SDL_SysWMmsg wmmsg; + + SDL_VERSION(&wmmsg.version); + wmmsg.subsystem = SDL_SYSWM_WINDOWS; + wmmsg.msg.win.hwnd = hwnd; + wmmsg.msg.win.msg = msg; + wmmsg.msg.win.wParam = wParam; + wmmsg.msg.win.lParam = lParam; + SDL_SendSysWMEvent(&wmmsg); + } + + /* Get the window data for the window */ + data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData")); + if (!data) { + return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); + } + +#ifdef WMMSG_DEBUG + { + FILE *log = fopen("wmmsg.txt", "a"); + fprintf(log, "Received windows message: %p ", hwnd); + if (msg > MAX_WMMSG) { + fprintf(log, "%d", msg); + } else { + fprintf(log, "%s", wmtab[msg]); + } + fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam); + fclose(log); + } +#endif + + if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata)) + return 0; + + switch (msg) { + + case WM_SHOWWINDOW: + { + if (wParam) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); + } else { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); + } + } + break; + + case WM_ACTIVATE: + { + BOOL minimized; + + minimized = HIWORD(wParam); + if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); + SDL_SendWindowEvent(data->window, + SDL_WINDOWEVENT_RESTORED, 0, 0); +#ifndef _WIN32_WCE /* WinCE misses IsZoomed() */ + if (IsZoomed(hwnd)) { + SDL_SendWindowEvent(data->window, + SDL_WINDOWEVENT_MAXIMIZED, 0, 0); + } +#endif + if (SDL_GetKeyboardFocus() != data->window) { + SDL_SetKeyboardFocus(data->window); + } + /* + * FIXME: Update keyboard state + */ + WIN_CheckClipboardUpdate(data->videodata); + } else { + if (SDL_GetKeyboardFocus() == data->window) { + SDL_SetKeyboardFocus(NULL); + } + if (minimized) { + SDL_SendWindowEvent(data->window, + SDL_WINDOWEVENT_MINIMIZED, 0, 0); + } + } + } + returnCode = 0; + break; + + case WM_MOUSEMOVE: +#ifdef _WIN32_WCE + /* transform coords for VGA, WVGA... */ + { + SDL_VideoData *videodata = data->videodata; + if(videodata->CoordTransform && + (videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW)) + { + POINT pt; + pt.x = LOWORD(lParam); + pt.y = HIWORD(lParam); + videodata->CoordTransform(data->window, &pt); + SDL_SendMouseMotion(data->window, 0, pt.x, pt.y); + break; + } + } +#endif + SDL_SendMouseMotion(data->window, 0, LOWORD(lParam), HIWORD(lParam)); + break; + + case WM_LBUTTONDOWN: + SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_LEFT); + break; + + case WM_LBUTTONUP: + SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_LEFT); + break; + + case WM_RBUTTONDOWN: + SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_RIGHT); + break; + + case WM_RBUTTONUP: + SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_RIGHT); + break; + + case WM_MBUTTONDOWN: + SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_MIDDLE); + break; + + case WM_MBUTTONUP: + SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_MIDDLE); + break; + + case WM_XBUTTONDOWN: + SDL_SendMouseButton(data->window, SDL_PRESSED, SDL_BUTTON_X1 + GET_XBUTTON_WPARAM(wParam) - 1); + returnCode = TRUE; + break; + + case WM_XBUTTONUP: + SDL_SendMouseButton(data->window, SDL_RELEASED, SDL_BUTTON_X1 + GET_XBUTTON_WPARAM(wParam) - 1); + returnCode = TRUE; + break; + + case WM_MOUSEWHEEL: + { + int motion = (short) HIWORD(wParam); + + SDL_SendMouseWheel(data->window, 0, motion); + break; + } + + case WM_MOUSELEAVE: + if (SDL_GetMouseFocus() == data->window) { + SDL_SetMouseFocus(NULL); + } + returnCode = 0; + break; + + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + { + wParam = RemapVKEY(wParam, lParam); + switch (wParam) { + case VK_CONTROL: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_RCONTROL; + else + wParam = VK_LCONTROL; + break; + case VK_SHIFT: + /* EXTENDED trick doesn't work here */ + { + Uint8 *state = SDL_GetKeyboardState(NULL); + if (state[SDL_SCANCODE_LSHIFT] == SDL_RELEASED + && (GetKeyState(VK_LSHIFT) & 0x8000)) { + wParam = VK_LSHIFT; + } else if (state[SDL_SCANCODE_RSHIFT] == SDL_RELEASED + && (GetKeyState(VK_RSHIFT) & 0x8000)) { + wParam = VK_RSHIFT; + } else { + /* Probably a key repeat */ + wParam = 256; + } + } + break; + case VK_MENU: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_RMENU; + else + wParam = VK_LMENU; + break; + case VK_RETURN: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_ENTER; + break; + } + if (wParam < 256) { + SDL_SendKeyboardKey(SDL_PRESSED, + data->videodata->key_layout[wParam]); + } + } + returnCode = 0; + break; + + case WM_SYSKEYUP: + case WM_KEYUP: + { + wParam = RemapVKEY(wParam, lParam); + switch (wParam) { + case VK_CONTROL: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_RCONTROL; + else + wParam = VK_LCONTROL; + break; + case VK_SHIFT: + /* EXTENDED trick doesn't work here */ + { + Uint8 *state = SDL_GetKeyboardState(NULL); + if (state[SDL_SCANCODE_LSHIFT] == SDL_PRESSED + && !(GetKeyState(VK_LSHIFT) & 0x8000)) { + wParam = VK_LSHIFT; + } else if (state[SDL_SCANCODE_RSHIFT] == SDL_PRESSED + && !(GetKeyState(VK_RSHIFT) & 0x8000)) { + wParam = VK_RSHIFT; + } else { + /* Probably a key repeat */ + wParam = 256; + } + } + break; + case VK_MENU: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_RMENU; + else + wParam = VK_LMENU; + break; + case VK_RETURN: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_ENTER; + break; + } + + /* Windows only reports keyup for print screen */ + if (wParam == VK_SNAPSHOT + && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] == + SDL_RELEASED) { + SDL_SendKeyboardKey(SDL_PRESSED, + data->videodata->key_layout[wParam]); + } + if (wParam < 256) { + SDL_SendKeyboardKey(SDL_RELEASED, + data->videodata->key_layout[wParam]); + } + } + returnCode = 0; + break; + + case WM_CHAR: + { + char text[4]; + + /* Convert to UTF-8 and send it on... */ + if (wParam <= 0x7F) { + text[0] = (char) wParam; + text[1] = '\0'; + } else if (wParam <= 0x7FF) { + text[0] = 0xC0 | (char) ((wParam >> 6) & 0x1F); + text[1] = 0x80 | (char) (wParam & 0x3F); + text[2] = '\0'; + } else { + text[0] = 0xE0 | (char) ((wParam >> 12) & 0x0F); + text[1] = 0x80 | (char) ((wParam >> 6) & 0x3F); + text[2] = 0x80 | (char) (wParam & 0x3F); + text[3] = '\0'; + } + SDL_SendKeyboardText(text); + } + returnCode = 0; + break; + + case WM_INPUTLANGCHANGE: + { + WIN_UpdateKeymap(); + } + returnCode = 1; + break; + + case WM_GETMINMAXINFO: + { + MINMAXINFO *info; + RECT size; + int x, y; + int w, h; + int style; + BOOL menu; + + /* If we allow resizing, let the resize happen naturally */ + if(SDL_IsShapedWindow(data->window)) + Win32_ResizeWindowShape(data->window); + if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) { + returnCode = 0; + break; + } + + /* Get the current position of our window */ + GetWindowRect(hwnd, &size); + x = size.left; + y = size.top; + + /* Calculate current size of our window */ + SDL_GetWindowSize(data->window, &w, &h); + size.top = 0; + size.left = 0; + size.bottom = h; + size.right = w; + + + style = GetWindowLong(hwnd, GWL_STYLE); +#ifdef _WIN32_WCE + menu = FALSE; +#else + /* DJM - according to the docs for GetMenu(), the + return value is undefined if hwnd is a child window. + Aparently it's too difficult for MS to check + inside their function, so I have to do it here. + */ + menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); +#endif + AdjustWindowRectEx(&size, style, menu, 0); + w = size.right - size.left; + h = size.bottom - size.top; + + /* Fix our size to the current size */ + info = (MINMAXINFO *) lParam; + info->ptMaxSize.x = w; + info->ptMaxSize.y = h; + info->ptMaxPosition.x = x; + info->ptMaxPosition.y = y; + info->ptMinTrackSize.x = w; + info->ptMinTrackSize.y = h; + info->ptMaxTrackSize.x = w; + info->ptMaxTrackSize.y = h; + } + returnCode = 0; + break; + + case WM_WINDOWPOSCHANGED: + { + RECT rect; + int x, y; + int w, h; + Uint32 window_flags; + + if (!GetClientRect(hwnd, &rect) || + (rect.right == rect.left && rect.bottom == rect.top)) { + break; + } + ClientToScreen(hwnd, (LPPOINT) & rect); + ClientToScreen(hwnd, (LPPOINT) & rect + 1); + + window_flags = SDL_GetWindowFlags(data->window); + if ((window_flags & SDL_WINDOW_INPUT_GRABBED) && + (window_flags & SDL_WINDOW_INPUT_FOCUS)) { + ClipCursor(&rect); + } + + x = rect.left; + y = rect.top; + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y); + + w = rect.right - rect.left; + h = rect.bottom - rect.top; + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w, + h); + } + break; + + case WM_SETCURSOR: + { + Uint16 hittest; + + hittest = LOWORD(lParam); + if (hittest == HTCLIENT) { + /* FIXME: Implement the cursor API */ + static HCURSOR cursor; + if (!cursor) { + cursor = LoadCursor(NULL, IDC_ARROW); + } + SetCursor(cursor); + returnCode = TRUE; + } + } + break; + + /* We are about to get palette focus! */ + case WM_QUERYNEWPALETTE: + { + /* + WIN_RealizePalette(current_video); + returnCode = TRUE; + */ + } + break; + + /* Another application changed the palette */ + case WM_PALETTECHANGED: + { + /* + WIN_PaletteChanged(current_video, (HWND) wParam); + */ + } + break; + + /* We were occluded, refresh our display */ + case WM_PAINT: + { + RECT rect; + if (GetUpdateRect(hwnd, &rect, FALSE)) { + ValidateRect(hwnd, &rect); + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, + 0, 0); + } + } + returnCode = 0; + break; + + /* We'll do our own drawing, prevent flicker */ + case WM_ERASEBKGND: + { + } + return (1); + + case WM_SYSCOMMAND: + { + /* Don't start the screensaver or blank the monitor in fullscreen apps */ + if ((wParam & 0xFFF0) == SC_SCREENSAVE || + (wParam & 0xFFF0) == SC_MONITORPOWER) { + if (SDL_GetVideoDevice()->suspend_screensaver) { + return (0); + } + } + } + break; + + case WM_CLOSE: + { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); + } + returnCode = 0; + break; + + case WM_TOUCH: + { + UINT i, num_inputs = LOWORD(wParam); + PTOUCHINPUT inputs = SDL_stack_alloc(TOUCHINPUT, num_inputs); + if (data->videodata->GetTouchInputInfo((HTOUCHINPUT)lParam, num_inputs, inputs, sizeof(TOUCHINPUT))) { + RECT rect; + float x, y; + + if (!GetClientRect(hwnd, &rect) || + (rect.right == rect.left && rect.bottom == rect.top)) { + break; + } + ClientToScreen(hwnd, (LPPOINT) & rect); + ClientToScreen(hwnd, (LPPOINT) & rect + 1); + rect.top *= 100; + rect.left *= 100; + rect.bottom *= 100; + rect.right *= 100; + + for (i = 0; i < num_inputs; ++i) { + PTOUCHINPUT input = &inputs[i]; + + SDL_TouchID touchId = (SDL_TouchID)input->hSource; + if (!SDL_GetTouch(touchId)) { + SDL_Touch touch; + + touch.id = touchId; + touch.x_min = 0; + touch.x_max = 1; + touch.native_xres = touch.x_max - touch.x_min; + touch.y_min = 0; + touch.y_max = 1; + touch.native_yres = touch.y_max - touch.y_min; + touch.pressure_min = 0; + touch.pressure_max = 1; + touch.native_pressureres = touch.pressure_max - touch.pressure_min; + + if (SDL_AddTouch(&touch, "") < 0) { + continue; + } + } + + // Get the normalized coordinates for the window + x = (float)(input->x - rect.left)/(rect.right - rect.left); + y = (float)(input->y - rect.top)/(rect.bottom - rect.top); + + if (input->dwFlags & TOUCHEVENTF_DOWN) { + SDL_SendFingerDown(touchId, input->dwID, SDL_TRUE, x, y, 1); + } + if (input->dwFlags & TOUCHEVENTF_MOVE) { + SDL_SendTouchMotion(touchId, input->dwID, SDL_FALSE, x, y, 1); + } + if (input->dwFlags & TOUCHEVENTF_UP) { + SDL_SendFingerDown(touchId, input->dwID, SDL_FALSE, x, y, 1); + } + } + } + SDL_stack_free(inputs); + + data->videodata->CloseTouchInputHandle((HTOUCHINPUT)lParam); + return 0; + } + break; + } + + /* If there's a window proc, assume it's going to handle messages */ + if (data->wndproc) { + return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam); + } else if (returnCode >= 0) { + return returnCode; + } else { + return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); + } +} + +void +WIN_PumpEvents(_THIS) +{ + MSG msg; + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +static int app_registered = 0; +LPTSTR SDL_Appname = NULL; +Uint32 SDL_Appstyle = 0; +HINSTANCE SDL_Instance = NULL; + +/* Register the class for this application */ +int +SDL_RegisterApp(char *name, Uint32 style, void *hInst) +{ + WNDCLASS class; + + /* Only do this once... */ + if (app_registered) { + ++app_registered; + return (0); + } + if (!name && !SDL_Appname) { + name = "SDL_app"; + SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC); + SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); + } + + if (name) { + SDL_Appname = WIN_UTF8ToString(name); + SDL_Appstyle = style; + SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); + } + + /* Register the application class */ + class.hCursor = NULL; + class.hIcon = + LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0, + LR_DEFAULTCOLOR); + class.lpszMenuName = NULL; + class.lpszClassName = SDL_Appname; + class.hbrBackground = NULL; + class.hInstance = SDL_Instance; + class.style = SDL_Appstyle; + class.lpfnWndProc = WIN_WindowProc; + class.cbWndExtra = 0; + class.cbClsExtra = 0; + if (!RegisterClass(&class)) { + SDL_SetError("Couldn't register application class"); + return (-1); + } + + app_registered = 1; + return (0); +} + +/* Unregisters the windowclass registered in SDL_RegisterApp above. */ +void +SDL_UnregisterApp() +{ + WNDCLASS class; + + /* SDL_RegisterApp might not have been called before */ + if (!app_registered) { + return; + } + --app_registered; + if (app_registered == 0) { + /* Check for any registered window classes. */ + if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) { + UnregisterClass(SDL_Appname, SDL_Instance); + } + SDL_free(SDL_Appname); + SDL_Appname = NULL; + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsevents.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsevents.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,37 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_windowsevents_h +#define _SDL_windowsevents_h + +extern LPTSTR SDL_Appname; +extern Uint32 SDL_Appstyle; +extern HINSTANCE SDL_Instance; + +extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, + LPARAM lParam); +extern void WIN_PumpEvents(_THIS); + +#endif /* _SDL_windowsevents_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsgamma.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsgamma.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,71 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#include "SDL_windowsvideo.h" + + +int +WIN_SetDisplayGammaRamp(_THIS, SDL_VideoDisplay * display, Uint16 * ramp) +{ +#ifdef _WIN32_WCE + return -1; +#else + SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; + HDC hdc; + BOOL succeeded = FALSE; + + hdc = CreateDC(data->DeviceName, NULL, NULL, NULL); + if (hdc) { + succeeded = SetDeviceGammaRamp(hdc, ramp); + if (!succeeded) { + WIN_SetError("SetDeviceGammaRamp()"); + } + DeleteDC(hdc); + } + return succeeded ? 0 : -1; +#endif +} + +int +WIN_GetDisplayGammaRamp(_THIS, SDL_VideoDisplay * display, Uint16 * ramp) +{ +#ifdef _WIN32_WCE + return -1; +#else + SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; + HDC hdc; + BOOL succeeded = FALSE; + + hdc = CreateDC(data->DeviceName, NULL, NULL, NULL); + if (hdc) { + succeeded = GetDeviceGammaRamp(hdc, ramp); + if (!succeeded) { + WIN_SetError("GetDeviceGammaRamp()"); + } + DeleteDC(hdc); + } + return succeeded ? 0 : -1; +#endif +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsgamma.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsgamma.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,32 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_windowsgamma_h +#define _SDL_windowsgamma_h + +extern int WIN_SetDisplayGammaRamp(_THIS, SDL_VideoDisplay * display, Uint16 * ramp); +extern int WIN_GetDisplayGammaRamp(_THIS, SDL_VideoDisplay * display, Uint16 * ramp); + +#endif /* _SDL_windowsgamma_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowskeyboard.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowskeyboard.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,1555 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#include "SDL_windowsvideo.h" + +#include "../../events/SDL_keyboard_c.h" +#include "../../events/scancodes_windows.h" + +#include +#include + +static void IME_Init(SDL_VideoData *videodata, HWND hwnd); +static void IME_Enable(SDL_VideoData *videodata, HWND hwnd); +static void IME_Disable(SDL_VideoData *videodata, HWND hwnd); +static void IME_Quit(SDL_VideoData *videodata); + +#ifndef MAPVK_VK_TO_VSC +#define MAPVK_VK_TO_VSC 0 +#endif +#ifndef MAPVK_VSC_TO_VK +#define MAPVK_VSC_TO_VK 1 +#endif +#ifndef MAPVK_VK_TO_CHAR +#define MAPVK_VK_TO_CHAR 2 +#endif + +/* Alphabetic scancodes for PC keyboards */ +BYTE alpha_scancodes[26] = { + 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50, 49, 24, + 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44 +}; + +BYTE keypad_scancodes[10] = { + 82, 79, 80, 81, 75, 76, 77, 71, 72, 73 +}; + +void +WIN_InitKeyboard(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + int i; + + /* Make sure the alpha scancodes are correct. T isn't usually remapped */ + if (MapVirtualKey('T', MAPVK_VK_TO_VSC) != alpha_scancodes['T' - 'A']) { +#if 0 + printf + ("Fixing alpha scancode map, assuming US QWERTY layout!\nPlease send the following 26 lines of output to the SDL mailing list , including a description of your keyboard hardware.\n"); +#endif + for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) { + alpha_scancodes[i] = MapVirtualKey('A' + i, MAPVK_VK_TO_VSC); +#if 0 + printf("%d = %d\n", i, alpha_scancodes[i]); +#endif + } + } + if (MapVirtualKey(VK_NUMPAD0, MAPVK_VK_TO_VSC) != keypad_scancodes[0]) { +#if 0 + printf + ("Fixing keypad scancode map!\nPlease send the following 10 lines of output to the SDL mailing list , including a description of your keyboard hardware.\n"); +#endif + for (i = 0; i < SDL_arraysize(keypad_scancodes); ++i) { + keypad_scancodes[i] = + MapVirtualKey(VK_NUMPAD0 + i, MAPVK_VK_TO_VSC); +#if 0 + printf("%d = %d\n", i, keypad_scancodes[i]); +#endif + } + } + + data->key_layout = windows_scancode_table; + + data->ime_com_initialized = SDL_FALSE; + data->ime_threadmgr = 0; + data->ime_initialized = SDL_FALSE; + data->ime_enabled = SDL_FALSE; + data->ime_available = SDL_FALSE; + data->ime_hwnd_main = 0; + data->ime_hwnd_current = 0; + data->ime_himc = 0; + data->ime_composition[0] = 0; + data->ime_readingstring[0] = 0; + data->ime_cursor = 0; + + data->ime_candlist = SDL_FALSE; + SDL_memset(data->ime_candidates, 0, sizeof(data->ime_candidates)); + data->ime_candcount = 0; + data->ime_candref = 0; + data->ime_candsel = 0; + data->ime_candpgsize = 0; + data->ime_candlistindexbase = 0; + data->ime_candvertical = SDL_TRUE; + + data->ime_candtex = NULL; + data->ime_dirty = SDL_FALSE; + SDL_memset(&data->ime_rect, 0, sizeof(data->ime_rect)); + SDL_memset(&data->ime_candlistrect, 0, sizeof(data->ime_candlistrect)); + data->ime_winwidth = 0; + data->ime_winheight = 0; + + data->ime_hkl = 0; + data->ime_himm32 = 0; + data->GetReadingString = 0; + data->ShowReadingWindow = 0; + data->ImmLockIMC = 0; + data->ImmUnlockIMC = 0; + data->ImmLockIMCC = 0; + data->ImmUnlockIMCC = 0; + data->ime_uiless = SDL_FALSE; + data->ime_threadmgrex = 0; + data->ime_uielemsinkcookie = TF_INVALID_COOKIE; + data->ime_alpnsinkcookie = TF_INVALID_COOKIE; + data->ime_openmodesinkcookie = TF_INVALID_COOKIE; + data->ime_convmodesinkcookie = TF_INVALID_COOKIE; + data->ime_uielemsink = 0; + data->ime_ippasink = 0; + + WIN_UpdateKeymap(); + + SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu"); + SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Windows"); + SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Windows"); +} + +void +WIN_UpdateKeymap() +{ + int i; + SDL_scancode scancode; + SDLKey keymap[SDL_NUM_SCANCODES]; + + SDL_GetDefaultKeymap(keymap); + + for (i = 0; i < SDL_arraysize(windows_scancode_table); i++) { + + /* Make sure this scancode is a valid character scancode */ + scancode = windows_scancode_table[i]; + if (scancode == SDL_SCANCODE_UNKNOWN || keymap[scancode] >= 127) { + continue; + } + + /* Alphabetic keys are handled specially, since Windows remaps them */ + if (i >= 'A' && i <= 'Z') { + BYTE vsc = alpha_scancodes[i - 'A']; + keymap[scancode] = MapVirtualKey(vsc, MAPVK_VSC_TO_VK) + 0x20; + } else { + keymap[scancode] = (MapVirtualKey(i, MAPVK_VK_TO_CHAR) & 0x7FFF); + } + } + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); +} + +void +WIN_QuitKeyboard(_THIS) +{ + IME_Quit((SDL_VideoData *)_this->driverdata); +} + +void +WIN_StartTextInput(_THIS) +{ + SDL_Window *window = SDL_GetKeyboardFocus(); + if (window) { + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + SDL_GetWindowSize(window, &videodata->ime_winwidth, &videodata->ime_winheight); + IME_Init(videodata, hwnd); + IME_Enable(videodata, hwnd); + } +} + +void +WIN_StopTextInput(_THIS) +{ + SDL_Window *window = SDL_GetKeyboardFocus(); + if (window) { + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + IME_Init(videodata, hwnd); + IME_Disable(videodata, hwnd); + } +} + +void +WIN_SetTextInputRect(_THIS, SDL_Rect *rect) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + videodata->ime_rect = *rect; +} + +#ifdef __GNUC__ +#undef DEFINE_GUID +#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) static const GUID n = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} +DEFINE_GUID(IID_ITfInputProcessorProfileActivationSink, 0x71C6E74E,0x0F28,0x11D8,0xA8,0x2A,0x00,0x06,0x5B,0x84,0x43,0x5C); +DEFINE_GUID(IID_ITfUIElementSink, 0xEA1EA136,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); +DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745C63,0xB2F0,0x4784,0x8B,0x67,0x5E,0x12,0xC8,0x70,0x1A,0x31); +DEFINE_GUID(IID_ITfSource, 0x4EA48A35,0x60AE,0x446F,0x8F,0xD6,0xE6,0xA8,0xD8,0x24,0x59,0xF7); +DEFINE_GUID(IID_ITfUIElementMgr, 0xEA1EA135,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); +DEFINE_GUID(IID_ITfCandidateListUIElement, 0xEA1EA138,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); +DEFINE_GUID(IID_ITfReadingInformationUIElement, 0xEA1EA139,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); +DEFINE_GUID(IID_ITfThreadMgr, 0xAA80E801,0x2021,0x11D2,0x93,0xE0,0x00,0x60,0xB0,0x67,0xB8,0x6E); +DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529A9E6B,0x6587,0x4F23,0xAB,0x9E,0x9C,0x7D,0x68,0x3E,0x3C,0x50); +DEFINE_GUID(IID_ITfThreadMgrEx, 0x3E90ADE3,0x7594,0x4CB0,0xBB,0x58,0x69,0x62,0x8F,0x5F,0x45,0x8C); +#endif + +#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) +#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) + +#define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) )) +#define IMEID_VER(id) ((id) & 0xffff0000) +#define IMEID_LANG(id) ((id) & 0x0000ffff) + +#define CHT_HKL_DAYI ((HKL)0xE0060404) +#define CHT_HKL_NEW_PHONETIC ((HKL)0xE0080404) +#define CHT_HKL_NEW_CHANG_JIE ((HKL)0xE0090404) +#define CHT_HKL_NEW_QUICK ((HKL)0xE00A0404) +#define CHT_HKL_HK_CANTONESE ((HKL)0xE00B0404) +#define CHT_IMEFILENAME1 "TINTLGNT.IME" +#define CHT_IMEFILENAME2 "CINTLGNT.IME" +#define CHT_IMEFILENAME3 "MSTCIPHA.IME" +#define IMEID_CHT_VER42 (LANG_CHT | MAKEIMEVERSION(4, 2)) +#define IMEID_CHT_VER43 (LANG_CHT | MAKEIMEVERSION(4, 3)) +#define IMEID_CHT_VER44 (LANG_CHT | MAKEIMEVERSION(4, 4)) +#define IMEID_CHT_VER50 (LANG_CHT | MAKEIMEVERSION(5, 0)) +#define IMEID_CHT_VER51 (LANG_CHT | MAKEIMEVERSION(5, 1)) +#define IMEID_CHT_VER52 (LANG_CHT | MAKEIMEVERSION(5, 2)) +#define IMEID_CHT_VER60 (LANG_CHT | MAKEIMEVERSION(6, 0)) +#define IMEID_CHT_VER_VISTA (LANG_CHT | MAKEIMEVERSION(7, 0)) + +#define CHS_HKL ((HKL)0xE00E0804) +#define CHS_IMEFILENAME1 "PINTLGNT.IME" +#define CHS_IMEFILENAME2 "MSSCIPYA.IME" +#define IMEID_CHS_VER41 (LANG_CHS | MAKEIMEVERSION(4, 1)) +#define IMEID_CHS_VER42 (LANG_CHS | MAKEIMEVERSION(4, 2)) +#define IMEID_CHS_VER53 (LANG_CHS | MAKEIMEVERSION(5, 3)) + +#define LANG() LOWORD((videodata->ime_hkl)) +#define PRIMLANG() ((WORD)PRIMARYLANGID(LANG())) +#define SUBLANG() SUBLANGID(LANG()) + +static void IME_UpdateInputLocale(SDL_VideoData *videodata); +static void IME_ClearComposition(SDL_VideoData *videodata); +static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd); +static void IME_SetupAPI(SDL_VideoData *videodata); +static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex); +static void IME_SendEditingEvent(SDL_VideoData *videodata); +static void IME_DestroyTextures(SDL_VideoData *videodata); + +#define SDL_IsEqualIID(riid1, riid2) SDL_IsEqualGUID(riid1, riid2) +#define SDL_IsEqualGUID(rguid1, rguid2) (!SDL_memcmp(rguid1, rguid2, sizeof(GUID))) + +static SDL_bool UILess_SetupSinks(SDL_VideoData *videodata); +static void UILess_ReleaseSinks(SDL_VideoData *videodata); +static void UILess_EnableUIUpdates(SDL_VideoData *videodata); +static void UILess_DisableUIUpdates(SDL_VideoData *videodata); + +static void +IME_Init(SDL_VideoData *videodata, HWND hwnd) +{ + if (videodata->ime_initialized) + return; + + videodata->ime_hwnd_main = hwnd; + if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) { + videodata->ime_com_initialized = SDL_TRUE; + CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (LPVOID *)&videodata->ime_threadmgr); + } + videodata->ime_initialized = SDL_TRUE; + videodata->ime_himm32 = LoadLibraryA("imm32.dll"); + if (!videodata->ime_himm32) { + videodata->ime_available = SDL_FALSE; + return; + } + videodata->ImmLockIMC = (LPINPUTCONTEXT2 (WINAPI *)(HIMC))GetProcAddress(videodata->ime_himm32, "ImmLockIMC"); + videodata->ImmUnlockIMC = (BOOL (WINAPI *)(HIMC))GetProcAddress(videodata->ime_himm32, "ImmUnlockIMC"); + videodata->ImmLockIMCC = (LPVOID (WINAPI *)(HIMCC))GetProcAddress(videodata->ime_himm32, "ImmLockIMCC"); + videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))GetProcAddress(videodata->ime_himm32, "ImmUnlockIMCC"); + + IME_SetWindow(videodata, hwnd); + videodata->ime_himc = ImmGetContext(hwnd); + ImmReleaseContext(hwnd, videodata->ime_himc); + if (!videodata->ime_himc) { + videodata->ime_available = SDL_FALSE; + IME_Disable(videodata, hwnd); + return; + } + videodata->ime_available = SDL_TRUE; + IME_UpdateInputLocale(videodata); + IME_SetupAPI(videodata); + videodata->ime_uiless = UILess_SetupSinks(videodata); + IME_UpdateInputLocale(videodata); + IME_Disable(videodata, hwnd); +} + +static void +IME_Enable(SDL_VideoData *videodata, HWND hwnd) +{ + if (!videodata->ime_initialized || !videodata->ime_hwnd_current) + return; + + if (!videodata->ime_available) { + IME_Disable(videodata, hwnd); + return; + } + if (videodata->ime_hwnd_current == videodata->ime_hwnd_main) + ImmAssociateContext(videodata->ime_hwnd_current, videodata->ime_himc); + + videodata->ime_enabled = SDL_TRUE; + IME_UpdateInputLocale(videodata); + UILess_EnableUIUpdates(videodata); +} + +static void +IME_Disable(SDL_VideoData *videodata, HWND hwnd) +{ + if (!videodata->ime_initialized || !videodata->ime_hwnd_current) + return; + + IME_ClearComposition(videodata); + if (videodata->ime_hwnd_current == videodata->ime_hwnd_main) + ImmAssociateContext(videodata->ime_hwnd_current, (HIMC)0); + + videodata->ime_enabled = SDL_FALSE; + UILess_DisableUIUpdates(videodata); +} + +static void +IME_Quit(SDL_VideoData *videodata) +{ + if (!videodata->ime_initialized) + return; + + UILess_ReleaseSinks(videodata); + if (videodata->ime_hwnd_main) + ImmAssociateContext(videodata->ime_hwnd_main, videodata->ime_himc); + + videodata->ime_hwnd_main = 0; + videodata->ime_himc = 0; + if (videodata->ime_himm32) { + FreeLibrary(videodata->ime_himm32); + videodata->ime_himm32 = 0; + } + if (videodata->ime_threadmgr) { + videodata->ime_threadmgr->lpVtbl->Release(videodata->ime_threadmgr); + videodata->ime_threadmgr = 0; + } + if (videodata->ime_com_initialized) { + CoUninitialize(); + videodata->ime_com_initialized = SDL_FALSE; + } + IME_DestroyTextures(videodata); + videodata->ime_initialized = SDL_FALSE; +} + +static void +IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) +{ + DWORD id = 0; + HIMC himc = 0; + WCHAR buffer[16]; + WCHAR *s = buffer; + DWORD len = 0; + INT err = 0; + BOOL vertical = FALSE; + UINT maxuilen = 0; + static OSVERSIONINFOA osversion = {0}; + if (videodata->ime_uiless) + return; + + videodata->ime_readingstring[0] = 0; + if (!osversion.dwOSVersionInfoSize) { + osversion.dwOSVersionInfoSize = sizeof(osversion); + GetVersionExA(&osversion); + } + id = IME_GetId(videodata, 0); + if (!id) + return; + + himc = ImmGetContext(hwnd); + if (!himc) + return; + + if (videodata->GetReadingString) { + len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen); + if (len) { + if (len > SDL_arraysize(buffer)) + len = SDL_arraysize(buffer); + + len = videodata->GetReadingString(himc, len, s, &err, &vertical, &maxuilen); + } + SDL_wcslcpy(videodata->ime_readingstring, s, len); + } + else { + LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc); + LPBYTE p = 0; + s = 0; + switch (id) + { + case IMEID_CHT_VER42: + case IMEID_CHT_VER43: + case IMEID_CHT_VER44: + p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 24); + if (!p) + break; + + len = *(DWORD *)(p + 7*4 + 32*4); + s = (WCHAR *)(p + 56); + break; + case IMEID_CHT_VER51: + case IMEID_CHT_VER52: + case IMEID_CHS_VER53: + p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 4); + if (!p) + break; + + p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4); + if (!p) + break; + + len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2); + s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4); + break; + case IMEID_CHS_VER41: + { + int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7; + p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4); + if (!p) + break; + + len = *(DWORD *)(p + 7*4 + 16*2*4); + s = (WCHAR *)(p + 6*4 + 16*2*1); + } + break; + case IMEID_CHS_VER42: + if (osversion.dwPlatformId != VER_PLATFORM_WIN32_NT) + break; + + p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1*4 + 1*4 + 6*4); + if (!p) + break; + + len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2); + s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4); + break; + } + if (s) + SDL_wcslcpy(videodata->ime_readingstring, s, len + 1); + + videodata->ImmUnlockIMCC(lpimc->hPrivate); + videodata->ImmUnlockIMC(himc); + } + ImmReleaseContext(hwnd, himc); + IME_SendEditingEvent(videodata); +} + +static void +IME_InputLangChanged(SDL_VideoData *videodata) +{ + UINT lang = PRIMLANG(); + IME_UpdateInputLocale(videodata); + if (!videodata->ime_uiless) + videodata->ime_candlistindexbase = (videodata->ime_hkl == CHT_HKL_DAYI) ? 0 : 1; + + IME_SetupAPI(videodata); + if (lang != PRIMLANG()) { + IME_ClearComposition(videodata); + } +} + +static DWORD +IME_GetId(SDL_VideoData *videodata, UINT uIndex) +{ + static HKL hklprev = 0; + static DWORD dwRet[2] = {0}; + DWORD dwVerSize = 0; + DWORD dwVerHandle = 0; + LPVOID lpVerBuffer = 0; + LPVOID lpVerData = 0; + UINT cbVerData = 0; + char szTemp[256]; + HKL hkl = 0; + DWORD dwLang = 0; + if (uIndex >= sizeof(dwRet) / sizeof(dwRet[0])) + return 0; + + hkl = videodata->ime_hkl; + if (hklprev == hkl) + return dwRet[uIndex]; + + hklprev = hkl; + dwLang = ((DWORD)hkl & 0xffff); + if (videodata->ime_uiless && LANG() == LANG_CHT) { + dwRet[0] = IMEID_CHT_VER_VISTA; + dwRet[1] = 0; + return dwRet[0]; + } + if (hkl != CHT_HKL_NEW_PHONETIC + && hkl != CHT_HKL_NEW_CHANG_JIE + && hkl != CHT_HKL_NEW_QUICK + && hkl != CHT_HKL_HK_CANTONESE + && hkl != CHS_HKL) { + dwRet[0] = dwRet[1] = 0; + return dwRet[uIndex]; + } + if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) { + dwRet[0] = dwRet[1] = 0; + return dwRet[uIndex]; + } + if (!videodata->GetReadingString) { + #define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) + if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2 + && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2 + && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2 + && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2 + && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) { + dwRet[0] = dwRet[1] = 0; + return dwRet[uIndex]; + } + #undef LCID_INVARIANT + dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle); + if (dwVerSize) { + lpVerBuffer = SDL_malloc(dwVerSize); + if (lpVerBuffer) { + if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) { + if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData)) { + #define pVerFixedInfo ((VS_FIXEDFILEINFO FAR*)lpVerData) + DWORD dwVer = pVerFixedInfo->dwFileVersionMS; + dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16; + if (videodata->GetReadingString || + dwLang == LANG_CHT && ( + dwVer == MAKEIMEVERSION(4, 2) || + dwVer == MAKEIMEVERSION(4, 3) || + dwVer == MAKEIMEVERSION(4, 4) || + dwVer == MAKEIMEVERSION(5, 0) || + dwVer == MAKEIMEVERSION(5, 1) || + dwVer == MAKEIMEVERSION(5, 2) || + dwVer == MAKEIMEVERSION(6, 0)) + || + dwLang == LANG_CHS && ( + dwVer == MAKEIMEVERSION(4, 1) || + dwVer == MAKEIMEVERSION(4, 2) || + dwVer == MAKEIMEVERSION(5, 3))) { + dwRet[0] = dwVer | dwLang; + dwRet[1] = pVerFixedInfo->dwFileVersionLS; + SDL_free(lpVerBuffer); + return dwRet[0]; + } + #undef pVerFixedInfo + } + } + } + SDL_free(lpVerBuffer); + } + } + dwRet[0] = dwRet[1] = 0; + return dwRet[uIndex]; +} + +static void +IME_SetupAPI(SDL_VideoData *videodata) +{ + char ime_file[MAX_PATH + 1]; + HMODULE hime = 0; + HKL hkl = 0; + videodata->GetReadingString = 0; + videodata->ShowReadingWindow = 0; + if (videodata->ime_uiless) + return; + + hkl = videodata->ime_hkl; + if (ImmGetIMEFileNameA(hkl, ime_file, sizeof(ime_file) - 1) <= 0) + return; + + hime = LoadLibraryA(ime_file); + if (!hime) + return; + + videodata->GetReadingString = (UINT (WINAPI *)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT)) + GetProcAddress(hime, "GetReadingString"); + videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL)) + GetProcAddress(hime, "ShowReadingWindow"); + + if (videodata->ShowReadingWindow) { + HIMC himc = ImmGetContext(videodata->ime_hwnd_current); + if (himc) { + videodata->ShowReadingWindow(himc, FALSE); + ImmReleaseContext(videodata->ime_hwnd_current, himc); + } + } +} + +static void +IME_SetWindow(SDL_VideoData* videodata, HWND hwnd) +{ + videodata->ime_hwnd_current = hwnd; + if (videodata->ime_threadmgr) { + struct ITfDocumentMgr *document_mgr = 0; + if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) { + if (document_mgr) + document_mgr->lpVtbl->Release(document_mgr); + } + } +} + +static void +IME_UpdateInputLocale(SDL_VideoData *videodata) +{ + static HKL hklprev = 0; + videodata->ime_hkl = GetKeyboardLayout(0); + if (hklprev == videodata->ime_hkl) + return; + + hklprev = videodata->ime_hkl; + switch (PRIMLANG()) { + case LANG_CHINESE: + videodata->ime_candvertical = SDL_TRUE; + if (SUBLANG() == SUBLANG_CHINESE_SIMPLIFIED) + videodata->ime_candvertical = SDL_FALSE; + + break; + case LANG_JAPANESE: + videodata->ime_candvertical = SDL_TRUE; + break; + case LANG_KOREAN: + videodata->ime_candvertical = SDL_FALSE; + break; + } +} + +static void +IME_ClearComposition(SDL_VideoData *videodata) +{ + HIMC himc = 0; + if (!videodata->ime_initialized) + return; + + himc = ImmGetContext(videodata->ime_hwnd_current); + if (!himc) + return; + + ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); + if (videodata->ime_uiless) + ImmSetCompositionString(himc, SCS_SETSTR, TEXT(""), sizeof(TCHAR), TEXT(""), sizeof(TCHAR)); + + ImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0); + ImmReleaseContext(videodata->ime_hwnd_current, himc); + SDL_SendEditingText("", 0, 0); +} + +static void +IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string) +{ + LONG length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition)); + if (length < 0) + length = 0; + + length /= sizeof(videodata->ime_composition[0]); + videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0)); + if (videodata->ime_composition[videodata->ime_cursor] == 0x3000) { + int i; + for (i = videodata->ime_cursor + 1; i < length; ++i) + videodata->ime_composition[i - 1] = videodata->ime_composition[i]; + + --length; + } + videodata->ime_composition[length] = 0; +} + +static void +IME_SendInputEvent(SDL_VideoData *videodata) +{ + char *s = 0; + s = WIN_StringToUTF8(videodata->ime_composition); + SDL_SendKeyboardText(s); + SDL_free(s); + + videodata->ime_composition[0] = 0; + videodata->ime_readingstring[0] = 0; + videodata->ime_cursor = 0; +} + +static void +IME_SendEditingEvent(SDL_VideoData *videodata) +{ + char *s = 0; + WCHAR buffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; + buffer[0] = 0; + if (videodata->ime_readingstring[0]) { + size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor); + SDL_wcslcpy(buffer, videodata->ime_composition, len + 1); + SDL_wcslcat(buffer, videodata->ime_readingstring, sizeof(buffer)); + SDL_wcslcat(buffer, &videodata->ime_composition[len], sizeof(buffer) - len); + } + else { + SDL_wcslcpy(buffer, videodata->ime_composition, sizeof(videodata->ime_composition)); + } + s = WIN_StringToUTF8(buffer); + SDL_SendEditingText(s, videodata->ime_cursor + SDL_wcslen(videodata->ime_readingstring), 0); + SDL_free(s); +} + +static void +IME_AddCandidate(SDL_VideoData *videodata, UINT i, LPCWSTR candidate) +{ + LPWSTR dst = videodata->ime_candidates[i]; + *dst++ = (WCHAR)(TEXT('0') + ((i + videodata->ime_candlistindexbase) % 10)); + if (videodata->ime_candvertical) + *dst++ = TEXT(' '); + + while (*candidate && (SDL_arraysize(videodata->ime_candidates[i]) > (dst - videodata->ime_candidates[i]))) + *dst++ = *candidate++; + + *dst = (WCHAR)'\0'; +} + +static void +IME_GetCandidateList(HIMC himc, SDL_VideoData *videodata) +{ + LPCANDIDATELIST cand_list = 0; + DWORD size = ImmGetCandidateListW(himc, 0, 0, 0); + if (size) { + cand_list = (LPCANDIDATELIST)SDL_malloc(size); + if (cand_list) { + size = ImmGetCandidateListW(himc, 0, cand_list, size); + if (size) { + int i = 0; + int j = 0; + int page_start = 0; + videodata->ime_candsel = cand_list->dwSelection; + videodata->ime_candcount = cand_list->dwCount; + + if (LANG() == LANG_CHS && IME_GetId(videodata, 0)) { + const UINT maxcandchar = 18; + UINT i = 0; + UINT cchars = 0; + + for (; i < videodata->ime_candcount; ++i) { + UINT len = SDL_wcslen((LPWSTR)((DWORD)cand_list + cand_list->dwOffset[i])) + 1; + if (len + cchars > maxcandchar) { + if (i > cand_list->dwSelection) + break; + + page_start = i; + cchars = len; + } + else { + cchars += len; + } + } + videodata->ime_candpgsize = i - page_start; + } + else { + videodata->ime_candpgsize = SDL_min(cand_list->dwPageSize, MAX_CANDLIST); + page_start = (cand_list->dwSelection / videodata->ime_candpgsize) * videodata->ime_candpgsize; + } + SDL_memset(&videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); + for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < (int)videodata->ime_candpgsize; i++, j++) { + LPCWSTR candidate = (LPCWSTR)((DWORD)cand_list + cand_list->dwOffset[i]); + IME_AddCandidate(videodata, j, candidate); + } + if (PRIMLANG() == LANG_KOREAN || (PRIMLANG() == LANG_CHT && !IME_GetId(videodata, 0))) + videodata->ime_candsel = -1; + + } + SDL_free(cand_list); + } + } +} + +static void +IME_ShowCandidateList(SDL_VideoData *videodata) +{ + videodata->ime_dirty = SDL_TRUE; + videodata->ime_candlist = SDL_TRUE; + IME_DestroyTextures(videodata); + IME_SendEditingEvent(videodata); +} + +static void +IME_HideCandidateList(SDL_VideoData *videodata) +{ + videodata->ime_dirty = SDL_FALSE; + videodata->ime_candlist = SDL_FALSE; + IME_DestroyTextures(videodata); + IME_SendEditingEvent(videodata); +} + +SDL_bool +IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata) +{ + SDL_bool trap = SDL_FALSE; + HIMC himc = 0; + if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled) + return SDL_FALSE; + + switch (msg) { + case WM_INPUTLANGCHANGE: + IME_InputLangChanged(videodata); + break; + case WM_IME_SETCONTEXT: + *lParam = 0; + break; + case WM_IME_STARTCOMPOSITION: + trap = SDL_TRUE; + break; + case WM_IME_COMPOSITION: + trap = SDL_TRUE; + himc = ImmGetContext(hwnd); + if (*lParam & GCS_RESULTSTR) { + IME_GetCompositionString(videodata, himc, GCS_RESULTSTR); + IME_SendInputEvent(videodata); + } + if (*lParam & GCS_COMPSTR) { + if (!videodata->ime_uiless) + videodata->ime_readingstring[0] = 0; + + IME_GetCompositionString(videodata, himc, GCS_COMPSTR); + IME_SendEditingEvent(videodata); + } + ImmReleaseContext(hwnd, himc); + break; + case WM_IME_ENDCOMPOSITION: + videodata->ime_composition[0] = 0; + videodata->ime_readingstring[0] = 0; + videodata->ime_cursor = 0; + SDL_SendEditingText("", 0, 0); + break; + case WM_IME_NOTIFY: + switch (wParam) { + case IMN_SETCONVERSIONMODE: + case IMN_SETOPENSTATUS: + IME_UpdateInputLocale(videodata); + break; + case IMN_OPENCANDIDATE: + case IMN_CHANGECANDIDATE: + if (videodata->ime_uiless) + break; + + trap = SDL_TRUE; + IME_ShowCandidateList(videodata); + himc = ImmGetContext(hwnd); + if (!himc) + break; + + IME_GetCandidateList(himc, videodata); + ImmReleaseContext(hwnd, himc); + break; + case IMN_CLOSECANDIDATE: + trap = SDL_TRUE; + IME_HideCandidateList(videodata); + break; + case IMN_PRIVATE: + { + DWORD dwId = IME_GetId(videodata, 0); + IME_GetReadingString(videodata, hwnd); + switch (dwId) + { + case IMEID_CHT_VER42: + case IMEID_CHT_VER43: + case IMEID_CHT_VER44: + case IMEID_CHS_VER41: + case IMEID_CHS_VER42: + if (*lParam == 1 || *lParam == 2) + trap = SDL_TRUE; + + break; + case IMEID_CHT_VER50: + case IMEID_CHT_VER51: + case IMEID_CHT_VER52: + case IMEID_CHT_VER60: + case IMEID_CHS_VER53: + if (*lParam == 16 + || *lParam == 17 + || *lParam == 26 + || *lParam == 27 + || *lParam == 28) + trap = SDL_TRUE; + break; + } + } + break; + default: + trap = SDL_TRUE; + break; + } + break; + } + return trap; +} + +static void +IME_CloseCandidateList(SDL_VideoData *videodata) +{ + IME_HideCandidateList(videodata); + videodata->ime_candcount = 0; + SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); +} + +static void +UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pcandlist) +{ + UINT selection = 0; + UINT count = 0; + UINT page = 0; + UINT pgcount = 0; + DWORD pgstart = 0; + DWORD pgsize = 0; + UINT i, j; + pcandlist->lpVtbl->GetSelection(pcandlist, &selection); + pcandlist->lpVtbl->GetCount(pcandlist, &count); + pcandlist->lpVtbl->GetCurrentPage(pcandlist, &page); + + videodata->ime_candsel = selection; + videodata->ime_candcount = count; + IME_ShowCandidateList(videodata); + + pcandlist->lpVtbl->GetPageIndex(pcandlist, 0, 0, &pgcount); + if (pgcount > 0) { + UINT *idxlist = SDL_malloc(sizeof(UINT) * pgcount); + if (idxlist) { + pcandlist->lpVtbl->GetPageIndex(pcandlist, idxlist, pgcount, &pgcount); + pgstart = idxlist[page]; + if (page < pgcount - 1) + pgsize = SDL_min(count, idxlist[page + 1]) - pgstart; + else + pgsize = count - pgstart; + + SDL_free(idxlist); + } + } + videodata->ime_candpgsize = SDL_min(pgsize, MAX_CANDLIST); + videodata->ime_candsel = videodata->ime_candsel - pgstart; + + SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); + for (i = pgstart, j = 0; (DWORD)i < count && j < videodata->ime_candpgsize; i++, j++) { + BSTR bstr; + if (SUCCEEDED(pcandlist->lpVtbl->GetString(pcandlist, i, &bstr))) { + if (bstr) { + IME_AddCandidate(videodata, j, bstr); + SysFreeString(bstr); + } + } + } + if (PRIMLANG() == LANG_KOREAN) + videodata->ime_candsel = -1; +} + +STDMETHODIMP_(ULONG) TSFSink_AddRef(TSFSink *sink) +{ + return ++sink->refcount; +} + +STDMETHODIMP_(ULONG)TSFSink_Release(TSFSink *sink) +{ + --sink->refcount; + if (sink->refcount == 0) { + SDL_free(sink); + return 0; + } + return sink->refcount; +} + +STDMETHODIMP UIElementSink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv) +{ + if (!ppv) + return E_INVALIDARG; + + *ppv = 0; + if (SDL_IsEqualIID(riid, &IID_IUnknown)) + *ppv = (IUnknown *)sink; + else if (SDL_IsEqualIID(riid, &IID_ITfUIElementSink)) + *ppv = (ITfUIElementSink *)sink; + + if (*ppv) { + TSFSink_AddRef(sink); + return S_OK; + } + return E_NOINTERFACE; +} + +ITfUIElement *UILess_GetUIElement(SDL_VideoData *videodata, DWORD dwUIElementId) +{ + ITfUIElementMgr *puiem = 0; + ITfUIElement *pelem = 0; + ITfThreadMgrEx *threadmgrex = videodata->ime_threadmgrex; + + if (SUCCEEDED(threadmgrex->lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem))) { + puiem->lpVtbl->GetUIElement(puiem, dwUIElementId, &pelem); + puiem->lpVtbl->Release(puiem); + } + return pelem; +} + +STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BOOL *pbShow) +{ + ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); + ITfReadingInformationUIElement *preading = 0; + ITfCandidateListUIElement *pcandlist = 0; + SDL_VideoData *videodata = (SDL_VideoData *)sink->data; + if (!element) + return E_INVALIDARG; + + *pbShow = FALSE; + if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { + BSTR bstr; + if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) { + WCHAR *s = (WCHAR *)bstr; + SysFreeString(bstr); + } + preading->lpVtbl->Release(preading); + } + else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { + videodata->ime_candref++; + UILess_GetCandidateList(videodata, pcandlist); + pcandlist->lpVtbl->Release(pcandlist); + } + return S_OK; +} + +STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId) +{ + ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); + ITfReadingInformationUIElement *preading = 0; + ITfCandidateListUIElement *pcandlist = 0; + SDL_VideoData *videodata = (SDL_VideoData *)sink->data; + if (!element) + return E_INVALIDARG; + + if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { + BSTR bstr; + if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) { + WCHAR *s = (WCHAR *)bstr; + SDL_wcslcpy(videodata->ime_readingstring, s, sizeof(videodata->ime_readingstring)); + IME_SendEditingEvent(videodata); + SysFreeString(bstr); + } + preading->lpVtbl->Release(preading); + } + else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { + UILess_GetCandidateList(videodata, pcandlist); + pcandlist->lpVtbl->Release(pcandlist); + } + return S_OK; +} + +STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId) +{ + ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId); + ITfReadingInformationUIElement *preading = 0; + ITfCandidateListUIElement *pcandlist = 0; + SDL_VideoData *videodata = (SDL_VideoData *)sink->data; + if (!element) + return E_INVALIDARG; + + if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { + videodata->ime_readingstring[0] = 0; + IME_SendEditingEvent(videodata); + preading->lpVtbl->Release(preading); + } + if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { + videodata->ime_candref--; + if (videodata->ime_candref == 0) + IME_CloseCandidateList(videodata); + + pcandlist->lpVtbl->Release(pcandlist); + } + return S_OK; +} + +STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv) +{ + if (!ppv) + return E_INVALIDARG; + + *ppv = 0; + if (SDL_IsEqualIID(riid, &IID_IUnknown)) + *ppv = (IUnknown *)sink; + else if (SDL_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink)) + *ppv = (ITfInputProcessorProfileActivationSink *)sink; + + if (*ppv) { + TSFSink_AddRef(sink); + return S_OK; + } + return E_NOINTERFACE; +} + +STDMETHODIMP IPPASink_OnActivated(TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags) +{ + static GUID TF_PROFILE_DAYI = {0x037B2C25, 0x480C, 0x4D7F, 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A}; + SDL_VideoData *videodata = (SDL_VideoData *)sink->data; + videodata->ime_candlistindexbase = SDL_IsEqualGUID(&TF_PROFILE_DAYI, guidProfile) ? 0 : 1; + if (SDL_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE)) + IME_InputLangChanged((SDL_VideoData *)sink->data); + + IME_HideCandidateList(videodata); + return S_OK; +} + +static void *vtUIElementSink[] = { + (void *)(UIElementSink_QueryInterface), + (void *)(TSFSink_AddRef), + (void *)(TSFSink_Release), + (void *)(UIElementSink_BeginUIElement), + (void *)(UIElementSink_UpdateUIElement), + (void *)(UIElementSink_EndUIElement) +}; + +static void *vtIPPASink[] = { + (void *)(IPPASink_QueryInterface), + (void *)(TSFSink_AddRef), + (void *)(TSFSink_Release), + (void *)(IPPASink_OnActivated) +}; + +static void +UILess_EnableUIUpdates(SDL_VideoData *videodata) +{ + ITfSource *source = 0; + if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie != TF_INVALID_COOKIE) + return; + + if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { + source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie); + source->lpVtbl->Release(source); + } +} + +static void +UILess_DisableUIUpdates(SDL_VideoData *videodata) +{ + ITfSource *source = 0; + if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie == TF_INVALID_COOKIE) + return; + + if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { + source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie); + videodata->ime_uielemsinkcookie = TF_INVALID_COOKIE; + source->lpVtbl->Release(source); + } +} + +static SDL_bool +UILess_SetupSinks(SDL_VideoData *videodata) +{ + TfClientId clientid = 0; + SDL_bool result = SDL_FALSE; + ITfSource *source = 0; + if (FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, (LPVOID *)&videodata->ime_threadmgrex))) + return SDL_FALSE; + + if (FAILED(videodata->ime_threadmgrex->lpVtbl->ActivateEx(videodata->ime_threadmgrex, &clientid, TF_TMAE_UIELEMENTENABLEDONLY))) + return SDL_FALSE; + + videodata->ime_uielemsink = SDL_malloc(sizeof(TSFSink)); + videodata->ime_ippasink = SDL_malloc(sizeof(TSFSink)); + + videodata->ime_uielemsink->lpVtbl = vtUIElementSink; + videodata->ime_uielemsink->refcount = 1; + videodata->ime_uielemsink->data = videodata; + + videodata->ime_ippasink->lpVtbl = vtIPPASink; + videodata->ime_ippasink->refcount = 1; + videodata->ime_ippasink->data = videodata; + + if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { + if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie))) { + if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfInputProcessorProfileActivationSink, (IUnknown *)videodata->ime_ippasink, &videodata->ime_alpnsinkcookie))) { + result = SDL_TRUE; + } + } + source->lpVtbl->Release(source); + } + return result; +} + +#define SAFE_RELEASE(p) \ +{ \ + if (p) { \ + (p)->lpVtbl->Release((p)); \ + (p) = 0; \ + } \ +} + +static void +UILess_ReleaseSinks(SDL_VideoData *videodata) +{ + ITfSource *source = 0; + if (videodata->ime_threadmgrex && SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { + source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie); + source->lpVtbl->UnadviseSink(source, videodata->ime_alpnsinkcookie); + SAFE_RELEASE(source); + videodata->ime_threadmgrex->lpVtbl->Deactivate(videodata->ime_threadmgrex); + SAFE_RELEASE(videodata->ime_threadmgrex); + TSFSink_Release(videodata->ime_uielemsink); + videodata->ime_uielemsink = 0; + TSFSink_Release(videodata->ime_ippasink); + videodata->ime_ippasink = 0; + } +} + +static void * +StartDrawToBitmap(HDC hdc, HBITMAP *hhbm, int width, int height) +{ + BITMAPINFO info = {0}; + BITMAPINFOHEADER *infoHeader = &info.bmiHeader; + BYTE *bits = NULL; + if (hhbm) { + infoHeader->biSize = sizeof(BITMAPINFOHEADER); + infoHeader->biWidth = width; + infoHeader->biHeight = -1 * SDL_abs(height); + infoHeader->biPlanes = 1; + infoHeader->biBitCount = 32; + infoHeader->biCompression = BI_RGB; + *hhbm = CreateDIBSection(hdc, &info, DIB_RGB_COLORS, (void **)&bits, 0, 0); + if (*hhbm) + SelectObject(hdc, *hhbm); + } + return bits; +} + +static void +StopDrawToBitmap(HDC hdc, HBITMAP *hhbm) +{ + if (hhbm && *hhbm) { + DeleteObject(*hhbm); + *hhbm = NULL; + } +} + +static void +BitmapToTexture(HBITMAP hbm, BYTE *bits, int width, int height, SDL_Texture **texture) +{ + SDL_Surface *surface = NULL; + BITMAP bm = {0}; + + if (GetObject(hbm, sizeof(bm), &bm) == 0) + return; + + if (bits && texture) { + /* + For transparency: + + const Uint8 alpha = 130; + unsigned long *p = (unsigned long *)bits; + unsigned long *end = (unsigned long *)(bits + (bm.bmWidthBytes * bm.bmHeight)); + while (p < end) { + *p = RGB(GetRValue(*p), GetGValue(*p), GetBValue(*p)) | (alpha << 24); + ++p; + } + surface = SDL_CreateRGBSurfaceFrom(bits, width, height, bm.bmBitsPixel, bm.bmWidthBytes, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); + */ + surface = SDL_CreateRGBSurfaceFrom(bits, width, height, bm.bmBitsPixel, bm.bmWidthBytes, 0x00ff0000, 0x0000ff00, 0x000000ff, 0); + if (surface) { + *texture = SDL_CreateTextureFromSurface(0, surface); + SDL_FreeSurface(surface); + } + } +} + +/* This draws only within the specified area and fills the entire region. */ +static void +DrawRect(HDC hdc, int left, int top, int right, int bottom, int pensize) +{ + /* The case of no pen (PenSize = 0) is automatically taken care of. */ + const int penadjust = (int)SDL_floor(pensize / 2.0f - 0.5f); + left += pensize / 2; + top += pensize / 2; + right -= penadjust; + bottom -= penadjust; + Rectangle(hdc, left, top, right, bottom); +} + +static void +DestroyTexture(SDL_Texture **texture) +{ + if (texture && *texture) { + SDL_DestroyTexture(*texture); + *texture = NULL; + } +} + +static void +IME_DestroyTextures(SDL_VideoData *videodata) +{ + DestroyTexture(&videodata->ime_candtex); +} + +#define SDL_swap(a,b) { \ + int c = (a); \ + (a) = (b); \ + (b) = c; \ + } + +static void +IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size) +{ + int left, top, right, bottom; + SDL_bool ok = SDL_FALSE; + int winw = videodata->ime_winwidth; + int winh = videodata->ime_winheight; + + /* Bottom */ + left = videodata->ime_rect.x; + top = videodata->ime_rect.y + videodata->ime_rect.h; + right = left + size.cx; + bottom = top + size.cy; + if (right >= winw) { + left -= right - winw; + right = winw; + } + if (bottom < winh) + ok = SDL_TRUE; + + /* Top */ + if (!ok) { + left = videodata->ime_rect.x; + top = videodata->ime_rect.y - size.cy; + right = left + size.cx; + bottom = videodata->ime_rect.y; + if (right >= winw) { + left -= right - winw; + right = winw; + } + if (top >= 0) + ok = SDL_TRUE; + } + + /* Right */ + if (!ok) { + left = videodata->ime_rect.x + size.cx; + top = 0; + right = left + size.cx; + bottom = size.cy; + if (right < winw) + ok = SDL_TRUE; + } + + /* Left */ + if (!ok) { + left = videodata->ime_rect.x - size.cx; + top = 0; + right = videodata->ime_rect.x; + bottom = size.cy; + if (right >= 0) + ok = SDL_TRUE; + } + + /* Window too small, show at (0,0) */ + if (!ok) { + left = 0; + top = 0; + right = size.cx; + bottom = size.cy; + } + + videodata->ime_candlistrect.x = left; + videodata->ime_candlistrect.y = top; + videodata->ime_candlistrect.w = right - left; + videodata->ime_candlistrect.h = bottom - top; +} + +static void +IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) +{ + int i, j; + SIZE size = {0}; + SIZE candsizes[MAX_CANDLIST]; + SIZE maxcandsize = {0}; + HBITMAP hbm = NULL; + BYTE *bits = NULL; + const int candcount = SDL_min(SDL_min(MAX_CANDLIST, videodata->ime_candcount), videodata->ime_candpgsize); + SDL_bool vertical = videodata->ime_candvertical; + + const int listborder = 1; + const int listpadding = 0; + const int listbordercolor = RGB(0xB4, 0xC7, 0xAA); + const int listfillcolor = RGB(255, 255, 255); + + const int candborder = 1; + const int candpadding = 0; + const int candmargin = 1; + const COLORREF candbordercolor = RGB(255, 255, 255); + const COLORREF candfillcolor = RGB(255, 255, 255); + const COLORREF candtextcolor = RGB(0, 0, 0); + const COLORREF selbordercolor = RGB(0x84, 0xAC, 0xDD); + const COLORREF selfillcolor = RGB(0xD2, 0xE6, 0xFF); + const COLORREF seltextcolor = RGB(0, 0, 0); + const int horzcandspacing = 5; + + HPEN listpen = listborder != 0 ? CreatePen(PS_SOLID, listborder, listbordercolor) : (HPEN)GetStockObject(NULL_PEN); + HBRUSH listbrush = CreateSolidBrush(listfillcolor); + HPEN candpen = candborder != 0 ? CreatePen(PS_SOLID, candborder, candbordercolor) : (HPEN)GetStockObject(NULL_PEN); + HBRUSH candbrush = CreateSolidBrush(candfillcolor); + HPEN selpen = candborder != 0 ? CreatePen(PS_DOT, candborder, selbordercolor) : (HPEN)GetStockObject(NULL_PEN); + HBRUSH selbrush = CreateSolidBrush(selfillcolor); + HFONT font = CreateFont((int)(1 + videodata->ime_rect.h * 0.75f), 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_SWISS, TEXT("Microsoft Sans Serif")); + + SetBkMode(hdc, TRANSPARENT); + SelectObject(hdc, font); + + for (i = 0; i < candcount; ++i) { + const WCHAR *s = videodata->ime_candidates[i]; + if (!*s) + break; + + GetTextExtentPoint32W(hdc, s, SDL_wcslen(s), &candsizes[i]); + maxcandsize.cx = SDL_max(maxcandsize.cx, candsizes[i].cx); + maxcandsize.cy = SDL_max(maxcandsize.cy, candsizes[i].cy); + + } + if (vertical) { + size.cx = + (listborder * 2) + + (listpadding * 2) + + (candmargin * 2) + + (candborder * 2) + + (candpadding * 2) + + (maxcandsize.cx) + ; + size.cy = + (listborder * 2) + + (listpadding * 2) + + ((candcount + 1) * candmargin) + + (candcount * candborder * 2) + + (candcount * candpadding * 2) + + (candcount * maxcandsize.cy) + ; + } + else { + size.cx = + (listborder * 2) + + (listpadding * 2) + + ((candcount + 1) * candmargin) + + (candcount * candborder * 2) + + (candcount * candpadding * 2) + + ((candcount - 1) * horzcandspacing); + ; + + for (i = 0; i < candcount; ++i) + size.cx += candsizes[i].cx; + + size.cy = + (listborder * 2) + + (listpadding * 2) + + (candmargin * 2) + + (candborder * 2) + + (candpadding * 2) + + (maxcandsize.cy) + ; + } + + bits = StartDrawToBitmap(hdc, &hbm, size.cx, size.cy); + + SelectObject(hdc, listpen); + SelectObject(hdc, listbrush); + DrawRect(hdc, 0, 0, size.cx, size.cy, listborder); + + SelectObject(hdc, candpen); + SelectObject(hdc, candbrush); + SetTextColor(hdc, candtextcolor); + SetBkMode(hdc, TRANSPARENT); + + for (i = 0; i < candcount; ++i) { + const WCHAR *s = videodata->ime_candidates[i]; + int left, top, right, bottom; + if (!*s) + break; + + if (vertical) { + left = listborder + listpadding + candmargin; + top = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * maxcandsize.cy); + right = size.cx - listborder - listpadding - candmargin; + bottom = top + maxcandsize.cy + (candpadding * 2) + (candborder * 2); + } + else { + left = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * horzcandspacing); + + for (j = 0; j < i; ++j) + left += candsizes[j].cx; + + top = listborder + listpadding + candmargin; + right = left + candsizes[i].cx + (candpadding * 2) + (candborder * 2); + bottom = size.cy - listborder - listpadding - candmargin; + } + + if (i == videodata->ime_candsel) { + SelectObject(hdc, selpen); + SelectObject(hdc, selbrush); + SetTextColor(hdc, seltextcolor); + } + else { + SelectObject(hdc, candpen); + SelectObject(hdc, candbrush); + SetTextColor(hdc, candtextcolor); + } + + DrawRect(hdc, left, top, right, bottom, candborder); + ExtTextOutW(hdc, left + candborder + candpadding, top + candborder + candpadding, 0, NULL, s, SDL_wcslen(s), NULL); + } + BitmapToTexture(hbm, bits, size.cx, size.cy, &videodata->ime_candtex); + StopDrawToBitmap(hdc, &hbm); + + DeleteObject(listpen); + DeleteObject(listbrush); + DeleteObject(candpen); + DeleteObject(candbrush); + DeleteObject(selpen); + DeleteObject(selbrush); + DeleteObject(font); + + IME_PositionCandidateList(videodata, size); +} + +static void +IME_Render(SDL_VideoData *videodata) +{ + HDC hdc = CreateCompatibleDC(NULL); + + if (videodata->ime_candlist) + IME_RenderCandidateList(videodata, hdc); + + DeleteDC(hdc); + + videodata->ime_dirty = SDL_FALSE; +} + +void IME_Present(SDL_VideoData *videodata) +{ + if (videodata->ime_dirty) + IME_Render(videodata); + + SDL_RenderCopy(videodata->ime_candtex, NULL, &videodata->ime_candlistrect); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowskeyboard.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowskeyboard.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,42 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_windowskeyboard_h +#define _SDL_windowskeyboard_h + +extern BYTE alpha_scancodes[26]; +extern BYTE keypad_scancodes[10]; + +extern void WIN_InitKeyboard(_THIS); +extern void WIN_UpdateKeymap(void); +extern void WIN_QuitKeyboard(_THIS); + +extern void WIN_StartTextInput(_THIS); +extern void WIN_StopTextInput(_THIS); +extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect); + +extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata); + +#endif /* _SDL_windowskeyboard_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsmodes.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsmodes.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,287 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#include "SDL_windowsvideo.h" + + +static SDL_bool +WIN_GetDisplayMode(LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) +{ + SDL_DisplayModeData *data; + DEVMODE devmode; + HDC hdc; + + devmode.dmSize = sizeof(devmode); + devmode.dmDriverExtra = 0; + if (!EnumDisplaySettings(deviceName, index, &devmode)) { + return SDL_FALSE; + } + + data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data)); + if (!data) { + return SDL_FALSE; + } + data->DeviceMode = devmode; + data->DeviceMode.dmFields = + (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY | + DM_DISPLAYFLAGS); + + /* Fill in the mode information */ + mode->format = SDL_PIXELFORMAT_UNKNOWN; + mode->w = devmode.dmPelsWidth; + mode->h = devmode.dmPelsHeight; + mode->refresh_rate = devmode.dmDisplayFrequency; + mode->driverdata = data; +#ifdef _WIN32_WCE + /* In WinCE EnumDisplaySettings(ENUM_CURRENT_SETTINGS) doesn't take the user defined orientation + into account but GetSystemMetrics does. */ + if (index == ENUM_CURRENT_SETTINGS) { + mode->w = GetSystemMetrics(SM_CXSCREEN); + mode->h = GetSystemMetrics(SM_CYSCREEN); + } +#endif + +/* WinCE has no GetDIBits, therefore we can't use it to get the display format */ +#ifndef _WIN32_WCE + if (index == ENUM_CURRENT_SETTINGS + && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) { + char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)]; + LPBITMAPINFO bmi; + HBITMAP hbm; + + SDL_zero(bmi_data); + bmi = (LPBITMAPINFO) bmi_data; + bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + + hbm = CreateCompatibleBitmap(hdc, 1, 1); + GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS); + GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS); + DeleteObject(hbm); + DeleteDC(hdc); + if (bmi->bmiHeader.biCompression == BI_BITFIELDS) { + switch (*(Uint32 *) bmi->bmiColors) { + case 0x00FF0000: + mode->format = SDL_PIXELFORMAT_RGB888; + break; + case 0x000000FF: + mode->format = SDL_PIXELFORMAT_BGR888; + break; + case 0xF800: + mode->format = SDL_PIXELFORMAT_RGB565; + break; + case 0x7C00: + mode->format = SDL_PIXELFORMAT_RGB555; + break; + } + } else if (bmi->bmiHeader.biBitCount == 8) { + mode->format = SDL_PIXELFORMAT_INDEX8; + } else if (bmi->bmiHeader.biBitCount == 4) { + mode->format = SDL_PIXELFORMAT_INDEX4LSB; + } + } else +#endif /* _WIN32_WCE */ + { + /* FIXME: Can we tell what this will be? */ + if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) { + switch (devmode.dmBitsPerPel) { + case 32: + mode->format = SDL_PIXELFORMAT_RGB888; + break; + case 24: + mode->format = SDL_PIXELFORMAT_RGB24; + break; + case 16: + mode->format = SDL_PIXELFORMAT_RGB565; + break; + case 15: + mode->format = SDL_PIXELFORMAT_RGB555; + break; + case 8: + mode->format = SDL_PIXELFORMAT_INDEX8; + break; + case 4: + mode->format = SDL_PIXELFORMAT_INDEX4LSB; + break; + } + } + } + return SDL_TRUE; +} + +static SDL_bool +WIN_AddDisplay(LPTSTR DeviceName) +{ + SDL_VideoDisplay display; + SDL_DisplayData *displaydata; + SDL_DisplayMode mode; + +#ifdef DEBUG_MODES + printf("Display: %s\n", WIN_StringToUTF8(DeviceName)); +#endif + if (!WIN_GetDisplayMode(DeviceName, ENUM_CURRENT_SETTINGS, &mode)) { + return SDL_FALSE; + } + + displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata)); + if (!displaydata) { + return SDL_FALSE; + } + SDL_memcpy(displaydata->DeviceName, DeviceName, + sizeof(displaydata->DeviceName)); + + SDL_zero(display); + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = displaydata; + SDL_AddVideoDisplay(&display); + return SDL_TRUE; +} + +int +WIN_InitModes(_THIS) +{ + DWORD i, j, count; + DISPLAY_DEVICE device; + + device.cb = sizeof(device); + for (i = 0;; ++i) { + TCHAR DeviceName[32]; + + if (!EnumDisplayDevices(NULL, i, &device, 0)) { + break; + } + if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { + continue; + } + SDL_memcpy(DeviceName, device.DeviceName, sizeof(DeviceName)); +#ifdef DEBUG_MODES + printf("Device: %s\n", WIN_StringToUTF8(DeviceName)); +#endif + count = 0; + for (j = 0;; ++j) { + if (!EnumDisplayDevices(DeviceName, j, &device, 0)) { + break; + } + if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) { + continue; + } + count += WIN_AddDisplay(device.DeviceName); + } + if (count == 0) { + WIN_AddDisplay(DeviceName); + } + } + if (_this->num_displays == 0) { + SDL_SetError("No displays available"); + return -1; + } + return 0; +} + +int +WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) +{ + SDL_DisplayModeData *data = (SDL_DisplayModeData *) display->desktop_mode.driverdata; + +#ifdef _WIN32_WCE + // WINCE: DEVMODE.dmPosition not found, or may be mingw32ce bug + rect->x = 0; + rect->y = 0; + rect->w = display->windows->w; + rect->h = display->windows->h; +#else + rect->x = (int)data->DeviceMode.dmPosition.x; + rect->y = (int)data->DeviceMode.dmPosition.y; + rect->w = data->DeviceMode.dmPelsWidth; + rect->h = data->DeviceMode.dmPelsHeight; +#endif + return 0; +} + +void +WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +{ + SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; + DWORD i; + SDL_DisplayMode mode; + + for (i = 0;; ++i) { + if (!WIN_GetDisplayMode(data->DeviceName, i, &mode)) { + break; + } + if (mode.format != SDL_PIXELFORMAT_UNKNOWN) { + if (!SDL_AddDisplayMode(display, &mode)) { + SDL_free(mode.driverdata); + } + } + } +} + +int +WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; + SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata; + LONG status; + +#ifdef _WIN32_WCE + /* TODO: implement correctly. + On my Asus MyPAL, if I execute the code below + I get DISP_CHANGE_BADFLAGS and the Titlebar of the fullscreen window stays + visible ... (SDL_RaiseWindow() would fix that one) */ + return 0; +#endif + + status = + ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode, + NULL, CDS_FULLSCREEN, NULL); + if (status == DISP_CHANGE_SUCCESSFUL) { + return 0; + } else { + const char *reason = "Unknown reason"; + switch (status) { + case DISP_CHANGE_BADFLAGS: + reason = "DISP_CHANGE_BADFLAGS"; + break; + case DISP_CHANGE_BADMODE: + reason = "DISP_CHANGE_BADMODE"; + break; + case DISP_CHANGE_BADPARAM: + reason = "DISP_CHANGE_BADPARAM"; + break; + case DISP_CHANGE_FAILED: + reason = "DISP_CHANGE_FAILED"; + break; + } + SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason); + return -1; + } +} + +void +WIN_QuitModes(_THIS) +{ + ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsmodes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsmodes.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,45 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_windowsmodes_h +#define _SDL_windowsmodes_h + +typedef struct +{ + TCHAR DeviceName[32]; +} SDL_DisplayData; + +typedef struct +{ + DEVMODE DeviceMode; +} SDL_DisplayModeData; + +extern int WIN_InitModes(_THIS); +extern int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); +extern void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display); +extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +extern void WIN_QuitModes(_THIS); + +#endif /* _SDL_windowsmodes_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsmouse.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsmouse.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,44 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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 +*/ + +/* we need to define it, so that raw input is included*/ + +#if (_WIN32_WINNT < 0x0501) +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif + +#include "SDL_config.h" + +#include "SDL_windowsvideo.h" + +void +WIN_InitMouse(_THIS) +{ +} + +void +WIN_QuitMouse(_THIS) +{ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsmouse.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsmouse.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,32 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_windowsmouse_h +#define _SDL_windowsmouse_h + +extern void WIN_InitMouse(_THIS); +extern void WIN_QuitMouse(_THIS); + +#endif /* _SDL_windowsmouse_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsopengl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsopengl.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,612 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#include "SDL_windowsvideo.h" + +/* WGL implementation of SDL OpenGL support */ + +#if SDL_VIDEO_OPENGL_WGL +#include "SDL_opengl.h" + +#define DEFAULT_OPENGL "OPENGL32.DLL" + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2093 +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#endif + +typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, + HGLRC + hShareContext, + const int + *attribList); + +int +WIN_GL_LoadLibrary(_THIS, const char *path) +{ + LPTSTR wpath; + HANDLE handle; + + if (path == NULL) { + path = SDL_getenv("SDL_OPENGL_LIBRARY"); + } + if (path == NULL) { + path = DEFAULT_OPENGL; + } + wpath = WIN_UTF8ToString(path); + _this->gl_config.dll_handle = LoadLibrary(wpath); + SDL_free(wpath); + if (!_this->gl_config.dll_handle) { + char message[1024]; + SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")", + path); + WIN_SetError(message); + return -1; + } + SDL_strlcpy(_this->gl_config.driver_path, path, + SDL_arraysize(_this->gl_config.driver_path)); + + /* Allocate OpenGL memory */ + _this->gl_data = + (struct SDL_GLDriverData *) SDL_calloc(1, + sizeof(struct + SDL_GLDriverData)); + if (!_this->gl_data) { + SDL_OutOfMemory(); + return -1; + } + + /* Load function pointers */ + handle = _this->gl_config.dll_handle; + _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *)) + GetProcAddress(handle, "wglGetProcAddress"); + _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC)) + GetProcAddress(handle, "wglCreateContext"); + _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC)) + GetProcAddress(handle, "wglDeleteContext"); + _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC)) + GetProcAddress(handle, "wglMakeCurrent"); + _this->gl_data->wglSwapIntervalEXT = (void (WINAPI *) (int)) + GetProcAddress(handle, "wglSwapIntervalEXT"); + _this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *) (void)) + GetProcAddress(handle, "wglGetSwapIntervalEXT"); + + if (!_this->gl_data->wglGetProcAddress || + !_this->gl_data->wglCreateContext || + !_this->gl_data->wglDeleteContext || + !_this->gl_data->wglMakeCurrent) { + SDL_SetError("Could not retrieve OpenGL functions"); + FreeLibrary(handle); + return -1; + } + + return 0; +} + +void * +WIN_GL_GetProcAddress(_THIS, const char *proc) +{ + void *func; + + /* This is to pick up extensions */ + func = _this->gl_data->wglGetProcAddress(proc); + if (!func) { + /* This is probably a normal GL function */ + func = GetProcAddress(_this->gl_config.dll_handle, proc); + } + return func; +} + +void +WIN_GL_UnloadLibrary(_THIS) +{ + FreeLibrary((HMODULE) _this->gl_config.dll_handle); + _this->gl_config.dll_handle = NULL; + + /* Free OpenGL memory */ + SDL_free(_this->gl_data); + _this->gl_data = NULL; +} + +static void +WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd) +{ + SDL_zerop(pfd); + pfd->nSize = sizeof(*pfd); + pfd->nVersion = 1; + pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL); + if (_this->gl_config.double_buffer) { + pfd->dwFlags |= PFD_DOUBLEBUFFER; + } + if (_this->gl_config.stereo) { + pfd->dwFlags |= PFD_STEREO; + } + pfd->iLayerType = PFD_MAIN_PLANE; + pfd->iPixelType = PFD_TYPE_RGBA; + pfd->cRedBits = _this->gl_config.red_size; + pfd->cGreenBits = _this->gl_config.green_size; + pfd->cBlueBits = _this->gl_config.blue_size; + pfd->cAlphaBits = _this->gl_config.alpha_size; + if (_this->gl_config.buffer_size) { + pfd->cColorBits = + _this->gl_config.buffer_size - _this->gl_config.alpha_size; + } else { + pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits); + } + pfd->cAccumRedBits = _this->gl_config.accum_red_size; + pfd->cAccumGreenBits = _this->gl_config.accum_green_size; + pfd->cAccumBlueBits = _this->gl_config.accum_blue_size; + pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size; + pfd->cAccumBits = + (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits + + pfd->cAccumAlphaBits); + pfd->cDepthBits = _this->gl_config.depth_size; + pfd->cStencilBits = _this->gl_config.stencil_size; +} + +/* Choose the closest pixel format that meets or exceeds the target. + FIXME: Should we weight any particular attribute over any other? +*/ +static int +WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target) +{ + PIXELFORMATDESCRIPTOR pfd; + int count, index, best = 0; + unsigned int dist, best_dist = ~0U; + + count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL); + + for (index = 1; index <= count; index++) { + + if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) { + continue; + } + + if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) { + continue; + } + + if (pfd.iLayerType != target->iLayerType) { + continue; + } + if (pfd.iPixelType != target->iPixelType) { + continue; + } + + dist = 0; + + if (pfd.cColorBits < target->cColorBits) { + continue; + } else { + dist += (pfd.cColorBits - target->cColorBits); + } + if (pfd.cRedBits < target->cRedBits) { + continue; + } else { + dist += (pfd.cRedBits - target->cRedBits); + } + if (pfd.cGreenBits < target->cGreenBits) { + continue; + } else { + dist += (pfd.cGreenBits - target->cGreenBits); + } + if (pfd.cBlueBits < target->cBlueBits) { + continue; + } else { + dist += (pfd.cBlueBits - target->cBlueBits); + } + if (pfd.cAlphaBits < target->cAlphaBits) { + continue; + } else { + dist += (pfd.cAlphaBits - target->cAlphaBits); + } + if (pfd.cAccumBits < target->cAccumBits) { + continue; + } else { + dist += (pfd.cAccumBits - target->cAccumBits); + } + if (pfd.cAccumRedBits < target->cAccumRedBits) { + continue; + } else { + dist += (pfd.cAccumRedBits - target->cAccumRedBits); + } + if (pfd.cAccumGreenBits < target->cAccumGreenBits) { + continue; + } else { + dist += (pfd.cAccumGreenBits - target->cAccumGreenBits); + } + if (pfd.cAccumBlueBits < target->cAccumBlueBits) { + continue; + } else { + dist += (pfd.cAccumBlueBits - target->cAccumBlueBits); + } + if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) { + continue; + } else { + dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits); + } + if (pfd.cDepthBits < target->cDepthBits) { + continue; + } else { + dist += (pfd.cDepthBits - target->cDepthBits); + } + if (pfd.cStencilBits < target->cStencilBits) { + continue; + } else { + dist += (pfd.cStencilBits - target->cStencilBits); + } + + if (dist < best_dist) { + best = index; + best_dist = dist; + } + } + + return best; +} + +static SDL_bool +HasExtension(const char *extension, const char *extensions) +{ + const char *start; + const char *where, *terminator; + + /* Extension names should not have spaces. */ + where = SDL_strchr(extension, ' '); + if (where || *extension == '\0') + return SDL_FALSE; + + if (!extensions) + return SDL_FALSE; + + /* It takes a bit of care to be fool-proof about parsing the + * OpenGL extensions string. Don't be fooled by sub-strings, + * etc. */ + + start = extensions; + + for (;;) { + where = SDL_strstr(start, extension); + if (!where) + break; + + terminator = where + SDL_strlen(extension); + if (where == start || *(where - 1) == ' ') + if (*terminator == ' ' || *terminator == '\0') + return SDL_TRUE; + + start = terminator; + } + return SDL_FALSE; +} + +static void +WIN_GL_InitExtensions(_THIS, HDC hdc) +{ + const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0; + const char *extensions; + + wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC)) + _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB"); + if (wglGetExtensionsStringARB) { + extensions = wglGetExtensionsStringARB(hdc); + } else { + extensions = NULL; + } + + /* Check for WGL_ARB_pixel_format */ + _this->gl_data->WGL_ARB_pixel_format = 0; + if (HasExtension("WGL_ARB_pixel_format", extensions)) { + _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *) + (HDC, const int *, + const FLOAT *, UINT, + int *, UINT *)) + WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB"); + _this->gl_data->wglGetPixelFormatAttribivARB = + (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *)) + WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB"); + + if ((_this->gl_data->wglChoosePixelFormatARB != NULL) && + (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) { + _this->gl_data->WGL_ARB_pixel_format = 1; + } + } + + /* Check for WGL_EXT_swap_control */ + if (HasExtension("WGL_EXT_swap_control", extensions)) { + _this->gl_data->wglSwapIntervalEXT = + WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT"); + _this->gl_data->wglGetSwapIntervalEXT = + WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT"); + } else { + _this->gl_data->wglSwapIntervalEXT = NULL; + _this->gl_data->wglGetSwapIntervalEXT = NULL; + } +} + +static int +WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs) +{ + HWND hwnd; + HDC hdc; + PIXELFORMATDESCRIPTOR pfd; + HGLRC hglrc; + int pixel_format = 0; + unsigned int matching; + + hwnd = + CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0, + 10, 10, NULL, NULL, SDL_Instance, NULL); + WIN_PumpEvents(_this); + + hdc = GetDC(hwnd); + + WIN_GL_SetupPixelFormat(_this, &pfd); + + SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd); + + hglrc = _this->gl_data->wglCreateContext(hdc); + if (hglrc) { + _this->gl_data->wglMakeCurrent(hdc, hglrc); + + WIN_GL_InitExtensions(_this, hdc); + + if (_this->gl_data->WGL_ARB_pixel_format) { + _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, + 1, &pixel_format, + &matching); + } + + _this->gl_data->wglMakeCurrent(NULL, NULL); + _this->gl_data->wglDeleteContext(hglrc); + } + ReleaseDC(hwnd, hdc); + DestroyWindow(hwnd); + WIN_PumpEvents(_this); + + return pixel_format; +} + +int +WIN_GL_SetupWindow(_THIS, SDL_Window * window) +{ + HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; + PIXELFORMATDESCRIPTOR pfd; + int pixel_format; + int iAttribs[64]; + int *iAttr; + float fAttribs[1] = { 0 }; + + WIN_GL_SetupPixelFormat(_this, &pfd); + + /* setup WGL_ARB_pixel_format attribs */ + iAttr = &iAttribs[0]; + + *iAttr++ = WGL_DRAW_TO_WINDOW_ARB; + *iAttr++ = GL_TRUE; + *iAttr++ = WGL_ACCELERATION_ARB; + *iAttr++ = WGL_FULL_ACCELERATION_ARB; + *iAttr++ = WGL_RED_BITS_ARB; + *iAttr++ = _this->gl_config.red_size; + *iAttr++ = WGL_GREEN_BITS_ARB; + *iAttr++ = _this->gl_config.green_size; + *iAttr++ = WGL_BLUE_BITS_ARB; + *iAttr++ = _this->gl_config.blue_size; + + if (_this->gl_config.alpha_size) { + *iAttr++ = WGL_ALPHA_BITS_ARB; + *iAttr++ = _this->gl_config.alpha_size; + } + + *iAttr++ = WGL_DOUBLE_BUFFER_ARB; + *iAttr++ = _this->gl_config.double_buffer; + + *iAttr++ = WGL_DEPTH_BITS_ARB; + *iAttr++ = _this->gl_config.depth_size; + + if (_this->gl_config.stencil_size) { + *iAttr++ = WGL_STENCIL_BITS_ARB; + *iAttr++ = _this->gl_config.stencil_size; + } + + if (_this->gl_config.accum_red_size) { + *iAttr++ = WGL_ACCUM_RED_BITS_ARB; + *iAttr++ = _this->gl_config.accum_red_size; + } + + if (_this->gl_config.accum_green_size) { + *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB; + *iAttr++ = _this->gl_config.accum_green_size; + } + + if (_this->gl_config.accum_blue_size) { + *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB; + *iAttr++ = _this->gl_config.accum_blue_size; + } + + if (_this->gl_config.accum_alpha_size) { + *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB; + *iAttr++ = _this->gl_config.accum_alpha_size; + } + + if (_this->gl_config.stereo) { + *iAttr++ = WGL_STEREO_ARB; + *iAttr++ = GL_TRUE; + } + + if (_this->gl_config.multisamplebuffers) { + *iAttr++ = WGL_SAMPLE_BUFFERS_ARB; + *iAttr++ = _this->gl_config.multisamplebuffers; + } + + if (_this->gl_config.multisamplesamples) { + *iAttr++ = WGL_SAMPLES_ARB; + *iAttr++ = _this->gl_config.multisamplesamples; + } + + if (_this->gl_config.accelerated >= 0) { + *iAttr++ = WGL_ACCELERATION_ARB; + *iAttr++ = + (_this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : + WGL_NO_ACCELERATION_ARB); + } + + *iAttr = 0; + + /* Choose and set the closest available pixel format */ + pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs); + if (!pixel_format) { + pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd); + } + if (!pixel_format) { + SDL_SetError("No matching GL pixel format available"); + return -1; + } + if (!SetPixelFormat(hdc, pixel_format, &pfd)) { + WIN_SetError("SetPixelFormat()"); + return (-1); + } + return 0; +} + +SDL_GLContext +WIN_GL_CreateContext(_THIS, SDL_Window * window) +{ + HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; + HGLRC context; + + if (_this->gl_config.major_version < 3) { + context = _this->gl_data->wglCreateContext(hdc); + } else { + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; + HGLRC temp_context = _this->gl_data->wglCreateContext(hdc); + if (!temp_context) { + SDL_SetError("Could not create GL context"); + return NULL; + } + + /* Make the context current */ + if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) { + WIN_GL_DeleteContext(_this, temp_context); + return NULL; + } + + wglCreateContextAttribsARB = + (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data-> + wglGetProcAddress("wglCreateContextAttribsARB"); + if (!wglCreateContextAttribsARB) { + SDL_SetError("GL 3.x is not supported"); + context = temp_context; + } else { + int attribs[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version, + WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version, + 0 + }; + /* Create the GL 3.x context */ + context = wglCreateContextAttribsARB(hdc, 0, attribs); + /* Delete the GL 2.x context */ + _this->gl_data->wglDeleteContext(temp_context); + } + } + + if (!context) { + WIN_SetError("Could not create GL context"); + return NULL; + } + + if (WIN_GL_MakeCurrent(_this, window, context) < 0) { + WIN_GL_DeleteContext(_this, context); + return NULL; + } + + WIN_GL_InitExtensions(_this, hdc); + + return context; +} + +int +WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ + HDC hdc; + int status; + + if (window) { + hdc = ((SDL_WindowData *) window->driverdata)->hdc; + } else { + hdc = NULL; + } + if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) { + WIN_SetError("wglMakeCurrent()"); + status = -1; + } else { + status = 0; + } + return status; +} + +int +WIN_GL_SetSwapInterval(_THIS, int interval) +{ + if (_this->gl_data->wglSwapIntervalEXT) { + _this->gl_data->wglSwapIntervalEXT(interval); + return 0; + } else { + SDL_Unsupported(); + return -1; + } +} + +int +WIN_GL_GetSwapInterval(_THIS) +{ + if (_this->gl_data->wglGetSwapIntervalEXT) { + return _this->gl_data->wglGetSwapIntervalEXT(); + } else { + SDL_Unsupported(); + return -1; + } +} + +void +WIN_GL_SwapWindow(_THIS, SDL_Window * window) +{ + HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; + + SwapBuffers(hdc); +} + +void +WIN_GL_DeleteContext(_THIS, SDL_GLContext context) +{ + _this->gl_data->wglDeleteContext((HGLRC) context); +} + +#endif /* SDL_VIDEO_OPENGL_WGL */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsopengl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsopengl.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,126 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_windowsopengl_h +#define _SDL_windowsopengl_h + +#if SDL_VIDEO_OPENGL_WGL + +struct SDL_GLDriverData +{ + int WGL_ARB_pixel_format; + + void *(WINAPI * wglGetProcAddress) (const char *proc); + HGLRC(WINAPI * wglCreateContext) (HDC hdc); + BOOL(WINAPI * wglDeleteContext) (HGLRC hglrc); + BOOL(WINAPI * wglMakeCurrent) (HDC hdc, HGLRC hglrc); + BOOL(WINAPI * wglChoosePixelFormatARB) (HDC hdc, + const int *piAttribIList, + const FLOAT * pfAttribFList, + UINT nMaxFormats, + int *piFormats, + UINT * nNumFormats); + BOOL(WINAPI * wglGetPixelFormatAttribivARB) (HDC hdc, int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int *piAttributes, + int *piValues); + void (WINAPI * wglSwapIntervalEXT) (int interval); + int (WINAPI * wglGetSwapIntervalEXT) (void); +}; + +/* OpenGL functions */ +extern int WIN_GL_LoadLibrary(_THIS, const char *path); +extern void *WIN_GL_GetProcAddress(_THIS, const char *proc); +extern void WIN_GL_UnloadLibrary(_THIS); +extern int WIN_GL_SetupWindow(_THIS, SDL_Window * window); +extern SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window * window); +extern int WIN_GL_MakeCurrent(_THIS, SDL_Window * window, + SDL_GLContext context); +extern int WIN_GL_SetSwapInterval(_THIS, int interval); +extern int WIN_GL_GetSwapInterval(_THIS); +extern void WIN_GL_SwapWindow(_THIS, SDL_Window * window); +extern void WIN_GL_DeleteContext(_THIS, SDL_GLContext context); + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#endif /* SDL_VIDEO_OPENGL_WGL */ + +#endif /* _SDL_windowsopengl_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsshape.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsshape.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,104 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 2010 Eli Gottlieb + + 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 + + Eli Gottlieb + eligottlieb@gmail.com +*/ + +#include +#include "SDL_assert.h" +#include "SDL_windowsshape.h" +#include "SDL_windowsvideo.h" + +SDL_WindowShaper* +Win32_CreateShaper(SDL_Window * window) { + int resized_properly; + SDL_WindowShaper* result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper)); + result->window = window; + result->mode.mode = ShapeModeDefault; + result->mode.parameters.binarizationCutoff = 1; + result->userx = result->usery = 0; + result->driverdata = (SDL_ShapeData*)SDL_malloc(sizeof(SDL_ShapeData)); + ((SDL_ShapeData*)result->driverdata)->mask_tree = NULL; + //Put some driver-data here. + window->shaper = result; + resized_properly = Win32_ResizeWindowShape(window); + if (resized_properly != 0) + return NULL; + + return result; +} + +void +CombineRectRegions(SDL_ShapeTree* node,void* closure) { + HRGN mask_region = *((HRGN*)closure),temp_region = NULL; + if(node->kind == OpaqueShape) { + //Win32 API regions exclude their outline, so we widen the region by one pixel in each direction to include the real outline. + temp_region = CreateRectRgn(node->data.shape.x,node->data.shape.y,node->data.shape.x + node->data.shape.w + 1,node->data.shape.y + node->data.shape.h + 1); + if(mask_region != NULL) { + CombineRgn(mask_region,mask_region,temp_region,RGN_OR); + DeleteObject(temp_region); + } + else + *((HRGN*)closure) = temp_region; + } +} + +int +Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { + SDL_ShapeData *data; + HRGN mask_region = NULL; + + if (shaper == NULL || shape == NULL) + return SDL_INVALID_SHAPE_ARGUMENT; + if(shape->format->Amask == 0 && shape_mode->mode != ShapeModeColorKey || shape->w != shaper->window->w || shape->h != shaper->window->h) + return SDL_INVALID_SHAPE_ARGUMENT; + + data = (SDL_ShapeData*)shaper->driverdata; + if(data->mask_tree != NULL) + SDL_FreeShapeTree(&data->mask_tree); + data->mask_tree = SDL_CalculateShapeTree(*shape_mode,shape); + + SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&mask_region); + SDL_assert(mask_region != NULL); + + SetWindowRgn(((SDL_WindowData *)(shaper->window->driverdata))->hwnd, mask_region, TRUE); + + return 0; +} + +int +Win32_ResizeWindowShape(SDL_Window *window) { + SDL_ShapeData* data; + + if (window == NULL) + return -1; + data = (SDL_ShapeData *)window->shaper->driverdata; + if (data == NULL) + return -1; + + if(data->mask_tree != NULL) + SDL_FreeShapeTree(&data->mask_tree); + if(window->shaper->hasshape == SDL_TRUE) { + window->shaper->userx = window->x; + window->shaper->usery = window->y; + SDL_SetWindowPosition(window,-1000,-1000); + } + + return 0; +} diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsshape.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsshape.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,41 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 2010 Eli Gottlieb + + 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 + + Eli Gottlieb + eligottlieb@gmail.com +*/ + +#include "SDL_config.h" + +#ifndef _SDL_windowsshape_h +#define _SDL_windowsshape_h + +#include "SDL_video.h" +#include "SDL_shape.h" +#include "../SDL_sysvideo.h" +#include "../SDL_shape_internals.h" + +typedef struct { + SDL_ShapeTree *mask_tree; +} SDL_ShapeData; + +extern SDL_WindowShaper* Win32_CreateShaper(SDL_Window * window); +extern int Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); +extern int Win32_ResizeWindowShape(SDL_Window *window); + +#endif /* _SDL_windowsshape_h */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsvideo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsvideo.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,266 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#include "SDL_main.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" + +#include "SDL_windowsvideo.h" +#include "SDL_windowsshape.h" +#include "SDL_d3drender.h" +#include "SDL_gdirender.h" +#include "SDL_gapirender.h" + +/* Initialization/Query functions */ +static int WIN_VideoInit(_THIS); +static void WIN_VideoQuit(_THIS); + +/* Sets an error message based on GetLastError() */ +void +WIN_SetError(const char *prefix) +{ + TCHAR buffer[1024]; + char *message; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, + buffer, SDL_arraysize(buffer), NULL); + message = WIN_StringToUTF8(buffer); + SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message); + SDL_free(message); +} + + +/* Windows driver bootstrap functions */ + +static int +WIN_Available(void) +{ + return (1); +} + +static void +WIN_DeleteDevice(SDL_VideoDevice * device) +{ + SDL_VideoData *data = (SDL_VideoData *) device->driverdata; + + SDL_UnregisterApp(); +#if SDL_VIDEO_RENDER_D3D + if (data->d3d) { + IDirect3D9_Release(data->d3d); + FreeLibrary(data->d3dDLL); + } +#endif +#if SDL_VIDEO_RENDER_DDRAW + if (data->ddraw) { + data->ddraw->lpVtbl->Release(data->ddraw); + FreeLibrary(data->ddrawDLL); + } +#endif +#ifdef _WIN32_WCE + if(data->hAygShell) { + FreeLibrary(data->hAygShell); + } +#endif + if (data->userDLL) { + FreeLibrary(data->userDLL); + } + + SDL_free(device->driverdata); + SDL_free(device); +} + +static SDL_VideoDevice * +WIN_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + SDL_VideoData *data; + + SDL_RegisterApp(NULL, 0, NULL); + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (device) { + data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + } else { + data = NULL; + } + if (!data) { + SDL_OutOfMemory(); + if (device) { + SDL_free(device); + } + return NULL; + } + device->driverdata = data; + +#if SDL_VIDEO_RENDER_D3D + data->d3dDLL = LoadLibrary(TEXT("D3D9.DLL")); + if (data->d3dDLL) { + IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion); + + D3DCreate = + (IDirect3D9 * (WINAPI *) (UINT)) GetProcAddress(data->d3dDLL, + "Direct3DCreate9"); + if (D3DCreate) { + data->d3d = D3DCreate(D3D_SDK_VERSION); + } + if (!data->d3d) { + FreeLibrary(data->d3dDLL); + data->d3dDLL = NULL; + } + } +#endif /* SDL_VIDEO_RENDER_D3D */ +#if SDL_VIDEO_RENDER_DDRAW + data->ddrawDLL = LoadLibrary(TEXT("ddraw.dll")); + if (data->ddrawDLL) { + IDirectDraw *(WINAPI * DDCreate) (GUID FAR * lpGUID, + LPDIRECTDRAW FAR * lplpDD, + IUnknown FAR * pUnkOuter); + + DDCreate = + (IDirectDraw * + (WINAPI *) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *)) + GetProcAddress(data->ddrawDLL, TEXT("DirectDrawCreate")); + if (!DDCreate || DDCreate(NULL, &data->ddraw, NULL) != DD_OK) { + FreeLibrary(data->ddrawDLL); + data->ddrawDLL = NULL; + data->ddraw = NULL; + } + } +#endif /* SDL_VIDEO_RENDER_DDRAW */ + +#ifdef _WIN32_WCE + data->hAygShell = LoadLibrary(TEXT("\\windows\\aygshell.dll")); + if(0 == data->hAygShell) + data->hAygShell = LoadLibrary(TEXT("aygshell.dll")); + data->SHFullScreen = (0 != data->hAygShell ? + (PFNSHFullScreen) GetProcAddress(data->hAygShell, TEXT("SHFullScreen")) : 0); + data->CoordTransform = NULL; +#endif + + data->userDLL = LoadLibrary(TEXT("USER32.DLL")); + if (data->userDLL) { + data->CloseTouchInputHandle = (BOOL (WINAPI *)( HTOUCHINPUT )) GetProcAddress(data->userDLL, "CloseTouchInputHandle"); + data->GetTouchInputInfo = (BOOL (WINAPI *)( HTOUCHINPUT, UINT, PTOUCHINPUT, int )) GetProcAddress(data->userDLL, "GetTouchInputInfo"); + data->RegisterTouchWindow = (BOOL (WINAPI *)( HWND, ULONG )) GetProcAddress(data->userDLL, "RegisterTouchWindow"); + } + + /* Set the function pointers */ + device->VideoInit = WIN_VideoInit; + device->VideoQuit = WIN_VideoQuit; + device->GetDisplayBounds = WIN_GetDisplayBounds; + device->GetDisplayModes = WIN_GetDisplayModes; + device->SetDisplayMode = WIN_SetDisplayMode; + device->SetDisplayGammaRamp = WIN_SetDisplayGammaRamp; + device->GetDisplayGammaRamp = WIN_GetDisplayGammaRamp; + device->PumpEvents = WIN_PumpEvents; + +#undef CreateWindow + device->CreateWindow = WIN_CreateWindow; + device->CreateWindowFrom = WIN_CreateWindowFrom; + device->SetWindowTitle = WIN_SetWindowTitle; + device->SetWindowIcon = WIN_SetWindowIcon; + device->SetWindowPosition = WIN_SetWindowPosition; + device->SetWindowSize = WIN_SetWindowSize; + device->ShowWindow = WIN_ShowWindow; + device->HideWindow = WIN_HideWindow; + device->RaiseWindow = WIN_RaiseWindow; + device->MaximizeWindow = WIN_MaximizeWindow; + device->MinimizeWindow = WIN_MinimizeWindow; + device->RestoreWindow = WIN_RestoreWindow; + device->SetWindowGrab = WIN_SetWindowGrab; + device->DestroyWindow = WIN_DestroyWindow; + device->GetWindowWMInfo = WIN_GetWindowWMInfo; + + device->shape_driver.CreateShaper = Win32_CreateShaper; + device->shape_driver.SetWindowShape = Win32_SetWindowShape; + device->shape_driver.ResizeWindowShape = Win32_ResizeWindowShape; + +#ifdef SDL_VIDEO_OPENGL_WGL + device->GL_LoadLibrary = WIN_GL_LoadLibrary; + device->GL_GetProcAddress = WIN_GL_GetProcAddress; + device->GL_UnloadLibrary = WIN_GL_UnloadLibrary; + device->GL_CreateContext = WIN_GL_CreateContext; + device->GL_MakeCurrent = WIN_GL_MakeCurrent; + device->GL_SetSwapInterval = WIN_GL_SetSwapInterval; + device->GL_GetSwapInterval = WIN_GL_GetSwapInterval; + device->GL_SwapWindow = WIN_GL_SwapWindow; + device->GL_DeleteContext = WIN_GL_DeleteContext; +#endif + device->StartTextInput = WIN_StartTextInput; + device->StopTextInput = WIN_StopTextInput; + device->SetTextInputRect = WIN_SetTextInputRect; + + device->SetClipboardText = WIN_SetClipboardText; + device->GetClipboardText = WIN_GetClipboardText; + device->HasClipboardText = WIN_HasClipboardText; + + device->free = WIN_DeleteDevice; + + return device; +} + +VideoBootStrap WINDOWS_bootstrap = { +#ifdef _WIN32_WCE + "wince", "SDL WinCE video driver", WINCE_Available, WIN_CreateDevice +#else + "windows", "SDL Win32/64 video driver", WIN_Available, WIN_CreateDevice +#endif +}; + +int +WIN_VideoInit(_THIS) +{ + if (WIN_InitModes(_this) < 0) { + return -1; + } + +#if SDL_VIDEO_RENDER_D3D + D3D_AddRenderDriver(_this); +#endif +#if SDL_VIDEO_RENDER_DDRAW + DDRAW_AddRenderDriver(_this); +#endif +#if SDL_VIDEO_RENDER_GDI + GDI_AddRenderDriver(_this); +#endif +#if SDL_VIDEO_RENDER_GAPI + WINCE_AddRenderDriver(_this); +#endif + + WIN_InitKeyboard(_this); + WIN_InitMouse(_this); + + return 0; +} + +void +WIN_VideoQuit(_THIS) +{ + WIN_QuitModes(_this); + WIN_QuitKeyboard(_this); + WIN_QuitMouse(_this); +} + +/* vim: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowsvideo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowsvideo.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,222 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_windowsvideo_h +#define _SDL_windowsvideo_h + +#include "../SDL_sysvideo.h" + +#define WIN32_LEAN_AND_MEAN +#define STRICT +#ifndef UNICODE +#define UNICODE +#endif +#undef WINVER +#define WINVER 0x500 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices() */ + +#include + +#ifndef __GNUC__ +#include +#else +#include "SDL_msctf.h" +#endif + +#include + +#define MAX_CANDLIST 10 +#define MAX_CANDLENGTH 256 + +#if SDL_VIDEO_RENDER_D3D +//#include +#define D3D_DEBUG_INFO +#include "d3d9.h" +#endif + +#if SDL_VIDEO_RENDER_DDRAW +/* WIN32_LEAN_AND_MEAN was defined, so we have to include this by hand */ +#include +#include "ddraw.h" +#endif + +#include "SDL_windowsclipboard.h" +#include "SDL_windowsevents.h" +#include "SDL_windowsgamma.h" +#include "SDL_windowskeyboard.h" +#include "SDL_windowsmodes.h" +#include "SDL_windowsmouse.h" +#include "SDL_windowsopengl.h" +#include "SDL_windowswindow.h" +#include "SDL_events.h" + +#ifdef UNICODE +#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UCS-2", (char *)S, (SDL_wcslen(S)+1)*sizeof(WCHAR)) +#define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UCS-2", "UTF-8", (char *)S, SDL_strlen(S)+1) +#else +#define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "ASCII", (char *)S, (SDL_strlen(S)+1)) +#define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)S, SDL_strlen(S)+1) +#endif +extern void WIN_SetError(const char *prefix); + +enum { RENDER_NONE, RENDER_D3D, RENDER_DDRAW, RENDER_GDI, RENDER_GAPI, RENDER_RAW }; + +#if WINVER < 0x0601 +/* Touch input definitions */ +#define TWF_FINETOUCH 1 +#define TWF_WANTPALM 2 + +#define TOUCHEVENTF_MOVE 0x0001 +#define TOUCHEVENTF_DOWN 0x0002 +#define TOUCHEVENTF_UP 0x0004 + +DECLARE_HANDLE(HTOUCHINPUT); + +typedef struct _TOUCHINPUT { + LONG x; + LONG y; + HANDLE hSource; + DWORD dwID; + DWORD dwFlags; + DWORD dwMask; + DWORD dwTime; + ULONG_PTR dwExtraInfo; + DWORD cxContact; + DWORD cyContact; +} TOUCHINPUT, *PTOUCHINPUT; + +#endif /* WINVER < 0x0601 */ + +typedef BOOL (*PFNSHFullScreen)(HWND, DWORD); +typedef void (*PFCoordTransform)(SDL_Window*, POINT*); + +typedef struct +{ + void **lpVtbl; + int refcount; + void *data; +} TSFSink; + +/* Definition from Win98DDK version of IMM.H */ +typedef struct tagINPUTCONTEXT2 { + HWND hWnd; + BOOL fOpen; + POINT ptStatusWndPos; + POINT ptSoftKbdPos; + DWORD fdwConversion; + DWORD fdwSentence; + union { + LOGFONTA A; + LOGFONTW W; + } lfFont; + COMPOSITIONFORM cfCompForm; + CANDIDATEFORM cfCandForm[4]; + HIMCC hCompStr; + HIMCC hCandInfo; + HIMCC hGuideLine; + HIMCC hPrivate; + DWORD dwNumMsgBuf; + HIMCC hMsgBuf; + DWORD fdwInit; + DWORD dwReserve[3]; +} INPUTCONTEXT2, *PINPUTCONTEXT2, NEAR *NPINPUTCONTEXT2, FAR *LPINPUTCONTEXT2; + +/* Private display data */ + +typedef struct SDL_VideoData +{ + int render; + +#if SDL_VIDEO_RENDER_D3D + HANDLE d3dDLL; + IDirect3D9 *d3d; +#endif +#if SDL_VIDEO_RENDER_DDRAW + HANDLE ddrawDLL; + IDirectDraw *ddraw; +#endif +#ifdef _WIN32_WCE + HMODULE hAygShell; + PFNSHFullScreen SHFullScreen; + PFCoordTransform CoordTransform; +#endif + + const SDL_scancode *key_layout; + DWORD clipboard_count; + + /* Touch input functions */ + HANDLE userDLL; + BOOL (WINAPI *CloseTouchInputHandle)( HTOUCHINPUT ); + BOOL (WINAPI *GetTouchInputInfo)( HTOUCHINPUT, UINT, PTOUCHINPUT, int ); + BOOL (WINAPI *RegisterTouchWindow)( HWND, ULONG ); + + SDL_bool ime_com_initialized; + struct ITfThreadMgr *ime_threadmgr; + SDL_bool ime_initialized; + SDL_bool ime_enabled; + SDL_bool ime_available; + HWND ime_hwnd_main; + HWND ime_hwnd_current; + HIMC ime_himc; + + WCHAR ime_composition[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; + WCHAR ime_readingstring[16]; + int ime_cursor; + + SDL_bool ime_candlist; + WCHAR ime_candidates[MAX_CANDLIST][MAX_CANDLENGTH]; + DWORD ime_candcount; + DWORD ime_candref; + DWORD ime_candsel; + UINT ime_candpgsize; + int ime_candlistindexbase; + SDL_bool ime_candvertical; + + SDL_Texture *ime_candtex; + SDL_bool ime_dirty; + SDL_Rect ime_rect; + SDL_Rect ime_candlistrect; + int ime_winwidth; + int ime_winheight; + + HKL ime_hkl; + HMODULE ime_himm32; + UINT (WINAPI *GetReadingString)(HIMC himc, UINT uReadingBufLen, LPWSTR lpwReadingBuf, PINT pnErrorIndex, BOOL *pfIsVertical, PUINT puMaxReadingLen); + BOOL (WINAPI *ShowReadingWindow)(HIMC himc, BOOL bShow); + LPINPUTCONTEXT2 (WINAPI *ImmLockIMC)(HIMC himc); + BOOL (WINAPI *ImmUnlockIMC)(HIMC himc); + LPVOID (WINAPI *ImmLockIMCC)(HIMCC himcc); + BOOL (WINAPI *ImmUnlockIMCC)(HIMCC himcc); + + SDL_bool ime_uiless; + struct ITfThreadMgrEx *ime_threadmgrex; + DWORD ime_uielemsinkcookie; + DWORD ime_alpnsinkcookie; + DWORD ime_openmodesinkcookie; + DWORD ime_convmodesinkcookie; + TSFSink *ime_uielemsink; + TSFSink *ime_ippasink; +} SDL_VideoData; + +#endif /* _SDL_windowsvideo_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowswindow.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowswindow.c Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,639 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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" + +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_keyboard_c.h" + +#include "SDL_windowsvideo.h" +#include "SDL_windowswindow.h" + +/* This is included after SDL_windowsvideo.h, which includes windows.h */ +#include "SDL_syswm.h" +#include "SDL_gapirender.h" + + +/* Fake window to help with DirectInput events. */ +HWND SDL_HelperWindow = NULL; +static WCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher"); +static WCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow"); +static ATOM SDL_HelperWindowClass = 0; + +static int +SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_VideoDisplay *display = window->display; + SDL_WindowData *data; + + /* Allocate the window data */ + data = (SDL_WindowData *) SDL_malloc(sizeof(*data)); + if (!data) { + SDL_OutOfMemory(); + return -1; + } + data->window = window; + data->hwnd = hwnd; + data->hdc = GetDC(hwnd); + data->created = created; + data->mouse_pressed = SDL_FALSE; + data->videodata = videodata; + + /* Associate the data with the window */ + if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) { + ReleaseDC(hwnd, data->hdc); + SDL_free(data); + WIN_SetError("SetProp() failed"); + return -1; + } + + /* Set up the window proc function */ + data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC); + if (data->wndproc == WIN_WindowProc) { + data->wndproc = NULL; + } + else { + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc); + } + + /* Fill in the SDL window with the window data */ + { + POINT point; + point.x = 0; + point.y = 0; + if (ClientToScreen(hwnd, &point)) { + SDL_Rect bounds; + WIN_GetDisplayBounds(_this, display, &bounds); + window->x = point.x - bounds.x; + window->y = point.y - bounds.y; + } + } + { + RECT rect; + if (GetClientRect(hwnd, &rect)) { + window->w = rect.right; + window->h = rect.bottom; + } + } + { + DWORD style = GetWindowLong(hwnd, GWL_STYLE); + if (style & WS_VISIBLE) { + window->flags |= SDL_WINDOW_SHOWN; + } else { + window->flags &= ~SDL_WINDOW_SHOWN; + } + if (style & (WS_BORDER | WS_THICKFRAME)) { + window->flags &= ~SDL_WINDOW_BORDERLESS; + } else { + window->flags |= SDL_WINDOW_BORDERLESS; + } + if (style & WS_THICKFRAME) { + window->flags |= SDL_WINDOW_RESIZABLE; + } else { + window->flags &= ~SDL_WINDOW_RESIZABLE; + } + if (style & WS_MAXIMIZE) { + window->flags |= SDL_WINDOW_MAXIMIZED; + } else { + window->flags &= ~SDL_WINDOW_MAXIMIZED; + } + if (style & WS_MINIMIZE) { + window->flags |= SDL_WINDOW_MINIMIZED; + } else { + window->flags &= ~SDL_WINDOW_MINIMIZED; + } + } + if (GetFocus() == hwnd) { + window->flags |= SDL_WINDOW_INPUT_FOCUS; + SDL_SetKeyboardFocus(data->window); + + if (window->flags & SDL_WINDOW_INPUT_GRABBED) { + RECT rect; + GetClientRect(hwnd, &rect); + ClientToScreen(hwnd, (LPPOINT) & rect); + ClientToScreen(hwnd, (LPPOINT) & rect + 1); + ClipCursor(&rect); + } + } + + /* Enable multi-touch */ + if (videodata->RegisterTouchWindow) { + videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH|TWF_WANTPALM)); + } + + /* All done! */ + window->driverdata = data; + return 0; +} + +int +WIN_CreateWindow(_THIS, SDL_Window * window) +{ + SDL_VideoDisplay *display = window->display; + HWND hwnd; + RECT rect; + SDL_Rect bounds; + DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN); + int x, y; + int w, h; + + if (window->flags & (SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN)) { + style |= WS_POPUP; + } else { + style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX); + } + if ((window->flags & SDL_WINDOW_RESIZABLE) + && !(window->flags & SDL_WINDOW_FULLSCREEN)) { + style |= (WS_THICKFRAME | WS_MAXIMIZEBOX); + } + + /* Figure out what the window area will be */ + rect.left = 0; + rect.top = 0; + rect.right = window->w; + rect.bottom = window->h; + AdjustWindowRectEx(&rect, style, FALSE, 0); + w = (rect.right - rect.left); + h = (rect.bottom - rect.top); + + WIN_GetDisplayBounds(_this, display, &bounds); + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* The bounds when this window is visible is the fullscreen mode */ + SDL_DisplayMode fullscreen_mode; + if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { + bounds.w = fullscreen_mode.w; + bounds.h = fullscreen_mode.h; + } + } + if ((window->flags & SDL_WINDOW_FULLSCREEN) + || window->x == SDL_WINDOWPOS_CENTERED) { + x = bounds.x + (bounds.w - w) / 2; + } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { + if (bounds.x == 0) { + x = CW_USEDEFAULT; + } else { + x = bounds.x; + } + } else { + x = bounds.x + window->x + rect.left; + } + if ((window->flags & SDL_WINDOW_FULLSCREEN) + || window->y == SDL_WINDOWPOS_CENTERED) { + y = bounds.y + (bounds.h - h) / 2; + } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { + if (bounds.x == 0) { + y = CW_USEDEFAULT; + } else { + y = bounds.y; + } + } else { + y = bounds.y + window->y + rect.top; + } + + hwnd = + CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL, + SDL_Instance, NULL); + if (!hwnd) { + WIN_SetError("Couldn't create window"); + return -1; + } + //RegisterTouchWindow(hwnd, 0); + + WIN_PumpEvents(_this); + + if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) { + DestroyWindow(hwnd); + return -1; + } +#ifdef SDL_VIDEO_OPENGL_WGL + if (window->flags & SDL_WINDOW_OPENGL) { + if (WIN_GL_SetupWindow(_this, window) < 0) { + WIN_DestroyWindow(_this, window); + return -1; + } + } +#endif + return 0; +} + +int +WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +{ + HWND hwnd = (HWND) data; + LPTSTR title; + int titleLen; + + /* Query the title from the existing window */ + titleLen = GetWindowTextLength(hwnd); + title = SDL_stack_alloc(TCHAR, titleLen + 1); + if (title) { + titleLen = GetWindowText(hwnd, title, titleLen); + } else { + titleLen = 0; + } + if (titleLen > 0) { + window->title = WIN_StringToUTF8(title); + } + if (title) { + SDL_stack_free(title); + } + + if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) { + return -1; + } + return 0; +} + +void +WIN_SetWindowTitle(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + LPTSTR title; + + if (window->title) { + title = WIN_UTF8ToString(window->title); + } else { + title = NULL; + } + SetWindowText(hwnd, title ? title : TEXT("")); + if (title) { + SDL_free(title); + } +} + +void +WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + HICON hicon = NULL; + + if (icon) { + BYTE *icon_bmp; + int icon_len; + SDL_RWops *dst; + SDL_PixelFormat format; + SDL_Surface *surface; + + /* Create temporary bitmap buffer */ + icon_len = 40 + icon->h * icon->w * 4; + icon_bmp = SDL_stack_alloc(BYTE, icon_len); + dst = SDL_RWFromMem(icon_bmp, icon_len); + if (!dst) { + SDL_stack_free(icon_bmp); + return; + } + + /* Write the BITMAPINFO header */ + SDL_WriteLE32(dst, 40); + SDL_WriteLE32(dst, icon->w); + SDL_WriteLE32(dst, icon->h * 2); + SDL_WriteLE16(dst, 1); + SDL_WriteLE16(dst, 32); + SDL_WriteLE32(dst, BI_RGB); + SDL_WriteLE32(dst, icon->h * icon->w * 4); + SDL_WriteLE32(dst, 0); + SDL_WriteLE32(dst, 0); + SDL_WriteLE32(dst, 0); + SDL_WriteLE32(dst, 0); + + /* Convert the icon to a 32-bit surface with alpha channel */ + SDL_InitFormat(&format, 32, + 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); + surface = SDL_ConvertSurface(icon, &format, 0); + if (surface) { + /* Write the pixels upside down into the bitmap buffer */ + int y = surface->h; + while (y--) { + Uint8 *src = (Uint8 *) surface->pixels + y * surface->pitch; + SDL_RWwrite(dst, src, surface->pitch, 1); + } + SDL_FreeSurface(surface); + +/* TODO: create the icon in WinCE (CreateIconFromResource isn't available) */ +#ifndef _WIN32_WCE + hicon = + CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000); +#endif + } + SDL_RWclose(dst); + SDL_stack_free(icon_bmp); + } + + /* Set the icon for the window */ + SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon); + + /* Set the icon in the task manager (should we do this?) */ + SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon); +} + +void +WIN_SetWindowPosition(_THIS, SDL_Window * window) +{ + SDL_VideoDisplay *display = window->display; + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + RECT rect; + SDL_Rect bounds; + DWORD style; + HWND top; + BOOL menu; + int x, y; + int w, h; + + /* Figure out what the window area will be */ + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + style = GetWindowLong(hwnd, GWL_STYLE); + rect.left = 0; + rect.top = 0; + rect.right = window->w; + rect.bottom = window->h; +#ifdef _WIN32_WCE + menu = FALSE; +#else + menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); +#endif + AdjustWindowRectEx(&rect, style, menu, 0); + w = (rect.right - rect.left); + h = (rect.bottom - rect.top); + + WIN_GetDisplayBounds(_this, display, &bounds); + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* The bounds when this window is visible is the fullscreen mode */ + SDL_DisplayMode fullscreen_mode; + if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { + bounds.w = fullscreen_mode.w; + bounds.h = fullscreen_mode.h; + } + } + if ((window->flags & SDL_WINDOW_FULLSCREEN) + || window->x == SDL_WINDOWPOS_CENTERED) { + x = bounds.x + (bounds.w - w) / 2; + } else { + x = bounds.x + window->x + rect.left; + } + if ((window->flags & SDL_WINDOW_FULLSCREEN) + || window->y == SDL_WINDOWPOS_CENTERED) { + y = bounds.y + (bounds.h - h) / 2; + } else { + y = bounds.y + window->y + rect.top; + } + + SetWindowPos(hwnd, top, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE)); +} + +void +WIN_SetWindowSize(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + RECT rect; + DWORD style; + HWND top; + BOOL menu; + int w, h; + + /* Figure out what the window area will be */ + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + style = GetWindowLong(hwnd, GWL_STYLE); + rect.left = 0; + rect.top = 0; + rect.right = window->w; + rect.bottom = window->h; +#ifdef _WIN32_WCE + menu = FALSE; +#else + menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); +#endif + AdjustWindowRectEx(&rect, style, menu, 0); + w = (rect.right - rect.left); + h = (rect.bottom - rect.top); + + SetWindowPos(hwnd, top, 0, 0, w, h, (SWP_NOCOPYBITS | SWP_NOMOVE)); +} + +void +WIN_ShowWindow(_THIS, SDL_Window * window) +{ +#ifdef _WIN32_WCE + WINCE_ShowWindow(_this, window, 1); +#else + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + ShowWindow(hwnd, SW_SHOW); +#endif +} + +void +WIN_HideWindow(_THIS, SDL_Window * window) +{ +#ifdef _WIN32_WCE + WINCE_ShowWindow(_this, window, 0); +#else + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + ShowWindow(hwnd, SW_HIDE); +#endif +} + +void +WIN_RaiseWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + HWND top; + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE)); +} + +void +WIN_MaximizeWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + +#ifdef _WIN32_WCE + if((window->flags & SDL_WINDOW_FULLSCREEN) && videodata->SHFullScreen) + videodata->SHFullScreen(hwnd, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON); +#endif + + ShowWindow(hwnd, SW_MAXIMIZE); +} + +void +WIN_MinimizeWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + + ShowWindow(hwnd, SW_MINIMIZE); + +#ifdef _WIN32_WCE + if((window->flags & SDL_WINDOW_FULLSCREEN) && videodata->SHFullScreen) + videodata->SHFullScreen(hwnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON); +#endif +} + +void +WIN_RestoreWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_RESTORE); +} + +void +WIN_SetWindowGrab(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) + && (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + RECT rect; + GetClientRect(hwnd, &rect); + ClientToScreen(hwnd, (LPPOINT) & rect); + ClientToScreen(hwnd, (LPPOINT) & rect + 1); + ClipCursor(&rect); + } else { + ClipCursor(NULL); + } +} + +void +WIN_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (data) { +#ifdef _WIN32_WCE + WINCE_ShowWindow(_this, window, 0); +#endif + ReleaseDC(data->hwnd, data->hdc); + if (data->created) { + DestroyWindow(data->hwnd); + } + SDL_free(data); + } +} + +SDL_bool +WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + if (info->version.major <= SDL_MAJOR_VERSION) { + info->subsystem = SDL_SYSWM_WINDOWS; + info->info.win.window = hwnd; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d.%d\n", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + return SDL_FALSE; + } +} + + +/* + * Creates a HelperWindow used for DirectInput events. + */ +int +SDL_HelperWindowCreate(void) +{ + HINSTANCE hInstance = GetModuleHandle(NULL); + WNDCLASS wce; + HWND hWndParent = NULL; + + /* Make sure window isn't created twice. */ + if (SDL_HelperWindow != NULL) { + return 0; + } + + /* Create the class. */ + SDL_zero(wce); + wce.lpfnWndProc = DefWindowProc; + wce.lpszClassName = (LPCWSTR) SDL_HelperWindowClassName; + wce.hInstance = hInstance; + + /* Register the class. */ + SDL_HelperWindowClass = RegisterClass(&wce); + if (SDL_HelperWindowClass == 0) { + WIN_SetError("Unable to create Helper Window Class"); + return -1; + } + +#ifndef _WIN32_WCE + /* WinCE doesn't have HWND_MESSAGE */ + hWndParent = HWND_MESSAGE; +#endif + + /* Create the window. */ + SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName, + SDL_HelperWindowName, + WS_OVERLAPPED, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, hWndParent, NULL, + hInstance, NULL); + if (SDL_HelperWindow == NULL) { + UnregisterClass(SDL_HelperWindowClassName, hInstance); + WIN_SetError("Unable to create Helper Window"); + return -1; + } + + return 0; +} + + +/* + * Destroys the HelperWindow previously created with SDL_HelperWindowCreate. + */ +void +SDL_HelperWindowDestroy(void) +{ + HINSTANCE hInstance = GetModuleHandle(NULL); + + /* Destroy the window. */ + if (SDL_HelperWindow != NULL) { + if (DestroyWindow(SDL_HelperWindow) == 0) { + WIN_SetError("Unable to destroy Helper Window"); + return; + } + SDL_HelperWindow = NULL; + } + + /* Unregister the class. */ + if (SDL_HelperWindowClass != 0) { + if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) { + WIN_SetError("Unable to destroy Helper Window Class"); + return; + } + SDL_HelperWindowClass = 0; + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/SDL_windowswindow.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/SDL_windowswindow.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,66 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 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_windowswindow_h +#define _SDL_windowswindow_h + +#ifdef _WIN32_WCE +#define SHFS_SHOWTASKBAR 0x0001 +#define SHFS_HIDETASKBAR 0x0002 +#define SHFS_SHOWSIPBUTTON 0x0004 +#define SHFS_HIDESIPBUTTON 0x0008 +#define SHFS_SHOWSTARTICON 0x0010 +#define SHFS_HIDESTARTICON 0x0020 +#endif + +typedef struct +{ + SDL_Window *window; + HWND hwnd; + HDC hdc; + WNDPROC wndproc; + SDL_bool created; + int mouse_pressed; + struct SDL_VideoData *videodata; +} SDL_WindowData; + +extern int WIN_CreateWindow(_THIS, SDL_Window * window); +extern int WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); +extern void WIN_SetWindowTitle(_THIS, SDL_Window * window); +extern void WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); +extern void WIN_SetWindowPosition(_THIS, SDL_Window * window); +extern void WIN_SetWindowSize(_THIS, SDL_Window * window); +extern void WIN_ShowWindow(_THIS, SDL_Window * window); +extern void WIN_HideWindow(_THIS, SDL_Window * window); +extern void WIN_RaiseWindow(_THIS, SDL_Window * window); +extern void WIN_MaximizeWindow(_THIS, SDL_Window * window); +extern void WIN_MinimizeWindow(_THIS, SDL_Window * window); +extern void WIN_RestoreWindow(_THIS, SDL_Window * window); +extern void WIN_SetWindowGrab(_THIS, SDL_Window * window); +extern void WIN_DestroyWindow(_THIS, SDL_Window * window); +extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +#endif /* _SDL_windowswindow_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 src/video/windows/wmmsg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/windows/wmmsg.h Thu Jan 20 18:04:05 2011 -0800 @@ -0,0 +1,1032 @@ + +#define MAX_WMMSG (sizeof(wmtab)/sizeof(wmtab[0])) + +char *wmtab[] = { + "WM_NULL", + "WM_CREATE", + "WM_DESTROY", + "WM_MOVE", + "UNKNOWN (4)", + "WM_SIZE", + "WM_ACTIVATE", + "WM_SETFOCUS", + "WM_KILLFOCUS", + "UNKNOWN (9)", + "WM_ENABLE", + "WM_SETREDRAW", + "WM_SETTEXT", + "WM_GETTEXT", + "WM_GETTEXTLENGTH", + "WM_PAINT", + "WM_CLOSE", + "WM_QUERYENDSESSION", + "WM_QUIT", + "WM_QUERYOPEN", + "WM_ERASEBKGND", + "WM_SYSCOLORCHANGE", + "WM_ENDSESSION", + "UNKNOWN (23)", + "WM_SHOWWINDOW", + "UNKNOWN (25)", + "WM_SETTINGCHANGE", + "WM_DEVMODECHANGE", + "WM_ACTIVATEAPP", + "WM_FONTCHANGE", + "WM_TIMECHANGE", + "WM_CANCELMODE", + "WM_SETCURSOR", + "WM_MOUSEACTIVATE", + "WM_CHILDACTIVATE", + "WM_QUEUESYNC", + "WM_GETMINMAXINFO", + "UNKNOWN (37)", + "WM_PAINTICON", + "WM_ICONERASEBKGND", + "WM_NEXTDLGCTL", + "UNKNOWN (41)", + "WM_SPOOLERSTATUS", + "WM_DRAWITEM", + "WM_MEASUREITEM", + "WM_DELETEITEM", + "WM_VKEYTOITEM", + "WM_CHARTOITEM", + "WM_SETFONT", + "WM_GETFONT", + "WM_SETHOTKEY", + "WM_GETHOTKEY", + "UNKNOWN (52)", + "UNKNOWN (53)", + "UNKNOWN (54)", + "WM_QUERYDRAGICON", + "UNKNOWN (56)", + "WM_COMPAREITEM", + "UNKNOWN (58)", + "UNKNOWN (59)", + "UNKNOWN (60)", + "WM_GETOBJECT", + "UNKNOWN (62)", + "UNKNOWN (63)", + "UNKNOWN (64)", + "WM_COMPACTING", + "UNKNOWN (66)", + "UNKNOWN (67)", + "WM_COMMNOTIFY", + "UNKNOWN (69)", + "WM_WINDOWPOSCHANGING", + "WM_WINDOWPOSCHANGED", + "WM_POWER", + "UNKNOWN (73)", + "WM_COPYDATA", + "WM_CANCELJOURNAL", + "UNKNOWN (76)", + "UNKNOWN (77)", + "WM_NOTIFY", + "UNKNOWN (79)", + "WM_INPUTLANGCHANGEREQUEST", + "WM_INPUTLANGCHANGE", + "WM_TCARD", + "WM_HELP", + "WM_USERCHANGED", + "WM_NOTIFYFORMAT", + "UNKNOWN (86)", + "UNKNOWN (87)", + "UNKNOWN (88)", + "UNKNOWN (89)", + "UNKNOWN (90)", + "UNKNOWN (91)", + "UNKNOWN (92)", + "UNKNOWN (93)", + "UNKNOWN (94)", + "UNKNOWN (95)", + "UNKNOWN (96)", + "UNKNOWN (97)", + "UNKNOWN (98)", + "UNKNOWN (99)", + "UNKNOWN (100)", + "UNKNOWN (101)", + "UNKNOWN (102)", + "UNKNOWN (103)", + "UNKNOWN (104)", + "UNKNOWN (105)", + "UNKNOWN (106)", + "UNKNOWN (107)", + "UNKNOWN (108)", + "UNKNOWN (109)", + "UNKNOWN (110)", + "UNKNOWN (111)", + "UNKNOWN (112)", + "UNKNOWN (113)", + "UNKNOWN (114)", + "UNKNOWN (115)", + "UNKNOWN (116)", + "UNKNOWN (117)", + "UNKNOWN (118)", + "UNKNOWN (119)", + "UNKNOWN (120)", + "UNKNOWN (121)", + "UNKNOWN (122)", + "WM_CONTEXTMENU", + "WM_STYLECHANGING", + "WM_STYLECHANGED", + "WM_DISPLAYCHANGE", + "WM_GETICON", + "WM_SETICON", + "WM_NCCREATE", + "WM_NCDESTROY", + "WM_NCCALCSIZE", + "WM_NCHITTEST", + "WM_NCPAINT", + "WM_NCACTIVATE", + "WM_GETDLGCODE", + "WM_SYNCPAINT", + "UNKNOWN (137)", + "UNKNOWN (138)", + "UNKNOWN (139)", + "UNKNOWN (140)", + "UNKNOWN (141)", + "UNKNOWN (142)", + "UNKNOWN (143)", + "UNKNOWN (144)", + "UNKNOWN (145)", + "UNKNOWN (146)", + "UNKNOWN (147)", + "UNKNOWN (148)", + "UNKNOWN (149)", + "UNKNOWN (150)", + "UNKNOWN (151)", + "UNKNOWN (152)", + "UNKNOWN (153)", + "UNKNOWN (154)", + "UNKNOWN (155)", + "UNKNOWN (156)", + "UNKNOWN (157)", + "UNKNOWN (158)", + "UNKNOWN (159)", + "WM_NCMOUSEMOVE", + "WM_NCLBUTTONDOWN", + "WM_NCLBUTTONUP", + "WM_NCLBUTTONDBLCLK", + "WM_NCRBUTTONDOWN", + "WM_NCRBUTTONUP", + "WM_NCRBUTTONDBLCLK", + "WM_NCMBUTTONDOWN", + "WM_NCMBUTTONUP", + "WM_NCMBUTTONDBLCLK", + "UNKNOWN (170)", + "UNKNOWN (171)", + "UNKNOWN (172)", + "UNKNOWN (173)", + "UNKNOWN (174)", + "UNKNOWN (175)", + "UNKNOWN (176)", + "UNKNOWN (177)", + "UNKNOWN (178)", + "UNKNOWN (179)", + "UNKNOWN (180)", + "UNKNOWN (181)", + "UNKNOWN (182)", + "UNKNOWN (183)", + "UNKNOWN (184)", + "UNKNOWN (185)", + "UNKNOWN (186)", + "UNKNOWN (187)", + "UNKNOWN (188)", + "UNKNOWN (189)", + "UNKNOWN (190)", + "UNKNOWN (191)", + "UNKNOWN (192)", + "UNKNOWN (193)", + "UNKNOWN (194)", + "UNKNOWN (195)", + "UNKNOWN (196)", + "UNKNOWN (197)", + "UNKNOWN (198)", + "UNKNOWN (199)", + "UNKNOWN (200)", + "UNKNOWN (201)", + "UNKNOWN (202)", + "UNKNOWN (203)", + "UNKNOWN (204)", + "UNKNOWN (205)", + "UNKNOWN (206)", + "UNKNOWN (207)", + "UNKNOWN (208)", + "UNKNOWN (209)", + "UNKNOWN (210)", + "UNKNOWN (211)", + "UNKNOWN (212)", + "UNKNOWN (213)", + "UNKNOWN (214)", + "UNKNOWN (215)", + "UNKNOWN (216)", + "UNKNOWN (217)", + "UNKNOWN (218)", + "UNKNOWN (219)", + "UNKNOWN (220)", + "UNKNOWN (221)", + "UNKNOWN (222)", + "UNKNOWN (223)", + "UNKNOWN (224)", + "UNKNOWN (225)", + "UNKNOWN (226)", + "UNKNOWN (227)", + "UNKNOWN (228)", + "UNKNOWN (229)", + "UNKNOWN (230)", + "UNKNOWN (231)", + "UNKNOWN (232)", + "UNKNOWN (233)", + "UNKNOWN (234)", + "UNKNOWN (235)", + "UNKNOWN (236)", + "UNKNOWN (237)", + "UNKNOWN (238)", + "UNKNOWN (239)", + "UNKNOWN (240)", + "UNKNOWN (241)", + "UNKNOWN (242)", + "UNKNOWN (243)", + "UNKNOWN (244)", + "UNKNOWN (245)", + "UNKNOWN (246)", + "UNKNOWN (247)", + "UNKNOWN (248)", + "UNKNOWN (249)", + "UNKNOWN (250)", + "UNKNOWN (251)", + "UNKNOWN (252)", + "UNKNOWN (253)", + "UNKNOWN (254)", + "UNKNOWN (255)", + "WM_KEYDOWN", + "WM_KEYUP", + "WM_CHAR", + "WM_DEADCHAR", + "WM_SYSKEYDOWN", + "WM_SYSKEYUP", + "WM_SYSCHAR", + "WM_SYSDEADCHAR", + "WM_KEYLAST", + "UNKNOWN (265)", + "UNKNOWN (266)", + "UNKNOWN (267)", + "UNKNOWN (268)", + "UNKNOWN (269)", + "UNKNOWN (270)", + "UNKNOWN (271)", + "WM_INITDIALOG", + "WM_COMMAND", + "WM_SYSCOMMAND", + "WM_TIMER", + "WM_HSCROLL", + "WM_VSCROLL", + "WM_INITMENU", + "WM_INITMENUPOPUP", + "UNKNOWN (280)", + "WM_GESTURE", + "UNKNOWN (282)", + "UNKNOWN (283)", + "UNKNOWN (284)", + "UNKNOWN (285)", + "UNKNOWN (286)", + "WM_MENUSELECT", + "WM_MENUCHAR", + "WM_ENTERIDLE", + "WM_MENURBUTTONUP", + "WM_MENUDRAG", + "WM_MENUGETOBJECT", + "WM_UNINITMENUPOPUP", + "WM_MENUCOMMAND", + "UNKNOWN (295)", + "UNKNOWN (296)", + "UNKNOWN (297)", + "UNKNOWN (298)", + "UNKNOWN (299)", + "UNKNOWN (300)", + "UNKNOWN (301)", + "UNKNOWN (302)", + "UNKNOWN (303)", + "UNKNOWN (304)", + "UNKNOWN (305)", + "WM_CTLCOLORMSGBOX", + "WM_CTLCOLOREDIT", + "WM_CTLCOLORLISTBOX", + "WM_CTLCOLORBTN", + "WM_CTLCOLORDLG", + "WM_CTLCOLORSCROLLBAR", + "WM_CTLCOLORSTATIC", + "UNKNOWN (313)", + "UNKNOWN (314)", + "UNKNOWN (315)", + "UNKNOWN (316)", + "UNKNOWN (317)", + "UNKNOWN (318)", + "UNKNOWN (319)", + "UNKNOWN (320)", + "UNKNOWN (321)", + "UNKNOWN (322)", + "UNKNOWN (323)", + "UNKNOWN (324)", + "UNKNOWN (325)", + "UNKNOWN (326)", + "UNKNOWN (327)", + "UNKNOWN (328)", + "UNKNOWN (329)", + "UNKNOWN (330)", + "UNKNOWN (331)", + "UNKNOWN (332)", + "UNKNOWN (333)", + "UNKNOWN (334)", + "UNKNOWN (335)", + "UNKNOWN (336)", + "UNKNOWN (337)", + "UNKNOWN (338)", + "UNKNOWN (339)", + "UNKNOWN (340)", + "UNKNOWN (341)", + "UNKNOWN (342)", + "UNKNOWN (343)", + "UNKNOWN (344)", + "UNKNOWN (345)", + "UNKNOWN (346)", + "UNKNOWN (347)", + "UNKNOWN (348)", + "UNKNOWN (349)", + "UNKNOWN (350)", + "UNKNOWN (351)", + "UNKNOWN (352)", + "UNKNOWN (353)", + "UNKNOWN (354)", + "UNKNOWN (355)", + "UNKNOWN (356)", + "UNKNOWN (357)", + "UNKNOWN (358)", + "UNKNOWN (359)", + "UNKNOWN (360)", + "UNKNOWN (361)", + "UNKNOWN (362)", + "UNKNOWN (363)", + "UNKNOWN (364)", + "UNKNOWN (365)", + "UNKNOWN (366)", + "UNKNOWN (367)", + "UNKNOWN (368)", + "UNKNOWN (369)", + "UNKNOWN (370)", + "UNKNOWN (371)", + "UNKNOWN (372)", + "UNKNOWN (373)", + "UNKNOWN (374)", + "UNKNOWN (375)", + "UNKNOWN (376)", + "UNKNOWN (377)", + "UNKNOWN (378)", + "UNKNOWN (379)", + "UNKNOWN (380)", + "UNKNOWN (381)", + "UNKNOWN (382)", + "UNKNOWN (383)", + "UNKNOWN (384)", + "UNKNOWN (385)", + "UNKNOWN (386)", + "UNKNOWN (387)", + "UNKNOWN (388)", + "UNKNOWN (389)", + "UNKNOWN (390)", + "UNKNOWN (391)", + "UNKNOWN (392)", + "UNKNOWN (393)", + "UNKNOWN (394)", + "UNKNOWN (395)", + "UNKNOWN (396)", + "UNKNOWN (397)", + "UNKNOWN (398)", + "UNKNOWN (399)", + "UNKNOWN (400)", + "UNKNOWN (401)", + "UNKNOWN (402)", + "UNKNOWN (403)", + "UNKNOWN (404)", + "UNKNOWN (405)", + "UNKNOWN (406)", + "UNKNOWN (407)", + "UNKNOWN (408)", + "UNKNOWN (409)", + "UNKNOWN (410)", + "UNKNOWN (411)", + "UNKNOWN (412)", + "UNKNOWN (413)", + "UNKNOWN (414)", + "UNKNOWN (415)", + "UNKNOWN (416)", + "UNKNOWN (417)", + "UNKNOWN (418)", + "UNKNOWN (419)", + "UNKNOWN (420)", + "UNKNOWN (421)", + "UNKNOWN (422)", + "UNKNOWN (423)", + "UNKNOWN (424)", + "UNKNOWN (425)", + "UNKNOWN (426)", + "UNKNOWN (427)", + "UNKNOWN (428)", + "UNKNOWN (429)", + "UNKNOWN (430)", + "UNKNOWN (431)", + "UNKNOWN (432)", + "UNKNOWN (433)", + "UNKNOWN (434)", + "UNKNOWN (435)", + "UNKNOWN (436)", + "UNKNOWN (437)", + "UNKNOWN (438)", + "UNKNOWN (439)", + "UNKNOWN (440)", + "UNKNOWN (441)", + "UNKNOWN (442)", + "UNKNOWN (443)", + "UNKNOWN (444)", + "UNKNOWN (445)", + "UNKNOWN (446)", + "UNKNOWN (447)", + "UNKNOWN (448)", + "UNKNOWN (449)", + "UNKNOWN (450)", + "UNKNOWN (451)", + "UNKNOWN (452)", + "UNKNOWN (453)", + "UNKNOWN (454)", + "UNKNOWN (455)", + "UNKNOWN (456)", + "UNKNOWN (457)", + "UNKNOWN (458)", + "UNKNOWN (459)", + "UNKNOWN (460)", + "UNKNOWN (461)", + "UNKNOWN (462)", + "UNKNOWN (463)", + "UNKNOWN (464)", + "UNKNOWN (465)", + "UNKNOWN (466)", + "UNKNOWN (467)", + "UNKNOWN (468)", + "UNKNOWN (469)", + "UNKNOWN (470)", + "UNKNOWN (471)", + "UNKNOWN (472)", + "UNKNOWN (473)", + "UNKNOWN (474)", + "UNKNOWN (475)", + "UNKNOWN (476)", + "UNKNOWN (477)", + "UNKNOWN (478)", + "UNKNOWN (479)", + "UNKNOWN (480)", + "UNKNOWN (481)", + "UNKNOWN (482)", + "UNKNOWN (483)", + "UNKNOWN (484)", + "UNKNOWN (485)", + "UNKNOWN (486)", + "UNKNOWN (487)", + "UNKNOWN (488)", + "UNKNOWN (489)", + "UNKNOWN (490)", + "UNKNOWN (491)", + "UNKNOWN (492)", + "UNKNOWN (493)", + "UNKNOWN (494)", + "UNKNOWN (495)", + "UNKNOWN (496)", + "UNKNOWN (497)", + "UNKNOWN (498)", + "UNKNOWN (499)", + "UNKNOWN (500)", + "UNKNOWN (501)", + "UNKNOWN (502)", + "UNKNOWN (503)", + "UNKNOWN (504)", + "UNKNOWN (505)", + "UNKNOWN (506)", + "UNKNOWN (507)", + "UNKNOWN (508)", + "UNKNOWN (509)", + "UNKNOWN (510)", + "UNKNOWN (511)", + "WM_MOUSEMOVE", + "WM_LBUTTONDOWN", + "WM_LBUTTONUP", + "WM_LBUTTONDBLCLK", + "WM_RBUTTONDOWN", + "WM_RBUTTONUP", + "WM_RBUTTONDBLCLK", + "WM_MBUTTONDOWN", + "WM_MBUTTONUP", + "WM_MOUSELAST", + "WM_MOUSEWHEEL", + "WM_XBUTTONDOWN", + "WM_XBUTTONUP", + "UNKNOWN (525)", + "UNKNOWN (526)", + "UNKNOWN (527)", + "WM_PARENTNOTIFY", + "WM_ENTERMENULOOP", + "WM_EXITMENULOOP", + "WM_NEXTMENU", + "WM_SIZING", + "WM_CAPTURECHANGED", + "WM_MOVING", + "UNKNOWN (535)", + "WM_POWERBROADCAST", + "WM_DEVICECHANGE", + "UNKNOWN (538)", + "UNKNOWN (539)", + "UNKNOWN (540)", + "UNKNOWN (541)", + "UNKNOWN (542)", + "UNKNOWN (543)", + "WM_MDICREATE", + "WM_MDIDESTROY", + "WM_MDIACTIVATE", + "WM_MDIRESTORE", + "WM_MDINEXT", + "WM_MDIMAXIMIZE", + "WM_MDITILE", + "WM_MDICASCADE", + "WM_MDIICONARRANGE", + "WM_MDIGETACTIVE", + "UNKNOWN (554)", + "UNKNOWN (555)", + "UNKNOWN (556)", + "UNKNOWN (557)", + "UNKNOWN (558)", + "UNKNOWN (559)", + "WM_MDISETMENU", + "WM_ENTERSIZEMOVE", + "WM_EXITSIZEMOVE", + "WM_DROPFILES", + "WM_MDIREFRESHMENU", + "UNKNOWN (565)", + "UNKNOWN (566)", + "UNKNOWN (567)", + "UNKNOWN (568)", + "UNKNOWN (569)", + "UNKNOWN (570)", + "UNKNOWN (571)", + "UNKNOWN (572)", + "UNKNOWN (573)", + "UNKNOWN (574)", + "UNKNOWN (575)", + "WM_TOUCH", + "UNKNOWN (577)", + "UNKNOWN (578)", + "UNKNOWN (579)", + "UNKNOWN (580)", + "UNKNOWN (581)", + "UNKNOWN (582)", + "UNKNOWN (583)", + "UNKNOWN (584)", + "UNKNOWN (585)", + "UNKNOWN (586)", + "UNKNOWN (587)", + "UNKNOWN (588)", + "UNKNOWN (589)", + "UNKNOWN (590)", + "UNKNOWN (591)", + "UNKNOWN (592)", + "UNKNOWN (593)", + "UNKNOWN (594)", + "UNKNOWN (595)", + "UNKNOWN (596)", + "UNKNOWN (597)", + "UNKNOWN (598)", + "UNKNOWN (599)", + "UNKNOWN (600)", + "UNKNOWN (601)", + "UNKNOWN (602)", + "UNKNOWN (603)", + "UNKNOWN (604)", + "UNKNOWN (605)", + "UNKNOWN (606)", + "UNKNOWN (607)", + "UNKNOWN (608)", + "UNKNOWN (609)", + "UNKNOWN (610)", + "UNKNOWN (611)", + "UNKNOWN (612)", + "UNKNOWN (613)", + "UNKNOWN (614)", + "UNKNOWN (615)", + "UNKNOWN (616)", + "UNKNOWN (617)", + "UNKNOWN (618)", + "UNKNOWN (619)", + "UNKNOWN (620)", + "UNKNOWN (621)", + "UNKNOWN (622)", + "UNKNOWN (623)", + "UNKNOWN (624)", + "UNKNOWN (625)", + "UNKNOWN (626)", + "UNKNOWN (627)", + "UNKNOWN (628)", + "UNKNOWN (629)", + "UNKNOWN (630)", + "UNKNOWN (631)", + "UNKNOWN (632)", + "UNKNOWN (633)", + "UNKNOWN (634)", + "UNKNOWN (635)", + "UNKNOWN (636)", + "UNKNOWN (637)", + "UNKNOWN (638)", + "UNKNOWN (639)", + "UNKNOWN (640)", + "UNKNOWN (641)", + "UNKNOWN (642)", + "UNKNOWN (643)", + "UNKNOWN (644)", + "UNKNOWN (645)", + "UNKNOWN (646)", + "UNKNOWN (647)", + "UNKNOWN (648)", + "UNKNOWN (649)", + "UNKNOWN (650)", + "UNKNOWN (651)", + "UNKNOWN (652)", + "UNKNOWN (653)", + "UNKNOWN (654)", + "UNKNOWN (655)", + "UNKNOWN (656)", + "UNKNOWN (657)", + "UNKNOWN (658)", + "UNKNOWN (659)", + "UNKNOWN (660)", + "UNKNOWN (661)", + "UNKNOWN (662)", + "UNKNOWN (663)", + "UNKNOWN (664)", + "UNKNOWN (665)", + "UNKNOWN (666)", + "UNKNOWN (667)", + "UNKNOWN (668)", + "UNKNOWN (669)", + "UNKNOWN (670)", + "UNKNOWN (671)", + "UNKNOWN (672)", + "WM_MOUSEHOVER", + "UNKNOWN (674)", + "WM_MOUSELEAVE", + "UNKNOWN (676)", + "UNKNOWN (677)", + "UNKNOWN (678)", + "UNKNOWN (679)", + "UNKNOWN (680)", + "UNKNOWN (681)", + "UNKNOWN (682)", + "UNKNOWN (683)", + "UNKNOWN (684)", + "UNKNOWN (685)", + "UNKNOWN (686)", + "UNKNOWN (687)", + "UNKNOWN (688)", + "UNKNOWN (689)", + "UNKNOWN (690)", + "UNKNOWN (691)", + "UNKNOWN (692)", + "UNKNOWN (693)", + "UNKNOWN (694)", + "UNKNOWN (695)", + "UNKNOWN (696)", + "UNKNOWN (697)", + "UNKNOWN (698)", + "UNKNOWN (699)", + "UNKNOWN (700)", + "UNKNOWN (701)", + "UNKNOWN (702)", + "UNKNOWN (703)", + "UNKNOWN (704)", + "UNKNOWN (705)", + "UNKNOWN (706)", + "UNKNOWN (707)", + "UNKNOWN (708)", + "UNKNOWN (709)", + "UNKNOWN (710)", + "UNKNOWN (711)", + "UNKNOWN (712)", + "UNKNOWN (713)", + "UNKNOWN (714)", + "UNKNOWN (715)", + "UNKNOWN (716)", + "UNKNOWN (717)", + "UNKNOWN (718)", + "UNKNOWN (719)", + "UNKNOWN (720)", + "UNKNOWN (721)", + "UNKNOWN (722)", + "UNKNOWN (723)", + "UNKNOWN (724)", + "UNKNOWN (725)", + "UNKNOWN (726)", + "UNKNOWN (727)", + "UNKNOWN (728)", + "UNKNOWN (729)", + "UNKNOWN (730)", + "UNKNOWN (731)", + "UNKNOWN (732)", + "UNKNOWN (733)", + "UNKNOWN (734)", + "UNKNOWN (735)", + "UNKNOWN (736)", + "UNKNOWN (737)", + "UNKNOWN (738)", + "UNKNOWN (739)", + "UNKNOWN (740)", + "UNKNOWN (741)", + "UNKNOWN (742)", + "UNKNOWN (743)", + "UNKNOWN (744)", + "UNKNOWN (745)", + "UNKNOWN (746)", + "UNKNOWN (747)", + "UNKNOWN (748)", + "UNKNOWN (749)", + "UNKNOWN (750)", + "UNKNOWN (751)", + "UNKNOWN (752)", + "UNKNOWN (753)", + "UNKNOWN (754)", + "UNKNOWN (755)", + "UNKNOWN (756)", + "UNKNOWN (757)", + "UNKNOWN (758)", + "UNKNOWN (759)", + "UNKNOWN (760)", + "UNKNOWN (761)", + "UNKNOWN (762)", + "UNKNOWN (763)", + "UNKNOWN (764)", + "UNKNOWN (765)", + "UNKNOWN (766)", + "UNKNOWN (767)", + "WM_CUT", + "WM_COPY", + "WM_PASTE", + "WM_CLEAR", + "WM_UNDO", + "WM_RENDERFORMAT", + "WM_RENDERALLFORMATS", + "WM_DESTROYCLIPBOARD", + "WM_DRAWCLIPBOARD", + "WM_PAINTCLIPBOARD", + "WM_VSCROLLCLIPBOARD", + "WM_SIZECLIPBOARD", + "WM_ASKCBFORMATNAME", + "WM_CHANGECBCHAIN", + "WM_HSCROLLCLIPBOARD", + "WM_QUERYNEWPALETTE", + "WM_PALETTEISCHANGING", + "WM_PALETTECHANGED", + "WM_HOTKEY", + "UNKNOWN (787)", + "UNKNOWN (788)", + "UNKNOWN (789)", + "UNKNOWN (790)", + "WM_PRINT", + "WM_PRINTCLIENT", + "UNKNOWN (793)", + "UNKNOWN (794)", + "UNKNOWN (795)", + "UNKNOWN (796)", + "UNKNOWN (797)", + "UNKNOWN (798)", + "UNKNOWN (799)", + "UNKNOWN (800)", + "UNKNOWN (801)", + "UNKNOWN (802)", + "UNKNOWN (803)", + "UNKNOWN (804)", + "UNKNOWN (805)", + "UNKNOWN (806)", + "UNKNOWN (807)", + "UNKNOWN (808)", + "UNKNOWN (809)", + "UNKNOWN (810)", + "UNKNOWN (811)", + "UNKNOWN (812)", + "UNKNOWN (813)", + "UNKNOWN (814)", + "UNKNOWN (815)", + "UNKNOWN (816)", + "UNKNOWN (817)", + "UNKNOWN (818)", + "UNKNOWN (819)", + "UNKNOWN (820)", + "UNKNOWN (821)", + "UNKNOWN (822)", + "UNKNOWN (823)", + "UNKNOWN (824)", + "UNKNOWN (825)", + "UNKNOWN (826)", + "UNKNOWN (827)", + "UNKNOWN (828)", + "UNKNOWN (829)", + "UNKNOWN (830)", + "UNKNOWN (831)", + "UNKNOWN (832)", + "UNKNOWN (833)", + "UNKNOWN (834)", + "UNKNOWN (835)", + "UNKNOWN (836)", + "UNKNOWN (837)", + "UNKNOWN (838)", + "UNKNOWN (839)", + "UNKNOWN (840)", + "UNKNOWN (841)", + "UNKNOWN (842)", + "UNKNOWN (843)", + "UNKNOWN (844)", + "UNKNOWN (845)", + "UNKNOWN (846)", + "UNKNOWN (847)", + "UNKNOWN (848)", + "UNKNOWN (849)", + "UNKNOWN (850)", + "UNKNOWN (851)", + "UNKNOWN (852)", + "UNKNOWN (853)", + "UNKNOWN (854)", + "UNKNOWN (855)", + "WM_HANDHELDFIRST", + "UNKNOWN (857)", + "UNKNOWN (858)", + "UNKNOWN (859)", + "UNKNOWN (860)", + "UNKNOWN (861)", + "UNKNOWN (862)", + "WM_HANDHELDLAST", + "WM_AFXFIRST", + "UNKNOWN (865)", + "UNKNOWN (866)", + "UNKNOWN (867)", + "UNKNOWN (868)", + "UNKNOWN (869)", + "UNKNOWN (870)", + "UNKNOWN (871)", + "UNKNOWN (872)", + "UNKNOWN (873)", + "UNKNOWN (874)", + "UNKNOWN (875)", + "UNKNOWN (876)", + "UNKNOWN (877)", + "UNKNOWN (878)", + "UNKNOWN (879)", + "UNKNOWN (880)", + "UNKNOWN (881)", + "UNKNOWN (882)", + "UNKNOWN (883)", + "UNKNOWN (884)", + "UNKNOWN (885)", + "UNKNOWN (886)", + "UNKNOWN (887)", + "UNKNOWN (888)", + "UNKNOWN (889)", + "UNKNOWN (890)", + "UNKNOWN (891)", + "UNKNOWN (892)", + "UNKNOWN (893)", + "UNKNOWN (894)", + "WM_AFXLAST", + "WM_PENWINFIRST", + "UNKNOWN (897)", + "UNKNOWN (898)", + "UNKNOWN (899)", + "UNKNOWN (900)", + "UNKNOWN (901)", + "UNKNOWN (902)", + "UNKNOWN (903)", + "UNKNOWN (904)", + "UNKNOWN (905)", + "UNKNOWN (906)", + "UNKNOWN (907)", + "UNKNOWN (908)", + "UNKNOWN (909)", + "UNKNOWN (910)", + "WM_PENWINLAST", + "UNKNOWN (912)", + "UNKNOWN (913)", + "UNKNOWN (914)", + "UNKNOWN (915)", + "UNKNOWN (916)", + "UNKNOWN (917)", + "UNKNOWN (918)", + "UNKNOWN (919)", + "UNKNOWN (920)", + "UNKNOWN (921)", + "UNKNOWN (922)", + "UNKNOWN (923)", + "UNKNOWN (924)", + "UNKNOWN (925)", + "UNKNOWN (926)", + "UNKNOWN (927)", + "UNKNOWN (928)", + "UNKNOWN (929)", + "UNKNOWN (930)", + "UNKNOWN (931)", + "UNKNOWN (932)", + "UNKNOWN (933)", + "UNKNOWN (934)", + "UNKNOWN (935)", + "UNKNOWN (936)", + "UNKNOWN (937)", + "UNKNOWN (938)", + "UNKNOWN (939)", + "UNKNOWN (940)", + "UNKNOWN (941)", + "UNKNOWN (942)", + "UNKNOWN (943)", + "UNKNOWN (944)", + "UNKNOWN (945)", + "UNKNOWN (946)", + "UNKNOWN (947)", + "UNKNOWN (948)", + "UNKNOWN (949)", + "UNKNOWN (950)", + "UNKNOWN (951)", + "UNKNOWN (952)", + "UNKNOWN (953)", + "UNKNOWN (954)", + "UNKNOWN (955)", + "UNKNOWN (956)", + "UNKNOWN (957)", + "UNKNOWN (958)", + "UNKNOWN (959)", + "UNKNOWN (960)", + "UNKNOWN (961)", + "UNKNOWN (962)", + "UNKNOWN (963)", + "UNKNOWN (964)", + "UNKNOWN (965)", + "UNKNOWN (966)", + "UNKNOWN (967)", + "UNKNOWN (968)", + "UNKNOWN (969)", + "UNKNOWN (970)", + "UNKNOWN (971)", + "UNKNOWN (972)", + "UNKNOWN (973)", + "UNKNOWN (974)", + "UNKNOWN (975)", + "UNKNOWN (976)", + "UNKNOWN (977)", + "UNKNOWN (978)", + "UNKNOWN (979)", + "UNKNOWN (980)", + "UNKNOWN (981)", + "UNKNOWN (982)", + "UNKNOWN (983)", + "UNKNOWN (984)", + "UNKNOWN (985)", + "UNKNOWN (986)", + "UNKNOWN (987)", + "UNKNOWN (988)", + "UNKNOWN (989)", + "UNKNOWN (990)", + "UNKNOWN (991)", + "UNKNOWN (992)", + "UNKNOWN (993)", + "UNKNOWN (994)", + "UNKNOWN (995)", + "UNKNOWN (996)", + "UNKNOWN (997)", + "UNKNOWN (998)", + "UNKNOWN (999)", + "UNKNOWN (1000)", + "UNKNOWN (1001)", + "UNKNOWN (1002)", + "UNKNOWN (1003)", + "UNKNOWN (1004)", + "UNKNOWN (1005)", + "UNKNOWN (1006)", + "UNKNOWN (1007)", + "UNKNOWN (1008)", + "UNKNOWN (1009)", + "UNKNOWN (1010)", + "UNKNOWN (1011)", + "UNKNOWN (1012)", + "UNKNOWN (1013)", + "UNKNOWN (1014)", + "UNKNOWN (1015)", + "UNKNOWN (1016)", + "UNKNOWN (1017)", + "UNKNOWN (1018)", + "UNKNOWN (1019)", + "UNKNOWN (1020)", + "UNKNOWN (1021)", + "UNKNOWN (1022)", + "UNKNOWN (1023)", + "WM_USER" +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 9e9940eae455 -r e8916fe9cfc8 test/automated/rwops/TestSupportRWops_Generic.c --- a/test/automated/rwops/TestSupportRWops_Generic.c Thu Jan 20 17:33:06 2011 -0800 +++ b/test/automated/rwops/TestSupportRWops_Generic.c Thu Jan 20 18:04:05 2011 -0800 @@ -2,7 +2,7 @@ * Customizations for specific platforms should go in alternative files. */ -// quiet win32 compiler warnings +// quiet windows compiler warnings #define _CRT_SECURE_NO_WARNINGS #include diff -r 9e9940eae455 -r e8916fe9cfc8 test/testfile.c --- a/test/testfile.c Thu Jan 20 17:33:06 2011 -0800 +++ b/test/testfile.c Thu Jan 20 18:04:05 2011 -0800 @@ -1,7 +1,7 @@ /* sanity tests on SDL_rwops.c (usefull for alternative implementations of stdio rwops) */ -// quiet win32 compiler warnings +// quiet windows compiler warnings #define _CRT_NONSTDC_NO_WARNINGS #include diff -r 9e9940eae455 -r e8916fe9cfc8 test/testgesture.c --- a/test/testgesture.c Thu Jan 20 17:33:06 2011 -0800 +++ b/test/testgesture.c Thu Jan 20 18:04:05 2011 -0800 @@ -19,14 +19,14 @@ #define PRIu32 "u" #endif #ifndef PRIs64 -#ifdef __WIN32__ +#ifdef __WINDOWS__ #define PRIs64 "I64" #else #define PRIs64 "lld" #endif #endif #ifndef PRIu64 -#ifdef __WIN32__ +#ifdef __WINDOWS__ #define PRIu64 "I64u" #else #define PRIu64 "llu" diff -r 9e9940eae455 -r e8916fe9cfc8 test/testnative.c --- a/test/testnative.c Thu Jan 20 17:33:06 2011 -0800 +++ b/test/testnative.c Thu Jan 20 18:04:05 2011 -0800 @@ -10,8 +10,8 @@ #define MAX_SPEED 1 static NativeWindowFactory *factories[] = { -#ifdef TEST_NATIVE_WIN32 - &Win32WindowFactory, +#ifdef TEST_NATIVE_WINDOWS + &WindowsWindowFactory, #endif #ifdef TEST_NATIVE_X11 &X11WindowFactory, diff -r 9e9940eae455 -r e8916fe9cfc8 test/testnative.h --- a/test/testnative.h Thu Jan 20 17:33:06 2011 -0800 +++ b/test/testnative.h Thu Jan 20 18:04:05 2011 -0800 @@ -15,9 +15,9 @@ void (*DestroyNativeWindow) (void *window); } NativeWindowFactory; -#ifdef SDL_VIDEO_DRIVER_WIN32 -#define TEST_NATIVE_WIN32 -extern NativeWindowFactory Win32WindowFactory; +#ifdef SDL_VIDEO_DRIVER_WINDOWS +#define TEST_NATIVE_WINDOWS +extern NativeWindowFactory WindowsWindowFactory; #endif #ifdef SDL_VIDEO_DRIVER_X11 diff -r 9e9940eae455 -r e8916fe9cfc8 test/testnativew32.c --- a/test/testnativew32.c Thu Jan 20 17:33:06 2011 -0800 +++ b/test/testnativew32.c Thu Jan 20 18:04:05 2011 -0800 @@ -1,15 +1,15 @@ #include "testnative.h" -#ifdef TEST_NATIVE_WIN32 +#ifdef TEST_NATIVE_WINDOWS -static void *CreateWindowWin32(int w, int h); -static void DestroyWindowWin32(void *window); +static void *CreateWindowNative(int w, int h); +static void DestroyWindowNative(void *window); -NativeWindowFactory Win32WindowFactory = { - "win32", - CreateWindowWin32, - DestroyWindowWin32 +NativeWindowFactory WindowsWindowFactory = { + "windows", + CreateWindowNative, + DestroyWindowNative }; LRESULT CALLBACK @@ -29,7 +29,7 @@ } static void * -CreateWindowWin32(int w, int h) +CreateWindowNative(int w, int h) { HWND hwnd; WNDCLASS wc; @@ -67,7 +67,7 @@ } static void -DestroyWindowWin32(void *window) +DestroyWindowNative(void *window) { DestroyWindow((HWND) window); }